mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 13:12:41 +00:00
CLI for OPML import, and proper exceptions
This commit is contained in:
parent
67492cd7ef
commit
b9821d925a
4 changed files with 38 additions and 16 deletions
|
@ -86,8 +86,14 @@ abstract class AbstractException extends \Exception {
|
|||
"Feed/Exception.xmlEntity" => 10512,
|
||||
"Feed/Exception.subscriptionNotFound" => 10521,
|
||||
"Feed/Exception.unsupportedFeedFormat" => 10522,
|
||||
"ImportExport/Exception.fileMissing" => 10601,
|
||||
"ImportExport/Exception.fileUnreadable" => 10603,
|
||||
"ImportExport/Exception.fileUnwritable" => 10604,
|
||||
"ImportExport/Exception.fileUncreatable" => 10605,
|
||||
"ImportExport/Exception.invalidSyntax" => 10611,
|
||||
"ImportExport/Exception.invalidSemantics" => 10612,
|
||||
"ImportExport/Exception.invalidFolderName" => 10613,
|
||||
"ImportExport/Exception.invalidFolderCopy" => 10614,
|
||||
];
|
||||
|
||||
public function __construct(string $msgID = "", $vars = null, \Throwable $e = null) {
|
||||
|
|
11
lib/CLI.php
11
lib/CLI.php
|
@ -24,7 +24,10 @@ Usage:
|
|||
arsse.php user unset-pass <username>
|
||||
[--oldpass=<pass>] [--fever]
|
||||
arsse.php user auth <username> <password> [--fever]
|
||||
arsse.php export <username> [<file>] [-f | --flat]
|
||||
arsse.php export <username> [<file>]
|
||||
[-f | --flat]
|
||||
arsse.php import <username> [<file>]
|
||||
[-f | --flat] [-r | --replace]
|
||||
arsse.php --version
|
||||
arsse.php --help | -h
|
||||
|
||||
|
@ -70,7 +73,7 @@ USAGE_TEXT;
|
|||
'help' => false,
|
||||
]);
|
||||
try {
|
||||
$cmd = $this->command(["--help", "--version", "daemon", "feed refresh", "feed refresh-all", "conf save-defaults", "user", "export"], $args);
|
||||
$cmd = $this->command(["--help", "--version", "daemon", "feed refresh", "feed refresh-all", "conf save-defaults", "user", "export", "import"], $args);
|
||||
if ($cmd && !in_array($cmd, ["--help", "--version", "conf save-defaults"])) {
|
||||
// only certain commands don't require configuration to be loaded
|
||||
$this->loadConf();
|
||||
|
@ -99,6 +102,10 @@ USAGE_TEXT;
|
|||
$u = $args['<username>'];
|
||||
$file = $this->resolveFile($args['<file>'], "w");
|
||||
return (int) !$this->getInstance(OPML::class)->exportFile($file, $u, $args['--flat']);
|
||||
case "import":
|
||||
$u = $args['<username>'];
|
||||
$file = $this->resolveFile($args['<file>'], "w");
|
||||
return (int) !$this->getInstance(OPML::class)->importFile($file, $u, $args['--flat'], $args['--replace']);
|
||||
}
|
||||
} catch (AbstractException $e) {
|
||||
$this->logError($e->getMessage());
|
||||
|
|
|
@ -19,14 +19,14 @@ class OPML {
|
|||
foreach ($folders as $f) {
|
||||
// check to make sure folder names are all valid
|
||||
if (!strlen(trim($f['name']))) {
|
||||
throw new \Exception;
|
||||
throw new Exception("invalidFolderName");
|
||||
}
|
||||
// check for duplicates
|
||||
if (!isset($folderMap[$f['parent']])) {
|
||||
$folderMap[$f['parent']] = [];
|
||||
}
|
||||
if (isset($folderMap[$f['parent']][$f['name']])) {
|
||||
throw new \Exception;
|
||||
throw new Exception("invalidFolderCopy");
|
||||
} else {
|
||||
$folderMap[$f['parent']][$f['name']] = true;
|
||||
}
|
||||
|
@ -142,12 +142,13 @@ class OPML {
|
|||
$d = new \DOMDocument;
|
||||
if (!@$d->loadXML($opml)) {
|
||||
// not a valid XML document
|
||||
throw new \Exception;
|
||||
$err = libxml_get_last_error();
|
||||
throw new Exception("invalidSyntax", ['line' => $err->line, 'column' => $err->column]);
|
||||
}
|
||||
$body = $d->getElementsByTagName("body");
|
||||
if ($d->documentElement->nodeName !== "opml" || !$body->length || $body->item(0)->parentNode != $d->documentElement) {
|
||||
// not a valid OPML document
|
||||
throw new \Exception;
|
||||
throw new Exception("invalidSemantics", ['type' => "OPML"]);
|
||||
}
|
||||
$body = $body->item(0);
|
||||
$folders = [];
|
||||
|
@ -268,4 +269,14 @@ class OPML {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function imortFile(string $file, string $user, bool $flat = false, bool $replace): bool {
|
||||
$data = @file_get_contents($file);
|
||||
if ($data === false) {
|
||||
// if it fails throw an exception
|
||||
$err = file_exists($file) ? "fileUnreadable" : "fileMissing";
|
||||
throw new Exception($err, ['file' => $file, 'format' => str_replace(__NAMESPACE__."\\", "", __CLASS__)]);
|
||||
}
|
||||
return $this->import($user, $data, $flat, $replace);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -155,14 +155,12 @@ return [
|
|||
'Exception.JKingWeb/Arsse/Feed/Exception.xmlEntity' => 'Refused to parse feed "{url}" because it contains an XXE attack',
|
||||
'Exception.JKingWeb/Arsse/Feed/Exception.subscriptionNotFound' => 'Unable to find a feed at location "{url}"',
|
||||
'Exception.JKingWeb/Arsse/Feed/Exception.unsupportedFeedFormat' => 'Feed "{url}" is of an unsupported format',
|
||||
'Exception.JKingWeb/Arsse/ImportExport/Exception.fileUncreatable' =>
|
||||
'Insufficient permissions to write {type, select,
|
||||
OPML {OPML}
|
||||
other {"{type}"}
|
||||
} export to file "{file}"',
|
||||
'Exception.JKingWeb/Arsse/ImportExport/Exception.fileUnwritable' =>
|
||||
'Insufficient permissions to write {type, select,
|
||||
OPML {OPML}
|
||||
other {"{type}"}
|
||||
} export to existing file "{file}"',
|
||||
'Exception.JKingWeb/Arsse/ImportExport/Exception.fileMissing' => 'Import {type} file "{file}" does not exist',
|
||||
'Exception.JKingWeb/Arsse/ImportExport/Exception.fileUnreadable' => 'Insufficient permissions to read {type} file "{file}" for import',
|
||||
'Exception.JKingWeb/Arsse/ImportExport/Exception.fileUncreatable' => 'Insufficient permissions to write {type} export to file "{file}"',
|
||||
'Exception.JKingWeb/Arsse/ImportExport/Exception.fileUnwritable' => 'Insufficient permissions to write {type} export to existing file "{file}"',
|
||||
'Exception.JKingWeb/Arsse/ImportExport/Exception.invalidSyntax' => 'Input data syntax error at line {line}, column {column}',
|
||||
'Exception.JKingWeb/Arsse/ImportExport/Exception.invalidSemantics' => 'Input data is not valid {type} data',
|
||||
'Exception.JKingWeb/Arsse/ImportExport/Exception.invalidFolderName' => 'Input data contains an invalid folder name',
|
||||
'Exception.JKingWeb/Arsse/ImportExport/Exception.invalidFolderCopy' => 'Input data contains multiple folders of the same name under the same parent',
|
||||
];
|
||||
|
|
Loading…
Reference in a new issue