kopia lustrzana https://github.com/nextcloud/social
Merge pull request #1586 from nextcloud/enh/noid/media_attachment-in-stream
add media_attachments to apipull/1611/head
commit
d251806d55
|
@ -18,7 +18,7 @@
|
|||
|
||||
**🕸 Open standards:** We use the established ActivityPub standard!
|
||||
]]></description>
|
||||
<version>0.6.0-beta1</version>
|
||||
<version>0.6.0-beta2</version>
|
||||
<licence>agpl</licence>
|
||||
<author mail="maxence@artificial-owl.com" homepage="https://artificial-owl.com/">Maxence Lange</author>
|
||||
<author mail="jus@bitgrid.net">Julius Härtl</author>
|
||||
|
|
|
@ -83,8 +83,13 @@ return [
|
|||
['name' => 'Api#favourites', 'url' => '/api/v1/favourites/', 'verb' => 'GET'],
|
||||
['name' => 'Api#notifications', 'url' => '/api/v1/notifications', 'verb' => 'GET'],
|
||||
['name' => 'Api#tag', 'url' => '/api/v1/timelines/tag/{hashtag}', 'verb' => 'GET'],
|
||||
['name' => 'Api#mediaNew', 'url' => '/api/v1/media', 'verb' => 'POST'],
|
||||
['name' => 'Api#mediaGet', 'url' => '/api/v1/media/{nid}', 'verb' => 'GET'],
|
||||
['name' => 'Api#mediaOpen', 'url' => '/media/{uuid}', 'verb' => 'GET'],
|
||||
|
||||
['name' => 'Api#statusNew', 'url' => '/api/v1/statuses', 'verb' => 'POST'],
|
||||
['name' => 'Api#statusGet', 'url' => '/api/v1/statuses/{nid}', 'verb' => 'GET'],
|
||||
['name' => 'Api#statusContext', 'url' => '/api/v1/statuses/{nid}/context', 'verb' => 'GET'],
|
||||
['name' => 'Api#accountStatuses', 'url' => '/api/v1/accounts/{account}/statuses', 'verb' => 'GET'],
|
||||
|
||||
// Api for local front-end
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
},
|
||||
"require": {
|
||||
"gumlet/php-image-resize": "2.0.*",
|
||||
"friendica/json-ld": "^1.0"
|
||||
"friendica/json-ld": "^1.0",
|
||||
"kornrunner/blurhash": "^1.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5",
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "bed6d4ecfb5f6fb104979f9c8eeff3f1",
|
||||
"content-hash": "4babe68311d0661c2c9135eb8882265b",
|
||||
"packages": [
|
||||
{
|
||||
"name": "friendica/json-ld",
|
||||
"version": "1.1.1",
|
||||
"version": "1.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://git.friendi.ca/friendica/php-json-ld",
|
||||
"reference": "ca3916d10d2ad9073b3b1eae383978dbe828e1e1"
|
||||
"reference": "5f6ea87b261d346e57f03457ae906e6835f0205f"
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
|
@ -48,7 +48,7 @@
|
|||
"Semantic Web",
|
||||
"jsonld"
|
||||
],
|
||||
"time": "2018-10-08T20:41:00+00:00"
|
||||
"time": "2023-02-20T21:56:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "gumlet/php-image-resize",
|
||||
|
@ -108,6 +108,54 @@
|
|||
"source": "https://github.com/gumlet/php-image-resize/tree/2.0.3"
|
||||
},
|
||||
"time": "2022-06-21T16:20:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "kornrunner/blurhash",
|
||||
"version": "v1.2.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/kornrunner/php-blurhash.git",
|
||||
"reference": "bc8a4596cb0a49874f0158696a382ab3933fefe4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/kornrunner/php-blurhash/zipball/bc8a4596cb0a49874f0158696a382ab3933fefe4",
|
||||
"reference": "bc8a4596cb0a49874f0158696a382ab3933fefe4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-gd": "*",
|
||||
"ocramius/package-versions": "^1.4|^2.0",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpunit/phpunit": "^9",
|
||||
"vimeo/psalm": "^4.3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"kornrunner\\Blurhash\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Boris Momčilović",
|
||||
"email": "boris.momcilovic@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Pure PHP implementation of Blurhash",
|
||||
"homepage": "https://github.com/kornrunner/php-blurhash",
|
||||
"support": {
|
||||
"issues": "https://github.com/kornrunner/php-blurhash/issues",
|
||||
"source": "https://github.com/kornrunner/php-blurhash.git"
|
||||
},
|
||||
"time": "2022-07-13T19:38:39+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
@ -607,30 +655,30 @@
|
|||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
"version": "1.14.2",
|
||||
"version": "2.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/annotations.git",
|
||||
"reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b"
|
||||
"reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/annotations/zipball/ad785217c1e9555a7d6c6c8c9f406395a5e2882b",
|
||||
"reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b",
|
||||
"url": "https://api.github.com/repos/doctrine/annotations/zipball/e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f",
|
||||
"reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/lexer": "^1 || ^2",
|
||||
"doctrine/lexer": "^2 || ^3",
|
||||
"ext-tokenizer": "*",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"php": "^7.2 || ^8.0",
|
||||
"psr/cache": "^1 || ^2 || ^3"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/cache": "^1.11 || ^2.0",
|
||||
"doctrine/coding-standard": "^9 || ^10",
|
||||
"phpstan/phpstan": "~1.4.10 || ^1.8.0",
|
||||
"doctrine/cache": "^2.0",
|
||||
"doctrine/coding-standard": "^10",
|
||||
"phpstan/phpstan": "^1.8.0",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
|
||||
"symfony/cache": "^4.4 || ^5.4 || ^6",
|
||||
"symfony/cache": "^5.4 || ^6",
|
||||
"vimeo/psalm": "^4.10"
|
||||
},
|
||||
"suggest": {
|
||||
|
@ -677,9 +725,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/annotations/issues",
|
||||
"source": "https://github.com/doctrine/annotations/tree/1.14.2"
|
||||
"source": "https://github.com/doctrine/annotations/tree/2.0.1"
|
||||
},
|
||||
"time": "2022-12-15T06:48:22+00:00"
|
||||
"time": "2023-02-02T22:02:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/deprecations",
|
||||
|
@ -975,16 +1023,16 @@
|
|||
},
|
||||
{
|
||||
"name": "fidry/cpu-core-counter",
|
||||
"version": "0.4.1",
|
||||
"version": "0.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/theofidry/cpu-core-counter.git",
|
||||
"reference": "79261cc280aded96d098e1b0e0ba0c4881b432c2"
|
||||
"reference": "b58e5a3933e541dc286cc91fc4f3898bbc6f1623"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/79261cc280aded96d098e1b0e0ba0c4881b432c2",
|
||||
"reference": "79261cc280aded96d098e1b0e0ba0c4881b432c2",
|
||||
"url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/b58e5a3933e541dc286cc91fc4f3898bbc6f1623",
|
||||
"reference": "b58e5a3933e541dc286cc91fc4f3898bbc6f1623",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1024,7 +1072,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/theofidry/cpu-core-counter/issues",
|
||||
"source": "https://github.com/theofidry/cpu-core-counter/tree/0.4.1"
|
||||
"source": "https://github.com/theofidry/cpu-core-counter/tree/0.5.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1032,55 +1080,56 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-12-16T22:01:02+00:00"
|
||||
"time": "2022-12-24T12:35:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.13.2",
|
||||
"version": "v3.14.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||
"reference": "3952f08a81bd3b1b15e11c3de0b6bf037faa8496"
|
||||
"reference": "1b3d9dba63d93b8a202c31e824748218781eae6b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/3952f08a81bd3b1b15e11c3de0b6bf037faa8496",
|
||||
"reference": "3952f08a81bd3b1b15e11c3de0b6bf037faa8496",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/1b3d9dba63d93b8a202c31e824748218781eae6b",
|
||||
"reference": "1b3d9dba63d93b8a202c31e824748218781eae6b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer/semver": "^3.2",
|
||||
"composer/semver": "^3.3",
|
||||
"composer/xdebug-handler": "^3.0.3",
|
||||
"doctrine/annotations": "^1.13",
|
||||
"doctrine/annotations": "^2",
|
||||
"doctrine/lexer": "^2 || ^3",
|
||||
"ext-json": "*",
|
||||
"ext-tokenizer": "*",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"sebastian/diff": "^4.0",
|
||||
"sebastian/diff": "^4.0 || ^5.0",
|
||||
"symfony/console": "^5.4 || ^6.0",
|
||||
"symfony/event-dispatcher": "^5.4 || ^6.0",
|
||||
"symfony/filesystem": "^5.4 || ^6.0",
|
||||
"symfony/finder": "^5.4 || ^6.0",
|
||||
"symfony/options-resolver": "^5.4 || ^6.0",
|
||||
"symfony/polyfill-mbstring": "^1.23",
|
||||
"symfony/polyfill-php80": "^1.25",
|
||||
"symfony/polyfill-php81": "^1.25",
|
||||
"symfony/polyfill-mbstring": "^1.27",
|
||||
"symfony/polyfill-php80": "^1.27",
|
||||
"symfony/polyfill-php81": "^1.27",
|
||||
"symfony/process": "^5.4 || ^6.0",
|
||||
"symfony/stopwatch": "^5.4 || ^6.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"justinrainbow/json-schema": "^5.2",
|
||||
"keradus/cli-executor": "^2.0",
|
||||
"mikey179/vfsstream": "^1.6.10",
|
||||
"php-coveralls/php-coveralls": "^2.5.2",
|
||||
"mikey179/vfsstream": "^1.6.11",
|
||||
"php-coveralls/php-coveralls": "^2.5.3",
|
||||
"php-cs-fixer/accessible-object": "^1.1",
|
||||
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2",
|
||||
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1",
|
||||
"phpspec/prophecy": "^1.15",
|
||||
"phpspec/prophecy": "^1.16",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"phpunitgoodpractices/polyfill": "^1.6",
|
||||
"phpunitgoodpractices/traits": "^1.9.2",
|
||||
"symfony/phpunit-bridge": "^6.0",
|
||||
"symfony/phpunit-bridge": "^6.2.3",
|
||||
"symfony/yaml": "^5.4 || ^6.0"
|
||||
},
|
||||
"suggest": {
|
||||
|
@ -1113,7 +1162,7 @@
|
|||
"description": "A tool to automatically fix PHP code style",
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.13.2"
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.14.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1121,7 +1170,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-01-02T23:53:50+00:00"
|
||||
"time": "2023-02-09T21:49:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
|
@ -1280,12 +1329,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nextcloud-deps/ocp.git",
|
||||
"reference": "b04607fb154ae49b6d9e1d4e971e5585a98de1bb"
|
||||
"reference": "c4a05e2e3b749899fb3dd5577ecb5763d3993da3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/b04607fb154ae49b6d9e1d4e971e5585a98de1bb",
|
||||
"reference": "b04607fb154ae49b6d9e1d4e971e5585a98de1bb",
|
||||
"url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/c4a05e2e3b749899fb3dd5577ecb5763d3993da3",
|
||||
"reference": "c4a05e2e3b749899fb3dd5577ecb5763d3993da3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1317,7 +1366,7 @@
|
|||
"issues": "https://github.com/nextcloud-deps/ocp/issues",
|
||||
"source": "https://github.com/nextcloud-deps/ocp/tree/master"
|
||||
},
|
||||
"time": "2023-01-21T00:37:31+00:00"
|
||||
"time": "2023-02-22T00:36:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
|
@ -1653,16 +1702,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "9.2.23",
|
||||
"version": "9.2.24",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c"
|
||||
"reference": "2cf940ebc6355a9d430462811b5aaa308b174bed"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c",
|
||||
"reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2cf940ebc6355a9d430462811b5aaa308b174bed",
|
||||
"reference": "2cf940ebc6355a9d430462811b5aaa308b174bed",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1718,7 +1767,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.23"
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.24"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1726,7 +1775,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-12-28T12:41:10+00:00"
|
||||
"time": "2023-01-26T08:26:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
|
@ -1971,16 +2020,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "9.5.28",
|
||||
"version": "9.6.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "954ca3113a03bf780d22f07bf055d883ee04b65e"
|
||||
"reference": "e7b1615e3e887d6c719121c6d4a44b0ab9645555"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/954ca3113a03bf780d22f07bf055d883ee04b65e",
|
||||
"reference": "954ca3113a03bf780d22f07bf055d883ee04b65e",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e7b1615e3e887d6c719121c6d4a44b0ab9645555",
|
||||
"reference": "e7b1615e3e887d6c719121c6d4a44b0ab9645555",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2022,7 +2071,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "9.5-dev"
|
||||
"dev-master": "9.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
@ -2053,7 +2102,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.28"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -2069,7 +2118,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-01-14T12:32:24+00:00"
|
||||
"time": "2023-02-04T13:37:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/cache",
|
||||
|
@ -2682,16 +2731,16 @@
|
|||
},
|
||||
{
|
||||
"name": "sebastian/environment",
|
||||
"version": "5.1.4",
|
||||
"version": "5.1.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/environment.git",
|
||||
"reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7"
|
||||
"reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7",
|
||||
"reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
|
||||
"reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2733,7 +2782,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/environment/issues",
|
||||
"source": "https://github.com/sebastianbergmann/environment/tree/5.1.4"
|
||||
"source": "https://github.com/sebastianbergmann/environment/tree/5.1.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -2741,7 +2790,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-04-03T09:37:03+00:00"
|
||||
"time": "2023-02-03T06:03:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/exporter",
|
||||
|
@ -3055,16 +3104,16 @@
|
|||
},
|
||||
{
|
||||
"name": "sebastian/recursion-context",
|
||||
"version": "4.0.4",
|
||||
"version": "4.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/recursion-context.git",
|
||||
"reference": "cd9d8cf3c5804de4341c283ed787f099f5506172"
|
||||
"reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172",
|
||||
"reference": "cd9d8cf3c5804de4341c283ed787f099f5506172",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
|
||||
"reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3103,10 +3152,10 @@
|
|||
}
|
||||
],
|
||||
"description": "Provides functionality to recursively process PHP variables",
|
||||
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
|
||||
"homepage": "https://github.com/sebastianbergmann/recursion-context",
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/recursion-context/issues",
|
||||
"source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4"
|
||||
"source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -3114,7 +3163,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2020-10-26T13:17:30+00:00"
|
||||
"time": "2023-02-03T06:07:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/resource-operations",
|
||||
|
@ -3173,16 +3222,16 @@
|
|||
},
|
||||
{
|
||||
"name": "sebastian/type",
|
||||
"version": "3.2.0",
|
||||
"version": "3.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/type.git",
|
||||
"reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e"
|
||||
"reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e",
|
||||
"reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
|
||||
"reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3217,7 +3266,7 @@
|
|||
"homepage": "https://github.com/sebastianbergmann/type",
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/type/issues",
|
||||
"source": "https://github.com/sebastianbergmann/type/tree/3.2.0"
|
||||
"source": "https://github.com/sebastianbergmann/type/tree/3.2.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -3225,7 +3274,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-09-12T14:47:03+00:00"
|
||||
"time": "2023-02-03T06:13:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/version",
|
||||
|
@ -3512,16 +3561,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v5.4.17",
|
||||
"version": "v5.4.19",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "8e18a9d559eb8ebc2220588f1faa726a2fcd31c9"
|
||||
"reference": "abf49cc084c087d94b4cb939c3f3672971784e0c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8e18a9d559eb8ebc2220588f1faa726a2fcd31c9",
|
||||
"reference": "8e18a9d559eb8ebc2220588f1faa726a2fcd31c9",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/abf49cc084c087d94b4cb939c3f3672971784e0c",
|
||||
"reference": "abf49cc084c087d94b4cb939c3f3672971784e0c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3577,7 +3626,7 @@
|
|||
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/event-dispatcher/tree/v5.4.17"
|
||||
"source": "https://github.com/symfony/event-dispatcher/tree/v5.4.19"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -3593,7 +3642,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-12-12T15:54:21+00:00"
|
||||
"time": "2023-01-01T08:32:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher-contracts",
|
||||
|
@ -4786,16 +4835,16 @@
|
|||
},
|
||||
{
|
||||
"name": "vimeo/psalm",
|
||||
"version": "5.6.0",
|
||||
"version": "5.7.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vimeo/psalm.git",
|
||||
"reference": "e784128902dfe01d489c4123d69918a9f3c1eac5"
|
||||
"reference": "5390c212bab06ee230c8720c2e9c54b823db00c8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/vimeo/psalm/zipball/e784128902dfe01d489c4123d69918a9f3c1eac5",
|
||||
"reference": "e784128902dfe01d489c4123d69918a9f3c1eac5",
|
||||
"url": "https://api.github.com/repos/vimeo/psalm/zipball/5390c212bab06ee230c8720c2e9c54b823db00c8",
|
||||
"reference": "5390c212bab06ee230c8720c2e9c54b823db00c8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4814,12 +4863,12 @@
|
|||
"ext-tokenizer": "*",
|
||||
"felixfbecker/advanced-json-rpc": "^3.1",
|
||||
"felixfbecker/language-server-protocol": "^1.5.2",
|
||||
"fidry/cpu-core-counter": "^0.4.0",
|
||||
"fidry/cpu-core-counter": "^0.4.1 || ^0.5.1",
|
||||
"netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0",
|
||||
"nikic/php-parser": "^4.13",
|
||||
"php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0",
|
||||
"sebastian/diff": "^4.0 || ^5.0",
|
||||
"spatie/array-to-xml": "^2.17.0",
|
||||
"spatie/array-to-xml": "^2.17.0 || ^3.0",
|
||||
"symfony/console": "^4.1.6 || ^5.0 || ^6.0",
|
||||
"symfony/filesystem": "^5.4 || ^6.0"
|
||||
},
|
||||
|
@ -4828,13 +4877,13 @@
|
|||
},
|
||||
"require-dev": {
|
||||
"bamarni/composer-bin-plugin": "^1.4",
|
||||
"brianium/paratest": "^6.0",
|
||||
"brianium/paratest": "^6.9",
|
||||
"ext-curl": "*",
|
||||
"mockery/mockery": "^1.5",
|
||||
"nunomaduro/mock-final-classes": "^1.1",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||
"phpstan/phpdoc-parser": "^1.6",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"phpunit/phpunit": "^9.6",
|
||||
"psalm/plugin-mockery": "^1.1",
|
||||
"psalm/plugin-phpunit": "^0.18",
|
||||
"slevomat/coding-standard": "^8.4",
|
||||
|
@ -4880,13 +4929,14 @@
|
|||
"keywords": [
|
||||
"code",
|
||||
"inspection",
|
||||
"php"
|
||||
"php",
|
||||
"static analysis"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/vimeo/psalm/issues",
|
||||
"source": "https://github.com/vimeo/psalm/tree/5.6.0"
|
||||
"source": "https://github.com/vimeo/psalm/tree/5.7.5"
|
||||
},
|
||||
"time": "2023-01-23T20:32:47+00:00"
|
||||
"time": "2023-02-21T16:02:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
|
|
|
@ -31,21 +31,26 @@ declare(strict_types=1);
|
|||
namespace OCA\Social\Controller;
|
||||
|
||||
use Exception;
|
||||
use OCA\Social\AP;
|
||||
use OCA\Social\AppInfo\Application;
|
||||
use OCA\Social\Exceptions\AccountDoesNotExistException;
|
||||
use OCA\Social\Exceptions\ClientNotFoundException;
|
||||
use OCA\Social\Exceptions\InstanceDoesNotExistException;
|
||||
use OCA\Social\Model\ActivityPub\ACore;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCA\Social\Model\ActivityPub\Object\Document;
|
||||
use OCA\Social\Model\ActivityPub\Stream;
|
||||
use OCA\Social\Model\Client\MediaAttachment;
|
||||
use OCA\Social\Model\Client\Options\TimelineOptions;
|
||||
use OCA\Social\Model\Client\SocialClient;
|
||||
use OCA\Social\Model\Client\Status;
|
||||
use OCA\Social\Model\Post;
|
||||
use OCA\Social\Service\AccountService;
|
||||
use OCA\Social\Service\CacheActorService;
|
||||
use OCA\Social\Service\CacheDocumentService;
|
||||
use OCA\Social\Service\ClientService;
|
||||
use OCA\Social\Service\ConfigService;
|
||||
use OCA\Social\Service\DocumentService;
|
||||
use OCA\Social\Service\FollowService;
|
||||
use OCA\Social\Service\InstanceService;
|
||||
use OCA\Social\Service\PostService;
|
||||
|
@ -54,7 +59,10 @@ use OCA\Social\Tools\Traits\TNCDataResponse;
|
|||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\Http\FileDisplayResponse;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\IRequest;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUserSession;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
|
@ -66,12 +74,15 @@ use Psr\Log\LoggerInterface;
|
|||
class ApiController extends Controller {
|
||||
use TNCDataResponse;
|
||||
|
||||
private IURLGenerator $urlGenerator;
|
||||
private IUserSession $userSession;
|
||||
private LoggerInterface $logger;
|
||||
private InstanceService $instanceService;
|
||||
private ClientService $clientService;
|
||||
private AccountService $accountService;
|
||||
private CacheActorService $cacheActorService;
|
||||
private CacheDocumentService $cacheDocumentService;
|
||||
private DocumentService $documentService;
|
||||
private FollowService $followService;
|
||||
private StreamService $streamService;
|
||||
private PostService $postService;
|
||||
|
@ -83,12 +94,15 @@ class ApiController extends Controller {
|
|||
|
||||
public function __construct(
|
||||
IRequest $request,
|
||||
IURLGenerator $urlGenerator,
|
||||
IUserSession $userSession,
|
||||
LoggerInterface $logger,
|
||||
InstanceService $instanceService,
|
||||
ClientService $clientService,
|
||||
AccountService $accountService,
|
||||
CacheActorService $cacheActorService,
|
||||
CacheDocumentService $cacheDocumentService,
|
||||
DocumentService $documentService,
|
||||
FollowService $followService,
|
||||
StreamService $streamService,
|
||||
PostService $postService,
|
||||
|
@ -96,12 +110,15 @@ class ApiController extends Controller {
|
|||
) {
|
||||
parent::__construct(Application::APP_NAME, $request);
|
||||
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->userSession = $userSession;
|
||||
$this->logger = $logger;
|
||||
$this->instanceService = $instanceService;
|
||||
$this->clientService = $clientService;
|
||||
$this->accountService = $accountService;
|
||||
$this->cacheActorService = $cacheActorService;
|
||||
$this->cacheDocumentService = $cacheDocumentService;
|
||||
$this->documentService = $documentService;
|
||||
$this->followService = $followService;
|
||||
$this->streamService = $streamService;
|
||||
$this->postService = $postService;
|
||||
|
@ -218,7 +235,7 @@ class ApiController extends Controller {
|
|||
$this->initViewer(true);
|
||||
|
||||
$input = file_get_contents('php://input');
|
||||
$this->logger->debug('[ApiController] newStatus: ' . $input);
|
||||
$this->logger->debug('[ApiController] statusNew: ' . $input);
|
||||
|
||||
$status = new Status();
|
||||
$status->import($this->convertInput($input));
|
||||
|
@ -227,6 +244,17 @@ class ApiController extends Controller {
|
|||
$post->setContent($status->getStatus());
|
||||
$post->setType($status->getVisibility());
|
||||
|
||||
if (!empty($status->getMediaIds())) {
|
||||
$post->setMedias(
|
||||
array_map(function (Document $document): MediaAttachment {
|
||||
return $document->convertToMediaAttachment($this->urlGenerator);
|
||||
}, $this->documentService->getMediaFromArray(
|
||||
$status->getMediaIds(),
|
||||
$this->viewer->getPreferredUsername()
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
$activity = $this->postService->createPost($post);
|
||||
$activity->setExportFormat(ACore::FORMAT_LOCAL);
|
||||
|
||||
|
@ -239,6 +267,118 @@ class ApiController extends Controller {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @PublicPage
|
||||
* @NoCSRFRequired
|
||||
*
|
||||
* @return DataResponse
|
||||
*/
|
||||
public function mediaNew(): DataResponse {
|
||||
try {
|
||||
$this->initViewer(true);
|
||||
|
||||
$file = $_FILES['file'] ?? [];
|
||||
if (empty($file)) {
|
||||
throw new Exception('no media found');
|
||||
}
|
||||
|
||||
if ($file['error'] !== UPLOAD_ERR_OK) {
|
||||
throw new Exception('error during upload');
|
||||
}
|
||||
|
||||
$name = $file['tmp_name'] ?? '';
|
||||
$size = $file['size'] ?? -1;
|
||||
$type = $file['type'] ?? '';
|
||||
|
||||
if ($name === '' || $size === -1 || $type === '') {
|
||||
throw new Exception('missing details');
|
||||
}
|
||||
|
||||
$this->logger->debug('[ApiController] mediaNew: ' . json_encode($file));
|
||||
|
||||
$document = new Document();
|
||||
$document->setAccount($this->viewer->getPreferredUsername());
|
||||
$document->setUrlCloud($this->configService->getCloudUrl());
|
||||
$document->generateUniqueId('/documents/local');
|
||||
$document->setPublic(true);
|
||||
|
||||
$this->cacheDocumentService->saveFromTempToCache($document, $name);
|
||||
$service = AP::$activityPub->getInterfaceForItem($document);
|
||||
$service->save($document);
|
||||
|
||||
$mediaAttachment = $document->convertToMediaAttachment($this->urlGenerator);
|
||||
|
||||
$this->logger->debug('generated attachment: ' . json_encode($mediaAttachment));
|
||||
|
||||
return new DataResponse($mediaAttachment, Http::STATUS_OK);
|
||||
} catch (Exception $e) {
|
||||
$this->logger->warning('issues while mediaNew', ['exception' => $e]);
|
||||
|
||||
return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @PublicPage
|
||||
* @NoCSRFRequired
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function mediaGet(string $nid, string $preview = ''): Response {
|
||||
try {
|
||||
return new DataResponse([], Http::STATUS_OK);
|
||||
} catch (Exception $e) {
|
||||
$this->logger->warning('issues while mediaNew', ['exception' => $e]);
|
||||
|
||||
return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @PublicPage
|
||||
* @NoCSRFRequired
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function mediaOpen(string $uuid): Response {
|
||||
$ext = '';
|
||||
if (strpos($uuid, '.') > 0) {
|
||||
[$uuid, $ext] = explode('.', $uuid, 2);
|
||||
}
|
||||
|
||||
try {
|
||||
$mime = '';
|
||||
$file = $this->documentService->getFromUuid($uuid);
|
||||
|
||||
return new FileDisplayResponse(
|
||||
$file, Http::STATUS_OK, ['Content-Type' => $this->mimeFromExt($ext)]
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
$this->logger->warning('issues while mediaOpen', ['exception' => $e]);
|
||||
|
||||
return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ext
|
||||
* only support image actually
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function mimeFromExt(string $ext): string {
|
||||
if ($ext === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
return 'image/' . $ext;
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoCSRFRequired
|
||||
* @PublicPage
|
||||
|
@ -302,6 +442,24 @@ class ApiController extends Controller {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @NoCSRFRequired
|
||||
* @PublicPage
|
||||
*
|
||||
* @param int $nid
|
||||
*
|
||||
* @return DataResponse
|
||||
*/
|
||||
public function statusContext(int $nid): DataResponse {
|
||||
try {
|
||||
$this->initViewer(true);
|
||||
$context = $this->streamService->getContextByNid($nid);
|
||||
|
||||
return new DataResponse($context, Http::STATUS_OK);
|
||||
} catch (Exception $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoCSRFRequired
|
||||
|
|
|
@ -38,7 +38,6 @@ class MediaApiController extends Controller {
|
|||
'url' => '',
|
||||
'preview_url' => '',
|
||||
'remote_url' => null,
|
||||
'text_url' => '',
|
||||
'description' => '',
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -39,15 +39,11 @@ use OCP\DB\QueryBuilder\IQueryBuilder;
|
|||
class CacheDocumentsRequest extends CacheDocumentsRequestBuilder {
|
||||
public const CACHING_TIMEOUT = 5; // 5 min
|
||||
|
||||
/**
|
||||
* Insert cache about an Actor in database.
|
||||
*
|
||||
* @param Document $document
|
||||
*/
|
||||
public function save(Document $document): void {
|
||||
$qb = $this->getCacheDocumentsInsertSql();
|
||||
$qb->setValue('id', $qb->createNamedParameter($document->getId()))
|
||||
->setValue('id_prim', $qb->createNamedParameter($qb->prim($document->getId())))
|
||||
->setValue('account', $qb->createNamedParameter($document->getAccount()))
|
||||
->setValue('type', $qb->createNamedParameter($document->getType()))
|
||||
->setValue('url', $qb->createNamedParameter($document->getUrl()))
|
||||
->setValue('media_type', $qb->createNamedParameter($document->getMediaType()))
|
||||
|
@ -55,6 +51,8 @@ class CacheDocumentsRequest extends CacheDocumentsRequestBuilder {
|
|||
->setValue('error', $qb->createNamedParameter($document->getError()))
|
||||
->setValue('local_copy', $qb->createNamedParameter($document->getLocalCopy()))
|
||||
->setValue('resized_copy', $qb->createNamedParameter($document->getResizedCopy()))
|
||||
->setValue('blurhash', $qb->createNamedParameter($document->getBlurHash()))
|
||||
->setValue('description', $qb->createNamedParameter($document->getDescription()))
|
||||
->setValue('parent_id', $qb->createNamedParameter($document->getParentId()))
|
||||
->setValue('parent_id_prim', $qb->createNamedParameter($qb->prim($document->getParentId())))
|
||||
->setValue('public', $qb->createNamedParameter(($document->isPublic()) ? '1' : '0'));
|
||||
|
@ -68,6 +66,7 @@ class CacheDocumentsRequest extends CacheDocumentsRequestBuilder {
|
|||
}
|
||||
|
||||
$qb->executeStatement();
|
||||
$document->setNid($qb->getLastInsertId());
|
||||
}
|
||||
|
||||
|
||||
|
@ -83,6 +82,8 @@ class CacheDocumentsRequest extends CacheDocumentsRequestBuilder {
|
|||
->set('error', $qb->createNamedParameter($document->getError()))
|
||||
->set('local_copy', $qb->createNamedParameter($document->getLocalCopy()))
|
||||
->set('resized_copy', $qb->createNamedParameter($document->getResizedCopy()))
|
||||
->set('blurhash', $qb->createNamedParameter($document->getBlurHash()))
|
||||
->set('description', $qb->createNamedParameter($document->getDescription()))
|
||||
->set('parent_id', $qb->createNamedParameter($document->getParentId()))
|
||||
->set('parent_id_prim', $qb->createNamedParameter($qb->prim($document->getParentId())))
|
||||
->set('public', $qb->createNamedParameter(($document->isPublic()) ? '1' : '0'));
|
||||
|
@ -95,7 +96,7 @@ class CacheDocumentsRequest extends CacheDocumentsRequestBuilder {
|
|||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
$this->limitToIdString($qb, $document->getId());
|
||||
$qb->limitToIdPrim($qb->prim($document->getId()));
|
||||
$qb->executeStatement();
|
||||
}
|
||||
|
||||
|
@ -126,6 +127,8 @@ class CacheDocumentsRequest extends CacheDocumentsRequestBuilder {
|
|||
$this->limitToIdString($qb, $document->getId());
|
||||
$qb->set('local_copy', $qb->createNamedParameter($document->getLocalCopy()));
|
||||
$qb->set('resized_copy', $qb->createNamedParameter($document->getResizedCopy()));
|
||||
$qb->set('blurhash', $qb->createNamedParameter($document->getBlurHash()));
|
||||
$qb->set('description', $qb->createNamedParameter($document->getDescription()));
|
||||
$qb->set('error', $qb->createNamedParameter($document->getError()));
|
||||
|
||||
$qb->executeStatement();
|
||||
|
@ -155,16 +158,37 @@ class CacheDocumentsRequest extends CacheDocumentsRequestBuilder {
|
|||
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param array $mediaIds
|
||||
* @param string $account - limit to account
|
||||
*
|
||||
* @return Document[]
|
||||
*/
|
||||
public function getFromArray(array $mediaIds, string $account = ''): array {
|
||||
$qb = $this->getCacheDocumentsSelectSql();
|
||||
$qb->limitToDBFieldArray('nid', $mediaIds);
|
||||
$qb->limitToAccount($account);
|
||||
|
||||
$documents = [];
|
||||
$cursor = $qb->execute();
|
||||
while ($data = $cursor->fetch()) {
|
||||
$documents[] = $this->parseCacheDocumentsSelectSql($data);
|
||||
}
|
||||
$cursor->closeCursor();
|
||||
|
||||
return $documents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param bool $public
|
||||
* @param bool $useNid
|
||||
*
|
||||
* @return Document
|
||||
* @throws CacheDocumentDoesNotExistException
|
||||
*/
|
||||
public function getById(string $id, bool $public = false) {
|
||||
$qb = $this->getCacheDocumentsSelectSql();
|
||||
$this->limitToIdString($qb, $id);
|
||||
$qb->limitToIdPrim($qb->prim($id));
|
||||
|
||||
if ($public === true) {
|
||||
$this->limitToPublic($qb);
|
||||
|
|
|
@ -60,8 +60,10 @@ class CacheDocumentsRequestBuilder extends CoreRequestBuilder {
|
|||
$qb = $this->getQueryBuilder();
|
||||
|
||||
$qb->select(
|
||||
'cd.id', 'cd.type', 'cd.parent_id', 'cd.media_type', 'cd.mime_type', 'cd.url',
|
||||
'cd.local_copy', 'cd.public', 'cd.error', 'cd.creation', 'cd.caching', 'cd.resized_copy'
|
||||
'cd.nid', 'cd.id', 'cd.type', 'cd.parent_id', 'cd.account',
|
||||
'cd.media_type', 'cd.mime_type', 'cd.url', 'cd.local_copy', 'cd.public',
|
||||
'cd.error', 'cd.creation', 'cd.caching', 'cd.resized_copy', 'cd.blurhash',
|
||||
'cd.description'
|
||||
)
|
||||
->from(self::TABLE_CACHE_DOCUMENTS, 'cd');
|
||||
|
||||
|
|
|
@ -119,15 +119,19 @@ class CoreRequestBuilder {
|
|||
'creation'
|
||||
],
|
||||
self::TABLE_CACHE_DOCUMENTS => [
|
||||
'nid',
|
||||
'id_prim',
|
||||
'id',
|
||||
'type',
|
||||
'account',
|
||||
'parent_id',
|
||||
'media_type',
|
||||
'mime_type',
|
||||
'url',
|
||||
'local_copy',
|
||||
'resized_copy',
|
||||
'blurhash',
|
||||
'description',
|
||||
'public',
|
||||
'error',
|
||||
'creation',
|
||||
|
|
|
@ -74,7 +74,9 @@ class DocumentInterface extends AbstractActivityPubInterface implements IActivit
|
|||
$this->cacheDocumentsRequest->getById($item->getId());
|
||||
$this->cacheDocumentsRequest->update($item);
|
||||
} catch (CacheDocumentDoesNotExistException $e) {
|
||||
if (!$this->cacheDocumentsRequest->isDuplicate($item)) {
|
||||
// parentId / url can only be empty on new document, meaning owner cannot be empty here
|
||||
if (($item->getUrl() === '' && $item->getParentId() === '' && $item->getAccount() !== '')
|
||||
|| !$this->cacheDocumentsRequest->isDuplicate($item)) {
|
||||
$this->cacheDocumentsRequest->save($item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ class Version1000Date20221118000001 extends SimpleMigrationStep {
|
|||
);
|
||||
|
||||
$table->setPrimaryKey(['id_prim']);
|
||||
$table->addUniqueIndex(['actor_id_prim', 'object_id_prim', 'type'], 'aot');
|
||||
$table->addUniqueIndex(['actor_id_prim', 'object_id_prim', 'type'], 'apopt');
|
||||
}
|
||||
|
||||
|
||||
|
@ -896,6 +896,15 @@ class Version1000Date20221118000001 extends SimpleMigrationStep {
|
|||
}
|
||||
|
||||
$table = $schema->createTable('social_cache_doc');
|
||||
$table->addColumn(
|
||||
'nid', Types::BIGINT,
|
||||
[
|
||||
'autoincrement' => true,
|
||||
'notnull' => true,
|
||||
'length' => 14,
|
||||
'unsigned' => true,
|
||||
]
|
||||
);
|
||||
$table->addColumn(
|
||||
'id', Types::TEXT,
|
||||
[
|
||||
|
@ -969,6 +978,21 @@ class Version1000Date20221118000001 extends SimpleMigrationStep {
|
|||
'default' => ''
|
||||
]
|
||||
);
|
||||
$table->addColumn(
|
||||
'blurhash', Types::STRING,
|
||||
[
|
||||
'notnull' => true,
|
||||
'length' => 63,
|
||||
'default' => ''
|
||||
]
|
||||
);
|
||||
$table->addColumn(
|
||||
'description', Types::TEXT,
|
||||
[
|
||||
'notnull' => true,
|
||||
'default' => ''
|
||||
]
|
||||
);
|
||||
$table->addColumn(
|
||||
'public', Types::BOOLEAN,
|
||||
[
|
||||
|
@ -996,7 +1020,7 @@ class Version1000Date20221118000001 extends SimpleMigrationStep {
|
|||
]
|
||||
);
|
||||
|
||||
$table->setPrimaryKey(['id_prim']);
|
||||
$table->setPrimaryKey(['nid']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Nextcloud - Social Support
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @copyright 2023, Maxence Lange <maxence@artificial-owl.com>
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Social\Migration;
|
||||
|
||||
use Closure;
|
||||
use OCP\DB\ISchemaWrapper;
|
||||
use OCP\Migration\IOutput;
|
||||
use OCP\Migration\SimpleMigrationStep;
|
||||
|
||||
class Version1000Date20230217000001 extends SimpleMigrationStep {
|
||||
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ISchemaWrapper {
|
||||
/** @var ISchemaWrapper $schema */
|
||||
$schema = $schemaClosure();
|
||||
|
||||
if ($schema->hasTable('social_cache_doc')) {
|
||||
$table = $schema->getTable('social_cache_doc');
|
||||
|
||||
if (!$table->hasColumn('nid')) {
|
||||
$table->dropPrimaryKey();
|
||||
}
|
||||
}
|
||||
|
||||
return $schema;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Nextcloud - Social Support
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @copyright 2023, Maxence Lange <maxence@artificial-owl.com>
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Social\Migration;
|
||||
|
||||
use Closure;
|
||||
use OCP\DB\ISchemaWrapper;
|
||||
use OCP\DB\Types;
|
||||
use OCP\Migration\IOutput;
|
||||
use OCP\Migration\SimpleMigrationStep;
|
||||
|
||||
class Version1000Date20230217000002 extends SimpleMigrationStep {
|
||||
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ISchemaWrapper {
|
||||
/** @var ISchemaWrapper $schema */
|
||||
$schema = $schemaClosure();
|
||||
|
||||
if ($schema->hasTable('social_cache_doc')) {
|
||||
$table = $schema->getTable('social_cache_doc');
|
||||
|
||||
if (!$table->hasColumn('nid')) {
|
||||
$table->addColumn(
|
||||
'nid', Types::BIGINT,
|
||||
[
|
||||
'autoincrement' => true,
|
||||
'notnull' => true,
|
||||
'length' => 14,
|
||||
'unsigned' => true,
|
||||
]
|
||||
);
|
||||
$table->setPrimaryKey(['nid']);
|
||||
}
|
||||
|
||||
if (!$table->hasColumn('account')) {
|
||||
$table->addColumn(
|
||||
'account', Types::STRING,
|
||||
[
|
||||
'notnull' => true,
|
||||
'length' => 127,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
if (!$table->hasColumn('blurhash')) {
|
||||
$table->addColumn(
|
||||
'blurhash', Types::STRING,
|
||||
[
|
||||
'notnull' => true,
|
||||
'length' => 63,
|
||||
'default' => ''
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
if (!$table->hasColumn('description')) {
|
||||
$table->addColumn(
|
||||
'description', Types::TEXT,
|
||||
[
|
||||
'notnull' => true,
|
||||
'default' => ''
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $schema;
|
||||
}
|
||||
}
|
|
@ -37,6 +37,11 @@ use JsonSerializable;
|
|||
use OCA\Social\Exceptions\InvalidOriginException;
|
||||
use OCA\Social\Exceptions\UrlCloudException;
|
||||
use OCA\Social\Model\ActivityPub\ACore;
|
||||
use OCA\Social\Model\Client\AttachmentMeta;
|
||||
use OCA\Social\Model\Client\AttachmentMetaDim;
|
||||
use OCA\Social\Model\Client\AttachmentMetaFocus;
|
||||
use OCA\Social\Model\Client\MediaAttachment;
|
||||
use OCP\IURLGenerator;
|
||||
|
||||
/**
|
||||
* Class Document
|
||||
|
@ -46,22 +51,20 @@ use OCA\Social\Model\ActivityPub\ACore;
|
|||
class Document extends ACore implements JsonSerializable {
|
||||
public const TYPE = 'Document';
|
||||
|
||||
|
||||
private string $account = '';
|
||||
private string $mediaType = '';
|
||||
|
||||
private string $mimeType = '';
|
||||
|
||||
private string $localCopy = '';
|
||||
|
||||
private string $resizedCopy = '';
|
||||
|
||||
private string $blurHash = '';
|
||||
private string $description = '';
|
||||
private int $caching = 0;
|
||||
|
||||
private bool $public = false;
|
||||
|
||||
private int $error = 0;
|
||||
|
||||
private string $parentId = '';
|
||||
private array $localCopySize = [0, 0];
|
||||
private array $resizedCopySize = [0, 0];
|
||||
|
||||
|
||||
/**
|
||||
* Document constructor.
|
||||
|
@ -75,6 +78,17 @@ class Document extends ACore implements JsonSerializable {
|
|||
}
|
||||
|
||||
|
||||
public function setAccount(string $account): self {
|
||||
$this->account = $account;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAccount(): string {
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
@ -125,7 +139,7 @@ class Document extends ACore implements JsonSerializable {
|
|||
*
|
||||
* @return Document
|
||||
*/
|
||||
public function setLocalCopy(string $localCopy): Document {
|
||||
public function setLocalCopy(string $localCopy): self {
|
||||
$this->localCopy = $localCopy;
|
||||
|
||||
return $this;
|
||||
|
@ -144,12 +158,51 @@ class Document extends ACore implements JsonSerializable {
|
|||
*
|
||||
* @return Document
|
||||
*/
|
||||
public function setResizedCopy(string $resizedCopy): Document {
|
||||
public function setResizedCopy(string $resizedCopy): self {
|
||||
$this->resizedCopy = $resizedCopy;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setLocalCopySize(int $width, int $height): self {
|
||||
$this->localCopySize = [$width, $height];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLocalCopySize(): array {
|
||||
return $this->localCopySize;
|
||||
}
|
||||
|
||||
public function setResizedCopySize(int $width, int $height): void {
|
||||
$this->resizedCopySize = [$width, $height];
|
||||
}
|
||||
|
||||
public function getResizedCopySize(): array {
|
||||
return $this->resizedCopySize;
|
||||
}
|
||||
|
||||
|
||||
public function setBlurHash(string $blurHash): self {
|
||||
$this->blurHash = $blurHash;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBlurHash(): string {
|
||||
return $this->blurHash;
|
||||
}
|
||||
|
||||
public function setDescription(string $description): self {
|
||||
$this->description = $description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescription(): string {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
|
@ -163,7 +216,7 @@ class Document extends ACore implements JsonSerializable {
|
|||
*
|
||||
* @return Document
|
||||
*/
|
||||
public function setPublic(bool $public): Document {
|
||||
public function setPublic(bool $public): self {
|
||||
$this->public = $public;
|
||||
|
||||
return $this;
|
||||
|
@ -182,7 +235,7 @@ class Document extends ACore implements JsonSerializable {
|
|||
*
|
||||
* @return Document
|
||||
*/
|
||||
public function setParentId(string $parentId): Document {
|
||||
public function setParentId(string $parentId): self {
|
||||
$this->parentId = $parentId;
|
||||
|
||||
return $this;
|
||||
|
@ -201,7 +254,7 @@ class Document extends ACore implements JsonSerializable {
|
|||
*
|
||||
* @return Document
|
||||
*/
|
||||
public function setError(int $error): Document {
|
||||
public function setError(int $error): self {
|
||||
$this->error = $error;
|
||||
|
||||
return $this;
|
||||
|
@ -220,7 +273,7 @@ class Document extends ACore implements JsonSerializable {
|
|||
*
|
||||
* @return Document
|
||||
*/
|
||||
public function setCaching(int $caching): Document {
|
||||
public function setCaching(int $caching): self {
|
||||
$this->caching = $caching;
|
||||
|
||||
return $this;
|
||||
|
@ -253,10 +306,13 @@ class Document extends ACore implements JsonSerializable {
|
|||
public function importFromDatabase(array $data) {
|
||||
parent::importFromDatabase($data);
|
||||
|
||||
$this->setPublic(($this->getInt('public', $data, 0) === 1) ? true : false);
|
||||
$this->setAccount($this->get('account', $data));
|
||||
$this->setPublic(($this->getInt('public', $data, 0) === 1));
|
||||
$this->setError($this->getInt('error', $data, 0));
|
||||
$this->setLocalCopy($this->get('local_copy', $data, ''));
|
||||
$this->setResizedCopy($this->get('resized_copy', $data, ''));
|
||||
$this->setBlurHash($this->get('blurhash', $data, ''));
|
||||
$this->setDescription($this->get('description', $data, ''));
|
||||
$this->setMediaType($this->get('media_type', $data, ''));
|
||||
$this->setMimeType($this->get('mime_type', $data, ''));
|
||||
$this->setParentId($this->get('parent_id', $data, ''));
|
||||
|
@ -292,4 +348,42 @@ class Document extends ACore implements JsonSerializable {
|
|||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MediaAttachment
|
||||
*/
|
||||
public function convertToMediaAttachment(?IURLGenerator $urlGenerator = null): MediaAttachment {
|
||||
$media = new MediaAttachment();
|
||||
|
||||
[$type, $mime] = explode('/', $this->getMediaType(), 2);
|
||||
$media->setId((string)$this->getNid())
|
||||
->setType($type);
|
||||
|
||||
if (!is_null($urlGenerator)) {
|
||||
$media->setUrl(
|
||||
$urlGenerator->linkToRouteAbsolute(
|
||||
'social.Api.mediaOpen',
|
||||
['uuid' => $this->getLocalCopy() . '.' . $mime]
|
||||
)
|
||||
);
|
||||
$media->setPreviewUrl(
|
||||
$urlGenerator->linkToRouteAbsolute(
|
||||
'social.Api.mediaOpen',
|
||||
['uuid' => $this->getResizedCopy() . '.' . $mime]
|
||||
)
|
||||
);
|
||||
$media->setRemoteUrl($this->getUrl());
|
||||
}
|
||||
|
||||
$meta = new AttachmentMeta();
|
||||
$meta->setOriginal(new AttachmentMetaDim($this->getLocalCopySize()))
|
||||
->setSmall(new AttachmentMetaDim($this->getResizedCopySize()))
|
||||
->setFocus(new AttachmentMetaFocus(0, 0));
|
||||
|
||||
$media->setMeta($meta)
|
||||
->setDescription($this->getDescription())
|
||||
->setBlurHash($this->getBlurHash());
|
||||
|
||||
return $media;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,19 +30,14 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Social\Model\ActivityPub\Object;
|
||||
|
||||
use Exception;
|
||||
use JsonSerializable;
|
||||
use OCA\Social\AP;
|
||||
use OCA\Social\Exceptions\InvalidResourceEntryException;
|
||||
use OCA\Social\Exceptions\ItemAlreadyExistsException;
|
||||
use OCA\Social\Exceptions\ItemUnknownException;
|
||||
use OCA\Social\Model\ActivityPub\ACore;
|
||||
use OCA\Social\Model\ActivityPub\Stream;
|
||||
|
||||
class Note extends Stream implements JsonSerializable {
|
||||
public const TYPE = 'Note';
|
||||
|
||||
private array $attachments = [];
|
||||
private array $hashtags = [];
|
||||
|
||||
public function __construct(ACore $parent = null) {
|
||||
|
@ -51,16 +46,6 @@ class Note extends Stream implements JsonSerializable {
|
|||
$this->setType(self::TYPE);
|
||||
}
|
||||
|
||||
public function getAttachments(): array {
|
||||
return $this->attachments;
|
||||
}
|
||||
|
||||
public function setAttachments(array $attachments): Note {
|
||||
$this->attachments = $attachments;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHashtags(): array {
|
||||
return $this->hashtags;
|
||||
}
|
||||
|
@ -92,57 +77,13 @@ class Note extends Stream implements JsonSerializable {
|
|||
public function import(array $data): void {
|
||||
parent::import($data);
|
||||
|
||||
$this->importAttachments($this->getArray('attachment', $data, []));
|
||||
$this->fillHashtags();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws ItemAlreadyExistsException
|
||||
*/
|
||||
public function importAttachments(array $list): void {
|
||||
$new = [];
|
||||
foreach ($list as $item) {
|
||||
try {
|
||||
$attachment = AP::$activityPub->getItemFromData($item, $this);
|
||||
} catch (Exception $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($attachment->getType() !== Document::TYPE
|
||||
&& $attachment->getType() !== Image::TYPE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$attachment->setUrl(
|
||||
$this->validateEntryString(ACore::AS_URL, $attachment->getUrl())
|
||||
);
|
||||
} catch (InvalidResourceEntryException $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($attachment->getUrl() === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$interface = AP::$activityPub->getInterfaceFromType($attachment->getType());
|
||||
} catch (ItemUnknownException $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$interface->save($attachment);
|
||||
$new[] = $attachment;
|
||||
}
|
||||
|
||||
$this->setAttachments($new);
|
||||
}
|
||||
|
||||
public function importFromDatabase(array $data): void {
|
||||
parent::importFromDatabase($data);
|
||||
|
||||
$this->setAttachments($this->getArray('attachments', $data, []));
|
||||
$this->setHashtags($this->getArray('hashtags', $data, []));
|
||||
}
|
||||
|
||||
|
@ -151,7 +92,6 @@ class Note extends Stream implements JsonSerializable {
|
|||
|
||||
if ($this->isCompleteDetails()) {
|
||||
$result['hashtags'] = $this->getHashtags();
|
||||
$result['attachment'] = $this->getAttachments();
|
||||
}
|
||||
|
||||
$this->cleanArray($result);
|
||||
|
|
|
@ -33,10 +33,17 @@ namespace OCA\Social\Model\ActivityPub;
|
|||
use DateTime;
|
||||
use Exception;
|
||||
use JsonSerializable;
|
||||
use OCA\Social\AP;
|
||||
use OCA\Social\Exceptions\InvalidResourceEntryException;
|
||||
use OCA\Social\Exceptions\ItemAlreadyExistsException;
|
||||
use OCA\Social\Exceptions\ItemUnknownException;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCA\Social\Model\ActivityPub\Object\Announce;
|
||||
use OCA\Social\Model\ActivityPub\Object\Document;
|
||||
use OCA\Social\Model\ActivityPub\Object\Follow;
|
||||
use OCA\Social\Model\ActivityPub\Object\Image;
|
||||
use OCA\Social\Model\ActivityPub\Object\Like;
|
||||
use OCA\Social\Model\Client\MediaAttachment;
|
||||
use OCA\Social\Model\StreamAction;
|
||||
use OCA\Social\Tools\IQueryRow;
|
||||
use OCA\Social\Tools\Model\Cache;
|
||||
|
@ -67,6 +74,7 @@ class Stream extends ACore implements IQueryRow, JsonSerializable {
|
|||
private string $language = 'en';
|
||||
private string $attributedTo = '';
|
||||
private string $inReplyTo = '';
|
||||
private array $attachments = [];
|
||||
private bool $sensitive = false;
|
||||
private string $conversation = '';
|
||||
private ?Cache $cache = null;
|
||||
|
@ -198,6 +206,25 @@ class Stream extends ACore implements IQueryRow, JsonSerializable {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return MediaAttachment[]
|
||||
*/
|
||||
public function getAttachments(): array {
|
||||
return $this->attachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MediaAttachment[] $attachments
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setAttachments(array $attachments): self {
|
||||
$this->attachments = $attachments;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
|
@ -372,10 +399,57 @@ class Stream extends ACore implements IQueryRow, JsonSerializable {
|
|||
$this->setObjectId($this->get('object', $data, ''));
|
||||
$this->setConversation($this->validate(self::AS_ID, 'conversation', $data, ''));
|
||||
$this->setContent($this->get('content', $data, ''));
|
||||
try {
|
||||
$this->importAttachments($this->getArray('attachments', $data, []));
|
||||
} catch (ItemAlreadyExistsException $e) {
|
||||
}
|
||||
$this->convertPublished();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws ItemAlreadyExistsException
|
||||
*/
|
||||
public function importAttachments(array $list): void {
|
||||
$new = [];
|
||||
foreach ($list as $item) {
|
||||
// try {
|
||||
// $attachment = AP::$activityPub->getItemFromData($item, $this);
|
||||
// } catch (Exception $e) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// if ($attachment->getType() !== Document::TYPE
|
||||
// && $attachment->getType() !== Image::TYPE) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// try {
|
||||
// $attachment->setUrl(
|
||||
// $this->validateEntryString(ACore::AS_URL, $attachment->getUrl())
|
||||
// );
|
||||
// } catch (InvalidResourceEntryException $e) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// if ($attachment->getUrl() === '') {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// try {
|
||||
// $interface = AP::$activityPub->getInterfaceFromType($attachment->getType());
|
||||
// } catch (ItemUnknownException $e) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// $interface->save($attachment);
|
||||
// $new[] = $attachment;
|
||||
}
|
||||
|
||||
$this->setAttachments($new);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
|
@ -395,6 +469,7 @@ class Stream extends ACore implements IQueryRow, JsonSerializable {
|
|||
$this->setInReplyTo($this->validate(self::AS_ID, 'in_reply_to', $data));
|
||||
$this->setDetailsAll($this->getArray('details', $data, []));
|
||||
$this->setFilterDuplicate($this->getBool('filter_duplicate', $data, false));
|
||||
$this->setAttachments($this->getArray('attachments', $data, []));
|
||||
|
||||
$cache = new Cache();
|
||||
$cache->import($this->getArray('cache', $data, []));
|
||||
|
@ -438,10 +513,6 @@ class Stream extends ACore implements IQueryRow, JsonSerializable {
|
|||
'publishedTime' => $this->getPublishedTime()
|
||||
]
|
||||
);
|
||||
|
||||
// $result['cc'] = '';
|
||||
// $result['bcc'] = '';
|
||||
// $result['to'] = '';
|
||||
}
|
||||
|
||||
$this->cleanArray($result);
|
||||
|
@ -488,6 +559,7 @@ class Stream extends ACore implements IQueryRow, JsonSerializable {
|
|||
'uri' => $this->getId(),
|
||||
'url' => $this->getId(),
|
||||
"reblog" => null,
|
||||
'media_attachments' => $this->getAttachments(),
|
||||
"created_at" => date('Y-m-d\TH:i:s', $this->getPublishedTime()) . '.000Z'
|
||||
];
|
||||
|
||||
|
@ -530,4 +602,17 @@ class Stream extends ACore implements IQueryRow, JsonSerializable {
|
|||
|
||||
return array_merge(parent::exportAsNotification(), $result);
|
||||
}
|
||||
|
||||
|
||||
public function jsonSerialize(): array {
|
||||
$result = parent::jsonSerialize();
|
||||
|
||||
$result['media_attachments'] = $this->getAttachments();
|
||||
|
||||
// if ($this->isCompleteDetails()) {
|
||||
// $result['attachments'] = $this->getAttachments();
|
||||
// }
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,228 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Nextcloud - Social Support
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @copyright 2022, Maxence Lange <maxence@artificial-owl.com>
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Social\Model\Client;
|
||||
|
||||
use JsonSerializable;
|
||||
use OCA\Social\Tools\Traits\TArrayTools;
|
||||
|
||||
class AttachmentMeta implements JsonSerializable {
|
||||
use TArrayTools;
|
||||
|
||||
private ?AttachmentMetaDim $original = null;
|
||||
private ?AttachmentMetaDim $small = null;
|
||||
private ?AttachmentMetaFocus $focus = null;
|
||||
|
||||
private ?int $width = null;
|
||||
private ?int $height = null;
|
||||
private ?float $aspect = null;
|
||||
private string $size = '';
|
||||
private string $length = '';
|
||||
private ?float $duration = null;
|
||||
private ?float $fps = null;
|
||||
|
||||
private string $audioEncode = '';
|
||||
private string $audioBitrate = '';
|
||||
private string $audioChannels = '';
|
||||
|
||||
private string $description = '';
|
||||
private string $blurHash = '';
|
||||
|
||||
public function setOriginal(AttachmentMetaDim $original): self {
|
||||
$this->original = $original;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOriginal(): ?AttachmentMetaDim {
|
||||
return $this->original;
|
||||
}
|
||||
|
||||
public function setSmall(AttachmentMetaDim $small): self {
|
||||
$this->small = $small;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSmall(): ?AttachmentMetaDim {
|
||||
return $this->small;
|
||||
}
|
||||
|
||||
public function setFocus(AttachmentMetaFocus $focus): self {
|
||||
$this->focus = $focus;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFocus(): ?AttachmentMetaFocus {
|
||||
return $this->focus;
|
||||
}
|
||||
|
||||
public function setWidth(int $width): self {
|
||||
$this->width = $width;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getWidth(): ?int {
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
public function setHeight(int $height): self {
|
||||
$this->height = $height;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHeight(): ?int {
|
||||
return $this->height;
|
||||
}
|
||||
|
||||
public function setAspect(float $aspect): self {
|
||||
$this->aspect = $aspect;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAspect(): ?float {
|
||||
return $this->aspect;
|
||||
}
|
||||
|
||||
public function setSize(string $size): self {
|
||||
$this->size = $size;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSize(): string {
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
public function setLength(string $length): self {
|
||||
$this->length = $length;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLength(): string {
|
||||
return $this->length;
|
||||
}
|
||||
|
||||
public function setDuration(float $duration): self {
|
||||
$this->duration = $duration;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDuration(): ?float {
|
||||
return $this->duration;
|
||||
}
|
||||
|
||||
public function setFps(float $fps): self {
|
||||
$this->fps = $fps;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFps(): ?float {
|
||||
return $this->fps;
|
||||
}
|
||||
|
||||
public function setAudioEncode(string $audioEncode): self {
|
||||
$this->audioEncode = $audioEncode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAudioEncode(): string {
|
||||
return $this->audioEncode;
|
||||
}
|
||||
|
||||
public function setAudioBitrate(string $audioBitrate): self {
|
||||
$this->audioBitrate = $audioBitrate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAudioBitrate(): string {
|
||||
return $this->audioBitrate;
|
||||
}
|
||||
|
||||
public function setAudioChannels(string $audioChannels): self {
|
||||
$this->audioChannels = $audioChannels;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAudioChannels(): string {
|
||||
return $this->audioChannels;
|
||||
}
|
||||
|
||||
public function setDescription(string $description): self {
|
||||
$this->description = $description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescription(): string {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setBlurHash(string $blurHash): self {
|
||||
$this->blurHash = $blurHash;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBlurHash(): ?string {
|
||||
return $this->blurHash;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array {
|
||||
return array_filter(
|
||||
[
|
||||
'width' => $this->getWidth(),
|
||||
'height' => $this->getHeight(),
|
||||
'aspect' => $this->getAspect(),
|
||||
'size' => $this->getSize(),
|
||||
'length' => $this->getLength(),
|
||||
'duration' => $this->getDuration(),
|
||||
'fps' => $this->getFps(),
|
||||
'original' => $this->getOriginal(),
|
||||
'small' => $this->getSmall(),
|
||||
'focus' => $this->getFocus(),
|
||||
'audio_encode' => $this->getAudioEncode(),
|
||||
'audio_bitrate' => $this->getAudioBitrate(),
|
||||
'audio_channels' => $this->getAudioChannels(),
|
||||
'description' => $this->getDescription(),
|
||||
'blurhash' => $this->getBlurHash()
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Nextcloud - Social Support
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @copyright 2022, Maxence Lange <maxence@artificial-owl.com>
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Social\Model\Client;
|
||||
|
||||
use JsonSerializable;
|
||||
|
||||
class AttachmentMetaDim implements JsonSerializable {
|
||||
private ?int $width = null;
|
||||
private ?int $height = null;
|
||||
private string $size = '';
|
||||
private ?float $aspect = null;
|
||||
private ?float $duration = null;
|
||||
private ?float $bitrate = null;
|
||||
private ?float $frameRate = null;
|
||||
|
||||
public function __construct(array $dim) {
|
||||
$width = (int)$dim[0];
|
||||
$height = (int)$dim[1];
|
||||
|
||||
if ($width > 0 && $height > 0) {
|
||||
$this->width = $width;
|
||||
$this->height = $height;
|
||||
$this->size = $width . 'x' . $height;
|
||||
$this->aspect = $width / $height;
|
||||
}
|
||||
}
|
||||
|
||||
public function setWidth(int $width): self {
|
||||
$this->width = $width;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getWidth(): ?int {
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
public function setHeight(int $height): self {
|
||||
$this->height = $height;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHeight(): ?int {
|
||||
return $this->height;
|
||||
}
|
||||
|
||||
public function setSize(string $size): self {
|
||||
$this->size = $size;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSize(): string {
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
public function setAspect(float $aspect): self {
|
||||
$this->aspect = $aspect;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAspect(): ?float {
|
||||
return $this->aspect;
|
||||
}
|
||||
|
||||
public function setDuration(float $duration): self {
|
||||
$this->duration = $duration;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDuration(): ?float {
|
||||
return $this->duration;
|
||||
}
|
||||
|
||||
public function setBitrate(float $bitrate): self {
|
||||
$this->bitrate = $bitrate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBitrate(): ?float {
|
||||
return $this->bitrate;
|
||||
}
|
||||
|
||||
public function setFrameRate(float $frameRate): self {
|
||||
$this->frameRate = $frameRate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFrameRate(): ?float {
|
||||
return $this->frameRate;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array {
|
||||
return array_filter(
|
||||
[
|
||||
'width' => $this->getWidth(),
|
||||
'height' => $this->getHeight(),
|
||||
'size' => $this->getSize(),
|
||||
'aspect' => $this->getAspect(),
|
||||
'duration' => $this->getDuration(),
|
||||
'bitrate' => $this->getBitrate(),
|
||||
'frame_rate' => $this->getFrameRate()
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Nextcloud - Social Support
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @copyright 2022, Maxence Lange <maxence@artificial-owl.com>
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Social\Model\Client;
|
||||
|
||||
use JsonSerializable;
|
||||
|
||||
class AttachmentMetaFocus implements JsonSerializable {
|
||||
private ?float $x;
|
||||
private ?float $y;
|
||||
|
||||
public function __construct(?float $x = null, ?float $y = null) {
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
}
|
||||
|
||||
public function setX(float $x): self {
|
||||
$this->x = $x;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getX(): ?float {
|
||||
return $this->x;
|
||||
}
|
||||
|
||||
public function setY(float $y): self {
|
||||
$this->y = $y;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getY(): ?float {
|
||||
return $this->y;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array {
|
||||
return array_filter(
|
||||
[
|
||||
'x' => $this->getX(),
|
||||
'y' => $this->getY()
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Nextcloud - Social Support
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @copyright 2022, Maxence Lange <maxence@artificial-owl.com>
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Social\Model\Client;
|
||||
|
||||
use JsonSerializable;
|
||||
use OCA\Social\Tools\Traits\TArrayTools;
|
||||
|
||||
class MediaAttachment implements JsonSerializable {
|
||||
use TArrayTools;
|
||||
|
||||
private string $id = '';
|
||||
private string $type = '';
|
||||
private ?string $url = null;
|
||||
private string $previewUrl = '';
|
||||
private ?string $remoteUrl = null;
|
||||
private string $textUrl = '';
|
||||
private ?AttachmentMeta $meta = null;
|
||||
private string $description = '';
|
||||
private string $blurHash = '';
|
||||
|
||||
public function setId(string $id): self {
|
||||
$this->id = $id;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getId(): string {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setType(string $type): self {
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getType(): string {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function setUrl(string $url): self {
|
||||
$this->url = $url;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUrl(): ?string {
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function setPreviewUrl(string $previewUrl): self {
|
||||
$this->previewUrl = $previewUrl;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPreviewUrl(): string {
|
||||
return $this->previewUrl;
|
||||
}
|
||||
|
||||
public function setRemoteUrl(string $remoteUrl): self {
|
||||
$this->remoteUrl = $remoteUrl;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRemoteUrl(): ?string {
|
||||
return $this->remoteUrl;
|
||||
}
|
||||
|
||||
public function setTextUrl(string $textUrl): self {
|
||||
$this->textUrl = $textUrl;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTextUrl(): string {
|
||||
return $this->textUrl;
|
||||
}
|
||||
|
||||
public function setMeta(AttachmentMeta $meta): self {
|
||||
$this->meta = $meta;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMeta(): ?AttachmentMeta {
|
||||
return $this->meta;
|
||||
}
|
||||
|
||||
public function setDescription(string $description): self {
|
||||
$this->description = $description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescription(): string {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setBlurHash(string $blurHash): self {
|
||||
$this->blurHash = $blurHash;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBlurHash(): string {
|
||||
return $this->blurHash;
|
||||
}
|
||||
|
||||
|
||||
public function jsonSerialize(): array {
|
||||
return array_filter(
|
||||
[
|
||||
'id' => $this->getId(),
|
||||
'type' => $this->getType(),
|
||||
'url' => $this->getUrl(),
|
||||
'preview_url' => $this->getPreviewUrl(),
|
||||
'remote_url' => $this->getRemoteUrl(),
|
||||
'meta' => $this->getMeta(),
|
||||
'description' => $this->getDescription(),
|
||||
"blurhash" => $this->getBlurHash()
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -45,33 +45,19 @@ use JsonSerializable;
|
|||
class SocialClient implements IQueryRow, JsonSerializable {
|
||||
use TArrayTools;
|
||||
|
||||
|
||||
private int $id = 0;
|
||||
|
||||
private string $appName = '';
|
||||
|
||||
private string $appWebsite = '';
|
||||
|
||||
private array $appRedirectUris = [];
|
||||
|
||||
private string $appClientId = '';
|
||||
|
||||
private string $appClientSecret = '';
|
||||
|
||||
private array $appScopes = [];
|
||||
|
||||
private array $authScopes = [];
|
||||
|
||||
private string $authAccount = '';
|
||||
|
||||
private string $authUserId = '';
|
||||
|
||||
private string $authCode = '';
|
||||
|
||||
private int $lastUpdate = -1;
|
||||
|
||||
private string $token = '';
|
||||
|
||||
private int $creation = -1;
|
||||
|
||||
// /** @var array */
|
||||
|
|
|
@ -38,6 +38,7 @@ class Status implements \JsonSerializable {
|
|||
private bool $sensitive = false;
|
||||
private string $visibility = '';
|
||||
private string $spoilerText = '';
|
||||
private array $mediaIds = [];
|
||||
private string $status = '';
|
||||
|
||||
//"media_ids": [],
|
||||
|
@ -121,6 +122,18 @@ class Status implements \JsonSerializable {
|
|||
return $this->spoilerText;
|
||||
}
|
||||
|
||||
public function setMediaIds(array $mediaIds): self {
|
||||
$this->mediaIds = array_map(function (string $id): int {
|
||||
return (int)$id;
|
||||
}, $mediaIds);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMediaIds(): array {
|
||||
return $this->mediaIds;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $status
|
||||
|
@ -146,6 +159,7 @@ class Status implements \JsonSerializable {
|
|||
$this->setSensitive($this->getBool('sensitive', $data));
|
||||
$this->setVisibility($this->get('visibility', $data));
|
||||
$this->setSpoilerText($this->get('spoiler_text', $data));
|
||||
$this->setMediaIds($this->getArray('media_ids', $data));
|
||||
$this->setStatus($this->get('status', $data));
|
||||
|
||||
return $this;
|
||||
|
@ -155,6 +169,7 @@ class Status implements \JsonSerializable {
|
|||
return [
|
||||
'contentType' => $this->getContentType(),
|
||||
'sensitive' => $this->isSensitive(),
|
||||
'mediaIds' => $this->getMediaIds(),
|
||||
'visibility' => $this->getVisibility(),
|
||||
'spoilerText' => $this->getSpoilerText(),
|
||||
'status' => $this->getStatus()
|
||||
|
|
|
@ -30,10 +30,11 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Social\Model;
|
||||
|
||||
use OCA\Social\Tools\Traits\TArrayTools;
|
||||
use JsonSerializable;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCA\Social\Model\ActivityPub\Object\Document;
|
||||
use OCA\Social\Model\Client\MediaAttachment;
|
||||
use OCA\Social\Tools\Traits\TArrayTools;
|
||||
|
||||
/**
|
||||
* Class Post
|
||||
|
@ -52,6 +53,8 @@ class Post implements JsonSerializable {
|
|||
|
||||
/** @var string[] */
|
||||
private array $attachments = [];
|
||||
/** @var MediaAttachment[] */
|
||||
private array $medias = [];
|
||||
|
||||
/** @var Document[] */
|
||||
private array $documents = [];
|
||||
|
@ -180,14 +183,30 @@ class Post implements JsonSerializable {
|
|||
/**
|
||||
* @param string[] $attachments
|
||||
*
|
||||
* @return Post
|
||||
* @return self
|
||||
*/
|
||||
public function setAttachments(array $attachments): Post {
|
||||
public function setAttachments(array $attachments): self {
|
||||
$this->attachments = $attachments;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MediaAttachment[] $medias
|
||||
*/
|
||||
public function setMedias(array $medias): self {
|
||||
$this->medias = $medias;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MediaAttachment[]
|
||||
*/
|
||||
public function getMedias(): array {
|
||||
return $this->medias;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Document[]
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Nextcloud - Social Support
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @copyright 2023, Maxence Lange <maxence@artificial-owl.com>
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Social\Service;
|
||||
|
||||
use GdImage;
|
||||
use kornrunner\Blurhash\Blurhash;
|
||||
|
||||
class BlurService {
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
public function generateBlurHash(GdImage $image): string {
|
||||
$width = imagesx($image);
|
||||
$height = imagesy($image);
|
||||
|
||||
$pixels = [];
|
||||
for ($y = 0; $y < $height; ++$y) {
|
||||
$row = [];
|
||||
for ($x = 0; $x < $width; ++$x) {
|
||||
$index = imagecolorat($image, $x, $y);
|
||||
$colors = imagecolorsforindex($image, $index);
|
||||
|
||||
$row[] = [$colors['red'], $colors['green'], $colors['blue']];
|
||||
}
|
||||
$pixels[] = $row;
|
||||
}
|
||||
|
||||
return Blurhash::encode($pixels, 4, 3);
|
||||
}
|
||||
}
|
|
@ -29,15 +29,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Social\Service;
|
||||
|
||||
use OCA\Social\Tools\Exceptions\MalformedArrayException;
|
||||
use OCA\Social\Tools\Exceptions\RequestContentException;
|
||||
use OCA\Social\Tools\Exceptions\RequestNetworkException;
|
||||
use OCA\Social\Tools\Exceptions\RequestResultSizeException;
|
||||
use OCA\Social\Tools\Exceptions\RequestServerException;
|
||||
use OCA\Social\Tools\Model\NCRequest;
|
||||
use OCA\Social\Tools\Model\Request;
|
||||
use OCA\Social\Tools\Traits\TArrayTools;
|
||||
use OCA\Social\Tools\Traits\TStringTools;
|
||||
use Exception;
|
||||
use Gumlet\ImageResize;
|
||||
use Gumlet\ImageResizeException;
|
||||
|
@ -47,6 +38,15 @@ use OCA\Social\Exceptions\CacheDocumentDoesNotExistException;
|
|||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\UnauthorizedFediverseException;
|
||||
use OCA\Social\Model\ActivityPub\Object\Document;
|
||||
use OCA\Social\Tools\Exceptions\MalformedArrayException;
|
||||
use OCA\Social\Tools\Exceptions\RequestContentException;
|
||||
use OCA\Social\Tools\Exceptions\RequestNetworkException;
|
||||
use OCA\Social\Tools\Exceptions\RequestResultSizeException;
|
||||
use OCA\Social\Tools\Exceptions\RequestServerException;
|
||||
use OCA\Social\Tools\Model\NCRequest;
|
||||
use OCA\Social\Tools\Model\Request;
|
||||
use OCA\Social\Tools\Traits\TArrayTools;
|
||||
use OCA\Social\Tools\Traits\TStringTools;
|
||||
use OCP\Files\IAppData;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\Files\NotPermittedException;
|
||||
|
@ -56,22 +56,24 @@ class CacheDocumentService {
|
|||
use TArrayTools;
|
||||
use TStringTools;
|
||||
|
||||
public const RESIZED_WIDTH = 280;
|
||||
public const RESIZED_WIDTH = 420;
|
||||
public const RESIZED_HEIGHT = 180;
|
||||
|
||||
private IAppData $appData;
|
||||
private CurlService $curlService;
|
||||
private ConfigService $configService;
|
||||
private MiscService $miscService;
|
||||
private BlurService $blurService;
|
||||
|
||||
public function __construct(
|
||||
IAppData $appData, CurlService $curlService, ConfigService $configService,
|
||||
MiscService $miscService
|
||||
IAppData $appData,
|
||||
CurlService $curlService,
|
||||
BlurService $blurService,
|
||||
ConfigService $configService
|
||||
) {
|
||||
$this->appData = $appData;
|
||||
$this->curlService = $curlService;
|
||||
$this->blurService = $blurService;
|
||||
$this->configService = $configService;
|
||||
$this->miscService = $miscService;
|
||||
}
|
||||
|
||||
|
||||
|
@ -132,7 +134,8 @@ class CacheDocumentService {
|
|||
|
||||
$filename = $this->generateFileFromContent($content);
|
||||
$document->setLocalCopy($filename);
|
||||
$this->resizeImage($content);
|
||||
|
||||
$this->resizeImage($document, $content);
|
||||
$resized = $this->generateFileFromContent($content);
|
||||
$document->setResizedCopy($resized);
|
||||
}
|
||||
|
@ -150,7 +153,8 @@ class CacheDocumentService {
|
|||
|
||||
$filename = $this->generateFileFromContent($content);
|
||||
$document->setLocalCopy($filename);
|
||||
$this->resizeImage($content);
|
||||
|
||||
$this->resizeImage($document, $content);
|
||||
$resized = $this->generateFileFromContent($content);
|
||||
$document->setResizedCopy($resized);
|
||||
}
|
||||
|
@ -165,8 +169,7 @@ class CacheDocumentService {
|
|||
*/
|
||||
private function generateFileFromContent(string $content): string {
|
||||
$filename = $this->uuid();
|
||||
// creating a path aa/bb/cc/dd/ from the filename aabbccdd-0123-[...]
|
||||
$path = chunk_split(substr($filename, 0, 8), 2, '/');
|
||||
$path = $this->generatePath($filename);
|
||||
|
||||
try {
|
||||
$folder = $this->appData->getFolder($path);
|
||||
|
@ -177,7 +180,19 @@ class CacheDocumentService {
|
|||
$cache = $folder->newFile($filename);
|
||||
$cache->putContent($content);
|
||||
|
||||
return $path . $filename;
|
||||
return $filename;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* creating a path aa/bb/cc/dd/ from the filename aabbccdd-0123-[...]
|
||||
*
|
||||
* @param string $filename
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generatePath(string $filename): string {
|
||||
return chunk_split(substr($filename, 0, 8), 2, '/');
|
||||
}
|
||||
|
||||
|
||||
|
@ -205,56 +220,65 @@ class CacheDocumentService {
|
|||
/**
|
||||
* @param string $content
|
||||
*/
|
||||
private function resizeImage(string &$content) {
|
||||
private function resizeImage(Document $document, string &$content): void {
|
||||
try {
|
||||
$image = ImageResize::createFromString($content);
|
||||
$image->quality_jpg = 100;
|
||||
$image->quality_png = 9;
|
||||
$image->quality_jpg = 80;
|
||||
$image->quality_png = 7;
|
||||
|
||||
$image->resizeToBestFit(self::RESIZED_WIDTH, self::RESIZED_HEIGHT);
|
||||
$newContent = $image->getImageAsString();
|
||||
if (!$newContent) {
|
||||
|
||||
if ($newContent) {
|
||||
$content = $newContent;
|
||||
}
|
||||
} catch (ImageResizeException $e) {
|
||||
}
|
||||
|
||||
$document->setLocalCopySize($image->getSourceWidth(), $image->getSourceHeight());
|
||||
$document->setResizedCopySize($image->getDestWidth(), $image->getDestHeight());
|
||||
|
||||
$hash = $this->blurService->generateBlurHash(imagecreatefromstring($content));
|
||||
$document->setBlurHash($hash);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param string $filename
|
||||
*
|
||||
* @return ISimpleFile
|
||||
* @throws CacheContentException
|
||||
* @throws CacheDocumentDoesNotExistException
|
||||
*/
|
||||
public function getContentFromCache(string $path): ISimpleFile {
|
||||
if ($path === '') {
|
||||
public function getContentFromCache(string $filename): ISimpleFile {
|
||||
if ($filename === '') {
|
||||
throw new CacheDocumentDoesNotExistException();
|
||||
}
|
||||
|
||||
// right now, we do not handle cache for local avatar, we need to change this
|
||||
// so the current avatar is cached, or a new avatar is uploaded
|
||||
if ($path === 'avatar') {
|
||||
if ($filename === 'avatar') {
|
||||
throw new CacheContentException();
|
||||
}
|
||||
|
||||
|
||||
$pos = strrpos($path, '/');
|
||||
$dir = substr($path, 0, $pos);
|
||||
$filename = substr($path, $pos + 1);
|
||||
|
||||
try {
|
||||
$file = $this->appData->getFolder($dir)
|
||||
->getFile($filename);
|
||||
|
||||
return $file;
|
||||
return $this->appData->getFolder($this->generatePath($filename))
|
||||
->getFile($filename);
|
||||
} catch (Exception $e) {
|
||||
throw new CacheContentException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function getFromUuid(string $uuid): ISimpleFile {
|
||||
try {
|
||||
return $this->appData->getFolder($this->generatePath($uuid))
|
||||
->getFile($uuid);
|
||||
} catch (NotFoundException $e) {
|
||||
throw new NotFoundException('document not found');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*
|
||||
|
|
|
@ -31,12 +31,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Social\Service;
|
||||
|
||||
use OCA\Social\Tools\Exceptions\MalformedArrayException;
|
||||
use OCA\Social\Tools\Exceptions\RequestContentException;
|
||||
use OCA\Social\Tools\Exceptions\RequestNetworkException;
|
||||
use OCA\Social\Tools\Exceptions\RequestResultNotJsonException;
|
||||
use OCA\Social\Tools\Exceptions\RequestResultSizeException;
|
||||
use OCA\Social\Tools\Exceptions\RequestServerException;
|
||||
use Exception;
|
||||
use OCA\Social\AP;
|
||||
use OCA\Social\Db\ActorsRequest;
|
||||
|
@ -53,6 +47,12 @@ use OCA\Social\Exceptions\UrlCloudException;
|
|||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCA\Social\Model\ActivityPub\Object\Document;
|
||||
use OCA\Social\Model\ActivityPub\Object\Image;
|
||||
use OCA\Social\Tools\Exceptions\MalformedArrayException;
|
||||
use OCA\Social\Tools\Exceptions\RequestContentException;
|
||||
use OCA\Social\Tools\Exceptions\RequestNetworkException;
|
||||
use OCA\Social\Tools\Exceptions\RequestResultNotJsonException;
|
||||
use OCA\Social\Tools\Exceptions\RequestResultSizeException;
|
||||
use OCA\Social\Tools\Exceptions\RequestServerException;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\Files\NotPermittedException;
|
||||
use OCP\Files\SimpleFS\ISimpleFile;
|
||||
|
@ -164,9 +164,9 @@ class DocumentService {
|
|||
$document->setError(self::ERROR_SIZE);
|
||||
$this->cacheDocumentsRequest->endCaching($document);
|
||||
} catch (RequestContentException $e) {
|
||||
$this->cacheDocumentsRequest->deleteById($id);
|
||||
$this->cacheDocumentsRequest->deleteById($document->getId());
|
||||
} catch (UnauthorizedFediverseException $e) {
|
||||
$this->cacheDocumentsRequest->deleteById($id);
|
||||
$this->cacheDocumentsRequest->deleteById($document->getId());
|
||||
} catch (RequestNetworkException $e) {
|
||||
$this->cacheDocumentsRequest->endCaching($document);
|
||||
} catch (RequestServerException $e) {
|
||||
|
@ -208,13 +208,41 @@ class DocumentService {
|
|||
* @throws MalformedArrayException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function getFromCache(string $id, string &$mimeType = '', bool $public = false): ISimpleFile {
|
||||
public function getFromCache(
|
||||
string $id, string &$mimeType = '', bool $public = false
|
||||
): ISimpleFile {
|
||||
$document = $this->cacheRemoteDocument($id, $public);
|
||||
$mimeType = $document->getMimeType();
|
||||
|
||||
return $this->cacheService->getContentFromCache($document->getLocalCopy());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uuid
|
||||
*
|
||||
* @return ISimpleFile
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function getFromUuid(string $uuid): ISimpleFile {
|
||||
if (preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/', $uuid)
|
||||
!== 1) {
|
||||
throw new NotFoundException('invalid document');
|
||||
}
|
||||
|
||||
return $this->cacheService->getFromUuid($uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $getMediaIds
|
||||
* @param string $account
|
||||
*
|
||||
* @return Document[]
|
||||
*/
|
||||
public function getMediaFromArray(array $getMediaIds, string $account = ''): array {
|
||||
return $this->cacheDocumentsRequest->getFromArray($getMediaIds, $account);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
|
|
|
@ -106,13 +106,14 @@ class PostService {
|
|||
|
||||
$note->setAttributedTo($actor->getId());
|
||||
$note->setContent(htmlentities($post->getContent(), ENT_QUOTES));
|
||||
$note->setAttachments($post->getMedias());
|
||||
|
||||
$this->generateDocumentsFromAttachments($note, $post);
|
||||
// $this->generateDocumentsFromAttachments($note, $post);
|
||||
|
||||
$this->streamService->replyTo($note, $post->getReplyTo());
|
||||
$this->streamService->addRecipients($note, $post->getType(), $post->getTo());
|
||||
$this->streamService->addHashtags($note, $post->getHashtags());
|
||||
$this->streamService->addAttachments($note, $post->getDocuments());
|
||||
// $this->streamService->addAttachments($note, $post->getDocuments());
|
||||
|
||||
$token = $this->activityService->createActivity($actor, $note, $activity);
|
||||
$this->accountService->cacheLocalActorDetailCount($actor);
|
||||
|
|
|
@ -41,7 +41,6 @@ use OCA\Social\Exceptions\StreamNotFoundException;
|
|||
use OCA\Social\Exceptions\UnauthorizedFediverseException;
|
||||
use OCA\Social\Model\ActivityPub\ACore;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCA\Social\Model\ActivityPub\Object\Document;
|
||||
use OCA\Social\Model\ActivityPub\Object\Note;
|
||||
use OCA\Social\Model\ActivityPub\Stream;
|
||||
use OCA\Social\Model\Client\Options\TimelineOptions;
|
||||
|
@ -98,7 +97,7 @@ class StreamService {
|
|||
* @throws SocialAppConfigException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function assignItem(Acore &$stream, Person $actor, string $type) {
|
||||
public function assignItem(Acore $stream, Person $actor, string $type) {
|
||||
$stream->setId($this->configService->generateId('@' . $actor->getPreferredUsername()));
|
||||
$stream->setPublished(date("c"));
|
||||
|
||||
|
@ -282,13 +281,6 @@ class StreamService {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Note $note
|
||||
* @param Document[] $documents
|
||||
*/
|
||||
public function addAttachments(Note $note, array $documents) {
|
||||
$note->setAttachments($documents);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -357,6 +349,14 @@ class StreamService {
|
|||
return $this->streamRequest->getStreamById($id, $asViewer, $format);
|
||||
}
|
||||
|
||||
// TODO: returns context for status
|
||||
public function getContextByNid(int $nid): array {
|
||||
return [
|
||||
'ancestors' => [],
|
||||
'descendants' => []
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
|
|
Ładowanie…
Reference in New Issue