diff options
author | dave@33eels.com <dave@33eels.com@4eb1ac78-321c-0410-a911-ec516a8615a5> | 2008-09-15 19:59:24 (GMT) |
---|---|---|
committer | dave@33eels.com <dave@33eels.com@4eb1ac78-321c-0410-a911-ec516a8615a5> | 2008-09-15 19:59:24 (GMT) |
commit | 2e1d0b8a9e7ece43a90fdd3a5caf961ba5136a21 (patch) | |
tree | 75bdb284228304b063288f709dd66f19129c8cb3 | |
parent | 750b6ed96d82753e916569da33af70580d8cd486 (diff) |
Implemented feed factory storage methods.
Added firstrun handling.
Default feeds.
git-svn-id: http://svn.mozilla.org/addons/trunk@18254 4eb1ac78-321c-0410-a911-ec516a8615a5
-rw-r--r-- | bandwagon/components/bandwagon-service.js | 67 | ||||
-rw-r--r-- | bandwagon/content/scripts/bandwagon.js | 4 | ||||
-rw-r--r-- | bandwagon/content/scripts/factory/feedFactory.js | 551 | ||||
-rw-r--r-- | bandwagon/content/scripts/model/feed.js | 5 | ||||
-rw-r--r-- | bandwagon/content/scripts/model/feedItem.js | 2 | ||||
-rw-r--r-- | bandwagon/content/scripts/util.js | 12 | ||||
-rw-r--r-- | bandwagon/content/ui/feedsPaneController.js | 7 |
7 files changed, 615 insertions, 33 deletions
diff --git a/bandwagon/components/bandwagon-service.js b/bandwagon/components/bandwagon-service.js index f75d728..e93d99b 100644 --- a/bandwagon/components/bandwagon-service.js +++ b/bandwagon/components/bandwagon-service.js @@ -95,8 +95,10 @@ BandwagonService.prototype = { this._service = new Bandwagon.RPC.Service(); this._service.registerLogger(Bandwagon.Logger); this._service.registerObserver(this._getFeedObserver); + this.registerFeedUpdateObserver(this.commit); // init sqlite storage + this._initStorage(); // first run stuff @@ -107,28 +109,20 @@ BandwagonService.prototype = { Bandwagon.Preferences.setPreference("firstrun", false); } - // **** START TEMP TEMP TEMP **** - - // always do first run (to create db tables) - this.firstrun(); +// **** START TEMP TEMP TEMP **** +// always do first run (to create db tables) +//this.firstrun(); +// **** END TEMP TEMP TEMP **** - // populate a feed here - var feed = new Bandwagon.Model.Feed(); - //feed.url = "https://services.addons.mozilla.org/en-US/firefox/api/1.1/list/featured/all/10/"; - feed.url = "http://www.33eels.com/clients/briks/bandwagon/testfeed.xml"; - feed.name = "Featured Add-ons"; - this.feeds[feed.url] = feed; + // storage initialized, tables created - open the feeds - /* - var feed2 = new Bandwagon.Model.Feed(); - feed2.url = "http://www.33eels.com/clients/briks/bandwagon/testfeed.xml"; - feed2.name = "Featured Add-ons"; - this.feeds[feed2.url] = feed2; - */ + var storageFeeds = this._feedFactory.openFeeds(); - this._service.getFeed(feed2); - - // **** END TEMP TEMP TEMP **** + for (var id in storageFeeds) + { + this.feeds[id] = storageFeeds[id]; + Bandwagon.Logger.debug("opened feed from storage: " + id); + } this._initialized = true; @@ -141,7 +135,7 @@ BandwagonService.prototype = { var extensionsManager = ExtensionsManager.getService(nsIExtensionManager); // (if file doesn't exist, Storage will create it) - var file = extensionsManager.getInstallLocation(Bandwagon.EMID).getItemFile(Bandwagon.EMID, "bandwagon.sqlite"); + var file = extensionsManager.getInstallLocation(Bandwagon.EMID).getItemFile(Bandwagon.EMID, Bandwagon.SQLITE_FILENAME); try { @@ -254,7 +248,21 @@ BandwagonService.prototype = { { Bandwagon.Logger.info("This is bandwagon's firstrun"); + // set up database tables + this._storageFirstrun(); + + // set up and save default feeds + + var defaultFeed1 = this._feedFactory.newFeed(); + defaultFeed1.url = Bandwagon.DEFAULT_FEED1_URL + defaultFeed1.name = Bandwagon.DEFAULT_FEED1_NAME; + this.feeds[defaultFeed1.url] = defaultFeed1; + this.commit(defaultFeed1); + + // populate default feed + + this._service.getFeed(defaultFeed1); }, _storageFirstrun: function() @@ -276,7 +284,8 @@ BandwagonService.prototype = { + "dateLastCheck INTEGER, " + "updateInterval INTEGER NOT NULL, " + "showNotifications INTEGER NOT NULL, " - + "autoPublish INTEGER NOT NULL)" + + "autoPublish INTEGER NOT NULL, " + + "active INTEGER NOT NULL DEFAULT 1)" ); this._storageConnection.executeSimpleSQL( "CREATE TABLE IF NOT EXISTS feedItems " @@ -341,12 +350,24 @@ BandwagonService.prototype = { // TODO }, - commit: function() + commit: function(feed) + { + if (!bandwagonService._feedFactory) + return; + + Bandwagon.Logger.debug("In commit() with feed: " + feed.url); + + bandwagonService._feedFactory.commitFeed(feed); + }, + + commitAll: function() { if (!this._feedFactory) return; - this._feedFactory.commitFeeds(); + Bandwagon.Logger.debug("In commitAll()"); + + this._feedFactory.commitFeeds(this.feeds); }, // for nsISupports diff --git a/bandwagon/content/scripts/bandwagon.js b/bandwagon/content/scripts/bandwagon.js index a6e943e..c49c2fe 100644 --- a/bandwagon/content/scripts/bandwagon.js +++ b/bandwagon/content/scripts/bandwagon.js @@ -41,6 +41,8 @@ Bandwagon.Controller = new function() {} Bandwagon.RPC = new function() {} Bandwagon.EMID = "sharing@addons.mozilla.org"; +Bandwagon.SQLITE_FILENAME = "bandwagon.sqlite"; +Bandwagon.DEFAULT_FEED1_URL = "http://www.33eels.com/clients/briks/bandwagon/testfeed.xml"; +Bandwagon.DEFAULT_FEED1_NAME = "Featured Add-ons"; -//var bandwagonService; diff --git a/bandwagon/content/scripts/factory/feedFactory.js b/bandwagon/content/scripts/factory/feedFactory.js index 0f20741..946d509 100644 --- a/bandwagon/content/scripts/factory/feedFactory.js +++ b/bandwagon/content/scripts/factory/feedFactory.js @@ -36,36 +36,575 @@ Bandwagon.Factory.FeedFactory = function(connection) { + this.Bandwagon = Bandwagon; this.connection = connection; } Bandwagon.Factory.FeedFactory.prototype.newFeed = function() { - // TODO + return new this.Bandwagon.Model.Feed(); } Bandwagon.Factory.FeedFactory.prototype.openFeed = function(feed_id) { - // TODO + if (!this.connection) + return null; + + var feeds = {}; + + var statement = this.connection.createStatement("SELECT * FROM feeds where id = ?1"); + + try + { + statement.bindInt32Parameter(0, feed_id); + statement.execute(); + + var feed = this._openFeedFromRS(statement); + + if (!feed) + return null; + + feed.feedItems = this._openFeedItems(feed); + + feeds[feed.url] = feed; + } + finally + { + statement.reset(); + } + + return feed; } Bandwagon.Factory.FeedFactory.prototype.openFeeds = function() { - // TODO + if (!this.connection) + return null; + + var feeds = {}; + + var statement = this.connection.createStatement("SELECT * FROM feeds"); + + try + { + while (statement.executeStep()) + { + var feed = this._openFeedFromRS(statement); + + if (!feed) + continue; + + feed.feedItems = this._openFeedItems(feed); + + feeds[feed.url] = feed; + } + } + finally + { + statement.reset(); + } + + return feeds; } Bandwagon.Factory.FeedFactory.prototype.commitFeed = function(feed) { - // TODO + if (!this.connection) + return; + + var statement = this.connection.createStatement("REPLACE INTO feeds VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)"); + + try + { + (feed.id==-1?statement.bindNullParameter(0):statement.bindInt32Parameter(0, feed.id)); + statement.bindUTF8StringParameter(1, feed.url); + statement.bindUTF8StringParameter(2, feed.name); + statement.bindUTF8StringParameter(3, feed.description); + statement.bindInt32Parameter(4, feed.dateAdded.getTime()/1000); + (feed.dateLastCheck == null?statement.bindNullParameter(5):statement.bindInt32Parameter(5, feed.dateLastCheck.getTime()/1000)); + statement.bindInt32Parameter(6, feed.updateInterval); + statement.bindInt32Parameter(7, (feed.showNotifications?1:0)); + statement.bindInt32Parameter(8, (feed.autoPublish?1:0)); + statement.bindInt32Parameter(9, (feed.active?1:0)); + + statement.execute(); + } + finally + { + statement.reset(); + } + + if (feed.id == -1) + { + feed.id = this.connection.lastInsertRowID; + } + + for (var id in feed.feedItems) + { + this._commitFeedItem(feed, feed.feedItems[id]); + } + + return true; } Bandwagon.Factory.FeedFactory.prototype.commitFeeds = function(feeds) { - // TODO + for (var id in feeds) + { + this.commitFeed(feeds[id]); + } } Bandwagon.Factory.FeedFactory.prototype.deleteFeed = function(feed) { - // TODO + if (!this.connection) + return null; + + var statement1 = this.connection.createStatement("DELETE FROM feeds where id = ?1"); + var statement2 = this.connection.createStatement("DELETE FROM feedItems where feed = ?1"); + + try + { + // TODO transaction here? + + statement1.bindInt32Parameter(0, feed.id); + statement1.execute(); + + statement2.bindInt32Parameter(0, feed.id); + statement2.execute(); + } + finally + { + statement1.reset(); + statement2.reset(); + } + + return (statement2.lastError>0?false:true); +} + +// private methods + +Bandwagon.Factory.FeedFactory.prototype._openFeedFromRS = function(resultset) +{ + var feed = new this.Bandwagon.Model.Feed(); + feed.id = resultset.getInt32(0); + feed.url = resultset.getUTF8String(1); + feed.name = resultset.getUTF8String(2); + feed.description = resultset.getUTF8String(3); + feed.dateAdded = new Date(resultset.getInt32(4)*1000); + + if (!resultset.getIsNull(5)) + feed.dateLastCheck = new Date(resultset.getInt32(5)*1000); + + feed.updateInterval = resultset.getInt32(6); + feed.showNotifications = (resultset.getInt32(7)==1?true:false); + feed.autoPublish = (resultset.getInt32(8)==1?true:false); + + return feed; +} + +Bandwagon.Factory.FeedFactory.prototype._openFeedItems = function(feed) +{ + var feedItems = {}; + + var statement = this.connection.createStatement("SELECT addons.* FROM addons LEFT JOIN feedItems ON addons.id = feedItems.addon WHERE feedItems.feed = ?1"); + + try + { + statement.bindInt32Parameter(0, feed.id); + + while (statement.executeStep()) + { + var feedItem = new this.Bandwagon.Model.FeedItem(); + + feedItem.id = statement.getInt32(0); + feedItem.guid = statement.getUTF8String(1); + feedItem.name = statement.getUTF8String(2); + feedItem.type = statement.getInt32(3); + feedItem.version = statement.getUTF8String(4); + feedItem.status = statement.getInt32(5); + feedItem.summary = statement.getUTF8String(6); + feedItem.description = statement.getUTF8String(7); + feedItem.icon = statement.getUTF8String(8); + feedItem.eula = statement.getUTF8String(9); + feedItem.thumbnail = statement.getUTF8String(10); + feedItem.learnmore = statement.getUTF8String(11); + feedItem.author = statement.getUTF8String(12); + feedItem.category = statement.getUTF8String(13); + feedItem.dateAdded = new Date(statement.getInt32(14)*1000); + + feedItem.compatibleApplications = this._openFeedItemCompatibleApplications(feedItem); + feedItem.compatibleOS = this._openFeedItemCompatibleOS(feedItem); + feedItem.installs = this._openFeedItemInstalls(feedItem); + feedItem.comments = this._openFeedItemComments(feedItem); + + feedItems[feedItem.guid] = feedItem; + } + } + finally + { + statement.reset(); + } + + return feedItems; +} + +Bandwagon.Factory.FeedFactory.prototype._openFeedItemCompatibleApplications = function(feedItem) +{ + var compatibleApplications = {}; + + var statement = this.connection.createStatement("SELECT * FROM addonCompatibleApplications WHERE addon = ?1"); + + try + { + statement.bindInt32Parameter(0, feedItem.id); + + while (statement.executeStep()) + { + var application = + { + name: statement.getUTF8String(1).toString().toUpperCase(), + applicationId: statement.getInt32(2), + minVersion: statement.getUTF8String(3), + maxVersion: statement.getUTF8String(4), + guid: statement.getUTF8String(5) + }; + + compatibleApplications[application.name.toUpperCase()] = application; + } + } + finally + { + statement.reset(); + } + + return compatibleApplications; +} + +Bandwagon.Factory.FeedFactory.prototype._openFeedItemCompatibleOS = function(feedItem) +{ + var compatibleOS = {}; + + var statement = this.connection.createStatement("SELECT * FROM addonCompatibleOS WHERE addon = ?1"); + + try + { + statement.bindInt32Parameter(0, feedItem.id); + + while (statement.executeStep()) + { + var os = statement.getUTF8String(1).toString().toUpperCase(); + + compatibleOS[os] = os; + } + } + finally + { + statement.reset(); + } + + return compatibleOS; +} + +Bandwagon.Factory.FeedFactory.prototype._openFeedItemInstalls = function(feedItem) +{ + var installs = {}; + + var statement = this.connection.createStatement("SELECT * FROM addonInstalls WHERE addon = ?1"); + + try + { + statement.bindInt32Parameter(0, feedItem.id); + + while (statement.executeStep()) + { + var install = + { + url: statement.getUTF8String(1), + hash: statement.getUTF8String(2), + os: statement.getUTF8String(3).toString().toUpperCase() + }; + + installs[install.os] = install; + } + } + finally + { + statement.reset(); + } + + return installs; +} + +Bandwagon.Factory.FeedFactory.prototype._openFeedItemComments = function(feedItem) +{ + var comments = []; + + var statement = this.connection.createStatement("SELECT * FROM addonComments WHERE addon = ?1"); + + try + { + statement.bindInt32Parameter(0, feedItem.id); + + while (statement.executeStep()) + { + var comment = + { + comment: statement.getUTF8String(1), + author: statement.getUTF8String(2) + }; + + comments.push(comment); + } + } + finally + { + statement.reset(); + } + + return comments; +} + +Bandwagon.Factory.FeedFactory.prototype._commitFeedItem = function(feed, feedItem) +{ + if (!this.connection) + return; + + // addons + // if guid already exists - just update the addon + // if guid doesn't exist - insert + + var statement = this.connection.createStatement("SELECT id FROM addons where guid = ?1"); + var addonid = null; + + try + { + statement.bindUTF8StringParameter(0, feedItem.guid); + + while (statement.executeStep()) + { + addonid = statement.getInt32(0); + } + } + finally + { + statement.reset(); + } + + statement = this.connection.createStatement("REPLACE INTO addons VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15)"); + + try + { + if (addonid != null) + { + // addon already exists (in another feed, or from previous commit of this feed) + statement.bindInt32Parameter(0, addonid); + } + else if (feedItem.id != -1) + { + // addon doesn't already exist, but exists from a previous commit of this feed (?) + statement.bindInt32Parameter(0, feedItem.id); + } + else + { + // new addon + statement.bindNullParameter(0) + } + + statement.bindUTF8StringParameter(1, feedItem.guid); + statement.bindUTF8StringParameter(2, feedItem.name); + statement.bindInt32Parameter(3, feedItem.type); + statement.bindUTF8StringParameter(4, feedItem.version); + statement.bindInt32Parameter(5, feedItem.status); + statement.bindUTF8StringParameter(6, feedItem.summary); + statement.bindUTF8StringParameter(7, feedItem.description); + statement.bindUTF8StringParameter(8, feedItem.icon); + statement.bindUTF8StringParameter(9, feedItem.eula); + statement.bindUTF8StringParameter(10, feedItem.thumbnail); + statement.bindUTF8StringParameter(11, feedItem.learnmore); + statement.bindUTF8StringParameter(12, feedItem.author); + statement.bindUTF8StringParameter(13, feedItem.category); + statement.bindUTF8StringParameter(14, feedItem.dateAdded.getTime()/1000); + + statement.execute(); + } + finally + { + statement.reset(); + } + + if (feedItem.id == -1 && addonid == null) + { + addonid = this.connection.lastInsertRowID; + } + + // add the other addon bits + + for (var id in feedItem.compatibleApplications) + { + this._commitAddonCompatibleApplication(addonid, feedItem.compatibleApplications[id]); + } + + for (var id in feedItem.compatibleOS) + { + this._commitAddonCompatibleOS(addonid, feedItem.compatibleOS[id]); + } + + for (var id in feedItem.installs) + { + this._commitAddonInstall(addonid, feedItem.installs[id]); + } + + for (var i=0; i<feedItem.comments.length; i++) + { + this._commitAddonComment(addonid, feedItem.comments[i]); + } + + // add the feedItem connector + + if (feedItem.id == -1) + { + statement = this.connection.createStatement("REPLACE INTO feedItems VALUES (?1, ?2, ?3)"); + + try + { + statement.bindNullParameter(0); + statement.bindInt32Parameter(1, feed.id); + statement.bindInt32Parameter(2, addonid); + + statement.execute(); + } + finally + { + statement.reset(); + } + + feedItem.id = this.connection.lastInsertRowID; + } + + return true; +} + +Bandwagon.Factory.FeedFactory.prototype._commitAddonCompatibleApplication = function(addonid, application) +{ + var statement = this.connection.createStatement("DELETE FROM addonCompatibleApplications WHERE addon = ?1"); + + try + { + statement.bindInt32Parameter(0, addonid); + statement.execute(); + } + finally + { + statement.reset(); + } + + statement = this.connection.createStatement("INSERT INTO addonCompatibleApplications VALUES (?1, ?2, ?3, ?4, ?5, ?6)"); + + try + { + statement.bindInt32Parameter(0, addonid); + statement.bindUTF8StringParameter(1, application.name); + statement.bindInt32Parameter(2, application.applicationId); + statement.bindUTF8StringParameter(3, application.minVersion); + statement.bindUTF8StringParameter(4, application.maxVersion); + statement.bindUTF8StringParameter(5, application.guid); + + statement.execute(); + } + finally + { + statement.reset(); + } +} + +Bandwagon.Factory.FeedFactory.prototype._commitAddonCompatibleOS = function(addonid, os) +{ + var statement = this.connection.createStatement("DELETE FROM addonCompatibleOS WHERE addon = ?1"); + + try + { + statement.bindInt32Parameter(0, addonid); + statement.execute(); + } + finally + { + statement.reset(); + } + + statement = this.connection.createStatement("INSERT INTO addonCompatibleOS VALUES (?1, ?2)"); + + try + { + statement.bindInt32Parameter(0, addonid); + statement.bindUTF8StringParameter(1, os); + + statement.execute(); + } + finally + { + statement.reset(); + } +} + +Bandwagon.Factory.FeedFactory.prototype._commitAddonInstall = function(addonid, install) +{ + var statement = this.connection.createStatement("DELETE FROM addonInstalls WHERE addon = ?1"); + + try + { + statement.bindInt32Parameter(0, addonid); + statement.execute(); + } + finally + { + statement.reset(); + } + + statement = this.connection.createStatement("INSERT INTO addonInstalls VALUES (?1, ?2, ?3, ?4)"); + + try + { + statement.bindInt32Parameter(0, addonid); + statement.bindUTF8StringParameter(1, install.url); + statement.bindUTF8StringParameter(2, install.hash); + statement.bindUTF8StringParameter(3, install.os); + + statement.execute(); + } + finally + { + statement.reset(); + } +} + +Bandwagon.Factory.FeedFactory.prototype._commitAddonComment = function(addonid, comment) +{ + var statement = this.connection.createStatement("DELETE FROM addonComments WHERE addon = ?1"); + + try + { + statement.bindInt32Parameter(0, addonid); + statement.execute(); + } + finally + { + statement.reset(); + } + + statement = this.connection.createStatement("INSERT INTO addonComments VALUES (?1, ?2, ?3)"); + + try + { + statement.bindInt32Parameter(0, addonid); + statement.bindUTF8StringParameter(1, comment.comment); + statement.bindUTF8StringParameter(2, comment.author); + + statement.execute(); + } + finally + { + statement.reset(); + } } diff --git a/bandwagon/content/scripts/model/feed.js b/bandwagon/content/scripts/model/feed.js index a0741c2..d0d3dfa 100644 --- a/bandwagon/content/scripts/model/feed.js +++ b/bandwagon/content/scripts/model/feed.js @@ -38,15 +38,18 @@ Bandwagon.Model.Feed = function() { this.Bandwagon = Bandwagon; + this.id = -1; // internal bandwagon id + this.url = ""; this.name = ""; this.description = ""; this.password = null; - this.dateAdded = null; + this.dateAdded = new Date(); this.dateLastCheck = null; this.updateInterval = 0; this.showNotifications = false; this.autoPublish = false; + this.active = true; this.feedItems = {}; } diff --git a/bandwagon/content/scripts/model/feedItem.js b/bandwagon/content/scripts/model/feedItem.js index 7a9ddaa..b35cf8a 100644 --- a/bandwagon/content/scripts/model/feedItem.js +++ b/bandwagon/content/scripts/model/feedItem.js @@ -41,6 +41,8 @@ Bandwagon.Model.FeedItem = function() this.TYPE_EXTENSION = 1; this.STATUS_PUBLIC = 4; + this.id = -1; // internal bandwagon id + this.name = ""; this.type = -1; this.guid = ""; diff --git a/bandwagon/content/scripts/util.js b/bandwagon/content/scripts/util.js index ace73dd..9438629 100644 --- a/bandwagon/content/scripts/util.js +++ b/bandwagon/content/scripts/util.js @@ -164,3 +164,15 @@ Bandwagon.Util._dumpObject = function(obj, name, indent, depth) } } +Bandwagon.Util.lengthOfHash = function(hash) +{ + var length = 0; + + for (var object in hash) + { + length++; + } + + return length; +} + diff --git a/bandwagon/content/ui/feedsPaneController.js b/bandwagon/content/ui/feedsPaneController.js index 9496777..e935550 100644 --- a/bandwagon/content/ui/feedsPaneController.js +++ b/bandwagon/content/ui/feedsPaneController.js @@ -63,11 +63,14 @@ Bandwagon.Controller.FeedsPane.uninit = function() Bandwagon.Controller.FeedsPane.initialized = false; bandwagonService.unregisterFeedUpdateObserver(Bandwagon.Controller.FeedsPane.feedUpdateObserver); + + // now is a good time to save feeds to storage + bandwagonService.commitAll(); } Bandwagon.Controller.FeedsPane._repopulateFeedsList = function() { - Bandwagon.Logger.debug("about to repopulate the feeds list"); + //Bandwagon.Logger.debug("Bandwagon.Controller.FeedsPane: about to repopulate the feeds list"); var elemBandwagonFeedsList = document.getElementById("bandwagon-feeds-list"); @@ -109,7 +112,7 @@ Bandwagon.Controller.FeedsPane._repopulateFeedsList = function() Bandwagon.Controller.FeedsPane._repopulateFeedItemsList = function(feed) { - Bandwagon.Logger.debug("repopulating feed '" + feed.url + "'"); + Bandwagon.Logger.debug("Bandwagon.Controller.FeedsPane: repopulating feed '" + feed.url + "'"); var elemBandwagonFeedItemsList = document.getElementById("bandwagon-feeditems-list"); |