www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

feedItems.js (5153B)


      1 /*
      2     ***** BEGIN LICENSE BLOCK *****
      3     
      4     Copyright © 2015 Center for History and New Media
      5                      George Mason University, Fairfax, Virginia, USA
      6                      http://zotero.org
      7     
      8     This file is part of Zotero.
      9     
     10     Zotero is free software: you can redistribute it and/or modify
     11     it under the terms of the GNU Affero General Public License as published by
     12     the Free Software Foundation, either version 3 of the License, or
     13     (at your option) any later version.
     14     
     15     Zotero is distributed in the hope that it will be useful,
     16     but WITHOUT ANY WARRANTY; without even the implied warranty of
     17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18     GNU Affero General Public License for more details.
     19     
     20     You should have received a copy of the GNU Affero General Public License
     21     along with Zotero.  If not, see <http://www.gnu.org/licenses/>.
     22     
     23     ***** END LICENSE BLOCK *****
     24 */
     25 
     26 
     27 /*
     28  * Primary interface for accessing Zotero feed items
     29  */
     30 Zotero.FeedItems = new Proxy(function() {
     31 	let _idCache = {},
     32 		_guidCache = {};
     33 	
     34 	// Teach Zotero.Items about Zotero.FeedItem
     35 	
     36 	// This one is a lazy getter, so we don't patch it up until first access
     37 	let zi_primaryDataSQLParts = Object.getOwnPropertyDescriptor(Zotero.Items, '_primaryDataSQLParts').get;
     38 	Zotero.defineProperty(Zotero.Items, '_primaryDataSQLParts', {
     39 		get: function() {
     40 			let obj = zi_primaryDataSQLParts.call(this);
     41 			obj.feedItemGUID = "FI.guid AS feedItemGUID";
     42 			obj.feedItemReadTime = "FI.readTime AS feedItemReadTime";
     43 			obj.feedItemTranslatedTime = "FI.translatedTime AS feedItemTranslatedTime";
     44 			return obj;
     45 		}
     46 	}, {lazy: true});
     47 	Zotero.Items._primaryDataSQLFrom += " LEFT JOIN feedItems FI ON (FI.itemID=O.itemID)";
     48 	
     49 	let zi_getObjectForRow = Zotero.Items._getObjectForRow;
     50 	Zotero.Items._getObjectForRow = function(row) {
     51 		if (row.feedItemGUID) {
     52 			return new Zotero.FeedItem();
     53 		}
     54 		
     55 		return zi_getObjectForRow.apply(Zotero.Items, arguments);
     56 	}
     57 	
     58 	this.getIDFromGUID = Zotero.Promise.coroutine(function* (guid) {
     59 		if (_idCache[guid] !== undefined) return _idCache[guid];
     60 		
     61 		let id = yield Zotero.DB.valueQueryAsync('SELECT itemID FROM feedItems WHERE guid=?', [guid]);
     62 		if (!id) return false;
     63 		
     64 		this._setGUIDMapping(guid, id);
     65 		return id;
     66 	});
     67 	
     68 	this._setGUIDMapping = function(guid, id) {
     69 		_idCache[guid] = id;
     70 		_guidCache[id] = guid;
     71 	};
     72 	
     73 	this._deleteGUIDMapping = function(guid, id) {
     74 		if (!id) id = _idCache[guid];
     75 		if (!guid) guid = _guidCache[id];
     76 		
     77 		if (!guid || !id) return;
     78 		
     79 		delete _idCache[guid];
     80 		delete _guidCache[id];
     81 	};
     82 	
     83 	this.unload = function() {
     84 		Zotero.Items.unload.apply(Zotero.Items, arguments);
     85 		let ids = Zotero.flattenArguments(arguments);
     86 		for (let i=0; i<ids.length; i++) {
     87 			this._deleteGUIDMapping(null, ids[i]);
     88 		}
     89 	};
     90 	
     91 	this.getAsyncByGUID = Zotero.Promise.coroutine(function* (guid) {
     92 		let id = yield this.getIDFromGUID(guid);
     93 		if (id === false) return false;
     94 		
     95 		return this.getAsync(id);
     96 	});
     97 	
     98 	this.getMarkedAsRead = Zotero.Promise.coroutine(function* (libraryID, onlyGUIDs=false) {
     99 		let sql = "SELECT " + (onlyGUIDs ? "guid " : "itemID ") + 
    100 			"FROM feedItems FI " +
    101 			"JOIN items I USING (itemID) " +
    102 			"WHERE libraryID=? AND readTime IS NOT NULL";
    103 		let ids = yield Zotero.DB.columnQueryAsync(sql, [libraryID]);
    104 		if (onlyGUIDs) {
    105 			return ids;
    106 		}
    107 		return Zotero.FeedItems.getAsync(ids);
    108 		
    109 	});
    110 
    111 	/**
    112 	 * Currently not used
    113 	 */
    114 	this.markAsReadByGUID = Zotero.Promise.coroutine(function* (guids) {
    115 		if (! Array.isArray(guids)) {
    116 			throw new Error('guids must be an array in Zotero.FeedItems.toggleReadByID');
    117 		}
    118 		let ids = [];
    119 		Zotero.debug("Marking items as read");
    120 		Zotero.debug(guids);
    121 		for (let guid of guids) {
    122 			let id = yield this.getIDFromGUID(guid);
    123 			if (id) {
    124 				ids.push(id);
    125 			}
    126 		}
    127 		return this.toggleReadByID(ids, true);
    128 	});
    129 	
    130 	this.toggleReadByID = Zotero.Promise.coroutine(function* (ids, state) {
    131 		if (!Array.isArray(ids)) {
    132 			if (typeof ids != 'string') throw new Error('ids must be a string or array in Zotero.FeedItems.toggleReadByID');
    133 			
    134 			ids = [ids];
    135 		}
    136 		let items = yield this.getAsync(ids);
    137 		
    138 		if (state == undefined) {
    139 			// If state undefined, toggle read if at least one unread
    140 			state = false;
    141 			for (let item of items) {
    142 				if (!item.isRead) {
    143 					state = true;
    144 					break;
    145 				}
    146 			}
    147 		}
    148 
    149 		let feedsToUpdate = new Set();
    150 		let readTime = state ? Zotero.Date.dateToSQL(new Date(), true) : null;
    151 		for (let i=0; i<items.length; i++) {
    152 			items[i]._feedItemReadTime = readTime;
    153 
    154 			let feed = Zotero.Feeds.get(items[i].libraryID);
    155 			feedsToUpdate.add(feed);
    156 		}
    157 		
    158 		yield Zotero.DB.queryAsync(`UPDATE feedItems SET readTime=? WHERE itemID IN (${ids.join(', ')})`, readTime);
    159 		yield Zotero.Notifier.trigger('modify', 'item', ids, {});
    160 
    161 		for (let feed of feedsToUpdate) {
    162 			yield feed.updateUnreadCount();
    163 		}
    164 	});
    165 	
    166 	return this;
    167 }.call({}),
    168 
    169 // Proxy handler
    170 {
    171 	get: function(target, name) {
    172 		return name in target
    173 			? target[name]
    174 			: Zotero.Items[name];
    175 	},
    176 	has: function(target, name) {
    177 		return name in target || name in Zotero.Items;
    178 	}
    179 });