initial commit
This commit is contained in:
177
src/API/PhotoPrism.php
Normal file
177
src/API/PhotoPrism.php
Normal file
@ -0,0 +1,177 @@
|
||||
<?php
|
||||
|
||||
namespace PhotoPrismUpload\API;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Handler\RotatingFileHandler;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use PhotoPrismUpload\Exceptions\NetworkException;
|
||||
use PhotoPrismUpload\Exceptions\AuthenticationException;
|
||||
use PhotoPrismUpload\Entities\Album;
|
||||
|
||||
class PhotoPrism
|
||||
{
|
||||
protected string $base_url = 'https://photos.phlaym.net';
|
||||
protected string $api_url = '';
|
||||
protected ?string $session_id = null;
|
||||
protected array $config;
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
public function __construct(
|
||||
array $config,
|
||||
?string $log_path = null
|
||||
) {
|
||||
$this->api_url = $this->base_url.'/api/v1';
|
||||
$this->config = $config;
|
||||
$this->logger = new Logger('PhotoPrismUpload');
|
||||
if (empty($log_path)) {
|
||||
$log_path = __DIR__.'/logs/log.log';
|
||||
}
|
||||
$handler = new RotatingFileHandler($log_path, 5, Logger::DEBUG, true);
|
||||
$this->logger->pushHandler($handler);
|
||||
if (isset($_SESSION['pp_sessionid'])) {
|
||||
$this->session_id = $_SESSION['pp_sessionid'];
|
||||
}
|
||||
}
|
||||
|
||||
private function parseHeaders(string $response): array
|
||||
{
|
||||
$response = explode("\r\n\r\n", $response, 2);
|
||||
$headers = $response[0];
|
||||
if ($headers === 'HTTP/1.1 100 Continue') {
|
||||
$response = explode("\r\n\r\n", $response[1], 2);
|
||||
$headers = $response[0];
|
||||
}
|
||||
if (isset($response[1])) {
|
||||
$content = $response[1];
|
||||
} else {
|
||||
$content = '';
|
||||
}
|
||||
// this is not a good way to parse http headers
|
||||
// it will not (for example) take into account multiline headers
|
||||
// but what we're looking for is pretty basic, so we can ignore those shortcomings
|
||||
$response_headers = explode("\r\n", $headers);
|
||||
$header_arr = [];
|
||||
foreach ($response_headers as $header) {
|
||||
$header = explode(': ', $header, 2);
|
||||
if (count($header) < 2) {
|
||||
continue;
|
||||
}
|
||||
list($k,$v) = $header;
|
||||
$header_arr[$k] = $v;
|
||||
}
|
||||
return ['headers' => $header_arr, 'content' => $content];
|
||||
}
|
||||
|
||||
private function makeRequest(
|
||||
string $method,
|
||||
string $path,
|
||||
array $data = [],
|
||||
string $content_type = 'application/json'
|
||||
): string {
|
||||
$url = $this->api_url.$path;
|
||||
$method = strtolower($method);
|
||||
$query_data = [];
|
||||
$headers = [];
|
||||
$result = null;
|
||||
try {
|
||||
if (is_array($data) && $method !== 'post-raw') {
|
||||
$query_data = $content_type === 'application/json' ? json_encode($data) : http_build_query($data);
|
||||
}
|
||||
|
||||
$ch = curl_init();
|
||||
if ($method === 'get' && !empty($query_data)) {
|
||||
$url .= '?'.$query_data;
|
||||
} else {
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $query_data);
|
||||
}
|
||||
if ($method !== 'get') {
|
||||
$headers[] = 'Content-Type: '.$content_type;
|
||||
}
|
||||
|
||||
if (!empty($this->session_id)) {
|
||||
$headers[] = 'X-Session-Id: ' . $this->session_id;
|
||||
}
|
||||
$this->logger->info($method .' request to ' . $url);
|
||||
$this->logger->debug('Headers ' . json_encode($headers));
|
||||
$this->logger->debug('postfields data ' . json_encode($data));
|
||||
$this->logger->debug('postfields ' . $query_data);
|
||||
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_POST, $method !== 'get');
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
|
||||
$output = curl_exec($ch);
|
||||
|
||||
$request = curl_getinfo($ch, CURLINFO_HEADER_OUT);
|
||||
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
|
||||
if ($output === false) {
|
||||
throw new NetworkException("Error sending request to " . $url, 0);
|
||||
}
|
||||
if (empty($output) || $output === false) {
|
||||
$e = new NetworkException("No answer from" . $url, 0);
|
||||
$this->logger->error("Error sending request", ['Exception' => $e]);
|
||||
throw $e;
|
||||
}
|
||||
if ($http_status === 0) {
|
||||
throw new NetworkException('Unable to connect to API ' . $url);
|
||||
}
|
||||
if ($http_status >= 400) {
|
||||
throw new NetworkException('Invalid response ' . $url . ': ' . $http_status);
|
||||
}
|
||||
$result = $this->parseHeaders($output);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error("Error sending request", ['Exception' => $e]);
|
||||
throw new NetworkException("Error sending request to " . $url, 0, $e);
|
||||
}
|
||||
return $result['content'];
|
||||
}
|
||||
|
||||
public function login(bool $force = false)
|
||||
{
|
||||
if (!empty($this->session_id) && !$force) {
|
||||
$this->logger->info('Skipping login, already logged in');
|
||||
return;
|
||||
}
|
||||
$data = [
|
||||
'username' => $this->config['username'],
|
||||
'password' => $this->config['password'],
|
||||
];
|
||||
$res = $this->makeRequest('POST', '/session', $data);
|
||||
$this->logger->info('Login result: ' . $res);
|
||||
$response = json_decode($res, true);
|
||||
if (!empty($response['error'])) {
|
||||
throw new AuthenticationException($response['error']);
|
||||
}
|
||||
$this->session_id = $response['id'];
|
||||
$_SESSION['pp_sessionid'] = $this->session_id;
|
||||
$this->logger->debug('Session ID: ' . $this->session_id);
|
||||
}
|
||||
|
||||
public function getAlbums(int $count = 1000, int $offset = 0): array
|
||||
{
|
||||
$data = [
|
||||
'count' => $count,
|
||||
'offset' => $offset,
|
||||
'type' => 'album'
|
||||
];
|
||||
$res = $this->makeRequest('GET', '/albums', $data, 'text/plain');
|
||||
$response = json_decode($res, true);
|
||||
if (!empty($response['error'])) {
|
||||
throw new NetworkException($response['error']);
|
||||
}
|
||||
$albums = array_map(
|
||||
function ($entry) {
|
||||
return new Album($entry);
|
||||
},
|
||||
$response
|
||||
);
|
||||
$this->logger->debug('Albums' . json_encode($albums));
|
||||
return $albums;
|
||||
}
|
||||
|
||||
#https://photos.phlaym.net/api/v1/albums?q=&count=1000&offset=0&type=album
|
||||
}
|
Reference in New Issue
Block a user