mirror of
https://git.friendi.ca/friendica/friendica.git
synced 2025-06-07 18:44:26 +02:00
Merge branch 'develop' into introduce-phpmd
This commit is contained in:
commit
f1af52baa1
100 changed files with 19158 additions and 18342 deletions
|
@ -7,8 +7,13 @@ parameters:
|
||||||
|
|
||||||
paths:
|
paths:
|
||||||
- addon/
|
- addon/
|
||||||
- src/
|
- bin/auth_ejabberd.php
|
||||||
|
- bin/console.php
|
||||||
|
- bin/daemon.php
|
||||||
|
- bin/jetstream.php
|
||||||
|
- bin/worker.php
|
||||||
- index.php
|
- index.php
|
||||||
|
- src/
|
||||||
|
|
||||||
excludePaths:
|
excludePaths:
|
||||||
analyse:
|
analyse:
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
# The code standard check is just triggered for PRs and pushes to non-stable branches of Friendica
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
exclude: [ stable ]
|
||||||
|
event: [ pull_request, push ]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
restore_cache:
|
restore_cache:
|
||||||
image: meltwater/drone-cache:dev
|
image: meltwater/drone-cache:dev
|
||||||
|
@ -31,12 +37,20 @@ steps:
|
||||||
volumes:
|
volumes:
|
||||||
- /tmp/drone-cache:/tmp/cache
|
- /tmp/drone-cache:/tmp/cache
|
||||||
check:
|
check:
|
||||||
image: friendicaci/php-cs
|
image: php:8.3
|
||||||
commands:
|
commands:
|
||||||
|
- echo "**** Use bin/dev/fix-codestyle.sh in case of errors ****"
|
||||||
|
- apt-get update -q
|
||||||
|
- DEBIAN_FRONTEND=noninteractive apt-get install -q -y git
|
||||||
- if [ ! -z "$${CI_COMMIT_PULL_REQUEST}" ]; then
|
- if [ ! -z "$${CI_COMMIT_PULL_REQUEST}" ]; then
|
||||||
git fetch --no-tags origin ${CI_COMMIT_TARGET_BRANCH};
|
git fetch --no-tags origin ${CI_COMMIT_TARGET_BRANCH};
|
||||||
export CHANGED_FILES="$(git diff --name-status $(git merge-base FETCH_HEAD origin/${CI_COMMIT_TARGET_BRANCH})..${CI_COMMIT_SHA} | grep ^A | cut -f2)";
|
CHANGED_FILES="$(git diff --name-only --diff-filter=ACMRTUXB $(git merge-base FETCH_HEAD origin/${CI_COMMIT_TARGET_BRANCH})..${CI_COMMIT_SHA})";
|
||||||
else
|
else
|
||||||
export CHANGED_FILES="$(git diff --name-status ${CI_COMMIT_SHA} | grep ^A | cut -f2)";
|
CHANGED_FILES="$(git diff --name-only --diff-filter=ACMRTUXB ${CI_COMMIT_SHA})";
|
||||||
fi
|
fi
|
||||||
- /check-php-cs.sh
|
- if ! echo "$${CHANGED_FILES}" | grep -qE "^(\\.php-cs-fixer(\\.dist)?\\.php|composer\\.lock)$"; then
|
||||||
|
EXTRA_ARGS=$(printf -- '--path-mode=intersection\n--\n%s' "$${CHANGED_FILES}");
|
||||||
|
else
|
||||||
|
EXTRA_ARGS='';
|
||||||
|
fi
|
||||||
|
- ./bin/dev/php-cs-fixer/vendor/bin/php-cs-fixer check --config=.php-cs-fixer.dist.php -v --diff --using-cache=no $${EXTRA_ARGS}
|
||||||
|
|
|
@ -13,6 +13,12 @@ labels:
|
||||||
location: friendica
|
location: friendica
|
||||||
type: releaser
|
type: releaser
|
||||||
|
|
||||||
|
# CD is triggered after pushing new code to the develop or *-rc branch, excluding the stable branch
|
||||||
|
when:
|
||||||
|
repo: friendica/friendica
|
||||||
|
branch: [ develop, '*-rc' ]
|
||||||
|
event: push
|
||||||
|
|
||||||
skip_clone: true
|
skip_clone: true
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
@ -23,10 +29,6 @@ steps:
|
||||||
- git checkout $CI_COMMIT_BRANCH
|
- git checkout $CI_COMMIT_BRANCH
|
||||||
- git fetch origin $CI_COMMIT_REF
|
- git fetch origin $CI_COMMIT_REF
|
||||||
- git merge $CI_COMMIT_SHA
|
- git merge $CI_COMMIT_SHA
|
||||||
when:
|
|
||||||
repo: friendica/friendica
|
|
||||||
branch: [ develop, '*-rc' ]
|
|
||||||
event: push
|
|
||||||
restore_cache:
|
restore_cache:
|
||||||
image: meltwater/drone-cache:dev
|
image: meltwater/drone-cache:dev
|
||||||
settings:
|
settings:
|
||||||
|
@ -38,10 +40,6 @@ steps:
|
||||||
- '.composer'
|
- '.composer'
|
||||||
volumes:
|
volumes:
|
||||||
- /tmp/drone-cache:/tmp/cache
|
- /tmp/drone-cache:/tmp/cache
|
||||||
when:
|
|
||||||
repo: friendica/friendica
|
|
||||||
branch: [ develop, '*-rc' ]
|
|
||||||
event: push
|
|
||||||
composer_install:
|
composer_install:
|
||||||
image: friendicaci/php8.2:php8.2.16
|
image: friendicaci/php8.2:php8.2.16
|
||||||
commands:
|
commands:
|
||||||
|
@ -51,10 +49,6 @@ steps:
|
||||||
- composer install --no-dev --optimize-autoloader
|
- composer install --no-dev --optimize-autoloader
|
||||||
volumes:
|
volumes:
|
||||||
- /etc/hosts:/etc/hosts
|
- /etc/hosts:/etc/hosts
|
||||||
when:
|
|
||||||
repo: friendica/friendica
|
|
||||||
branch: [ develop, '*-rc' ]
|
|
||||||
event: push
|
|
||||||
create_artifacts:
|
create_artifacts:
|
||||||
image: debian
|
image: debian
|
||||||
commands:
|
commands:
|
||||||
|
@ -75,10 +69,6 @@ steps:
|
||||||
- ls -lh
|
- ls -lh
|
||||||
- cat "$ARTIFACT.sum256"
|
- cat "$ARTIFACT.sum256"
|
||||||
- sha256sum "$ARTIFACT"
|
- sha256sum "$ARTIFACT"
|
||||||
when:
|
|
||||||
repo: friendica/friendica
|
|
||||||
branch: [ develop, '*-rc' ]
|
|
||||||
event: push
|
|
||||||
sign_artifacts:
|
sign_artifacts:
|
||||||
image: plugins/gpgsign
|
image: plugins/gpgsign
|
||||||
settings:
|
settings:
|
||||||
|
@ -91,17 +81,9 @@ steps:
|
||||||
exclude:
|
exclude:
|
||||||
- build/*.sum256
|
- build/*.sum256
|
||||||
detach_sign: true
|
detach_sign: true
|
||||||
when:
|
|
||||||
repo: friendica/friendica
|
|
||||||
branch: [ develop, '*-rc' ]
|
|
||||||
event: push
|
|
||||||
publish_artifacts:
|
publish_artifacts:
|
||||||
image: alpine
|
image: alpine
|
||||||
commands:
|
commands:
|
||||||
- cp -fr build/* /tmp/friendica_files/
|
- cp -fr build/* /tmp/friendica_files/
|
||||||
volumes:
|
volumes:
|
||||||
- files:/tmp/friendica_files
|
- files:/tmp/friendica_files
|
||||||
when:
|
|
||||||
repo: friendica/friendica
|
|
||||||
branch: [ develop, '*-rc' ]
|
|
||||||
event: push
|
|
||||||
|
|
|
@ -8,8 +8,9 @@ matrix:
|
||||||
PHP_VERSION: 8.2.16
|
PHP_VERSION: 8.2.16
|
||||||
|
|
||||||
when:
|
when:
|
||||||
- branch:
|
branch:
|
||||||
exclude: [ stable ]
|
exclude: [ stable ]
|
||||||
|
event: [ pull_request, push ]
|
||||||
|
|
||||||
# This forces CI executions at the "opensocial" labeled location (because of much more power...)
|
# This forces CI executions at the "opensocial" labeled location (because of much more power...)
|
||||||
labels:
|
labels:
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
exclude: [ stable ]
|
||||||
|
event: [ pull_request, push ]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
check:
|
check:
|
||||||
image: fsfe/reuse:latest
|
image: fsfe/reuse:latest
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
exclude: [ stable ]
|
||||||
|
event: [ pull_request, push ]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
build_xgettext:
|
build_xgettext:
|
||||||
image: friendicaci/transifex
|
image: friendicaci/transifex
|
||||||
|
@ -11,7 +16,3 @@ steps:
|
||||||
image: friendicaci/transifex
|
image: friendicaci/transifex
|
||||||
commands:
|
commands:
|
||||||
- /check-messages.sh
|
- /check-messages.sh
|
||||||
|
|
||||||
when:
|
|
||||||
- branch:
|
|
||||||
exclude: [ stable ]
|
|
||||||
|
|
|
@ -19,6 +19,11 @@ matrix:
|
||||||
labels:
|
labels:
|
||||||
location: opensocial
|
location: opensocial
|
||||||
|
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
exclude: [ stable ]
|
||||||
|
event: [ pull_request, push ]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
php-lint:
|
php-lint:
|
||||||
image: php:${PHP_MAJOR_VERSION}
|
image: php:${PHP_MAJOR_VERSION}
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
depends_on:
|
|
||||||
- phpunit
|
|
||||||
- code_standards_check
|
|
||||||
|
|
||||||
# This prevents executing this pipeline at other servers than ci.friendi.ca
|
# This prevents executing this pipeline at other servers than ci.friendi.ca
|
||||||
labels:
|
labels:
|
||||||
location: friendica
|
location: friendica
|
||||||
|
@ -13,6 +9,11 @@ labels:
|
||||||
|
|
||||||
skip_clone: true
|
skip_clone: true
|
||||||
|
|
||||||
|
when:
|
||||||
|
repo: friendica/friendica
|
||||||
|
branch: stable
|
||||||
|
event: tag
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
clone:
|
clone:
|
||||||
image: alpine/git
|
image: alpine/git
|
||||||
|
@ -21,10 +22,7 @@ steps:
|
||||||
- git checkout $CI_COMMIT_BRANCH
|
- git checkout $CI_COMMIT_BRANCH
|
||||||
- git fetch origin $CI_COMMIT_REF
|
- git fetch origin $CI_COMMIT_REF
|
||||||
- git merge $CI_COMMIT_SHA
|
- git merge $CI_COMMIT_SHA
|
||||||
when:
|
|
||||||
repo: friendica/friendica
|
|
||||||
branch: stable
|
|
||||||
event: tag
|
|
||||||
restore_cache:
|
restore_cache:
|
||||||
image: meltwater/drone-cache:dev
|
image: meltwater/drone-cache:dev
|
||||||
settings:
|
settings:
|
||||||
|
@ -36,10 +34,6 @@ steps:
|
||||||
- '.composer'
|
- '.composer'
|
||||||
volumes:
|
volumes:
|
||||||
- /tmp/drone-cache:/tmp/cache
|
- /tmp/drone-cache:/tmp/cache
|
||||||
when:
|
|
||||||
repo: friendica/friendica
|
|
||||||
branch: stable
|
|
||||||
event: tag
|
|
||||||
composer_install:
|
composer_install:
|
||||||
image: friendicaci/php8.2:php8.2.16
|
image: friendicaci/php8.2:php8.2.16
|
||||||
commands:
|
commands:
|
||||||
|
@ -47,10 +41,6 @@ steps:
|
||||||
- export COMPOSER_HOME=.composer
|
- export COMPOSER_HOME=.composer
|
||||||
- composer validate
|
- composer validate
|
||||||
- composer install --no-dev --optimize-autoloader
|
- composer install --no-dev --optimize-autoloader
|
||||||
when:
|
|
||||||
repo: friendica/friendica
|
|
||||||
branch: stable
|
|
||||||
event: tag
|
|
||||||
volumes:
|
volumes:
|
||||||
- /etc/hosts:/etc/hosts
|
- /etc/hosts:/etc/hosts
|
||||||
create_artifacts:
|
create_artifacts:
|
||||||
|
@ -73,10 +63,6 @@ steps:
|
||||||
- ls -lh
|
- ls -lh
|
||||||
- cat "$ARTIFACT.sum256"
|
- cat "$ARTIFACT.sum256"
|
||||||
- sha256sum "$ARTIFACT"
|
- sha256sum "$ARTIFACT"
|
||||||
when:
|
|
||||||
repo: friendica/friendica
|
|
||||||
branch: stable
|
|
||||||
event: tag
|
|
||||||
sign_artifacts:
|
sign_artifacts:
|
||||||
image: plugins/gpgsign
|
image: plugins/gpgsign
|
||||||
settings:
|
settings:
|
||||||
|
@ -99,7 +85,3 @@ steps:
|
||||||
- cp -fr build/* /tmp/friendica_files/
|
- cp -fr build/* /tmp/friendica_files/
|
||||||
volumes:
|
volumes:
|
||||||
- files:/tmp/friendica_files
|
- files:/tmp/friendica_files
|
||||||
when:
|
|
||||||
repo: friendica/friendica
|
|
||||||
branch: stable
|
|
||||||
event: tag
|
|
||||||
|
|
64
CHANGELOG
64
CHANGELOG
|
@ -1,16 +1,76 @@
|
||||||
Version 2024.12 (unreleased)
|
Version 2025.02 (unreleased)
|
||||||
Friendica Core
|
Friendica Core
|
||||||
|
Deprecated bin/daemon in favor of bin/console daemon (PR 14642) [nupplaphil]
|
||||||
|
Deprecated bin/jetstream in favor of bin/console jetstream (PR 14655) [nupplaphil]
|
||||||
|
|
||||||
Friendica Addons
|
Friendica Addons
|
||||||
|
|
||||||
Closed Issues
|
Closed Issues
|
||||||
|
|
||||||
Version 2024.09 (unreleased)
|
Version 2024.12 (2024-12-31)
|
||||||
Friendica Core
|
Friendica Core
|
||||||
|
Updates to the translations AR, BG, CA, CS, DE, EO, ES, ET, FR, GD, HU, IS, IT, JA, NL, PL, RU, SV
|
||||||
|
Updates to the documentation [annando, bmillwood, tobiasd]
|
||||||
|
Updates to the themes (frio) [haheute]
|
||||||
|
Friendica Core is now REUSE compliant [tobiasd]
|
||||||
|
General code cleanup [annando, nupplaphil, mexon]
|
||||||
|
Improved federation with Bluesky, Hubzilla, Peertube, threads, Wordpress [annando]
|
||||||
|
Improved the API [annando]
|
||||||
|
Improved display of contact connection state [annando]
|
||||||
|
Improved handling of bad webfinger requests [annando, mexon, zotanmew]
|
||||||
|
Improved the order of actions on the 2FA settings page [tobiasd]
|
||||||
|
Improved server type detection [annando]
|
||||||
|
Improved content negotiation [annando]
|
||||||
|
Improved expiration [annando]
|
||||||
|
Improved contact archiving [annando]
|
||||||
|
Improved delivery of content [annando]
|
||||||
|
Improved displayed project icons [annando]
|
||||||
|
Improved splitting of long postings via connectors [annando]
|
||||||
|
Improved contact import [annando]
|
||||||
|
Improved URL detection in searches [annando]
|
||||||
|
Improved handling of blocked users [annando]
|
||||||
|
Fixed a bug in creating app specific passwords [nupplaphil]
|
||||||
|
Fixed a bug in importing some notes from Mastodon [annando]
|
||||||
|
Fixed a bug with postings from buffer including images [annando]
|
||||||
|
Fixed a apache2 problem with unsafe URLs [annando]
|
||||||
|
Fixed a bug in the contact settings [annando]
|
||||||
|
Fixed a bug with latin1 encoded databases [annando]
|
||||||
|
Fixed a bug while uploading server blocklists [ne20002]
|
||||||
|
Fixed a bug while parsing events [annando]
|
||||||
|
Fixed a bug in the initial registry settings [annando]
|
||||||
|
Fixed a bug in 0Auth with buffer [annando]
|
||||||
|
Fixed a problem with rich HTML content [annando]
|
||||||
|
Fixed a bug with private comments [annando]
|
||||||
|
Fixed a bug in gettext [tobiasd]
|
||||||
|
Fixed a bug in the installation process [tobiasd]
|
||||||
|
Fixed schema.org issue [annando]
|
||||||
|
Added admin info to stats module [nupplaphil]
|
||||||
|
Added an option to exclude postings with images without ALT text [annando]
|
||||||
|
Added an option to hide custom emojis [annando]
|
||||||
|
Added support for HLS [annando]
|
||||||
|
Added devcontainer for Friendica [ne20002]
|
||||||
|
Added jetstream support for AT protocol [annando]
|
||||||
|
Added native probe support for AT protocol [annando]
|
||||||
|
Removed custom emojis from contact names [annando]
|
||||||
|
Removed OStatus support [annando]
|
||||||
|
|
||||||
Friendica Addons
|
Friendica Addons
|
||||||
|
bluesky
|
||||||
|
Added block functionality [annando]
|
||||||
|
Added option to complete threads [annando]
|
||||||
|
Fixed issue with blocking contacts [annando]
|
||||||
|
Improved handling of startersets [annando]
|
||||||
|
Improved fetching of postings [annando]
|
||||||
|
invidious [loma-one]
|
||||||
|
unicode_smileys [loma-one]
|
||||||
|
fancybox
|
||||||
|
Deprecated the addon [tobiasd]
|
||||||
|
|
||||||
Closed Issues
|
Closed Issues
|
||||||
|
13270, 13943, 14121, 14126, 14145, 14174, 14212, 14244, 14281,
|
||||||
|
14292, 14294, 14303, 14307, 14344, 14368, 14370, 14373, 14377,
|
||||||
|
14381, 14413, 14421, 14525, 14450, 14451, 14464, 14487, 14488,
|
||||||
|
14491, 14495, 14512, 14587, 14609, 14630
|
||||||
|
|
||||||
Version 2024.08 (2024-08-17)
|
Version 2024.08 (2024-08-17)
|
||||||
Friendica Core
|
Friendica Core
|
||||||
|
|
13
CREDITS.txt
13
CREDITS.txt
|
@ -23,6 +23,7 @@ Andi Stadler
|
||||||
Andreas H.
|
Andreas H.
|
||||||
Andreas Neustifter
|
Andreas Neustifter
|
||||||
Andrej Stieben
|
Andrej Stieben
|
||||||
|
Andrey Esin
|
||||||
André Alves
|
André Alves
|
||||||
André Lohan
|
André Lohan
|
||||||
Andy
|
Andy
|
||||||
|
@ -46,6 +47,7 @@ beardyunixer
|
||||||
Beatriz Vital
|
Beatriz Vital
|
||||||
Beluga
|
Beluga
|
||||||
Ben
|
Ben
|
||||||
|
Ben Millwood
|
||||||
Ben Roberts
|
Ben Roberts
|
||||||
ben-utzer
|
ben-utzer
|
||||||
Beringer Zsolt
|
Beringer Zsolt
|
||||||
|
@ -72,6 +74,7 @@ Christian Wiwie
|
||||||
Cohan Robinson
|
Cohan Robinson
|
||||||
Colby Sollars
|
Colby Sollars
|
||||||
Copiis
|
Copiis
|
||||||
|
cracrayol
|
||||||
CrystalStiletto
|
CrystalStiletto
|
||||||
csolisr
|
csolisr
|
||||||
Cyboulette
|
Cyboulette
|
||||||
|
@ -91,9 +94,11 @@ Dean Townsley
|
||||||
Denis Chenu
|
Denis Chenu
|
||||||
dependabot[bot]
|
dependabot[bot]
|
||||||
Devlon Duthie
|
Devlon Duthie
|
||||||
|
dew-git
|
||||||
Diego Souza
|
Diego Souza
|
||||||
Domovoy
|
Domovoy
|
||||||
Doru DEACONU
|
Doru DEACONU
|
||||||
|
Dr. Tobias Quathamer
|
||||||
Dylan Thiedeke
|
Dylan Thiedeke
|
||||||
Développeur égaré
|
Développeur égaré
|
||||||
eddy2508
|
eddy2508
|
||||||
|
@ -188,8 +193,10 @@ Kris
|
||||||
Kristoffer Grundström
|
Kristoffer Grundström
|
||||||
ktlinux
|
ktlinux
|
||||||
KulikAlex
|
KulikAlex
|
||||||
|
Laura Hausmann
|
||||||
Lea1995polish
|
Lea1995polish
|
||||||
Leberwurscht
|
Leberwurscht
|
||||||
|
Leonard
|
||||||
Leonard Lausen
|
Leonard Lausen
|
||||||
Lionel Triay
|
Lionel Triay
|
||||||
loma-one
|
loma-one
|
||||||
|
@ -227,9 +234,11 @@ Mike Macgirvin
|
||||||
miqrogroove
|
miqrogroove
|
||||||
Morgan McMillian
|
Morgan McMillian
|
||||||
mpanhans
|
mpanhans
|
||||||
|
MrPetovan
|
||||||
mytbk
|
mytbk
|
||||||
nathilia-peirce
|
nathilia-peirce
|
||||||
Nicola Spanti
|
Nicola Spanti
|
||||||
|
ne20002
|
||||||
Nicolas Derive
|
Nicolas Derive
|
||||||
nnsrymni
|
nnsrymni
|
||||||
nobody
|
nobody
|
||||||
|
@ -308,7 +317,6 @@ snajafov
|
||||||
softmetz
|
softmetz
|
||||||
soko1
|
soko1
|
||||||
Spencer Dub
|
Spencer Dub
|
||||||
SpencerDub
|
|
||||||
St John Karp
|
St John Karp
|
||||||
Stanislav N.
|
Stanislav N.
|
||||||
Steffen K9
|
Steffen K9
|
||||||
|
@ -340,6 +348,7 @@ Tom
|
||||||
Tom Aurlund
|
Tom Aurlund
|
||||||
Tom Hu
|
Tom Hu
|
||||||
tomamplius
|
tomamplius
|
||||||
|
tommy tomson
|
||||||
tomtom84
|
tomtom84
|
||||||
Tony Baldwin
|
Tony Baldwin
|
||||||
Torbjörn Andersson
|
Torbjörn Andersson
|
||||||
|
@ -370,6 +379,7 @@ Wanting Chen
|
||||||
Wil Tur
|
Wil Tur
|
||||||
Wladimir Palant
|
Wladimir Palant
|
||||||
Wouter Broers
|
Wouter Broers
|
||||||
|
www-data
|
||||||
Xiaofei Xu
|
Xiaofei Xu
|
||||||
XMPPはいいぞ
|
XMPPはいいぞ
|
||||||
xundeenergie
|
xundeenergie
|
||||||
|
@ -382,6 +392,7 @@ Zered
|
||||||
zotlabs
|
zotlabs
|
||||||
zottel
|
zottel
|
||||||
Zvi ben Yaakov (a.k.a rdc)
|
Zvi ben Yaakov (a.k.a rdc)
|
||||||
|
Éibhear Ó hAnluain
|
||||||
Михаил
|
Михаил
|
||||||
Олексій Замковий
|
Олексій Замковий
|
||||||
朱陈锬
|
朱陈锬
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
2024.12-dev
|
2025.02-dev
|
||||||
|
|
2
Vagrantfile
vendored
2
Vagrantfile
vendored
|
@ -7,7 +7,7 @@ public_folder = "/vagrant"
|
||||||
|
|
||||||
Vagrant.configure(2) do |config|
|
Vagrant.configure(2) do |config|
|
||||||
# Set server to Debian 11 / Bullseye 64bit
|
# Set server to Debian 11 / Bullseye 64bit
|
||||||
config.vm.box = "debian/bullseye64"
|
config.vm.box = "debian/bookworm64"
|
||||||
|
|
||||||
# Disable automatic box update checking. If you disable this, then
|
# Disable automatic box update checking. If you disable this, then
|
||||||
# boxes will only be checked for updates when the user runs
|
# boxes will only be checked for updates when the user runs
|
||||||
|
|
|
@ -52,6 +52,7 @@ require dirname(__FILE__, 2) . '/vendor/autoload.php';
|
||||||
|
|
||||||
$dice = (new Dice())->addRules(require(dirname(__FILE__, 2) . '/static/dependencies.config.php'));
|
$dice = (new Dice())->addRules(require(dirname(__FILE__, 2) . '/static/dependencies.config.php'));
|
||||||
|
|
||||||
$app = \Friendica\App::fromDice($dice);
|
$container = \Friendica\Core\Container::fromDice($dice);
|
||||||
|
$app = \Friendica\App::fromContainer($container);
|
||||||
|
|
||||||
$app->processEjabberd();
|
$app->processEjabberd();
|
||||||
|
|
|
@ -14,20 +14,10 @@ if (php_sapi_name() !== 'cli') {
|
||||||
}
|
}
|
||||||
|
|
||||||
use Dice\Dice;
|
use Dice\Dice;
|
||||||
use Friendica\Core\Logger\Capability\LogChannel;
|
|
||||||
use Friendica\DI;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
|
|
||||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
$dice = (new Dice())->addRules(include __DIR__ . '/../static/dependencies.config.php');
|
$dice = (new Dice())->addRules(require(dirname(__DIR__) . '/static/dependencies.config.php'));
|
||||||
/** @var \Friendica\Core\Addon\Capability\ICanLoadAddons $addonLoader */
|
|
||||||
$addonLoader = $dice->create(\Friendica\Core\Addon\Capability\ICanLoadAddons::class);
|
|
||||||
$dice = $dice->addRules($addonLoader->getActiveAddonConfig('dependencies'));
|
|
||||||
$dice = $dice->addRule(LoggerInterface::class, ['constructParams' => [LogChannel::CONSOLE]]);
|
|
||||||
|
|
||||||
/// @fixme Necessary until Hooks inside the Logger can get loaded without the DI-class
|
$container = \Friendica\Core\Container::fromDice($dice);
|
||||||
DI::init($dice);
|
\Friendica\Core\Console::create($container, $_SERVER['argv'] ?? [])->execute();
|
||||||
\Friendica\Core\Logger\Handler\ErrorHandler::register($dice->create(\Psr\Log\LoggerInterface::class));
|
|
||||||
|
|
||||||
(new Friendica\Core\Console($dice, $argv))->execute();
|
|
||||||
|
|
228
bin/daemon.php
228
bin/daemon.php
|
@ -5,6 +5,8 @@
|
||||||
* SPDX-FileCopyrightText: 2010-2024 the Friendica project
|
* SPDX-FileCopyrightText: 2010-2024 the Friendica project
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
*
|
||||||
|
* @deprecated 2025.02 use bin/console.php daemon instead
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,230 +20,16 @@ if (php_sapi_name() !== 'cli') {
|
||||||
}
|
}
|
||||||
|
|
||||||
use Dice\Dice;
|
use Dice\Dice;
|
||||||
use Friendica\App\Mode;
|
|
||||||
use Friendica\Core\Logger;
|
|
||||||
use Friendica\Core\Update;
|
|
||||||
use Friendica\Core\Worker;
|
|
||||||
use Friendica\Database\DBA;
|
|
||||||
use Friendica\DI;
|
|
||||||
use Friendica\Util\DateTimeFormat;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
|
|
||||||
// Get options
|
|
||||||
$shortopts = 'f';
|
|
||||||
$longopts = ['foreground'];
|
|
||||||
$options = getopt($shortopts, $longopts);
|
|
||||||
|
|
||||||
// Ensure that daemon.php is executed from the base path of the installation
|
// Ensure that daemon.php is executed from the base path of the installation
|
||||||
if (!file_exists('index.php') && (sizeof($_SERVER['argv']) != 0)) {
|
chdir(dirname(__DIR__));
|
||||||
$directory = dirname($_SERVER['argv'][0]);
|
|
||||||
|
|
||||||
if (substr($directory, 0, 1) != '/') {
|
|
||||||
$directory = $_SERVER['PWD'] . '/' . $directory;
|
|
||||||
}
|
|
||||||
$directory = realpath($directory . '/..');
|
|
||||||
|
|
||||||
chdir($directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
$dice = (new Dice())->addRules(include __DIR__ . '/../static/dependencies.config.php');
|
$dice = (new Dice())->addRules(require(dirname(__DIR__) . '/static/dependencies.config.php'));
|
||||||
/** @var \Friendica\Core\Addon\Capability\ICanLoadAddons $addonLoader */
|
|
||||||
$addonLoader = $dice->create(\Friendica\Core\Addon\Capability\ICanLoadAddons::class);
|
|
||||||
$dice = $dice->addRules($addonLoader->getActiveAddonConfig('dependencies'));
|
|
||||||
$dice = $dice->addRule(LoggerInterface::class, ['constructParams' => [Logger\Capability\LogChannel::DAEMON]]);
|
|
||||||
|
|
||||||
DI::init($dice);
|
$argv = $_SERVER['argv'] ?? [];
|
||||||
\Friendica\Core\Logger\Handler\ErrorHandler::register($dice->create(\Psr\Log\LoggerInterface::class));
|
array_splice($argv, 1, 0, "daemon");
|
||||||
|
|
||||||
if (DI::mode()->isInstall()) {
|
$container = \Friendica\Core\Container::fromDice($dice);
|
||||||
die("Friendica isn't properly installed yet.\n");
|
\Friendica\Core\Console::create($container, $argv)->execute();
|
||||||
}
|
|
||||||
|
|
||||||
DI::mode()->setExecutor(Mode::DAEMON);
|
|
||||||
|
|
||||||
DI::config()->reload();
|
|
||||||
|
|
||||||
if (empty(DI::config()->get('system', 'pidfile'))) {
|
|
||||||
die(<<<TXT
|
|
||||||
Please set system.pidfile in config/local.config.php. For example:
|
|
||||||
|
|
||||||
'system' => [
|
|
||||||
'pidfile' => '/path/to/daemon.pid',
|
|
||||||
],
|
|
||||||
TXT
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$pidfile = DI::config()->get('system', 'pidfile');
|
|
||||||
|
|
||||||
if (in_array('start', $_SERVER['argv'])) {
|
|
||||||
$mode = 'start';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array('stop', $_SERVER['argv'])) {
|
|
||||||
$mode = 'stop';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array('status', $_SERVER['argv'])) {
|
|
||||||
$mode = 'status';
|
|
||||||
}
|
|
||||||
|
|
||||||
$foreground = array_key_exists('f', $options) || array_key_exists('foreground', $options);
|
|
||||||
|
|
||||||
if (!isset($mode)) {
|
|
||||||
die("Please use either 'start', 'stop' or 'status'.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($_SERVER['argv'][0])) {
|
|
||||||
die("Unexpected script behaviour. This message should never occur.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
$pid = null;
|
|
||||||
|
|
||||||
if (is_readable($pidfile)) {
|
|
||||||
$pid = intval(file_get_contents($pidfile));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($pid) && in_array($mode, ['stop', 'status'])) {
|
|
||||||
DI::keyValue()->set('worker_daemon_mode', false);
|
|
||||||
die("Pidfile wasn't found. Is the daemon running?\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($mode == 'status') {
|
|
||||||
if (posix_kill($pid, 0)) {
|
|
||||||
die("Daemon process $pid is running.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
unlink($pidfile);
|
|
||||||
|
|
||||||
DI::keyValue()->set('worker_daemon_mode', false);
|
|
||||||
die("Daemon process $pid isn't running.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($mode == 'stop') {
|
|
||||||
posix_kill($pid, SIGTERM);
|
|
||||||
|
|
||||||
unlink($pidfile);
|
|
||||||
|
|
||||||
Logger::notice('Worker daemon process was killed', ['pid' => $pid]);
|
|
||||||
|
|
||||||
DI::keyValue()->set('worker_daemon_mode', false);
|
|
||||||
die("Worker daemon process $pid was killed.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($pid) && posix_kill($pid, 0)) {
|
|
||||||
die("Daemon process $pid is already running.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger::notice('Starting worker daemon.', ['pid' => $pid]);
|
|
||||||
|
|
||||||
if (!$foreground) {
|
|
||||||
echo "Starting worker daemon.\n";
|
|
||||||
|
|
||||||
DBA::disconnect();
|
|
||||||
|
|
||||||
// Fork a daemon process
|
|
||||||
$pid = pcntl_fork();
|
|
||||||
if ($pid == -1) {
|
|
||||||
echo "Daemon couldn't be forked.\n";
|
|
||||||
Logger::warning('Could not fork daemon');
|
|
||||||
exit(1);
|
|
||||||
} elseif ($pid) {
|
|
||||||
// The parent process continues here
|
|
||||||
if (!file_put_contents($pidfile, $pid)) {
|
|
||||||
echo "Pid file wasn't written.\n";
|
|
||||||
Logger::warning('Could not store pid file');
|
|
||||||
posix_kill($pid, SIGTERM);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
echo 'Child process started with pid ' . $pid . ".\n";
|
|
||||||
Logger::notice('Child process started', ['pid' => $pid]);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We now are in the child process
|
|
||||||
register_shutdown_function('shutdown');
|
|
||||||
|
|
||||||
// Make the child the main process, detach it from the terminal
|
|
||||||
if (posix_setsid() < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Closing all existing connections with the outside
|
|
||||||
fclose(STDIN);
|
|
||||||
|
|
||||||
// And now connect the database again
|
|
||||||
DBA::connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
DI::keyValue()->set('worker_daemon_mode', true);
|
|
||||||
|
|
||||||
// Just to be sure that this script really runs endlessly
|
|
||||||
set_time_limit(0);
|
|
||||||
|
|
||||||
$wait_interval = intval(DI::config()->get('system', 'cron_interval', 5)) * 60;
|
|
||||||
|
|
||||||
$do_cron = true;
|
|
||||||
$last_cron = 0;
|
|
||||||
|
|
||||||
// Now running as a daemon.
|
|
||||||
while (true) {
|
|
||||||
// Check the database structure and possibly fixes it
|
|
||||||
Update::check(DI::basePath(), true);
|
|
||||||
|
|
||||||
if (!$do_cron && ($last_cron + $wait_interval) < time()) {
|
|
||||||
Logger::info('Forcing cron worker call.', ['pid' => $pid]);
|
|
||||||
$do_cron = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($do_cron || (!DI::system()->isMaxLoadReached() && Worker::entriesExists() && Worker::isReady())) {
|
|
||||||
Worker::spawnWorker($do_cron);
|
|
||||||
} else {
|
|
||||||
Logger::info('Cool down for 5 seconds', ['pid' => $pid]);
|
|
||||||
sleep(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($do_cron) {
|
|
||||||
// We force a reconnect of the database connection.
|
|
||||||
// This is done to ensure that the connection don't get lost over time.
|
|
||||||
DBA::reconnect();
|
|
||||||
|
|
||||||
$last_cron = time();
|
|
||||||
}
|
|
||||||
|
|
||||||
$start = time();
|
|
||||||
Logger::info('Sleeping', ['pid' => $pid, 'until' => gmdate(DateTimeFormat::MYSQL, $start + $wait_interval)]);
|
|
||||||
|
|
||||||
do {
|
|
||||||
$seconds = (time() - $start);
|
|
||||||
|
|
||||||
// logarithmic wait time calculation.
|
|
||||||
// Background: After jobs had been started, they often fork many workers.
|
|
||||||
// To not waste too much time, the sleep period increases.
|
|
||||||
$arg = (($seconds + 1) / ($wait_interval / 9)) + 1;
|
|
||||||
$sleep = min(1000000, round(log10($arg) * 1000000, 0));
|
|
||||||
usleep($sleep);
|
|
||||||
|
|
||||||
$pid = pcntl_waitpid(-1, $status, WNOHANG);
|
|
||||||
if ($pid > 0) {
|
|
||||||
Logger::info('Children quit via pcntl_waitpid', ['pid' => $pid, 'status' => $status]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$timeout = ($seconds >= $wait_interval);
|
|
||||||
} while (!$timeout && !Worker\IPC::JobsExists());
|
|
||||||
|
|
||||||
if ($timeout) {
|
|
||||||
$do_cron = true;
|
|
||||||
Logger::info('Woke up after $wait_interval seconds.', ['pid' => $pid, 'sleep' => $wait_interval]);
|
|
||||||
} else {
|
|
||||||
$do_cron = false;
|
|
||||||
Logger::info('Worker jobs are calling to be forked.', ['pid' => $pid]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function shutdown() {
|
|
||||||
posix_kill(posix_getpid(), SIGTERM);
|
|
||||||
posix_kill(posix_getpid(), SIGHUP);
|
|
||||||
}
|
|
||||||
|
|
24
bin/dev/fix-codestyle.sh
Executable file
24
bin/dev/fix-codestyle.sh
Executable file
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# SPDX-FileCopyrightText: 2010-2025 the Friendica project
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
#
|
||||||
|
# this script checks or fixes php-files, based on the php-cs rules
|
||||||
|
#
|
||||||
|
# You can use the following variables:
|
||||||
|
# COMMAND ... the php-cs command to execute (default is "check --diff")
|
||||||
|
# TARGET_BRANCH ... set the target branch for the current branch to create a diff between them
|
||||||
|
#
|
||||||
|
##
|
||||||
|
|
||||||
|
COMMAND=${COMMAND:-"check --diff"}
|
||||||
|
|
||||||
|
if [ -n "${TARGET_BRANCH}" ]; then
|
||||||
|
CHANGED_FILES="$(git diff --name-only --diff-filter=ACMRTUXB "$(git ls-remote -q | grep refs/heads/"${TARGET_BRANCH}"$ | awk '{print $1}' | xargs git rev-parse )".."$(git rev-parse HEAD)")";
|
||||||
|
else
|
||||||
|
CHANGED_FILES="$(git diff --name-only --diff-filter=ACMRTUXB "$(git rev-parse HEAD)")";
|
||||||
|
fi
|
||||||
|
|
||||||
|
EXTRA_ARGS=$(printf -- '--path-mode=intersection\n--\n%s' "${CHANGED_FILES}");
|
||||||
|
|
||||||
|
./bin/dev/php-cs-fixer/vendor/bin/php-cs-fixer ${COMMAND} --config=.php-cs-fixer.dist.php -v --using-cache=no ${EXTRA_ARGS}
|
|
@ -42,6 +42,18 @@ openssl genrsa -out "$SSL_DIR/xip.io.key" 4096
|
||||||
openssl req -new -subj "$(echo -n "$SUBJ" | tr "\n" "/")" -key "$SSL_DIR/xip.io.key" -out "$SSL_DIR/xip.io.csr" -passin pass:$PASSPHRASE
|
openssl req -new -subj "$(echo -n "$SUBJ" | tr "\n" "/")" -key "$SSL_DIR/xip.io.key" -out "$SSL_DIR/xip.io.csr" -passin pass:$PASSPHRASE
|
||||||
openssl x509 -req -days 365 -in "$SSL_DIR/xip.io.csr" -signkey "$SSL_DIR/xip.io.key" -out "$SSL_DIR/xip.io.crt"
|
openssl x509 -req -days 365 -in "$SSL_DIR/xip.io.csr" -signkey "$SSL_DIR/xip.io.key" -out "$SSL_DIR/xip.io.crt"
|
||||||
|
|
||||||
|
#Install php
|
||||||
|
echo ">>> Add PHP repository"
|
||||||
|
apt-get install -qq -y lsb-release ca-certificates apt-transport-https software-properties-common gnupg
|
||||||
|
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/sury-php.list
|
||||||
|
wget -qO - https://packages.sury.org/php/apt.gpg | sudo gpg --dearmor --yes -o /etc/apt/trusted.gpg.d/php.gpg
|
||||||
|
apt update
|
||||||
|
|
||||||
|
echo ">>> Installing PHP8"
|
||||||
|
apt-get install -qq php libapache2-mod-php php8.3-cli php8.3-mysql php8.3-curl php8.3-gd php8.3-mbstring php8.3-xml imagemagick php8.3-imagick php8.3-zip php8.3-gmp php8.3-intl
|
||||||
|
|
||||||
|
echo ">>> Installing PHP7"
|
||||||
|
apt-get install -qq php7.4 php7.4-cli php7.4-mysql php7.4-curl php7.4-gd php7.4-mbstring php7.4-xml php7.4-imagick php7.4-zip php7.4-gmp php7.4-intl
|
||||||
|
|
||||||
#Install apache2
|
#Install apache2
|
||||||
echo ">>> Installing Apache2 webserver"
|
echo ">>> Installing Apache2 webserver"
|
||||||
|
@ -53,19 +65,6 @@ vhost -s 192.168.56.10.xip.io -d /var/www -p /etc/ssl/xip.io -c xip.io -a friend
|
||||||
a2dissite 000-default
|
a2dissite 000-default
|
||||||
service apache2 restart
|
service apache2 restart
|
||||||
|
|
||||||
#Install php
|
|
||||||
echo ">>> Installing PHP7"
|
|
||||||
apt-get install -qq php libapache2-mod-php php-cli php-mysql php-curl php-gd php-mbstring php-xml imagemagick php-imagick php-zip php-gmp
|
|
||||||
systemctl restart apache2
|
|
||||||
|
|
||||||
echo ">>> Installing PHP8"
|
|
||||||
apt-get install -qq -y lsb-release ca-certificates apt-transport-https software-properties-common gnupg
|
|
||||||
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/sury-php.list
|
|
||||||
wget -qO - https://packages.sury.org/php/apt.gpg | sudo apt-key add -
|
|
||||||
apt update
|
|
||||||
apt-get install -qq php8.0 php8.0-cli php8.0-mysql php8.0-curl php8.0-gd php8.0-mbstring php8.0-xml php8.0-imagick php8.0-zip php8.0-gmp
|
|
||||||
systemctl restart apache2
|
|
||||||
|
|
||||||
#Install mysql
|
#Install mysql
|
||||||
echo ">>> Installing Mysql"
|
echo ">>> Installing Mysql"
|
||||||
debconf-set-selections <<< "mariadb-server mariadb-server/root_password password root"
|
debconf-set-selections <<< "mariadb-server mariadb-server/root_password password root"
|
||||||
|
@ -130,7 +129,7 @@ bin/console user password "$USER_NICK" "$USER_PASSW"
|
||||||
# create cronjob - activate if you have enough memory in you dev VM
|
# create cronjob - activate if you have enough memory in you dev VM
|
||||||
# cronjob runs as www-data user
|
# cronjob runs as www-data user
|
||||||
echo ">>> Installing cronjob"
|
echo ">>> Installing cronjob"
|
||||||
echo "*/10 * * * * www-data cd /vagrant; /usr/bin/php bin/worker.php" >> /etc/cron.d/friendica
|
echo "*/10 * * * * www-data cd /vagrant; /usr/bin/php bin/console.php worker" >> /etc/cron.d/friendica
|
||||||
|
|
||||||
# friendica needs write access to /tmp
|
# friendica needs write access to /tmp
|
||||||
chmod 777 /tmp
|
chmod 777 /tmp
|
||||||
|
|
|
@ -6,16 +6,10 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*
|
*
|
||||||
|
* @deprecated 2025.02 use bin/console.php jetstream instead
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use Dice\Dice;
|
use Dice\Dice;
|
||||||
use Friendica\Core\Addon;
|
|
||||||
use Friendica\Core\Hook;
|
|
||||||
use Friendica\Core\Logger;
|
|
||||||
use Friendica\Database\DBA;
|
|
||||||
use Friendica\DI;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
use Friendica\Protocol\ATProtocol\Jetstream;
|
|
||||||
|
|
||||||
if (php_sapi_name() !== 'cli') {
|
if (php_sapi_name() !== 'cli') {
|
||||||
header($_SERVER["SERVER_PROTOCOL"] . ' 403 Forbidden');
|
header($_SERVER["SERVER_PROTOCOL"] . ' 403 Forbidden');
|
||||||
|
@ -23,162 +17,14 @@ if (php_sapi_name() !== 'cli') {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that Jetstream.php is executed from the base path of the installation
|
// Ensure that Jetstream.php is executed from the base path of the installation
|
||||||
if (!file_exists('index.php') && (sizeof((array)$_SERVER['argv']) != 0)) {
|
chdir(dirname(__DIR__));
|
||||||
$directory = dirname($_SERVER['argv'][0]);
|
|
||||||
|
|
||||||
if (substr($directory, 0, 1) != '/') {
|
|
||||||
$directory = $_SERVER['PWD'] . '/' . $directory;
|
|
||||||
}
|
|
||||||
$directory = realpath($directory . '/..');
|
|
||||||
|
|
||||||
chdir($directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
$dice = (new Dice())->addRules(include __DIR__ . '/../static/dependencies.config.php');
|
$dice = (new Dice())->addRules(require(dirname(__DIR__) . '/static/dependencies.config.php'));
|
||||||
/** @var \Friendica\Core\Addon\Capability\ICanLoadAddons $addonLoader */
|
|
||||||
$addonLoader = $dice->create(\Friendica\Core\Addon\Capability\ICanLoadAddons::class);
|
|
||||||
$dice = $dice->addRules($addonLoader->getActiveAddonConfig('dependencies'));
|
|
||||||
$dice = $dice->addRule(LoggerInterface::class, ['constructParams' => [Logger\Capability\LogChannel::DAEMON]]);
|
|
||||||
|
|
||||||
DI::init($dice);
|
$argv = $_SERVER['argv'] ?? [];
|
||||||
\Friendica\Core\Logger\Handler\ErrorHandler::register($dice->create(\Psr\Log\LoggerInterface::class));
|
array_splice($argv, 1, 0, "jetstream");
|
||||||
Addon::loadAddons();
|
|
||||||
Hook::loadHooks();
|
|
||||||
DI::config()->reload();
|
|
||||||
|
|
||||||
if (DI::mode()->isInstall()) {
|
$container = \Friendica\Core\Container::fromDice($dice);
|
||||||
die("Friendica isn't properly installed yet.\n");
|
\Friendica\Core\Console::create($container, $argv)->execute();
|
||||||
}
|
|
||||||
|
|
||||||
if (empty(DI::config()->get('jetstream', 'pidfile'))) {
|
|
||||||
die(<<<TXT
|
|
||||||
Please set jetstream.pidfile in config/local.config.php. For example:
|
|
||||||
|
|
||||||
'jetstream' => [
|
|
||||||
'pidfile' => '/path/to/jetstream.pid',
|
|
||||||
],
|
|
||||||
TXT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Addon::isEnabled('bluesky')) {
|
|
||||||
die("Bluesky has to be enabled.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
$pidfile = DI::config()->get('jetstream', 'pidfile');
|
|
||||||
|
|
||||||
if (in_array('start', (array)$_SERVER['argv'])) {
|
|
||||||
$mode = 'start';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array('stop', (array)$_SERVER['argv'])) {
|
|
||||||
$mode = 'stop';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array('status', (array)$_SERVER['argv'])) {
|
|
||||||
$mode = 'status';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($mode)) {
|
|
||||||
die("Please use either 'start', 'stop' or 'status'.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get options
|
|
||||||
$shortopts = 'f';
|
|
||||||
$longopts = ['foreground'];
|
|
||||||
$options = getopt($shortopts, $longopts);
|
|
||||||
|
|
||||||
$foreground = array_key_exists('f', $options) || array_key_exists('foreground', $options);
|
|
||||||
|
|
||||||
if (empty($_SERVER['argv'][0])) {
|
|
||||||
die("Unexpected script behaviour. This message should never occur.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
$pid = null;
|
|
||||||
|
|
||||||
if (is_readable($pidfile)) {
|
|
||||||
$pid = intval(file_get_contents($pidfile));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($pid) && in_array($mode, ['stop', 'status'])) {
|
|
||||||
die("Pidfile wasn't found. Is jetstream running?\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($mode == 'status') {
|
|
||||||
if (posix_kill($pid, 0)) {
|
|
||||||
die("Jetstream process $pid is running.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
unlink($pidfile);
|
|
||||||
|
|
||||||
die("Jetstream process $pid isn't running.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($mode == 'stop') {
|
|
||||||
posix_kill($pid, SIGTERM);
|
|
||||||
|
|
||||||
unlink($pidfile);
|
|
||||||
|
|
||||||
Logger::notice('Jetstream process was killed', ['pid' => $pid]);
|
|
||||||
|
|
||||||
die("Jetstream process $pid was killed.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($pid) && posix_kill($pid, 0)) {
|
|
||||||
die("Jetstream process $pid is already running.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger::notice('Starting jetstream daemon.', ['pid' => $pid]);
|
|
||||||
|
|
||||||
if (!$foreground) {
|
|
||||||
echo "Starting jetstream daemon.\n";
|
|
||||||
|
|
||||||
DBA::disconnect();
|
|
||||||
|
|
||||||
// Fork a daemon process
|
|
||||||
$pid = pcntl_fork();
|
|
||||||
if ($pid == -1) {
|
|
||||||
echo "Daemon couldn't be forked.\n";
|
|
||||||
Logger::warning('Could not fork daemon');
|
|
||||||
exit(1);
|
|
||||||
} elseif ($pid) {
|
|
||||||
// The parent process continues here
|
|
||||||
if (!file_put_contents($pidfile, $pid)) {
|
|
||||||
echo "Pid file wasn't written.\n";
|
|
||||||
Logger::warning('Could not store pid file');
|
|
||||||
posix_kill($pid, SIGTERM);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
echo 'Child process started with pid ' . $pid . ".\n";
|
|
||||||
Logger::notice('Child process started', ['pid' => $pid]);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We now are in the child process
|
|
||||||
register_shutdown_function('shutdown');
|
|
||||||
|
|
||||||
// Make the child the main process, detach it from the terminal
|
|
||||||
if (posix_setsid() < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Closing all existing connections with the outside
|
|
||||||
fclose(STDIN);
|
|
||||||
|
|
||||||
// And now connect the database again
|
|
||||||
DBA::connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just to be sure that this script really runs endlessly
|
|
||||||
set_time_limit(0);
|
|
||||||
|
|
||||||
// Now running as a daemon.
|
|
||||||
$jetstream = $dice->create(Jetstream::class);
|
|
||||||
$jetstream->listen();
|
|
||||||
|
|
||||||
function shutdown()
|
|
||||||
{
|
|
||||||
posix_kill(posix_getpid(), SIGTERM);
|
|
||||||
posix_kill(posix_getpid(), SIGHUP);
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*
|
*
|
||||||
* Starts the background processing
|
* Starts the background processing
|
||||||
|
*
|
||||||
|
* @deprecated 2025.02 use bin/console.php worker instead
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (php_sapi_name() !== 'cli') {
|
if (php_sapi_name() !== 'cli') {
|
||||||
|
@ -15,64 +17,16 @@ if (php_sapi_name() !== 'cli') {
|
||||||
}
|
}
|
||||||
|
|
||||||
use Dice\Dice;
|
use Dice\Dice;
|
||||||
use Friendica\App\Mode;
|
|
||||||
use Friendica\Core\Logger\Capability\LogChannel;
|
|
||||||
use Friendica\Core\Update;
|
|
||||||
use Friendica\Core\Worker;
|
|
||||||
use Friendica\DI;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
|
|
||||||
// Get options
|
|
||||||
$shortopts = 'sn';
|
|
||||||
$longopts = ['spawn', 'no_cron'];
|
|
||||||
$options = getopt($shortopts, $longopts);
|
|
||||||
|
|
||||||
// Ensure that worker.php is executed from the base path of the installation
|
// Ensure that worker.php is executed from the base path of the installation
|
||||||
if (!file_exists("index.php") && (sizeof($_SERVER["argv"]) != 0)) {
|
chdir(dirname(__DIR__));
|
||||||
$directory = dirname($_SERVER["argv"][0]);
|
|
||||||
|
|
||||||
if (substr($directory, 0, 1) != '/') {
|
|
||||||
$directory = $_SERVER["PWD"] . '/' . $directory;
|
|
||||||
}
|
|
||||||
$directory = realpath($directory . '/..');
|
|
||||||
|
|
||||||
chdir($directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
$dice = (new Dice())->addRules(include __DIR__ . '/../static/dependencies.config.php');
|
$dice = (new Dice())->addRules(require(dirname(__DIR__) . '/static/dependencies.config.php'));
|
||||||
/** @var \Friendica\Core\Addon\Capability\ICanLoadAddons $addonLoader */
|
|
||||||
$addonLoader = $dice->create(\Friendica\Core\Addon\Capability\ICanLoadAddons::class);
|
|
||||||
$dice = $dice->addRules($addonLoader->getActiveAddonConfig('dependencies'));
|
|
||||||
$dice = $dice->addRule(LoggerInterface::class, ['constructParams' => [LogChannel::WORKER]]);
|
|
||||||
|
|
||||||
DI::init($dice);
|
$argv = $_SERVER['argv'] ?? [];
|
||||||
\Friendica\Core\Logger\Handler\ErrorHandler::register($dice->create(\Psr\Log\LoggerInterface::class));
|
array_splice($argv, 1, 0, "worker");
|
||||||
|
|
||||||
DI::mode()->setExecutor(Mode::WORKER);
|
$container = \Friendica\Core\Container::fromDice($dice);
|
||||||
|
\Friendica\Core\Console::create($container, $argv)->execute();
|
||||||
// Check the database structure and possibly fixes it
|
|
||||||
Update::check(DI::basePath(), true);
|
|
||||||
|
|
||||||
// Quit when in maintenance
|
|
||||||
if (!DI::mode()->has(Mode::MAINTENANCEDISABLED)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$spawn = array_key_exists('s', $options) || array_key_exists('spawn', $options);
|
|
||||||
|
|
||||||
if ($spawn) {
|
|
||||||
Worker::spawnWorker();
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
$run_cron = !array_key_exists('n', $options) && !array_key_exists('no_cron', $options);
|
|
||||||
|
|
||||||
$process = DI::process()->create(getmypid(), basename(__FILE__));
|
|
||||||
|
|
||||||
Worker::processQueue($run_cron, $process);
|
|
||||||
|
|
||||||
Worker::unclaimProcess($process);
|
|
||||||
|
|
||||||
DI::process()->delete($process);
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
-- ------------------------------------------
|
-- ------------------------------------------
|
||||||
-- Friendica 2024.12-dev (Yellow Archangel)
|
-- Friendica 2025.02-dev (Interrupted Fern)
|
||||||
-- DB_UPDATE_VERSION 1576
|
-- DB_UPDATE_VERSION 1576
|
||||||
-- ------------------------------------------
|
-- ------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -268,7 +268,7 @@ You might wish to delete/rename `config/local.config.php` to another name and dr
|
||||||
Set up a cron job or scheduled task to run the worker once every 5-10 minutes in order to perform background processing.
|
Set up a cron job or scheduled task to run the worker once every 5-10 minutes in order to perform background processing.
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
cd /base/directory; /path/to/php bin/worker.php
|
cd /base/directory; /path/to/php bin/console.php worker
|
||||||
|
|
||||||
Change "/base/directory", and "/path/to/php" as appropriate for your situation.
|
Change "/base/directory", and "/path/to/php" as appropriate for your situation.
|
||||||
|
|
||||||
|
@ -277,7 +277,7 @@ Change "/base/directory", and "/path/to/php" as appropriate for your situation.
|
||||||
If you are using a Linux server, run "crontab -e" and add a line like the
|
If you are using a Linux server, run "crontab -e" and add a line like the
|
||||||
one shown, substituting for your unique paths and settings:
|
one shown, substituting for your unique paths and settings:
|
||||||
|
|
||||||
*/10 * * * * cd /home/myname/mywebsite; /usr/bin/php bin/worker.php
|
*/10 * * * * cd /home/myname/mywebsite; /usr/bin/php bin/console.php worker
|
||||||
|
|
||||||
You can generally find the location of PHP by executing "which php".
|
You can generally find the location of PHP by executing "which php".
|
||||||
If you run into trouble with this section please contact your hosting provider for assistance.
|
If you run into trouble with this section please contact your hosting provider for assistance.
|
||||||
|
@ -290,11 +290,11 @@ Once you have installed Friendica and created an admin account as part of the pr
|
||||||
#### worker alternative: daemon
|
#### worker alternative: daemon
|
||||||
Otherwise, you’ll need to use the command line on your remote server and start the Friendica daemon (background task) using the following command:
|
Otherwise, you’ll need to use the command line on your remote server and start the Friendica daemon (background task) using the following command:
|
||||||
|
|
||||||
cd /path/to/friendica; php bin/daemon.php start
|
cd /path/to/friendica; php bin/console.php daemon start
|
||||||
|
|
||||||
Once started, you can check the daemon status using the following command:
|
Once started, you can check the daemon status using the following command:
|
||||||
|
|
||||||
cd /path/to/friendica; php bin/daemon.php status
|
cd /path/to/friendica; php bin/console.php daemon status
|
||||||
|
|
||||||
After a server restart or any other failure, the daemon needs to be restarted.
|
After a server restart or any other failure, the daemon needs to be restarted.
|
||||||
This could be achieved by a cronjob.
|
This could be achieved by a cronjob.
|
||||||
|
@ -426,7 +426,7 @@ provided by one of our members.
|
||||||
>
|
>
|
||||||
> */10 * * * * cd /var/www/friendica/friendica/ && sudo -u www-data /usr/bin/php \
|
> */10 * * * * cd /var/www/friendica/friendica/ && sudo -u www-data /usr/bin/php \
|
||||||
> -d suhosin.executor.func.blacklist=none \
|
> -d suhosin.executor.func.blacklist=none \
|
||||||
> -d suhosin.executor.eval.blacklist=none -f bin/worker.php
|
> -d suhosin.executor.eval.blacklist=none -f bin/console.php
|
||||||
>
|
>
|
||||||
> This worked well for simple test cases, but the friendica-cron still failed
|
> This worked well for simple test cases, but the friendica-cron still failed
|
||||||
> with a fatal error:
|
> with a fatal error:
|
||||||
|
@ -435,7 +435,7 @@ provided by one of our members.
|
||||||
> (attacker 'REMOTE_ADDR not set', file '/var/www/friendica/friendica/boot.php',
|
> (attacker 'REMOTE_ADDR not set', file '/var/www/friendica/friendica/boot.php',
|
||||||
> line 1341)
|
> line 1341)
|
||||||
>
|
>
|
||||||
> After a while I noticed, that `bin/worker.php` calls further PHP script via `proc_open`.
|
> After a while I noticed, that `bin/console.php worker` calls further PHP script via `proc_open`.
|
||||||
> These scripts themselves also use `proc_open` and fail, because they are NOT
|
> These scripts themselves also use `proc_open` and fail, because they are NOT
|
||||||
> called with `-d suhosin.executor.func.blacklist=none`.
|
> called with `-d suhosin.executor.func.blacklist=none`.
|
||||||
>
|
>
|
||||||
|
|
|
@ -28,7 +28,7 @@ Jetstream is a service that connects to the Bluesky firehose.
|
||||||
With Jetstream, messages arrive in real time rather than having to be polled.
|
With Jetstream, messages arrive in real time rather than having to be polled.
|
||||||
It also enables real-time processing of blocks or tracking activities performed by the user via the Bluesky website or application.
|
It also enables real-time processing of blocks or tracking activities performed by the user via the Bluesky website or application.
|
||||||
|
|
||||||
To enable Jetstream processing, run `bin/jetstream.php' from the command line.
|
To enable Jetstream processing, run `bin/console.php jetstream' from the command line.
|
||||||
You will need to define the process id file in local.config.php in the 'jetstream' section using the key 'pidfile'.
|
You will need to define the process id file in local.config.php in the 'jetstream' section using the key 'pidfile'.
|
||||||
|
|
||||||
To keep track of the messages processed and the drift (the time difference between the date of the message and the date the system processed that message), some fields are added to the statistics endpoint.
|
To keep track of the messages processed and the drift (the time difference between the date of the message and the date the system processed that message), some fields are added to the statistics endpoint.
|
|
@ -57,7 +57,7 @@ Finally, you may also want to optimise your database with the following command:
|
||||||
|
|
||||||
### Going offline
|
### Going offline
|
||||||
Stop background tasks and put your server in maintenance mode.
|
Stop background tasks and put your server in maintenance mode.
|
||||||
1. If you had set up a worker cron job like this ``*/10 * * * * cd /var/www/friendica; /usr/bin/php bin/worker.php`` run ``crontab -e`` and comment out this line. Alternatively if you deploy a worker daemon, disable this instead.
|
1. If you had set up a worker cron job like this ``*/10 * * * * cd /var/www/friendica; /usr/bin/php bin/console.php worker`` run ``crontab -e`` and comment out this line. Alternatively if you deploy a worker daemon, disable this instead.
|
||||||
2. Put your server into maintenance mode: ``bin/console maintenance 1 "We are currently upgrading our system and will be back soon."``
|
2. Put your server into maintenance mode: ``bin/console maintenance 1 "We are currently upgrading our system and will be back soon."``
|
||||||
|
|
||||||
## Dumping DB
|
## Dumping DB
|
||||||
|
@ -78,7 +78,7 @@ Ensure the newly created database credentials are identical to the setting in th
|
||||||
### Cron job for worker
|
### Cron job for worker
|
||||||
Set up the required daily cron job.
|
Set up the required daily cron job.
|
||||||
Run ``crontab -e`` and add the following line according to your system specification
|
Run ``crontab -e`` and add the following line according to your system specification
|
||||||
``*/10 * * * * cd /var/www/friendica; /usr/bin/php bin/worker.php``
|
``*/10 * * * * cd /var/www/friendica; /usr/bin/php bin/console.php worker``
|
||||||
|
|
||||||
### DNS settings
|
### DNS settings
|
||||||
Adjust your DNS records by pointing them to your new server.
|
Adjust your DNS records by pointing them to your new server.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
This is your Suggested Friends page.
|
This is your Suggested Friends page.
|
||||||
If you get lost, you can <a href="help/Quick-Start-makenewfriends">click this link</a> to bring yourself back here.
|
If you get lost, you can <a href="help/Quick-Start-makingnewfriends">click this link</a> to bring yourself back here.
|
||||||
|
|
||||||
This is a bit like the Friend Suggestions page of Facebook.
|
This is a bit like the Friend Suggestions page of Facebook.
|
||||||
Everybody on this list has agreed that they may be suggested as a friend.
|
Everybody on this list has agreed that they may be suggested as a friend.
|
||||||
|
@ -16,6 +16,6 @@ Click the link at the top of this page to go back to the suggested friends list
|
||||||
Feel uncomfortable adding people you don't know?
|
Feel uncomfortable adding people you don't know?
|
||||||
Don't worry - that's where <a href="help/Quick-Start-groupsandpages">Groups and Pages</a> come in!
|
Don't worry - that's where <a href="help/Quick-Start-groupsandpages">Groups and Pages</a> come in!
|
||||||
|
|
||||||
<iframe src="suggest" width="950" height="600"></iframe>
|
<iframe src="contact/suggestions" width="950" height="600"></iframe>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -210,13 +210,13 @@ Gehe in den Friendica-Hauptordner und führe den Kommandozeilen Befehl aus:
|
||||||
Erstelle einen Cron job oder einen regelmäßigen Task, um den Poller alle 5-10 Minuten im Hintergrund ablaufen zu lassen.
|
Erstelle einen Cron job oder einen regelmäßigen Task, um den Poller alle 5-10 Minuten im Hintergrund ablaufen zu lassen.
|
||||||
Beispiel:
|
Beispiel:
|
||||||
|
|
||||||
cd /base/directory; /path/to/php bin/worker.php
|
cd /base/directory; /path/to/php bin/console.php worker
|
||||||
|
|
||||||
Ändere "/base/directory" und "/path/to/php" auf deine Systemvorgaben.
|
Ändere "/base/directory" und "/path/to/php" auf deine Systemvorgaben.
|
||||||
|
|
||||||
Wenn du einen Linux-Server nutzt, benutze den Befehl "crontab -e" und ergänze eine Zeile wie die Folgende; angepasst an dein System
|
Wenn du einen Linux-Server nutzt, benutze den Befehl "crontab -e" und ergänze eine Zeile wie die Folgende; angepasst an dein System
|
||||||
|
|
||||||
`*/10 * * * * cd /home/myname/mywebsite; /usr/bin/php bin/worker.php`
|
`*/10 * * * * cd /home/myname/mywebsite; /usr/bin/php bin/console.php worker`
|
||||||
|
|
||||||
Du kannst den PHP-Pfad finden, indem du den Befehl „which php“ ausführst.
|
Du kannst den PHP-Pfad finden, indem du den Befehl „which php“ ausführst.
|
||||||
Wenn du Schwierigkeiten mit diesem Schritt hast, kannst du deinen Hosting-Anbieter kontaktieren.
|
Wenn du Schwierigkeiten mit diesem Schritt hast, kannst du deinen Hosting-Anbieter kontaktieren.
|
||||||
|
|
|
@ -27,7 +27,7 @@ Jetstream ist ein Dienst, der sich mit dem Bluesky-Firehose verbindet.
|
||||||
Mit Jetstream kommen die Nachrichten in Echtzeit an und müssen nicht erst abgefragt werden.
|
Mit Jetstream kommen die Nachrichten in Echtzeit an und müssen nicht erst abgefragt werden.
|
||||||
Es ermöglicht auch die Echtzeitverarbeitung von Blöcken oder Tracking-Aktivitäten, die über die Bluesky-Website oder -Anwendung durchgeführt werden.
|
Es ermöglicht auch die Echtzeitverarbeitung von Blöcken oder Tracking-Aktivitäten, die über die Bluesky-Website oder -Anwendung durchgeführt werden.
|
||||||
|
|
||||||
Um die Jetstream-Verarbeitung zu aktivieren, führe `bin/jetstream.php' über die Befehlszeile aus.
|
Um die Jetstream-Verarbeitung zu aktivieren, führe `bin/console.php daemon' über die Befehlszeile aus.
|
||||||
Du musst vorher die Prozess-ID-Datei in local.config.php im Abschnitt „jetstream“ mit dem Schlüssel „pidfile“ definieren.
|
Du musst vorher die Prozess-ID-Datei in local.config.php im Abschnitt „jetstream“ mit dem Schlüssel „pidfile“ definieren.
|
||||||
|
|
||||||
Um die verarbeiteten Nachrichten und die Drift (die Zeitdifferenz zwischen dem Datum der Nachricht und dem Datum, an dem das System diese Nachricht verarbeitet hat) zu verfolgen, wurden dem Statistik-Endpunkt einige Felder hinzugefügt.
|
Um die verarbeiteten Nachrichten und die Drift (die Zeitdifferenz zwischen dem Datum der Nachricht und dem Datum, an dem das System diese Nachricht verarbeitet hat) zu verfolgen, wurden dem Statistik-Endpunkt einige Felder hinzugefügt.
|
||||||
|
|
|
@ -4,7 +4,7 @@ Neue Freunde finden
|
||||||
* [Zur Startseite der Hilfe](help)
|
* [Zur Startseite der Hilfe](help)
|
||||||
|
|
||||||
Hier siehst Du die Kontaktvorschläge.
|
Hier siehst Du die Kontaktvorschläge.
|
||||||
Wenn Du Dich mal verirrt hast, kannst Du diesen Link klicken und wieder hierher kommen.
|
Wenn Du Dich mal verirrt hast, kannst Du <a href="help/Quick-Start-makingnewfriends">diesen Link klicken</a> und wieder hierher kommen.
|
||||||
|
|
||||||
Diese Seite funktioniert in etwa wie die Seite für Kontaktvorschläge in Facebook.
|
Diese Seite funktioniert in etwa wie die Seite für Kontaktvorschläge in Facebook.
|
||||||
Jeder auf dieser Liste hat zugestimmt, als Kontaktvorschlag zu erscheinen.
|
Jeder auf dieser Liste hat zugestimmt, als Kontaktvorschlag zu erscheinen.
|
||||||
|
@ -23,6 +23,6 @@ Klicke einfach auf den Link oben auf dieser Seite und Du gelangst zur Seite mit
|
||||||
Du willst nicht einfach Personen hinzufügen, die du nicht kennst?
|
Du willst nicht einfach Personen hinzufügen, die du nicht kennst?
|
||||||
Kein Problem - an dieser Stelle kommen wir zu den <a href="help/Quick-Start-groupsandpages">Gruppen und Seiten</a>.
|
Kein Problem - an dieser Stelle kommen wir zu den <a href="help/Quick-Start-groupsandpages">Gruppen und Seiten</a>.
|
||||||
|
|
||||||
<iframe src="suggest" width="950" height="600"></iframe>
|
<iframe src="contact/suggestions" width="950" height="600"></iframe>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,9 @@ require __DIR__ . '/vendor/autoload.php';
|
||||||
|
|
||||||
$request = \GuzzleHttp\Psr7\ServerRequest::fromGlobals();
|
$request = \GuzzleHttp\Psr7\ServerRequest::fromGlobals();
|
||||||
|
|
||||||
$dice = (new Dice())->addRules(include __DIR__ . '/static/dependencies.config.php');
|
$dice = (new Dice())->addRules(require(__DIR__ . '/static/dependencies.config.php'));
|
||||||
|
|
||||||
$app = \Friendica\App::fromDice($dice);
|
$container = \Friendica\Core\Container::fromDice($dice);
|
||||||
|
$app = \Friendica\App::fromContainer($container);
|
||||||
|
|
||||||
$app->processRequest($request, $start_time);
|
$app->processRequest($request, $start_time);
|
||||||
|
|
|
@ -6,4 +6,4 @@ Description=Friendica Worker
|
||||||
User=http
|
User=http
|
||||||
#Adapt the path in the following line to your system, use 'which php' to find php path,
|
#Adapt the path in the following line to your system, use 'which php' to find php path,
|
||||||
#provide the absolute path for worker.php
|
#provide the absolute path for worker.php
|
||||||
ExecStart=/usr/bin/php /www/path/bin/worker.php &
|
ExecStart=/usr/bin/php /www/path/bin/console.php worker &
|
||||||
|
|
150
src/App.php
150
src/App.php
|
@ -15,23 +15,28 @@ use Friendica\App\Page;
|
||||||
use Friendica\App\Request;
|
use Friendica\App\Request;
|
||||||
use Friendica\App\Router;
|
use Friendica\App\Router;
|
||||||
use Friendica\Capabilities\ICanCreateResponses;
|
use Friendica\Capabilities\ICanCreateResponses;
|
||||||
|
use Friendica\Capabilities\ICanHandleRequests;
|
||||||
use Friendica\Content\Nav;
|
use Friendica\Content\Nav;
|
||||||
use Friendica\Core\Config\Factory\Config;
|
use Friendica\Core\Config\Factory\Config;
|
||||||
|
use Friendica\Core\Container;
|
||||||
|
use Friendica\Core\Renderer;
|
||||||
use Friendica\Core\Session\Capability\IHandleUserSessions;
|
use Friendica\Core\Session\Capability\IHandleUserSessions;
|
||||||
use Friendica\Database\Definition\DbaDefinition;
|
use Friendica\Database\Definition\DbaDefinition;
|
||||||
use Friendica\Database\Definition\ViewDefinition;
|
use Friendica\Database\Definition\ViewDefinition;
|
||||||
use Friendica\Module\Maintenance;
|
use Friendica\Module\Maintenance;
|
||||||
use Friendica\Security\Authentication;
|
use Friendica\Security\Authentication;
|
||||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
|
use Friendica\Core\L10n;
|
||||||
use Friendica\Core\Logger\Capability\LogChannel;
|
use Friendica\Core\Logger\Capability\LogChannel;
|
||||||
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
|
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
|
||||||
use Friendica\Core\L10n;
|
|
||||||
use Friendica\Core\System;
|
use Friendica\Core\System;
|
||||||
|
use Friendica\Core\Update;
|
||||||
use Friendica\Module\Special\HTTPException as ModuleHTTPException;
|
use Friendica\Module\Special\HTTPException as ModuleHTTPException;
|
||||||
use Friendica\Network\HTTPException;
|
use Friendica\Network\HTTPException;
|
||||||
use Friendica\Protocol\ATProtocol\DID;
|
use Friendica\Protocol\ATProtocol\DID;
|
||||||
use Friendica\Security\ExAuth;
|
use Friendica\Security\ExAuth;
|
||||||
use Friendica\Security\OpenWebAuth;
|
use Friendica\Security\OpenWebAuth;
|
||||||
|
use Friendica\Util\BasePath;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
use Friendica\Util\HTTPInputData;
|
use Friendica\Util\HTTPInputData;
|
||||||
use Friendica\Util\HTTPSignature;
|
use Friendica\Util\HTTPSignature;
|
||||||
|
@ -52,16 +57,16 @@ use Psr\Log\LoggerInterface;
|
||||||
class App
|
class App
|
||||||
{
|
{
|
||||||
const PLATFORM = 'Friendica';
|
const PLATFORM = 'Friendica';
|
||||||
const CODENAME = 'Yellow Archangel';
|
const CODENAME = 'Interrupted Fern';
|
||||||
const VERSION = '2024.12-dev';
|
const VERSION = '2025.02-dev';
|
||||||
|
|
||||||
public static function fromDice(Dice $dice): self
|
public static function fromContainer(Container $container): self
|
||||||
{
|
{
|
||||||
return new self($dice);
|
return new self($container);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Dice
|
* @var Container
|
||||||
*/
|
*/
|
||||||
private $container;
|
private $container;
|
||||||
|
|
||||||
|
@ -116,24 +121,20 @@ class App
|
||||||
*/
|
*/
|
||||||
private $appHelper;
|
private $appHelper;
|
||||||
|
|
||||||
private function __construct(Dice $container)
|
private function __construct(Container $container)
|
||||||
{
|
{
|
||||||
$this->container = $container;
|
$this->container = $container;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function processRequest(ServerRequestInterface $request, float $start_time): void
|
public function processRequest(ServerRequestInterface $request, float $start_time): void
|
||||||
{
|
{
|
||||||
$this->setupContainerForAddons();
|
$this->container->addRule(Mode::class, [
|
||||||
|
|
||||||
$this->container = $this->container->addRule(Mode::class, [
|
|
||||||
'call' => [
|
'call' => [
|
||||||
['determineRunMode', [false, $request->getServerParams()], Dice::CHAIN_CALL],
|
['determineRunMode', [false, $request->getServerParams()], Dice::CHAIN_CALL],
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->setupLegacyServiceLocator();
|
$this->container->setup(LogChannel::APP, false);
|
||||||
|
|
||||||
$this->registerErrorHandler();
|
|
||||||
|
|
||||||
$this->requestId = $this->container->create(Request::class)->getRequestId();
|
$this->requestId = $this->container->create(Request::class)->getRequestId();
|
||||||
$this->auth = $this->container->create(Authentication::class);
|
$this->auth = $this->container->create(Authentication::class);
|
||||||
|
@ -147,39 +148,35 @@ class App
|
||||||
$this->session = $this->container->create(IHandleUserSessions::class);
|
$this->session = $this->container->create(IHandleUserSessions::class);
|
||||||
$this->appHelper = $this->container->create(AppHelper::class);
|
$this->appHelper = $this->container->create(AppHelper::class);
|
||||||
|
|
||||||
$this->load(
|
$this->loadSetupForFrontend(
|
||||||
|
$request,
|
||||||
$this->container->create(DbaDefinition::class),
|
$this->container->create(DbaDefinition::class),
|
||||||
$this->container->create(ViewDefinition::class),
|
$this->container->create(ViewDefinition::class),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->registerTemplateEngine();
|
||||||
|
|
||||||
$this->mode->setExecutor(Mode::INDEX);
|
$this->mode->setExecutor(Mode::INDEX);
|
||||||
|
|
||||||
$this->runFrontend(
|
$this->runFrontend(
|
||||||
$this->container->create(Router::class),
|
|
||||||
$this->container->create(IManagePersonalConfigValues::class),
|
$this->container->create(IManagePersonalConfigValues::class),
|
||||||
$this->container->create(Page::class),
|
$this->container->create(Page::class),
|
||||||
$this->container->create(Nav::class),
|
$this->container->create(Nav::class),
|
||||||
$this->container->create(ModuleHTTPException::class),
|
$this->container->create(ModuleHTTPException::class),
|
||||||
new HTTPInputData($request->getServerParams()),
|
|
||||||
$start_time,
|
$start_time,
|
||||||
$request->getServerParams()
|
$request
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function processEjabberd(): void
|
public function processEjabberd(): void
|
||||||
{
|
{
|
||||||
$this->setupContainerForAddons();
|
$this->container->setup(LogChannel::AUTH_JABBERED, false);
|
||||||
|
|
||||||
$this->container = $this->container->addRule(LoggerInterface::class,[
|
/** @var BasePath */
|
||||||
'constructParams' => [LogChannel::AUTH_JABBERED],
|
$basePath = $this->container->create(BasePath::class);
|
||||||
]);
|
|
||||||
|
|
||||||
$this->setupLegacyServiceLocator();
|
|
||||||
|
|
||||||
$this->registerErrorHandler();
|
|
||||||
|
|
||||||
// Check the database structure and possibly fixes it
|
// Check the database structure and possibly fixes it
|
||||||
\Friendica\Core\Update::check(\Friendica\DI::basePath(), true);
|
Update::check($basePath->getPath(), true);
|
||||||
|
|
||||||
$appMode = $this->container->create(Mode::class);
|
$appMode = $this->container->create(Mode::class);
|
||||||
|
|
||||||
|
@ -190,28 +187,15 @@ class App
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setupContainerForAddons(): void
|
private function registerTemplateEngine(): void
|
||||||
{
|
{
|
||||||
/** @var \Friendica\Core\Addon\Capability\ICanLoadAddons $addonLoader */
|
Renderer::registerTemplateEngine('Friendica\Render\FriendicaSmartyEngine');
|
||||||
$addonLoader = $this->container->create(\Friendica\Core\Addon\Capability\ICanLoadAddons::class);
|
|
||||||
|
|
||||||
$this->container = $this->container->addRules($addonLoader->getActiveAddonConfig('dependencies'));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function setupLegacyServiceLocator(): void
|
|
||||||
{
|
|
||||||
\Friendica\DI::init($this->container);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function registerErrorHandler(): void
|
|
||||||
{
|
|
||||||
\Friendica\Core\Logger\Handler\ErrorHandler::register($this->container->create(LoggerInterface::class));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the whole app instance
|
* Load the whole app instance
|
||||||
*/
|
*/
|
||||||
private function load(DbaDefinition $dbaDefinition, ViewDefinition $viewDefinition)
|
private function loadSetupForFrontend(ServerRequestInterface $request, DbaDefinition $dbaDefinition, ViewDefinition $viewDefinition)
|
||||||
{
|
{
|
||||||
if ($this->config->get('system', 'ini_max_execution_time') !== false) {
|
if ($this->config->get('system', 'ini_max_execution_time') !== false) {
|
||||||
set_time_limit((int)$this->config->get('system', 'ini_max_execution_time'));
|
set_time_limit((int)$this->config->get('system', 'ini_max_execution_time'));
|
||||||
|
@ -233,7 +217,7 @@ class App
|
||||||
|
|
||||||
if ($this->mode->has(Mode::DBAVAILABLE)) {
|
if ($this->mode->has(Mode::DBAVAILABLE)) {
|
||||||
Core\Hook::loadHooks();
|
Core\Hook::loadHooks();
|
||||||
$loader = (new Config())->createConfigFileManager($this->appHelper->getBasePath(), $_SERVER);
|
$loader = (new Config())->createConfigFileManager($this->appHelper->getBasePath(), $request->getServerParams());
|
||||||
Core\Hook::callAll('load_config', $loader);
|
Core\Hook::callAll('load_config', $loader);
|
||||||
|
|
||||||
// Hooks are now working, reload the whole definitions with hook enabled
|
// Hooks are now working, reload the whole definitions with hook enabled
|
||||||
|
@ -242,8 +226,6 @@ class App
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->loadDefaultTimezone();
|
$this->loadDefaultTimezone();
|
||||||
// Register template engines
|
|
||||||
Core\Renderer::registerTemplateEngine('Friendica\Render\FriendicaSmartyEngine');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -273,29 +255,28 @@ class App
|
||||||
*
|
*
|
||||||
* This probably should change to limit the size of this monster method.
|
* This probably should change to limit the size of this monster method.
|
||||||
*
|
*
|
||||||
* @param Router $router
|
|
||||||
* @param IManagePersonalConfigValues $pconfig
|
* @param IManagePersonalConfigValues $pconfig
|
||||||
* @param Page $page The Friendica page printing container
|
* @param Page $page The Friendica page printing container
|
||||||
* @param ModuleHTTPException $httpException The possible HTTP Exception container
|
* @param ModuleHTTPException $httpException The possible HTTP Exception container
|
||||||
* @param HTTPInputData $httpInput A library for processing PHP input streams
|
|
||||||
* @param float $start_time The start time of the overall script execution
|
* @param float $start_time The start time of the overall script execution
|
||||||
* @param array $server The $_SERVER array
|
|
||||||
*
|
*
|
||||||
* @throws HTTPException\InternalServerErrorException
|
* @throws HTTPException\InternalServerErrorException
|
||||||
* @throws \ImagickException
|
* @throws \ImagickException
|
||||||
*/
|
*/
|
||||||
private function runFrontend(
|
private function runFrontend(
|
||||||
Router $router,
|
|
||||||
IManagePersonalConfigValues $pconfig,
|
IManagePersonalConfigValues $pconfig,
|
||||||
Page $page,
|
Page $page,
|
||||||
Nav $nav,
|
Nav $nav,
|
||||||
ModuleHTTPException $httpException,
|
ModuleHTTPException $httpException,
|
||||||
HTTPInputData $httpInput,
|
|
||||||
float $start_time,
|
float $start_time,
|
||||||
array $server
|
ServerRequestInterface $request
|
||||||
) {
|
) {
|
||||||
$requeststring = ($server['REQUEST_METHOD'] ?? '') . ' ' . ($server['REQUEST_URI'] ?? '') . ' ' . ($server['SERVER_PROTOCOL'] ?? '');
|
$httpInput = new HTTPInputData($request->getServerParams());
|
||||||
$this->logger->debug('Request received', ['address' => $server['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $server['HTTP_REFERER'] ?? '', 'user-agent' => $server['HTTP_USER_AGENT'] ?? '']);
|
$serverVars = $request->getServerParams();
|
||||||
|
$queryVars = $request->getQueryParams();
|
||||||
|
|
||||||
|
$requeststring = ($serverVars['REQUEST_METHOD'] ?? '') . ' ' . ($serverVars['REQUEST_URI'] ?? '') . ' ' . ($serverVars['SERVER_PROTOCOL'] ?? '');
|
||||||
|
$this->logger->debug('Request received', ['address' => $serverVars['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $serverVars['HTTP_REFERER'] ?? '', 'user-agent' => $serverVars['HTTP_USER_AGENT'] ?? '']);
|
||||||
$request_start = microtime(true);
|
$request_start = microtime(true);
|
||||||
$request = $_REQUEST;
|
$request = $_REQUEST;
|
||||||
|
|
||||||
|
@ -314,42 +295,42 @@ class App
|
||||||
if (!$this->mode->isInstall()) {
|
if (!$this->mode->isInstall()) {
|
||||||
// Force SSL redirection
|
// Force SSL redirection
|
||||||
if ($this->config->get('system', 'force_ssl') &&
|
if ($this->config->get('system', 'force_ssl') &&
|
||||||
(empty($server['HTTPS']) || $server['HTTPS'] === 'off') &&
|
(empty($serverVars['HTTPS']) || $serverVars['HTTPS'] === 'off') &&
|
||||||
(empty($server['HTTP_X_FORWARDED_PROTO']) || $server['HTTP_X_FORWARDED_PROTO'] === 'http') &&
|
(empty($serverVars['HTTP_X_FORWARDED_PROTO']) || $serverVars['HTTP_X_FORWARDED_PROTO'] === 'http') &&
|
||||||
!empty($server['REQUEST_METHOD']) &&
|
!empty($serverVars['REQUEST_METHOD']) &&
|
||||||
$server['REQUEST_METHOD'] === 'GET') {
|
$serverVars['REQUEST_METHOD'] === 'GET') {
|
||||||
System::externalRedirect($this->baseURL . '/' . $this->args->getQueryString());
|
System::externalRedirect($this->baseURL . '/' . $this->args->getQueryString());
|
||||||
}
|
}
|
||||||
Core\Hook::callAll('init_1');
|
Core\Hook::callAll('init_1');
|
||||||
}
|
}
|
||||||
|
|
||||||
DID::routeRequest($this->args->getCommand(), $server);
|
DID::routeRequest($this->args->getCommand(), $serverVars);
|
||||||
|
|
||||||
if ($this->mode->isNormal() && !$this->mode->isBackend()) {
|
if ($this->mode->isNormal() && !$this->mode->isBackend()) {
|
||||||
$requester = HTTPSignature::getSigner('', $server);
|
$requester = HTTPSignature::getSigner('', $serverVars);
|
||||||
if (!empty($requester)) {
|
if (!empty($requester)) {
|
||||||
OpenWebAuth::addVisitorCookieForHandle($requester);
|
OpenWebAuth::addVisitorCookieForHandle($requester);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ZRL
|
// ZRL
|
||||||
if (!empty($_GET['zrl']) && $this->mode->isNormal() && !$this->mode->isBackend() && !$this->session->getLocalUserId()) {
|
if (!empty($queryVars['zrl']) && $this->mode->isNormal() && !$this->mode->isBackend() && !$this->session->getLocalUserId()) {
|
||||||
// Only continue when the given profile link seems valid.
|
// Only continue when the given profile link seems valid.
|
||||||
// Valid profile links contain a path with "/profile/" and no query parameters
|
// Valid profile links contain a path with "/profile/" and no query parameters
|
||||||
if ((parse_url($_GET['zrl'], PHP_URL_QUERY) == '') &&
|
if ((parse_url($queryVars['zrl'], PHP_URL_QUERY) == '') &&
|
||||||
strpos(parse_url($_GET['zrl'], PHP_URL_PATH) ?? '', '/profile/') !== false) {
|
strpos(parse_url($queryVars['zrl'], PHP_URL_PATH) ?? '', '/profile/') !== false) {
|
||||||
$this->auth->setUnauthenticatedVisitor($_GET['zrl']);
|
$this->auth->setUnauthenticatedVisitor($queryVars['zrl']);
|
||||||
OpenWebAuth::zrlInit();
|
OpenWebAuth::zrlInit();
|
||||||
} else {
|
} else {
|
||||||
// Someone came with an invalid parameter, maybe as a DDoS attempt
|
// Someone came with an invalid parameter, maybe as a DDoS attempt
|
||||||
// We simply stop processing here
|
// We simply stop processing here
|
||||||
$this->logger->debug('Invalid ZRL parameter.', ['zrl' => $_GET['zrl']]);
|
$this->logger->debug('Invalid ZRL parameter.', ['zrl' => $queryVars['zrl']]);
|
||||||
throw new HTTPException\ForbiddenException();
|
throw new HTTPException\ForbiddenException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($_GET['owt']) && $this->mode->isNormal()) {
|
if (!empty($queryVars['owt']) && $this->mode->isNormal()) {
|
||||||
$token = $_GET['owt'];
|
$token = $queryVars['owt'];
|
||||||
OpenWebAuth::init($token);
|
OpenWebAuth::init($token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,11 +401,11 @@ class App
|
||||||
|
|
||||||
// The "view" module is required to show the theme CSS
|
// The "view" module is required to show the theme CSS
|
||||||
if (!$this->mode->isInstall() && !$this->mode->has(Mode::MAINTENANCEDISABLED) && $moduleName !== 'view') {
|
if (!$this->mode->isInstall() && !$this->mode->has(Mode::MAINTENANCEDISABLED) && $moduleName !== 'view') {
|
||||||
$module = $router->getModule(Maintenance::class);
|
$module = $this->createModuleInstance(Maintenance::class);
|
||||||
} else {
|
} else {
|
||||||
// determine the module class and save it to the module instance
|
// determine the module class and save it to the module instance
|
||||||
// @todo there's an implicit dependency due SESSION::start(), so it has to be called here (yet)
|
// @todo there's an implicit dependency due SESSION::start(), so it has to be called here (yet)
|
||||||
$module = $router->getModule();
|
$module = $this->createModuleInstance(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display can change depending on the requested language, so it shouldn't be cached whole
|
// Display can change depending on the requested language, so it shouldn't be cached whole
|
||||||
|
@ -444,17 +425,42 @@ class App
|
||||||
$response = $page->run($this->appHelper, $this->session, $this->baseURL, $this->args, $this->mode, $response, $this->l10n, $this->profiler, $this->config, $pconfig, $nav, $this->session->getLocalUserId());
|
$response = $page->run($this->appHelper, $this->session, $this->baseURL, $this->args, $this->mode, $response, $this->l10n, $this->profiler, $this->config, $pconfig, $nav, $this->session->getLocalUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->logger->debug('Request processed sucessfully', ['response' => $response->getStatusCode(), 'address' => $server['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $server['HTTP_REFERER'] ?? '', 'user-agent' => $server['HTTP_USER_AGENT'] ?? '', 'duration' => number_format(microtime(true) - $request_start, 3)]);
|
$this->logger->debug('Request processed sucessfully', ['response' => $response->getStatusCode(), 'address' => $serverVars['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $serverVars['HTTP_REFERER'] ?? '', 'user-agent' => $serverVars['HTTP_USER_AGENT'] ?? '', 'duration' => number_format(microtime(true) - $request_start, 3)]);
|
||||||
$this->logSlowCalls(microtime(true) - $request_start, $response->getStatusCode(), $requeststring, $server['HTTP_USER_AGENT'] ?? '');
|
$this->logSlowCalls(microtime(true) - $request_start, $response->getStatusCode(), $requeststring, $serverVars['HTTP_USER_AGENT'] ?? '');
|
||||||
System::echoResponse($response);
|
System::echoResponse($response);
|
||||||
} catch (HTTPException $e) {
|
} catch (HTTPException $e) {
|
||||||
$this->logger->debug('Request processed with exception', ['response' => $e->getCode(), 'address' => $server['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $server['HTTP_REFERER'] ?? '', 'user-agent' => $server['HTTP_USER_AGENT'] ?? '', 'duration' => number_format(microtime(true) - $request_start, 3)]);
|
$this->logger->debug('Request processed with exception', ['response' => $e->getCode(), 'address' => $serverVars['REMOTE_ADDR'] ?? '', 'request' => $requeststring, 'referer' => $serverVars['HTTP_REFERER'] ?? '', 'user-agent' => $serverVars['HTTP_USER_AGENT'] ?? '', 'duration' => number_format(microtime(true) - $request_start, 3)]);
|
||||||
$this->logSlowCalls(microtime(true) - $request_start, $e->getCode(), $requeststring, $server['HTTP_USER_AGENT'] ?? '');
|
$this->logSlowCalls(microtime(true) - $request_start, $e->getCode(), $requeststring, $serverVars['HTTP_USER_AGENT'] ?? '');
|
||||||
$httpException->rawContent($e);
|
$httpException->rawContent($e);
|
||||||
}
|
}
|
||||||
$page->logRuntime($this->config, 'runFrontend');
|
$page->logRuntime($this->config, 'runFrontend');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function createModuleInstance(?string $moduleClass = null): ICanHandleRequests
|
||||||
|
{
|
||||||
|
/** @var Router $router */
|
||||||
|
$router = $this->container->create(Router::class);
|
||||||
|
|
||||||
|
$moduleClass = $moduleClass ?? $router->getModuleClass();
|
||||||
|
$parameters = $router->getParameters();
|
||||||
|
|
||||||
|
$dice_profiler_threshold = $this->config->get('system', 'dice_profiler_threshold', 0);
|
||||||
|
|
||||||
|
$stamp = microtime(true);
|
||||||
|
|
||||||
|
/** @var ICanHandleRequests $module */
|
||||||
|
$module = $this->container->create($moduleClass, $parameters);
|
||||||
|
|
||||||
|
if ($dice_profiler_threshold > 0) {
|
||||||
|
$dur = floatval(microtime(true) - $stamp);
|
||||||
|
if ($dur >= $dice_profiler_threshold) {
|
||||||
|
$this->logger->notice('Dice module creation lasts too long.', ['duration' => round($dur, 3), 'module' => $moduleClass, 'parameters' => $parameters]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $module;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log slow page executions
|
* Log slow page executions
|
||||||
*
|
*
|
||||||
|
|
|
@ -89,12 +89,6 @@ class Router
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
private $isLocalUser;
|
private $isLocalUser;
|
||||||
|
|
||||||
/** @var float */
|
|
||||||
private $dice_profiler_threshold;
|
|
||||||
|
|
||||||
/** @var Dice */
|
|
||||||
private $dice;
|
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $baseRoutesFilepath;
|
private $baseRoutesFilepath;
|
||||||
|
|
||||||
|
@ -113,11 +107,10 @@ class Router
|
||||||
* @param IManageConfigValues $config
|
* @param IManageConfigValues $config
|
||||||
* @param Arguments $args
|
* @param Arguments $args
|
||||||
* @param LoggerInterface $logger
|
* @param LoggerInterface $logger
|
||||||
* @param Dice $dice
|
|
||||||
* @param IHandleUserSessions $userSession
|
* @param IHandleUserSessions $userSession
|
||||||
* @param RouteCollector|null $routeCollector
|
* @param RouteCollector|null $routeCollector
|
||||||
*/
|
*/
|
||||||
public function __construct(array $server, string $baseRoutesFilepath, L10n $l10n, ICanCache $cache, ICanLock $lock, IManageConfigValues $config, Arguments $args, LoggerInterface $logger, Dice $dice, IHandleUserSessions $userSession, RouteCollector $routeCollector = null)
|
public function __construct(array $server, string $baseRoutesFilepath, L10n $l10n, ICanCache $cache, ICanLock $lock, IManageConfigValues $config, Arguments $args, LoggerInterface $logger, IHandleUserSessions $userSession, RouteCollector $routeCollector = null)
|
||||||
{
|
{
|
||||||
$this->baseRoutesFilepath = $baseRoutesFilepath;
|
$this->baseRoutesFilepath = $baseRoutesFilepath;
|
||||||
$this->l10n = $l10n;
|
$this->l10n = $l10n;
|
||||||
|
@ -125,11 +118,9 @@ class Router
|
||||||
$this->lock = $lock;
|
$this->lock = $lock;
|
||||||
$this->args = $args;
|
$this->args = $args;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->dice = $dice;
|
|
||||||
$this->server = $server;
|
$this->server = $server;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
$this->isLocalUser = !empty($userSession->getLocalUserId());
|
$this->isLocalUser = !empty($userSession->getLocalUserId());
|
||||||
$this->dice_profiler_threshold = $config->get('system', 'dice_profiler_threshold', 0);
|
|
||||||
|
|
||||||
$this->routeCollector = $routeCollector ?? new RouteCollector(new Std(), new GroupCountBased());
|
$this->routeCollector = $routeCollector ?? new RouteCollector(new Std(), new GroupCountBased());
|
||||||
|
|
||||||
|
@ -328,23 +319,9 @@ class Router
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getModule(?string $module_class = null): ICanHandleRequests
|
public function getParameters(): array
|
||||||
{
|
{
|
||||||
$moduleClass = $module_class ?? $this->getModuleClass();
|
return $this->parameters;
|
||||||
|
|
||||||
$stamp = microtime(true);
|
|
||||||
|
|
||||||
/** @var ICanHandleRequests $module */
|
|
||||||
$module = $this->dice->create($moduleClass, $this->parameters);
|
|
||||||
|
|
||||||
if ($this->dice_profiler_threshold > 0) {
|
|
||||||
$dur = floatval(microtime(true) - $stamp);
|
|
||||||
if ($dur >= $this->dice_profiler_threshold) {
|
|
||||||
$this->logger->notice('Dice module creation lasts too long.', ['duration' => round($dur, 3), 'module' => $moduleClass, 'parameters' => $this->parameters]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $module;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -164,6 +164,19 @@ abstract class BaseModule implements ICanHandleRequests
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module GET method to process submitted data
|
||||||
|
*
|
||||||
|
* Extend this method if the module is supposed to process GET requests.
|
||||||
|
* Doesn't display any content
|
||||||
|
*
|
||||||
|
* @param string[] $request The $_REQUEST content
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function get(array $request = [])
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -210,17 +223,20 @@ abstract class BaseModule implements ICanHandleRequests
|
||||||
switch ($this->args->getMethod()) {
|
switch ($this->args->getMethod()) {
|
||||||
case Router::DELETE:
|
case Router::DELETE:
|
||||||
$this->delete($request);
|
$this->delete($request);
|
||||||
return $this->response->generate();
|
break;
|
||||||
case Router::PATCH:
|
case Router::PATCH:
|
||||||
$this->patch($request);
|
$this->patch($request);
|
||||||
return $this->response->generate();
|
break;
|
||||||
case Router::POST:
|
case Router::POST:
|
||||||
Core\Hook::callAll($this->args->getModuleName() . '_mod_post', $request);
|
Core\Hook::callAll($this->args->getModuleName() . '_mod_post', $request);
|
||||||
$this->post($request);
|
$this->post($request);
|
||||||
return $this->response->generate();
|
break;
|
||||||
case Router::PUT:
|
case Router::PUT:
|
||||||
$this->put($request);
|
$this->put($request);
|
||||||
return $this->response->generate();
|
break;
|
||||||
|
case Router::GET:
|
||||||
|
$this->get($request);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$timestamp = microtime(true);
|
$timestamp = microtime(true);
|
||||||
|
|
39
src/Console/AbstractConsole.php
Normal file
39
src/Console/AbstractConsole.php
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Copyright (C) 2010-2024, the Friendica project
|
||||||
|
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Friendica\Console;
|
||||||
|
|
||||||
|
use Asika\SimpleConsole\Console;
|
||||||
|
use Friendica\Core\Console as CoreConsole;
|
||||||
|
use Friendica\Core\Logger\Capability\LogChannel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract Console class for common settings
|
||||||
|
*/
|
||||||
|
abstract class AbstractConsole extends Console
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Overwrite this const in case you want to switch the LogChannel for this console command
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public const LOG_CHANNEL = LogChannel::CONSOLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks, if the Console command was executed outside `bin/console.php` and prints the correct execution
|
||||||
|
*
|
||||||
|
* @param string $command the current command
|
||||||
|
*/
|
||||||
|
protected function checkDeprecated(string $command): void
|
||||||
|
{
|
||||||
|
if (substr($this->executable, -strlen(CoreConsole::getDefaultExecutable())) === CoreConsole::getDefaultExecutable()) {
|
||||||
|
$this->out(sprintf("'%s' is deprecated and will removed. Please use 'bin/console.php %s' instead", $this->executable, $command));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
228
src/Console/Daemon.php
Normal file
228
src/Console/Daemon.php
Normal file
|
@ -0,0 +1,228 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Copyright (C) 2010-2024, the Friendica project
|
||||||
|
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Friendica\Console;
|
||||||
|
|
||||||
|
use Asika\SimpleConsole\CommandArgsException;
|
||||||
|
use Friendica\App\Mode;
|
||||||
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
|
use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs;
|
||||||
|
use Friendica\Core\Logger\Capability\LogChannel;
|
||||||
|
use Friendica\Core\System;
|
||||||
|
use Friendica\Core\Update;
|
||||||
|
use Friendica\Core\Worker;
|
||||||
|
use Friendica\Database\Database;
|
||||||
|
use Friendica\System\Daemon as SysDaemon;
|
||||||
|
use Friendica\Util\BasePath;
|
||||||
|
use Friendica\Util\DateTimeFormat;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Console command for interacting with the daemon
|
||||||
|
*/
|
||||||
|
final class Daemon extends AbstractConsole
|
||||||
|
{
|
||||||
|
public const LOG_CHANNEL = LogChannel::DAEMON;
|
||||||
|
|
||||||
|
private Mode $mode;
|
||||||
|
private IManageConfigValues $config;
|
||||||
|
private IManageKeyValuePairs $keyValue;
|
||||||
|
private BasePath $basePath;
|
||||||
|
private System $system;
|
||||||
|
private LoggerInterface $logger;
|
||||||
|
private Database $dba;
|
||||||
|
private SysDaemon $daemon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Mode $mode
|
||||||
|
* @param IManageConfigValues $config
|
||||||
|
* @param IManageKeyValuePairs $keyValue
|
||||||
|
* @param BasePath $basePath
|
||||||
|
* @param System $system
|
||||||
|
* @param LoggerInterface $logger
|
||||||
|
* @param Database $dba
|
||||||
|
* @param SysDaemon $daemon
|
||||||
|
* @param array|null $argv
|
||||||
|
*/
|
||||||
|
public function __construct(Mode $mode, IManageConfigValues $config, IManageKeyValuePairs $keyValue, BasePath $basePath, System $system, LoggerInterface $logger, Database $dba, SysDaemon $daemon, array $argv = null)
|
||||||
|
{
|
||||||
|
parent::__construct($argv);
|
||||||
|
|
||||||
|
$this->mode = $mode;
|
||||||
|
$this->config = $config;
|
||||||
|
$this->keyValue = $keyValue;
|
||||||
|
$this->basePath = $basePath;
|
||||||
|
$this->system = $system;
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->dba = $dba;
|
||||||
|
$this->daemon = $daemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getHelp(): string
|
||||||
|
{
|
||||||
|
return <<<HELP
|
||||||
|
Daemon - Interact with the Friendica daemon
|
||||||
|
Synopsis
|
||||||
|
bin/console daemon start [-h|--help|-?] [-v] [-f]
|
||||||
|
bin/console daemon stop [-h|--help|-?] [-v]
|
||||||
|
bin/console daemon status [-h|--help|-?] [-v]
|
||||||
|
|
||||||
|
Description
|
||||||
|
Interact with the Friendica daemon
|
||||||
|
|
||||||
|
Options
|
||||||
|
-h|--help|-? Show help information
|
||||||
|
-v Show more debug information.
|
||||||
|
-f|--foreground Runs the daemon in the foreground
|
||||||
|
|
||||||
|
Examples
|
||||||
|
bin/console daemon start -f
|
||||||
|
Starts the daemon in the foreground
|
||||||
|
|
||||||
|
bin/console daemon status
|
||||||
|
Gets the status of the daemon
|
||||||
|
HELP;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function doExecute()
|
||||||
|
{
|
||||||
|
$this->checkDeprecated('daemon');
|
||||||
|
|
||||||
|
if ($this->mode->isInstall()) {
|
||||||
|
throw new RuntimeException("Friendica isn't properly installed yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->mode->setExecutor(Mode::DAEMON);
|
||||||
|
|
||||||
|
$this->config->reload();
|
||||||
|
|
||||||
|
if (empty($this->config->get('system', 'pidfile'))) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
<<< TXT
|
||||||
|
Please set system.pidfile in config/local.config.php. For example:
|
||||||
|
|
||||||
|
'system' => [
|
||||||
|
'pidfile' => '/path/to/daemon.pid',
|
||||||
|
],
|
||||||
|
TXT
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pidfile = $this->config->get('system', 'pidfile');
|
||||||
|
|
||||||
|
$daemonMode = $this->getArgument(0);
|
||||||
|
$foreground = $this->getOption(['f', 'foreground']) ?? false;
|
||||||
|
|
||||||
|
if (empty($daemonMode)) {
|
||||||
|
throw new CommandArgsException("Please use either 'start', 'stop' or 'status'");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->daemon->init($pidfile);
|
||||||
|
|
||||||
|
if ($daemonMode == 'status') {
|
||||||
|
if ($this->daemon->isRunning()) {
|
||||||
|
$this->out(sprintf("Daemon process %s is running (%s)", $this->daemon->getPid(), $this->daemon->getPidfile()));
|
||||||
|
} else {
|
||||||
|
$this->out(sprintf("Daemon process %s isn't running (%s)", $this->daemon->getPid(), $this->daemon->getPidfile()));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($daemonMode == 'stop') {
|
||||||
|
if (!$this->daemon->isRunning()) {
|
||||||
|
$this->out(sprintf("Daemon process %s isn't running (%s)", $this->daemon->getPid(), $this->daemon->getPidfile()));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->daemon->stop()) {
|
||||||
|
$this->keyValue->set('worker_daemon_mode', false);
|
||||||
|
$this->out(sprintf("Daemon process %s was killed (%s)", $this->daemon->getPid(), $this->daemon->getPidfile()));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->daemon->isRunning()) {
|
||||||
|
$this->out(sprintf("Daemon process %s is already running (%s)", $this->daemon->getPid(), $this->daemon->getPidfile()));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($daemonMode == "start") {
|
||||||
|
$this->out("Starting Friendica daemon");
|
||||||
|
|
||||||
|
$this->daemon->start(function () {
|
||||||
|
$wait_interval = intval($this->config->get('system', 'cron_interval', 5)) * 60;
|
||||||
|
|
||||||
|
$do_cron = true;
|
||||||
|
$last_cron = 0;
|
||||||
|
|
||||||
|
$path = $this->basePath->getPath();
|
||||||
|
|
||||||
|
// Now running as a daemon.
|
||||||
|
while (true) {
|
||||||
|
// Check the database structure and possibly fixes it
|
||||||
|
Update::check($path, true);
|
||||||
|
|
||||||
|
if (!$do_cron && ($last_cron + $wait_interval) < time()) {
|
||||||
|
$this->logger->info('Forcing cron worker call.', ['pid' => $this->daemon->getPid()]);
|
||||||
|
$do_cron = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($do_cron || (!$this->system->isMaxLoadReached() && Worker::entriesExists() && Worker::isReady())) {
|
||||||
|
Worker::spawnWorker($do_cron);
|
||||||
|
} else {
|
||||||
|
$this->logger->info('Cool down for 5 seconds', ['pid' => $this->daemon->getPid()]);
|
||||||
|
sleep(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($do_cron) {
|
||||||
|
// We force a reconnect of the database connection.
|
||||||
|
// This is done to ensure that the connection don't get lost over time.
|
||||||
|
$this->dba->reconnect();
|
||||||
|
|
||||||
|
$last_cron = time();
|
||||||
|
}
|
||||||
|
|
||||||
|
$start = time();
|
||||||
|
$this->logger->info('Sleeping', ['pid' => $this->daemon->getPid(), 'until' => gmdate(DateTimeFormat::MYSQL, $start + $wait_interval)]);
|
||||||
|
|
||||||
|
do {
|
||||||
|
$seconds = (time() - $start);
|
||||||
|
|
||||||
|
// logarithmic wait time calculation.
|
||||||
|
// Background: After jobs had been started, they often fork many workers.
|
||||||
|
// To not waste too much time, the sleep period increases.
|
||||||
|
$arg = (($seconds + 1) / ($wait_interval / 9)) + 1;
|
||||||
|
$sleep = min(1000000, round(log10($arg) * 1000000, 0));
|
||||||
|
|
||||||
|
$this->daemon->sleep((int)$sleep);
|
||||||
|
|
||||||
|
$timeout = ($seconds >= $wait_interval);
|
||||||
|
} while (!$timeout && !Worker\IPC::JobsExists());
|
||||||
|
|
||||||
|
if ($timeout) {
|
||||||
|
$do_cron = true;
|
||||||
|
$this->logger->info('Woke up after $wait_interval seconds.', ['pid' => $this->daemon->getPid(), 'sleep' => $wait_interval]);
|
||||||
|
} else {
|
||||||
|
$do_cron = false;
|
||||||
|
$this->logger->info('Worker jobs are calling to be forked.', ['pid' => $this->daemon->getPid()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, $foreground);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->err('Invalid command');
|
||||||
|
$this->out($this->getHelp());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
163
src/Console/JetstreamDaemon.php
Normal file
163
src/Console/JetstreamDaemon.php
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Copyright (C) 2010-2025, the Friendica project
|
||||||
|
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Friendica\Console;
|
||||||
|
|
||||||
|
use Friendica\App\Mode;
|
||||||
|
use Friendica\Core\Addon;
|
||||||
|
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||||
|
use Friendica\Core\Hook;
|
||||||
|
use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs;
|
||||||
|
use Friendica\Core\Logger\Capability\LogChannel;
|
||||||
|
use Friendica\Protocol\ATProtocol\Jetstream;
|
||||||
|
use Friendica\System\Daemon as SysDaemon;
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Console command for interacting with the daemon
|
||||||
|
*/
|
||||||
|
final class JetstreamDaemon extends AbstractConsole
|
||||||
|
{
|
||||||
|
public const LOG_CHANNEL = LogChannel::DAEMON;
|
||||||
|
|
||||||
|
private Mode $mode;
|
||||||
|
private IManageConfigValues $config;
|
||||||
|
private IManageKeyValuePairs $keyValue;
|
||||||
|
private SysDaemon $daemon;
|
||||||
|
private Jetstream $jetstream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Mode $mode
|
||||||
|
* @param IManageConfigValues $config
|
||||||
|
* @param IManageKeyValuePairs $keyValue
|
||||||
|
* @param SysDaemon $daemon
|
||||||
|
* @param Jetstream $jetstream
|
||||||
|
* @param array|null $argv
|
||||||
|
*/
|
||||||
|
public function __construct(Mode $mode, IManageConfigValues $config, IManageKeyValuePairs $keyValue, SysDaemon $daemon, Jetstream $jetstream, array $argv = null)
|
||||||
|
{
|
||||||
|
parent::__construct($argv);
|
||||||
|
|
||||||
|
$this->mode = $mode;
|
||||||
|
$this->config = $config;
|
||||||
|
$this->keyValue = $keyValue;
|
||||||
|
$this->jetstream = $jetstream;
|
||||||
|
$this->daemon = $daemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getHelp(): string
|
||||||
|
{
|
||||||
|
return <<<HELP
|
||||||
|
jetstream - Interact with the Jetstream daemon
|
||||||
|
Synopsis
|
||||||
|
bin/console jetstream start [-h|--help|-?] [-v] [-f]
|
||||||
|
bin/console jetstream stop [-h|--help|-?] [-v]
|
||||||
|
bin/console jetstream status [-h|--help|-?] [-v]
|
||||||
|
|
||||||
|
Description
|
||||||
|
Interact with the Jetstream daemon
|
||||||
|
|
||||||
|
Options
|
||||||
|
-h|--help|-? Show help information
|
||||||
|
-v Show more debug information.
|
||||||
|
-f|--foreground Runs the daemon in the foreground
|
||||||
|
|
||||||
|
Examples
|
||||||
|
bin/console jetstream start -f
|
||||||
|
Starts the daemon in the foreground
|
||||||
|
|
||||||
|
bin/console jetstream status
|
||||||
|
Gets the status of the daemon
|
||||||
|
HELP;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function doExecute()
|
||||||
|
{
|
||||||
|
$this->checkDeprecated('jetstream');
|
||||||
|
|
||||||
|
if ($this->mode->isInstall()) {
|
||||||
|
throw new RuntimeException("Friendica isn't properly installed yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->config->reload();
|
||||||
|
|
||||||
|
if (empty($this->config->get('jetstream', 'pidfile'))) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
<<< TXT
|
||||||
|
Please set jetstream.pidfile in config/local.config.php. For example:
|
||||||
|
|
||||||
|
'jetstream' => [
|
||||||
|
'pidfile' => '/path/to/jetstream.pid',
|
||||||
|
],
|
||||||
|
TXT
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Addon::loadAddons();
|
||||||
|
Hook::loadHooks();
|
||||||
|
|
||||||
|
if (!Addon::isEnabled('bluesky')) {
|
||||||
|
throw new RuntimeException("Bluesky has to be enabled.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
$pidfile = $this->config->get('jetstream', 'pidfile');
|
||||||
|
|
||||||
|
$daemonMode = $this->getArgument(0);
|
||||||
|
$foreground = $this->getOption(['f', 'foreground']) ?? false;
|
||||||
|
|
||||||
|
if (empty($daemonMode)) {
|
||||||
|
throw new RuntimeException("Please use either 'start', 'stop' or 'status'");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->daemon->init($pidfile);
|
||||||
|
|
||||||
|
if ($daemonMode == 'status') {
|
||||||
|
if ($this->daemon->isRunning()) {
|
||||||
|
$this->out(sprintf("Daemon process %s is running (%s)", $this->daemon->getPid(), $this->daemon->getPidfile()));
|
||||||
|
} else {
|
||||||
|
$this->out(sprintf("Daemon process %s isn't running (%s)", $this->daemon->getPid(), $this->daemon->getPidfile()));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($daemonMode == 'stop') {
|
||||||
|
if (!$this->daemon->isRunning()) {
|
||||||
|
$this->out(sprintf("Daemon process %s isn't running (%s)", $this->daemon->getPid(), $this->daemon->getPidfile()));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->daemon->stop()) {
|
||||||
|
$this->keyValue->set('worker_daemon_mode', false);
|
||||||
|
$this->out(sprintf("Daemon process %s was killed (%s)", $this->daemon->getPid(), $this->daemon->getPidfile()));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->daemon->isRunning()) {
|
||||||
|
$this->out(sprintf("Daemon process %s is already running (%s)", $this->daemon->getPid(), $this->daemon->getPidfile()));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($daemonMode == "start") {
|
||||||
|
$this->out("Starting Jetstream daemon");
|
||||||
|
|
||||||
|
$this->daemon->start(function () {
|
||||||
|
$this->jetstream->listen();
|
||||||
|
}, $foreground);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->err('Invalid command');
|
||||||
|
$this->out($this->getHelp());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
100
src/Console/Worker.php
Normal file
100
src/Console/Worker.php
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Copyright (C) 2010-2024, the Friendica project
|
||||||
|
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Friendica\Console;
|
||||||
|
|
||||||
|
use Friendica\App\Mode;
|
||||||
|
use Friendica\Core\Logger\Capability\LogChannel;
|
||||||
|
use Friendica\Core\Update;
|
||||||
|
use Friendica\Core\Worker as CoreWorker;
|
||||||
|
use Friendica\Core\Worker\Repository\Process as ProcessRepository;
|
||||||
|
use Friendica\Util\BasePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Console command for starting worker
|
||||||
|
*/
|
||||||
|
final class Worker extends AbstractConsole
|
||||||
|
{
|
||||||
|
public const LOG_CHANNEL = LogChannel::WORKER;
|
||||||
|
|
||||||
|
private Mode $mode;
|
||||||
|
private BasePath $basePath;
|
||||||
|
private ProcessRepository $processRepo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Mode $mode
|
||||||
|
* @param BasePath $basePath
|
||||||
|
* @param ProcessRepository $processRepo
|
||||||
|
* @param array|null $argv
|
||||||
|
*/
|
||||||
|
public function __construct(Mode $mode, BasePath $basePath, ProcessRepository $processRepo, array $argv = null)
|
||||||
|
{
|
||||||
|
parent::__construct($argv);
|
||||||
|
|
||||||
|
$this->mode = $mode;
|
||||||
|
$this->basePath = $basePath;
|
||||||
|
$this->processRepo = $processRepo;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getHelp(): string
|
||||||
|
{
|
||||||
|
return <<<HELP
|
||||||
|
Worker - Start a worker
|
||||||
|
Synopsis
|
||||||
|
bin/console worker [-h|--help|-?] [-v] [-n|--no_cron] [-s|--spawn]
|
||||||
|
|
||||||
|
Description
|
||||||
|
Start a worker process
|
||||||
|
|
||||||
|
Options
|
||||||
|
-h|--help|-? Show help information
|
||||||
|
-v Show more debug information.
|
||||||
|
-n|--no_cron Don't executes the Cronjob
|
||||||
|
-s|--spawn Spawn an additional worker
|
||||||
|
|
||||||
|
Examples
|
||||||
|
bin/console worker -n
|
||||||
|
Starts the worker without executing other recurring tasks
|
||||||
|
|
||||||
|
bin/console worker -s
|
||||||
|
Starts the worker and immediately spawn another worker process
|
||||||
|
HELP;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function doExecute()
|
||||||
|
{
|
||||||
|
$this->checkDeprecated('worker');
|
||||||
|
|
||||||
|
$this->mode->setExecutor(Mode::WORKER);
|
||||||
|
|
||||||
|
// Check the database structure and possibly fixes it
|
||||||
|
Update::check($this->basePath->getPath(), true);
|
||||||
|
|
||||||
|
// Quit when in maintenance
|
||||||
|
if (!$this->mode->has(Mode::MAINTENANCEDISABLED)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$spawn = $this->getOption(['s', 'spawn'], false);
|
||||||
|
|
||||||
|
if ($spawn) {
|
||||||
|
CoreWorker::spawnWorker();
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$run_cron = !$this->getOption(['n', 'no_cron'], false);
|
||||||
|
|
||||||
|
$process = $this->processRepo->create(getmypid(), 'worker.php');
|
||||||
|
|
||||||
|
CoreWorker::processQueue($run_cron, $process);
|
||||||
|
CoreWorker::unclaimProcess($process);
|
||||||
|
|
||||||
|
$this->processRepo->delete($process);
|
||||||
|
}
|
||||||
|
}
|
|
@ -69,7 +69,7 @@ class VCard
|
||||||
} else {
|
} else {
|
||||||
$pcontact = Contact::selectFirst([], ['uid' => DI::userSession()->getLocalUserId(), 'uri-id' => $contact['uri-id'], 'deleted' => false]);
|
$pcontact = Contact::selectFirst([], ['uid' => DI::userSession()->getLocalUserId(), 'uri-id' => $contact['uri-id'], 'deleted' => false]);
|
||||||
|
|
||||||
$id = $pcontact['id'] ?? 0;
|
$id = $pcontact['id'] ?? $contact['id'];
|
||||||
$rel = $pcontact['rel'] ?? Contact::NOTHING;
|
$rel = $pcontact['rel'] ?? Contact::NOTHING;
|
||||||
$pending = $pcontact['pending'] ?? false;
|
$pending = $pcontact['pending'] ?? false;
|
||||||
|
|
||||||
|
|
|
@ -7,23 +7,34 @@
|
||||||
|
|
||||||
namespace Friendica\Core;
|
namespace Friendica\Core;
|
||||||
|
|
||||||
use Dice\Dice;
|
|
||||||
use Friendica;
|
use Friendica;
|
||||||
use Friendica\App;
|
use Friendica\App;
|
||||||
|
use Friendica\Core\Logger\Capability\LogChannel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description of Console
|
* Description of Console
|
||||||
*/
|
*/
|
||||||
class Console extends \Asika\SimpleConsole\Console
|
class Console extends \Asika\SimpleConsole\Console
|
||||||
{
|
{
|
||||||
// Disables the default help handling
|
/** @var string The default executable for a console call */
|
||||||
protected $helpOptions = [];
|
private const CONSOLE_EXECUTABLE = 'bin/console.php';
|
||||||
protected $customHelpOptions = ['h', 'help', '?'];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Dice The DI library
|
* @return string The default executable for a console call
|
||||||
*/
|
*/
|
||||||
protected $dice;
|
public static function getDefaultExecutable(): string
|
||||||
|
{
|
||||||
|
return self::CONSOLE_EXECUTABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disables the default help handling
|
||||||
|
protected $helpOptions = [];
|
||||||
|
protected array $customHelpOptions = ['h', 'help', '?'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Container The Container
|
||||||
|
*/
|
||||||
|
protected Container $container;
|
||||||
|
|
||||||
protected function getHelp()
|
protected function getHelp()
|
||||||
{
|
{
|
||||||
|
@ -37,6 +48,9 @@ Commands:
|
||||||
config Edit site config
|
config Edit site config
|
||||||
contact Contact management
|
contact Contact management
|
||||||
createdoxygen Generate Doxygen headers
|
createdoxygen Generate Doxygen headers
|
||||||
|
daemon Interact with the Friendica daemon
|
||||||
|
jetstream Interact with the Jetstream daemon
|
||||||
|
worker Start worker process
|
||||||
dbstructure Do database updates
|
dbstructure Do database updates
|
||||||
docbloxerrorchecker Check the file tree for DocBlox errors
|
docbloxerrorchecker Check the file tree for DocBlox errors
|
||||||
extract Generate translation string file for the Friendica project (deprecated)
|
extract Generate translation string file for the Friendica project (deprecated)
|
||||||
|
@ -66,7 +80,7 @@ HELP;
|
||||||
return $help;
|
return $help;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $subConsoles = [
|
protected array $subConsoles = [
|
||||||
'addon' => Friendica\Console\Addon::class,
|
'addon' => Friendica\Console\Addon::class,
|
||||||
'archivecontact' => Friendica\Console\ArchiveContact::class,
|
'archivecontact' => Friendica\Console\ArchiveContact::class,
|
||||||
'autoinstall' => Friendica\Console\AutomaticInstallation::class,
|
'autoinstall' => Friendica\Console\AutomaticInstallation::class,
|
||||||
|
@ -75,6 +89,9 @@ HELP;
|
||||||
'config' => Friendica\Console\Config::class,
|
'config' => Friendica\Console\Config::class,
|
||||||
'contact' => Friendica\Console\Contact::class,
|
'contact' => Friendica\Console\Contact::class,
|
||||||
'createdoxygen' => Friendica\Console\CreateDoxygen::class,
|
'createdoxygen' => Friendica\Console\CreateDoxygen::class,
|
||||||
|
'daemon' => Friendica\Console\Daemon::class,
|
||||||
|
'jetstream' => Friendica\Console\JetstreamDaemon::class,
|
||||||
|
'worker' => Friendica\Console\Worker::class,
|
||||||
'docbloxerrorchecker' => Friendica\Console\DocBloxErrorChecker::class,
|
'docbloxerrorchecker' => Friendica\Console\DocBloxErrorChecker::class,
|
||||||
'dbstructure' => Friendica\Console\DatabaseStructure::class,
|
'dbstructure' => Friendica\Console\DatabaseStructure::class,
|
||||||
'extract' => Friendica\Console\Extract::class,
|
'extract' => Friendica\Console\Extract::class,
|
||||||
|
@ -100,14 +117,18 @@ HELP;
|
||||||
/**
|
/**
|
||||||
* CliInput Friendica constructor.
|
* CliInput Friendica constructor.
|
||||||
*
|
*
|
||||||
* @param Dice $dice The DI library
|
* @param Container $container The Friendica container
|
||||||
* @param array $argv
|
|
||||||
*/
|
*/
|
||||||
public function __construct(Dice $dice, array $argv = null)
|
public function __construct(Container $container, array $argv = null)
|
||||||
{
|
{
|
||||||
parent::__construct($argv);
|
parent::__construct($argv);
|
||||||
|
|
||||||
$this->dice = $dice;
|
$this->container = $container;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function create(Container $container, array $argv = null): Console
|
||||||
|
{
|
||||||
|
return new self($container, $argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function doExecute(): int
|
protected function doExecute(): int
|
||||||
|
@ -166,12 +187,14 @@ HELP;
|
||||||
|
|
||||||
$className = $this->subConsoles[$command];
|
$className = $this->subConsoles[$command];
|
||||||
|
|
||||||
Friendica\DI::init($this->dice);
|
if (is_subclass_of($className, Friendica\Console\AbstractConsole::class)) {
|
||||||
|
$this->container->setup($className::LOG_CHANNEL);
|
||||||
Renderer::registerTemplateEngine('Friendica\Render\FriendicaSmartyEngine');
|
} else {
|
||||||
|
$this->container->setup(LogChannel::CONSOLE);
|
||||||
|
}
|
||||||
|
|
||||||
/** @var Console $subconsole */
|
/** @var Console $subconsole */
|
||||||
$subconsole = $this->dice->create($className, [$subargs]);
|
$subconsole = $this->container->create($className, [$subargs]);
|
||||||
|
|
||||||
foreach ($this->options as $name => $value) {
|
foreach ($this->options as $name => $value) {
|
||||||
$subconsole->setOption($name, $value);
|
$subconsole->setOption($name, $value);
|
||||||
|
@ -179,5 +202,4 @@ HELP;
|
||||||
|
|
||||||
return $subconsole;
|
return $subconsole;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
118
src/Core/Container.php
Normal file
118
src/Core/Container.php
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Copyright (C) 2010-2024, the Friendica project
|
||||||
|
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Friendica\Core;
|
||||||
|
|
||||||
|
use Dice\Dice;
|
||||||
|
use Friendica\Core\Addon\Capability\ICanLoadAddons;
|
||||||
|
use Friendica\Core\Logger\Capability\LogChannel;
|
||||||
|
use Friendica\Core\Logger\Handler\ErrorHandler;
|
||||||
|
use Friendica\DI;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for the Dice class to make some basic setups
|
||||||
|
*/
|
||||||
|
class Container
|
||||||
|
{
|
||||||
|
private Dice $container;
|
||||||
|
|
||||||
|
protected function __construct(Dice $container)
|
||||||
|
{
|
||||||
|
$this->container = $container;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance with Dice
|
||||||
|
*
|
||||||
|
* @param Dice $container
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public static function fromDice(Dice $container): self
|
||||||
|
{
|
||||||
|
return new self($container);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the container with the given parameters
|
||||||
|
*
|
||||||
|
* @param string $logChannel The Log Channel of this call
|
||||||
|
* @param bool $withTemplateEngine true, if the template engine should be set too
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setup(string $logChannel = LogChannel::DEFAULT, bool $withTemplateEngine = true)
|
||||||
|
{
|
||||||
|
$this->setupContainerForAddons();
|
||||||
|
$this->setupContainerForLogger($logChannel);
|
||||||
|
$this->setupLegacyServiceLocator();
|
||||||
|
$this->registerErrorHandler();
|
||||||
|
|
||||||
|
if ($withTemplateEngine) {
|
||||||
|
$this->registerTemplateEngine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a fully constructed object based on $name using $args and $share as constructor arguments if supplied
|
||||||
|
* @param string $name name The name of the class to instantiate
|
||||||
|
* @param array $args An array with any additional arguments to be passed into the constructor upon instantiation
|
||||||
|
* @param array $share a list of defined in shareInstances for objects higher up the object graph, should only be used internally
|
||||||
|
* @return object A fully constructed object based on the specified input arguments
|
||||||
|
*
|
||||||
|
* @see Dice::create()
|
||||||
|
*/
|
||||||
|
public function create(string $name, array $args = [], array $share = []): object
|
||||||
|
{
|
||||||
|
return $this->container->create($name, $args, $share);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a rule $rule to the class $name
|
||||||
|
* @param string $name The name of the class to add the rule for
|
||||||
|
* @param array $rule The container can be fully configured using rules provided by associative arrays. See {@link https://r.je/dice.html#example3} for a description of the rules.
|
||||||
|
*
|
||||||
|
* @see Dice::addRule()
|
||||||
|
*/
|
||||||
|
public function addRule(string $name, array $rule): void
|
||||||
|
{
|
||||||
|
$this->container = $this->container->addRule($name, $rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setupContainerForAddons(): void
|
||||||
|
{
|
||||||
|
/** @var ICanLoadAddons $addonLoader */
|
||||||
|
$addonLoader = $this->container->create(ICanLoadAddons::class);
|
||||||
|
|
||||||
|
$this->container = $this->container->addRules($addonLoader->getActiveAddonConfig('dependencies'));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setupContainerForLogger(string $logChannel): void
|
||||||
|
{
|
||||||
|
$this->container = $this->container->addRule(LoggerInterface::class, [
|
||||||
|
'constructParams' => [$logChannel],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setupLegacyServiceLocator(): void
|
||||||
|
{
|
||||||
|
DI::init($this->container);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function registerErrorHandler(): void
|
||||||
|
{
|
||||||
|
ErrorHandler::register($this->container->create(LoggerInterface::class));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function registerTemplateEngine(): void
|
||||||
|
{
|
||||||
|
Renderer::registerTemplateEngine('Friendica\Render\FriendicaSmartyEngine');
|
||||||
|
}
|
||||||
|
}
|
|
@ -164,9 +164,10 @@ class System
|
||||||
* Executes a child process with 'proc_open'
|
* Executes a child process with 'proc_open'
|
||||||
*
|
*
|
||||||
* @param string $command The command to execute
|
* @param string $command The command to execute
|
||||||
* @param array $args Arguments to pass to the command ( [ 'key' => value, 'key2' => value2, ... ]
|
* @param array $args Arguments to pass to the command ( ['arg1', 'arg2', ... ] )
|
||||||
|
* @param array $options Options to pass to the command ( [ 'key' => value, 'key2' => value2, ... ]
|
||||||
*/
|
*/
|
||||||
public function run(string $command, array $args)
|
public function run(string $command, array $args = [], array $options = [])
|
||||||
{
|
{
|
||||||
if (!function_exists('proc_open')) {
|
if (!function_exists('proc_open')) {
|
||||||
$this->logger->warning('"proc_open" not available - quitting');
|
$this->logger->warning('"proc_open" not available - quitting');
|
||||||
|
@ -175,7 +176,11 @@ class System
|
||||||
|
|
||||||
$cmdline = $this->config->get('config', 'php_path', 'php') . ' ' . escapeshellarg($command);
|
$cmdline = $this->config->get('config', 'php_path', 'php') . ' ' . escapeshellarg($command);
|
||||||
|
|
||||||
foreach ($args as $key => $value) {
|
foreach ($args as $argumment) {
|
||||||
|
$cmdline .= ' ' . $argumment;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($options as $key => $value) {
|
||||||
if (!is_null($value) && is_bool($value) && !$value) {
|
if (!is_null($value) && is_bool($value) && !$value) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -272,10 +277,13 @@ class System
|
||||||
*/
|
*/
|
||||||
public static function echoResponse(ResponseInterface $response)
|
public static function echoResponse(ResponseInterface $response)
|
||||||
{
|
{
|
||||||
header(sprintf("HTTP/%s %s %s",
|
header(
|
||||||
|
sprintf(
|
||||||
|
"HTTP/%s %s %s",
|
||||||
$response->getProtocolVersion(),
|
$response->getProtocolVersion(),
|
||||||
$response->getStatusCode(),
|
$response->getStatusCode(),
|
||||||
$response->getReasonPhrase())
|
$response->getReasonPhrase()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ($response->getHeaders() as $key => $header) {
|
foreach ($response->getHeaders() as $key => $header) {
|
||||||
|
|
|
@ -603,13 +603,13 @@ class Worker
|
||||||
self::$lock_duration = 0;
|
self::$lock_duration = 0;
|
||||||
|
|
||||||
if ($duration > 3600) {
|
if ($duration > 3600) {
|
||||||
Logger::info('Longer than 1 hour.', ['priority' => $queue['priority'], 'id' => $queue['id'], 'duration' => round($duration/60, 3)]);
|
Logger::info('Longer than 1 hour.', ['priority' => $queue['priority'], 'id' => $queue['id'], 'duration' => round($duration / 60, 3)]);
|
||||||
} elseif ($duration > 600) {
|
} elseif ($duration > 600) {
|
||||||
Logger::info('Longer than 10 minutes.', ['priority' => $queue['priority'], 'id' => $queue['id'], 'duration' => round($duration/60, 3)]);
|
Logger::info('Longer than 10 minutes.', ['priority' => $queue['priority'], 'id' => $queue['id'], 'duration' => round($duration / 60, 3)]);
|
||||||
} elseif ($duration > 300) {
|
} elseif ($duration > 300) {
|
||||||
Logger::info('Longer than 5 minutes.', ['priority' => $queue['priority'], 'id' => $queue['id'], 'duration' => round($duration/60, 3)]);
|
Logger::info('Longer than 5 minutes.', ['priority' => $queue['priority'], 'id' => $queue['id'], 'duration' => round($duration / 60, 3)]);
|
||||||
} elseif ($duration > 120) {
|
} elseif ($duration > 120) {
|
||||||
Logger::info('Longer than 2 minutes.', ['priority' => $queue['priority'], 'id' => $queue['id'], 'duration' => round($duration/60, 3)]);
|
Logger::info('Longer than 2 minutes.', ['priority' => $queue['priority'], 'id' => $queue['id'], 'duration' => round($duration / 60, 3)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::info('Process done.', ['function' => $funcname, 'priority' => $queue['priority'], 'retrial' => $queue['retrial'], 'id' => $queue['id'], 'duration' => round($duration, 3)]);
|
Logger::info('Process done.', ['function' => $funcname, 'priority' => $queue['priority'], 'retrial' => $queue['retrial'], 'id' => $queue['id'], 'duration' => round($duration, 3)]);
|
||||||
|
@ -1083,8 +1083,11 @@ class Worker
|
||||||
$stamp = (float)microtime(true);
|
$stamp = (float)microtime(true);
|
||||||
foreach ($worker as $worker_pid => $worker_ids) {
|
foreach ($worker as $worker_pid => $worker_ids) {
|
||||||
Logger::info('Set queue entry', ['pid' => $worker_pid, 'ids' => $worker_ids]);
|
Logger::info('Set queue entry', ['pid' => $worker_pid, 'ids' => $worker_ids]);
|
||||||
DBA::update('workerqueue', ['executed' => DateTimeFormat::utcNow(), 'pid' => $worker_pid],
|
DBA::update(
|
||||||
['id' => $worker_ids, 'done' => false, 'pid' => 0]);
|
'workerqueue',
|
||||||
|
['executed' => DateTimeFormat::utcNow(), 'pid' => $worker_pid],
|
||||||
|
['id' => $worker_ids, 'done' => false, 'pid' => 0]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
self::$db_duration += (microtime(true) - $stamp);
|
self::$db_duration += (microtime(true) - $stamp);
|
||||||
self::$db_duration_write += (microtime(true) - $stamp);
|
self::$db_duration_write += (microtime(true) - $stamp);
|
||||||
|
@ -1207,7 +1210,7 @@ class Worker
|
||||||
if (Worker\Daemon::isMode() && DI::config()->get('system', 'worker_fork')) {
|
if (Worker\Daemon::isMode() && DI::config()->get('system', 'worker_fork')) {
|
||||||
self::forkProcess($do_cron);
|
self::forkProcess($do_cron);
|
||||||
} else {
|
} else {
|
||||||
DI::system()->run('bin/worker.php', ['no_cron' => !$do_cron]);
|
DI::system()->run('bin/console.php', ['worker'], ['no_cron' => !$do_cron]);
|
||||||
}
|
}
|
||||||
if (Worker\Daemon::isMode()) {
|
if (Worker\Daemon::isMode()) {
|
||||||
Worker\IPC::SetJobState(false);
|
Worker\IPC::SetJobState(false);
|
||||||
|
|
|
@ -115,7 +115,7 @@ class Daemon
|
||||||
private static function spawn()
|
private static function spawn()
|
||||||
{
|
{
|
||||||
Logger::notice('Starting new daemon process');
|
Logger::notice('Starting new daemon process');
|
||||||
DI::system()->run('bin/daemon.php', ['start']);
|
DI::system()->run('bin/console.php', ['start']);
|
||||||
Logger::notice('New daemon process started');
|
Logger::notice('New daemon process started');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,6 +233,14 @@ class Item
|
||||||
|
|
||||||
$content_fields = ['raw-body' => trim($fields['raw-body'] ?? $fields['body'])];
|
$content_fields = ['raw-body' => trim($fields['raw-body'] ?? $fields['body'])];
|
||||||
|
|
||||||
|
if ($item['origin'] && empty($item['quote-uri-id'])) {
|
||||||
|
$quote_id = Post\Media::getActivityUriId($item['uri-id']);
|
||||||
|
if (!empty($quote_id)) {
|
||||||
|
Logger::notice('Found attached post', ['id' => $quote_id, 'guid' => $item['guid'], 'uri-id' => $item['uri-id']]);
|
||||||
|
$content_fields['quote-uri-id'] = $quote_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Remove all media attachments from the body and store them in the post-media table
|
// Remove all media attachments from the body and store them in the post-media table
|
||||||
// @todo On shared postings (Diaspora style and commented reshare) don't fetch content from the shared part
|
// @todo On shared postings (Diaspora style and commented reshare) don't fetch content from the shared part
|
||||||
$content_fields['raw-body'] = Post\Media::insertFromBody($item['uri-id'], $content_fields['raw-body']);
|
$content_fields['raw-body'] = Post\Media::insertFromBody($item['uri-id'], $content_fields['raw-body']);
|
||||||
|
@ -1221,6 +1229,14 @@ class Item
|
||||||
Post\Media::insertFromAttachment($item['uri-id'], $item['attach']);
|
Post\Media::insertFromAttachment($item['uri-id'], $item['attach']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($item['origin'] && empty($item['quote-uri-id'])) {
|
||||||
|
$quote_id = Post\Media::getActivityUriId($item['uri-id']);
|
||||||
|
if (!empty($quote_id)) {
|
||||||
|
Logger::notice('Found attached post', ['id' => $quote_id, 'guid' => $item['guid'], 'uri-id' => $item['uri-id']]);
|
||||||
|
$item['quote-uri-id'] = $quote_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (empty($item['event-id'])) {
|
if (empty($item['event-id'])) {
|
||||||
unset($item['event-id']);
|
unset($item['event-id']);
|
||||||
|
|
||||||
|
@ -4252,9 +4268,10 @@ class Item
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the uri-id of a quote
|
* Fetch the uri-id of a quoted post by searching for data in the body or attached media
|
||||||
*
|
*
|
||||||
* @param string $body
|
* @param string $body The body of the
|
||||||
|
* @param int $uid The id of the user
|
||||||
* @return integer
|
* @return integer
|
||||||
*/
|
*/
|
||||||
public static function getQuoteUriId(string $body, int $uid = 0): int
|
public static function getQuoteUriId(string $body, int $uid = 0): int
|
||||||
|
|
|
@ -323,6 +323,7 @@ class Photo
|
||||||
$values = array_fill(0, count($fields), '');
|
$values = array_fill(0, count($fields), '');
|
||||||
|
|
||||||
$photo = array_combine($fields, $values);
|
$photo = array_combine($fields, $values);
|
||||||
|
|
||||||
$photo['data'] = $image_data;
|
$photo['data'] = $image_data;
|
||||||
$photo['type'] = $mimetype ?: Images::getMimeTypeByData($image_data);
|
$photo['type'] = $mimetype ?: Images::getMimeTypeByData($image_data);
|
||||||
$photo['cacheable'] = false;
|
$photo['cacheable'] = false;
|
||||||
|
@ -476,6 +477,8 @@ class Photo
|
||||||
'backend-ref' => $backend_ref
|
'backend-ref' => $backend_ref
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$fields = DI::dbaDefinition()->truncateFieldsForTable('photo', $fields);
|
||||||
|
|
||||||
if (DBA::isResult($existing_photo)) {
|
if (DBA::isResult($existing_photo)) {
|
||||||
$r = DBA::update('photo', $fields, ['id' => $existing_photo['id']]);
|
$r = DBA::update('photo', $fields, ['id' => $existing_photo['id']]);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -90,6 +90,7 @@ class Media
|
||||||
}
|
}
|
||||||
|
|
||||||
$media['url'] = Network::sanitizeUrl($media['url']);
|
$media['url'] = Network::sanitizeUrl($media['url']);
|
||||||
|
|
||||||
$media = self::unsetEmptyFields($media);
|
$media = self::unsetEmptyFields($media);
|
||||||
$media = DI::dbaDefinition()->truncateFieldsForTable('post-media', $media);
|
$media = DI::dbaDefinition()->truncateFieldsForTable('post-media', $media);
|
||||||
|
|
||||||
|
@ -157,8 +158,11 @@ class Media
|
||||||
public static function getAttachElement(string $href, int $length, string $type, string $title = ''): string
|
public static function getAttachElement(string $href, int $length, string $type, string $title = ''): string
|
||||||
{
|
{
|
||||||
$media = self::fetchAdditionalData([
|
$media = self::fetchAdditionalData([
|
||||||
'type' => self::DOCUMENT, 'url' => $href,
|
'type' => self::DOCUMENT,
|
||||||
'size' => $length, 'mimetype' => $type, 'description' => $title
|
'url' => $href,
|
||||||
|
'size' => $length,
|
||||||
|
'mimetype' => $type,
|
||||||
|
'description' => $title
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return '[attach]href="' . $media['url'] . '" length="' . $media['size'] .
|
return '[attach]href="' . $media['url'] . '" length="' . $media['size'] .
|
||||||
|
@ -184,7 +188,7 @@ class Media
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch the mimetype or size if missing.
|
// Fetch the mimetype or size if missing.
|
||||||
if (Network::isValidHttpUrl($media['url']) && empty($media['mimetype']) && !in_array($media['type'], [self::IMAGE, self::HLS])) {
|
if (Network::isValidHttpUrl($media['url']) && (empty($media['mimetype']) || $media['type'] == self::HTML) && !in_array($media['type'], [self::IMAGE, self::HLS])) {
|
||||||
$timeout = DI::config()->get('system', 'xrd_timeout');
|
$timeout = DI::config()->get('system', 'xrd_timeout');
|
||||||
try {
|
try {
|
||||||
$curlResult = DI::httpClient()->head($media['url'], [HttpClientOptions::ACCEPT_CONTENT => HttpClientAccept::AS_DEFAULT, HttpClientOptions::TIMEOUT => $timeout, HttpClientOptions::REQUEST => HttpClientRequest::CONTENTTYPE]);
|
$curlResult = DI::httpClient()->head($media['url'], [HttpClientOptions::ACCEPT_CONTENT => HttpClientAccept::AS_DEFAULT, HttpClientOptions::TIMEOUT => $timeout, HttpClientOptions::REQUEST => HttpClientRequest::CONTENTTYPE]);
|
||||||
|
@ -194,8 +198,8 @@ class Media
|
||||||
$curlResult = DI::httpClient()->get($media['url'], HttpClientAccept::AS_DEFAULT, [HttpClientOptions::TIMEOUT => $timeout]);
|
$curlResult = DI::httpClient()->get($media['url'], HttpClientAccept::AS_DEFAULT, [HttpClientOptions::TIMEOUT => $timeout]);
|
||||||
}
|
}
|
||||||
if ($curlResult->isSuccess()) {
|
if ($curlResult->isSuccess()) {
|
||||||
if (empty($media['mimetype'])) {
|
if (!empty($curlResult->getContentType())) {
|
||||||
$media['mimetype'] = $curlResult->getContentType() ?? '';
|
$media['mimetype'] = $curlResult->getContentType();
|
||||||
}
|
}
|
||||||
if (empty($media['size'])) {
|
if (empty($media['size'])) {
|
||||||
$media['size'] = (int)($curlResult->getHeader('Content-Length')[0] ?? strlen($curlResult->getBodyString() ?? ''));
|
$media['size'] = (int)($curlResult->getHeader('Content-Length')[0] ?? strlen($curlResult->getBodyString() ?? ''));
|
||||||
|
@ -611,21 +615,33 @@ class Media
|
||||||
if (self::isLinkToImagePage($picture[1], $picture[2])) {
|
if (self::isLinkToImagePage($picture[1], $picture[2])) {
|
||||||
$body = str_replace($picture[0], '', $body);
|
$body = str_replace($picture[0], '', $body);
|
||||||
$image = str_replace(['-1.', '-2.'], '-0.', $picture[2]);
|
$image = str_replace(['-1.', '-2.'], '-0.', $picture[2]);
|
||||||
|
|
||||||
$attachments[$image] = [
|
$attachments[$image] = [
|
||||||
'uri-id' => $uriid, 'type' => self::IMAGE, 'url' => $image,
|
'uri-id' => $uriid,
|
||||||
'preview' => $picture[2], 'description' => $picture[3]
|
'type' => self::IMAGE,
|
||||||
|
'url' => $image,
|
||||||
|
'preview' => $picture[2],
|
||||||
|
'description' => $picture[3]
|
||||||
];
|
];
|
||||||
} elseif (self::isLinkToPhoto($picture[1], $picture[2])) {
|
} elseif (self::isLinkToPhoto($picture[1], $picture[2])) {
|
||||||
$body = str_replace($picture[0], '', $body);
|
$body = str_replace($picture[0], '', $body);
|
||||||
|
|
||||||
$attachments[$picture[1]] = [
|
$attachments[$picture[1]] = [
|
||||||
'uri-id' => $uriid, 'type' => self::IMAGE, 'url' => $picture[1],
|
'uri-id' => $uriid,
|
||||||
'preview' => $picture[2], 'description' => $picture[3]
|
'type' => self::IMAGE,
|
||||||
|
'url' => $picture[1],
|
||||||
|
'preview' => $picture[2],
|
||||||
|
'description' => $picture[3]
|
||||||
];
|
];
|
||||||
} elseif ($removepicturelinks) {
|
} elseif ($removepicturelinks) {
|
||||||
$body = str_replace($picture[0], '', $body);
|
$body = str_replace($picture[0], '', $body);
|
||||||
|
|
||||||
$attachments[$picture[1]] = [
|
$attachments[$picture[1]] = [
|
||||||
'uri-id' => $uriid, 'type' => self::UNKNOWN, 'url' => $picture[1],
|
'uri-id' => $uriid,
|
||||||
'preview' => $picture[2], 'description' => $picture[3]
|
'type' => self::UNKNOWN,
|
||||||
|
'url' => $picture[1],
|
||||||
|
'preview' => $picture[2],
|
||||||
|
'description' => $picture[3]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -634,6 +650,7 @@ class Media
|
||||||
if (preg_match_all("/\[img=([^\[\]]*)\]([^\[\]]*)\[\/img\]$endmatchpattern/Usi", $body, $pictures, PREG_SET_ORDER)) {
|
if (preg_match_all("/\[img=([^\[\]]*)\]([^\[\]]*)\[\/img\]$endmatchpattern/Usi", $body, $pictures, PREG_SET_ORDER)) {
|
||||||
foreach ($pictures as $picture) {
|
foreach ($pictures as $picture) {
|
||||||
$body = str_replace($picture[0], '', $body);
|
$body = str_replace($picture[0], '', $body);
|
||||||
|
|
||||||
$attachments[$picture[1]] = ['uri-id' => $uriid, 'type' => self::IMAGE, 'url' => $picture[1], 'description' => $picture[2]];
|
$attachments[$picture[1]] = ['uri-id' => $uriid, 'type' => self::IMAGE, 'url' => $picture[1], 'description' => $picture[2]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -643,21 +660,33 @@ class Media
|
||||||
if (self::isLinkToImagePage($picture[1], $picture[2])) {
|
if (self::isLinkToImagePage($picture[1], $picture[2])) {
|
||||||
$body = str_replace($picture[0], '', $body);
|
$body = str_replace($picture[0], '', $body);
|
||||||
$image = str_replace(['-1.', '-2.'], '-0.', $picture[2]);
|
$image = str_replace(['-1.', '-2.'], '-0.', $picture[2]);
|
||||||
|
|
||||||
$attachments[$image] = [
|
$attachments[$image] = [
|
||||||
'uri-id' => $uriid, 'type' => self::IMAGE, 'url' => $image,
|
'uri-id' => $uriid,
|
||||||
'preview' => $picture[2], 'description' => null
|
'type' => self::IMAGE,
|
||||||
|
'url' => $image,
|
||||||
|
'preview' => $picture[2],
|
||||||
|
'description' => null
|
||||||
];
|
];
|
||||||
} elseif (self::isLinkToPhoto($picture[1], $picture[2])) {
|
} elseif (self::isLinkToPhoto($picture[1], $picture[2])) {
|
||||||
$body = str_replace($picture[0], '', $body);
|
$body = str_replace($picture[0], '', $body);
|
||||||
|
|
||||||
$attachments[$picture[1]] = [
|
$attachments[$picture[1]] = [
|
||||||
'uri-id' => $uriid, 'type' => self::IMAGE, 'url' => $picture[1],
|
'uri-id' => $uriid,
|
||||||
'preview' => $picture[2], 'description' => null
|
'type' => self::IMAGE,
|
||||||
|
'url' => $picture[1],
|
||||||
|
'preview' => $picture[2],
|
||||||
|
'description' => null
|
||||||
];
|
];
|
||||||
} elseif ($removepicturelinks) {
|
} elseif ($removepicturelinks) {
|
||||||
$body = str_replace($picture[0], '', $body);
|
$body = str_replace($picture[0], '', $body);
|
||||||
|
|
||||||
$attachments[$picture[1]] = [
|
$attachments[$picture[1]] = [
|
||||||
'uri-id' => $uriid, 'type' => self::UNKNOWN, 'url' => $picture[1],
|
'uri-id' => $uriid,
|
||||||
'preview' => $picture[2], 'description' => null
|
'type' => self::UNKNOWN,
|
||||||
|
'url' => $picture[1],
|
||||||
|
'preview' => $picture[2],
|
||||||
|
'description' => null
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -666,6 +695,7 @@ class Media
|
||||||
if (preg_match_all("/\[img\]([^\[\]]*)\[\/img\]$endmatchpattern/ism", $body, $pictures, PREG_SET_ORDER)) {
|
if (preg_match_all("/\[img\]([^\[\]]*)\[\/img\]$endmatchpattern/ism", $body, $pictures, PREG_SET_ORDER)) {
|
||||||
foreach ($pictures as $picture) {
|
foreach ($pictures as $picture) {
|
||||||
$body = str_replace($picture[0], '', $body);
|
$body = str_replace($picture[0], '', $body);
|
||||||
|
|
||||||
$attachments[$picture[1]] = ['uri-id' => $uriid, 'type' => self::IMAGE, 'url' => $picture[1]];
|
$attachments[$picture[1]] = ['uri-id' => $uriid, 'type' => self::IMAGE, 'url' => $picture[1]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -673,6 +703,7 @@ class Media
|
||||||
if (preg_match_all("/\[audio\]([^\[\]]*)\[\/audio\]$endmatchpattern/ism", $body, $audios, PREG_SET_ORDER)) {
|
if (preg_match_all("/\[audio\]([^\[\]]*)\[\/audio\]$endmatchpattern/ism", $body, $audios, PREG_SET_ORDER)) {
|
||||||
foreach ($audios as $audio) {
|
foreach ($audios as $audio) {
|
||||||
$body = str_replace($audio[0], '', $body);
|
$body = str_replace($audio[0], '', $body);
|
||||||
|
|
||||||
$attachments[$audio[1]] = ['uri-id' => $uriid, 'type' => self::AUDIO, 'url' => $audio[1]];
|
$attachments[$audio[1]] = ['uri-id' => $uriid, 'type' => self::AUDIO, 'url' => $audio[1]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -680,6 +711,7 @@ class Media
|
||||||
if (preg_match_all("/\[video\]([^\[\]]*)\[\/video\]$endmatchpattern/ism", $body, $videos, PREG_SET_ORDER)) {
|
if (preg_match_all("/\[video\]([^\[\]]*)\[\/video\]$endmatchpattern/ism", $body, $videos, PREG_SET_ORDER)) {
|
||||||
foreach ($videos as $video) {
|
foreach ($videos as $video) {
|
||||||
$body = str_replace($video[0], '', $body);
|
$body = str_replace($video[0], '', $body);
|
||||||
|
|
||||||
$attachments[$video[1]] = ['uri-id' => $uriid, 'type' => self::VIDEO, 'url' => $video[1]];
|
$attachments[$video[1]] = ['uri-id' => $uriid, 'type' => self::VIDEO, 'url' => $video[1]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1130,4 +1162,19 @@ class Media
|
||||||
(Proxy::getPixelsFromSize($size) ? Proxy::getPixelsFromSize($size) . '/' : '') .
|
(Proxy::getPixelsFromSize($size) ? Proxy::getPixelsFromSize($size) . '/' : '') .
|
||||||
$id;
|
$id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the uri-id of an attached uri-post for a given uri-id
|
||||||
|
*
|
||||||
|
* @param integer $uri_id Uri-Id of the post
|
||||||
|
* @return integer uri-id of the first attached post
|
||||||
|
*/
|
||||||
|
public static function getActivityUriId(int $uri_id): int
|
||||||
|
{
|
||||||
|
$posts = self::getByURIId($uri_id, [self::ACTIVITY]);
|
||||||
|
if (!$posts) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return reset($posts)['media-uri-id'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -677,11 +677,12 @@ class User
|
||||||
* @param mixed $user_info
|
* @param mixed $user_info
|
||||||
* @param string $password
|
* @param string $password
|
||||||
* @param bool $third_party
|
* @param bool $third_party
|
||||||
|
* @param bool $with_blocked
|
||||||
* @return int User Id if authentication is successful
|
* @return int User Id if authentication is successful
|
||||||
* @throws HTTPException\ForbiddenException
|
* @throws HTTPException\ForbiddenException
|
||||||
* @throws HTTPException\NotFoundException
|
* @throws HTTPException\NotFoundException
|
||||||
*/
|
*/
|
||||||
public static function getIdFromPasswordAuthentication($user_info, string $password, bool $third_party = false): int
|
public static function getIdFromPasswordAuthentication($user_info, string $password, bool $third_party = false, bool $with_blocked = false): int
|
||||||
{
|
{
|
||||||
// Addons registered with the "authenticate" hook may create the user on the
|
// Addons registered with the "authenticate" hook may create the user on the
|
||||||
// fly. `getAuthenticationInfo` will fail if the user doesn't exist yet. If
|
// fly. `getAuthenticationInfo` will fail if the user doesn't exist yet. If
|
||||||
|
@ -689,7 +690,7 @@ class User
|
||||||
// user in our database, if applicable, before re-throwing the exception if
|
// user in our database, if applicable, before re-throwing the exception if
|
||||||
// they fail.
|
// they fail.
|
||||||
try {
|
try {
|
||||||
$user = self::getAuthenticationInfo($user_info);
|
$user = self::getAuthenticationInfo($user_info, $with_blocked);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$username = (is_string($user_info) ? $user_info : $user_info['nickname'] ?? '');
|
$username = (is_string($user_info) ? $user_info : $user_info['nickname'] ?? '');
|
||||||
|
|
||||||
|
@ -782,10 +783,11 @@ class User
|
||||||
* - User array with at least the uid and the hashed password
|
* - User array with at least the uid and the hashed password
|
||||||
*
|
*
|
||||||
* @param mixed $user_info
|
* @param mixed $user_info
|
||||||
|
* @param bool $with_blocked
|
||||||
* @return array|null Null if not found/determined
|
* @return array|null Null if not found/determined
|
||||||
* @throws HTTPException\NotFoundException
|
* @throws HTTPException\NotFoundException
|
||||||
*/
|
*/
|
||||||
public static function getAuthenticationInfo($user_info)
|
public static function getAuthenticationInfo($user_info, bool $with_blocked = false)
|
||||||
{
|
{
|
||||||
$user = null;
|
$user = null;
|
||||||
|
|
||||||
|
@ -804,25 +806,27 @@ class User
|
||||||
throw new Exception(DI::l10n()->t('Not enough information to authenticate'));
|
throw new Exception(DI::l10n()->t('Not enough information to authenticate'));
|
||||||
}
|
}
|
||||||
} elseif (is_int($user_info) || is_string($user_info)) {
|
} elseif (is_int($user_info) || is_string($user_info)) {
|
||||||
if (is_int($user_info)) {
|
|
||||||
$user = DBA::selectFirst(
|
|
||||||
'user',
|
|
||||||
['uid', 'nickname', 'password', 'legacy_password'],
|
|
||||||
[
|
|
||||||
'uid' => $user_info,
|
|
||||||
'blocked' => 0,
|
|
||||||
'account_expired' => 0,
|
|
||||||
'account_removed' => 0,
|
|
||||||
'verified' => 1
|
|
||||||
]
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$fields = ['uid', 'nickname', 'password', 'legacy_password'];
|
$fields = ['uid', 'nickname', 'password', 'legacy_password'];
|
||||||
|
if (is_int($user_info)) {
|
||||||
|
$condition = [
|
||||||
|
'uid' => $user_info,
|
||||||
|
'account_expired' => false,
|
||||||
|
'account_removed' => false,
|
||||||
|
'verified' => true
|
||||||
|
];
|
||||||
|
if (!$with_blocked) {
|
||||||
|
$condition = DBA::mergeConditions($condition, ['blocked' => false]);
|
||||||
|
}
|
||||||
|
$user = DBA::selectFirst('user', $fields, $condition);
|
||||||
|
} else {
|
||||||
$condition = [
|
$condition = [
|
||||||
"(`email` = ? OR `username` = ? OR `nickname` = ?)
|
"(`email` = ? OR `username` = ? OR `nickname` = ?)
|
||||||
AND `verified` AND NOT `blocked` AND NOT `account_removed` AND NOT `account_expired`",
|
AND `verified` AND NOT `account_removed` AND NOT `account_expired`",
|
||||||
$user_info, $user_info, $user_info
|
$user_info, $user_info, $user_info
|
||||||
];
|
];
|
||||||
|
if (!$with_blocked) {
|
||||||
|
$condition = DBA::mergeConditions($condition, ['blocked' => false]);
|
||||||
|
}
|
||||||
$user = DBA::selectFirst('user', $fields, $condition);
|
$user = DBA::selectFirst('user', $fields, $condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,6 @@ class UpdateCredentials extends BaseApi
|
||||||
}
|
}
|
||||||
|
|
||||||
$account = DI::mstdnAccount()->createFromContactId($ucid, $uid);
|
$account = DI::mstdnAccount()->createFromContactId($ucid, $uid);
|
||||||
$this->response->addJsonContent($account->toArray());
|
$this->jsonExit($account->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ class Lists extends BaseApi
|
||||||
/**
|
/**
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
protected function rawContent(array $request = [])
|
protected function get(array $request = [])
|
||||||
{
|
{
|
||||||
$this->checkAllowedScope(self::SCOPE_READ);
|
$this->checkAllowedScope(self::SCOPE_READ);
|
||||||
$uid = self::getCurrentUserID();
|
$uid = self::getCurrentUserID();
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
namespace Friendica\Module\Api\Mastodon\Lists;
|
namespace Friendica\Module\Api\Mastodon\Lists;
|
||||||
|
|
||||||
use Friendica\Core\System;
|
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
use Friendica\Model\Circle;
|
use Friendica\Model\Circle;
|
||||||
|
@ -53,7 +52,7 @@ class Accounts extends BaseApi
|
||||||
/**
|
/**
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
protected function rawContent(array $request = [])
|
protected function get(array $request = [])
|
||||||
{
|
{
|
||||||
$this->checkAllowedScope(self::SCOPE_READ);
|
$this->checkAllowedScope(self::SCOPE_READ);
|
||||||
$uid = self::getCurrentUserID();
|
$uid = self::getCurrentUserID();
|
||||||
|
|
|
@ -51,7 +51,7 @@ class Markers extends BaseApi
|
||||||
/**
|
/**
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
protected function rawContent(array $request = [])
|
protected function get(array $request = [])
|
||||||
{
|
{
|
||||||
$this->checkAllowedScope(self::SCOPE_READ);
|
$this->checkAllowedScope(self::SCOPE_READ);
|
||||||
$uid = self::getCurrentUserID();
|
$uid = self::getCurrentUserID();
|
||||||
|
|
|
@ -116,7 +116,7 @@ class Media extends BaseApi
|
||||||
/**
|
/**
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
protected function rawContent(array $request = [])
|
protected function get(array $request = [])
|
||||||
{
|
{
|
||||||
$this->checkAllowedScope(self::SCOPE_READ);
|
$this->checkAllowedScope(self::SCOPE_READ);
|
||||||
$uid = self::getCurrentUserID();
|
$uid = self::getCurrentUserID();
|
||||||
|
|
|
@ -66,7 +66,7 @@ class PushSubscription extends BaseApi
|
||||||
$this->logger->info('Subscription stored', ['ret' => $ret, 'subscription' => $subscription]);
|
$this->logger->info('Subscription stored', ['ret' => $ret, 'subscription' => $subscription]);
|
||||||
|
|
||||||
$subscriptionObj = $this->subscriptionFac->createForApplicationIdAndUserId($application['id'], $uid);
|
$subscriptionObj = $this->subscriptionFac->createForApplicationIdAndUserId($application['id'], $uid);
|
||||||
$this->response->addJsonContent($subscriptionObj->toArray());
|
$this->jsonExit($subscriptionObj->toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function put(array $request = []): void
|
public function put(array $request = []): void
|
||||||
|
@ -105,7 +105,7 @@ class PushSubscription extends BaseApi
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$subscriptionObj = $this->subscriptionFac->createForApplicationIdAndUserId($application['id'], $uid);
|
$subscriptionObj = $this->subscriptionFac->createForApplicationIdAndUserId($application['id'], $uid);
|
||||||
$this->response->addJsonContent($subscriptionObj->toArray());
|
$this->jsonExit($subscriptionObj->toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setBoolean($input): bool
|
private function setBoolean($input): bool
|
||||||
|
@ -130,10 +130,10 @@ class PushSubscription extends BaseApi
|
||||||
'uid' => $uid,
|
'uid' => $uid,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->response->addJsonContent([]);
|
$this->jsonExit([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function rawContent(array $request = []): void
|
protected function get(array $request = []): void
|
||||||
{
|
{
|
||||||
$this->checkAllowedScope(self::SCOPE_PUSH);
|
$this->checkAllowedScope(self::SCOPE_PUSH);
|
||||||
$uid = self::getCurrentUserID();
|
$uid = self::getCurrentUserID();
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
namespace Friendica\Module\Api\Mastodon;
|
namespace Friendica\Module\Api\Mastodon;
|
||||||
|
|
||||||
use Friendica\App\Router;
|
use Friendica\App\Router;
|
||||||
use Friendica\Core\System;
|
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
use Friendica\Model\Post;
|
use Friendica\Model\Post;
|
||||||
|
@ -48,7 +47,7 @@ class ScheduledStatuses extends BaseApi
|
||||||
/**
|
/**
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
protected function rawContent(array $request = [])
|
protected function get(array $request = [])
|
||||||
{
|
{
|
||||||
$this->checkAllowedScope(self::SCOPE_READ);
|
$this->checkAllowedScope(self::SCOPE_READ);
|
||||||
$uid = self::getCurrentUserID();
|
$uid = self::getCurrentUserID();
|
||||||
|
|
|
@ -308,6 +308,7 @@ class Statuses extends BaseApi
|
||||||
if (!empty($request['scheduled_at'])) {
|
if (!empty($request['scheduled_at'])) {
|
||||||
$item['guid'] = Item::guid($item, true);
|
$item['guid'] = Item::guid($item, true);
|
||||||
$item['uri'] = Item::newURI($item['guid']);
|
$item['uri'] = Item::newURI($item['guid']);
|
||||||
|
|
||||||
$id = Post\Delayed::add($item['uri'], $item, Worker::PRIORITY_HIGH, Post\Delayed::PREPARED, DateTimeFormat::utc($request['scheduled_at']));
|
$id = Post\Delayed::add($item['uri'], $item, Worker::PRIORITY_HIGH, Post\Delayed::PREPARED, DateTimeFormat::utc($request['scheduled_at']));
|
||||||
if (empty($id)) {
|
if (empty($id)) {
|
||||||
$this->logAndJsonError(500, $this->errorFactory->InternalError());
|
$this->logAndJsonError(500, $this->errorFactory->InternalError());
|
||||||
|
@ -350,7 +351,7 @@ class Statuses extends BaseApi
|
||||||
/**
|
/**
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
protected function rawContent(array $request = [])
|
protected function get(array $request = [])
|
||||||
{
|
{
|
||||||
$uid = self::getCurrentUserID();
|
$uid = self::getCurrentUserID();
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ use Friendica\Module\BaseApi;
|
||||||
*/
|
*/
|
||||||
class Inbox extends DirectMessagesEndpoint
|
class Inbox extends DirectMessagesEndpoint
|
||||||
{
|
{
|
||||||
protected function rawContent(array $request = [])
|
protected function get(array $request = [])
|
||||||
{
|
{
|
||||||
$this->checkAllowedScope(BaseApi::SCOPE_READ);
|
$this->checkAllowedScope(BaseApi::SCOPE_READ);
|
||||||
$uid = BaseApi::getCurrentUserID();
|
$uid = BaseApi::getCurrentUserID();
|
||||||
|
|
|
@ -165,7 +165,6 @@ class Install extends BaseModule
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DI::baseUrl()->redirect('install?pass=' . $this->currentWizardStep);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function content(array $request = []): string
|
protected function content(array $request = []): string
|
||||||
|
@ -282,10 +281,12 @@ class Install extends BaseModule
|
||||||
$this->configCache->get('config', 'admin_email'),
|
$this->configCache->get('config', 'admin_email'),
|
||||||
$this->t('Your account email address must match this in order to use the web admin panel.'),
|
$this->t('Your account email address must match this in order to use the web admin panel.'),
|
||||||
$this->t('Required'), 'autofocus', 'email'],
|
$this->t('Required'), 'autofocus', 'email'],
|
||||||
'$timezone' => Temporal::getTimezoneField('system-default_timezone',
|
'$timezone' => Temporal::getTimezoneField(
|
||||||
|
'system-default_timezone',
|
||||||
$this->t('Please select a default timezone for your website'),
|
$this->t('Please select a default timezone for your website'),
|
||||||
$this->configCache->get('system', 'default_timezone'),
|
$this->configCache->get('system', 'default_timezone'),
|
||||||
''),
|
''
|
||||||
|
),
|
||||||
'$language' => ['system-language',
|
'$language' => ['system-language',
|
||||||
$this->t('System Language:'),
|
$this->t('System Language:'),
|
||||||
$this->configCache->get('system', 'language'),
|
$this->configCache->get('system', 'language'),
|
||||||
|
|
|
@ -273,7 +273,7 @@ class Index extends BaseSearch
|
||||||
*/
|
*/
|
||||||
private static function tryRedirectToPost(string $search)
|
private static function tryRedirectToPost(string $search)
|
||||||
{
|
{
|
||||||
if (parse_url($search, PHP_URL_SCHEME) == '') {
|
if (!parse_url($search, PHP_URL_SCHEME) && !preg_match('=^[a-z]+://=', $search)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,12 +77,11 @@ class AppSpecific extends BaseSettings
|
||||||
$this->baseUrl->redirect('settings/2fa/app_specific?t=' . self::getFormSecurityToken('settings_2fa_password'));
|
$this->baseUrl->redirect('settings/2fa/app_specific?t=' . self::getFormSecurityToken('settings_2fa_password'));
|
||||||
} else {
|
} else {
|
||||||
$this->appSpecificPassword = AppSpecificPassword::generateForUser($this->session->getLocalUserId(), $request['description'] ?? '');
|
$this->appSpecificPassword = AppSpecificPassword::generateForUser($this->session->getLocalUserId(), $request['description'] ?? '');
|
||||||
$this->systemMessages->addInfo($this->t('New app-specific password generated: %s', $this->appSpecificPassword['plaintext_password']));
|
$this->systemMessages->addInfo($this->t('New app-specific password generated.'));
|
||||||
$this->baseUrl->redirect('settings/2fa/app_specific?t=' . self::getFormSecurityToken('settings_2fa_password'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'revoke_all' :
|
case 'revoke_all':
|
||||||
AppSpecificPassword::deleteAllForUser($this->session->getLocalUserId());
|
AppSpecificPassword::deleteAllForUser($this->session->getLocalUserId());
|
||||||
$this->systemMessages->addInfo($this->t('App-specific passwords successfully revoked.'));
|
$this->systemMessages->addInfo($this->t('App-specific passwords successfully revoked.'));
|
||||||
$this->baseUrl->redirect('settings/2fa/app_specific?t=' . self::getFormSecurityToken('settings_2fa_password'));
|
$this->baseUrl->redirect('settings/2fa/app_specific?t=' . self::getFormSecurityToken('settings_2fa_password'));
|
||||||
|
|
|
@ -291,10 +291,6 @@ final class ATProtocol
|
||||||
*/
|
*/
|
||||||
public function getUserDid(int $uid, bool $refresh = false): ?string
|
public function getUserDid(int $uid, bool $refresh = false): ?string
|
||||||
{
|
{
|
||||||
if (!$this->pConfig->get($uid, 'bluesky', 'post')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$refresh) {
|
if (!$refresh) {
|
||||||
$did = $this->pConfig->get($uid, 'bluesky', 'did');
|
$did = $this->pConfig->get($uid, 'bluesky', 'did');
|
||||||
if (!empty($did)) {
|
if (!empty($did)) {
|
||||||
|
|
|
@ -95,6 +95,7 @@ class Jetstream
|
||||||
// @todo make the path configurable
|
// @todo make the path configurable
|
||||||
$this->client = new \WebSocket\Client('wss://jetstream1.us-west.bsky.network/subscribe?requireHello=true' . $cursor);
|
$this->client = new \WebSocket\Client('wss://jetstream1.us-west.bsky.network/subscribe?requireHello=true' . $cursor);
|
||||||
$this->client->setTimeout($timeout);
|
$this->client->setTimeout($timeout);
|
||||||
|
$this->client->setLogger($this->logger);
|
||||||
} catch (\WebSocket\ConnectionException $e) {
|
} catch (\WebSocket\ConnectionException $e) {
|
||||||
$this->logger->error('Error while trying to establish the connection', ['code' => $e->getCode(), 'message' => $e->getMessage()]);
|
$this->logger->error('Error while trying to establish the connection', ['code' => $e->getCode(), 'message' => $e->getMessage()]);
|
||||||
echo "Connection wasn't established.\n";
|
echo "Connection wasn't established.\n";
|
||||||
|
|
|
@ -47,6 +47,7 @@ use Friendica\Util\Strings;
|
||||||
class Receiver
|
class Receiver
|
||||||
{
|
{
|
||||||
const PUBLIC_COLLECTION = 'as:Public';
|
const PUBLIC_COLLECTION = 'as:Public';
|
||||||
|
|
||||||
const ACCOUNT_TYPES = ['as:Person', 'as:Organization', 'as:Service', 'as:Group', 'as:Application'];
|
const ACCOUNT_TYPES = ['as:Person', 'as:Organization', 'as:Service', 'as:Group', 'as:Application'];
|
||||||
const CONTENT_TYPES = ['as:Note', 'as:Article', 'as:Video', 'as:Image', 'as:Event', 'as:Audio', 'as:Page', 'as:Question'];
|
const CONTENT_TYPES = ['as:Note', 'as:Article', 'as:Video', 'as:Image', 'as:Event', 'as:Audio', 'as:Page', 'as:Question'];
|
||||||
const ACTIVITY_TYPES = ['as:Like', 'as:Dislike', 'as:Accept', 'as:Reject', 'as:TentativeAccept', 'as:View', 'as:Read', 'litepub:EmojiReact'];
|
const ACTIVITY_TYPES = ['as:Like', 'as:Dislike', 'as:Accept', 'as:Reject', 'as:TentativeAccept', 'as:View', 'as:Read', 'litepub:EmojiReact'];
|
||||||
|
@ -373,6 +374,7 @@ class Receiver
|
||||||
$receivers = array_replace($receivers, $additional);
|
$receivers = array_replace($receivers, $additional);
|
||||||
if (empty($activity['thread-completion']) && (empty($reception_types[$uid]) || in_array($reception_types[$uid], [self::TARGET_UNKNOWN, self::TARGET_FOLLOWER, self::TARGET_ANSWER, self::TARGET_GLOBAL]))) {
|
if (empty($activity['thread-completion']) && (empty($reception_types[$uid]) || in_array($reception_types[$uid], [self::TARGET_UNKNOWN, self::TARGET_FOLLOWER, self::TARGET_ANSWER, self::TARGET_GLOBAL]))) {
|
||||||
$reception_types[$uid] = self::TARGET_BCC;
|
$reception_types[$uid] = self::TARGET_BCC;
|
||||||
|
|
||||||
$owner = User::getOwnerDataById($uid);
|
$owner = User::getOwnerDataById($uid);
|
||||||
if (!empty($owner['url'])) {
|
if (!empty($owner['url'])) {
|
||||||
$urls['as:bcc'][] = $owner['url'];
|
$urls['as:bcc'][] = $owner['url'];
|
||||||
|
@ -400,12 +402,14 @@ class Receiver
|
||||||
// Any activities on account types must not be altered
|
// Any activities on account types must not be altered
|
||||||
if (in_array($type, ['as:Flag'])) {
|
if (in_array($type, ['as:Flag'])) {
|
||||||
$object_data = [];
|
$object_data = [];
|
||||||
|
|
||||||
$object_data['id'] = JsonLD::fetchElement($activity, '@id');
|
$object_data['id'] = JsonLD::fetchElement($activity, '@id');
|
||||||
$object_data['object_id'] = JsonLD::fetchElement($activity, 'as:object', '@id');
|
$object_data['object_id'] = JsonLD::fetchElement($activity, 'as:object', '@id');
|
||||||
$object_data['object_ids'] = JsonLD::fetchElementArray($activity, 'as:object', '@id');
|
$object_data['object_ids'] = JsonLD::fetchElementArray($activity, 'as:object', '@id');
|
||||||
$object_data['content'] = JsonLD::fetchElement($activity, 'as:content', '@type');
|
$object_data['content'] = JsonLD::fetchElement($activity, 'as:content', '@type');
|
||||||
} elseif (in_array($object_type, self::ACCOUNT_TYPES)) {
|
} elseif (in_array($object_type, self::ACCOUNT_TYPES)) {
|
||||||
$object_data = [];
|
$object_data = [];
|
||||||
|
|
||||||
$object_data['id'] = JsonLD::fetchElement($activity, '@id');
|
$object_data['id'] = JsonLD::fetchElement($activity, '@id');
|
||||||
$object_data['object_id'] = JsonLD::fetchElement($activity, 'as:object', '@id');
|
$object_data['object_id'] = JsonLD::fetchElement($activity, 'as:object', '@id');
|
||||||
$object_data['object_actor'] = JsonLD::fetchElement($activity['as:object'], 'as:actor', '@id');
|
$object_data['object_actor'] = JsonLD::fetchElement($activity['as:object'], 'as:actor', '@id');
|
||||||
|
@ -436,12 +440,14 @@ class Receiver
|
||||||
// Create a mostly empty array out of the activity data (instead of the object).
|
// Create a mostly empty array out of the activity data (instead of the object).
|
||||||
// This way we later don't have to check for the existence of each individual array element.
|
// This way we later don't have to check for the existence of each individual array element.
|
||||||
$object_data = self::processObject($activity, $original_actor);
|
$object_data = self::processObject($activity, $original_actor);
|
||||||
|
|
||||||
$object_data['name'] = $type;
|
$object_data['name'] = $type;
|
||||||
$object_data['author'] = JsonLD::fetchElement($activity, 'as:actor', '@id');
|
$object_data['author'] = JsonLD::fetchElement($activity, 'as:actor', '@id');
|
||||||
$object_data['object_id'] = $object_id;
|
$object_data['object_id'] = $object_id;
|
||||||
$object_data['object_type'] = ''; // Since we don't fetch the object, we don't know the type
|
$object_data['object_type'] = ''; // Since we don't fetch the object, we don't know the type
|
||||||
} elseif (in_array($type, ['as:Add', 'as:Remove', 'as:Move'])) {
|
} elseif (in_array($type, ['as:Add', 'as:Remove', 'as:Move'])) {
|
||||||
$object_data = [];
|
$object_data = [];
|
||||||
|
|
||||||
$object_data['id'] = JsonLD::fetchElement($activity, '@id');
|
$object_data['id'] = JsonLD::fetchElement($activity, '@id');
|
||||||
$object_data['target_id'] = JsonLD::fetchElement($activity, 'as:target', '@id');
|
$object_data['target_id'] = JsonLD::fetchElement($activity, 'as:target', '@id');
|
||||||
$object_data['object_id'] = JsonLD::fetchElement($activity, 'as:object', '@id');
|
$object_data['object_id'] = JsonLD::fetchElement($activity, 'as:object', '@id');
|
||||||
|
@ -449,6 +455,7 @@ class Receiver
|
||||||
$object_data['object_content'] = JsonLD::fetchElement($activity['as:object'], 'as:content', '@type');
|
$object_data['object_content'] = JsonLD::fetchElement($activity['as:object'], 'as:content', '@type');
|
||||||
} else {
|
} else {
|
||||||
$object_data = [];
|
$object_data = [];
|
||||||
|
|
||||||
$object_data['id'] = JsonLD::fetchElement($activity, '@id');
|
$object_data['id'] = JsonLD::fetchElement($activity, '@id');
|
||||||
$object_data['object_id'] = JsonLD::fetchElement($activity, 'as:object', '@id');
|
$object_data['object_id'] = JsonLD::fetchElement($activity, 'as:object', '@id');
|
||||||
$object_data['object_actor'] = JsonLD::fetchElement($activity['as:object'], 'as:actor', '@id');
|
$object_data['object_actor'] = JsonLD::fetchElement($activity['as:object'], 'as:actor', '@id');
|
||||||
|
@ -555,6 +562,7 @@ class Receiver
|
||||||
|
|
||||||
$user = User::getById(array_key_first($receivers), ['language']);
|
$user = User::getById(array_key_first($receivers), ['language']);
|
||||||
$l10n = DI::l10n()->withLang($user['language']);
|
$l10n = DI::l10n()->withLang($user['language']);
|
||||||
|
|
||||||
$object_data['name'] = $l10n->t('Chat');
|
$object_data['name'] = $l10n->t('Chat');
|
||||||
|
|
||||||
$mail = DBA::selectFirst('mail', ['uri'], ['uid' => array_key_first($receivers), 'title' => $object_data['name']], ['order' => ['id' => true]]);
|
$mail = DBA::selectFirst('mail', ['uri'], ['uid' => array_key_first($receivers), 'title' => $object_data['name']], ['order' => ['id' => true]]);
|
||||||
|
@ -1237,8 +1245,10 @@ class Receiver
|
||||||
// Exception: The receiver is targetted via "to" or this is a comment
|
// Exception: The receiver is targetted via "to" or this is a comment
|
||||||
if ((($element != 'as:to') && empty($replyto)) || ($contact['contact-type'] == Contact::TYPE_COMMUNITY)) {
|
if ((($element != 'as:to') && empty($replyto)) || ($contact['contact-type'] == Contact::TYPE_COMMUNITY)) {
|
||||||
$networks = Protocol::FEDERATED;
|
$networks = Protocol::FEDERATED;
|
||||||
$condition = ['nurl' => Strings::normaliseLink($actor), 'rel' => [Contact::SHARING, Contact::FRIEND],
|
$condition = [
|
||||||
'network' => $networks, 'archive' => false, 'pending' => false, 'uid' => $contact['uid']];
|
'nurl' => Strings::normaliseLink($actor), 'rel' => [Contact::SHARING, Contact::FRIEND],
|
||||||
|
'network' => $networks, 'archive' => false, 'pending' => false, 'uid' => $contact['uid']
|
||||||
|
];
|
||||||
|
|
||||||
// Group posts are only accepted from group contacts
|
// Group posts are only accepted from group contacts
|
||||||
if ($contact['contact-type'] == Contact::TYPE_COMMUNITY) {
|
if ($contact['contact-type'] == Contact::TYPE_COMMUNITY) {
|
||||||
|
@ -1277,6 +1287,7 @@ class Receiver
|
||||||
|
|
||||||
if (empty($receivers) && !empty($parent['parent-author-link'])) {
|
if (empty($receivers) && !empty($parent['parent-author-link'])) {
|
||||||
$uid = User::getIdForURL($parent['parent-author-link']);
|
$uid = User::getIdForURL($parent['parent-author-link']);
|
||||||
|
|
||||||
$receivers[$uid] = ['uid' => $uid, 'type' => self::TARGET_BTO];
|
$receivers[$uid] = ['uid' => $uid, 'type' => self::TARGET_BTO];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1319,8 +1330,10 @@ class Receiver
|
||||||
*/
|
*/
|
||||||
private static function getReceiverForActor(array $tags, array $receivers, int $target_type, array $profile): array
|
private static function getReceiverForActor(array $tags, array $receivers, int $target_type, array $profile): array
|
||||||
{
|
{
|
||||||
$basecondition = ['rel' => [Contact::SHARING, Contact::FRIEND, Contact::FOLLOWER],
|
$basecondition = [
|
||||||
'network' => Protocol::FEDERATED, 'archive' => false, 'pending' => false];
|
'rel' => [Contact::SHARING, Contact::FRIEND, Contact::FOLLOWER],
|
||||||
|
'network' => Protocol::FEDERATED, 'archive' => false, 'pending' => false
|
||||||
|
];
|
||||||
|
|
||||||
$condition = DBA::mergeConditions($basecondition, ["`uri-id` = ? AND `uid` != ?", $profile['uri-id'], 0]);
|
$condition = DBA::mergeConditions($basecondition, ["`uri-id` = ? AND `uid` != ?", $profile['uri-id'], 0]);
|
||||||
$contacts = DBA::select('contact', ['uid', 'rel'], $condition);
|
$contacts = DBA::select('contact', ['uid', 'rel'], $condition);
|
||||||
|
@ -1545,10 +1558,9 @@ class Receiver
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$url = JsonLD::fetchElement($emoji['as:icon'], 'as:url', '@id');
|
|
||||||
$element = [
|
$element = [
|
||||||
'name' => JsonLD::fetchElement($emoji, 'as:name', '@value'),
|
'name' => JsonLD::fetchElement($emoji, 'as:name', '@value'),
|
||||||
'href' => $url
|
'href' => JsonLD::fetchElement($emoji['as:icon'], 'as:url', '@id')
|
||||||
];
|
];
|
||||||
|
|
||||||
$emojilist[] = $element;
|
$emojilist[] = $element;
|
||||||
|
@ -1847,6 +1859,7 @@ class Receiver
|
||||||
}
|
}
|
||||||
|
|
||||||
$size = (int)JsonLD::fetchElement($url, 'pt:size', '@value');
|
$size = (int)JsonLD::fetchElement($url, 'pt:size', '@value');
|
||||||
|
|
||||||
$attachments[] = ['type' => $filetype, 'mediaType' => $mediatype, 'url' => $href, 'height' => $height, 'size' => $size, 'name' => ''];
|
$attachments[] = ['type' => $filetype, 'mediaType' => $mediatype, 'url' => $href, 'height' => $height, 'size' => $size, 'name' => ''];
|
||||||
} elseif (in_array($mediatype, ['application/x-bittorrent', 'application/x-bittorrent;x-scheme-handler/magnet'])) {
|
} elseif (in_array($mediatype, ['application/x-bittorrent', 'application/x-bittorrent;x-scheme-handler/magnet'])) {
|
||||||
$height = (int)JsonLD::fetchElement($url, 'as:height', '@value');
|
$height = (int)JsonLD::fetchElement($url, 'as:height', '@value');
|
||||||
|
@ -1909,7 +1922,8 @@ class Receiver
|
||||||
return $object_data;
|
return $object_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function getCapabilities($object) {
|
private static function getCapabilities($object)
|
||||||
|
{
|
||||||
$capabilities = [];
|
$capabilities = [];
|
||||||
foreach (['pixelfed:canAnnounce', 'pixelfed:canLike', 'pixelfed:canReply'] as $element) {
|
foreach (['pixelfed:canAnnounce', 'pixelfed:canLike', 'pixelfed:canReply'] as $element) {
|
||||||
$capabilities_list = JsonLD::fetchElementArray($object['pixelfed:capabilities'], $element, '@id');
|
$capabilities_list = JsonLD::fetchElementArray($object['pixelfed:capabilities'], $element, '@id');
|
||||||
|
@ -1931,6 +1945,7 @@ class Receiver
|
||||||
public static function getObjectDataFromActivity(array $object): array
|
public static function getObjectDataFromActivity(array $object): array
|
||||||
{
|
{
|
||||||
$object_data = [];
|
$object_data = [];
|
||||||
|
|
||||||
$object_data['object_type'] = JsonLD::fetchElement($object, '@type');
|
$object_data['object_type'] = JsonLD::fetchElement($object, '@type');
|
||||||
$object_data['id'] = JsonLD::fetchElement($object, '@id');
|
$object_data['id'] = JsonLD::fetchElement($object, '@id');
|
||||||
$object_data['reply-to-id'] = JsonLD::fetchElement($object, 'as:inReplyTo', '@id');
|
$object_data['reply-to-id'] = JsonLD::fetchElement($object, 'as:inReplyTo', '@id');
|
||||||
|
@ -2037,9 +2052,15 @@ class Receiver
|
||||||
|
|
||||||
// Support for quoted posts (Pleroma, Fedibird and Misskey)
|
// Support for quoted posts (Pleroma, Fedibird and Misskey)
|
||||||
$object_data['quote-url'] = JsonLD::fetchElement($object, 'as:quoteUrl', '@id');
|
$object_data['quote-url'] = JsonLD::fetchElement($object, 'as:quoteUrl', '@id');
|
||||||
|
if (empty($object_data['quote-url'])) {
|
||||||
|
$object_data['quote-url'] = JsonLD::fetchElement($object, 'as:quoteUrl', '@value');
|
||||||
|
}
|
||||||
if (empty($object_data['quote-url'])) {
|
if (empty($object_data['quote-url'])) {
|
||||||
$object_data['quote-url'] = JsonLD::fetchElement($object, 'fedibird:quoteUri', '@id');
|
$object_data['quote-url'] = JsonLD::fetchElement($object, 'fedibird:quoteUri', '@id');
|
||||||
}
|
}
|
||||||
|
if (empty($object_data['quote-url'])) {
|
||||||
|
$object_data['quote-url'] = JsonLD::fetchElement($object, 'fedibird:quoteUri', '@value');
|
||||||
|
}
|
||||||
if (empty($object_data['quote-url'])) {
|
if (empty($object_data['quote-url'])) {
|
||||||
$object_data['quote-url'] = JsonLD::fetchElement($object, 'misskey:_misskey_quote', '@id');
|
$object_data['quote-url'] = JsonLD::fetchElement($object, 'misskey:_misskey_quote', '@id');
|
||||||
}
|
}
|
||||||
|
|
|
@ -254,7 +254,7 @@ class Authentication
|
||||||
$record = $this->dba->selectFirst(
|
$record = $this->dba->selectFirst(
|
||||||
'user',
|
'user',
|
||||||
[],
|
[],
|
||||||
['uid' => User::getIdFromPasswordAuthentication($username, $password)]
|
['uid' => User::getIdFromPasswordAuthentication($username, $password, false, true)]
|
||||||
);
|
);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$this->logger->warning('authenticate: failed login attempt', ['action' => 'login', 'username' => $username, 'ip' => $this->remoteAddress]);
|
$this->logger->warning('authenticate: failed login attempt', ['action' => 'login', 'username' => $username, 'ip' => $this->remoteAddress]);
|
||||||
|
@ -262,6 +262,12 @@ class Authentication
|
||||||
$this->baseUrl->redirect();
|
$this->baseUrl->redirect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($record['blocked']) {
|
||||||
|
$this->logger->warning('authenticate: user is blocked', ['action' => 'login', 'username' => $username, 'ip' => $this->remoteAddress]);
|
||||||
|
DI::sysmsg()->addNotice($this->l10n->t('Login failed because your account is blocked.'));
|
||||||
|
$this->baseUrl->redirect();
|
||||||
|
}
|
||||||
|
|
||||||
if (!$remember) {
|
if (!$remember) {
|
||||||
$trusted = $this->cookie->get('2fa_cookie_hash') ?? null;
|
$trusted = $this->cookie->get('2fa_cookie_hash') ?? null;
|
||||||
$this->cookie->clear();
|
$this->cookie->clear();
|
||||||
|
|
|
@ -189,7 +189,7 @@ class OAuth
|
||||||
'created_at' => DateTimeFormat::utcNow()
|
'created_at' => DateTimeFormat::utcNow()
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ([BaseApi::SCOPE_READ, BaseApi::SCOPE_WRITE, BaseApi::SCOPE_WRITE, BaseApi::SCOPE_PUSH] as $scope) {
|
foreach ([BaseApi::SCOPE_READ, BaseApi::SCOPE_WRITE, BaseApi::SCOPE_FOLLOW, BaseApi::SCOPE_PUSH] as $scope) {
|
||||||
if ($fields[$scope] && !$application[$scope]) {
|
if ($fields[$scope] && !$application[$scope]) {
|
||||||
Logger::warning('Requested token scope is not allowed for the application', ['token' => $fields, 'application' => $application]);
|
Logger::warning('Requested token scope is not allowed for the application', ['token' => $fields, 'application' => $application]);
|
||||||
}
|
}
|
||||||
|
|
210
src/System/Daemon.php
Normal file
210
src/System/Daemon.php
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Copyright (C) 2010-2025, the Friendica project
|
||||||
|
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
namespace Friendica\System;
|
||||||
|
|
||||||
|
use Friendica\Database\Database;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class for direct interacting with the daemon commands
|
||||||
|
*/
|
||||||
|
final class Daemon
|
||||||
|
{
|
||||||
|
private LoggerInterface $logger;
|
||||||
|
private Database $dba;
|
||||||
|
private ?string $pidfile = null;
|
||||||
|
private ?int $pid = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PID of the current daemon (null if either not set or not found)
|
||||||
|
*
|
||||||
|
* @return int|null
|
||||||
|
*/
|
||||||
|
public function getPid(): ?int
|
||||||
|
{
|
||||||
|
return $this->pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path to the PID file (null if not set)
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getPidfile(): ?string
|
||||||
|
{
|
||||||
|
return $this->pidfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct(LoggerInterface $logger, Database $dba)
|
||||||
|
{
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->dba = $dba;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the current daemon class with a given PID file
|
||||||
|
*
|
||||||
|
* @param string|null $pidfile the path to the PID file - using a given path if not directly set here
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function init(string $pidfile = null): void
|
||||||
|
{
|
||||||
|
if (!empty($pidfile)) {
|
||||||
|
$this->pid = null;
|
||||||
|
$this->pidfile = $pidfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->pid)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_readable($this->pidfile)) {
|
||||||
|
$this->pid = intval(file_get_contents($this->pidfile));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the daemon
|
||||||
|
*
|
||||||
|
* @param callable $daemonLogic the business logic of the daemon
|
||||||
|
* @param bool $foreground true, if started in foreground, otherwise spawned in the background
|
||||||
|
*
|
||||||
|
* @return bool true, if successfully started, otherwise false
|
||||||
|
*/
|
||||||
|
public function start(callable $daemonLogic, bool $foreground = false): bool
|
||||||
|
{
|
||||||
|
$this->init();
|
||||||
|
|
||||||
|
if (!empty($this->pid)) {
|
||||||
|
$this->logger->notice('process is already running', ['pid' => $this->pid, 'pidfile' => $this->pidfile]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->notice('starting daemon', ['pid' => $this->pid, 'pidfile' => $this->pidfile]);
|
||||||
|
|
||||||
|
if (!$foreground) {
|
||||||
|
$this->dba->disconnect();
|
||||||
|
|
||||||
|
// fork a daemon process
|
||||||
|
$this->pid = pcntl_fork();
|
||||||
|
if ($this->pid < 0) {
|
||||||
|
$this->logger->warning('Could not fork daemon');
|
||||||
|
return false;
|
||||||
|
} elseif ($this->pid) {
|
||||||
|
// The parent process continues here
|
||||||
|
if (!file_put_contents($this->pidfile, $this->pid)) {
|
||||||
|
$this->logger->warning('Could not store pid file', ['pid' => $this->pid, 'pidfile' => $this->pidfile]);
|
||||||
|
posix_kill($this->pid, SIGTERM);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$this->logger->notice('Child process started', ['pid' => $this->pid, 'pidfile' => $this->pidfile]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We now are in the child process
|
||||||
|
register_shutdown_function(function (): void {
|
||||||
|
posix_kill(posix_getpid(), SIGTERM);
|
||||||
|
posix_kill(posix_getpid(), SIGHUP);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Make the child the main process, detach it from the terminal
|
||||||
|
if (posix_setsid() < 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Closing all existing connections with the outside
|
||||||
|
fclose(STDIN);
|
||||||
|
|
||||||
|
// And now connect the database again
|
||||||
|
$this->dba->connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just to be sure that this script really runs endlessly
|
||||||
|
set_time_limit(0);
|
||||||
|
|
||||||
|
$daemonLogic();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks, if the current daemon is running
|
||||||
|
*
|
||||||
|
* @return bool true, if the daemon is running, otherwise false (f.e no PID found, no PID file found, PID is not bound to a running process))
|
||||||
|
*/
|
||||||
|
public function isRunning(): bool
|
||||||
|
{
|
||||||
|
$this->init();
|
||||||
|
|
||||||
|
if (empty($this->pid)) {
|
||||||
|
$this->logger->notice("Pid wasn't found");
|
||||||
|
|
||||||
|
if (is_readable($this->pidfile)) {
|
||||||
|
unlink($this->pidfile);
|
||||||
|
$this->logger->notice("Pidfile removed", ['pidfile' => $this->pidfile]);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (posix_kill($this->pid, 0)) {
|
||||||
|
$this->logger->notice("daemon process is running");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
unlink($this->pidfile);
|
||||||
|
$this->logger->notice("daemon process isn't running");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the daemon, if running
|
||||||
|
*
|
||||||
|
* @return bool true, if the daemon was successfully stopped or is already stopped, otherwise false
|
||||||
|
*/
|
||||||
|
public function stop(): bool
|
||||||
|
{
|
||||||
|
$this->init();
|
||||||
|
|
||||||
|
if (empty($this->pid)) {
|
||||||
|
$this->logger->notice("Pidfile wasn't found", ['pidfile' => $this->pidfile]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!posix_kill($this->pid, SIGTERM)) {
|
||||||
|
$this->logger->warning("Cannot kill the given PID", ['pid' => $this->pid, 'pidfile' => $this->pidfile]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!unlink($this->pidfile)) {
|
||||||
|
$this->logger->warning("Cannot delete the given PID file", ['pid' => $this->pid, 'pidfile' => $this->pidfile]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->notice('daemon process was killed', ['pid' => $this->pid, 'pidfile' => $this->pidfile]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current daemon to sleep and checks the status afterward
|
||||||
|
*
|
||||||
|
* @param int $duration the duration of time for sleeping (in milliseconds)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function sleep(int $duration)
|
||||||
|
{
|
||||||
|
usleep($duration);
|
||||||
|
|
||||||
|
$this->pid = pcntl_waitpid(-1, $status, WNOHANG);
|
||||||
|
if ($this->pid > 0) {
|
||||||
|
$this->logger->info('Children quit via pcntl_waitpid', ['pid' => $this->pid, 'status' => $status]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -227,6 +227,11 @@ class JsonLD
|
||||||
Logger::debug('schema.org path fixed');
|
Logger::debug('schema.org path fixed');
|
||||||
$value = 'http://schema.org#';
|
$value = 'http://schema.org#';
|
||||||
}
|
}
|
||||||
|
// Issue 14630: Wordpress Event Bridge uses a URL that cannot be retrieved
|
||||||
|
if (is_int($key) && $value == 'https://schema.org/') {
|
||||||
|
Logger::debug('https schema.org path fixed');
|
||||||
|
$value = 'https://schema.org/docs/jsonldcontext.json#';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Bookwyrm transmits "id" fields with "null", which isn't allowed.
|
// Bookwyrm transmits "id" fields with "null", which isn't allowed.
|
||||||
|
|
|
@ -219,7 +219,6 @@ return (function(string $basepath, array $getVars, array $serverVars, array $coo
|
||||||
'constructParams' => [
|
'constructParams' => [
|
||||||
$serverVars,
|
$serverVars,
|
||||||
__DIR__ . '/routes.config.php',
|
__DIR__ . '/routes.config.php',
|
||||||
[Dice::INSTANCE => Dice::SELF],
|
|
||||||
null
|
null
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
|
@ -5,22 +5,22 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
declare(strict_types = 1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Friendica\Test\Unit;
|
namespace Friendica\Test\Unit;
|
||||||
|
|
||||||
use Dice\Dice;
|
|
||||||
use Friendica\App;
|
use Friendica\App;
|
||||||
|
use Friendica\Core\Container;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class AppTest extends TestCase
|
class AppTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testFromDiceReturnsApp(): void
|
public function testFromContainerReturnsApp(): void
|
||||||
{
|
{
|
||||||
$dice = $this->createMock(Dice::class);
|
$container = $this->createMock(Container::class);
|
||||||
$dice->expects($this->never())->method('create');
|
$container->expects($this->never())->method('create');
|
||||||
|
|
||||||
$app = App::fromDice($dice);
|
$app = App::fromContainer($container);
|
||||||
|
|
||||||
$this->assertInstanceOf(App::class, $app);
|
$this->assertInstanceOf(App::class, $app);
|
||||||
}
|
}
|
||||||
|
|
48
tests/Unit/Core/ContainerTest.php
Normal file
48
tests/Unit/Core/ContainerTest.php
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Copyright (C) 2010-2024, the Friendica project
|
||||||
|
// SPDX-FileCopyrightText: 2010-2024 the Friendica project
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Core;
|
||||||
|
|
||||||
|
use Dice\Dice;
|
||||||
|
use Friendica\Core\Container;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Psr\Log\NullLogger;
|
||||||
|
|
||||||
|
class ContainerTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testFromDiceReturnsContainer(): void
|
||||||
|
{
|
||||||
|
$dice = $this->createMock(Dice::class);
|
||||||
|
$dice->expects($this->never())->method('create');
|
||||||
|
|
||||||
|
$container = Container::fromDice($dice);
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Container::class, $container);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCreateFromContainer(): void
|
||||||
|
{
|
||||||
|
$dice = $this->createMock(Dice::class);
|
||||||
|
$dice->expects($this->once())->method('create')->with(LoggerInterface::class)->willReturn(new NullLogger());
|
||||||
|
|
||||||
|
$container = Container::fromDice($dice);
|
||||||
|
|
||||||
|
$this->assertInstanceOf(NullLogger::class, $container->create(LoggerInterface::class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddRuleFromContainer(): void
|
||||||
|
{
|
||||||
|
$dice = $this->createMock(Dice::class);
|
||||||
|
$dice->expects($this->once())->method('addRule')->with(LoggerInterface::class, ['constructParams' => ['console']])->willReturn($dice);
|
||||||
|
|
||||||
|
$container = Container::fromDice($dice);
|
||||||
|
$container->addRule(LoggerInterface::class, ['constructParams' => ['console']]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,14 @@
|
||||||
# FRIENDICA Distributed Social Network
|
# FRIENDICA Distributed Social Network
|
||||||
# Copyright (C) 2010-2024, the Friendica project
|
# Copyright (C) 2010-2025, the Friendica project
|
||||||
# This file is distributed under the same license as the Friendica package.
|
# This file is distributed under the same license as the Friendica package.
|
||||||
# Mike Macgirvin, 2010
|
# Mike Macgirvin, 2010
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: 2024.12-dev\n"
|
"Project-Id-Version: 2025.02-dev\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-12-23 10:09+0000\n"
|
"POT-Creation-Date: 2025-01-04 20:55-0500\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -646,7 +646,7 @@ msgstr ""
|
||||||
msgid "Map"
|
msgid "Map"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/App.php:255
|
#: src/App.php:394
|
||||||
msgid "Apologies but the website is unavailable at the moment."
|
msgid "Apologies but the website is unavailable at the moment."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -747,17 +747,17 @@ msgstr ""
|
||||||
msgid "toggle mobile"
|
msgid "toggle mobile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/App/Router.php:295
|
#: src/App/Router.php:286
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Method not allowed for this module. Allowed method(s): %s"
|
msgid "Method not allowed for this module. Allowed method(s): %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/App/Router.php:297 src/Module/HTTPException/PageNotFound.php:35
|
#: src/App/Router.php:288 src/Module/HTTPException/PageNotFound.php:35
|
||||||
#: src/Module/Stats.php:56
|
#: src/Module/Stats.php:56
|
||||||
msgid "Page not found."
|
msgid "Page not found."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/App/Router.php:309
|
#: src/App/Router.php:300
|
||||||
msgid "You must be logged in to use addons. "
|
msgid "You must be logged in to use addons. "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -765,15 +765,15 @@ msgstr ""
|
||||||
msgid "No system theme config value set."
|
msgid "No system theme config value set."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/BaseModule.php:393
|
#: src/BaseModule.php:395
|
||||||
msgid "The form security token was not correct. This probably happened because the form has been opened for too long (>3 hours) before submitting it."
|
msgid "The form security token was not correct. This probably happened because the form has been opened for too long (>3 hours) before submitting it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/BaseModule.php:420
|
#: src/BaseModule.php:422
|
||||||
msgid "All contacts"
|
msgid "All contacts"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/BaseModule.php:425 src/Content/Conversation/Factory/Channel.php:32
|
#: src/BaseModule.php:427 src/Content/Conversation/Factory/Channel.php:32
|
||||||
#: src/Content/Widget.php:254 src/Core/ACL.php:182 src/Module/Contact.php:395
|
#: src/Content/Widget.php:254 src/Core/ACL.php:182 src/Module/Contact.php:395
|
||||||
#: src/Module/Privacy/PermissionTooltip.php:150
|
#: src/Module/Privacy/PermissionTooltip.php:150
|
||||||
#: src/Module/Privacy/PermissionTooltip.php:172
|
#: src/Module/Privacy/PermissionTooltip.php:172
|
||||||
|
@ -781,16 +781,16 @@ msgstr ""
|
||||||
msgid "Followers"
|
msgid "Followers"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/BaseModule.php:430 src/Content/Widget.php:255 src/Module/Contact.php:398
|
#: src/BaseModule.php:432 src/Content/Widget.php:255 src/Module/Contact.php:398
|
||||||
#: src/Module/Settings/Channels.php:145
|
#: src/Module/Settings/Channels.php:145
|
||||||
msgid "Following"
|
msgid "Following"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/BaseModule.php:435 src/Content/Widget.php:256 src/Module/Contact.php:401
|
#: src/BaseModule.php:437 src/Content/Widget.php:256 src/Module/Contact.php:401
|
||||||
msgid "Mutual friends"
|
msgid "Mutual friends"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/BaseModule.php:443
|
#: src/BaseModule.php:445
|
||||||
msgid "Common"
|
msgid "Common"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -944,7 +944,7 @@ msgstr ""
|
||||||
msgid "Enter user nickname: "
|
msgid "Enter user nickname: "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Console/User.php:168 src/Model/User.php:830
|
#: src/Console/User.php:168 src/Model/User.php:834
|
||||||
#: src/Module/Api/Twitter/ContactEndpoint.php:62
|
#: src/Module/Api/Twitter/ContactEndpoint.php:62
|
||||||
#: src/Module/Moderation/Users/Active.php:55
|
#: src/Module/Moderation/Users/Active.php:55
|
||||||
#: src/Module/Moderation/Users/Active.php:61
|
#: src/Module/Moderation/Users/Active.php:61
|
||||||
|
@ -1711,7 +1711,7 @@ msgstr ""
|
||||||
|
|
||||||
#: src/Content/Feature.php:116 src/Content/GroupManager.php:133
|
#: src/Content/Feature.php:116 src/Content/GroupManager.php:133
|
||||||
#: src/Content/Nav.php:264 src/Content/Text/HTML.php:868
|
#: src/Content/Nav.php:264 src/Content/Text/HTML.php:868
|
||||||
#: src/Content/Widget.php:555 src/Model/User.php:1390
|
#: src/Content/Widget.php:555 src/Model/User.php:1394
|
||||||
msgid "Groups"
|
msgid "Groups"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1835,7 +1835,7 @@ msgstr ""
|
||||||
msgid "Create new group"
|
msgid "Create new group"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Content/Item.php:322 src/Model/Item.php:3281
|
#: src/Content/Item.php:322 src/Model/Item.php:3297
|
||||||
msgid "event"
|
msgid "event"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1843,7 +1843,7 @@ msgstr ""
|
||||||
msgid "status"
|
msgid "status"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Content/Item.php:331 src/Model/Item.php:3283
|
#: src/Content/Item.php:331 src/Model/Item.php:3299
|
||||||
#: src/Module/Post/Tag/Add.php:109
|
#: src/Module/Post/Tag/Add.php:109
|
||||||
msgid "photo"
|
msgid "photo"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -2040,7 +2040,7 @@ msgid "Create an account"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Content/Nav.php:247 src/Module/Help.php:53
|
#: src/Content/Nav.php:247 src/Module/Help.php:53
|
||||||
#: src/Module/Settings/TwoFactor/AppSpecific.php:119
|
#: src/Module/Settings/TwoFactor/AppSpecific.php:118
|
||||||
#: src/Module/Settings/TwoFactor/Index.php:125
|
#: src/Module/Settings/TwoFactor/Index.php:125
|
||||||
#: src/Module/Settings/TwoFactor/Recovery.php:96
|
#: src/Module/Settings/TwoFactor/Recovery.php:96
|
||||||
#: src/Module/Settings/TwoFactor/Verify.php:135 view/theme/vier/theme.php:228
|
#: src/Module/Settings/TwoFactor/Verify.php:135 view/theme/vier/theme.php:228
|
||||||
|
@ -2245,8 +2245,8 @@ msgstr ""
|
||||||
msgid "<a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">%2$s</a> %3$s"
|
msgid "<a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">%2$s</a> %3$s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Content/Text/BBCode.php:926 src/Model/Item.php:4080
|
#: src/Content/Text/BBCode.php:926 src/Model/Item.php:4096
|
||||||
#: src/Model/Item.php:4086 src/Model/Item.php:4087
|
#: src/Model/Item.php:4102 src/Model/Item.php:4103
|
||||||
msgid "Link to source"
|
msgid "Link to source"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -2834,7 +2834,7 @@ msgstr ""
|
||||||
msgid "Could not connect to database."
|
msgid "Could not connect to database."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Core/L10n.php:426 src/Model/Item.php:2324
|
#: src/Core/L10n.php:426 src/Model/Item.php:2340
|
||||||
msgid "Undetermined"
|
msgid "Undetermined"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -3376,92 +3376,92 @@ msgstr ""
|
||||||
msgid "Happy Birthday %s"
|
msgid "Happy Birthday %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Item.php:2331
|
#: src/Model/Item.php:2347
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%s (%s - %s): %s"
|
msgid "%s (%s - %s): %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Item.php:2333
|
#: src/Model/Item.php:2349
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%s (%s): %s"
|
msgid "%s (%s): %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Item.php:2336
|
#: src/Model/Item.php:2352
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Detected languages in this post:\n"
|
"Detected languages in this post:\n"
|
||||||
"%s"
|
"%s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Item.php:3285
|
#: src/Model/Item.php:3301
|
||||||
msgid "activity"
|
msgid "activity"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Item.php:3287
|
#: src/Model/Item.php:3303
|
||||||
msgid "comment"
|
msgid "comment"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Item.php:3290 src/Module/Post/Tag/Add.php:109
|
#: src/Model/Item.php:3306 src/Module/Post/Tag/Add.php:109
|
||||||
msgid "post"
|
msgid "post"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Item.php:3463
|
#: src/Model/Item.php:3479
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%s is blocked"
|
msgid "%s is blocked"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Item.php:3465
|
#: src/Model/Item.php:3481
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%s is ignored"
|
msgid "%s is ignored"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Item.php:3467
|
#: src/Model/Item.php:3483
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Content from %s is collapsed"
|
msgid "Content from %s is collapsed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Item.php:3471
|
#: src/Model/Item.php:3487
|
||||||
msgid "Sensitive content"
|
msgid "Sensitive content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Item.php:3980
|
#: src/Model/Item.php:3996
|
||||||
msgid "bytes"
|
msgid "bytes"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Item.php:4011
|
#: src/Model/Item.php:4027
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%2$s (%3$d%%, %1$d vote)"
|
msgid "%2$s (%3$d%%, %1$d vote)"
|
||||||
msgid_plural "%2$s (%3$d%%, %1$d votes)"
|
msgid_plural "%2$s (%3$d%%, %1$d votes)"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#: src/Model/Item.php:4013
|
#: src/Model/Item.php:4029
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%2$s (%1$d vote)"
|
msgid "%2$s (%1$d vote)"
|
||||||
msgid_plural "%2$s (%1$d votes)"
|
msgid_plural "%2$s (%1$d votes)"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#: src/Model/Item.php:4018
|
#: src/Model/Item.php:4034
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d voter. Poll end: %s"
|
msgid "%d voter. Poll end: %s"
|
||||||
msgid_plural "%d voters. Poll end: %s"
|
msgid_plural "%d voters. Poll end: %s"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#: src/Model/Item.php:4020
|
#: src/Model/Item.php:4036
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "%d voter."
|
msgid "%d voter."
|
||||||
msgid_plural "%d voters."
|
msgid_plural "%d voters."
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#: src/Model/Item.php:4022
|
#: src/Model/Item.php:4038
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Poll end: %s"
|
msgid "Poll end: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/Item.php:4063 src/Model/Item.php:4064
|
#: src/Model/Item.php:4079 src/Model/Item.php:4080
|
||||||
msgid "View on separate page"
|
msgid "View on separate page"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -3619,138 +3619,138 @@ msgstr ""
|
||||||
msgid "Responsible account: %s"
|
msgid "Responsible account: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:217 src/Model/User.php:1310
|
#: src/Model/User.php:217 src/Model/User.php:1314
|
||||||
msgid "SERIOUS ERROR: Generation of security keys failed."
|
msgid "SERIOUS ERROR: Generation of security keys failed."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:739 src/Model/User.php:772
|
#: src/Model/User.php:740 src/Model/User.php:773
|
||||||
msgid "Login failed"
|
msgid "Login failed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:804
|
#: src/Model/User.php:806
|
||||||
msgid "Not enough information to authenticate"
|
msgid "Not enough information to authenticate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:929
|
#: src/Model/User.php:933
|
||||||
msgid "Password can't be empty"
|
msgid "Password can't be empty"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:971
|
#: src/Model/User.php:975
|
||||||
msgid "Empty passwords are not allowed."
|
msgid "Empty passwords are not allowed."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:975
|
#: src/Model/User.php:979
|
||||||
msgid "The new password has been exposed in a public data dump, please choose another."
|
msgid "The new password has been exposed in a public data dump, please choose another."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:979
|
#: src/Model/User.php:983
|
||||||
msgid "The password length is limited to 72 characters."
|
msgid "The password length is limited to 72 characters."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:983
|
#: src/Model/User.php:987
|
||||||
msgid "The password can't contain white spaces nor accentuated letters"
|
msgid "The password can't contain white spaces nor accentuated letters"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1192
|
#: src/Model/User.php:1196
|
||||||
msgid "Passwords do not match. Password unchanged."
|
msgid "Passwords do not match. Password unchanged."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1199
|
#: src/Model/User.php:1203
|
||||||
msgid "An invitation is required."
|
msgid "An invitation is required."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1203
|
#: src/Model/User.php:1207
|
||||||
msgid "Invitation could not be verified."
|
msgid "Invitation could not be verified."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1211
|
#: src/Model/User.php:1215
|
||||||
msgid "Invalid OpenID url"
|
msgid "Invalid OpenID url"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1225 src/Security/Authentication.php:231
|
#: src/Model/User.php:1229 src/Security/Authentication.php:231
|
||||||
msgid "We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID."
|
msgid "We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1225 src/Security/Authentication.php:231
|
#: src/Model/User.php:1229 src/Security/Authentication.php:231
|
||||||
msgid "The error message was:"
|
msgid "The error message was:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1231
|
#: src/Model/User.php:1235
|
||||||
msgid "Please enter the required information."
|
msgid "Please enter the required information."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1245
|
#: src/Model/User.php:1249
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "system.username_min_length (%s) and system.username_max_length (%s) are excluding each other, swapping values."
|
msgid "system.username_min_length (%s) and system.username_max_length (%s) are excluding each other, swapping values."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1252
|
#: src/Model/User.php:1256
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Username should be at least %s character."
|
msgid "Username should be at least %s character."
|
||||||
msgid_plural "Username should be at least %s characters."
|
msgid_plural "Username should be at least %s characters."
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#: src/Model/User.php:1256
|
#: src/Model/User.php:1260
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Username should be at most %s character."
|
msgid "Username should be at most %s character."
|
||||||
msgid_plural "Username should be at most %s characters."
|
msgid_plural "Username should be at most %s characters."
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#: src/Model/User.php:1264
|
#: src/Model/User.php:1268
|
||||||
msgid "That doesn't appear to be your full (First Last) name."
|
msgid "That doesn't appear to be your full (First Last) name."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1269
|
#: src/Model/User.php:1273
|
||||||
msgid "Your email domain is not among those allowed on this site."
|
msgid "Your email domain is not among those allowed on this site."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1273
|
#: src/Model/User.php:1277
|
||||||
msgid "Not a valid email address."
|
msgid "Not a valid email address."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1276
|
#: src/Model/User.php:1280
|
||||||
msgid "The nickname was blocked from registration by the nodes admin."
|
msgid "The nickname was blocked from registration by the nodes admin."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1280 src/Model/User.php:1286
|
#: src/Model/User.php:1284 src/Model/User.php:1290
|
||||||
msgid "Cannot use that email."
|
msgid "Cannot use that email."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1292
|
#: src/Model/User.php:1296
|
||||||
msgid "Your nickname can only contain a-z, 0-9 and _."
|
msgid "Your nickname can only contain a-z, 0-9 and _."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1300 src/Model/User.php:1350
|
#: src/Model/User.php:1304 src/Model/User.php:1354
|
||||||
msgid "Nickname is already registered. Please choose another."
|
msgid "Nickname is already registered. Please choose another."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1337 src/Model/User.php:1341
|
#: src/Model/User.php:1341 src/Model/User.php:1345
|
||||||
msgid "An error occurred during registration. Please try again."
|
msgid "An error occurred during registration. Please try again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1364
|
#: src/Model/User.php:1368
|
||||||
msgid "An error occurred creating your default profile. Please try again."
|
msgid "An error occurred creating your default profile. Please try again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1371
|
#: src/Model/User.php:1375
|
||||||
msgid "An error occurred creating your self contact. Please try again."
|
msgid "An error occurred creating your self contact. Please try again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1376
|
#: src/Model/User.php:1380
|
||||||
msgid "Friends"
|
msgid "Friends"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1380
|
#: src/Model/User.php:1384
|
||||||
msgid "An error occurred creating your default contact circle. Please try again."
|
msgid "An error occurred creating your default contact circle. Please try again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1428
|
#: src/Model/User.php:1432
|
||||||
msgid "Profile Photos"
|
msgid "Profile Photos"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1616
|
#: src/Model/User.php:1620
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -3758,7 +3758,7 @@ msgid ""
|
||||||
"\t\t\tthe administrator of %2$s has set up an account for you."
|
"\t\t\tthe administrator of %2$s has set up an account for you."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1619
|
#: src/Model/User.php:1623
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -3789,12 +3789,12 @@ msgid ""
|
||||||
"\t\tThank you and welcome to %4$s."
|
"\t\tThank you and welcome to %4$s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1651 src/Model/User.php:1757
|
#: src/Model/User.php:1655 src/Model/User.php:1761
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Registration details for %s"
|
msgid "Registration details for %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1671
|
#: src/Model/User.php:1675
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -3809,12 +3809,12 @@ msgid ""
|
||||||
"\t\t"
|
"\t\t"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1690
|
#: src/Model/User.php:1694
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Registration at %s"
|
msgid "Registration at %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1714
|
#: src/Model/User.php:1718
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -3823,7 +3823,7 @@ msgid ""
|
||||||
"\t\t\t"
|
"\t\t\t"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1722
|
#: src/Model/User.php:1726
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -3854,7 +3854,7 @@ msgid ""
|
||||||
"\t\t\tThank you and welcome to %2$s."
|
"\t\t\tThank you and welcome to %2$s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Model/User.php:1784
|
#: src/Model/User.php:1788
|
||||||
msgid "User with delegates can't be removed, please remove delegate users first"
|
msgid "User with delegates can't be removed, please remove delegate users first"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -9544,7 +9544,7 @@ msgstr ""
|
||||||
|
|
||||||
#: src/Module/Settings/Channels.php:177 src/Module/Settings/Channels.php:198
|
#: src/Module/Settings/Channels.php:177 src/Module/Settings/Channels.php:198
|
||||||
#: src/Module/Settings/Display.php:350
|
#: src/Module/Settings/Display.php:350
|
||||||
#: src/Module/Settings/TwoFactor/AppSpecific.php:124
|
#: src/Module/Settings/TwoFactor/AppSpecific.php:123
|
||||||
msgid "Description"
|
msgid "Description"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -10446,55 +10446,54 @@ msgid "App-specific password generation failed: This description already exists.
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Module/Settings/TwoFactor/AppSpecific.php:80
|
#: src/Module/Settings/TwoFactor/AppSpecific.php:80
|
||||||
#, php-format
|
msgid "New app-specific password generated."
|
||||||
msgid "New app-specific password generated: %s"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Module/Settings/TwoFactor/AppSpecific.php:87
|
#: src/Module/Settings/TwoFactor/AppSpecific.php:86
|
||||||
msgid "App-specific passwords successfully revoked."
|
msgid "App-specific passwords successfully revoked."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Module/Settings/TwoFactor/AppSpecific.php:97
|
#: src/Module/Settings/TwoFactor/AppSpecific.php:96
|
||||||
msgid "App-specific password successfully revoked."
|
msgid "App-specific password successfully revoked."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Module/Settings/TwoFactor/AppSpecific.php:118
|
#: src/Module/Settings/TwoFactor/AppSpecific.php:117
|
||||||
msgid "Two-factor app-specific passwords"
|
msgid "Two-factor app-specific passwords"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Module/Settings/TwoFactor/AppSpecific.php:120
|
#: src/Module/Settings/TwoFactor/AppSpecific.php:119
|
||||||
msgid "<p>App-specific passwords are randomly generated passwords used instead your regular password to authenticate your account on third-party applications that don't support two-factor authentication.</p>"
|
msgid "<p>App-specific passwords are randomly generated passwords used instead your regular password to authenticate your account on third-party applications that don't support two-factor authentication.</p>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Module/Settings/TwoFactor/AppSpecific.php:121
|
#: src/Module/Settings/TwoFactor/AppSpecific.php:120
|
||||||
msgid "Make sure to copy your new app-specific password now. You won’t be able to see it again!"
|
msgid "Make sure to copy your new app-specific password now. You won’t be able to see it again!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Module/Settings/TwoFactor/AppSpecific.php:125
|
#: src/Module/Settings/TwoFactor/AppSpecific.php:124
|
||||||
msgid "Last Used"
|
msgid "Last Used"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Module/Settings/TwoFactor/AppSpecific.php:126
|
#: src/Module/Settings/TwoFactor/AppSpecific.php:125
|
||||||
msgid "Revoke"
|
msgid "Revoke"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Module/Settings/TwoFactor/AppSpecific.php:127
|
#: src/Module/Settings/TwoFactor/AppSpecific.php:126
|
||||||
msgid "Revoke All"
|
msgid "Revoke All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Module/Settings/TwoFactor/AppSpecific.php:130
|
#: src/Module/Settings/TwoFactor/AppSpecific.php:129
|
||||||
msgid "When you generate a new app-specific password, you must use it right away, it will be shown to you once after you generate it."
|
msgid "When you generate a new app-specific password, you must use it right away, it will be shown to you once after you generate it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Module/Settings/TwoFactor/AppSpecific.php:131
|
#: src/Module/Settings/TwoFactor/AppSpecific.php:130
|
||||||
msgid "Generate new app-specific password"
|
msgid "Generate new app-specific password"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Module/Settings/TwoFactor/AppSpecific.php:132
|
#: src/Module/Settings/TwoFactor/AppSpecific.php:131
|
||||||
msgid "Friendiqa on my Fairphone 2..."
|
msgid "Friendiqa on my Fairphone 2..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Module/Settings/TwoFactor/AppSpecific.php:133
|
#: src/Module/Settings/TwoFactor/AppSpecific.php:132
|
||||||
msgid "Generate"
|
msgid "Generate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -11750,12 +11749,16 @@ msgstr ""
|
||||||
msgid "Login failed. Please check your credentials."
|
msgid "Login failed. Please check your credentials."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Security/Authentication.php:374
|
#: src/Security/Authentication.php:267
|
||||||
|
msgid "Login failed because your account is blocked."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/Security/Authentication.php:380
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "Welcome %s"
|
msgid "Welcome %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/Security/Authentication.php:375
|
#: src/Security/Authentication.php:381
|
||||||
msgid "Please upload a profile photo."
|
msgid "Please upload a profile photo."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1106,6 +1106,7 @@ $a->strings['Display'] = 'العرض';
|
||||||
$a->strings['Social Networks'] = 'الشبكات الاجتماعية';
|
$a->strings['Social Networks'] = 'الشبكات الاجتماعية';
|
||||||
$a->strings['Manage Accounts'] = 'إدارة الحسابات';
|
$a->strings['Manage Accounts'] = 'إدارة الحسابات';
|
||||||
$a->strings['Connected apps'] = 'التطبيقات المتصلة';
|
$a->strings['Connected apps'] = 'التطبيقات المتصلة';
|
||||||
|
$a->strings['Import Contacts'] = 'استيراد متراسلين';
|
||||||
$a->strings['Export personal data'] = 'تصدير البيانات الشخصية';
|
$a->strings['Export personal data'] = 'تصدير البيانات الشخصية';
|
||||||
$a->strings['Remove account'] = 'أزل الحساب';
|
$a->strings['Remove account'] = 'أزل الحساب';
|
||||||
$a->strings['This page is missing a url parameter.'] = 'هذه الصفحة تفتقد معطى للرابط.';
|
$a->strings['This page is missing a url parameter.'] = 'هذه الصفحة تفتقد معطى للرابط.';
|
||||||
|
@ -1768,8 +1769,6 @@ $a->strings['Wrong Password.'] = 'كلمة المرور خاطئة.';
|
||||||
$a->strings['Invalid email.'] = 'البريد الإلكتروني غير صالح.';
|
$a->strings['Invalid email.'] = 'البريد الإلكتروني غير صالح.';
|
||||||
$a->strings['Cannot change to that email.'] = 'لا يمكن التغيير إلى هذا البريد الإلكتروني.';
|
$a->strings['Cannot change to that email.'] = 'لا يمكن التغيير إلى هذا البريد الإلكتروني.';
|
||||||
$a->strings['Settings were not updated.'] = 'لم تُحدث الإعدادات.';
|
$a->strings['Settings were not updated.'] = 'لم تُحدث الإعدادات.';
|
||||||
$a->strings['Contact CSV file upload error'] = 'خطأ أثناء رفع ملف CSV';
|
|
||||||
$a->strings['Importing Contacts done'] = 'أُستورد المتراسلون';
|
|
||||||
$a->strings['Relocate message has been send to your contacts'] = 'أُرسلت رسالة تنبيه بانتقالك إلى متراسليك';
|
$a->strings['Relocate message has been send to your contacts'] = 'أُرسلت رسالة تنبيه بانتقالك إلى متراسليك';
|
||||||
$a->strings['Unable to find your profile. Please contact your admin.'] = 'تعذر العثور على ملفك الشخصي. من فضلك اتصال بالمدير.';
|
$a->strings['Unable to find your profile. Please contact your admin.'] = 'تعذر العثور على ملفك الشخصي. من فضلك اتصال بالمدير.';
|
||||||
$a->strings['Personal Page Subtypes'] = 'الأنواع الفرعية للصفحة الشخصية';
|
$a->strings['Personal Page Subtypes'] = 'الأنواع الفرعية للصفحة الشخصية';
|
||||||
|
@ -1851,9 +1850,6 @@ $a->strings['Show notifications of ignored contacts'] = 'أظهر تنبيهات
|
||||||
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = 'أنت لا ترى مشاركات المتراسلين المتجاهلين. لكن لا يزال بإمكانك رؤية تعليقاتهم. هذا الإعداد يتحكم إذا كنت ترغب في الاستمرار في تلقي تنبيهات سببها المتراسلون المتجاهلون.';
|
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = 'أنت لا ترى مشاركات المتراسلين المتجاهلين. لكن لا يزال بإمكانك رؤية تعليقاتهم. هذا الإعداد يتحكم إذا كنت ترغب في الاستمرار في تلقي تنبيهات سببها المتراسلون المتجاهلون.';
|
||||||
$a->strings['Advanced Account/Page Type Settings'] = 'الإعدادات المتقدمة للحساب/للصفحة';
|
$a->strings['Advanced Account/Page Type Settings'] = 'الإعدادات المتقدمة للحساب/للصفحة';
|
||||||
$a->strings['Change the behaviour of this account for special situations'] = 'غيّر سلوك هذا الحساب للحالات الخاصة';
|
$a->strings['Change the behaviour of this account for special situations'] = 'غيّر سلوك هذا الحساب للحالات الخاصة';
|
||||||
$a->strings['Import Contacts'] = 'استيراد متراسلين';
|
|
||||||
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'ارفع ملف CSV معرفات المتراسلين لحسابك القديم، معرفات المتابَعين تكون في العمود الأول.';
|
|
||||||
$a->strings['Upload File'] = 'ارفع ملفًا';
|
|
||||||
$a->strings['Relocate'] = 'الانتقال';
|
$a->strings['Relocate'] = 'الانتقال';
|
||||||
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'إذا كنت قد نقلت هذا الملف الشخصي من خادم آخر، وبعض المتراسلين لا يتلقون تحديثاتك، أنقر هذا الزر.';
|
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'إذا كنت قد نقلت هذا الملف الشخصي من خادم آخر، وبعض المتراسلين لا يتلقون تحديثاتك، أنقر هذا الزر.';
|
||||||
$a->strings['Resend relocate message to contacts'] = 'أعد إرسال رسالة الانتقال للمتراسلين';
|
$a->strings['Resend relocate message to contacts'] = 'أعد إرسال رسالة الانتقال للمتراسلين';
|
||||||
|
@ -1875,8 +1871,6 @@ $a->strings['Normally the system tries to find the best link to add to shortened
|
||||||
$a->strings['Enable simple text shortening'] = 'فعّل اختصار النصوص';
|
$a->strings['Enable simple text shortening'] = 'فعّل اختصار النصوص';
|
||||||
$a->strings['Attach the link title'] = 'أرفق عنوان الرابط';
|
$a->strings['Attach the link title'] = 'أرفق عنوان الرابط';
|
||||||
$a->strings['When activated, the title of the attached link will be added as a title on posts to Diaspora. This is mostly helpful with "remote-self" contacts that share feed content.'] = 'عند تفعيله سيتم إرفاق عنوان الصفحة بمنشور دياسبورا. هذا مفيد بشكل أساسي مع المتراسلين "الذاتيين" الذين يشاركون تغذيات Rss / Atom.';
|
$a->strings['When activated, the title of the attached link will be added as a title on posts to Diaspora. This is mostly helpful with "remote-self" contacts that share feed content.'] = 'عند تفعيله سيتم إرفاق عنوان الصفحة بمنشور دياسبورا. هذا مفيد بشكل أساسي مع المتراسلين "الذاتيين" الذين يشاركون تغذيات Rss / Atom.';
|
||||||
$a->strings['Your legacy ActivityPub/GNU Social account'] = 'حساب GNU Social\ActivityPub القديم';
|
|
||||||
$a->strings['If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.'] = 'إذا قمت بإدخال اسم حساب ActivityPub/GNU Social/Statusnet القديم هنا (بنسق user@domain.tld)، سيضاف المتراسلون في هذا الحساب تلقائيا. سيصفر الحقل عند الانتهاء.';
|
|
||||||
$a->strings['Email/Mailbox Setup'] = 'إعداد بريد الكتروني/صندوق بريد';
|
$a->strings['Email/Mailbox Setup'] = 'إعداد بريد الكتروني/صندوق بريد';
|
||||||
$a->strings['If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox.'] = 'إذا كنت ترغب في التواصل مع متراسلي البريد الإلكتروني باستخدام هذه الخدمة (اختيارية)، من فضلك حدد كيفية الاتصال بصندوق بريدك.';
|
$a->strings['If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox.'] = 'إذا كنت ترغب في التواصل مع متراسلي البريد الإلكتروني باستخدام هذه الخدمة (اختيارية)، من فضلك حدد كيفية الاتصال بصندوق بريدك.';
|
||||||
$a->strings['Last successful email check:'] = 'آخر تحقق ناجح للبريد الإلكتروني:';
|
$a->strings['Last successful email check:'] = 'آخر تحقق ناجح للبريد الإلكتروني:';
|
||||||
|
@ -1890,6 +1884,12 @@ $a->strings['Send public posts to all email contacts:'] = 'أرسل المشار
|
||||||
$a->strings['Action after import:'] = 'الإجراء بعد الاستيراد:';
|
$a->strings['Action after import:'] = 'الإجراء بعد الاستيراد:';
|
||||||
$a->strings['Move to folder'] = 'انقل إلى مجلد';
|
$a->strings['Move to folder'] = 'انقل إلى مجلد';
|
||||||
$a->strings['Move to folder:'] = 'انقل إلى المجلد:';
|
$a->strings['Move to folder:'] = 'انقل إلى المجلد:';
|
||||||
|
$a->strings['Contact CSV file upload error'] = 'خطأ أثناء رفع ملف CSV';
|
||||||
|
$a->strings['Importing Contacts done'] = 'أُستورد المتراسلون';
|
||||||
|
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'ارفع ملف CSV معرفات المتراسلين لحسابك القديم، معرفات المتابَعين تكون في العمود الأول.';
|
||||||
|
$a->strings['Upload File'] = 'ارفع ملفًا';
|
||||||
|
$a->strings['Your legacy ActivityPub/GNU Social account'] = 'حساب GNU Social\ActivityPub القديم';
|
||||||
|
$a->strings['If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.'] = 'إذا قمت بإدخال اسم حساب ActivityPub/GNU Social/Statusnet القديم هنا (بنسق user@domain.tld)، سيضاف المتراسلون في هذا الحساب تلقائيا. سيصفر الحقل عند الانتهاء.';
|
||||||
$a->strings['Delegation successfully granted.'] = 'منح التفويض بنجاح.';
|
$a->strings['Delegation successfully granted.'] = 'منح التفويض بنجاح.';
|
||||||
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'لم يُعثر على الولي أو هو غير متوفر أو كلمة مرور غير صحيحة.';
|
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'لم يُعثر على الولي أو هو غير متوفر أو كلمة مرور غير صحيحة.';
|
||||||
$a->strings['Delegation successfully revoked.'] = 'نجح إبطال التفويض.';
|
$a->strings['Delegation successfully revoked.'] = 'نجح إبطال التفويض.';
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1606,6 +1606,7 @@ $a->strings['Social Networks'] = 'Soziale Netzwerke';
|
||||||
$a->strings['Manage Accounts'] = 'Accounts Verwalten';
|
$a->strings['Manage Accounts'] = 'Accounts Verwalten';
|
||||||
$a->strings['Connected apps'] = 'Verbundene Programme';
|
$a->strings['Connected apps'] = 'Verbundene Programme';
|
||||||
$a->strings['Remote servers'] = 'Remote Instanzen';
|
$a->strings['Remote servers'] = 'Remote Instanzen';
|
||||||
|
$a->strings['Import Contacts'] = 'Kontakte Importieren';
|
||||||
$a->strings['Export personal data'] = 'Persönliche Daten exportieren';
|
$a->strings['Export personal data'] = 'Persönliche Daten exportieren';
|
||||||
$a->strings['Remove account'] = 'Konto löschen';
|
$a->strings['Remove account'] = 'Konto löschen';
|
||||||
$a->strings['This page is missing a url parameter.'] = 'Der Seite fehlt ein URL Parameter.';
|
$a->strings['This page is missing a url parameter.'] = 'Der Seite fehlt ein URL Parameter.';
|
||||||
|
@ -2439,8 +2440,6 @@ $a->strings['Wrong Password.'] = 'Falsches Passwort';
|
||||||
$a->strings['Invalid email.'] = 'Ungültige E-Mail-Adresse.';
|
$a->strings['Invalid email.'] = 'Ungültige E-Mail-Adresse.';
|
||||||
$a->strings['Cannot change to that email.'] = 'Ändern der E-Mail nicht möglich. ';
|
$a->strings['Cannot change to that email.'] = 'Ändern der E-Mail nicht möglich. ';
|
||||||
$a->strings['Settings were not updated.'] = 'Einstellungen nicht aktualisiert';
|
$a->strings['Settings were not updated.'] = 'Einstellungen nicht aktualisiert';
|
||||||
$a->strings['Contact CSV file upload error'] = 'Fehler beim Hochladen der Kontakt CSV Datei';
|
|
||||||
$a->strings['Importing Contacts done'] = 'Kontakte wurden importiert.';
|
|
||||||
$a->strings['Relocate message has been send to your contacts'] = 'Die Umzugsbenachrichtigung wurde an Deine Kontakte versendet.';
|
$a->strings['Relocate message has been send to your contacts'] = 'Die Umzugsbenachrichtigung wurde an Deine Kontakte versendet.';
|
||||||
$a->strings['Unable to find your profile. Please contact your admin.'] = 'Konnte dein Profil nicht finden. Bitte kontaktiere den Admin.';
|
$a->strings['Unable to find your profile. Please contact your admin.'] = 'Konnte dein Profil nicht finden. Bitte kontaktiere den Admin.';
|
||||||
$a->strings['Account for a service that automatically shares content based on user defined channels.'] = 'Konto für einen Dienst, der automatisch Inhalte basierend auf vom Benutzer definierten Kanälen teilt.';
|
$a->strings['Account for a service that automatically shares content based on user defined channels.'] = 'Konto für einen Dienst, der automatisch Inhalte basierend auf vom Benutzer definierten Kanälen teilt.';
|
||||||
|
@ -2536,9 +2535,6 @@ $a->strings['Show notifications of ignored contacts'] = 'Zeige Benachrichtigunge
|
||||||
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = 'Beiträge von ignorierten Kontakten werden dir nicht angezeigt. Aber du siehst immer noch ihre Kommentare. Diese Einstellung legt fest, ob du dazu weiterhin Benachrichtigungen erhalten willst oder ob diese einfach verworfen werden sollen.';
|
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = 'Beiträge von ignorierten Kontakten werden dir nicht angezeigt. Aber du siehst immer noch ihre Kommentare. Diese Einstellung legt fest, ob du dazu weiterhin Benachrichtigungen erhalten willst oder ob diese einfach verworfen werden sollen.';
|
||||||
$a->strings['Advanced Account/Page Type Settings'] = 'Erweiterte Konto-/Seitentyp-Einstellungen';
|
$a->strings['Advanced Account/Page Type Settings'] = 'Erweiterte Konto-/Seitentyp-Einstellungen';
|
||||||
$a->strings['Change the behaviour of this account for special situations'] = 'Verhalten dieses Kontos in bestimmten Situationen:';
|
$a->strings['Change the behaviour of this account for special situations'] = 'Verhalten dieses Kontos in bestimmten Situationen:';
|
||||||
$a->strings['Import Contacts'] = 'Kontakte Importieren';
|
|
||||||
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'Lade eine CSV Datei hoch, die das Handle der Kontakte deines alten Nutzerkontos in der ersten Spalte enthält.';
|
|
||||||
$a->strings['Upload File'] = 'Datei hochladen';
|
|
||||||
$a->strings['Relocate'] = 'Umziehen';
|
$a->strings['Relocate'] = 'Umziehen';
|
||||||
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Wenn du dein Profil von einem anderen Server umgezogen hast und einige deiner Kontakte deine Beiträge nicht erhalten, verwende diesen Button.';
|
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Wenn du dein Profil von einem anderen Server umgezogen hast und einige deiner Kontakte deine Beiträge nicht erhalten, verwende diesen Button.';
|
||||||
$a->strings['Resend relocate message to contacts'] = 'Umzugsbenachrichtigung erneut an Kontakte senden';
|
$a->strings['Resend relocate message to contacts'] = 'Umzugsbenachrichtigung erneut an Kontakte senden';
|
||||||
|
@ -2606,8 +2602,6 @@ $a->strings['API: Automatically links at the end of the post as attached posts']
|
||||||
$a->strings['When activated, added links at the end of the post react the same way as added links in the web interface.'] = 'Wenn dies aktiviert ist, reagieren hinzugefügte Links am Ende des Beitrags genauso wie hinzugefügte Links in der Weboberfläche.';
|
$a->strings['When activated, added links at the end of the post react the same way as added links in the web interface.'] = 'Wenn dies aktiviert ist, reagieren hinzugefügte Links am Ende des Beitrags genauso wie hinzugefügte Links in der Weboberfläche.';
|
||||||
$a->strings['Article Mode'] = 'Artikel Modus';
|
$a->strings['Article Mode'] = 'Artikel Modus';
|
||||||
$a->strings['Controls how posts with titles are transmitted. Mastodon and its forks don\'t display the content of these posts if the post is created in the correct (default) way.'] = 'Kontrolliert wie Beiträge mit Titeln übermittel werden. Mastodon und dessen Forks stellen den Inhalt dieser Beiträge nicht dar, wenn sie an sich korrekt in den Grundeinstellungen übertragen werden.';
|
$a->strings['Controls how posts with titles are transmitted. Mastodon and its forks don\'t display the content of these posts if the post is created in the correct (default) way.'] = 'Kontrolliert wie Beiträge mit Titeln übermittel werden. Mastodon und dessen Forks stellen den Inhalt dieser Beiträge nicht dar, wenn sie an sich korrekt in den Grundeinstellungen übertragen werden.';
|
||||||
$a->strings['Your legacy ActivityPub/GNU Social account'] = 'Dein alter ActivityPub/GNU Social-Account';
|
|
||||||
$a->strings['If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.'] = 'Wenn du deinen alten ActivityPub oder GNU Social/Statusnet-Account-Namen hier angibst (Format name@domain.tld), werden deine Kontakte automatisch hinzugefügt. Dieses Feld wird geleert, wenn die Kontakte hinzugefügt wurden.';
|
|
||||||
$a->strings['Email/Mailbox Setup'] = 'E-Mail/Postfach-Einstellungen';
|
$a->strings['Email/Mailbox Setup'] = 'E-Mail/Postfach-Einstellungen';
|
||||||
$a->strings['If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox.'] = 'Wenn du mit E-Mail-Kontakten über diesen Service kommunizieren möchtest (optional), gib bitte die Einstellungen für dein Postfach an.';
|
$a->strings['If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox.'] = 'Wenn du mit E-Mail-Kontakten über diesen Service kommunizieren möchtest (optional), gib bitte die Einstellungen für dein Postfach an.';
|
||||||
$a->strings['Last successful email check:'] = 'Letzter erfolgreicher E-Mail-Check';
|
$a->strings['Last successful email check:'] = 'Letzter erfolgreicher E-Mail-Check';
|
||||||
|
@ -2621,6 +2615,12 @@ $a->strings['Send public posts to all email contacts:'] = 'Sende öffentliche Be
|
||||||
$a->strings['Action after import:'] = 'Aktion nach Import:';
|
$a->strings['Action after import:'] = 'Aktion nach Import:';
|
||||||
$a->strings['Move to folder'] = 'In einen Ordner verschieben';
|
$a->strings['Move to folder'] = 'In einen Ordner verschieben';
|
||||||
$a->strings['Move to folder:'] = 'In diesen Ordner verschieben:';
|
$a->strings['Move to folder:'] = 'In diesen Ordner verschieben:';
|
||||||
|
$a->strings['Contact CSV file upload error'] = 'Fehler beim Hochladen der Kontakt CSV Datei';
|
||||||
|
$a->strings['Importing Contacts done'] = 'Kontakte wurden importiert.';
|
||||||
|
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'Lade eine CSV Datei hoch, die das Handle der Kontakte deines alten Nutzerkontos in der ersten Spalte enthält.';
|
||||||
|
$a->strings['Upload File'] = 'Datei hochladen';
|
||||||
|
$a->strings['Your legacy ActivityPub/GNU Social account'] = 'Dein alter ActivityPub/GNU Social-Account';
|
||||||
|
$a->strings['If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.'] = 'Wenn du deinen alten ActivityPub oder GNU Social/Statusnet-Account-Namen hier angibst (Format name@domain.tld), werden deine Kontakte automatisch hinzugefügt. Dieses Feld wird geleert, wenn die Kontakte hinzugefügt wurden.';
|
||||||
$a->strings['Delegation successfully granted.'] = 'Delegierung erfolgreich eingerichtet.';
|
$a->strings['Delegation successfully granted.'] = 'Delegierung erfolgreich eingerichtet.';
|
||||||
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'Der angegebene Nutzer konnte nicht gefunden werden, ist nicht verfügbar oder das angegebene Passwort ist nicht richtig.';
|
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'Der angegebene Nutzer konnte nicht gefunden werden, ist nicht verfügbar oder das angegebene Passwort ist nicht richtig.';
|
||||||
$a->strings['Delegation successfully revoked.'] = 'Delegation erfolgreich aufgehoben.';
|
$a->strings['Delegation successfully revoked.'] = 'Delegation erfolgreich aufgehoben.';
|
||||||
|
@ -3037,7 +3037,7 @@ $a->strings['Delete globally'] = 'Global löschen';
|
||||||
$a->strings['Remove locally'] = 'Lokal entfernen';
|
$a->strings['Remove locally'] = 'Lokal entfernen';
|
||||||
$a->strings['Block %s'] = 'Blockiere %s';
|
$a->strings['Block %s'] = 'Blockiere %s';
|
||||||
$a->strings['Ignore %s'] = 'Ignoriere %s';
|
$a->strings['Ignore %s'] = 'Ignoriere %s';
|
||||||
$a->strings['Collapse %s'] = 'Verberge %s';
|
$a->strings['Collapse %s'] = 'Klappe %s zu';
|
||||||
$a->strings['Report post'] = 'Beitrag melden';
|
$a->strings['Report post'] = 'Beitrag melden';
|
||||||
$a->strings['Save to folder'] = 'In Ordner speichern';
|
$a->strings['Save to folder'] = 'In Ordner speichern';
|
||||||
$a->strings['I will attend'] = 'Ich werde teilnehmen';
|
$a->strings['I will attend'] = 'Ich werde teilnehmen';
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1073,6 +1073,7 @@ $a->strings['Display'] = 'Interfaz del usuario';
|
||||||
$a->strings['Social Networks'] = 'Redes sociales';
|
$a->strings['Social Networks'] = 'Redes sociales';
|
||||||
$a->strings['Manage Accounts'] = 'Gestionar cuentas';
|
$a->strings['Manage Accounts'] = 'Gestionar cuentas';
|
||||||
$a->strings['Connected apps'] = 'Aplicaciones conectadas';
|
$a->strings['Connected apps'] = 'Aplicaciones conectadas';
|
||||||
|
$a->strings['Import Contacts'] = 'Importar contactos';
|
||||||
$a->strings['Export personal data'] = 'Exportación de datos personales';
|
$a->strings['Export personal data'] = 'Exportación de datos personales';
|
||||||
$a->strings['Remove account'] = 'Eliminar cuenta';
|
$a->strings['Remove account'] = 'Eliminar cuenta';
|
||||||
$a->strings['This page is missing a url parameter.'] = 'A la página le falta URL.';
|
$a->strings['This page is missing a url parameter.'] = 'A la página le falta URL.';
|
||||||
|
@ -1686,8 +1687,6 @@ $a->strings['Wrong Password.'] = 'Password erróneo';
|
||||||
$a->strings['Invalid email.'] = 'Corréo no válido.';
|
$a->strings['Invalid email.'] = 'Corréo no válido.';
|
||||||
$a->strings['Cannot change to that email.'] = 'Imposible cambiar a ese correo.';
|
$a->strings['Cannot change to that email.'] = 'Imposible cambiar a ese correo.';
|
||||||
$a->strings['Settings were not updated.'] = 'Configuración no actualizada';
|
$a->strings['Settings were not updated.'] = 'Configuración no actualizada';
|
||||||
$a->strings['Contact CSV file upload error'] = 'Error al subir archivo CSV';
|
|
||||||
$a->strings['Importing Contacts done'] = 'Importación del contacto completada';
|
|
||||||
$a->strings['Relocate message has been send to your contacts'] = 'Mensaje de reubicación enviado a sus contactos.';
|
$a->strings['Relocate message has been send to your contacts'] = 'Mensaje de reubicación enviado a sus contactos.';
|
||||||
$a->strings['Unable to find your profile. Please contact your admin.'] = 'No se encontró tu perfil. Contacta al Administrador.';
|
$a->strings['Unable to find your profile. Please contact your admin.'] = 'No se encontró tu perfil. Contacta al Administrador.';
|
||||||
$a->strings['Personal Page Subtypes'] = 'Subtipos de Página Personal';
|
$a->strings['Personal Page Subtypes'] = 'Subtipos de Página Personal';
|
||||||
|
@ -1766,9 +1765,6 @@ $a->strings['Show notifications of ignored contacts'] = 'Mostrar notificación d
|
||||||
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = 'No ves publicaciones de contactos ignorados. Pero todavía ves sus comentarios. Esta configuración controla si aún desea recibir notificaciones regulares causadas por contactos ignorados o no.';
|
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = 'No ves publicaciones de contactos ignorados. Pero todavía ves sus comentarios. Esta configuración controla si aún desea recibir notificaciones regulares causadas por contactos ignorados o no.';
|
||||||
$a->strings['Advanced Account/Page Type Settings'] = 'Configuración avanzada de tipo de Cuenta/Página';
|
$a->strings['Advanced Account/Page Type Settings'] = 'Configuración avanzada de tipo de Cuenta/Página';
|
||||||
$a->strings['Change the behaviour of this account for special situations'] = 'Cambiar el comportamiento de esta cuenta para situaciones especiales';
|
$a->strings['Change the behaviour of this account for special situations'] = 'Cambiar el comportamiento de esta cuenta para situaciones especiales';
|
||||||
$a->strings['Import Contacts'] = 'Importar contactos';
|
|
||||||
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'Subir archivo CSV que contenga identificador de tus cuentas seguidas en elprimera columna que exportó desde la cuenta anterior.';
|
|
||||||
$a->strings['Upload File'] = 'Subir archivo';
|
|
||||||
$a->strings['Relocate'] = 'Relocalizar';
|
$a->strings['Relocate'] = 'Relocalizar';
|
||||||
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Si migró este perfil desde otro servidor y algunos contactos no reciben sus publicaciones intente oprimiendo esta opción.';
|
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Si migró este perfil desde otro servidor y algunos contactos no reciben sus publicaciones intente oprimiendo esta opción.';
|
||||||
$a->strings['Resend relocate message to contacts'] = 'Reenviar mensaje de relocalización a contactos';
|
$a->strings['Resend relocate message to contacts'] = 'Reenviar mensaje de relocalización a contactos';
|
||||||
|
@ -1796,6 +1792,10 @@ $a->strings['Send public posts to all email contacts:'] = 'Enviar notificaciones
|
||||||
$a->strings['Action after import:'] = 'Acción al importar:';
|
$a->strings['Action after import:'] = 'Acción al importar:';
|
||||||
$a->strings['Move to folder'] = 'Mover a un folder';
|
$a->strings['Move to folder'] = 'Mover a un folder';
|
||||||
$a->strings['Move to folder:'] = 'Mover al folder:';
|
$a->strings['Move to folder:'] = 'Mover al folder:';
|
||||||
|
$a->strings['Contact CSV file upload error'] = 'Error al subir archivo CSV';
|
||||||
|
$a->strings['Importing Contacts done'] = 'Importación del contacto completada';
|
||||||
|
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'Subir archivo CSV que contenga identificador de tus cuentas seguidas en elprimera columna que exportó desde la cuenta anterior.';
|
||||||
|
$a->strings['Upload File'] = 'Subir archivo';
|
||||||
$a->strings['Delegation successfully granted.'] = 'Se autorizó delegación.';
|
$a->strings['Delegation successfully granted.'] = 'Se autorizó delegación.';
|
||||||
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'Usuario padre no encontrado, o no coincide contraseña.';
|
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'Usuario padre no encontrado, o no coincide contraseña.';
|
||||||
$a->strings['Delegation successfully revoked.'] = 'Delegación revocada con éxito.';
|
$a->strings['Delegation successfully revoked.'] = 'Delegación revocada con éxito.';
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -729,7 +729,6 @@ $a->strings['Text-only notification emails'] = 'Ainult tekstipõhised teavitusme
|
||||||
$a->strings['Send text only notification emails, without the html part'] = 'Saada ainut tekstimeile ilma html-ita';
|
$a->strings['Send text only notification emails, without the html part'] = 'Saada ainut tekstimeile ilma html-ita';
|
||||||
$a->strings['Show detailled notifications'] = 'Kuva detailseid teavitusi';
|
$a->strings['Show detailled notifications'] = 'Kuva detailseid teavitusi';
|
||||||
$a->strings['Advanced Account/Page Type Settings'] = 'Konto/Lehetüübi sätted edasijõudnutele';
|
$a->strings['Advanced Account/Page Type Settings'] = 'Konto/Lehetüübi sätted edasijõudnutele';
|
||||||
$a->strings['Upload File'] = 'Lae fail üles';
|
|
||||||
$a->strings['Addon Settings'] = 'Lisade sätted';
|
$a->strings['Addon Settings'] = 'Lisade sätted';
|
||||||
$a->strings['Add'] = 'Lisa';
|
$a->strings['Add'] = 'Lisa';
|
||||||
$a->strings['Failed to connect with email account using the settings provided.'] = 'E-posti kontoga ei õnnestu antud sätetega ühendust saada.';
|
$a->strings['Failed to connect with email account using the settings provided.'] = 'E-posti kontoga ei õnnestu antud sätetega ühendust saada.';
|
||||||
|
@ -740,6 +739,7 @@ $a->strings['Last successful email check:'] = 'Viimane õnnestunud meilikontroll
|
||||||
$a->strings['Action after import:'] = 'Tegevus peale inporti:';
|
$a->strings['Action after import:'] = 'Tegevus peale inporti:';
|
||||||
$a->strings['Move to folder'] = 'Liiguta kausta';
|
$a->strings['Move to folder'] = 'Liiguta kausta';
|
||||||
$a->strings['Move to folder:'] = 'Liiguta kausta:';
|
$a->strings['Move to folder:'] = 'Liiguta kausta:';
|
||||||
|
$a->strings['Upload File'] = 'Lae fail üles';
|
||||||
$a->strings['No parent user'] = 'Vanemkasutajad ei ole';
|
$a->strings['No parent user'] = 'Vanemkasutajad ei ole';
|
||||||
$a->strings['Parent User'] = 'Vanemkasutaja';
|
$a->strings['Parent User'] = 'Vanemkasutaja';
|
||||||
$a->strings['Additional Accounts'] = 'Lisakontod';
|
$a->strings['Additional Accounts'] = 'Lisakontod';
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1639,6 +1639,7 @@ $a->strings['Social Networks'] = 'Réseaux sociaux';
|
||||||
$a->strings['Manage Accounts'] = 'Gérer vos comptes';
|
$a->strings['Manage Accounts'] = 'Gérer vos comptes';
|
||||||
$a->strings['Connected apps'] = 'Applications connectées';
|
$a->strings['Connected apps'] = 'Applications connectées';
|
||||||
$a->strings['Remote servers'] = 'Serveurs distants';
|
$a->strings['Remote servers'] = 'Serveurs distants';
|
||||||
|
$a->strings['Import Contacts'] = 'Importer des contacts';
|
||||||
$a->strings['Export personal data'] = 'Exporter';
|
$a->strings['Export personal data'] = 'Exporter';
|
||||||
$a->strings['Remove account'] = 'Supprimer le compte';
|
$a->strings['Remove account'] = 'Supprimer le compte';
|
||||||
$a->strings['This page is missing a url parameter.'] = 'Il manque un paramètre d\'URL à cette adresse.';
|
$a->strings['This page is missing a url parameter.'] = 'Il manque un paramètre d\'URL à cette adresse.';
|
||||||
|
@ -2489,8 +2490,6 @@ $a->strings['Wrong Password.'] = 'Mot de passe erroné.';
|
||||||
$a->strings['Invalid email.'] = 'Courriel invalide.';
|
$a->strings['Invalid email.'] = 'Courriel invalide.';
|
||||||
$a->strings['Cannot change to that email.'] = 'Ne peut pas changer vers ce courriel.';
|
$a->strings['Cannot change to that email.'] = 'Ne peut pas changer vers ce courriel.';
|
||||||
$a->strings['Settings were not updated.'] = 'Les paramètres n\'ont pas été mis à jour.';
|
$a->strings['Settings were not updated.'] = 'Les paramètres n\'ont pas été mis à jour.';
|
||||||
$a->strings['Contact CSV file upload error'] = 'Erreur de téléversement du fichier de contact CSV';
|
|
||||||
$a->strings['Importing Contacts done'] = 'Import des contacts effectué';
|
|
||||||
$a->strings['Relocate message has been send to your contacts'] = 'Un message de relocalisation a été envoyé à vos contacts.';
|
$a->strings['Relocate message has been send to your contacts'] = 'Un message de relocalisation a été envoyé à vos contacts.';
|
||||||
$a->strings['Unable to find your profile. Please contact your admin.'] = 'Impossible de trouver votre profile. Merci de contacter votre administrateur.';
|
$a->strings['Unable to find your profile. Please contact your admin.'] = 'Impossible de trouver votre profile. Merci de contacter votre administrateur.';
|
||||||
$a->strings['Account for a service that automatically shares content based on user defined channels.'] = 'Compte de service qui partage automatiquement du contenu basés les chaînes de l\'utilisateur';
|
$a->strings['Account for a service that automatically shares content based on user defined channels.'] = 'Compte de service qui partage automatiquement du contenu basés les chaînes de l\'utilisateur';
|
||||||
|
@ -2586,9 +2585,6 @@ $a->strings['Show notifications of ignored contacts'] = 'Montrer les notificatio
|
||||||
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = 'Par défaut les notifications de vos contacts ignorés sont également ignorées.';
|
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = 'Par défaut les notifications de vos contacts ignorés sont également ignorées.';
|
||||||
$a->strings['Advanced Account/Page Type Settings'] = 'Paramètres avancés de compte/page';
|
$a->strings['Advanced Account/Page Type Settings'] = 'Paramètres avancés de compte/page';
|
||||||
$a->strings['Change the behaviour of this account for special situations'] = 'Modifier le comportement de ce compte dans certaines situations';
|
$a->strings['Change the behaviour of this account for special situations'] = 'Modifier le comportement de ce compte dans certaines situations';
|
||||||
$a->strings['Import Contacts'] = 'Importer des contacts';
|
|
||||||
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'Téléversez un fichier CSV contenant des identifiants de contacts dans la première colonne.';
|
|
||||||
$a->strings['Upload File'] = 'Téléverser le fichier';
|
|
||||||
$a->strings['Relocate'] = 'Relocaliser';
|
$a->strings['Relocate'] = 'Relocaliser';
|
||||||
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Si vous avez migré ce profil depuis un autre serveur et que vos contacts ne reçoivent plus vos mises à jour, essayez ce bouton.';
|
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Si vous avez migré ce profil depuis un autre serveur et que vos contacts ne reçoivent plus vos mises à jour, essayez ce bouton.';
|
||||||
$a->strings['Resend relocate message to contacts'] = 'Renvoyer un message de relocalisation aux contacts.';
|
$a->strings['Resend relocate message to contacts'] = 'Renvoyer un message de relocalisation aux contacts.';
|
||||||
|
@ -2656,8 +2652,6 @@ $a->strings['API: Automatically links at the end of the post as attached posts']
|
||||||
$a->strings['When activated, added links at the end of the post react the same way as added links in the web interface.'] = 'Quand activé, les liens ajoutés à la fin d\'une publication fonctionnent de la même manière que les liens ajoutés dans l\'interface web.';
|
$a->strings['When activated, added links at the end of the post react the same way as added links in the web interface.'] = 'Quand activé, les liens ajoutés à la fin d\'une publication fonctionnent de la même manière que les liens ajoutés dans l\'interface web.';
|
||||||
$a->strings['Article Mode'] = 'Mode Article';
|
$a->strings['Article Mode'] = 'Mode Article';
|
||||||
$a->strings['Controls how posts with titles are transmitted. Mastodon and its forks don\'t display the content of these posts if the post is created in the correct (default) way.'] = 'Contrôle la façon dont les publications avec des titres sont transmises. Mastodon et ses forks n\'affichent pas le contenu de ces publications si la publication est créée de la bonne manière (par défaut).';
|
$a->strings['Controls how posts with titles are transmitted. Mastodon and its forks don\'t display the content of these posts if the post is created in the correct (default) way.'] = 'Contrôle la façon dont les publications avec des titres sont transmises. Mastodon et ses forks n\'affichent pas le contenu de ces publications si la publication est créée de la bonne manière (par défaut).';
|
||||||
$a->strings['Your legacy ActivityPub/GNU Social account'] = 'Votre ancient compte ActivityPub/GNU Social';
|
|
||||||
$a->strings['If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.'] = 'Si vous saisissez votre adresse de compte précédente d\'un réseau basé sur ActivityPub ou GNU Social/Statusnet (au format utilisateur@domaine.tld), vos contacts seront ajoutés autoamtiquement. Le champ sera vidé quand l\'opération sera terminé.';
|
|
||||||
$a->strings['Email/Mailbox Setup'] = 'Réglages de courriel/boîte à lettre';
|
$a->strings['Email/Mailbox Setup'] = 'Réglages de courriel/boîte à lettre';
|
||||||
$a->strings['If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox.'] = 'Si vous souhaitez communiquer avec vos contacts "courriel" (facultatif), merci de nous indiquer comment vous connecter à votre boîte.';
|
$a->strings['If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox.'] = 'Si vous souhaitez communiquer avec vos contacts "courriel" (facultatif), merci de nous indiquer comment vous connecter à votre boîte.';
|
||||||
$a->strings['Last successful email check:'] = 'Dernière vérification réussie des courriels :';
|
$a->strings['Last successful email check:'] = 'Dernière vérification réussie des courriels :';
|
||||||
|
@ -2671,6 +2665,12 @@ $a->strings['Send public posts to all email contacts:'] = 'Envoyer les publicati
|
||||||
$a->strings['Action after import:'] = 'Action après import :';
|
$a->strings['Action after import:'] = 'Action après import :';
|
||||||
$a->strings['Move to folder'] = 'Déplacer vers';
|
$a->strings['Move to folder'] = 'Déplacer vers';
|
||||||
$a->strings['Move to folder:'] = 'Déplacer vers :';
|
$a->strings['Move to folder:'] = 'Déplacer vers :';
|
||||||
|
$a->strings['Contact CSV file upload error'] = 'Erreur de téléversement du fichier de contact CSV';
|
||||||
|
$a->strings['Importing Contacts done'] = 'Import des contacts effectué';
|
||||||
|
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'Téléversez un fichier CSV contenant des identifiants de contacts dans la première colonne.';
|
||||||
|
$a->strings['Upload File'] = 'Téléverser le fichier';
|
||||||
|
$a->strings['Your legacy ActivityPub/GNU Social account'] = 'Votre ancient compte ActivityPub/GNU Social';
|
||||||
|
$a->strings['If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.'] = 'Si vous saisissez votre adresse de compte précédente d\'un réseau basé sur ActivityPub ou GNU Social/Statusnet (au format utilisateur@domaine.tld), vos contacts seront ajoutés autoamtiquement. Le champ sera vidé quand l\'opération sera terminé.';
|
||||||
$a->strings['Delegation successfully granted.'] = 'Délégation accordée avec succès.';
|
$a->strings['Delegation successfully granted.'] = 'Délégation accordée avec succès.';
|
||||||
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'Utilisateur parent introuvable, indisponible ou mot de passe incorrect.';
|
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'Utilisateur parent introuvable, indisponible ou mot de passe incorrect.';
|
||||||
$a->strings['Delegation successfully revoked.'] = 'Délégation retirée avec succès.';
|
$a->strings['Delegation successfully revoked.'] = 'Délégation retirée avec succès.';
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2208,8 +2208,6 @@ $a->strings['Normally the system shortens posts at the next line feed. If this o
|
||||||
$a->strings['Attach the link title'] = 'Cuir tiotal a’ cheangail ris';
|
$a->strings['Attach the link title'] = 'Cuir tiotal a’ cheangail ris';
|
||||||
$a->strings['When activated, the title of the attached link will be added as a title on posts to Diaspora. This is mostly helpful with "remote-self" contacts that share feed content.'] = 'Nuair a bhios seo an gnìomh, thèid tiotal a’ cheangail a chur ris mar tiotal air postaichean gu diaspora*. Tha seo as fheumaile dhan luchd-aithne “remote-self” a cho-roinneas susbaint inbhir.';
|
$a->strings['When activated, the title of the attached link will be added as a title on posts to Diaspora. This is mostly helpful with "remote-self" contacts that share feed content.'] = 'Nuair a bhios seo an gnìomh, thèid tiotal a’ cheangail a chur ris mar tiotal air postaichean gu diaspora*. Tha seo as fheumaile dhan luchd-aithne “remote-self” a cho-roinneas susbaint inbhir.';
|
||||||
$a->strings['When activated, added links at the end of the post react the same way as added links in the web interface.'] = 'Nuair a bhios seo an gnìomh, bidh an t-aon ghiùlan aig ceanglaichean a thèid a chur ri bonn puist ’s a tha aig ceanglaichean a thèid a chur ris san eadar-aghaidh-lìn.';
|
$a->strings['When activated, added links at the end of the post react the same way as added links in the web interface.'] = 'Nuair a bhios seo an gnìomh, bidh an t-aon ghiùlan aig ceanglaichean a thèid a chur ri bonn puist ’s a tha aig ceanglaichean a thèid a chur ris san eadar-aghaidh-lìn.';
|
||||||
$a->strings['Your legacy ActivityPub/GNU Social account'] = 'An cunntas ActivityPub/GNU Social dìleabach agad';
|
|
||||||
$a->strings['If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.'] = 'Ma chuireas tu ainm seann-chunntais ris o shiostam stèidhichte air ActivityPub no ainm do chunntais GNU Social/Statusnet an-seo (san fhòrmat cleachdaiche@àrainn.tld), thèid an luchd-aithne agad a chur ris gu fèin-obrachail. Thèid an raon fhalamhachadh nuair a bhios sin deiseil.';
|
|
||||||
$a->strings['Email/Mailbox Setup'] = 'Suidheachadh a’ phuist-d/a’ bhogsa-phuist';
|
$a->strings['Email/Mailbox Setup'] = 'Suidheachadh a’ phuist-d/a’ bhogsa-phuist';
|
||||||
$a->strings['If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox.'] = 'Ma tha thu airson an t-seirbheis seo a chleachdadh airson conaltradh le luchd-aithne air a’ post-d (gu roghainneil), sònraich an dòigh air a nì thu ceangal leis a’ bhogsa-phuist agad.';
|
$a->strings['If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox.'] = 'Ma tha thu airson an t-seirbheis seo a chleachdadh airson conaltradh le luchd-aithne air a’ post-d (gu roghainneil), sònraich an dòigh air a nì thu ceangal leis a’ bhogsa-phuist agad.';
|
||||||
$a->strings['Last successful email check:'] = 'An turas mu dheireadh a chaidh leinn sùil a thoirt air a’ phost-d:';
|
$a->strings['Last successful email check:'] = 'An turas mu dheireadh a chaidh leinn sùil a thoirt air a’ phost-d:';
|
||||||
|
@ -2223,6 +2221,8 @@ $a->strings['Send public posts to all email contacts:'] = 'Cuir postaichean pobl
|
||||||
$a->strings['Action after import:'] = 'Gnìomh às dèid an ion-phortaidh:';
|
$a->strings['Action after import:'] = 'Gnìomh às dèid an ion-phortaidh:';
|
||||||
$a->strings['Move to folder'] = 'Gluais gu pasgan';
|
$a->strings['Move to folder'] = 'Gluais gu pasgan';
|
||||||
$a->strings['Move to folder:'] = 'Gluais gu pasgan:';
|
$a->strings['Move to folder:'] = 'Gluais gu pasgan:';
|
||||||
|
$a->strings['Your legacy ActivityPub/GNU Social account'] = 'An cunntas ActivityPub/GNU Social dìleabach agad';
|
||||||
|
$a->strings['If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.'] = 'Ma chuireas tu ainm seann-chunntais ris o shiostam stèidhichte air ActivityPub no ainm do chunntais GNU Social/Statusnet an-seo (san fhòrmat cleachdaiche@àrainn.tld), thèid an luchd-aithne agad a chur ris gu fèin-obrachail. Thèid an raon fhalamhachadh nuair a bhios sin deiseil.';
|
||||||
$a->strings['Delegation successfully granted.'] = 'Chaidh neach-ionaid a dhèanamh dheth.';
|
$a->strings['Delegation successfully granted.'] = 'Chaidh neach-ionaid a dhèanamh dheth.';
|
||||||
$a->strings['Delegation successfully revoked.'] = 'Chaidh ceadan neach-ionaid a thoirt air falbh.';
|
$a->strings['Delegation successfully revoked.'] = 'Chaidh ceadan neach-ionaid a thoirt air falbh.';
|
||||||
$a->strings['Delegated administrators can view but not change delegation permissions.'] = 'Chì rianairean a tha ’nan luchd-ionaid na ceadan ach chan urrainn dhaibh an atharrachadh.';
|
$a->strings['Delegated administrators can view but not change delegation permissions.'] = 'Chì rianairean a tha ’nan luchd-ionaid na ceadan ach chan urrainn dhaibh an atharrachadh.';
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1618,6 +1618,7 @@ $a->strings['Social Networks'] = 'Közösségi hálózatok';
|
||||||
$a->strings['Manage Accounts'] = 'Fiókok kezelése';
|
$a->strings['Manage Accounts'] = 'Fiókok kezelése';
|
||||||
$a->strings['Connected apps'] = 'Kapcsolt alkalmazások';
|
$a->strings['Connected apps'] = 'Kapcsolt alkalmazások';
|
||||||
$a->strings['Remote servers'] = 'Távoli kiszolgálók';
|
$a->strings['Remote servers'] = 'Távoli kiszolgálók';
|
||||||
|
$a->strings['Import Contacts'] = 'Partnerek importálása';
|
||||||
$a->strings['Export personal data'] = 'Személyes adatok exportálása';
|
$a->strings['Export personal data'] = 'Személyes adatok exportálása';
|
||||||
$a->strings['Remove account'] = 'Fiók eltávolítása';
|
$a->strings['Remove account'] = 'Fiók eltávolítása';
|
||||||
$a->strings['This page is missing a url parameter.'] = 'Erről az oldalról hiányzik egy URL paraméter.';
|
$a->strings['This page is missing a url parameter.'] = 'Erről az oldalról hiányzik egy URL paraméter.';
|
||||||
|
@ -2446,8 +2447,6 @@ $a->strings['Wrong Password.'] = 'Hibás jelszó.';
|
||||||
$a->strings['Invalid email.'] = 'Érvénytelen e-mail-cím.';
|
$a->strings['Invalid email.'] = 'Érvénytelen e-mail-cím.';
|
||||||
$a->strings['Cannot change to that email.'] = 'Nem lehet megváltoztatni arra az e-mail-címre.';
|
$a->strings['Cannot change to that email.'] = 'Nem lehet megváltoztatni arra az e-mail-címre.';
|
||||||
$a->strings['Settings were not updated.'] = 'A beállítások nem lettek frissítve.';
|
$a->strings['Settings were not updated.'] = 'A beállítások nem lettek frissítve.';
|
||||||
$a->strings['Contact CSV file upload error'] = 'Partner CSV-fájl feltöltési hiba';
|
|
||||||
$a->strings['Importing Contacts done'] = 'A partnerek importálása kész';
|
|
||||||
$a->strings['Relocate message has been send to your contacts'] = 'Az áthelyezési üzenet el lett küldve a partnereknek';
|
$a->strings['Relocate message has been send to your contacts'] = 'Az áthelyezési üzenet el lett küldve a partnereknek';
|
||||||
$a->strings['Unable to find your profile. Please contact your admin.'] = 'Nem található a profilja. Vegye fel a kapcsolatot a rendszergazdával.';
|
$a->strings['Unable to find your profile. Please contact your admin.'] = 'Nem található a profilja. Vegye fel a kapcsolatot a rendszergazdával.';
|
||||||
$a->strings['Account for a service that automatically shares content based on user defined channels.'] = 'Fiók egy olyan szolgáltatáshoz, amely automatikusan megosztja a tartalmat a felhasználó által meghatározott csatornák alapján.';
|
$a->strings['Account for a service that automatically shares content based on user defined channels.'] = 'Fiók egy olyan szolgáltatáshoz, amely automatikusan megosztja a tartalmat a felhasználó által meghatározott csatornák alapján.';
|
||||||
|
@ -2543,9 +2542,6 @@ $a->strings['Show notifications of ignored contacts'] = 'Mellőzött partnerek
|
||||||
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = 'Nem látja a mellőzött partnerektől érkező bejegyzéseket. Viszont továbbra is látja a hozzászólásaikat. Ez a beállítás azt vezérli, hogy továbbra is szeretne-e olyan normál értesítéseket kapni vagy sem, amelyeket mellőzött partnerek okoznak.';
|
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = 'Nem látja a mellőzött partnerektől érkező bejegyzéseket. Viszont továbbra is látja a hozzászólásaikat. Ez a beállítás azt vezérli, hogy továbbra is szeretne-e olyan normál értesítéseket kapni vagy sem, amelyeket mellőzött partnerek okoznak.';
|
||||||
$a->strings['Advanced Account/Page Type Settings'] = 'Speciális fióktípus vagy oldaltípus beállítások';
|
$a->strings['Advanced Account/Page Type Settings'] = 'Speciális fióktípus vagy oldaltípus beállítások';
|
||||||
$a->strings['Change the behaviour of this account for special situations'] = 'A fiók viselkedésének megváltoztatása bizonyos helyzetekre.';
|
$a->strings['Change the behaviour of this account for special situations'] = 'A fiók viselkedésének megváltoztatása bizonyos helyzetekre.';
|
||||||
$a->strings['Import Contacts'] = 'Partnerek importálása';
|
|
||||||
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'Töltsön fel egy olyan CSV-fájlt, amely a követett fiókok kezelőjét tartalmazza az első oszlopban, ahogy a régi fiókból exportálta.';
|
|
||||||
$a->strings['Upload File'] = 'Fájl feltöltése';
|
|
||||||
$a->strings['Relocate'] = 'Áthelyezés';
|
$a->strings['Relocate'] = 'Áthelyezés';
|
||||||
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Ha áthelyezte ezt a profilt egy másik kiszolgálóról, és néhány partnere nem kapta meg a frissítéseket, akkor próbálja meg megnyomni ezt a gombot.';
|
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Ha áthelyezte ezt a profilt egy másik kiszolgálóról, és néhány partnere nem kapta meg a frissítéseket, akkor próbálja meg megnyomni ezt a gombot.';
|
||||||
$a->strings['Resend relocate message to contacts'] = 'Áthelyezési üzenet küldése a partnereknek';
|
$a->strings['Resend relocate message to contacts'] = 'Áthelyezési üzenet küldése a partnereknek';
|
||||||
|
@ -2613,8 +2609,6 @@ $a->strings['API: Automatically links at the end of the post as attached posts']
|
||||||
$a->strings['When activated, added links at the end of the post react the same way as added links in the web interface.'] = 'Ha aktiválva van, akkor a bejegyzés végéhez hozzáadott hivatkozások ugyanúgy reagálnak, mint a webes felületen hozzáadott hivatkozások.';
|
$a->strings['When activated, added links at the end of the post react the same way as added links in the web interface.'] = 'Ha aktiválva van, akkor a bejegyzés végéhez hozzáadott hivatkozások ugyanúgy reagálnak, mint a webes felületen hozzáadott hivatkozások.';
|
||||||
$a->strings['Article Mode'] = 'Cikk mód';
|
$a->strings['Article Mode'] = 'Cikk mód';
|
||||||
$a->strings['Controls how posts with titles are transmitted. Mastodon and its forks don\'t display the content of these posts if the post is created in the correct (default) way.'] = 'Azt vezérli, hogy a címekkel rendelkező bejegyzések hogyan kerülnek továbbításra. A Mastodon és elágaztatásai nem jelenítik meg ezeknek a bejegyzéseknek a tartalmát, ha a bejegyzést a megfelelő (alapértelmezett) módon hozták létre.';
|
$a->strings['Controls how posts with titles are transmitted. Mastodon and its forks don\'t display the content of these posts if the post is created in the correct (default) way.'] = 'Azt vezérli, hogy a címekkel rendelkező bejegyzések hogyan kerülnek továbbításra. A Mastodon és elágaztatásai nem jelenítik meg ezeknek a bejegyzéseknek a tartalmát, ha a bejegyzést a megfelelő (alapértelmezett) módon hozták létre.';
|
||||||
$a->strings['Your legacy ActivityPub/GNU Social account'] = 'Az örökölt ActivityPub/GNU Social fiókja';
|
|
||||||
$a->strings['If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.'] = 'Ha megadja itt a régi, egy ActivityPub alapú rendszerből származó fiókja nevét, illetve a GNU Social vagy Statusnet fiókja nevét (felhasználó@tartomány.tld formátumban), akkor a partnerei automatikusan hozzá lesznek adva. A mező ki lesz ürítve, ha elkészült.';
|
|
||||||
$a->strings['Email/Mailbox Setup'] = 'E-mail vagy postafiók-beállítások';
|
$a->strings['Email/Mailbox Setup'] = 'E-mail vagy postafiók-beállítások';
|
||||||
$a->strings['If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox.'] = 'Ha e-mailes partnerekkel szeretne kommunikálni ezen szolgáltatás használatával (opcionális), akkor adja meg, hogy hogyan kell kapcsolódni a postafiókjához.';
|
$a->strings['If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox.'] = 'Ha e-mailes partnerekkel szeretne kommunikálni ezen szolgáltatás használatával (opcionális), akkor adja meg, hogy hogyan kell kapcsolódni a postafiókjához.';
|
||||||
$a->strings['Last successful email check:'] = 'Legutóbbi sikeres e-mail-ellenőrzés:';
|
$a->strings['Last successful email check:'] = 'Legutóbbi sikeres e-mail-ellenőrzés:';
|
||||||
|
@ -2628,6 +2622,12 @@ $a->strings['Send public posts to all email contacts:'] = 'Nyilvános bejegyzés
|
||||||
$a->strings['Action after import:'] = 'Importálás utáni művelet:';
|
$a->strings['Action after import:'] = 'Importálás utáni művelet:';
|
||||||
$a->strings['Move to folder'] = 'Áthelyezés mappába';
|
$a->strings['Move to folder'] = 'Áthelyezés mappába';
|
||||||
$a->strings['Move to folder:'] = 'Áthelyezés mappába:';
|
$a->strings['Move to folder:'] = 'Áthelyezés mappába:';
|
||||||
|
$a->strings['Contact CSV file upload error'] = 'Partner CSV-fájl feltöltési hiba';
|
||||||
|
$a->strings['Importing Contacts done'] = 'A partnerek importálása kész';
|
||||||
|
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'Töltsön fel egy olyan CSV-fájlt, amely a követett fiókok kezelőjét tartalmazza az első oszlopban, ahogy a régi fiókból exportálta.';
|
||||||
|
$a->strings['Upload File'] = 'Fájl feltöltése';
|
||||||
|
$a->strings['Your legacy ActivityPub/GNU Social account'] = 'Az örökölt ActivityPub/GNU Social fiókja';
|
||||||
|
$a->strings['If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.'] = 'Ha megadja itt a régi, egy ActivityPub alapú rendszerből származó fiókja nevét, illetve a GNU Social vagy Statusnet fiókja nevét (felhasználó@tartomány.tld formátumban), akkor a partnerei automatikusan hozzá lesznek adva. A mező ki lesz ürítve, ha elkészült.';
|
||||||
$a->strings['Delegation successfully granted.'] = 'A meghatalmazás sikeresen megadva.';
|
$a->strings['Delegation successfully granted.'] = 'A meghatalmazás sikeresen megadva.';
|
||||||
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'A fölérendelt felhasználó nem található, nem érhető el vagy a jelszó nem egyezik.';
|
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'A fölérendelt felhasználó nem található, nem érhető el vagy a jelszó nem egyezik.';
|
||||||
$a->strings['Delegation successfully revoked.'] = 'A meghatalmazás sikeresen visszavonva.';
|
$a->strings['Delegation successfully revoked.'] = 'A meghatalmazás sikeresen visszavonva.';
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1121,6 +1121,7 @@ $a->strings['Display'] = 'Visualizzazione';
|
||||||
$a->strings['Social Networks'] = 'Social Networks';
|
$a->strings['Social Networks'] = 'Social Networks';
|
||||||
$a->strings['Manage Accounts'] = 'Gestisci Account';
|
$a->strings['Manage Accounts'] = 'Gestisci Account';
|
||||||
$a->strings['Connected apps'] = 'Applicazioni collegate';
|
$a->strings['Connected apps'] = 'Applicazioni collegate';
|
||||||
|
$a->strings['Import Contacts'] = 'Importa Contatti';
|
||||||
$a->strings['Export personal data'] = 'Esporta dati personali';
|
$a->strings['Export personal data'] = 'Esporta dati personali';
|
||||||
$a->strings['Remove account'] = 'Rimuovi account';
|
$a->strings['Remove account'] = 'Rimuovi account';
|
||||||
$a->strings['This page is missing a url parameter.'] = 'A questa pagina manca il parametro url.';
|
$a->strings['This page is missing a url parameter.'] = 'A questa pagina manca il parametro url.';
|
||||||
|
@ -1785,8 +1786,6 @@ $a->strings['Wrong Password.'] = 'Password Sbagliata.';
|
||||||
$a->strings['Invalid email.'] = 'Email non valida.';
|
$a->strings['Invalid email.'] = 'Email non valida.';
|
||||||
$a->strings['Cannot change to that email.'] = 'Non puoi usare quella email.';
|
$a->strings['Cannot change to that email.'] = 'Non puoi usare quella email.';
|
||||||
$a->strings['Settings were not updated.'] = 'Le impostazioni non sono state aggiornate.';
|
$a->strings['Settings were not updated.'] = 'Le impostazioni non sono state aggiornate.';
|
||||||
$a->strings['Contact CSV file upload error'] = 'Errore nel caricamento del file CSV dei contatti';
|
|
||||||
$a->strings['Importing Contacts done'] = 'Importazione dei Contatti riuscita';
|
|
||||||
$a->strings['Relocate message has been send to your contacts'] = 'Il messaggio di trasloco è stato inviato ai tuoi contatti';
|
$a->strings['Relocate message has been send to your contacts'] = 'Il messaggio di trasloco è stato inviato ai tuoi contatti';
|
||||||
$a->strings['Unable to find your profile. Please contact your admin.'] = 'Impossibile trovare il tuo profilo. Contatta il tuo amministratore.';
|
$a->strings['Unable to find your profile. Please contact your admin.'] = 'Impossibile trovare il tuo profilo. Contatta il tuo amministratore.';
|
||||||
$a->strings['Personal Page Subtypes'] = 'Sottotipi di Pagine Personali';
|
$a->strings['Personal Page Subtypes'] = 'Sottotipi di Pagine Personali';
|
||||||
|
@ -1868,9 +1867,6 @@ $a->strings['Show notifications of ignored contacts'] = 'Mostra notifiche dai co
|
||||||
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = 'Non vedi i messaggi da contatti ignorati. Ma puoi ancora vedere i loro commenti. Questa impostazione controlla se vuoi o meno continuare a ricevere notifiche regolari che sono causate dai contatti ignorati.';
|
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = 'Non vedi i messaggi da contatti ignorati. Ma puoi ancora vedere i loro commenti. Questa impostazione controlla se vuoi o meno continuare a ricevere notifiche regolari che sono causate dai contatti ignorati.';
|
||||||
$a->strings['Advanced Account/Page Type Settings'] = 'Impostazioni avanzate Account/Tipo di pagina';
|
$a->strings['Advanced Account/Page Type Settings'] = 'Impostazioni avanzate Account/Tipo di pagina';
|
||||||
$a->strings['Change the behaviour of this account for special situations'] = 'Modifica il comportamento di questo account in situazioni speciali';
|
$a->strings['Change the behaviour of this account for special situations'] = 'Modifica il comportamento di questo account in situazioni speciali';
|
||||||
$a->strings['Import Contacts'] = 'Importa Contatti';
|
|
||||||
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'Carica un file CSV che contiene gli indirizzi dei tuoi account seguiti nella prima colonna che hai esportato dal vecchio account.';
|
|
||||||
$a->strings['Upload File'] = 'Carica File';
|
|
||||||
$a->strings['Relocate'] = 'Trasloca';
|
$a->strings['Relocate'] = 'Trasloca';
|
||||||
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Se hai spostato questo profilo da un\'altro server, e alcuni dei tuoi contatti non ricevono i tuoi aggiornamenti, prova a premere questo bottone.';
|
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Se hai spostato questo profilo da un\'altro server, e alcuni dei tuoi contatti non ricevono i tuoi aggiornamenti, prova a premere questo bottone.';
|
||||||
$a->strings['Resend relocate message to contacts'] = 'Invia nuovamente il messaggio di trasloco ai contatti';
|
$a->strings['Resend relocate message to contacts'] = 'Invia nuovamente il messaggio di trasloco ai contatti';
|
||||||
|
@ -1889,8 +1885,6 @@ $a->strings['Enable simple text shortening'] = 'Abilita accorciamento semplice d
|
||||||
$a->strings['Normally the system shortens posts at the next line feed. If this option is enabled then the system will shorten the text at the maximum character limit.'] = 'Normalmente il sistema accorcia i messaggi alla successiva interruzione di linea. Se questa opzione è abilitata il sistema accorcerà il testo al raggiungimento del limite massimo di caratteri.';
|
$a->strings['Normally the system shortens posts at the next line feed. If this option is enabled then the system will shorten the text at the maximum character limit.'] = 'Normalmente il sistema accorcia i messaggi alla successiva interruzione di linea. Se questa opzione è abilitata il sistema accorcerà il testo al raggiungimento del limite massimo di caratteri.';
|
||||||
$a->strings['Attach the link title'] = 'Allega il titolo del collegamento';
|
$a->strings['Attach the link title'] = 'Allega il titolo del collegamento';
|
||||||
$a->strings['When activated, the title of the attached link will be added as a title on posts to Diaspora. This is mostly helpful with "remote-self" contacts that share feed content.'] = 'Quando attivato, il titolo del collegamento allegato sarà aggiunto come titolo dei messaggi su Diaspora. Questo è più che altro utile con i contatti "remoti di sè stessi" che condividono il contenuto del flusso.';
|
$a->strings['When activated, the title of the attached link will be added as a title on posts to Diaspora. This is mostly helpful with "remote-self" contacts that share feed content.'] = 'Quando attivato, il titolo del collegamento allegato sarà aggiunto come titolo dei messaggi su Diaspora. Questo è più che altro utile con i contatti "remoti di sè stessi" che condividono il contenuto del flusso.';
|
||||||
$a->strings['Your legacy ActivityPub/GNU Social account'] = 'Il tuo vecchio account ActivityPub/GNU Social ';
|
|
||||||
$a->strings['If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.'] = 'Se inserisci il nome del tuo vecchio account su un sistema basato su ActivityPub o del tuo vecchio account GNU Social/Statusnet (nel formato utente@dominio.tld), i tuoi contatti verranno importati automaticamente. Il campo verrà svuotato una volta terminata l\'operazione.';
|
|
||||||
$a->strings['Email/Mailbox Setup'] = 'Impostazioni email';
|
$a->strings['Email/Mailbox Setup'] = 'Impostazioni email';
|
||||||
$a->strings['If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox.'] = 'Se vuoi comunicare con i contatti email usando questo servizio, specifica come collegarti alla tua casella di posta. (opzionale)';
|
$a->strings['If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox.'] = 'Se vuoi comunicare con i contatti email usando questo servizio, specifica come collegarti alla tua casella di posta. (opzionale)';
|
||||||
$a->strings['Last successful email check:'] = 'Ultimo controllo email eseguito con successo:';
|
$a->strings['Last successful email check:'] = 'Ultimo controllo email eseguito con successo:';
|
||||||
|
@ -1904,6 +1898,12 @@ $a->strings['Send public posts to all email contacts:'] = 'Invia i messaggi pubb
|
||||||
$a->strings['Action after import:'] = 'Azione dopo importazione:';
|
$a->strings['Action after import:'] = 'Azione dopo importazione:';
|
||||||
$a->strings['Move to folder'] = 'Sposta nella cartella';
|
$a->strings['Move to folder'] = 'Sposta nella cartella';
|
||||||
$a->strings['Move to folder:'] = 'Sposta nella cartella:';
|
$a->strings['Move to folder:'] = 'Sposta nella cartella:';
|
||||||
|
$a->strings['Contact CSV file upload error'] = 'Errore nel caricamento del file CSV dei contatti';
|
||||||
|
$a->strings['Importing Contacts done'] = 'Importazione dei Contatti riuscita';
|
||||||
|
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'Carica un file CSV che contiene gli indirizzi dei tuoi account seguiti nella prima colonna che hai esportato dal vecchio account.';
|
||||||
|
$a->strings['Upload File'] = 'Carica File';
|
||||||
|
$a->strings['Your legacy ActivityPub/GNU Social account'] = 'Il tuo vecchio account ActivityPub/GNU Social ';
|
||||||
|
$a->strings['If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.'] = 'Se inserisci il nome del tuo vecchio account su un sistema basato su ActivityPub o del tuo vecchio account GNU Social/Statusnet (nel formato utente@dominio.tld), i tuoi contatti verranno importati automaticamente. Il campo verrà svuotato una volta terminata l\'operazione.';
|
||||||
$a->strings['Delegation successfully granted.'] = 'Delega concessa con successo.';
|
$a->strings['Delegation successfully granted.'] = 'Delega concessa con successo.';
|
||||||
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'Utente principale non trovato, non disponibile o la password non corrisponde.';
|
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'Utente principale non trovato, non disponibile o la password non corrisponde.';
|
||||||
$a->strings['Delegation successfully revoked.'] = 'Delega revocata con successo.';
|
$a->strings['Delegation successfully revoked.'] = 'Delega revocata con successo.';
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -969,6 +969,7 @@ $a->strings['Display'] = '表示';
|
||||||
$a->strings['Social Networks'] = 'ソーシャルネットワーク';
|
$a->strings['Social Networks'] = 'ソーシャルネットワーク';
|
||||||
$a->strings['Manage Accounts'] = 'アカウントの管理';
|
$a->strings['Manage Accounts'] = 'アカウントの管理';
|
||||||
$a->strings['Connected apps'] = '接続されたアプリ';
|
$a->strings['Connected apps'] = '接続されたアプリ';
|
||||||
|
$a->strings['Import Contacts'] = 'コンタクトをインポートする';
|
||||||
$a->strings['Export personal data'] = '個人データのエクスポート';
|
$a->strings['Export personal data'] = '個人データのエクスポート';
|
||||||
$a->strings['Remove account'] = 'アカウントを削除';
|
$a->strings['Remove account'] = 'アカウントを削除';
|
||||||
$a->strings['This page is missing a url parameter.'] = 'このページにはurlパラメーターがありません。';
|
$a->strings['This page is missing a url parameter.'] = 'このページにはurlパラメーターがありません。';
|
||||||
|
@ -1482,8 +1483,6 @@ $a->strings['Wrong Password.'] = 'パスワードが間違っています。';
|
||||||
$a->strings['Invalid email.'] = '無効なメール。';
|
$a->strings['Invalid email.'] = '無効なメール。';
|
||||||
$a->strings['Cannot change to that email.'] = 'そのメールに変更できません。';
|
$a->strings['Cannot change to that email.'] = 'そのメールに変更できません。';
|
||||||
$a->strings['Settings were not updated.'] = '設定が更新されませんでした。';
|
$a->strings['Settings were not updated.'] = '設定が更新されませんでした。';
|
||||||
$a->strings['Contact CSV file upload error'] = 'アップロードエラー:コンタクトCSVファイル';
|
|
||||||
$a->strings['Importing Contacts done'] = 'コンタクトのインポートが完了しました';
|
|
||||||
$a->strings['Relocate message has been send to your contacts'] = '再配置メッセージがコンタクトに送信されました';
|
$a->strings['Relocate message has been send to your contacts'] = '再配置メッセージがコンタクトに送信されました';
|
||||||
$a->strings['Unable to find your profile. Please contact your admin.'] = 'プロフィールが見つかりません。管理者に連絡してください。';
|
$a->strings['Unable to find your profile. Please contact your admin.'] = 'プロフィールが見つかりません。管理者に連絡してください。';
|
||||||
$a->strings['Personal Page Subtypes'] = '個人ページのサブタイプ';
|
$a->strings['Personal Page Subtypes'] = '個人ページのサブタイプ';
|
||||||
|
@ -1562,9 +1561,6 @@ $a->strings['Show notifications of ignored contacts'] = '無視されたコン
|
||||||
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = '無視されたコンタクトからの投稿は表示されません。しかし、相手のコメントは表示されます。この設定では、無視されたコンタクトからの通知を定期的に受け取るかどうかを設定します。';
|
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = '無視されたコンタクトからの投稿は表示されません。しかし、相手のコメントは表示されます。この設定では、無視されたコンタクトからの通知を定期的に受け取るかどうかを設定します。';
|
||||||
$a->strings['Advanced Account/Page Type Settings'] = 'アカウント/ページタイプの詳細設定';
|
$a->strings['Advanced Account/Page Type Settings'] = 'アカウント/ページタイプの詳細設定';
|
||||||
$a->strings['Change the behaviour of this account for special situations'] = '特別な状況でこのアカウントの動作を変更する';
|
$a->strings['Change the behaviour of this account for special situations'] = '特別な状況でこのアカウントの動作を変更する';
|
||||||
$a->strings['Import Contacts'] = 'コンタクトをインポートする';
|
|
||||||
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = '古いアカウントからエクスポートしたCSVファイルをアップロードします。これは最初の列に、フォローしているアカウントのハンドルを含みます。';
|
|
||||||
$a->strings['Upload File'] = 'ファイルをアップロード';
|
|
||||||
$a->strings['Relocate'] = '再配置';
|
$a->strings['Relocate'] = '再配置';
|
||||||
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'このプロフィールを別のサーバーから移動し、コンタクトの一部が更新を受信しない場合は、このボタンを押してみてください。';
|
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'このプロフィールを別のサーバーから移動し、コンタクトの一部が更新を受信しない場合は、このボタンを押してみてください。';
|
||||||
$a->strings['Resend relocate message to contacts'] = '再配置メッセージをコンタクトに再送信する';
|
$a->strings['Resend relocate message to contacts'] = '再配置メッセージをコンタクトに再送信する';
|
||||||
|
@ -1592,6 +1588,10 @@ $a->strings['Send public posts to all email contacts:'] = 'すべてのメール
|
||||||
$a->strings['Action after import:'] = 'インポート後のアクション:';
|
$a->strings['Action after import:'] = 'インポート後のアクション:';
|
||||||
$a->strings['Move to folder'] = 'フォルダへ移動';
|
$a->strings['Move to folder'] = 'フォルダへ移動';
|
||||||
$a->strings['Move to folder:'] = 'フォルダへ移動:';
|
$a->strings['Move to folder:'] = 'フォルダへ移動:';
|
||||||
|
$a->strings['Contact CSV file upload error'] = 'アップロードエラー:コンタクトCSVファイル';
|
||||||
|
$a->strings['Importing Contacts done'] = 'コンタクトのインポートが完了しました';
|
||||||
|
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = '古いアカウントからエクスポートしたCSVファイルをアップロードします。これは最初の列に、フォローしているアカウントのハンドルを含みます。';
|
||||||
|
$a->strings['Upload File'] = 'ファイルをアップロード';
|
||||||
$a->strings['Delegation successfully granted.'] = '委任が正常に許可されました。';
|
$a->strings['Delegation successfully granted.'] = '委任が正常に許可されました。';
|
||||||
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = '親ユーザーが見つからないか、利用できないか、パスワードが一致しません。';
|
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = '親ユーザーが見つからないか、利用できないか、パスワードが一致しません。';
|
||||||
$a->strings['Delegation successfully revoked.'] = '委任が正常に取り消されました。';
|
$a->strings['Delegation successfully revoked.'] = '委任が正常に取り消されました。';
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -966,6 +966,7 @@ $a->strings['Display'] = 'Weergave';
|
||||||
$a->strings['Social Networks'] = 'Sociale netwerken';
|
$a->strings['Social Networks'] = 'Sociale netwerken';
|
||||||
$a->strings['Manage Accounts'] = 'Beheer Gebruikers';
|
$a->strings['Manage Accounts'] = 'Beheer Gebruikers';
|
||||||
$a->strings['Connected apps'] = 'Verbonden applicaties';
|
$a->strings['Connected apps'] = 'Verbonden applicaties';
|
||||||
|
$a->strings['Import Contacts'] = 'Importeer contacten';
|
||||||
$a->strings['Export personal data'] = 'Persoonlijke gegevens exporteren';
|
$a->strings['Export personal data'] = 'Persoonlijke gegevens exporteren';
|
||||||
$a->strings['Remove account'] = 'Account verwijderen';
|
$a->strings['Remove account'] = 'Account verwijderen';
|
||||||
$a->strings['This page is missing a url parameter.'] = 'Deze pagina mist een url-parameter.';
|
$a->strings['This page is missing a url parameter.'] = 'Deze pagina mist een url-parameter.';
|
||||||
|
@ -1462,7 +1463,6 @@ $a->strings['Wrong Password.'] = 'Verkeerd wachtwoord.';
|
||||||
$a->strings['Invalid email.'] = 'Ongeldig email adres.';
|
$a->strings['Invalid email.'] = 'Ongeldig email adres.';
|
||||||
$a->strings['Cannot change to that email.'] = 'Kan niet naar dat email adres veranderen.';
|
$a->strings['Cannot change to that email.'] = 'Kan niet naar dat email adres veranderen.';
|
||||||
$a->strings['Settings were not updated.'] = 'Wijziging instellingen is niet opgeslagen.';
|
$a->strings['Settings were not updated.'] = 'Wijziging instellingen is niet opgeslagen.';
|
||||||
$a->strings['Importing Contacts done'] = 'Importeren Contacten voltooid';
|
|
||||||
$a->strings['Relocate message has been send to your contacts'] = 'Verhuis boodschap is verzonden naar je contacten';
|
$a->strings['Relocate message has been send to your contacts'] = 'Verhuis boodschap is verzonden naar je contacten';
|
||||||
$a->strings['Unable to find your profile. Please contact your admin.'] = 'Kan je profiel niet vinden. Contacteer alsjeblieft je beheerder.';
|
$a->strings['Unable to find your profile. Please contact your admin.'] = 'Kan je profiel niet vinden. Contacteer alsjeblieft je beheerder.';
|
||||||
$a->strings['Personal Page Subtypes'] = 'Persoonlijke Pagina Subtypes';
|
$a->strings['Personal Page Subtypes'] = 'Persoonlijke Pagina Subtypes';
|
||||||
|
@ -1539,9 +1539,6 @@ $a->strings['Show detailled notifications'] = 'Toon gedetailleerde notificaties'
|
||||||
$a->strings['Per default, notifications are condensed to a single notification per item. When enabled every notification is displayed.'] = 'Standaard worden notificaties samengevoegd in een enkele notificatie per item. Als je deze parameter activeert wordt elke notificatie getoond.';
|
$a->strings['Per default, notifications are condensed to a single notification per item. When enabled every notification is displayed.'] = 'Standaard worden notificaties samengevoegd in een enkele notificatie per item. Als je deze parameter activeert wordt elke notificatie getoond.';
|
||||||
$a->strings['Advanced Account/Page Type Settings'] = 'Geavanceerde Account/Pagina Type Instellingen';
|
$a->strings['Advanced Account/Page Type Settings'] = 'Geavanceerde Account/Pagina Type Instellingen';
|
||||||
$a->strings['Change the behaviour of this account for special situations'] = 'Pas het gedrag van dit account aan voor speciale situaties';
|
$a->strings['Change the behaviour of this account for special situations'] = 'Pas het gedrag van dit account aan voor speciale situaties';
|
||||||
$a->strings['Import Contacts'] = 'Importeer contacten';
|
|
||||||
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'Upload een CSV-bestand met de handle van uw gevolgde gebruikers in de eerste kolom die u uit de oude gebruiker hebt geëxporteerd.';
|
|
||||||
$a->strings['Upload File'] = 'Upload bestand';
|
|
||||||
$a->strings['Relocate'] = 'Verhuis';
|
$a->strings['Relocate'] = 'Verhuis';
|
||||||
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Als je je profiel van een andere server hebt verhuisd, en er zijn contacten die geen updates van je ontvangen, probeer dan eens deze knop.';
|
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Als je je profiel van een andere server hebt verhuisd, en er zijn contacten die geen updates van je ontvangen, probeer dan eens deze knop.';
|
||||||
$a->strings['Resend relocate message to contacts'] = 'Stuur verhuis boodschap naar contacten';
|
$a->strings['Resend relocate message to contacts'] = 'Stuur verhuis boodschap naar contacten';
|
||||||
|
@ -1569,6 +1566,9 @@ $a->strings['Send public posts to all email contacts:'] = 'Openbare posts naar a
|
||||||
$a->strings['Action after import:'] = 'Actie na importeren:';
|
$a->strings['Action after import:'] = 'Actie na importeren:';
|
||||||
$a->strings['Move to folder'] = 'Naar map verplaatsen';
|
$a->strings['Move to folder'] = 'Naar map verplaatsen';
|
||||||
$a->strings['Move to folder:'] = 'Verplaatsen naar map:';
|
$a->strings['Move to folder:'] = 'Verplaatsen naar map:';
|
||||||
|
$a->strings['Importing Contacts done'] = 'Importeren Contacten voltooid';
|
||||||
|
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'Upload een CSV-bestand met de handle van uw gevolgde gebruikers in de eerste kolom die u uit de oude gebruiker hebt geëxporteerd.';
|
||||||
|
$a->strings['Upload File'] = 'Upload bestand';
|
||||||
$a->strings['Delegation successfully granted.'] = 'Delegatie met succes verleend.';
|
$a->strings['Delegation successfully granted.'] = 'Delegatie met succes verleend.';
|
||||||
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'Brongebruiker niet gevonden, niet beschikbaar of wachtwoord komt niet overeen.';
|
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'Brongebruiker niet gevonden, niet beschikbaar of wachtwoord komt niet overeen.';
|
||||||
$a->strings['Delegation successfully revoked.'] = 'Delegatie is ingetrokken.';
|
$a->strings['Delegation successfully revoked.'] = 'Delegatie is ingetrokken.';
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1209,6 +1209,7 @@ $a->strings['Display'] = 'Wygląd';
|
||||||
$a->strings['Social Networks'] = 'Portale społecznościowe';
|
$a->strings['Social Networks'] = 'Portale społecznościowe';
|
||||||
$a->strings['Manage Accounts'] = 'Zarządzanie kontami';
|
$a->strings['Manage Accounts'] = 'Zarządzanie kontami';
|
||||||
$a->strings['Connected apps'] = 'Powiązane aplikacje';
|
$a->strings['Connected apps'] = 'Powiązane aplikacje';
|
||||||
|
$a->strings['Import Contacts'] = 'Import kontaktów';
|
||||||
$a->strings['Export personal data'] = 'Eksportuj dane osobiste';
|
$a->strings['Export personal data'] = 'Eksportuj dane osobiste';
|
||||||
$a->strings['Remove account'] = 'Usuń konto';
|
$a->strings['Remove account'] = 'Usuń konto';
|
||||||
$a->strings['This page is missing a url parameter.'] = 'Na tej stronie brakuje parametru url.';
|
$a->strings['This page is missing a url parameter.'] = 'Na tej stronie brakuje parametru url.';
|
||||||
|
@ -1917,8 +1918,6 @@ $a->strings['Wrong Password.'] = 'Nieprawidłowe hasło.';
|
||||||
$a->strings['Invalid email.'] = 'Niepoprawny e-mail.';
|
$a->strings['Invalid email.'] = 'Niepoprawny e-mail.';
|
||||||
$a->strings['Cannot change to that email.'] = 'Nie można zmienić tego e-maila.';
|
$a->strings['Cannot change to that email.'] = 'Nie można zmienić tego e-maila.';
|
||||||
$a->strings['Settings were not updated.'] = 'Ustawienia nie zostały zaktualizowane.';
|
$a->strings['Settings were not updated.'] = 'Ustawienia nie zostały zaktualizowane.';
|
||||||
$a->strings['Contact CSV file upload error'] = 'Kontakt z plikiem CSV błąd przekazywania plików';
|
|
||||||
$a->strings['Importing Contacts done'] = 'Importowanie kontaktów zakończone';
|
|
||||||
$a->strings['Relocate message has been send to your contacts'] = 'Przeniesienie wiadomości zostało wysłane do Twoich kontaktów';
|
$a->strings['Relocate message has been send to your contacts'] = 'Przeniesienie wiadomości zostało wysłane do Twoich kontaktów';
|
||||||
$a->strings['Unable to find your profile. Please contact your admin.'] = 'Nie można znaleźć Twojego profilu. Skontaktuj się z administratorem.';
|
$a->strings['Unable to find your profile. Please contact your admin.'] = 'Nie można znaleźć Twojego profilu. Skontaktuj się z administratorem.';
|
||||||
$a->strings['Personal Page Subtypes'] = 'Podtypy osobistych stron';
|
$a->strings['Personal Page Subtypes'] = 'Podtypy osobistych stron';
|
||||||
|
@ -2006,9 +2005,6 @@ $a->strings['Show notifications of ignored contacts'] = 'Pokaż powiadomienia o
|
||||||
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = 'Nie widzisz wpisów od ignorowanych kontaktów. Ale nadal widzisz ich komentarze. To ustawienie określa, czy chcesz nadal otrzymywać regularne powiadomienia, które są powodowane przez ignorowane kontakty, czy nie.';
|
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = 'Nie widzisz wpisów od ignorowanych kontaktów. Ale nadal widzisz ich komentarze. To ustawienie określa, czy chcesz nadal otrzymywać regularne powiadomienia, które są powodowane przez ignorowane kontakty, czy nie.';
|
||||||
$a->strings['Advanced Account/Page Type Settings'] = 'Zaawansowane ustawienia konta/rodzaju strony';
|
$a->strings['Advanced Account/Page Type Settings'] = 'Zaawansowane ustawienia konta/rodzaju strony';
|
||||||
$a->strings['Change the behaviour of this account for special situations'] = 'Zmień zachowanie tego konta w sytuacjach specjalnych';
|
$a->strings['Change the behaviour of this account for special situations'] = 'Zmień zachowanie tego konta w sytuacjach specjalnych';
|
||||||
$a->strings['Import Contacts'] = 'Import kontaktów';
|
|
||||||
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'Prześlij plik CSV zawierający obsługę obserwowanych kont w pierwszej kolumnie wyeksportowanej ze starego konta.';
|
|
||||||
$a->strings['Upload File'] = 'Prześlij plik';
|
|
||||||
$a->strings['Relocate'] = 'Przeniesienie';
|
$a->strings['Relocate'] = 'Przeniesienie';
|
||||||
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Jeśli ten profil został przeniesiony z innego serwera, a niektóre z Twoich kontaktów nie otrzymają aktualizacji, spróbuj nacisnąć ten przycisk.';
|
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Jeśli ten profil został przeniesiony z innego serwera, a niektóre z Twoich kontaktów nie otrzymają aktualizacji, spróbuj nacisnąć ten przycisk.';
|
||||||
$a->strings['Resend relocate message to contacts'] = 'Wyślij ponownie przenieść wiadomości do kontaktów';
|
$a->strings['Resend relocate message to contacts'] = 'Wyślij ponownie przenieść wiadomości do kontaktów';
|
||||||
|
@ -2032,8 +2028,6 @@ $a->strings['Enable simple text shortening'] = 'Włącz proste skracanie tekstu'
|
||||||
$a->strings['Normally the system shortens posts at the next line feed. If this option is enabled then the system will shorten the text at the maximum character limit.'] = 'Zwykle system skraca wpisy przy następnym wysunięciu wiersza. Jeśli ta opcja jest włączona, system skróci tekst do maksymalnego limitu znaków.';
|
$a->strings['Normally the system shortens posts at the next line feed. If this option is enabled then the system will shorten the text at the maximum character limit.'] = 'Zwykle system skraca wpisy przy następnym wysunięciu wiersza. Jeśli ta opcja jest włączona, system skróci tekst do maksymalnego limitu znaków.';
|
||||||
$a->strings['Attach the link title'] = 'Dołącz tytuł linku';
|
$a->strings['Attach the link title'] = 'Dołącz tytuł linku';
|
||||||
$a->strings['When activated, the title of the attached link will be added as a title on posts to Diaspora. This is mostly helpful with "remote-self" contacts that share feed content.'] = 'Po aktywacji tytuł dołączonego linku zostanie dodany jako tytuł postów do Diaspory. Jest to szczególnie pomocne w przypadku kontaktów „zdalnych”, które udostępniają treść kanału.';
|
$a->strings['When activated, the title of the attached link will be added as a title on posts to Diaspora. This is mostly helpful with "remote-self" contacts that share feed content.'] = 'Po aktywacji tytuł dołączonego linku zostanie dodany jako tytuł postów do Diaspory. Jest to szczególnie pomocne w przypadku kontaktów „zdalnych”, które udostępniają treść kanału.';
|
||||||
$a->strings['Your legacy ActivityPub/GNU Social account'] = 'Twoje stare konto ActivityPub/GNU Social';
|
|
||||||
$a->strings['If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.'] = 'Jeśli wprowadzisz tutaj swoją starą nazwę konta z systemu opartego na ActivityPub lub nazwę konta GNU Social/Statusnet (w formacie użytkownik@domena.tld), Twoje kontakty zostaną dodane automatycznie. Po zakończeniu pole zostanie opróżnione.';
|
|
||||||
$a->strings['Email/Mailbox Setup'] = 'Ustawienia emaila/skrzynki mailowej';
|
$a->strings['Email/Mailbox Setup'] = 'Ustawienia emaila/skrzynki mailowej';
|
||||||
$a->strings['If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox.'] = 'Jeśli chcesz komunikować się z kontaktami e-mail za pomocą tej usługi (opcjonalnie), określ sposób łączenia się ze skrzynką pocztową.';
|
$a->strings['If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox.'] = 'Jeśli chcesz komunikować się z kontaktami e-mail za pomocą tej usługi (opcjonalnie), określ sposób łączenia się ze skrzynką pocztową.';
|
||||||
$a->strings['Last successful email check:'] = 'Ostatni sprawdzony e-mail:';
|
$a->strings['Last successful email check:'] = 'Ostatni sprawdzony e-mail:';
|
||||||
|
@ -2047,6 +2041,12 @@ $a->strings['Send public posts to all email contacts:'] = 'Wyślij publiczny wpi
|
||||||
$a->strings['Action after import:'] = 'Akcja po zaimportowaniu:';
|
$a->strings['Action after import:'] = 'Akcja po zaimportowaniu:';
|
||||||
$a->strings['Move to folder'] = 'Przenieś do katalogu';
|
$a->strings['Move to folder'] = 'Przenieś do katalogu';
|
||||||
$a->strings['Move to folder:'] = 'Przenieś do katalogu:';
|
$a->strings['Move to folder:'] = 'Przenieś do katalogu:';
|
||||||
|
$a->strings['Contact CSV file upload error'] = 'Kontakt z plikiem CSV błąd przekazywania plików';
|
||||||
|
$a->strings['Importing Contacts done'] = 'Importowanie kontaktów zakończone';
|
||||||
|
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'Prześlij plik CSV zawierający obsługę obserwowanych kont w pierwszej kolumnie wyeksportowanej ze starego konta.';
|
||||||
|
$a->strings['Upload File'] = 'Prześlij plik';
|
||||||
|
$a->strings['Your legacy ActivityPub/GNU Social account'] = 'Twoje stare konto ActivityPub/GNU Social';
|
||||||
|
$a->strings['If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.'] = 'Jeśli wprowadzisz tutaj swoją starą nazwę konta z systemu opartego na ActivityPub lub nazwę konta GNU Social/Statusnet (w formacie użytkownik@domena.tld), Twoje kontakty zostaną dodane automatycznie. Po zakończeniu pole zostanie opróżnione.';
|
||||||
$a->strings['Delegation successfully granted.'] = 'Delegacja została pomyślnie przyznana.';
|
$a->strings['Delegation successfully granted.'] = 'Delegacja została pomyślnie przyznana.';
|
||||||
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'Nie znaleziono użytkownika nadrzędnego, jest on niedostępny lub hasło nie pasuje.';
|
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'Nie znaleziono użytkownika nadrzędnego, jest on niedostępny lub hasło nie pasuje.';
|
||||||
$a->strings['Delegation successfully revoked.'] = 'Delegacja została pomyślnie odwołana.';
|
$a->strings['Delegation successfully revoked.'] = 'Delegacja została pomyślnie odwołana.';
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1444,6 +1444,7 @@ $a->strings['Social Networks'] = 'Социальные сети';
|
||||||
$a->strings['Manage Accounts'] = 'Управление учётными записями';
|
$a->strings['Manage Accounts'] = 'Управление учётными записями';
|
||||||
$a->strings['Connected apps'] = 'Подключенные приложения';
|
$a->strings['Connected apps'] = 'Подключенные приложения';
|
||||||
$a->strings['Remote servers'] = 'Другие серверы';
|
$a->strings['Remote servers'] = 'Другие серверы';
|
||||||
|
$a->strings['Import Contacts'] = 'Импорт контактов';
|
||||||
$a->strings['Export personal data'] = 'Экспорт личных данных';
|
$a->strings['Export personal data'] = 'Экспорт личных данных';
|
||||||
$a->strings['Remove account'] = 'Удалить аккаунт';
|
$a->strings['Remove account'] = 'Удалить аккаунт';
|
||||||
$a->strings['The post was created'] = 'Запись создана';
|
$a->strings['The post was created'] = 'Запись создана';
|
||||||
|
@ -2250,8 +2251,6 @@ $a->strings['Wrong Password.'] = 'Неправильный пароль';
|
||||||
$a->strings['Invalid email.'] = 'Неправильный адрес почты';
|
$a->strings['Invalid email.'] = 'Неправильный адрес почты';
|
||||||
$a->strings['Cannot change to that email.'] = 'Нельзя установить этот адрес почты';
|
$a->strings['Cannot change to that email.'] = 'Нельзя установить этот адрес почты';
|
||||||
$a->strings['Settings were not updated.'] = 'Настройки не были изменены.';
|
$a->strings['Settings were not updated.'] = 'Настройки не были изменены.';
|
||||||
$a->strings['Contact CSV file upload error'] = 'Ошибка загрузки CSV с контактами';
|
|
||||||
$a->strings['Importing Contacts done'] = 'Импорт контактов завершён';
|
|
||||||
$a->strings['Relocate message has been send to your contacts'] = 'Перемещённое сообщение было отправлено списку контактов';
|
$a->strings['Relocate message has been send to your contacts'] = 'Перемещённое сообщение было отправлено списку контактов';
|
||||||
$a->strings['Unable to find your profile. Please contact your admin.'] = 'Не получается найти ваш профиль. Пожалуйста свяжитесь с администратором.';
|
$a->strings['Unable to find your profile. Please contact your admin.'] = 'Не получается найти ваш профиль. Пожалуйста свяжитесь с администратором.';
|
||||||
$a->strings['Account for a service that automatically shares content based on user defined channels.'] = 'Учётная запись, которая автоматически публикует контент из каналов, созданных пользователем.';
|
$a->strings['Account for a service that automatically shares content based on user defined channels.'] = 'Учётная запись, которая автоматически публикует контент из каналов, созданных пользователем.';
|
||||||
|
@ -2347,9 +2346,6 @@ $a->strings['Show notifications of ignored contacts'] = 'Показывать у
|
||||||
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = 'Вы не видите записи от игнорируемых контактов, но вы видите их комментарии. Эта настройка определяет, хотите ли вы получать уведомления от действий игнорируемых контактов или нет.';
|
$a->strings['You don\'t see posts from ignored contacts. But you still see their comments. This setting controls if you want to still receive regular notifications that are caused by ignored contacts or not.'] = 'Вы не видите записи от игнорируемых контактов, но вы видите их комментарии. Эта настройка определяет, хотите ли вы получать уведомления от действий игнорируемых контактов или нет.';
|
||||||
$a->strings['Advanced Account/Page Type Settings'] = 'Расширенные настройки учётной записи';
|
$a->strings['Advanced Account/Page Type Settings'] = 'Расширенные настройки учётной записи';
|
||||||
$a->strings['Change the behaviour of this account for special situations'] = 'Измените поведение этого аккаунта в специальных ситуациях';
|
$a->strings['Change the behaviour of this account for special situations'] = 'Измените поведение этого аккаунта в специальных ситуациях';
|
||||||
$a->strings['Import Contacts'] = 'Импорт контактов';
|
|
||||||
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'Загрузите файл CSV, который содержит адреса ваших контактов в первой колонке. Вы можете экспортировать его из вашей старой учётной записи.';
|
|
||||||
$a->strings['Upload File'] = 'Загрузить файл';
|
|
||||||
$a->strings['Relocate'] = 'Перемещение';
|
$a->strings['Relocate'] = 'Перемещение';
|
||||||
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Если вы переместили эту анкету с другого сервера, и некоторые из ваших контактов не получили ваши обновления, попробуйте нажать эту кнопку.';
|
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Если вы переместили эту анкету с другого сервера, и некоторые из ваших контактов не получили ваши обновления, попробуйте нажать эту кнопку.';
|
||||||
$a->strings['Resend relocate message to contacts'] = 'Отправить перемещённые сообщения контактам';
|
$a->strings['Resend relocate message to contacts'] = 'Отправить перемещённые сообщения контактам';
|
||||||
|
@ -2417,8 +2413,6 @@ $a->strings['API: Automatically links at the end of the post as attached posts']
|
||||||
$a->strings['When activated, added links at the end of the post react the same way as added links in the web interface.'] = 'Если включено, ссылки в конце записей будут обрабатываться так же, как ссылки, добавленные через веб-интерфейс.';
|
$a->strings['When activated, added links at the end of the post react the same way as added links in the web interface.'] = 'Если включено, ссылки в конце записей будут обрабатываться так же, как ссылки, добавленные через веб-интерфейс.';
|
||||||
$a->strings['Article Mode'] = 'Режим статей';
|
$a->strings['Article Mode'] = 'Режим статей';
|
||||||
$a->strings['Controls how posts with titles are transmitted. Mastodon and its forks don\'t display the content of these posts if the post is created in the correct (default) way.'] = 'Как будут передаваться записи, у которых указан заголовок. Mastodon и похожие платформы не показывают содержимое таких записей, если они созданы в обычном формате (по-умолчанию), оставляя лишь ссылку на них.';
|
$a->strings['Controls how posts with titles are transmitted. Mastodon and its forks don\'t display the content of these posts if the post is created in the correct (default) way.'] = 'Как будут передаваться записи, у которых указан заголовок. Mastodon и похожие платформы не показывают содержимое таких записей, если они созданы в обычном формате (по-умолчанию), оставляя лишь ссылку на них.';
|
||||||
$a->strings['Your legacy ActivityPub/GNU Social account'] = 'Ваша старая учётная запись ActivityPub/GNU Social';
|
|
||||||
$a->strings['If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.'] = 'Если вы введете тут вашу старую учетную запись от платформы совместимой с ActivityPub или GNU Social/Statusnet (в виде пользователь@домен), ваши контакты оттуда будут автоматически добавлены. Поле будет очищено когда все контакты будут добавлены.';
|
|
||||||
$a->strings['Email/Mailbox Setup'] = 'Настройка эл. почты / почтового ящика';
|
$a->strings['Email/Mailbox Setup'] = 'Настройка эл. почты / почтового ящика';
|
||||||
$a->strings['If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox.'] = 'Если вы хотите общаться с Email контактами, используя этот сервис (по желанию), пожалуйста, уточните, как подключиться к вашему почтовому ящику.';
|
$a->strings['If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox.'] = 'Если вы хотите общаться с Email контактами, используя этот сервис (по желанию), пожалуйста, уточните, как подключиться к вашему почтовому ящику.';
|
||||||
$a->strings['Last successful email check:'] = 'Последняя успешная проверка электронной почты:';
|
$a->strings['Last successful email check:'] = 'Последняя успешная проверка электронной почты:';
|
||||||
|
@ -2432,6 +2426,12 @@ $a->strings['Send public posts to all email contacts:'] = 'Отправлять
|
||||||
$a->strings['Action after import:'] = 'Действие после импорта:';
|
$a->strings['Action after import:'] = 'Действие после импорта:';
|
||||||
$a->strings['Move to folder'] = 'Переместить в папку';
|
$a->strings['Move to folder'] = 'Переместить в папку';
|
||||||
$a->strings['Move to folder:'] = 'Переместить в папку:';
|
$a->strings['Move to folder:'] = 'Переместить в папку:';
|
||||||
|
$a->strings['Contact CSV file upload error'] = 'Ошибка загрузки CSV с контактами';
|
||||||
|
$a->strings['Importing Contacts done'] = 'Импорт контактов завершён';
|
||||||
|
$a->strings['Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'] = 'Загрузите файл CSV, который содержит адреса ваших контактов в первой колонке. Вы можете экспортировать его из вашей старой учётной записи.';
|
||||||
|
$a->strings['Upload File'] = 'Загрузить файл';
|
||||||
|
$a->strings['Your legacy ActivityPub/GNU Social account'] = 'Ваша старая учётная запись ActivityPub/GNU Social';
|
||||||
|
$a->strings['If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.'] = 'Если вы введете тут вашу старую учетную запись от платформы совместимой с ActivityPub или GNU Social/Statusnet (в виде пользователь@домен), ваши контакты оттуда будут автоматически добавлены. Поле будет очищено когда все контакты будут добавлены.';
|
||||||
$a->strings['Delegation successfully granted.'] = 'Делегирование успешно предоставлено.';
|
$a->strings['Delegation successfully granted.'] = 'Делегирование успешно предоставлено.';
|
||||||
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'Родительский пользователь не найден, недоступен или пароль не совпадает.';
|
$a->strings['Parent user not found, unavailable or password doesn\'t match.'] = 'Родительский пользователь не найден, недоступен или пароль не совпадает.';
|
||||||
$a->strings['Delegation successfully revoked.'] = 'Делегирование успешно отменено.';
|
$a->strings['Delegation successfully revoked.'] = 'Делегирование успешно отменено.';
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -730,6 +730,7 @@ $a->strings['Account'] = 'Konto';
|
||||||
$a->strings['Display'] = 'Skärm';
|
$a->strings['Display'] = 'Skärm';
|
||||||
$a->strings['Social Networks'] = 'Sociala nätverk';
|
$a->strings['Social Networks'] = 'Sociala nätverk';
|
||||||
$a->strings['Connected apps'] = 'Anslutna appar';
|
$a->strings['Connected apps'] = 'Anslutna appar';
|
||||||
|
$a->strings['Import Contacts'] = 'Importera kontakter';
|
||||||
$a->strings['Export personal data'] = 'Exporter personlig data';
|
$a->strings['Export personal data'] = 'Exporter personlig data';
|
||||||
$a->strings['Remove account'] = 'Ta bort konto';
|
$a->strings['Remove account'] = 'Ta bort konto';
|
||||||
$a->strings['The post was created'] = 'Inlägget skapades';
|
$a->strings['The post was created'] = 'Inlägget skapades';
|
||||||
|
@ -1079,8 +1080,6 @@ $a->strings['Someone liked your content'] = 'Någon gillade ditt innehåll';
|
||||||
$a->strings['Someone shared your content'] = 'Någon delade ditt innehåll';
|
$a->strings['Someone shared your content'] = 'Någon delade ditt innehåll';
|
||||||
$a->strings['Activate desktop notifications'] = 'Aktivera skrivbordsaviseringar';
|
$a->strings['Activate desktop notifications'] = 'Aktivera skrivbordsaviseringar';
|
||||||
$a->strings['Show detailled notifications'] = 'Visa detaljerade aviseringar';
|
$a->strings['Show detailled notifications'] = 'Visa detaljerade aviseringar';
|
||||||
$a->strings['Import Contacts'] = 'Importera kontakter';
|
|
||||||
$a->strings['Upload File'] = 'Ladda upp fil';
|
|
||||||
$a->strings['Relocate'] = 'Omlokalisera';
|
$a->strings['Relocate'] = 'Omlokalisera';
|
||||||
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Om du har flyttat den här profilen från en annan server och några av dina kontakter inte får dina uppdateringar, försök att trycka på den här knappen.';
|
$a->strings['If you have moved this profile from another server, and some of your contacts don\'t receive your updates, try pushing this button.'] = 'Om du har flyttat den här profilen från en annan server och några av dina kontakter inte får dina uppdateringar, försök att trycka på den här knappen.';
|
||||||
$a->strings['Addon Settings'] = 'Inställningar för Tillägg';
|
$a->strings['Addon Settings'] = 'Inställningar för Tillägg';
|
||||||
|
@ -1103,6 +1102,7 @@ $a->strings['Send public posts to all email contacts:'] = 'Skicka publika inläg
|
||||||
$a->strings['Action after import:'] = 'Åtgärd efter importering:';
|
$a->strings['Action after import:'] = 'Åtgärd efter importering:';
|
||||||
$a->strings['Move to folder'] = 'Flytta till mapp';
|
$a->strings['Move to folder'] = 'Flytta till mapp';
|
||||||
$a->strings['Move to folder:'] = 'Flytta till mapp:';
|
$a->strings['Move to folder:'] = 'Flytta till mapp:';
|
||||||
|
$a->strings['Upload File'] = 'Ladda upp fil';
|
||||||
$a->strings['Potential Delegates'] = 'Potentiella delegater';
|
$a->strings['Potential Delegates'] = 'Potentiella delegater';
|
||||||
$a->strings['No entries.'] = 'Inga poster.';
|
$a->strings['No entries.'] = 'Inga poster.';
|
||||||
$a->strings['Display Settings'] = 'Skärm-inställningar';
|
$a->strings['Display Settings'] = 'Skärm-inställningar';
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue