Completed
Push — master ( b4b2b8...95370d )
by Maxence
02:36
created

BookmarksService::generateDocuments()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 21
rs 9.0534
cc 4
eloc 13
nc 4
nop 1
1
<?php
2
/**
3
 * Bookmarks_FullTextSearch - Indexing bookmarks
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2018
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
namespace OCA\Bookmarks_FullTextSearch\Service;
28
29
30
use Exception;
31
use OCA\Bookmarks\Controller\Lib\Bookmarks;
32
use OCA\Bookmarks_FullTextSearch\Exceptions\WebpageIsNotIndexableException;
33
use OCA\Bookmarks_FullTextSearch\Model\BookmarksDocument;
34
use OCA\FullTextSearch\Model\DocumentAccess;
35
use OCA\FullTextSearch\Model\Index;
36
use OCA\FullTextSearch\Model\IndexDocument;
37
use OCA\FullTextSearch\Model\Runner;
38
use OCP\AppFramework\IAppContainer;
39
use OCP\AppFramework\QueryException;
40
41
class BookmarksService {
42
43
	const DOCUMENT_TYPE = 'bookmarks';
44
45
46
	/** @var ConfigService */
47
	private $configService;
48
49
	/** @var MiscService */
50
	private $miscService;
51
52
	/** @var Bookmarks */
53
	private $bookmarksClass;
54
55
56
	/**
57
	 * BookmarksService constructor.
58
	 *
59
	 * @param IAppContainer $container
60
	 * @param ConfigService $configService
61
	 * @param MiscService $miscService
62
	 */
63
	public function __construct(
64
		IAppContainer $container, ConfigService $configService, MiscService $miscService
65
	) {
66
		$this->configService = $configService;
67
		$this->miscService = $miscService;
68
69
		try {
70
			$this->bookmarksClass = $container->query(Bookmarks::class);
71
		} catch (QueryException $e) {
72
			/** we do nothing */
73
		}
74
	}
75
76
77
	/**
78
	 * @param Runner $runner
79
	 * @param string $userId
80
	 *
81
	 * @return BookmarksDocument[]
82
	 */
83
	public function getBookmarksFromUser(Runner $runner, $userId) {
84
85
		$bookmarks = $this->bookmarksClass->findBookmarks($userId, 0, 'id', [], false, -1);
86
87
		$documents = [];
88
		foreach ($bookmarks as $bookmark) {
89
			$document = $this->generateBookmarksDocumentFromBookmark($bookmark, $userId);
90
91
			$documents[] = $document;
92
		}
93
94
		return $documents;
95
	}
96
97
98
	/**
99
	 * @param BookmarksDocument[] $documents
100
	 *
101
	 * TODO - update $document with a error status instead of just ignore !
102
	 * @return array
103
	 */
104
	public function generateDocuments($documents) {
105
106
		$index = [];
107
		foreach ($documents as $document) {
108
			if (!($document instanceof BookmarksDocument)) {
109
				continue;
110
			}
111
112
			try {
113
				$this->updateDocumentFromBookmarksDocument($document);
114
			} catch (Exception $e) {
115
				$document->getIndex()
116
						 ->setStatus(Index::INDEX_IGNORE);
117
				echo 'Exception: ' . json_encode($e->getTrace()) . ' - ' . $e->getMessage() . "\n";
118
			}
119
120
			$index[] = $document;
121
		}
122
123
		return $index;
124
	}
125
126
127
	/**
128
	 * @param BookmarksDocument $document
129
	 *
130
	 * @throws WebpageIsNotIndexableException
131
	 */
132
	private function updateDocumentFromBookmarksDocument(BookmarksDocument $document) {
133
		$html = $this->getWebpageFromUrl($document->getSource());
134
135
		$document->setContent(base64_encode($html), IndexDocument::ENCODED_BASE64);
136
	}
137
138
139
	/**
140
	 * @param $url
141
	 *
142
	 * @return mixed
143
	 * @throws WebpageIsNotIndexableException
144
	 */
145
	private function getWebpageFromUrl($url) {
146
		$curl = curl_init($url);
147
		curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
148
		curl_setopt($curl, CURLOPT_TIMEOUT, 10);
149
150
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
151
152
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
153
		curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
154
155
		$html = curl_exec($curl);
156
		if (curl_error($curl)) {
157
			throw new WebpageIsNotIndexableException('Webpage is not reachable');
158
		}
159
160
		curl_close($curl);
161
162
		return $html;
163
	}
164
165
166
	/**
167
	 * @param IndexDocument $document
168
	 *
169
	 * @return bool
170
	 */
171
	public function isDocumentUpToDate($document) {
172
		$index = $document->getIndex();
173
174
		if ($index->getStatus() !== Index::INDEX_OK) {
175
			return false;
176
		}
177
178
		$s = $this->configService->getAppValue(ConfigService::BOOKMARKS_TTL) * 3600 * 24;
179
		return ($index->getLastIndex() > time() - $s);
180
	}
181
182
183
	/**
184
	 * @param $bookmark
185
	 * @param $userId
186
	 *
187
	 * @return BookmarksDocument
188
	 */
189
	private function generateBookmarksDocumentFromBookmark($bookmark, $userId) {
190
		$document = new BookmarksDocument($bookmark['id']);
191
192
		$document->setAccess(new DocumentAccess($userId))
193
				 ->setModifiedTime($bookmark['lastmodified'])
194
				 ->setSource($bookmark['url'])
195
				 ->setTitle($bookmark['title'])
196
				 ->setTags($bookmark['tags']);
197
198
		return $document;
199
	}
200
201
202
	/**
203
	 * @param Index $index
204
	 *
205
	 * @return null|BookmarksDocument
206
	 */
207
	public function updateDocument(Index $index) {
208
		try {
209
			$document = $this->generateDocumentFromIndex($index);
210
211
			return $document;
212
		} catch (WebpageIsNotIndexableException $e) {
213
			return null;
214
		}
215
	}
216
217
218
	/**
219
	 * @param Index $index
220
	 *
221
	 * @return BookmarksDocument
222
	 * @throws WebpageIsNotIndexableException
223
	 */
224
	private function generateDocumentFromIndex(Index $index) {
225
226
		$bookmark =
227
			$this->bookmarksClass->findUniqueBookmark(
228
				$index->getDocumentId(), $index->getOwnerId()
229
			);
230
231
		if (sizeof($bookmark) === 0) {
232
			$index->setStatus(Index::INDEX_REMOVE);
233
			$document = new BookmarksDocument($index->getDocumentId());
234
			$document->setIndex($index);
235
236
			return $document;
237
		}
238
239
		$document = $this->generateBookmarksDocumentFromBookmark($bookmark, $index->getOwnerId());
240
		$document->setIndex($index);
241
242
		$this->updateDocumentFromBookmarksDocument($document);
243
244
		return $document;
245
	}
246
247
248
}