sbPlaylistHandlerUtils.js
Go to the documentation of this file.
1 /*
2  *=BEGIN SONGBIRD GPL
3  *
4  * This file is part of the Songbird web player.
5  *
6  * Copyright(c) 2005-2010 POTI, Inc.
7  * http://www.songbirdnest.com
8  *
9  * This file may be licensed under the terms of of the
10  * GNU General Public License Version 2 (the ``GPL'').
11  *
12  * Software distributed under the License is distributed
13  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
14  * express or implied. See the GPL for the specific language
15  * governing rights and limitations.
16  *
17  * You should have received a copy of the GPL along with this
18  * program. If not, go to http://www.gnu.org/licenses/gpl.html
19  * or write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  *=END SONGBIRD GPL
23  */
24 
29 Components.utils.import("resource://app/jsmodules/sbProperties.jsm");
30 
31 const PR_RDONLY = -1;
32 const PR_FLAGS_DEFAULT = -1;
33 
34 // the minimum number of characters to feed into the charset detector
36 
46 function SB_ProcessFile(aFile, aCallback, aThis) {
47 
48  var istream = Cc["@mozilla.org/network/file-input-stream;1"]
49  .createInstance(Ci.nsIFileInputStream);
50  istream.init(aFile, PR_RDONLY, PR_FLAGS_DEFAULT, 0);
51  istream.QueryInterface(Ci.nsILineInputStream);
52 
53  var line = {}, hasmore;
54  do {
55  hasmore = istream.readLine(line);
56  aCallback.apply(aThis, [line.value]);
57  } while(hasmore);
58 
59  istream.close();
60 }
61 
72 function SB_DetectCharsetAndProcessFile(aFile, aCallback, aThis) {
73 
74  var istream = Cc["@mozilla.org/network/file-input-stream;1"]
75  .createInstance(Ci.nsIFileInputStream);
76  istream.init(aFile, PR_RDONLY, PR_FLAGS_DEFAULT, 0);
77  istream.QueryInterface(Ci.nsILineInputStream);
78 
79  var detector = Cc["@songbirdnest.com/Songbird/CharsetDetector;1"]
80  .createInstance(Ci.sbICharsetDetector);
81  var line = {}, hasmore, charset;
82  var value = "";
83  var length = 0;
84  try {
85  do {
86  hasmore = istream.readLine(line);
87  value = line.value;
88 
89  // Blank can be ignored.
90  if (value == "")
91  continue;
92 
93  // Send the file content for detection, until we get the best value.
94  detector.detect(value);
95 
96  length += value.length;
97  } while(hasmore &&
98  !detector.isCharsetFound &&
100  charset = detector.finish();
101  }
102  catch (ex) {
103  dump("charset detection error in SB_DetectCharsetAndProcessFile: " +
104  ex + "\n");
105  }
106 
107  istream.close();
108 
109  var fstream = Cc["@mozilla.org/network/file-input-stream;1"]
110  .createInstance(Ci.nsIFileInputStream);
111  fstream.init(aFile, PR_RDONLY, PR_FLAGS_DEFAULT, 0);
112  fstream.QueryInterface(Ci.nsILineInputStream);
113  var unicodeConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
114  .createInstance(Ci.nsIScriptableUnicodeConverter);
115  // Re-read the file with the charset found.
116  do {
117  hasmore = fstream.readLine(line);
118  value = line.value;
119 
120  // Blank can be ignored for all playlist handlers.
121  if (value == "")
122  continue;
123 
124  try {
125  unicodeConverter.charset = charset ? charset : "ISO-8859-1";
126  value = unicodeConverter.ConvertToUnicode(value);
127  }
128  catch (ex) {
129  dump("Unicode conversion error in SB_DetectCharsetAndProcessFile: " +
130  ex + "\n");
131  }
132 
133  aCallback.apply(aThis, [value]);
134  } while(hasmore);
135 
136  fstream.close();
137 }
138 
139 function SB_AddItems(aItems, aMediaList, aAddDistinctOnly) {
140 
141  if (aItems.length == 0)
142  return;
143 
144  function removeItemsByUri(items, uri) {
145  for (var i = items.length - 1; i >= 0; i--) {
146  if (items[i].uri.spec == uri)
147  items.splice(i, 1);
148  }
149  }
150 
151  // If aAddDistinctOnly is true, remove all items from the aItems array that
152  // are already in this list. List membership is based on matching either
153  // the #contentURL or #originURL properties
154  if (aAddDistinctOnly) {
155 
156  // De-dup aItems by uri
157  for (var i = 0; i < aItems.length - 1; i++) {
158  var uri = aItems[i].uri;
159  for (var j = i + 1; j < aItems.length; j++)
160  if (aItems[j].uri.equals(uri))
161  aItems.splice(j, 1);
162  }
163 
164  // Remove all the items from aItems that have matching #contentURL
165  // property values
166  var propertyArray = SBProperties.createArray();
167  aItems.forEach(function(e) {
168  propertyArray.appendProperty(SBProperties.contentURL, e.uri.spec);
169  });
170 
171  var listener = {
172  item: null,
173  onEnumerationBegin: function() {
174  },
175  onEnumeratedItem: function(list, item) {
176  removeItemsByUri(aItems, item.contentSrc.spec);
177  },
178  onEnumerationEnd: function() {
179  }
180  };
181 
182  aMediaList.enumerateItemsByProperties(propertyArray,
183  listener );
184 
185  // Remove all the items from aItems that have matching originUrl
186  // property values
187  if (aItems.length > 0) {
188  propertyArray.clear();
189  aItems.forEach(function(e) {
190  propertyArray.appendProperty(SBProperties.originURL, e.uri.spec);
191  });
192 
193  listener = {
194  item: null,
195  onEnumerationBegin: function() {
196  },
197  onEnumeratedItem: function(list, item) {
198  removeItemsByUri(aItems, item.getProperty(SBProperties.originURL));
199  },
200  onEnumerationEnd: function() {
201  }
202  };
203 
204  aMediaList.enumerateItemsByProperties(propertyArray,
205  listener );
206 
207  }
208  }
209 
210  // If any items are to be added, add them in a batch
211  if (aItems.length > 0) {
212 
213  // Create the array of media item content URIs.
214  var uris = Cc["@songbirdnest.com/moz/xpcom/threadsafe-array;1"]
215  .createInstance(Ci.nsIMutableArray);
216  var libraryUtils = Cc["@songbirdnest.com/Songbird/library/Manager;1"]
217  .getService(Ci.sbILibraryUtils);
218  aItems.forEach(function(e) {
219  uris.appendElement(libraryUtils.getContentURI(e.uri), false);
220  });
221 
222  // Create the media items.
223  var resultItems = {};
224  var created = aMediaList.library.batchCreateMediaItemsIfNotExist
225  (uris,
226  null,
227  resultItems);
228  resultItems = resultItems.value;
229 
230  for (var i = 0; i < aItems.length; i++) {
231  aItems[i].item = resultItems.queryElementAt(i, Ci.sbIMediaItem);
232  if (created.queryElementAt(i, Ci.nsIVariant))
233  aItems[i].created = true;
234  }
235  }
236 
237  // Set the properties on all the newly created items
238  aMediaList.runInBatchMode(function() {
239  aItems.forEach(function(e) {
240  if (e.created) {
241  for (var prop in e.properties) {
242  try {
243  e.item.setProperty(prop, e.properties[prop]);
244  }
245  catch(e) {
246  Components.utils.reportError(e);
247  }
248  }
249  }
250  });
251  });
252 
253  // We also need to add the new items to the media list. If the media list
254  // is actually the library, this is essentially a no-op
255  var enumerator = {
256  _index: 0,
257  _array: aItems,
258  hasMoreElements: function() {
259  return this._index < this._array.length;
260  },
261  getNext: function() {
262  var item = this._array[this._index].item;
263  this._index++;
264  return item;
265  }
266  };
267 
268  aMediaList.addSome(enumerator);
269 }
270 
271 function SB_ResolveURI(aStringURL, aBaseURI)
272 {
273  var isURI = false;
274 
275  var ios = Cc["@mozilla.org/network/io-service;1"]
276  .getService(Ci.nsIIOService);
277 
278  // If there is no base URI or the base URI is a file, try the string as a
279  // file
280  if (aBaseURI == null || aBaseURI.scheme == "file") {
281  try {
282  var file = Cc["@mozilla.org/file/local;1"]
283  .createInstance(Ci.nsILocalFile);
284  file.initWithPath(aStringURL);
285 
286  var uri = ios.newFileURI(file);
287  return uri;
288  }
289  catch(e) {
290  // If the base URI is a local file, try to use it to resolve the local
291  // file path
292  // XXXsteve: this does not work since setRelativeDescriptor does not know
293  // if the leaf of the base path is a directory or a file.
294 /*
295  if (aBaseURI && aBaseURI.scheme == "file") {
296  try {
297  var baseFile = aBaseURI.QueryInterface(Ci.nsIFileURL).file;
298  var file = Cc["@mozilla.org/file/local;1"]
299  .createInstance(Ci.nsILocalFile);
300  file.setRelativeDescriptor(baseFile, aStringURL);
301  var uri = ios.newFileURI(file);
302  return uri;
303  }
304  catch(e) {
305  // fall through
306  }
307  }
308 */
309  }
310  }
311 
312  // Ok, it is not a local file. Try creating a new URI with the base URI
313  try {
314  var uri = ios.newURI(aStringURL, null, aBaseURI);
315  if ( uri instanceof Ci.nsIFileURL && !uri.file.exists() ) {
316  return null;
317  } else {
318  return uri;
319  }
320  }
321  catch(e) {
322  // fall through
323  }
324 
325  // Couldn't resolve it, return null for failure
326  return null;
327 }
const Cc
var istream
const PR_RDONLY
var uris
for(let i=0;i< aHistory.count;i++)
const PR_FLAGS_DEFAULT
function SB_DetectCharsetAndProcessFile(aFile, aCallback, aThis)
Detect the charset of the file aFile, convert the file encode to the detected one, and process the file line by line with the callback function aCallback.
return null
Definition: FeedWriter.js:1143
SimpleArrayEnumerator prototype hasMoreElements
var uri
Definition: FeedWriter.js:1135
function SB_AddItems(aItems, aMediaList, aAddDistinctOnly)
countRef value
Definition: FeedWriter.js:1423
const Ci
var ios
Definition: head_feeds.js:5
const GUESS_CHARSET_MIN_CHAR_COUNT
function SB_ResolveURI(aStringURL, aBaseURI)
function SB_ProcessFile(aFile, aCallback, aThis)
Process the file aFile line by line with the callback function aCallback.
_getSelectedPageStyle s i
var file
converter charset