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

More changes in anticipation of a release:

- Don't load a config (and possibly create a database) in CLI if a configuration is not required
- Removed the 'dbSchemaBase' config option, which is really a testing hack
- Added sample Nginx configuration
- Fixed bug in REST handler
- Readme still needs work
This commit is contained in:
J. King 2017-08-19 23:56:32 -04:00
parent bd7fea1bee
commit cc2296522c
12 changed files with 86 additions and 42 deletions

1
.gitignore vendored
View file

@ -5,6 +5,7 @@ vendor/
documentation/ documentation/
tests/coverage tests/coverage
arsse.db* arsse.db*
config.php
# Windows image file caches # Windows image file caches
Thumbs.db Thumbs.db

View file

@ -37,9 +37,7 @@ sudo systemctl start arsse
### Configuring the Web server ### Configuring the Web server
A sample configuration file for Nginx can be found in `arsse/dist/nginx.conf` Sample configuration parameters for Nginx can be found in `arsse/dist/nginx.conf` and `arsse/dist/nginx-fcgi.conf`.
FIXME: stub
## Installation from source ## Installation from source

View file

@ -5,12 +5,7 @@ require_once __DIR__.DIRECTORY_SEPARATOR."bootstrap.php";
if(\PHP_SAPI=="cli") { if(\PHP_SAPI=="cli") {
// initialize the CLI; this automatically handles --help and --version // initialize the CLI; this automatically handles --help and --version
$cli = new CLI; $cli = new CLI;
// load configuration // handle other CLI requests; some do not require configuration
Arsse::load(new Conf());
if(file_exists(BASE."config.php")) {
Arsse::$conf->importFile(BASE."config.php");
}
// handle CLI requests
$cli->dispatch(); $cli->dispatch();
} else { } else {
// load configuration // load configuration

12
dist/nginx-fcgi.conf vendored Normal file
View file

@ -0,0 +1,12 @@
fastcgi_pass php; # PHP is assumed to already be configured for FastCGI operation
fastcgi_pass_header Authorization; # required if the Arsse is to perform its own HTTP authentication
fastcgi_pass_request_body on;
fastcgi_pass_request_headers on;
fastcgi_intercept_errors off;
fastcgi_buffering off;
fastcgi_param SCRIPT_FILENAME /usr/share/arsse/arsse.php;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param HTTPS $https if_not_empty;

24
dist/nginx.conf vendored Normal file
View file

@ -0,0 +1,24 @@
server {
server_name news.example.com;
listen 80; # adding HTTPS configuration is highly recommended
# redirect to HTTPS, if desired
#if ($https != "on") {rewrite ^ https://$host$request_uri;}
# the userPreAuth setting should be enabled if the Web server is handling authentication
#auth_basic "Advanced RSS Environment";
root /usr/share/arsse/www;
index index.html;
location / {
try_files $uri $uri/ =404;
}
location /index.php/apps/news/api {
include /usr/share/arsse/dist/nginx-fcgi.conf;
location ~ ^/index\.php/apps/news/api/?$ {
auth_basic off; # the NextCloud News API version enumerator does not require authentication
include /usr/share/arsse/dist/nginx-fcgi.conf;
}
}
}

View file

@ -11,11 +11,13 @@ class CLI {
Usage: Usage:
$prog daemon $prog daemon
$prog feed refresh <n> $prog feed refresh <n>
$prog conf save-defaults <file>
$prog --version $prog --version
$prog --help | -h $prog --help | -h
The Arsse command-line interface currently allows you to start the refresh The Arsse command-line interface currently allows you to start the refresh
daemon or refresh a specific feed by numeric ID. daemon, refresh a specific feed by numeric ID, or save default configuration
to a sample file.
USAGE_TEXT; USAGE_TEXT;
} }
@ -30,15 +32,28 @@ USAGE_TEXT;
]); ]);
} }
protected function loadConf(): bool {
// FIXME: this should be a method of the Conf class
Arsse::load(new Conf());
if(file_exists(BASE."config.php")) {
Arsse::$conf->importFile(BASE."config.php");
}
return true;
}
function dispatch(array $args = null): int { function dispatch(array $args = null): int {
// act on command line // act on command line
if(is_null($args)) { if(is_null($args)) {
$args = $this->args; $args = $this->args;
} }
if($args['daemon']) { if($args['daemon']) {
$this->loadConf();
return $this->daemon(); return $this->daemon();
} else if($args['feed'] && $args['refresh']) { } else if($args['feed'] && $args['refresh']) {
$this->loadConf();
return $this->feedRefresh((int) $args['<n>']); return $this->feedRefresh((int) $args['<n>']);
} else if($args['conf'] && $args['save-defaults']) {
return $this->confSaveDefaults($args['<file>']);
} }
} }
@ -50,4 +65,8 @@ USAGE_TEXT;
protected function feedRefresh(int $id): int { protected function feedRefresh(int $id): int {
return (int) !Arsse::$db->feedUpdate($id); // FIXME: exception error codes should be returned here return (int) !Arsse::$db->feedUpdate($id); // FIXME: exception error codes should be returned here
} }
protected function confSaveDefaults($file): int {
return (int) !(new Conf)->exportFile($file, true);
}
} }

View file

@ -13,8 +13,6 @@ class Conf {
/** @var string Class of the database driver in use (SQLite3 by default) */ /** @var string Class of the database driver in use (SQLite3 by default) */
public $dbDriver = Db\SQLite3\Driver::class; public $dbDriver = Db\SQLite3\Driver::class;
/** @var string Base path to database schema files */
public $dbSchemaBase = BASE.'sql';
/** @var boolean Whether to attempt to automatically update the database when updated to a new version with schema changes */ /** @var boolean Whether to attempt to automatically update the database when updated to a new version with schema changes */
public $dbAutoUpdate = true; public $dbAutoUpdate = true;
/** @var string Full path and file name of SQLite database (if using SQLite) */ /** @var string Full path and file name of SQLite database (if using SQLite) */

View file

@ -73,7 +73,7 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
return $this->query("PRAGMA user_version")->getValue(); return $this->query("PRAGMA user_version")->getValue();
} }
public function schemaUpdate(int $to): bool { public function schemaUpdate(int $to, string $basePath = null): bool {
$ver = $this->schemaVersion(); $ver = $this->schemaVersion();
if(!Arsse::$conf->dbAutoUpdate) { if(!Arsse::$conf->dbAutoUpdate) {
throw new Exception("updateManual", ['version' => $ver, 'driver_name' => $this->driverName()]); throw new Exception("updateManual", ['version' => $ver, 'driver_name' => $this->driverName()]);
@ -81,7 +81,7 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
throw new Exception("updateTooNew", ['difference' => ($ver - $to), 'current' => $ver, 'target' => $to, 'driver_name' => $this->driverName()]); throw new Exception("updateTooNew", ['difference' => ($ver - $to), 'current' => $ver, 'target' => $to, 'driver_name' => $this->driverName()]);
} }
$sep = \DIRECTORY_SEPARATOR; $sep = \DIRECTORY_SEPARATOR;
$path = Arsse::$conf->dbSchemaBase.$sep."SQLite3".$sep; $path = ($basePath ?? \JKingWeb\Arsse\BASE."sql").$sep."SQLite3".$sep;
// lock the database // lock the database
$this->savepointCreate(true); $this->savepointCreate(true);
for($a = $this->schemaVersion(); $a < $to; $a++) { for($a = $this->schemaVersion(); $a < $to; $a++) {

View file

@ -634,7 +634,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
} }
protected function userStatus(array $url, array $data): Response { protected function userStatus(array $url, array $data): Response {
$data = Arsse::$user::propertiesGet(Arsse::$user->id, true); $data = Arsse::$user->propertiesGet(Arsse::$user->id, true);
// construct the avatar structure, if an image is available // construct the avatar structure, if an image is available
if(isset($data['avatar'])) { if(isset($data['avatar'])) {
$avatar = [ $avatar = [

View file

@ -93,10 +93,10 @@ class TestConf extends Test\AbstractTest {
function testExportToArray() { function testExportToArray() {
$conf = new Conf(); $conf = new Conf();
$conf->lang = ["en", "fr"]; // should not be exported: not scalar $conf->lang = ["en", "fr"]; // should not be exported: not scalar
$conf->dbSchemaBase = "schema"; // should be exported: value changed $conf->dbSQLite3File = "test.db"; // should be exported: value changed
$conf->someCustomProperty = "Look at me!"; // should be exported: unknown property $conf->someCustomProperty = "Look at me!"; // should be exported: unknown property
$exp = [ $exp = [
'dbSchemaBase' => "schema", 'dbSQLite3File' => "test.db",
'someCustomProperty' => "Look at me!", 'someCustomProperty' => "Look at me!",
]; ];
$this->assertSame($exp, $conf->export()); $this->assertSame($exp, $conf->export());
@ -110,12 +110,12 @@ class TestConf extends Test\AbstractTest {
function testExportToFile() { function testExportToFile() {
$conf = new Conf(); $conf = new Conf();
$conf->lang = ["en", "fr"]; // should not be exported: not scalar $conf->lang = ["en", "fr"]; // should not be exported: not scalar
$conf->dbSchemaBase = "schema"; // should be exported: value changed $conf->dbSQLite3File = "test.db"; // should be exported: value changed
$conf->someCustomProperty = "Look at me!"; // should be exported: unknown property $conf->someCustomProperty = "Look at me!"; // should be exported: unknown property
$conf->exportFile(self::$path."confNotArray"); $conf->exportFile(self::$path."confNotArray");
$arr = (include self::$path."confNotArray"); $arr = (include self::$path."confNotArray");
$exp = [ $exp = [
'dbSchemaBase' => "schema", 'dbSQLite3File' => "test.db",
'someCustomProperty' => "Look at me!", 'someCustomProperty' => "Look at me!",
]; ];
$this->assertSame($exp, $arr); $this->assertSame($exp, $arr);

View file

@ -26,10 +26,10 @@ class TestDbUpdateSQLite3 extends Test\AbstractTest {
$conf = new Conf(); $conf = new Conf();
} }
$conf->dbDriver = Db\SQLite3\Driver::class; $conf->dbDriver = Db\SQLite3\Driver::class;
$conf->dbSchemaBase = $this->vfs->url();
$conf->dbSQLite3File = ":memory:"; $conf->dbSQLite3File = ":memory:";
Arsse::$conf = $conf; Arsse::$conf = $conf;
$this->base = $this->vfs->url()."/SQLite3/"; $this->base = $this->vfs->url();
$this->path = $this->base."/SQLite3/";
$this->drv = new Db\SQLite3\Driver(true); $this->drv = new Db\SQLite3\Driver(true);
} }
@ -42,40 +42,40 @@ class TestDbUpdateSQLite3 extends Test\AbstractTest {
function testLoadMissingFile() { function testLoadMissingFile() {
$this->assertException("updateFileMissing", "Db"); $this->assertException("updateFileMissing", "Db");
$this->drv->schemaUpdate(1); $this->drv->schemaUpdate(1, $this->base);
} }
function testLoadUnreadableFile() { function testLoadUnreadableFile() {
touch($this->base."0.sql"); touch($this->path."0.sql");
chmod($this->base."0.sql", 0000); chmod($this->path."0.sql", 0000);
$this->assertException("updateFileUnreadable", "Db"); $this->assertException("updateFileUnreadable", "Db");
$this->drv->schemaUpdate(1); $this->drv->schemaUpdate(1, $this->base);
} }
function testLoadCorruptFile() { function testLoadCorruptFile() {
file_put_contents($this->base."0.sql", "This is a corrupt file"); file_put_contents($this->path."0.sql", "This is a corrupt file");
$this->assertException("updateFileError", "Db"); $this->assertException("updateFileError", "Db");
$this->drv->schemaUpdate(1); $this->drv->schemaUpdate(1, $this->base);
} }
function testLoadIncompleteFile() { function testLoadIncompleteFile() {
file_put_contents($this->base."0.sql", "create table arsse_meta(key text primary key not null, value text);"); file_put_contents($this->path."0.sql", "create table arsse_meta(key text primary key not null, value text);");
$this->assertException("updateFileIncomplete", "Db"); $this->assertException("updateFileIncomplete", "Db");
$this->drv->schemaUpdate(1); $this->drv->schemaUpdate(1, $this->base);
} }
function testLoadCorrectFile() { function testLoadCorrectFile() {
file_put_contents($this->base."0.sql", self::MINIMAL1); file_put_contents($this->path."0.sql", self::MINIMAL1);
$this->drv->schemaUpdate(1); $this->drv->schemaUpdate(1, $this->base);
$this->assertEquals(1, $this->drv->schemaVersion()); $this->assertEquals(1, $this->drv->schemaVersion());
} }
function testPerformPartialUpdate() { function testPerformPartialUpdate() {
file_put_contents($this->base."0.sql", self::MINIMAL1); file_put_contents($this->path."0.sql", self::MINIMAL1);
file_put_contents($this->base."1.sql", ""); file_put_contents($this->path."1.sql", "");
$this->assertException("updateFileIncomplete", "Db"); $this->assertException("updateFileIncomplete", "Db");
try { try {
$this->drv->schemaUpdate(2); $this->drv->schemaUpdate(2, $this->base);
} catch(Exception $e) { } catch(Exception $e) {
$this->assertEquals(1, $this->drv->schemaVersion()); $this->assertEquals(1, $this->drv->schemaVersion());
throw $e; throw $e;
@ -83,14 +83,13 @@ class TestDbUpdateSQLite3 extends Test\AbstractTest {
} }
function testPerformSequentialUpdate() { function testPerformSequentialUpdate() {
file_put_contents($this->base."0.sql", self::MINIMAL1); file_put_contents($this->path."0.sql", self::MINIMAL1);
file_put_contents($this->base."1.sql", self::MINIMAL2); file_put_contents($this->path."1.sql", self::MINIMAL2);
$this->drv->schemaUpdate(2); $this->drv->schemaUpdate(2, $this->base);
$this->assertEquals(2, $this->drv->schemaVersion()); $this->assertEquals(2, $this->drv->schemaVersion());
} }
function testPerformActualUpdate() { function testPerformActualUpdate() {
Arsse::$conf->dbSchemaBase = (new Conf())->dbSchemaBase;
$this->drv->schemaUpdate(Database::SCHEMA_VERSION); $this->drv->schemaUpdate(Database::SCHEMA_VERSION);
$this->assertEquals(Database::SCHEMA_VERSION, $this->drv->schemaVersion()); $this->assertEquals(Database::SCHEMA_VERSION, $this->drv->schemaVersion());
} }
@ -106,6 +105,6 @@ class TestDbUpdateSQLite3 extends Test\AbstractTest {
function testDeclineDowngrade() { function testDeclineDowngrade() {
$this->assertException("updateTooNew", "Db"); $this->assertException("updateTooNew", "Db");
$this->drv->schemaUpdate(-1); $this->drv->schemaUpdate(-1, $this->base);
} }
} }

View file

@ -1,2 +0,0 @@
<?php
require_once __DIR__.DIRECTORY_SEPARATOR."..".DIRECTORY_SEPARATOR."arsse.php";