central.js
Go to the documentation of this file.
1 /* central.js
2  * This will be loaded into the main window, and manage all global FolderSync-
3  * related tasks that do not fit into another file / controller.
4  */
5 // Make a namespace.
6 if (typeof foldersync == 'undefined') {
7  var foldersync = {};
8 };
9 
10 /* Central controller
11  * Controller for central issues that doesn't fit to any of the controllers
12  * above, like debug messages and UI-independent localisation. Also controlls
13  * startup (calls other onLoads) and shutdown (calls other onUnloads), and
14  * UI integration.
15  */
16 foldersync.central={
17  // central.properties DOM node
18  _strings: null,
19  // the OS we're running on
20  _OS: null,
21  // the number of UIs connected
22  _numUI: 0,
23  // weather we show notifications currently
24  _showNotifications: false,
25 
26  // The central UI update listener for the sync controller
27  _listener: function(state, object) {
28  if (state.event == "started")
29  foldersync.central._updateSPNode(true);
30  var error = foldersync.sync.generateErrorMessage(state);
31  if ((state.event == "completed") ||
32  (state.event == "cancelled") ||
33  error){
34  foldersync.central._updateSPNode(false);
35 
36  // show a global notification that the sync is completed, if pref set
37  if (!foldersync.central._showNotifications)
38  return;
39  var msg = error ? error.error : foldersync.central.
40  getLocaleString("status.completed");
41  msg += ": " + object.sync.targetFolder;
42  var gNotify = document.getElementById("application-notificationbox");
43  if (!gNotify){
44  this.logEvent("central", "Application's notificationbox is not " +
45  "avaiable", 1, "chrome://foldersync/content/central.js");
46  return;
47  }
48  var level = error ? (error.fatal ? 8 : 5) : 2;
49  gNotify.appendNotification(msg,
50  level,
51  "chrome://foldersync/skin/node.png",
52  level,
53  error ? [{
54  accessKey: null,
55  callback: function(){
56  foldersync.central.showDialog(
57  error.error, error.message);
58  },
59  label: foldersync.central.
60  getLocaleString(
61  "notification.details"),
62  popup: null,
63  }] : []);
64  }
65  },
66 
67  // Startup code for the central controller
68  onLoad: function(e){
69  foldersync.central.logEvent("central", "Central controller " +
70  "initialisation started.", 5);
71  try {
72  // Get OS
73  this._OS = window.navigator.platform;
74  // Get strings
75  this._strings = document.getElementById("foldersync-central-strings");
76 
77  // Load the other global controllers
78  foldersync.preferences.onLoad(e);
79  foldersync.sync.onLoad(e);
80 
81  // Set up service pane
82  this._setupServicePaneNode();
83 
84  // Check weather our updater displays notifications
85  var UIprefs = foldersync.preferences.getUIPrefs();
86  this._showNotifications = UIprefs.notifications.isEnabled;
87 
88  // Register our updater
89  foldersync.sync.addListener(this._listener);
90 
91  // We're done!
92  foldersync.central.logEvent("central", "Central controller started.", 4);
93  } catch (e){
94  foldersync.central.logEvent("central",
95  "Startup of Central controller failed:\n\n" +
96  e, 1,
97  "chrome://foldersync/content/central.js",
98  e.lineNumber);
99  }
100  },
101  // Shutdown code for the central controller
102  onUnload: function(e){
103  foldersync.central.logEvent("central", "Central controller " +
104  "shutdown started.", 5);
105  // Remove the updater for our node
106  foldersync.sync.removeListener(this._listener);
107  // Unload other global controllers
108  foldersync.preferences.onUnload(e);
109  foldersync.sync.onUnload(e);
110  // We're done!
111  foldersync.central.logEvent("central", "Central controller stopped.", 4);
112  },
113 
114  /* Post event in error console, if logging of event type is turned on
115  * module (string): what module caused the event (for example: "central")
116  * msg (string): more detailed description what happened
117  * type (int): What event type the error is:
118  * 1: fatal error
119  * 2: error
120  * 3: warning
121  * 4: essential debug message (for example startup/shutdown of controllers)
122  * 5: debug message (for example a single song being synced)
123  * srcFile (string): The source file's URL, or null (errors and warnings)
124  * srcLine (int): The event's line number, or null (errors and warnings)
125  */
126  logEvent: function(module, msg, type, srcFile, srcLine){
127  // Drop messages for that logging is disabled
128  if (foldersync.preferences.getEvtLogLevel() < type)
129  return;
130  // Parse message
131  var msgStr = "FolderSync: Event raised in '" + module + "':\n" + msg;
132  // Post message
133  var consoleService = Components.classes["@mozilla.org/consoleservice;1"].
134  getService(Components.interfaces.nsIConsoleService);
135  switch (type){
136  case 1:
137  case 2:
138  case 3:
139  var message = Components.classes["@mozilla.org/scripterror;1"].
140  createInstance(Components.interfaces.nsIScriptError);
141  message.init(msgStr,
142  srcFile,
143  null,
144  srcLine == 0 ? null : srcLine,
145  null,
146  type != 3 ? 0x0 /*errorFlag*/ : 0x1 /*warningFlag*/,
147  null);
148  consoleService.logMessage(message);
149  break;
150  default:
151  consoleService.logStringMessage(msgStr);
152  }
153  },
154 
155  /* Get a specific localisation
156  * string (string): the name of the string
157  */
158  getLocaleString: function(string){
159  try {
160  return this._strings.getString(string);
161  } catch (e){
162  this.logEvent("central", "Getting locale string '"+string+"' failed:" +
163  "\n\n" + e, 1, "chrome://foldersync/content/central.js",
164  e.lineNumber);
165  }
166  },
167 
168  /* Get the main library, described as
169  * {
170  * name:<string>, // The library's name
171  * guid:<string>, // The library's guid
172  * }
173  */
174  getMainLibaray: function(){
175  foldersync.central.logEvent("central", "Get main library", 4);
176  // Get the library
177  var sbILibraryManager = Components.classes
178  ["@songbirdnest.com/Songbird/library/Manager;1"].
179  getService(Components.interfaces.
180  sbILibraryManager);
181  var libraries=sbILibraryManager.getLibraries();
182  var mLibrary = sbILibraryManager.mainLibrary;
183  // return it
184  return {name: mLibrary.name, guid: mLibrary.guid};
185  },
186 
187  /* Get a array of Playlists, each playlist described as
188  * {
189  * name:<string>, // The name the user entered
190  * guid:<string>, // The playlist's GUID
191  * }
192  * onlyMain (boolean): Only playlists avaiable in the main library
193  * onlyEditable (boolean): Only playlists that have the UserEditable flag
194  */
195  getPlaylists: function(onlyMain, onlyEditable){
196  foldersync.central.logEvent("central", "Get playlists:\n" +
197  "in main library only: " + onlyMain + "\n" +
198  "editable by user only: " + onlyEditable, 4);
199  // We'll store the result here
200  var result = [];
201  // Get the libraries
202  var sbILibraryManager = Components.classes
203  ["@songbirdnest.com/Songbird/library/Manager;1"].
204  getService(Components.interfaces.
205  sbILibraryManager);
206  var libraries=sbILibraryManager.getLibraries();
207  var crtLibrary = sbILibraryManager.mainLibrary;
208 
209  try {
210  while (crtLibrary){
211  // Write the library's MediaList to the result
212  result.push({name: crtLibrary.name, guid:crtLibrary.guid});
213  foldersync.central.logEvent("central", "Found Library:\n" +
214  "Name: " + crtLibrary.name + "\n" +
215  "GUID: " + crtLibrary.guid, 5);
216  // Get all other MediaLists and write them to the result
217  var libView = crtLibrary.createView();
218  var libFilters = libView.cascadeFilterSet;
219  libFilters.clearAll;
220  libFilters.appendSearch(new Array("*"), 1);
221  libFilters.appendFilter("http://songbirdnest.com/data/1.0#isList");
222  libFilters.set(1, new Array("1"), 1);
223  for (var i = 0; i < libView.length; i++){
224  try {
225  var pList=libView.getItemByIndex(i);
226  // Use playlists with name only, do not use smart ones, they have a
227  // simple "second identity" :P
228  if (pList.name && (pList.name != "") && (pList.name != " ") &&
229  (pList.type != "smart")){
230  result.push({name: pList.name, guid:pList.guid});
231  foldersync.central.logEvent("central", "Found Playlist:\n" +
232  "Name: " + pList.name + "\n" +
233  "GUID: " + pList.guid, 5);
234  }
235  } catch (e) {
236  this.logEvent("central", "Getting playlist failed:\n\n" +
237  e, 2, "chrome://foldersync/content/central.js",
238  e.lineNumber);
239  }
240  }
241 
242  // Get the next library, if we want one
243  if (onlyMain || (!libraries.hasMoreElements()))
244  crtLibrary = null;
245  else
246  crtLibrary = libraries.getNext();
247  }
248  } catch (e){
249  this.logEvent("central", "Getting playlists failed:\n\n" +
250  e, 1, "chrome://foldersync/content/central.js",
251  e.lineNumber);
252  }
253  return result;
254  },
255 
256  /* Get the playlist object with the given GUID or null if there is none
257  * guid (string): The guid
258  */
259  getPlaylistByGUID: function(guid){
260  foldersync.central.logEvent("central", "Search for playlist " + guid, 4);
261  // We'll store the result here
262  var result = null;
263  // Get the libraries
264  var sbILibraryManager = Components.classes
265  ["@songbirdnest.com/Songbird/library/Manager;1"].
266  getService(Components.interfaces.
267  sbILibraryManager);
268  var libraries=sbILibraryManager.getLibraries();
269  var crtLibrary = sbILibraryManager.mainLibrary;
270 
271  try {
272  while (crtLibrary){
273  // Check the Library's MediaList
274  if (crtLibrary.guid == guid)
275  return crtLibrary;
276  // Check all other MediaLists
277  var libView = crtLibrary.createView();
278  var libFilters = libView.cascadeFilterSet;
279  libFilters.clearAll;
280  libFilters.appendSearch(new Array("*"), 1);
281  libFilters.appendFilter("http://songbirdnest.com/data/1.0#isList");
282  libFilters.set(1, new Array("1"), 1);
283  for (var i = 0; i < libView.length; i++){
284  try {
285  var pList=libView.getItemByIndex(i);
286  if (pList.guid == guid)
287  return pList;
288  } catch (e) {
289  this.logEvent("central", "Searching playlist failed:\n\n" +
290  e, 2, "chrome://foldersync/content/central.js",
291  e.lineNumber);
292  }
293  }
294 
295  // Get the next library
296  if (!libraries.hasMoreElements())
297  crtLibrary = null;
298  else
299  crtLibrary = libraries.getNext();
300  }
301  } catch (e){
302  this.logEvent("central", "Searching playlists failed:\n\n" +
303  e, 1, "chrome://foldersync/content/central.js",
304  e.lineNumber);
305  }
306  this.logEvent("central", "Playlist " + guid + " not found.",
307  2, "chrome://foldersync/content/central.js");
308  return null;
309  },
310 
311  // Get OS we're running on
312  getOS: function(){
313  return this._OS;
314  },
315 
316  /* Displays a Error / Message dialog. See error.xul and error.js
317  * error (string): A short error description
318  * message (string): The (error) message itself
319  */
320  showDialog: function(error, message){
321  foldersync.central.logEvent("central", "Open Error Dialog:\n" +
322  "Error: " + error + "\n" +
323  "Message: " + message, 4);
324  try {
325  window.openDialog("chrome://foldersync/content/dialogs/error.xul",
326  "foldersync-error-dialog",
327  "dialog=yes,modal=no,alwaysRaised=yes," +
328  "centerscreen=yes,resizable=yes,dependent=yes",
329  error, message);
330  } catch (e){
331  this.logEvent("central", "Opening Error Dialog failed:\n\n" +
332  e, 1, "chrome://foldersync/content/central.js",
333  e.lineNumber);
334  }
335  },
336 
337  // Sets the service Pane Node for FolderSync up
338  _setupServicePaneNode : function() {
339  foldersync.central.logEvent("central", "Setup Service Pane Node", 4);
340  // The NS we need
341  var dtSB_NS = 'http://songbirdnest.com/data/1.0#';
342  var dtSP_NS = 'http://songbirdnest.com/rdf/servicepane#';
343  var dtSC_NS_DT = "http://songbirdnest.com/data/1.0#";
344  // Get the ServicePaneService
345  var SPS = Cc["@songbirdnest.com/servicepane/service;1"]
346  .getService(Ci.sbIServicePaneService);
347  // Check whether the node already exists
348  if (SPS.getNode("SB:MainLib:FolderSync")){
349  this.logEvent("central", "Wasn't able to setup Service Pane Node:\n\n" +
350  "Node exists already", 3,
351  "chrome://foldersync/content/central.js");
352  return;
353  }
354  // Get the main library's node
355  var libNode = SPS.getNode("urn:library:" + this.getMainLibaray().guid);
356  if (!libNode){
357  this.logEvent("central", "Wasn't able to setup Service Pane Node:\n\n" +
358  "Main Library's node not found", 1,
359  "chrome://foldersync/content/central.js");
360  return;
361  }
362 
363  // Create FolderSync Node
364  var foldersyncNode = SPS.createNode();
365  foldersyncNode.id = "SB:MainLib:FolderSync";
366  foldersyncNode.url = "chrome://foldersync/content/accesspane.xul";
367  var tNo = document.getElementById("foldersync-central-branding-tab-title");
368  foldersyncNode.name = tNo.getAttribute("value");
369  foldersyncNode.editable = false;
370  foldersyncNode.setAttributeNS(dtSP_NS,
371  "addonID",
372  "foldersync@rsjtdrjgfuzkfg.com");
373  foldersyncNode.image = 'chrome://foldersync/skin/node.png';
374  libNode.appendChild(foldersyncNode);
375  },
376 
377  /* Updates the Service Pane node, if we're working or not
378  * working (bool): show the user we're working
379  */
380  _updateSPNode: function(working){
381  // Get the ServicePaneService
382  var SPS = Cc["@songbirdnest.com/servicepane/service;1"]
383  .getService(Ci.sbIServicePaneService);
384  // Get our node
385  var spNode = SPS.getNode("SB:MainLib:FolderSync");
386  if (!spNode){
387  this.logEvent("central", "Wasn't able to update node:\n\n" +
388  "FolderSync's node not found", 1,
389  "chrome://foldersync/content/central.js");
390  return;
391  }
392  spNode.image = working ? 'chrome://foldersync/skin/node-working.png'
393  : 'chrome://foldersync/skin/node.png';
394  },
395 
396  // Called by a UI (for example our tab) to say that it is running
397  registerUI: function(){
398  foldersync.central.logEvent("central", "Register UI", 4);
399  this._numUI++;
400  var UIprefs = foldersync.preferences.getUIPrefs();
401  if (UIprefs.notifications.onlyExclusive)
402  this._showNotifications = false;
403  },
404 
405  // Called by a UI (for example our tab) to sync that
406  unregisterUI: function(){
407  foldersync.central.logEvent("central", "Unregister UI", 4);
408  this._numUI--;
409  var UIprefs = foldersync.preferences.getUIPrefs();
410  if ((this._numUI == 0) && UIprefs.notifications.isEnabled)
411  this._showNotifications = true;
412  },
413 };
414 
415 // load / unload central controller with window
416 window.addEventListener("load",
417  function(e){
418  foldersync.central.onLoad(e);
419  },
420  false);
421 window.addEventListener("unload",
422  function(e){
423  foldersync.central.onUnload(e);
424  },
425  false);
const Cc
sidebarFactory createInstance
Definition: nsSidebar.js:351
getService(Ci.sbIFaceplateManager)
let window
Manages the lifecycle of libraries in the system.
this _contentSandbox label
Definition: FeedWriter.js:814
const module
Definition: httpd.js:4659
Lastfm onLoad
Definition: mini.js:36
grep callback
GstMessage * message
return null
Definition: FeedWriter.js:1143
const Ci
function msg
function onUnload()
onUnload - called when the cover preview window unloads.
Definition: coverPreview.js:36
_getSelectedPageStyle s i