Browse Source

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
microsub
J. King 7 years ago
parent
commit
cc2296522c
  1. 1
      .gitignore
  2. 4
      README.md
  3. 7
      arsse.php
  4. 12
      dist/nginx-fcgi.conf
  5. 24
      dist/nginx.conf
  6. 23
      lib/CLI.php
  7. 2
      lib/Conf.php
  8. 4
      lib/Db/SQLite3/Driver.php
  9. 2
      lib/REST/NextCloudNews/V1_2.php
  10. 8
      tests/Conf/TestConf.php
  11. 39
      tests/Db/SQLite3/TestDbUpdateSQLite3.php
  12. 2
      www/arsse.php

1
.gitignore

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

4
README.md

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

7
arsse.php

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

12
dist/nginx-fcgi.conf

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

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

23
lib/CLI.php

@ -11,11 +11,13 @@ class CLI {
Usage:
$prog daemon
$prog feed refresh <n>
$prog conf save-defaults <file>
$prog --version
$prog --help | -h
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;
}
@ -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 {
// act on command line
if(is_null($args)) {
$args = $this->args;
}
if($args['daemon']) {
$this->loadConf();
return $this->daemon();
} elseif($args['feed'] && $args['refresh']) {
} else if($args['feed'] && $args['refresh']) {
$this->loadConf();
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 {
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);
}
}

2
lib/Conf.php

@ -13,8 +13,6 @@ class Conf {
/** @var string Class of the database driver in use (SQLite3 by default) */
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 */
public $dbAutoUpdate = true;
/** @var string Full path and file name of SQLite database (if using SQLite) */

4
lib/Db/SQLite3/Driver.php

@ -73,7 +73,7 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
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();
if(!Arsse::$conf->dbAutoUpdate) {
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()]);
}
$sep = \DIRECTORY_SEPARATOR;
$path = Arsse::$conf->dbSchemaBase.$sep."SQLite3".$sep;
$path = ($basePath ?? \JKingWeb\Arsse\BASE."sql").$sep."SQLite3".$sep;
// lock the database
$this->savepointCreate(true);
for($a = $this->schemaVersion(); $a < $to; $a++) {

2
lib/REST/NextCloudNews/V1_2.php

@ -634,7 +634,7 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
}
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
if(isset($data['avatar'])) {
$avatar = [

8
tests/Conf/TestConf.php

@ -93,10 +93,10 @@ class TestConf extends Test\AbstractTest {
function testExportToArray() {
$conf = new Conf();
$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
$exp = [
'dbSchemaBase' => "schema",
'dbSQLite3File' => "test.db",
'someCustomProperty' => "Look at me!",
];
$this->assertSame($exp, $conf->export());
@ -110,12 +110,12 @@ class TestConf extends Test\AbstractTest {
function testExportToFile() {
$conf = new Conf();
$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->exportFile(self::$path."confNotArray");
$arr = (include self::$path."confNotArray");
$exp = [
'dbSchemaBase' => "schema",
'dbSQLite3File' => "test.db",
'someCustomProperty' => "Look at me!",
];
$this->assertSame($exp, $arr);

39
tests/Db/SQLite3/TestDbUpdateSQLite3.php

@ -26,10 +26,10 @@ class TestDbUpdateSQLite3 extends Test\AbstractTest {
$conf = new Conf();
}
$conf->dbDriver = Db\SQLite3\Driver::class;
$conf->dbSchemaBase = $this->vfs->url();
$conf->dbSQLite3File = ":memory:";
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);
}
@ -42,40 +42,40 @@ class TestDbUpdateSQLite3 extends Test\AbstractTest {
function testLoadMissingFile() {
$this->assertException("updateFileMissing", "Db");
$this->drv->schemaUpdate(1);
$this->drv->schemaUpdate(1, $this->base);
}
function testLoadUnreadableFile() {
touch($this->base."0.sql");
chmod($this->base."0.sql", 0000);
touch($this->path."0.sql");
chmod($this->path."0.sql", 0000);
$this->assertException("updateFileUnreadable", "Db");
$this->drv->schemaUpdate(1);
$this->drv->schemaUpdate(1, $this->base);
}
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->drv->schemaUpdate(1);
$this->drv->schemaUpdate(1, $this->base);
}
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->drv->schemaUpdate(1);
$this->drv->schemaUpdate(1, $this->base);
}
function testLoadCorrectFile() {
file_put_contents($this->base."0.sql", self::MINIMAL1);
$this->drv->schemaUpdate(1);
file_put_contents($this->path."0.sql", self::MINIMAL1);
$this->drv->schemaUpdate(1, $this->base);
$this->assertEquals(1, $this->drv->schemaVersion());
}
function testPerformPartialUpdate() {
file_put_contents($this->base."0.sql", self::MINIMAL1);
file_put_contents($this->base."1.sql", "");
file_put_contents($this->path."0.sql", self::MINIMAL1);
file_put_contents($this->path."1.sql", "");
$this->assertException("updateFileIncomplete", "Db");
try {
$this->drv->schemaUpdate(2);
$this->drv->schemaUpdate(2, $this->base);
} catch(Exception $e) {
$this->assertEquals(1, $this->drv->schemaVersion());
throw $e;
@ -83,14 +83,13 @@ class TestDbUpdateSQLite3 extends Test\AbstractTest {
}
function testPerformSequentialUpdate() {
file_put_contents($this->base."0.sql", self::MINIMAL1);
file_put_contents($this->base."1.sql", self::MINIMAL2);
$this->drv->schemaUpdate(2);
file_put_contents($this->path."0.sql", self::MINIMAL1);
file_put_contents($this->path."1.sql", self::MINIMAL2);
$this->drv->schemaUpdate(2, $this->base);
$this->assertEquals(2, $this->drv->schemaVersion());
}
function testPerformActualUpdate() {
Arsse::$conf->dbSchemaBase = (new Conf())->dbSchemaBase;
$this->drv->schemaUpdate(Database::SCHEMA_VERSION);
$this->assertEquals(Database::SCHEMA_VERSION, $this->drv->schemaVersion());
}
@ -106,6 +105,6 @@ class TestDbUpdateSQLite3 extends Test\AbstractTest {
function testDeclineDowngrade() {
$this->assertException("updateTooNew", "Db");
$this->drv->schemaUpdate(-1);
$this->drv->schemaUpdate(-1, $this->base);
}
}

2
www/arsse.php

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