aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorJérémy Benoist <j0k3r@users.noreply.github.com>2017-05-31 17:26:05 +0200
committerGitHub <noreply@github.com>2017-05-31 17:26:05 +0200
commitec8e7ffad48c9920b4b63b8e278c8bec1fc6f480 (patch)
tree1f4387becf57b376759e72c6a8de28693776de6d /src
parent4423b88c5b2c2d530b0a83a822f521a61ca4d4b8 (diff)
parent4368a27152021fd5a5ac09109eb0260d69c54c3c (diff)
downloadwallabag-ec8e7ffad48c9920b4b63b8e278c8bec1fc6f480.tar.gz
wallabag-ec8e7ffad48c9920b4b63b8e278c8bec1fc6f480.tar.zst
wallabag-ec8e7ffad48c9920b4b63b8e278c8bec1fc6f480.zip
Merge pull request #3106 from wallabag/api-content
Allow other fields to be send using API
Diffstat (limited to 'src')
-rw-r--r--src/Wallabag/ApiBundle/Controller/EntryRestController.php52
-rw-r--r--src/Wallabag/CoreBundle/Helper/ContentProxy.php34
2 files changed, 62 insertions, 24 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
index 31bb67fd..c3ba1858 100644
--- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php
+++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
@@ -273,6 +273,9 @@ class EntryRestController extends WallabagRestController
273 /** 273 /**
274 * Create an entry. 274 * Create an entry.
275 * 275 *
276 * If you want to provide the HTML content (which means wallabag won't fetch it from the url), you must provide `content`, `title` & `url` fields **non-empty**.
277 * Otherwise, content will be fetched as normal from the url and values will be overwritten.
278 *
276 * @ApiDoc( 279 * @ApiDoc(
277 * parameters={ 280 * parameters={
278 * {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."}, 281 * {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."},
@@ -280,6 +283,11 @@ class EntryRestController extends WallabagRestController
280 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."}, 283 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
281 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already starred"}, 284 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already starred"},
282 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already archived"}, 285 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already archived"},
286 * {"name"="content", "dataType"="string", "required"=false, "description"="Content of the entry"},
287 * {"name"="language", "dataType"="string", "required"=false, "description"="Language of the entry"},
288 * {"name"="preview_picture", "dataType"="string", "required"=false, "description"="Preview picture of the entry"},
289 * {"name"="published_at", "dataType"="datetime|integer", "format"="YYYY-MM-DDTHH:II:SS+TZ or a timestamp", "required"=false, "description"="Published date of the entry"},
290 * {"name"="authors", "dataType"="string", "format"="Name Firstname,author2,author3", "required"=false, "description"="Authors of the entry"},
283 * } 291 * }
284 * ) 292 * )
285 * 293 *
@@ -291,32 +299,46 @@ class EntryRestController extends WallabagRestController
291 299
292 $url = $request->request->get('url'); 300 $url = $request->request->get('url');
293 $title = $request->request->get('title'); 301 $title = $request->request->get('title');
302 $tags = $request->request->get('tags', []);
294 $isArchived = $request->request->get('archive'); 303 $isArchived = $request->request->get('archive');
295 $isStarred = $request->request->get('starred'); 304 $isStarred = $request->request->get('starred');
305 $content = $request->request->get('content');
306 $language = $request->request->get('language');
307 $picture = $request->request->get('preview_picture');
308 $publishedAt = $request->request->get('published_at');
309 $authors = $request->request->get('authors', '');
296 310
297 $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId()); 311 $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId());
298 312
299 if (false === $entry) { 313 if (false === $entry) {
300 $entry = new Entry($this->getUser()); 314 $entry = new Entry($this->getUser());
301 try {
302 $entry = $this->get('wallabag_core.content_proxy')->updateEntry(
303 $entry,
304 $url
305 );
306 } catch (\Exception $e) {
307 $this->get('logger')->error('Error while saving an entry', [
308 'exception' => $e,
309 'entry' => $entry,
310 ]);
311 $entry->setUrl($url);
312 }
313 } 315 }
314 316
315 if (!is_null($title)) { 317 try {
316 $entry->setTitle($title); 318 $entry = $this->get('wallabag_core.content_proxy')->updateEntry(
319 $entry,
320 $url,
321 [
322 'title' => $title,
323 'html' => $content,
324 'url' => $url,
325 'language' => $language,
326 'date' => $publishedAt,
327 // faking the preview picture
328 'open_graph' => [
329 'og_image' => $picture,
330 ],
331 'authors' => explode(',', $authors),
332 ]
333 );
334 } catch (\Exception $e) {
335 $this->get('logger')->error('Error while saving an entry', [
336 'exception' => $e,
337 'entry' => $entry,
338 ]);
339 $entry->setUrl($url);
317 } 340 }
318 341
319 $tags = $request->request->get('tags', '');
320 if (!empty($tags)) { 342 if (!empty($tags)) {
321 $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags); 343 $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags);
322 } 344 }
diff --git a/src/Wallabag/CoreBundle/Helper/ContentProxy.php b/src/Wallabag/CoreBundle/Helper/ContentProxy.php
index 4b3e6fbb..8ba77ca9 100644
--- a/src/Wallabag/CoreBundle/Helper/ContentProxy.php
+++ b/src/Wallabag/CoreBundle/Helper/ContentProxy.php
@@ -31,7 +31,7 @@ class ContentProxy
31 } 31 }
32 32
33 /** 33 /**
34 * Fetch content using graby and hydrate given entry with results information. 34 * Fetch content using graby and hydrate given $entry with results information.
35 * In case we couldn't find content, we'll try to use Open Graph data. 35 * In case we couldn't find content, we'll try to use Open Graph data.
36 * 36 *
37 * We can also force the content, in case of an import from the v1 for example, so the function won't 37 * We can also force the content, in case of an import from the v1 for example, so the function won't
@@ -39,12 +39,17 @@ class ContentProxy
39 * 39 *
40 * @param Entry $entry Entry to update 40 * @param Entry $entry Entry to update
41 * @param string $url Url to grab content for 41 * @param string $url Url to grab content for
42 * @param array $content An array with AT LEAST keys title, html, url, language & content_type to skip the fetchContent from the url 42 * @param array $content An array with AT LEAST keys title, html, url to skip the fetchContent from the url
43 * 43 *
44 * @return Entry 44 * @return Entry
45 */ 45 */
46 public function updateEntry(Entry $entry, $url, array $content = []) 46 public function updateEntry(Entry $entry, $url, array $content = [])
47 { 47 {
48 // ensure content is a bit cleaned up
49 if (!empty($content['html'])) {
50 $content['html'] = $this->graby->cleanupHtml($content['html'], $url);
51 }
52
48 // do we have to fetch the content or the provided one is ok? 53 // do we have to fetch the content or the provided one is ok?
49 if (empty($content) || false === $this->validateContent($content)) { 54 if (empty($content) || false === $this->validateContent($content)) {
50 $fetchedContent = $this->graby->fetchContent($url); 55 $fetchedContent = $this->graby->fetchContent($url);
@@ -57,7 +62,7 @@ class ContentProxy
57 } 62 }
58 63
59 $title = $content['title']; 64 $title = $content['title'];
60 if (!$title && isset($content['open_graph']['og_title'])) { 65 if (!$title && !empty($content['open_graph']['og_title'])) {
61 $title = $content['open_graph']['og_title']; 66 $title = $content['open_graph']['og_title'];
62 } 67 }
63 68
@@ -65,7 +70,7 @@ class ContentProxy
65 if (false === $html) { 70 if (false === $html) {
66 $html = $this->fetchingErrorMessage; 71 $html = $this->fetchingErrorMessage;
67 72
68 if (isset($content['open_graph']['og_description'])) { 73 if (!empty($content['open_graph']['og_description'])) {
69 $html .= '<p><i>But we found a short description: </i></p>'; 74 $html .= '<p><i>But we found a short description: </i></p>';
70 $html .= $content['open_graph']['og_description']; 75 $html .= $content['open_graph']['og_description'];
71 } 76 }
@@ -76,8 +81,19 @@ class ContentProxy
76 $entry->setContent($html); 81 $entry->setContent($html);
77 $entry->setHttpStatus(isset($content['status']) ? $content['status'] : ''); 82 $entry->setHttpStatus(isset($content['status']) ? $content['status'] : '');
78 83
79 if (isset($content['date']) && null !== $content['date'] && '' !== $content['date']) { 84 if (!empty($content['date'])) {
80 $entry->setPublishedAt(new \DateTime($content['date'])); 85 $date = $content['date'];
86
87 // is it a timestamp?
88 if (filter_var($date, FILTER_VALIDATE_INT) !== false) {
89 $date = '@'.$content['date'];
90 }
91
92 try {
93 $entry->setPublishedAt(new \DateTime($date));
94 } catch (\Exception $e) {
95 $this->logger->warning('Error while defining date', ['e' => $e, 'url' => $url, 'date' => $content['date']]);
96 }
81 } 97 }
82 98
83 if (!empty($content['authors'])) { 99 if (!empty($content['authors'])) {
@@ -97,12 +113,12 @@ class ContentProxy
97 $entry->setDomainName($domainName); 113 $entry->setDomainName($domainName);
98 } 114 }
99 115
100 if (isset($content['open_graph']['og_image']) && $content['open_graph']['og_image']) { 116 if (!empty($content['open_graph']['og_image'])) {
101 $entry->setPreviewPicture($content['open_graph']['og_image']); 117 $entry->setPreviewPicture($content['open_graph']['og_image']);
102 } 118 }
103 119
104 // if content is an image define as a preview too 120 // if content is an image define as a preview too
105 if (isset($content['content_type']) && in_array($this->mimeGuesser->guess($content['content_type']), ['jpeg', 'jpg', 'gif', 'png'], true)) { 121 if (!empty($content['content_type']) && in_array($this->mimeGuesser->guess($content['content_type']), ['jpeg', 'jpg', 'gif', 'png'], true)) {
106 $entry->setPreviewPicture($content['url']); 122 $entry->setPreviewPicture($content['url']);
107 } 123 }
108 124
@@ -128,6 +144,6 @@ class ContentProxy
128 */ 144 */
129 private function validateContent(array $content) 145 private function validateContent(array $content)
130 { 146 {
131 return isset($content['title']) && isset($content['html']) && isset($content['url']) && isset($content['language']) && isset($content['content_type']); 147 return !empty($content['title']) && !empty($content['html']) && !empty($content['url']);
132 } 148 }
133} 149}