summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBernhard Posselt <dev@bernhard-posselt.com>2016-05-28 12:49:48 +0200
committerBernhard Posselt <dev@bernhard-posselt.com>2016-05-28 12:49:48 +0200
commit782896cb44c6d64af088c951768d6ec1fb0b0f9f (patch)
tree94a8c06287e05a84a789d515d3fb0aaf45fe759a
parenta92d104327a34c0c64ac0443a2c39dc29749a15c (diff)
Add content hash to items
-rw-r--r--appinfo/database.xml6
-rw-r--r--appinfo/info.xml2
-rw-r--r--db/item.php40
-rw-r--r--docs/developer/External-Api.md2
-rw-r--r--tests/unit/db/ItemTest.php4
-rw-r--r--tests/unit/upgrade/UpgradeTest.php4
-rw-r--r--upgrade/upgrade.php2
7 files changed, 36 insertions, 24 deletions
diff --git a/appinfo/database.xml b/appinfo/database.xml
index 5c17aba15..d12df002e 100644
--- a/appinfo/database.xml
+++ b/appinfo/database.xml
@@ -266,6 +266,12 @@
<length>32</length>
</field>
<field>
+ <name>content_hash</name>
+ <type>text</type>
+ <notnull>false</notnull>
+ <length>32</length>
+ </field>
+ <field>
<name>rtl</name>
<type>boolean</type>
<notnull>true</notnull>
diff --git a/appinfo/info.xml b/appinfo/info.xml
index 55e5d1b20..4957844b2 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -7,7 +7,7 @@
<author>Bernhard Posselt, Alessandro Cosentino, Jan-Christoph Borchardt</author>
<category>multimedia</category>
<licence>AGPL</licence>
- <version>8.8.0</version>
+ <version>8.8.2</version>
<namespace>News</namespace>
<!-- resources -->
diff --git a/db/item.php b/db/item.php
index 1ef74061e..e0d8b069b 100644
--- a/db/item.php
+++ b/db/item.php
@@ -5,8 +5,8 @@
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
- * @author Alessandro Cosentino <cosenal@gmail.com>
- * @author Bernhard Posselt <dev@bernhard-posselt.com>
+ * @author Alessandro Cosentino <cosenal@gmail.com>
+ * @author Bernhard Posselt <dev@bernhard-posselt.com>
* @copyright Alessandro Cosentino 2012
* @copyright Bernhard Posselt 2012, 2014
*/
@@ -15,7 +15,6 @@ namespace OCA\News\Db;
use \OCP\AppFramework\Db\Entity;
-
/**
* @method integer getId()
* @method void setId(integer $value)
@@ -28,6 +27,7 @@ use \OCP\AppFramework\Db\Entity;
* @method string getAuthor()
* @method string getRtl()
* @method string getFingerprint()
+ * @method string getContentHash()
* @method integer getPubDate()
* @method void setPubDate(integer $value)
* @method string getBody()
@@ -43,12 +43,14 @@ use \OCP\AppFramework\Db\Entity;
* @method integer getLastModified()
* @method void setLastModified(integer $value)
* @method void setFingerprint(string $value)
+ * @method void setContentHash(string $value)
* @method void setSearchIndex(string $value)
*/
class Item extends Entity implements IAPI, \JsonSerializable {
use EntityJSONSerializer;
+ protected $contentHash;
protected $guidHash;
protected $guid;
protected $url;
@@ -65,7 +67,7 @@ class Item extends Entity implements IAPI, \JsonSerializable {
protected $rtl;
protected $fingerprint;
- public function __construct(){
+ public function __construct() {
$this->addType('pubDate', 'integer');
$this->addType('feedId', 'integer');
$this->addType('status', 'integer');
@@ -73,7 +75,6 @@ class Item extends Entity implements IAPI, \JsonSerializable {
$this->addType('rtl', 'boolean');
}
-
public function setRead() {
$this->markFieldUpdated('status');
$this->status &= ~StatusFlag::UNREAD;
@@ -131,7 +132,7 @@ class Item extends Entity implements IAPI, \JsonSerializable {
'lastModified' => $this->getLastModified(),
'rtl' => $this->getRtl(),
'intro' => $this->getIntro(),
- 'fingerprint' => $this->getFingerprint()
+ 'fingerprint' => $this->getFingerprint(),
];
}
@@ -152,11 +153,11 @@ class Item extends Entity implements IAPI, \JsonSerializable {
'starred' => $this->isStarred(),
'lastModified' => $this->getLastModified(),
'rtl' => $this->getRtl(),
- 'fingerprint' => $this->getFingerprint()
+ 'fingerprint' => $this->getFingerprint(),
+ 'contentHash' => $this->getContentHash()
];
}
-
public function toExport($feeds) {
return [
'guid' => $this->getGuid(),
@@ -169,12 +170,11 @@ class Item extends Entity implements IAPI, \JsonSerializable {
'enclosureLink' => $this->getEnclosureLink(),
'unread' => $this->isUnread(),
'starred' => $this->isStarred(),
- 'feedLink' => $feeds['feed'. $this->getFeedId()]->getLink(),
- 'rtl' => $this->getRtl()
+ 'feedLink' => $feeds['feed' . $this->getFeedId()]->getLink(),
+ 'rtl' => $this->getRtl(),
];
}
-
public function getIntro() {
return strip_tags($this->getBody());
}
@@ -191,12 +191,12 @@ class Item extends Entity implements IAPI, \JsonSerializable {
$item->setEnclosureMime($import['enclosureMime']);
$item->setEnclosureLink($import['enclosureLink']);
$item->setRtl($import['rtl']);
- if($import['unread']) {
+ if ($import['unread']) {
$item->setUnread();
} else {
$item->setRead();
}
- if($import['starred']) {
+ if ($import['starred']) {
$item->setStarred();
} else {
$item->setUnstarred();
@@ -205,12 +205,10 @@ class Item extends Entity implements IAPI, \JsonSerializable {
return $item;
}
-
public function setAuthor($name) {
parent::setAuthor(strip_tags($name));
}
-
public function setTitle($title) {
parent::setTitle(strip_tags($title));
}
@@ -226,21 +224,27 @@ class Item extends Entity implements IAPI, \JsonSerializable {
)
);
$this->setFingerprint($this->computeFingerprint());
+ $this->setContentHash($this->computeContentHash());
+ }
+
+ private function computeContentHash() {
+ return md5($this->getTitle() . $this->getUrl() . $this->getBody() .
+ $this->getEnclosureLink() . $this->getEnclosureMime() .
+ $this->getAuthor());
}
private function computeFingerprint() {
return md5($this->getTitle() . $this->getUrl() . $this->getBody() .
- $this->getEnclosureLink());
+ $this->getEnclosureLink());
}
public function setUrl($url) {
$url = trim($url);
- if(strpos($url, 'http') === 0 || strpos($url, 'magnet') === 0) {
+ if (strpos($url, 'http') === 0 || strpos($url, 'magnet') === 0) {
parent::setUrl($url);
}
}
-
public function setBody($body) {
// FIXME: this should not happen if the target="_blank" is already
// on the link
diff --git a/docs/developer/External-Api.md b/docs/developer/External-Api.md
index 042c81d7b..2f0d0e950 100644
--- a/docs/developer/External-Api.md
+++ b/docs/developer/External-Api.md
@@ -607,7 +607,7 @@ The attributes mean the following:
* **fingerprint**: 64 ASCII characters, hash that is used to determine if an item is the same as an other one. The following behavior should be implemented:
* Items in a stream (e.g. All items, folders, feeds) should be filtered so that no item with the same fingerprint is present.
* When marking an item read, all items with the same fingerprint should also be marked as read.
-* **contentHash**: 64 ASCII characters, used to determine if the item on the client is up to or out of date. The difference between the contentHash and the fingerprint attribute is that contentHash is always calculated from a stable set of attributes (title, author, url, publishedAt, updatedAt, enclosure, body) whereas the fingerprint is calculated from a set of attributes depending on the feed. The reason for this is that some feeds use different URLs for the same article so you would not want to include the URL as uniqueness criteria in that case. If the fingerprint was used for syncing however, an URL update would never reach the client.
+* **contentHash**: 64 ASCII characters, used to determine if the item on the client is up to or out of date. The difference between the contentHash and the fingerprint attribute is that contentHash is always calculated from a stable set of attributes (title, author, url, enclosure, body) whereas the fingerprint is calculated from a set of attributes depending on the feed. The reason for this is that some feeds use different URLs for the same article so you would not want to include the URL as uniqueness criteria in that case. If the fingerprint was used for syncing however, an URL update would never reach the client.
### Full
A full item contains the full content:
diff --git a/tests/unit/db/ItemTest.php b/tests/unit/db/ItemTest.php
index 14abdfc71..b7bf76180 100644
--- a/tests/unit/db/ItemTest.php
+++ b/tests/unit/db/ItemTest.php
@@ -71,6 +71,7 @@ class ItemTest extends \PHPUnit_Framework_TestCase {
$item->setStarred();
$item->setLastModified(321);
$item->setFingerprint('fingerprint');
+ $item->setContentHash('contentHash');
$this->assertEquals([
'id' => 3,
@@ -88,7 +89,8 @@ class ItemTest extends \PHPUnit_Framework_TestCase {
'starred' => true,
'lastModified' => 321,
'rtl' => true,
- 'fingerprint' => 'fingerprint'
+ 'fingerprint' => 'fingerprint',
+ 'contentHash' => 'contentHash'
], $item->toAPI());
}
diff --git a/tests/unit/upgrade/UpgradeTest.php b/tests/unit/upgrade/UpgradeTest.php
index f2d2485f0..a3d473b63 100644
--- a/tests/unit/upgrade/UpgradeTest.php
+++ b/tests/unit/upgrade/UpgradeTest.php
@@ -49,7 +49,7 @@ class UpgradeTest extends \PHPUnit_Framework_TestCase {
$this->config->expects($this->once())
->method('getAppValue')
->with($this->equalTo('news'), $this->equalTo('installed_version'))
- ->will($this->returnValue('8.7.3'));
+ ->will($this->returnValue('8.9.0'));
$this->service->expects($this->once())
->method('generateSearchIndices');
@@ -61,7 +61,7 @@ class UpgradeTest extends \PHPUnit_Framework_TestCase {
$this->config->expects($this->once())
->method('getAppValue')
->with($this->equalTo('news'), $this->equalTo('installed_version'))
- ->will($this->returnValue('8.7.4'));
+ ->will($this->returnValue('8.9.1'));
$this->service->expects($this->never())
->method('generateSearchIndices');
diff --git a/upgrade/upgrade.php b/upgrade/upgrade.php
index 2c86e311d..2ddcddb2c 100644
--- a/upgrade/upgrade.php
+++ b/upgrade/upgrade.php
@@ -47,7 +47,7 @@ class Upgrade {
$this->appName, 'installed_version'
);
- if (version_compare($previousVersion, '8.7.3', '<=')) {
+ if (version_compare($previousVersion, '8.9.0', '<=')) {
$this->itemService->generateSearchIndices();
}
}