1
1
Fork 0
mirror of https://code.mensbeam.com/MensBeam/Arsse.git synced 2024-12-22 13:12:41 +00:00

Merge branch 'master' into redup

This commit is contained in:
J. King 2023-12-30 10:16:49 -05:00
commit 0eb0478195
242 changed files with 1265 additions and 1091 deletions

1
.gitignore vendored
View file

@ -7,7 +7,6 @@
/dist/arch/arsse/
/dist/arch/src/
/dist/arch/pkg/
/dist/man/
/arsse.db*
/config.php
/.php_cs.cache

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse;
const BASE = __DIR__.DIRECTORY_SEPARATOR;
@ -13,7 +14,10 @@ $paths = [
BASE."arsse.php",
BASE."RoboFile.php",
BASE."lib",
BASE."tests",
BASE."tests/cases",
BASE."tests/lib",
BASE."tests/bootstrap.php",
BASE."tests/server.php",
];
$rules = [
// PSR standard to apply
@ -37,6 +41,7 @@ $rules = [
'no_blank_lines_after_phpdoc' => true,
'no_empty_comment' => true,
'no_empty_phpdoc' => true,
'no_empty_statement' => true,
'no_extra_blank_lines' => true, // this could probably use more configuration
'no_mixed_echo_print' => ['use' => "echo"],
'no_short_bool_cast' => true,
@ -50,11 +55,14 @@ $rules = [
'pow_to_exponentiation' => true,
'set_type_to_cast' => true,
'standardize_not_equals' => true,
'trailing_comma_in_multiline' => true,
'trailing_comma_in_multiline' => ['elements' => ["arrays"]],
'unary_operator_spaces' => true,
'yoda_style' => false,
// house exceptions to PSR rules
'braces' => ['position_after_functions_and_oop_constructs' => "same"],
'curly_braces_position' => [
'functions_opening_brace' => "same_line",
'classes_opening_brace' => "same_line",
],
'function_declaration' => ['closure_function_spacing' => "none"],
'new_with_braces' => [
'anonymous_class' => false,

View file

@ -3,6 +3,7 @@ Version 0.??.? (????-??-??)
Changes:
- Require PHP 7.3
- Multiple editorial and stylistic changes to the UNIX manual page
Version 0.10.4 (2023-01-24)
===========================

View file

@ -34,7 +34,7 @@ Also necessary to the functioning of the application is the `/vendor/` directory
The `/locale/` and `/sql/` directories contain human-language files and database schemata, both of which are occasionally used by the application in the course of execution. The `/www/` directory serves as a document root for a few static files to be made available to users by a Web server.
The `/dist/` directory, on the other hand, contains general and system-specific build files, and samples of configuration for Web servers and other system integration. These are not used by The Arsse itself, but are used during the process of preparing new releases for supported operating systems.
The `/dist/` directory, on the other hand, contains general and system-specific build files, manual pages, and samples of configuration for Web servers and other system integration. These are not used by The Arsse itself, but are used during the process of preparing new releases for supported operating systems.
## Documentation
@ -65,11 +65,11 @@ PHPUnit's configuration can be customized by copying its configuration file to `
The `/vendor-bin/` directory houses the files needed for the tools used in The Arsse's programming environment. These are managed by the Composer ["bin" plugin](https://github.com/bamarni/composer-bin-plugin) and are not used by The Arsse itself. The following files are also related to various programming tools:
| Path | Description |
|-------------------|----------------------------------------------------------|
|---------------------------|----------------------------------------------------------|
| `/.gitattributes` | Git settings for handling files |
| `/.gitignore` | Git file exclusion patterns |
| `/.php_cs.dist` | Configuration for [php-cs-fixer](https://cs.symfony.com) |
| `/.php_cs.cache` | Cache for php-cs-fixer |
| `/.php-cs-fixer.dist.php` | Configuration for [php-cs-fixer](https://cs.symfony.com) |
| `/.php-cs-fixer.cache` | Cache for php-cs-fixer |
| `/composer.json` | Configuration for Composer |
| `/composer.lock` | Version synchronization data for Composer |
| `/RoboFile.php` | Task definitions for [Robo](https://robo.li/) |
@ -90,11 +90,11 @@ There is also a `test:quick` Robo task which excludes slower tests, and a `test:
### Test coverage
Computing the coverage of tests can be done by running `./robo coverage`, after which an HTML-format coverage report will be written to `/tests/coverage/`. Either [PCOV](https://github.com/krakjoe/pcov), [Xdebug](https://xdebug.org), or [phpdbg](https://php.net/manual/en/book.phpdbg.php) is required for this. PCOV is generally recommended as it is faster than Xdebug; phpdbg is faster still, but less accurate. If using either PCOV or Xdebug, the extension need not be enabled globally; PHPUnit will enable it when needed.
Computing the coverage of tests can be done by running `./robo coverage`, after which an HTML-format coverage report will be written to `/tests/coverage/`. Either [PCOV](https://github.com/krakjoe/pcov) or [Xdebug](https://xdebug.org) is required for this. PCOV is generally recommended as it is faster than Xdebug. Neither extension need be enabled globally; Robo will enable it when needed.
## Enforcing coding style
The [php-cs-fixer](https://cs.symfony.com) tool, executed via `./robo clean`, can be used to rewrite code to adhere to The Arsse's coding style. The style largely follows [PSR-2](https://www.php-fig.org/psr/psr-2/) with some exceptions:
The [php-cs-fixer](https://cs.symfony.com) tool, executed via `./robo clean`, can be used to rewrite code to adhere to The Arsse's coding style. The style largely follows [PSR-12](https://www.php-fig.org/psr/psr-12/) with some exceptions:
- Classes, methods, and functions should have their opening brace on the same line as the signature
- Anonymous functions should have no space before the parameter list
@ -107,20 +107,13 @@ The Arsse's user manual, made using [Daux](https://daux.io/), can be compiled by
The manual employs a custom theme derived from the standard Daux theme. If the standard Daux theme receives improvements, the custom theme can be rebuilt by running `./robo manual:theme`. This requires that [NodeJS](https://nodejs.org) and [Yarn](https://yarnpkg.com/) be installed, but JavaScript tools are not required to modify The Arsse itself, nor the content of the manual.
## Building the man page
The Arsse's UNIX manual page is authored in Markdown, and must be converted to the native roff format using [Pandoc](https://pandoc.org/). This can be done by running `./robo manpage`, which will output appropriate files to `/dist/man/`. The conversion should not be done manually as there is post-processing required for optimal output.
## Packaging a release
Producing release packages is done by running `./robo package`. This performs the following operations:
- Duplicates a [Git](https://git-scm.com/) working tree with the commit (usually a release tag) to package
- Generates UNIX manual pages with [Pandoc](https://pandoc.org/)
- Generates the HTML manual
- Installs runtime Composer dependencies with an optimized autoloader
- Deletes numerous unneeded files
- Exports the default configuration of The Arsse to a file
- Compresses the remaining files into a tarball
- Produces a binary package for Arch Linux, if possible
- Produces source and binary packages for Debian using [pbuilder](https://pbuilder-team.pages.debian.net/pbuilder/), if possible

View file

@ -55,8 +55,8 @@ class RoboFile extends \Robo\Tasks {
* tests/coverage/. Additional reports may be produced by passing
* arguments to this task as one would to PHPUnit.
*
* Robo first tries to use pcov and will fall back first to xdebug then
* phpdbg. Neither pcov nor xdebug need to be enabled to be used; they
* Robo first tries to use pcov and will fall back to xdebug.
* Neither pcov nor xdebug need to be enabled to be used; they
* only need to be present in the extension load path to be used.
*/
public function coverage(array $args): Result {
@ -80,9 +80,9 @@ class RoboFile extends \Robo\Tasks {
return $this->runTests($exec, "typical", array_merge(["--coverage-html", BASE_TEST."coverage"], $args));
}
/** Runs the coding standards fixer */
/** Runs the coding-style fixer */
public function clean($opts = ['demo|d' => false]): Result {
$t = $this->taskExec(norm(BASE."vendor/bin/php-cs-fixer"));
$t = $this->taskExec(norm(BASE."vendor-bin/csfixer/vendor/bin/php-cs-fixer"));
$t->arg("fix");
if ($opts['demo']) {
$t->args("--dry-run", "--diff")->option("--diff-format", "udiff");
@ -90,9 +90,10 @@ class RoboFile extends \Robo\Tasks {
return $t->run();
}
/** Finds the first suitable means of computing code coverage, either pcov or xdebug. */
protected function findCoverageEngine(): string {
$dir = rtrim(ini_get("extension_dir"), "/").\DIRECTORY_SEPARATOR;
$ext = IS_WIN ? "dll" : (IS_MAC ? "dylib" : "so");
$ext = IS_WIN ? "dll" : "so";
$php = escapeshellarg(\PHP_BINARY);
$code = escapeshellarg(BASE."lib");
if (extension_loaded("pcov")) {
@ -103,26 +104,28 @@ class RoboFile extends \Robo\Tasks {
return "$php -d extension=pcov.$ext -d pcov.enabled=1 -d pcov.directory=$code";
} elseif (file_exists($dir."xdebug.$ext")) {
return "$php -d zend_extension=xdebug.$ext -d xdebug.mode=coverage";
} else {
if (IS_WIN) {
$dbg = dirname(\PHP_BINARY)."\\phpdbg.exe";
$dbg = file_exists($dbg) ? $dbg : "";
} else {
$dbg = trim(`which phpdbg 2>/dev/null`);
}
if ($dbg) {
return escapeshellarg($dbg)." -qrr";
} else {
return $php;
}
}
}
/** Returns the necessary shell arguments to print error output or all output to the bitbucket
*
* @param bool $all Whether all output (true) or only error output (false) should be suppressed
*/
protected function blackhole(bool $all = false): string {
$hole = IS_WIN ? "nul" : "/dev/null";
return $all ? ">$hole 2>&1" : "2>$hole";
}
/** Executes PHPUnit, used by the test and coverage tasks.
*
* This also executes the built-in PHP Web server, which is required to fetch some newsfeeds during tests
*
* @param string $executor The path to the PHP binary to execute with any required extra arguments. Normally this is either "php" or the result of findCoverageEngine()
* @param string $set The set of tests to run, either "typical" (excludes redundant tests), "quick" (excludes redundant and slow tests), "coverage" (excludes tests not needed for coverage), or "full" (all tests)
* @param array $args Extra arguments passed by Robo from the command line
*/
protected function runTests(string $executor, string $set, array $args): Result {
switch ($set) {
case "typical":
@ -146,6 +149,12 @@ class RoboFile extends \Robo\Tasks {
return $this->taskExec($executor)->option("-d", "zend.assertions=1")->arg($execpath)->option("-c", $confpath)->args(array_merge($set, $args))->run();
}
/** Returns a Git version string for a given Git tree-ish ID
*
* Returns an array containing the tree-ish string and the version string.
*
* @param string|null $commit The tree-ish ID. If not supplied the user will be prompted
*/
protected function commitVersion(?string $commit): array {
$target = $commit ?? $this->askDefault("Reference commit:", "HEAD");
$base = escapeshellarg(BASE);
@ -158,13 +167,11 @@ class RoboFile extends \Robo\Tasks {
return [$target, $version];
}
/** Checks whether all the supplied terminal commands are available in path */
protected function toolExists(string ...$binary): bool {
$blackhole = $this->blackhole(IS_WIN);
foreach ($binary as $bin) {
if (
(IS_WIN && (!exec(escapeshellarg($bin)." --help $blackhole", $junk, $status) || $status))
|| (!IS_WIN && (!exec("which ".escapeshellarg($bin)." $blackhole", $junk, $status) || $status))
) {
if (!exec(escapeshellarg($bin)." --help $blackhole", $junk, $status) || $status) {
return false;
}
}
@ -230,18 +237,18 @@ class RoboFile extends \Robo\Tasks {
}
// save commit description to VERSION file for reference
$t->addTask($this->taskWriteToFile($dir."VERSION")->text($version));
if (file_exists($dir."docs") || file_exists($dir."manpages")) {
if (file_exists($dir."docs") || file_exists($dir."manpages/en.md")) {
// perform Composer installation in the temp location with dev dependencies to include Robo and Daux
$t->addTask($this->taskExec("composer install")->arg("-q")->dir($dir));
}
if (file_exists($dir."manpages")) {
// generate manpages
$t->addTask($this->taskExec("./robo manpage")->dir($dir));
}
if (file_exists($dir."docs")) {
// generate the HTML manual
$t->addTask($this->taskExec("./robo manual -q")->dir($dir));
}
if (file_exists($dir."manpages/en.md")) {
// generate manpages (NOTE: obsolete process)
$t->addTask($this->taskExec("./robo manpage")->dir($dir));
}
}
// perform Composer installation in the temp location for final output
$t->addTask($this->taskExec("composer install")->dir($dir)->arg("--no-dev")->arg("-o")->arg("--no-scripts")->arg("-q"));
// delete unwanted files
@ -400,12 +407,12 @@ class RoboFile extends \Robo\Tasks {
return $t->run();
}
/** Generates static manual pages in the "manual" directory
/** Generates static HTML manual pages in the "manual" directory
*
* The resultant files are suitable for offline viewing and inclusion into release builds
*/
public function manual(array $args): Result {
$execpath = escapeshellarg(norm(BASE."vendor/bin/daux"));
$execpath = escapeshellarg(norm(BASE."vendor-bin/daux/vendor/bin/daux"));
$t = $this->collectionBuilder();
$t->taskExec($execpath)->arg("generate")->option("-d", BASE."manual")->args($args);
$t->taskDeleteDir(BASE."manual/daux_libraries");
@ -416,7 +423,7 @@ class RoboFile extends \Robo\Tasks {
/** Serves a live view of the manual using the built-in Web server */
public function manualLive(array $args): Result {
$execpath = escapeshellarg(norm(BASE."vendor/bin/daux"));
$execpath = escapeshellarg(norm(BASE."vendor-bin/daux/vendor/bin/daux"));
return $this->taskExec($execpath)->arg("serve")->args($args)->run();
}
@ -447,29 +454,15 @@ class RoboFile extends \Robo\Tasks {
return $t->run();
}
/** Generates the "arsse" command's manual page (UNIX man page)
/** Parses the contents of the CHANGELOG file into an array structure
*
* This requires that the Pandoc document converter be installed and
* available in $PATH.
* This is done line-by-line and tends to be quite strict.
* The parsed output can be used to generate changelogs in other formats,
* such as a Debian changelog or RPM changelog.
*
* @param string $text The text of the CHANGELOG file
* @param string $targetVersion The x.y.z version number of the latest release. This is used to check that version numbers and dates have been updated when preparing a release
*/
public function manpage(): Result {
if (!$this->toolExists("pandoc")) {
throw new \Exception("Pandoc is required in PATH to generate manual pages");
}
$t = $this->collectionBuilder();
$man = [
'en' => "man1/arsse.1",
];
foreach ($man as $src => $out) {
$src = BASE."manpages/$src.md";
$out = BASE."dist/man/$out";
$t->addTask($this->taskFilesystemStack()->mkdir(dirname($out), 0755));
$t->addTask($this->taskExec("pandoc -s -f markdown-smart -t man -o ".escapeshellarg($out)." ".escapeshellarg($src)));
$t->addTask($this->taskReplaceInFile($out)->regex('/\.\n(?!\.)/s')->to(". "));
}
return $t->run();
}
protected function changelogParse(string $text, string $targetVersion): array {
$lines = preg_split('/\r?\n/', $text);
$version = "";
@ -479,7 +472,7 @@ class RoboFile extends \Robo\Tasks {
$expected = ["version"];
for ($a = 0; $a < sizeof($lines);) {
$l = rtrim($lines[$a++]);
if (in_array("version", $expected) && preg_match('/^Version (\d+(?:\.\d+)*) \(([\d\?]{4}-[\d\?]{2}-[\d\?]{2})\)\s*$/D', $l, $m)) {
if (in_array("version", $expected) && preg_match('/^Version ([\d\?]+(?:\.[\d\?]+)*) \(([\d\?]{4}-[\d\?]{2}-[\d\?]{2})\)\s*$/D', $l, $m)) {
$version = $m[1];
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/D', $m[2])) {
// uncertain dates are allowed only for the top version, and only if it does not match the target version (otherwise we have forgotten to set the correct date before tagging)
@ -546,7 +539,18 @@ class RoboFile extends \Robo\Tasks {
return $out;
}
/** Produce a Debian changelog from a parsed CHANGELOG file
*
* The Debian changelog format is extremely specific with certain tokens
* having special meaning and leading whitespace also being significant.
* Modifying this function should be done with extreme care.
*
* @param array $log The parsed chaneglog, output by changelogParse()
* @param string $targetVersion The second output of commitVersion()
*/
protected function changelogDebian(array $log, string $targetVersion): string {
$authorName = "J. King";
$authorMail = "jking@jkingweb.ca";
$latest = $log[0]['version'];
$baseVersion = preg_replace('/^(\d+(?:\.\d+)*).*/', "$1", $targetVersion);
if ($baseVersion !== $targetVersion && version_compare($latest, $baseVersion, ">")) {
@ -582,11 +586,20 @@ class RoboFile extends \Robo\Tasks {
$out .= " * ".trim(preg_replace("/^/m", " ", $item))."\n";
}
}
$out .= "\n -- J. King <jking@jkingweb.ca> ".\DateTimeImmutable::createFromFormat("Y-m-d", $entry['date'], new \DateTimeZone("UTC"))->format("D, d M Y")." 00:00:00 +0000\n\n";
$out .= "\n -- $authorName <$authorMail> ".\DateTimeImmutable::createFromFormat("Y-m-d", $entry['date'], new \DateTimeZone("UTC"))->format("D, d M Y")." 00:00:00 +0000\n\n";
}
return $out;
}
/** Produces a Debian "source control" file from various bits of data
*
* As with a Debian changelog, the output is of a very exacting format,
* and this function should be modified with care.
*
* @param string $dir The path to Debian-specific files, with trailing slash
* @param string $version The Debian version string, in the format x.y.z-a
* @param array $tarballs An array of paths to the "orig" and "debian" tarball files
*/
protected function generateDebianSourceControl(string $dir, string $version, array $tarballs): string {
// read in control file
if (!$control = @file_get_contents($dir."control")) {

View file

@ -11,7 +11,7 @@ usually prudent:
`composer install -o --no-dev`
Upgrading from 0.10.2 to 0.10.3
Upgrading from 0.10.4 to 0.10.?
=============================
- PHP 7.3 is now required

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse;
const BASE = __DIR__.DIRECTORY_SEPARATOR;

View file

@ -18,24 +18,24 @@
],
"require": {
"php": "^7.1 || ^8.0",
"php": ">=7.3",
"ext-intl": "*",
"ext-json": "*",
"ext-hash": "*",
"ext-filter": "*",
"ext-dom": "*",
"nicolus/picofeed": "dev-bugfix",
"nicolus/picofeed": "dev-patch-3",
"hosteurope/password-generator": "1.*",
"docopt/docopt": "dev-master",
"docopt/docopt": "1.*",
"jkingweb/druuid": "3.*",
"guzzlehttp/psr7": "1.*",
"laminas/laminas-httphandlerrunner": "1.*"
"guzzlehttp/psr7": "2.*",
"laminas/laminas-httphandlerrunner": "2.*"
},
"require-dev": {
"bamarni/composer-bin-plugin": "*"
},
"suggest": {
"ext-pcntl": "To respond to signals, particular to reload configuration via SIGHUP"
"ext-pcntl": "To respond to signals, particularly to reload configuration via SIGHUP"
},
"config": {
"platform": {
@ -45,9 +45,11 @@
"bamarni/composer-bin-plugin": true
}
},
"scripts": {
"post-install-cmd": ["@composer bin all install"],
"post-update-cmd": ["@composer bin all update"]
"extra": {
"bamarni-bin": {
"bin-links": false,
"forward-command": true
}
},
"autoload": {
"psr-4": {
@ -63,11 +65,7 @@
"repositories": [
{
"type": "vcs",
"url": "https://github.com/rhukster/picoFeed"
},
{
"type": "vcs",
"url": "https://github.com/docopt/docopt.php"
"url": "https://github.com/JKingweb/picoFeed-1/"
}
]
}

309
composer.lock generated
View file

@ -4,35 +4,32 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "2e8ad0d4821fdfc0d975e98f2e2c3efe",
"content-hash": "8d22dd66c6cde0b1ed4ca0009293bf88",
"packages": [
{
"name": "docopt/docopt",
"version": "dev-master",
"version": "1.0.5",
"source": {
"type": "git",
"url": "https://github.com/docopt/docopt.php.git",
"reference": "5ad491cb9fc072e8bb0497061a09b0efcf25cbcf"
"reference": "0e3db660cf2f2eb07a83253790b7d97cdb398826"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/docopt/docopt.php/zipball/5ad491cb9fc072e8bb0497061a09b0efcf25cbcf",
"reference": "5ad491cb9fc072e8bb0497061a09b0efcf25cbcf",
"url": "https://api.github.com/repos/docopt/docopt.php/zipball/0e3db660cf2f2eb07a83253790b7d97cdb398826",
"reference": "0e3db660cf2f2eb07a83253790b7d97cdb398826",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "4.1.*"
},
"default-branch": true,
"type": "library",
"autoload": {
"classmap": [
"src/docopt.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
@ -51,29 +48,29 @@
"docs"
],
"support": {
"source": "https://github.com/docopt/docopt.php/tree/master",
"issues": "https://github.com/docopt/docopt.php/issues"
"issues": "https://github.com/docopt/docopt.php/issues",
"source": "https://github.com/docopt/docopt.php/tree/1.0.5"
},
"time": "2022-05-11T23:52:25+00:00"
"time": "2023-03-22T12:31:48+00:00"
},
{
"name": "guzzlehttp/guzzle",
"version": "7.5.0",
"version": "7.7.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba"
"reference": "fb7566caccf22d74d1ab270de3551f72a58399f5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba",
"reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/fb7566caccf22d74d1ab270de3551f72a58399f5",
"reference": "fb7566caccf22d74d1ab270de3551f72a58399f5",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/promises": "^1.5",
"guzzlehttp/psr7": "^1.9 || ^2.4",
"guzzlehttp/promises": "^1.5.3 || ^2.0",
"guzzlehttp/psr7": "^1.9.1 || ^2.4.5",
"php": "^7.2.5 || ^8.0",
"psr/http-client": "^1.0",
"symfony/deprecation-contracts": "^2.2 || ^3.0"
@ -84,7 +81,8 @@
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.1",
"ext-curl": "*",
"php-http/client-integration-tests": "^3.0",
"php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999",
"php-http/message-factory": "^1.1",
"phpunit/phpunit": "^8.5.29 || ^9.5.23",
"psr/log": "^1.1 || ^2.0 || ^3.0"
},
@ -98,9 +96,6 @@
"bamarni-bin": {
"bin-links": true,
"forward-command": false
},
"branch-alias": {
"dev-master": "7.5-dev"
}
},
"autoload": {
@ -166,7 +161,7 @@
],
"support": {
"issues": "https://github.com/guzzle/guzzle/issues",
"source": "https://github.com/guzzle/guzzle/tree/7.5.0"
"source": "https://github.com/guzzle/guzzle/tree/7.7.0"
},
"funding": [
{
@ -182,38 +177,37 @@
"type": "tidelift"
}
],
"time": "2022-08-28T15:39:27+00:00"
"time": "2023-05-21T14:04:53+00:00"
},
{
"name": "guzzlehttp/promises",
"version": "1.5.2",
"version": "2.0.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "b94b2807d85443f9719887892882d0329d1e2598"
"reference": "3a494dc7dc1d7d12e511890177ae2d0e6c107da6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598",
"reference": "b94b2807d85443f9719887892882d0329d1e2598",
"url": "https://api.github.com/repos/guzzle/promises/zipball/3a494dc7dc1d7d12e511890177ae2d0e6c107da6",
"reference": "3a494dc7dc1d7d12e511890177ae2d0e6c107da6",
"shasum": ""
},
"require": {
"php": ">=5.5"
"php": "^7.2.5 || ^8.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^4.4 || ^5.1"
"bamarni/composer-bin-plugin": "^1.8.1",
"phpunit/phpunit": "^8.5.29 || ^9.5.23"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.5-dev"
"bamarni-bin": {
"bin-links": true,
"forward-command": false
}
},
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
}
@ -250,7 +244,7 @@
],
"support": {
"issues": "https://github.com/guzzle/promises/issues",
"source": "https://github.com/guzzle/promises/tree/1.5.2"
"source": "https://github.com/guzzle/promises/tree/2.0.0"
},
"funding": [
{
@ -266,47 +260,48 @@
"type": "tidelift"
}
],
"time": "2022-08-28T14:55:35+00:00"
"time": "2023-05-21T13:50:22+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "1.9.0",
"version": "2.5.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "e98e3e6d4f86621a9b75f623996e6bbdeb4b9318"
"reference": "b635f279edd83fc275f822a1188157ffea568ff6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/e98e3e6d4f86621a9b75f623996e6bbdeb4b9318",
"reference": "e98e3e6d4f86621a9b75f623996e6bbdeb4b9318",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6",
"reference": "b635f279edd83fc275f822a1188157ffea568ff6",
"shasum": ""
},
"require": {
"php": ">=5.4.0",
"psr/http-message": "~1.0",
"ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
"php": "^7.2.5 || ^8.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.1 || ^2.0",
"ralouphie/getallheaders": "^3.0"
},
"provide": {
"psr/http-factory-implementation": "1.0",
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"ext-zlib": "*",
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10"
"bamarni/composer-bin-plugin": "^1.8.1",
"http-interop/http-factory-tests": "^0.9",
"phpunit/phpunit": "^8.5.29 || ^9.5.23"
},
"suggest": {
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.9-dev"
"bamarni-bin": {
"bin-links": true,
"forward-command": false
}
},
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
}
@ -345,6 +340,11 @@
"name": "Tobias Schultze",
"email": "webmaster@tubo-world.de",
"homepage": "https://github.com/Tobion"
},
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com",
"homepage": "https://sagikazarmark.hu"
}
],
"description": "PSR-7 message implementation that also provides common utility methods",
@ -360,7 +360,7 @@
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/1.9.0"
"source": "https://github.com/guzzle/psr7/tree/2.5.0"
},
"funding": [
{
@ -376,7 +376,7 @@
"type": "tidelift"
}
],
"time": "2022-06-20T21:43:03+00:00"
"time": "2023-04-17T16:11:26+00:00"
},
{
"name": "hosteurope/password-generator",
@ -552,30 +552,26 @@
},
{
"name": "laminas/laminas-httphandlerrunner",
"version": "1.5.0",
"version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/laminas/laminas-httphandlerrunner.git",
"reference": "5f94e55d93f756e8ad07b9049aeb3d6d84582d0e"
"reference": "4d337cde83e6b901a4443b0ab5c3b97cbaa46413"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laminas/laminas-httphandlerrunner/zipball/5f94e55d93f756e8ad07b9049aeb3d6d84582d0e",
"reference": "5f94e55d93f756e8ad07b9049aeb3d6d84582d0e",
"url": "https://api.github.com/repos/laminas/laminas-httphandlerrunner/zipball/4d337cde83e6b901a4443b0ab5c3b97cbaa46413",
"reference": "4d337cde83e6b901a4443b0ab5c3b97cbaa46413",
"shasum": ""
},
"require": {
"laminas/laminas-zendframework-bridge": "^1.0",
"php": "^7.3 || ~8.0.0 || ~8.1.0",
"psr/http-message": "^1.0",
"psr/http-message-implementation": "^1.0",
"psr/http-server-handler": "^1.0"
},
"replace": {
"zendframework/zend-httphandlerrunner": "^1.1.0"
},
"require-dev": {
"laminas/laminas-coding-standard": "~1.0.0",
"laminas/laminas-coding-standard": "~2.3.0",
"laminas/laminas-diactoros": "^2.8.0",
"phpunit/phpunit": "^9.5.9",
"psalm/plugin-phpunit": "^0.16.1",
@ -619,7 +615,7 @@
"type": "community_bridge"
}
],
"time": "2021-09-22T09:17:54+00:00"
"time": "2021-09-22T09:27:36+00:00"
},
{
"name": "laminas/laminas-xml",
@ -681,80 +677,18 @@
],
"time": "2021-11-30T02:16:35+00:00"
},
{
"name": "laminas/laminas-zendframework-bridge",
"version": "1.4.1",
"source": {
"type": "git",
"url": "https://github.com/laminas/laminas-zendframework-bridge.git",
"reference": "88bf037259869891afce6504cacc4f8a07b24d0f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/88bf037259869891afce6504cacc4f8a07b24d0f",
"reference": "88bf037259869891afce6504cacc4f8a07b24d0f",
"shasum": ""
},
"require": {
"php": "^7.3 || ~8.0.0 || ~8.1.0"
},
"require-dev": {
"phpunit/phpunit": "^9.3",
"psalm/plugin-phpunit": "^0.15.1",
"squizlabs/php_codesniffer": "^3.5",
"vimeo/psalm": "^4.6"
},
"type": "library",
"extra": {
"laminas": {
"module": "Laminas\\ZendFrameworkBridge"
}
},
"autoload": {
"files": [
"src/autoload.php"
],
"psr-4": {
"Laminas\\ZendFrameworkBridge\\": "src//"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"description": "Alias legacy ZF class names to Laminas Project equivalents.",
"keywords": [
"ZendFramework",
"autoloading",
"laminas",
"zf"
],
"support": {
"forum": "https://discourse.laminas.dev/",
"issues": "https://github.com/laminas/laminas-zendframework-bridge/issues",
"rss": "https://github.com/laminas/laminas-zendframework-bridge/releases.atom",
"source": "https://github.com/laminas/laminas-zendframework-bridge"
},
"funding": [
{
"url": "https://funding.communitybridge.org/projects/laminas-project",
"type": "community_bridge"
}
],
"time": "2021-12-21T14:34:37+00:00"
},
{
"name": "nicolus/picofeed",
"version": "dev-bugfix",
"version": "dev-patch-3",
"source": {
"type": "git",
"url": "https://github.com/rhukster/picoFeed.git",
"reference": "b8e5e34ce7d0b97f1910b8c574aa72ff768a4078"
"url": "https://github.com/JKingweb/picoFeed-1.git",
"reference": "536911c180651fea79d6e1894a826fff6ab87a52"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rhukster/picoFeed/zipball/b8e5e34ce7d0b97f1910b8c574aa72ff768a4078",
"reference": "b8e5e34ce7d0b97f1910b8c574aa72ff768a4078",
"url": "https://api.github.com/repos/JKingweb/picoFeed-1/zipball/536911c180651fea79d6e1894a826fff6ab87a52",
"reference": "536911c180651fea79d6e1894a826fff6ab87a52",
"shasum": ""
},
"require": {
@ -803,27 +737,27 @@
"description": "RSS/Atom parsing library",
"homepage": "https://github.com/nicolus/picoFeed",
"support": {
"source": "https://github.com/rhukster/picoFeed/tree/bugfix"
"source": "https://github.com/JKingweb/picoFeed-1/tree/patch-3"
},
"time": "2022-09-23T17:42:18+00:00"
"time": "2023-03-23T01:54:27+00:00"
},
{
"name": "psr/http-client",
"version": "1.0.1",
"version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-client.git",
"reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621"
"reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
"reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
"url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31",
"reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31",
"shasum": ""
},
"require": {
"php": "^7.0 || ^8.0",
"psr/http-message": "^1.0"
"psr/http-message": "^1.0 || ^2.0"
},
"type": "library",
"extra": {
@ -843,7 +777,7 @@
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for HTTP clients",
@ -855,26 +789,27 @@
"psr-18"
],
"support": {
"source": "https://github.com/php-fig/http-client/tree/master"
"source": "https://github.com/php-fig/http-client/tree/1.0.2"
},
"time": "2020-06-29T06:28:15+00:00"
"time": "2023-04-10T20:12:12+00:00"
},
{
"name": "psr/http-message",
"version": "1.0.1",
"name": "psr/http-factory",
"version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
"url": "https://github.com/php-fig/http-factory.git",
"reference": "e616d01114759c4c489f93b099585439f795fe35"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35",
"reference": "e616d01114759c4c489f93b099585439f795fe35",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
"php": ">=7.0.0",
"psr/http-message": "^1.0 || ^2.0"
},
"type": "library",
"extra": {
@ -891,6 +826,60 @@
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interfaces for PSR-7 HTTP message factories",
"keywords": [
"factory",
"http",
"message",
"psr",
"psr-17",
"psr-7",
"request",
"response"
],
"support": {
"source": "https://github.com/php-fig/http-factory/tree/1.0.2"
},
"time": "2023-04-10T20:10:41+00:00"
},
{
"name": "psr/http-message",
"version": "1.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba",
"reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
@ -908,27 +897,27 @@
"response"
],
"support": {
"source": "https://github.com/php-fig/http-message/tree/master"
"source": "https://github.com/php-fig/http-message/tree/1.1"
},
"time": "2016-08-06T14:39:51+00:00"
"time": "2023-04-04T09:50:52+00:00"
},
{
"name": "psr/http-server-handler",
"version": "1.0.1",
"version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-server-handler.git",
"reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7"
"reference": "84c4fb66179be4caaf8e97bd239203245302e7d4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/aff2f80e33b7f026ec96bb42f63242dc50ffcae7",
"reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7",
"url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4",
"reference": "84c4fb66179be4caaf8e97bd239203245302e7d4",
"shasum": ""
},
"require": {
"php": ">=7.0",
"psr/http-message": "^1.0"
"psr/http-message": "^1.0 || ^2.0"
},
"type": "library",
"extra": {
@ -948,7 +937,7 @@
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for HTTP server-side request handler",
@ -964,10 +953,9 @@
"server"
],
"support": {
"issues": "https://github.com/php-fig/http-server-handler/issues",
"source": "https://github.com/php-fig/http-server-handler/tree/master"
"source": "https://github.com/php-fig/http-server-handler/tree/1.0.2"
},
"time": "2018-10-30T16:46:14+00:00"
"time": "2023-04-10T20:06:20+00:00"
},
{
"name": "psr/log",
@ -1193,13 +1181,12 @@
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
"nicolus/picofeed": 20,
"docopt/docopt": 20
"nicolus/picofeed": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": "^7.1 || ^8.0",
"php": ">=7.3",
"ext-intl": "*",
"ext-json": "*",
"ext-hash": "*",

342
dist/man/man1/arsse.1 vendored Normal file
View file

@ -0,0 +1,342 @@
.Dd October 27, 2023
.Dt ARSSE 1
.Os "The Arsse" 0.10.4
.
.
.Sh NAME
.Nm arsse
.Nd manage an instance of The Advanced RSS Environment (The Arsse)
.
.
.Sh SYNOPSIS
.Nm "arsse user"
.Op Nm list
.Nm "arsse user add"
.Ar username
.Op Ar password
.Op Fl Fl admin
.Nm "arsse user remove"
.Ar username
.Nm "arsse user show"
.Ar username
.Nm "arsse user set"
.Ar username
.Ar property
.Ar value
.Nm "arsse user unset"
.Ar username
.Ar property
.Nm "arsse user set\-pass"
.Ar username
.Op Ar password
.Op Fl Fl fever
.Nm "arsse user unset\-pass"
.Ar username
.Op Fl Fl fever
.Nm "arsse user auth"
.Ar username
.Op Ar password
.Op Fl Fl fever
.Nm "arsse token list"
.Ar username
.Nm "arsse token create"
.Ar username
.Op Ar label
.Nm "arsse token revoke"
.Ar username
.Op Ar token
.Nm "arsse import"
.Ar username
.Op Ar file
.Op Fl f | Fl Fl flat
.Op Fl r | Fl Fl replace
.Nm "arsse export"
.Ar username
.Op Ar file
.Op Fl f | Fl Fl flat
.Nm "arsse daemon"
.Op Fl Fl fork Ns = Ns Ar pidfile
.Nm "arsse feed refresh\-all"
.Nm "arsse feed refresh"
.Ar n
.Nm "arsse conf save\-defaults"
.Nm "arsse"
.Fl Fl version | Fl h | Fl Fl help
.
.
.Sh DESCRIPTION
.Nm
allows a sufficiently privileged user to perform various administrative operations related to The Arsse, including:
.Pp
.Bl -bullet -compact
.It
Adding and removing users and managing their metadata
.It
Managing passwords and authentication tokens
.It
Importing and exporting OPML newsfeed-lists
.El
.Pp
These are documented in the next section
.Sx COMMANDS Ns No .
Further, seldom-used commands are documented in the subsequent section
.Sx ADDITIONAL COMMANDS Ns No .
.
.
.Sh COMMANDS
.
.Ss Managing users and metadata
.Bl -tag
.It Nm "user" Op Nm list
Displays a simple list of user names with one entry per line
.It Nm "user add" Ar username Oo Ar password Oc Oo Fl Fl admin Oc
Adds a new user to the database with the specified username and password.
If
.Ar password
is omitted a random password will be generated and printed.
.Pp
The
.Fl Fl admin
flag may be used to mark the user as an administrator.
This has no meaning within the context of The Arsse as a whole,
but it is used control access to certain features in the Miniflux and Nextcloud News protocols.
.It Nm "user remove" Ar username
Immediately removes a user from the database.
All associated data (folders, subscriptions, etc.) are also removed.
.It Nm "user show" Ar username
Displays a table of metadata properties and their assigned values for
.Ar username Ns No .
These properties are primarily used by the Miniflux protocol.
Consult the section
.Sx USER METADATA
for details.
.It Nm "user set" Ar username Ar property Ar value
Sets a metadata property for a user.
These properties are primarily used by the Miniflux protocol.
Consult the section
.Sx USER METADATA
for details.
.It Nm "user unset" Ar username Ar property
Clears a metadata property for a user.
The property is thereafter set to its default value, which is protocol-dependent.
.El
.
.Ss Managing passwords and authentication tokens
.Bl -tag
.It Nm "user set\-pass" Ar username Oo Ar password Oc Oo Fl Fl fever Oc
Changes a user's password to the specified value.
If no password is specified, a random password will be generated and printed.
.Pp
The
.Fl Fl fever
option sets a user's Fever protocol password instead of their general password.
As the Fever protocol requires that passwords be stored insecurely,
users do not have Fever passwords by default, and logging in to the Fever protocol is disabled until a suitable password is set.
It is highly recommended that a user's Fever password be different from their general password.
.It Nm "user unset\-pass" Ar username Oo Fl Fl fever Oc
Unsets a user's password, effectively disabling their account.
As with password setting, the
.Fl Fl fever
option may be used to operate on a user's Fever password instead of their general password.
.It Nm "user auth" Ar username Ar password Oo Fl Fl fever Oc
Tests logging a user in.
This only checks that the user's password is correctly recognized;
it has no side effects.
.Pp
The
.Fl Fl fever
option may be used to test the user's Fever protocol password, if any.
.It Nm "token list" Ar username
Displays a user's authentication tokens in a simple tabular format.
These tokens act as an alternative means of authentication for the Miniflux protocol and may be required by some clients.
They do not expire.
.It Nm "token create" Ar username Oo Ar label Oc
Creates a new random login token and prints it.
These tokens act as an alternative means of authentication for the Miniflux protocol and may be required by some clients.
An optional
.Ar label
may be specified to give the token a meaningful name.
.It Nm "token revoke" Ar username Oo Ar token Oc
Deletes the specified
.Ar token
from the database.
The token itself must be supplied, not its label.
If it is omitted all tokens for
.Ar username
are revoked.
.El
.
.Ss Importing and exporting data
.Bl -tag
.It Nm "import" Ar username Oo Ar file Oc Oo Fl r | Fl Fl replace Oc Oo Fl f | Fl Fl flat Oc
Imports the newsfeeds, folders, and tags found in the OPML formatted
.Ar file
into the account of the specified user.
If no file is specified, data is instead read from standard input.
Import operations are atomic:
if any of the newsfeeds listed in the input cannot be retrieved, the entire import operation will fail.
.Pp
The
.Fl Fl replace
(or
.Fl r Ns
) option interprets the OPML file as the list of
.Em all
desired newsfeeds, folders and tags, performing any deletion or moving of existing entries which do not appear in the flle.
If this option is not specified, the file is assumed to list desired
.Em additions only Ns No .
.Pp
The
.Fl Fl flat
(or
.Fl f Ns
) option can be used to ignore any folder structures in the file, importing any newsfeeds directly into the root folder.
Combining this with the
.Fl Fl replace
option is possible.
.It Nm "export" Ar username Oo Ar file Oc Oo Fl f | Fl Fl flat Oc
Exports a user's newsfeeds, folders, and tags to the OPML file specified by
.Ar file Ns
, or standard output if no file is specified.
Note that due to a limitation of the OPML format, any commas present in tag names will not be retained in the export.
.Pp
The
.Fl Fl flat
(or
.Fl f Ns
) option can be used to omit folders from the export.
Some OPML implementations may not support folders, or arbitrary nesting;
this option may be used when planning to import into such software.
.El
.
.
.Sh ADDITIONAL COMMANDS
.Bl -tag
.It Nm "daemon" Oo Fl Fl fork Ns = Ns Ar pidfile Oc
Starts the newsfeed fetching service.
Normally this command is only invoked by systemd.
.Pp
The
.Fl Fl fork
option executes an "old-style" fork-then-terminate daemon rather than a "new-style" non-terminating daemon.
This option should only be employed if using a System V-style init daemon on POSIX systems;
normally systemd is used. When using this option the daemon will write its process identifier to
.Ar pidfile
after forking.
.It Nm "feed refresh\-all"
Performs a one-time fetch of all stale feeds.
This command can be used as the basis of a
.Nm cron
job to keep newsfeeds up-to-date.
.It Nm "feed refresh" Ar n
Performs a one-time fetch of the feed (not subscription) identified by integer
.Ar n Ns No .
This is used internally by the fetching service and should not normally be needed.
.It Nm "conf save\-defaults" Oo Ar file Oc
Prints default configuration parameters to standard output, or to
.Ar file
if specified.
Each parameter is annotated with a short description of its purpose and usage.
.El
.
.
.Sh USER METADATA
User metadata are primarily used by the Miniflux protocol,
and most properties have identical or similar names to those used by Miniflux.
Properties may also affect other protocols, or conversely may have no effect even when using the Miniflux protocol;
this is noted below when appropriate.
.Pp
Booleans accept any of the values
.Ar true Ns No / Ns Ar false Ns No ,
.Ar 1 Ns No / Ns Ar 0 Ns No ,
.Ar yes Ns No / Ns Ar no Ns No ,
or
.Ar on Ns No / Ns Ar off Ns No .
.Pp
The following metadata properties exist for each user:
.Pp
.Bl -tag
.It Cm num No (integer)
The numeric identifier of the user.
This is assigned at user creation and is read-only.
.It Cm admin No (boolean)
Boolean. Whether the user is an administrator.
Administrators may manage other users via the Miniflux protocol,
and also may trigger feed updates manually via the Nextcloud News protocol.
.It Cm lang No (string)
The preferred language of the user as a BCP 47 language tag, for example "en-ca".
Note that since The Arsse currently only includes English text it is not used by The Arsse itself,
but clients may use this metadatum in protocols which expose it.
.It Cm tz No (string)
The time zone of the user as a Time Zone Database identifier, for example "America/Los_Angeles".
.It Cm root_folder_name No (string)
The name of the root folder, in protocols which allow it to be renamed.
.It Cm sort_asc No (boolean)
Whether the user prefers ascending sort order for articles.
Descending order is usually the default,
but explicitly setting this property false will also make a preference for descending order explicit.
.It Cm theme No (string)
The user's preferred user-interface theme.
This is not used by The Arsse itself, but clients may use this metadatum in protocols which expose it.
.It Cm page_size No (integer)
The user's preferred page size when listing articles.
This is not used by The Arsse itself, but clients may use this metadatum in protocols which expose it.
.It Cm shortcuts No (boolean)
Whether to enable keyboard shortcuts.
This is not used by The Arsse itself, but clients may use this metadatum in protocols which expose it.
.It Cm gestures No (boolean)
Whether to enable touch gestures.
This is not used by The Arsse itself, but clients may use this metadatum in protocols which expose it.
.It Cm reading_time No (boolean)
Whether to calculate and display the estimated reading time for articles.
Currently The Arsse does not calculate reading time, so changing this will likely have no effect.
.It Cm stylesheet No (string)
A user stylesheet in CSS format.
This is not used by The Arsse itself, but clients may use this metadatum in protocols which expose it.
.El
.
.
.Sh EXAMPLES
.Bl -tag
.It Add an administrator to the database with an explicit password:
.Bd -literal
$ arsse user add \-\-admin alice "Curiouser and curiouser!"
.Ed
.It Add a regular user to the database with a random password:
.Bd -literal
$ arsse user add "Bob the Builder"
bLS!$_UUZ!iN2i_!^IC6
.Ed
.It Make Bob the Builder an administrator:
.Bd -literal
$ arsse user set "Bob the Builder" admin true
.Ed
.It Disable Alice's account by clearing her password:
.Bd -literal
$ arsse user unset\-pass alice
.Ed
.It Move all of Foobar's newsfeeds to the root folder:
.Bd -literal
$ arsse export foobar \-f | arsse import \-r foobar
.Ed
.It Fail to log in as Alice:
.Bd -literal
$ arsse user auth alice "Oh, dear!"
Authentication failed
$ echo $?
1
.Ed
.El
.
.
.Sh REPORTING BUGS
Any bugs found in The Arsse may be reported on the Web via the
.Lk https://code.mensbeam.com/MensBeam/arsse "MensBeam code repository"
or may be directed to the principal authors by e-mail:
.Pp
.Bl -bullet -compact
.It
.Lk https://jkingweb.ca/ "J. King"
.It
.Lk https://dustinwilson.com/ "Dustin Wilson"
.El

View file

@ -363,7 +363,7 @@ The default value is equal to two megabytes.
|---------|---------|
| boolean | `true` |
Whether to allow the possibility of fetching full article contents from an article's source, if a newsfeed only provides excerpts. Whether fetching will actually happen is governed by a per-newsfeed toggle (defaulting to `false`) which currently can only be changed by manually editing the database.
Whether to allow the possibility of fetching full article contents from an article's source, if a newsfeed only provides excerpts. Whether fetching will actually happen is governed by a per-newsfeed toggle (defaulting to `false`) which currently can only be changed via the Miniflux protocol.
### fetchUserAgentString

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse;
abstract class AbstractException extends \Exception {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse;
class Arsse {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse;
use JKingWeb\Arsse\REST\Fever\User as Fever;

View file

@ -5,6 +5,7 @@
/** Conf class */
declare(strict_types=1);
namespace JKingWeb\Arsse;
use AllowDynamicProperties;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Conf;
class Exception extends \JKingWeb\Arsse\AbstractException {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Context;
abstract class AbstractContext {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Context;
trait BooleanMembers {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Context;
class Context extends RootContext {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Context;
class ExclusionContext extends AbstractContext {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Context;
use JKingWeb\Arsse\Misc\ValueInfo;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Context;
abstract class RootContext extends AbstractContext {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Context;
class UnionContext extends RootContext implements \ArrayAccess, \Countable, \IteratorAggregate {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse;
use JKingWeb\DrUUID\UUID;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
use JKingWeb\Arsse\Arsse;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
abstract class AbstractResult implements Result {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
use JKingWeb\Arsse\Misc\Date;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
interface Driver {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
class Exception extends \JKingWeb\Arsse\AbstractException {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
class ExceptionInput extends \JKingWeb\Arsse\AbstractException {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
class ExceptionRetry extends \JKingWeb\Arsse\AbstractException {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
class ExceptionTimeout extends \JKingWeb\Arsse\AbstractException {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\MySQL;
use JKingWeb\Arsse\Arsse;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\MySQL;
use JKingWeb\Arsse\Db\Exception;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\MySQL;
use JKingWeb\Arsse\Arsse;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\MySQL;
class PDOStatement extends \JKingWeb\Arsse\Db\PDOStatement {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\MySQL;
class Result extends \JKingWeb\Arsse\Db\AbstractResult {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\MySQL;
class Statement extends \JKingWeb\Arsse\Db\AbstractStatement {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
trait PDODriver {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
trait PDOError {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
class PDOResult extends AbstractResult {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
abstract class PDOStatement extends AbstractStatement {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\PostgreSQL;
trait Dispatch {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\PostgreSQL;
use JKingWeb\Arsse\Arsse;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\PostgreSQL;
use JKingWeb\Arsse\Arsse;

View file

@ -4,10 +4,11 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\PostgreSQL;
class PDOResult extends \JKingWeb\Arsse\Db\PDOResult {
// This method exists to transparent handle byte-array results
// This method exists to transparently handle byte-array results
public function valid() {
$this->cur = $this->set->fetch(\PDO::FETCH_ASSOC);

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\PostgreSQL;
use JKingWeb\Arsse\Db\Result;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\PostgreSQL;
class Result extends \JKingWeb\Arsse\Db\AbstractResult {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\PostgreSQL;
class Statement extends \JKingWeb\Arsse\Db\AbstractStatement {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
interface Result extends \Iterator {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
class ResultAggregate extends AbstractResult {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
class ResultEmpty extends AbstractResult {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
trait SQLState {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\SQLite3;
abstract class AbstractPDODriver extends Driver {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\SQLite3;
use JKingWeb\Arsse\Arsse;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\SQLite3;
use JKingWeb\Arsse\Db\Exception;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\SQLite3;
use JKingWeb\Arsse\Arsse;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\SQLite3;
class PDOStatement extends \JKingWeb\Arsse\Db\PDOStatement {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\SQLite3;
class Result extends \JKingWeb\Arsse\Db\AbstractResult {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db\SQLite3;
class Statement extends \JKingWeb\Arsse\Db\AbstractStatement {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
interface Statement {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Db;
class Transaction {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse;
class Exception extends AbstractException {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse;
class ExceptionFatal extends AbstractException {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse;
class ExceptionType extends AbstractException {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse;
class Factory {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse;
use JKingWeb\Arsse\Feed\Item;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Feed;
use GuzzleHttp\Exception\BadResponseException;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Feed;
class Item {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\ImportExport;
use JKingWeb\Arsse\Arsse;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\ImportExport;
class Exception extends \JKingWeb\Arsse\AbstractException {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\ImportExport;
use JKingWeb\Arsse\Arsse;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse;
class Lang {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Lang;
class Exception extends \JKingWeb\Arsse\AbstractException {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Misc;
abstract class Date {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Misc;
use Psr\Http\Message\MessageInterface;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Misc;
class Query extends QueryFilter {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Misc;
class QueryFilter {

View file

@ -4,13 +4,14 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Misc;
/**
* A collection of functions for manipulating URLs
*/
class URL {
/** Returns whether a URL is absolute i.e. has a scheme */
/** Returns whether a URL is absolute i.e. whether it has a scheme */
public static function absolute(string $url): bool {
return (bool) strlen((string) parse_url($url, \PHP_URL_SCHEME));
}

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Misc;
use JKingWeb\Arsse\ExceptionType;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse;
use JKingWeb\Arsse\Misc\URL;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\REST;
use JKingWeb\Arsse\Arsse;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\REST;
class Exception extends \JKingWeb\Arsse\AbstractException {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\REST;
class Exception501 extends \Exception {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\REST\Fever;
use JKingWeb\Arsse\Arsse;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\REST\Fever;
use JKingWeb\Arsse\Arsse;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\REST;
use Psr\Http\Message\ServerRequestInterface;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\REST\Miniflux;
use JKingWeb\Arsse\Misc\HTTP;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\REST\Miniflux;
use JKingWeb\Arsse\Arsse;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\REST\Miniflux;
use JKingWeb\Arsse\Arsse;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\REST\NextcloudNews;
use JKingWeb\Arsse\Arsse;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\REST\NextcloudNews;
use JKingWeb\Arsse\Misc\HTTP;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\REST\TinyTinyRSS;
use JKingWeb\Arsse\Feed;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\REST\TinyTinyRSS;
class Exception extends \Exception {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\REST\TinyTinyRSS;
use JKingWeb\Arsse\Arsse;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\REST\TinyTinyRSS;
use JKingWeb\Arsse\Context\Context;
@ -319,7 +320,7 @@ class Search {
$start = $day."T00:00:00 $tz";
$end = $day."T23:59:59 $tz";
$cc = $neg ? $c->not : $c;
// NOTE: TTRSS treats multiple positive dates as contradictory; we instead treat them as complimentary instead, because it makes more sense
// NOTE: TTRSS treats multiple positive dates as contradictory; we instead treat them as complimentary because this makes more sense
return $cc->modifiedRanges(array_merge($cc->modifiedRanges, [[$start, $end]]));
}

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Rule;
class Exception extends \JKingWeb\Arsse\AbstractException {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Rule;
abstract class Rule {

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse;
use JKingWeb\Arsse\Misc\Date;

View file

@ -4,6 +4,7 @@
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace JKingWeb\Arsse\Service;
use JKingWeb\Arsse\AbstractException;

Some files were not shown because too many files have changed in this diff Show more