Skip to content

Commit b3eb0bf

Browse files
authored
Merge pull request #33494 from nextcloud/enh/references
Backend for reference metadata fetching
2 parents 4209dc7 + 1ab6698 commit b3eb0bf

23 files changed

+1212
-2
lines changed

3rdparty

Submodule 3rdparty updated 100 files

build/psalm-baseline.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2417,6 +2417,13 @@
24172417
<code>bool|mixed</code>
24182418
</LessSpecificImplementedReturnType>
24192419
</file>
2420+
<file src="lib/private/Collaboration/Reference/File/FileReferenceEventListener.php">
2421+
<InvalidArgument occurrences="3">
2422+
<code>addServiceListener</code>
2423+
<code>addServiceListener</code>
2424+
<code>addServiceListener</code>
2425+
</InvalidArgument>
2426+
</file>
24202427
<file src="lib/private/Command/CallableJob.php">
24212428
<ParamNameMismatch occurrences="1">
24222429
<code>$serializedCallable</code>

config/config.sample.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2245,4 +2245,11 @@
22452245
* Defaults to ``true``
22462246
*/
22472247
'bulkupload.enabled' => true,
2248+
2249+
/**
2250+
* Enables fetching open graph metadata from remote urls
2251+
*
2252+
* Defaults to ``true``
2253+
*/
2254+
'reference_opengraph' => true,
22482255
];
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* @copyright Copyright (c) 2022 Julius Härtl <jus@bitgrid.net>
6+
*
7+
* @author Julius Härtl <jus@bitgrid.net>
8+
*
9+
* @license GNU AGPL version 3 or any later version
10+
*
11+
* This program is free software: you can redistribute it and/or modify
12+
* it under the terms of the GNU Affero General Public License as
13+
* published by the Free Software Foundation, either version 3 of the
14+
* License, or (at your option) any later version.
15+
*
16+
* This program is distributed in the hope that it will be useful,
17+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU Affero General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU Affero General Public License
22+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
23+
*/
24+
25+
namespace OC\Core\Controller;
26+
27+
use OCP\AppFramework\Http\DataResponse;
28+
use OCP\Collaboration\Reference\IReferenceManager;
29+
use OCP\IRequest;
30+
31+
class ReferenceApiController extends \OCP\AppFramework\OCSController {
32+
private IReferenceManager $referenceManager;
33+
34+
public function __construct(string $appName, IRequest $request, IReferenceManager $referenceManager) {
35+
parent::__construct($appName, $request);
36+
$this->referenceManager = $referenceManager;
37+
}
38+
39+
/**
40+
* @NoAdminRequired
41+
*/
42+
public function extract(string $text, bool $resolve = false, int $limit = 1): DataResponse {
43+
$references = $this->referenceManager->extractReferences($text);
44+
45+
$result = [];
46+
$index = 0;
47+
foreach ($references as $reference) {
48+
if ($index++ >= $limit) {
49+
break;
50+
}
51+
52+
$result[$reference] = $resolve ? $this->referenceManager->resolveReference($reference) : null;
53+
}
54+
55+
return new DataResponse([
56+
'references' => $result
57+
]);
58+
}
59+
60+
61+
/**
62+
* @NoAdminRequired
63+
*
64+
* @param string[] $references
65+
*/
66+
public function resolve(array $references, int $limit = 1): DataResponse {
67+
$result = [];
68+
$index = 0;
69+
foreach ($references as $reference) {
70+
if ($index++ >= $limit) {
71+
break;
72+
}
73+
74+
$result[$reference] = $this->referenceManager->resolveReference($reference);
75+
}
76+
77+
return new DataResponse([
78+
'references' => array_filter($result)
79+
]);
80+
}
81+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* @copyright Copyright (c) 2022 Julius Härtl <jus@bitgrid.net>
6+
*
7+
* @author Julius Härtl <jus@bitgrid.net>
8+
*
9+
* @license GNU AGPL version 3 or any later version
10+
*
11+
* This program is free software: you can redistribute it and/or modify
12+
* it under the terms of the GNU Affero General Public License as
13+
* published by the Free Software Foundation, either version 3 of the
14+
* License, or (at your option) any later version.
15+
*
16+
* This program is distributed in the hope that it will be useful,
17+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU Affero General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU Affero General Public License
22+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
23+
*/
24+
25+
namespace OC\Core\Controller;
26+
27+
use OCP\AppFramework\Http\Response;
28+
use OCP\Collaboration\Reference\IReferenceManager;
29+
use OCP\AppFramework\Controller;
30+
use OCP\AppFramework\Http;
31+
use OCP\AppFramework\Http\DataDownloadResponse;
32+
use OCP\AppFramework\Http\DataResponse;
33+
use OCP\Files\AppData\IAppDataFactory;
34+
use OCP\Files\NotFoundException;
35+
use OCP\Files\NotPermittedException;
36+
use OCP\IRequest;
37+
38+
class ReferenceController extends Controller {
39+
private IReferenceManager $referenceManager;
40+
private IAppDataFactory $appDataFactory;
41+
42+
public function __construct(string $appName, IRequest $request, IReferenceManager $referenceManager, IAppDataFactory $appDataFactory) {
43+
parent::__construct($appName, $request);
44+
$this->referenceManager = $referenceManager;
45+
$this->appDataFactory = $appDataFactory;
46+
}
47+
48+
/**
49+
* @PublicPage
50+
* @NoCSRFRequired
51+
*/
52+
public function preview(string $referenceId): Response {
53+
$reference = $this->referenceManager->getReferenceByCacheKey($referenceId);
54+
if ($reference === null) {
55+
return new DataResponse('', Http::STATUS_NOT_FOUND);
56+
}
57+
58+
try {
59+
$appData = $this->appDataFactory->get('core');
60+
$folder = $appData->getFolder('opengraph');
61+
$file = $folder->getFile($referenceId);
62+
return new DataDownloadResponse($file->getContent(), $referenceId, $reference->getImageContentType());
63+
} catch (NotFoundException|NotPermittedException $e) {
64+
return new DataResponse('', Http::STATUS_NOT_FOUND);
65+
}
66+
}
67+
}

core/routes.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
['name' => 'Preview#getPreviewByFileId', 'url' => '/core/preview', 'verb' => 'GET'],
8080
['name' => 'Preview#getPreview', 'url' => '/core/preview.png', 'verb' => 'GET'],
8181
['name' => 'RecommendedApps#index', 'url' => '/core/apps/recommended', 'verb' => 'GET'],
82+
['name' => 'Reference#preview', 'url' => '/core/references/preview/{referenceId}', 'verb' => 'GET'],
8283
['name' => 'Css#getCss', 'url' => '/css/{appName}/{fileName}', 'verb' => 'GET'],
8384
['name' => 'Js#getJs', 'url' => '/js/{appName}/{fileName}', 'verb' => 'GET'],
8485
['name' => 'contactsMenu#index', 'url' => '/contactsmenu/contacts', 'verb' => 'POST'],
@@ -120,6 +121,9 @@
120121
['root' => '/collaboration', 'name' => 'CollaborationResources#getCollectionsByResource', 'url' => '/resources/{resourceType}/{resourceId}', 'verb' => 'GET'],
121122
['root' => '/collaboration', 'name' => 'CollaborationResources#createCollectionOnResource', 'url' => '/resources/{baseResourceType}/{baseResourceId}', 'verb' => 'POST'],
122123

124+
['root' => '/references', 'name' => 'ReferenceApi#extract', 'url' => '/extract', 'verb' => 'POST'],
125+
['root' => '/references', 'name' => 'ReferenceApi#resolve', 'url' => '/resolve', 'verb' => 'POST'],
126+
123127
['root' => '/profile', 'name' => 'ProfileApi#setVisibility', 'url' => '/{targetUserId}', 'verb' => 'PUT'],
124128

125129
// Unified search

core/src/OCP/comments.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import $ from 'jquery'
3131
*
3232
* The downside: anything not ascii is excluded. Not sure how common it is in areas using different
3333
* alphabets… the upside: fake domains with similar looking characters won't be formatted as links
34+
*
35+
* This is a copy of the backend regex in IURLGenerator, make sure to adjust both when changing
3436
*/
3537
const urlRegex = /(\s|^)(https?:\/\/)?((?:[-A-Z0-9+_]+\.)+[-A-Z]+(?:\/[-A-Z0-9+&@#%?=~_|!:,.;()]*)*)(\s|$)/ig
3638

dist/core-main.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/base.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,7 @@ public static function init() {
750750
self::registerEncryptionWrapperAndHooks();
751751
self::registerAccountHooks();
752752
self::registerResourceCollectionHooks();
753+
self::registerFileReferenceEventListener();
753754
self::registerAppRestrictionsHooks();
754755

755756
// Make sure that the application class is not loaded before the database is setup
@@ -912,6 +913,10 @@ private static function registerResourceCollectionHooks() {
912913
\OC\Collaboration\Resources\Listener::register(Server::get(SymfonyAdapter::class), Server::get(IEventDispatcher::class));
913914
}
914915

916+
private static function registerFileReferenceEventListener() {
917+
\OC\Collaboration\Reference\File\FileReferenceEventListener::register(Server::get(IEventDispatcher::class));
918+
}
919+
915920
/**
916921
* register hooks for the filesystem
917922
*/

lib/composer/composer/autoload_classmap.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@
142142
'OCP\\Collaboration\\Collaborators\\ISearchPlugin' => $baseDir . '/lib/public/Collaboration/Collaborators/ISearchPlugin.php',
143143
'OCP\\Collaboration\\Collaborators\\ISearchResult' => $baseDir . '/lib/public/Collaboration/Collaborators/ISearchResult.php',
144144
'OCP\\Collaboration\\Collaborators\\SearchResultType' => $baseDir . '/lib/public/Collaboration/Collaborators/SearchResultType.php',
145+
'OCP\\Collaboration\\Reference\\IReference' => $baseDir . '/lib/public/Collaboration/Reference/IReference.php',
146+
'OCP\\Collaboration\\Reference\\IReferenceManager' => $baseDir . '/lib/public/Collaboration/Reference/IReferenceManager.php',
147+
'OCP\\Collaboration\\Reference\\IReferenceProvider' => $baseDir . '/lib/public/Collaboration/Reference/IReferenceProvider.php',
145148
'OCP\\Collaboration\\Resources\\CollectionException' => $baseDir . '/lib/public/Collaboration/Resources/CollectionException.php',
146149
'OCP\\Collaboration\\Resources\\ICollection' => $baseDir . '/lib/public/Collaboration/Resources/ICollection.php',
147150
'OCP\\Collaboration\\Resources\\IManager' => $baseDir . '/lib/public/Collaboration/Resources/IManager.php',
@@ -823,6 +826,11 @@
823826
'OC\\Collaboration\\Collaborators\\Search' => $baseDir . '/lib/private/Collaboration/Collaborators/Search.php',
824827
'OC\\Collaboration\\Collaborators\\SearchResult' => $baseDir . '/lib/private/Collaboration/Collaborators/SearchResult.php',
825828
'OC\\Collaboration\\Collaborators\\UserPlugin' => $baseDir . '/lib/private/Collaboration/Collaborators/UserPlugin.php',
829+
'OC\\Collaboration\\Reference\\File\\FileReferenceEventListener' => $baseDir . '/lib/private/Collaboration/Reference/File/FileReferenceEventListener.php',
830+
'OC\\Collaboration\\Reference\\File\\FileReferenceProvider' => $baseDir . '/lib/private/Collaboration/Reference/File/FileReferenceProvider.php',
831+
'OC\\Collaboration\\Reference\\LinkReferenceProvider' => $baseDir . '/lib/private/Collaboration/Reference/LinkReferenceProvider.php',
832+
'OC\\Collaboration\\Reference\\Reference' => $baseDir . '/lib/private/Collaboration/Reference/Reference.php',
833+
'OC\\Collaboration\\Reference\\ReferenceManager' => $baseDir . '/lib/private/Collaboration/Reference/ReferenceManager.php',
826834
'OC\\Collaboration\\Resources\\Collection' => $baseDir . '/lib/private/Collaboration/Resources/Collection.php',
827835
'OC\\Collaboration\\Resources\\Listener' => $baseDir . '/lib/private/Collaboration/Resources/Listener.php',
828836
'OC\\Collaboration\\Resources\\Manager' => $baseDir . '/lib/private/Collaboration/Resources/Manager.php',
@@ -975,6 +983,8 @@
975983
'OC\\Core\\Controller\\ProfileApiController' => $baseDir . '/core/Controller/ProfileApiController.php',
976984
'OC\\Core\\Controller\\ProfilePageController' => $baseDir . '/core/Controller/ProfilePageController.php',
977985
'OC\\Core\\Controller\\RecommendedAppsController' => $baseDir . '/core/Controller/RecommendedAppsController.php',
986+
'OC\\Core\\Controller\\ReferenceApiController' => $baseDir . '/core/Controller/ReferenceApiController.php',
987+
'OC\\Core\\Controller\\ReferenceController' => $baseDir . '/core/Controller/ReferenceController.php',
978988
'OC\\Core\\Controller\\SearchController' => $baseDir . '/core/Controller/SearchController.php',
979989
'OC\\Core\\Controller\\SetupController' => $baseDir . '/core/Controller/SetupController.php',
980990
'OC\\Core\\Controller\\TwoFactorChallengeController' => $baseDir . '/core/Controller/TwoFactorChallengeController.php',

0 commit comments

Comments
 (0)