Moving Scholar.Attachments to its own file

This commit is contained in:
Dan Stillman 2006-10-02 21:41:38 +00:00
parent eccc2159c1
commit ace0d17ccb
3 changed files with 440 additions and 436 deletions

View file

@ -0,0 +1,436 @@
Scholar.Attachments = new function(){
this.LINK_MODE_IMPORTED_FILE = 0;
this.LINK_MODE_IMPORTED_URL = 1;
this.LINK_MODE_LINKED_FILE = 2;
this.LINK_MODE_LINKED_URL = 3;
this.importFromFile = importFromFile;
this.linkFromFile = linkFromFile;
this.importSnapshotFromFile = importSnapshotFromFile;
this.importFromURL = importFromURL;
this.linkFromURL = linkFromURL;
this.linkFromDocument = linkFromDocument;
this.importFromDocument = importFromDocument;
var self = this;
function importFromFile(file, sourceItemID){
var title = file.leafName;
Scholar.DB.beginTransaction();
try {
// Create a new attachment
var attachmentItem = Scholar.Items.getNewItemByType(Scholar.ItemTypes.getID('attachment'));
attachmentItem.setField('title', title);
attachmentItem.save();
var itemID = attachmentItem.getID();
// Create directory for attachment files within storage directory
var destDir = Scholar.getStorageDirectory();
destDir.append(itemID);
destDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0644);
file.copyTo(destDir, null);
// Point to copied file
var newFile = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
newFile.initWithFile(destDir);
newFile.append(title);
var mimeType = Scholar.MIME.getMIMETypeFromFile(newFile);
_addToDB(newFile, null, null, this.LINK_MODE_IMPORTED_FILE,
mimeType, null, sourceItemID, itemID);
Scholar.DB.commitTransaction();
// Determine charset and build fulltext index
_postProcessFile(itemID, newFile, mimeType);
}
catch (e){
// hmph
Scholar.DB.rollbackTransaction();
// Clean up
if (itemID){
var itemDir = Scholar.getStorageDirectory();
itemDir.append(itemID);
if (itemDir.exists()){
itemDir.remove(true);
}
}
throw (e);
}
return itemID;
}
function linkFromFile(file, sourceItemID){
var title = file.leafName;
var mimeType = Scholar.MIME.getMIMETypeFromFile(file);
var itemID = _addToDB(file, null, title, this.LINK_MODE_LINKED_FILE, mimeType,
null, sourceItemID);
// Determine charset and build fulltext index
_postProcessFile(itemID, file, mimeType);
return itemID;
}
function importSnapshotFromFile(file, url, title, mimeType, charset, sourceItemID){
var charsetID = Scholar.CharacterSets.getID(charset);
Scholar.DB.beginTransaction();
try {
// Create a new attachment
var attachmentItem = Scholar.Items.getNewItemByType(Scholar.ItemTypes.getID('attachment'));
attachmentItem.setField('title', title);
attachmentItem.setField('url', url);
// TODO: access date
attachmentItem.save();
var itemID = attachmentItem.getID();
var storageDir = Scholar.getStorageDirectory();
file.parent.copyTo(storageDir, itemID);
// Point to copied file
var newFile = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
newFile.initWithFile(storageDir);
newFile.append(itemID);
newFile.append(file.leafName);
_addToDB(newFile, url, null, this.LINK_MODE_IMPORTED_URL, mimeType,
charsetID, sourceItemID, itemID);
Scholar.DB.commitTransaction();
// Determine charset and build fulltext index
_postProcessFile(itemID, newFile, mimeType);
}
catch (e){
Scholar.DB.rollbackTransaction();
// Clean up
if (itemID){
var itemDir = Scholar.getStorageDirectory();
itemDir.append(itemID);
if (itemDir.exists()){
itemDir.remove(true);
}
}
throw (e);
}
return itemID;
}
function importFromURL(url, sourceItemID){
Scholar.Utilities.HTTP.doHead(url, function(obj){
var mimeType = obj.channel.contentType;
var nsIURL = Components.classes["@mozilla.org/network/standard-url;1"]
.createInstance(Components.interfaces.nsIURL);
nsIURL.spec = url;
var ext = nsIURL.fileExtension;
// If we can load this internally, use a hidden browser (so we can
// get the charset and title)
if (Scholar.MIME.hasInternalHandler(mimeType, ext)){
var browser = Scholar.Browser.createHiddenBrowser();
browser.addEventListener("pageshow", function(){
Scholar.Attachments.importFromDocument(browser.contentDocument, sourceItemID);
browser.removeEventListener("pageshow", arguments.callee, true);
Scholar.Browser.deleteHiddenBrowser(browser);
}, true);
browser.loadURI(url);
}
// Otherwise use a remote web page persist
else {
var fileName = _getFileNameFromURL(url, mimeType);
var title = fileName;
const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
var wbp = Components
.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
.createInstance(nsIWBP);
//wbp.persistFlags = nsIWBP.PERSIST_FLAGS...;
var encodingFlags = false;
Scholar.DB.beginTransaction();
try {
// Create a new attachment
var attachmentItem = Scholar.Items.getNewItemByType(Scholar.ItemTypes.getID('attachment'));
attachmentItem.setField('title', title);
attachmentItem.setField('url', url);
attachmentItem.setField('accessDate', "CURRENT_TIMESTAMP");
attachmentItem.save();
var itemID = attachmentItem.getID();
// Create a new folder for this item in the storage directory
var destDir = Scholar.getStorageDirectory();
destDir.append(itemID);
destDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0644);
var file = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
file.initWithFile(destDir);
file.append(fileName);
wbp.saveURI(nsIURL, null, null, null, null, file);
_addToDB(file, url, title, Scholar.Attachments.LINK_MODE_IMPORTED_URL,
mimeType, null, sourceItemID, itemID);
Scholar.DB.commitTransaction();
}
catch (e){
Scholar.DB.rollbackTransaction();
throw (e);
}
}
});
}
function linkFromURL(url, sourceItemID, mimeType, title){
// If no title provided, figure it out from the URL
if (!title){
title = url.substring(url.lastIndexOf('/')+1);
}
// If we have the title and mime type, skip loading
if (title && mimeType){
_addToDB(null, url, title, this.LINK_MODE_LINKED_URL, mimeType,
null, sourceItemID);
return;
}
// Otherwise do a head request for the mime type
Scholar.Utilities.HTTP.doHead(url, function(obj){
_addToDB(null, url, title, Scholar.Attachments.LINK_MODE_LINKED_URL,
obj.channel.contentType, null, sourceItemID);
});
}
// TODO: what if called on file:// document?
function linkFromDocument(document, sourceItemID){
var url = document.location;
var title = document.title; // TODO: don't use Mozilla-generated title for images, etc.
var mimeType = document.contentType;
var charsetID = Scholar.CharacterSets.getID(document.characterSet);
var itemID = _addToDB(null, url, title, this.LINK_MODE_LINKED_URL,
mimeType, charsetID, sourceItemID);
// Run the fulltext indexer asynchronously (actually, it hangs the UI
// thread, but at least it lets the menu close)
setTimeout(function(){
Scholar.Fulltext.indexDocument(document, itemID);
}, 50);
return itemID;
}
function importFromDocument(document, sourceItemID){
var url = document.location;
var title = document.title;
var mimeType = document.contentType;
var charsetID = Scholar.CharacterSets.getID(document.characterSet);
const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
var wbp = Components
.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
.createInstance(nsIWBP);
//wbp.persistFlags = nsIWBP.PERSIST_FLAGS...;
var encodingFlags = false;
Scholar.DB.beginTransaction();
// Create a new attachment
var attachmentItem = Scholar.Items.getNewItemByType(Scholar.ItemTypes.getID('attachment'));
attachmentItem.setField('title', title);
attachmentItem.setField('url', url);
attachmentItem.setField('accessDate', "CURRENT_TIMESTAMP");
attachmentItem.save();
var itemID = attachmentItem.getID();
// Create a new folder for this item in the storage directory
var destDir = Scholar.getStorageDirectory();
destDir.append(itemID);
destDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0644);
var file = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
file.initWithFile(destDir);
var fileName = _getFileNameFromURL(url, mimeType);
// This is a hack to make sure the file is opened in the browser when
// we use loadURI(), since Firefox's internal detection mechanisms seem
// to sometimes get confused
// (see #192, https://chnm.gmu.edu/trac/scholar/ticket/192)
if (mimeType=='text/html' &&
(fileName.substr(fileName.length-5)!='.html'
&& fileName.substr(fileName.length-4)!='.htm')){
fileName += '.html';
}
file.append(fileName);
wbp.saveDocument(document, file, destDir, mimeType, encodingFlags, false);
_addToDB(file, url, title, this.LINK_MODE_IMPORTED_URL, mimeType,
charsetID, sourceItemID, itemID);
Scholar.DB.commitTransaction();
// Run the fulltext indexer asynchronously (actually, it hangs the UI
// thread, but at least it lets the menu close)
setTimeout(function(){
Scholar.Fulltext.indexDocument(document, itemID);
}, 50);
return itemID;
}
function _getFileNameFromURL(url, mimeType){
var nsIURL = Components.classes["@mozilla.org/network/standard-url;1"]
.createInstance(Components.interfaces.nsIURL);
nsIURL.spec = url;
if (nsIURL.fileName){
return nsIURL.fileName;
}
if (mimeType){
var ext = Components.classes["@mozilla.org/mime;1"]
.getService(Components.interfaces.nsIMIMEService)
.getPrimaryExtension(mimeType, nsIURL.fileExt ? nsIURL.fileExt : null);
}
return nsIURL.host + (ext ? '.' + ext : '');
}
/**
* Create a new item of type 'attachment' and add to the itemAttachments table
*
* Passing an itemID causes it to skip new item creation and use the specified
* item instead -- used when importing files (since we have to know
* the itemID before copying in a file and don't want to update the DB before
* the file is saved)
*
* Returns the itemID of the new attachment
**/
function _addToDB(file, url, title, linkMode, mimeType, charsetID, sourceItemID, itemID){
if (file){
// Path relative to Scholar directory for external files and relative
// to storage directory for imported files
var refDir = (linkMode==this.LINK_MODE_LINKED_FILE)
? Scholar.getScholarDirectory() : Scholar.getStorageDirectory();
var path = file.getRelativeDescriptor(refDir);
}
Scholar.DB.beginTransaction();
if (sourceItemID){
var sourceItem = Scholar.Items.get(sourceItemID);
if (!sourceItem){
Scholar.DB.commitTransaction();
throw ("Cannot set attachment source to invalid item " + sourceItemID);
}
if (sourceItem.isAttachment()){
Scholar.DB.commitTransaction();
throw ("Cannot set attachment source to another file (" + sourceItemID + ")");
}
}
// If an itemID is provided, use that
if (itemID){
var attachmentItem = Scholar.Items.get(itemID);
if (!attachmentItem.isAttachment()){
throw ("Item " + itemID + " is not a valid attachment in _addToDB()");
}
}
// Otherwise create a new attachment
else {
var attachmentItem = Scholar.Items.getNewItemByType(Scholar.ItemTypes.getID('attachment'));
attachmentItem.setField('title', title);
if (linkMode==self.LINK_MODE_IMPORTED_URL
|| linkMode==self.LINK_MODE_LINKED_URL){
attachmentItem.setField('url', url);
attachmentItem.setField('accessDate', "CURRENT_TIMESTAMP");
}
attachmentItem.save();
}
var sql = "INSERT INTO itemAttachments (itemID, sourceItemID, linkMode, "
+ "mimeType, charsetID, path) VALUES (?,?,?,?,?,?)";
var bindParams = [
attachmentItem.getID(),
(sourceItemID ? {int:sourceItemID} : null),
{int:linkMode},
{string:mimeType},
(charsetID ? {int:charsetID} : null),
(path ? {string:path} : null)
];
Scholar.DB.query(sql, bindParams);
Scholar.DB.commitTransaction();
if (sourceItemID){
sourceItem.incrementAttachmentCount();
Scholar.Notifier.trigger('modify', 'item', sourceItemID);
}
Scholar.Notifier.trigger('add', 'item', attachmentItem.getID());
return attachmentItem.getID();
}
/*
* Since we have to load the content into the browser to get the
* character set (at least until we figure out a better way to get
* at the native detectors), we create the item above and update
* asynchronously after the fact
*/
function _postProcessFile(itemID, file, mimeType){
var ext = Scholar.File.getExtension(file);
if (mimeType.substr(0, 5)!='text/' ||
!Scholar.MIME.hasInternalHandler(mimeType, ext)){
return false;
}
var browser = Scholar.Browser.createHiddenBrowser();
Scholar.File.addCharsetListener(browser, new function(){
return function(charset, id){
var charsetID = Scholar.CharacterSets.getID(charset);
if (charsetID){
var sql = "UPDATE itemAttachments SET charsetID=" + charsetID
+ " WHERE itemID=" + itemID;
Scholar.DB.query(sql);
}
// Chain fulltext indexer inside the charset callback,
// since it's asynchronous and a prerequisite
Scholar.Fulltext.indexDocument(browser.contentDocument, itemID);
Scholar.Browser.deleteHiddenBrowser(browser);
}
}, itemID);
var url = Components.classes["@mozilla.org/network/protocol;1?name=file"]
.getService(Components.interfaces.nsIFileProtocolHandler)
.getURLSpecFromFile(file);
browser.loadURI(url);
}
}

View file

@ -2017,442 +2017,6 @@ Scholar.Notes = new function(){
Scholar.Attachments = new function(){
this.LINK_MODE_IMPORTED_FILE = 0;
this.LINK_MODE_IMPORTED_URL = 1;
this.LINK_MODE_LINKED_FILE = 2;
this.LINK_MODE_LINKED_URL = 3;
this.importFromFile = importFromFile;
this.linkFromFile = linkFromFile;
this.importSnapshotFromFile = importSnapshotFromFile;
this.importFromURL = importFromURL;
this.linkFromURL = linkFromURL;
this.linkFromDocument = linkFromDocument;
this.importFromDocument = importFromDocument;
var self = this;
function importFromFile(file, sourceItemID){
var title = file.leafName;
Scholar.DB.beginTransaction();
try {
// Create a new attachment
var attachmentItem = Scholar.Items.getNewItemByType(Scholar.ItemTypes.getID('attachment'));
attachmentItem.setField('title', title);
attachmentItem.save();
var itemID = attachmentItem.getID();
// Create directory for attachment files within storage directory
var destDir = Scholar.getStorageDirectory();
destDir.append(itemID);
destDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0644);
file.copyTo(destDir, null);
// Point to copied file
var newFile = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
newFile.initWithFile(destDir);
newFile.append(title);
var mimeType = Scholar.MIME.getMIMETypeFromFile(newFile);
_addToDB(newFile, null, null, this.LINK_MODE_IMPORTED_FILE,
mimeType, null, sourceItemID, itemID);
Scholar.DB.commitTransaction();
// Determine charset and build fulltext index
_postProcessFile(itemID, newFile, mimeType);
}
catch (e){
// hmph
Scholar.DB.rollbackTransaction();
// Clean up
if (itemID){
var itemDir = Scholar.getStorageDirectory();
itemDir.append(itemID);
if (itemDir.exists()){
itemDir.remove(true);
}
}
throw (e);
}
return itemID;
}
function linkFromFile(file, sourceItemID){
var title = file.leafName;
var mimeType = Scholar.MIME.getMIMETypeFromFile(file);
var itemID = _addToDB(file, null, title, this.LINK_MODE_LINKED_FILE, mimeType,
null, sourceItemID);
// Determine charset and build fulltext index
_postProcessFile(itemID, file, mimeType);
return itemID;
}
function importSnapshotFromFile(file, url, title, mimeType, charset, sourceItemID){
var charsetID = Scholar.CharacterSets.getID(charset);
Scholar.DB.beginTransaction();
try {
// Create a new attachment
var attachmentItem = Scholar.Items.getNewItemByType(Scholar.ItemTypes.getID('attachment'));
attachmentItem.setField('title', title);
attachmentItem.setField('url', url);
// TODO: access date
attachmentItem.save();
var itemID = attachmentItem.getID();
var storageDir = Scholar.getStorageDirectory();
file.parent.copyTo(storageDir, itemID);
// Point to copied file
var newFile = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
newFile.initWithFile(storageDir);
newFile.append(itemID);
newFile.append(file.leafName);
_addToDB(newFile, url, null, this.LINK_MODE_IMPORTED_URL, mimeType,
charsetID, sourceItemID, itemID);
Scholar.DB.commitTransaction();
// Determine charset and build fulltext index
_postProcessFile(itemID, newFile, mimeType);
}
catch (e){
Scholar.DB.rollbackTransaction();
// Clean up
if (itemID){
var itemDir = Scholar.getStorageDirectory();
itemDir.append(itemID);
if (itemDir.exists()){
itemDir.remove(true);
}
}
throw (e);
}
return itemID;
}
function importFromURL(url, sourceItemID){
Scholar.Utilities.HTTP.doHead(url, function(obj){
var mimeType = obj.channel.contentType;
var nsIURL = Components.classes["@mozilla.org/network/standard-url;1"]
.createInstance(Components.interfaces.nsIURL);
nsIURL.spec = url;
var ext = nsIURL.fileExtension;
// If we can load this internally, use a hidden browser (so we can
// get the charset and title)
if (Scholar.MIME.hasInternalHandler(mimeType, ext)){
var browser = Scholar.Browser.createHiddenBrowser();
browser.addEventListener("pageshow", function(){
Scholar.Attachments.importFromDocument(browser.contentDocument, sourceItemID);
browser.removeEventListener("pageshow", arguments.callee, true);
Scholar.Browser.deleteHiddenBrowser(browser);
}, true);
browser.loadURI(url);
}
// Otherwise use a remote web page persist
else {
var fileName = _getFileNameFromURL(url, mimeType);
var title = fileName;
const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
var wbp = Components
.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
.createInstance(nsIWBP);
//wbp.persistFlags = nsIWBP.PERSIST_FLAGS...;
var encodingFlags = false;
Scholar.DB.beginTransaction();
try {
// Create a new attachment
var attachmentItem = Scholar.Items.getNewItemByType(Scholar.ItemTypes.getID('attachment'));
attachmentItem.setField('title', title);
attachmentItem.setField('url', url);
attachmentItem.setField('accessDate', "CURRENT_TIMESTAMP");
attachmentItem.save();
var itemID = attachmentItem.getID();
// Create a new folder for this item in the storage directory
var destDir = Scholar.getStorageDirectory();
destDir.append(itemID);
destDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0644);
var file = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
file.initWithFile(destDir);
file.append(fileName);
wbp.saveURI(nsIURL, null, null, null, null, file);
_addToDB(file, url, title, Scholar.Attachments.LINK_MODE_IMPORTED_URL,
mimeType, null, sourceItemID, itemID);
Scholar.DB.commitTransaction();
}
catch (e){
Scholar.DB.rollbackTransaction();
throw (e);
}
}
});
}
function linkFromURL(url, sourceItemID, mimeType, title){
// If no title provided, figure it out from the URL
if (!title){
title = url.substring(url.lastIndexOf('/')+1);
}
// If we have the title and mime type, skip loading
if (title && mimeType){
_addToDB(null, url, title, this.LINK_MODE_LINKED_URL, mimeType,
null, sourceItemID);
return;
}
// Otherwise do a head request for the mime type
Scholar.Utilities.HTTP.doHead(url, function(obj){
_addToDB(null, url, title, Scholar.Attachments.LINK_MODE_LINKED_URL,
obj.channel.contentType, null, sourceItemID);
});
}
// TODO: what if called on file:// document?
function linkFromDocument(document, sourceItemID){
var url = document.location;
var title = document.title; // TODO: don't use Mozilla-generated title for images, etc.
var mimeType = document.contentType;
var charsetID = Scholar.CharacterSets.getID(document.characterSet);
var itemID = _addToDB(null, url, title, this.LINK_MODE_LINKED_URL,
mimeType, charsetID, sourceItemID);
// Run the fulltext indexer asynchronously (actually, it hangs the UI
// thread, but at least it lets the menu close)
setTimeout(function(){
Scholar.Fulltext.indexDocument(document, itemID);
}, 50);
return itemID;
}
function importFromDocument(document, sourceItemID){
var url = document.location;
var title = document.title;
var mimeType = document.contentType;
var charsetID = Scholar.CharacterSets.getID(document.characterSet);
const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
var wbp = Components
.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
.createInstance(nsIWBP);
//wbp.persistFlags = nsIWBP.PERSIST_FLAGS...;
var encodingFlags = false;
Scholar.DB.beginTransaction();
// Create a new attachment
var attachmentItem = Scholar.Items.getNewItemByType(Scholar.ItemTypes.getID('attachment'));
attachmentItem.setField('title', title);
attachmentItem.setField('url', url);
attachmentItem.setField('accessDate', "CURRENT_TIMESTAMP");
attachmentItem.save();
var itemID = attachmentItem.getID();
// Create a new folder for this item in the storage directory
var destDir = Scholar.getStorageDirectory();
destDir.append(itemID);
destDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0644);
var file = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
file.initWithFile(destDir);
var fileName = _getFileNameFromURL(url, mimeType);
// This is a hack to make sure the file is opened in the browser when
// we use loadURI(), since Firefox's internal detection mechanisms seem
// to sometimes get confused
// (see #192, https://chnm.gmu.edu/trac/scholar/ticket/192)
if (mimeType=='text/html' &&
(fileName.substr(fileName.length-5)!='.html'
&& fileName.substr(fileName.length-4)!='.htm')){
fileName += '.html';
}
file.append(fileName);
wbp.saveDocument(document, file, destDir, mimeType, encodingFlags, false);
_addToDB(file, url, title, this.LINK_MODE_IMPORTED_URL, mimeType,
charsetID, sourceItemID, itemID);
Scholar.DB.commitTransaction();
// Run the fulltext indexer asynchronously (actually, it hangs the UI
// thread, but at least it lets the menu close)
setTimeout(function(){
Scholar.Fulltext.indexDocument(document, itemID);
}, 50);
return itemID;
}
function _getFileNameFromURL(url, mimeType){
var nsIURL = Components.classes["@mozilla.org/network/standard-url;1"]
.createInstance(Components.interfaces.nsIURL);
nsIURL.spec = url;
if (nsIURL.fileName){
return nsIURL.fileName;
}
if (mimeType){
var ext = Components.classes["@mozilla.org/mime;1"]
.getService(Components.interfaces.nsIMIMEService)
.getPrimaryExtension(mimeType, nsIURL.fileExt ? nsIURL.fileExt : null);
}
return nsIURL.host + (ext ? '.' + ext : '');
}
/**
* Create a new item of type 'attachment' and add to the itemAttachments table
*
* Passing an itemID causes it to skip new item creation and use the specified
* item instead -- used when importing files (since we have to know
* the itemID before copying in a file and don't want to update the DB before
* the file is saved)
*
* Returns the itemID of the new attachment
**/
function _addToDB(file, url, title, linkMode, mimeType, charsetID, sourceItemID, itemID){
if (file){
// Path relative to Scholar directory for external files and relative
// to storage directory for imported files
var refDir = (linkMode==this.LINK_MODE_LINKED_FILE)
? Scholar.getScholarDirectory() : Scholar.getStorageDirectory();
var path = file.getRelativeDescriptor(refDir);
}
Scholar.DB.beginTransaction();
if (sourceItemID){
var sourceItem = Scholar.Items.get(sourceItemID);
if (!sourceItem){
Scholar.DB.commitTransaction();
throw ("Cannot set attachment source to invalid item " + sourceItemID);
}
if (sourceItem.isAttachment()){
Scholar.DB.commitTransaction();
throw ("Cannot set attachment source to another file (" + sourceItemID + ")");
}
}
// If an itemID is provided, use that
if (itemID){
var attachmentItem = Scholar.Items.get(itemID);
if (!attachmentItem.isAttachment()){
throw ("Item " + itemID + " is not a valid attachment in _addToDB()");
}
}
// Otherwise create a new attachment
else {
var attachmentItem = Scholar.Items.getNewItemByType(Scholar.ItemTypes.getID('attachment'));
attachmentItem.setField('title', title);
if (linkMode==self.LINK_MODE_IMPORTED_URL
|| linkMode==self.LINK_MODE_LINKED_URL){
attachmentItem.setField('url', url);
attachmentItem.setField('accessDate', "CURRENT_TIMESTAMP");
}
attachmentItem.save();
}
var sql = "INSERT INTO itemAttachments (itemID, sourceItemID, linkMode, "
+ "mimeType, charsetID, path) VALUES (?,?,?,?,?,?)";
var bindParams = [
attachmentItem.getID(),
(sourceItemID ? {int:sourceItemID} : null),
{int:linkMode},
{string:mimeType},
(charsetID ? {int:charsetID} : null),
(path ? {string:path} : null)
];
Scholar.DB.query(sql, bindParams);
Scholar.DB.commitTransaction();
if (sourceItemID){
sourceItem.incrementAttachmentCount();
Scholar.Notifier.trigger('modify', 'item', sourceItemID);
}
Scholar.Notifier.trigger('add', 'item', attachmentItem.getID());
return attachmentItem.getID();
}
/*
* Since we have to load the content into the browser to get the
* character set (at least until we figure out a better way to get
* at the native detectors), we create the item above and update
* asynchronously after the fact
*/
function _postProcessFile(itemID, file, mimeType){
var ext = Scholar.File.getExtension(file);
if (mimeType.substr(0, 5)!='text/' ||
!Scholar.MIME.hasInternalHandler(mimeType, ext)){
return false;
}
var browser = Scholar.Browser.createHiddenBrowser();
Scholar.File.addCharsetListener(browser, new function(){
return function(charset, id){
var charsetID = Scholar.CharacterSets.getID(charset);
if (charsetID){
var sql = "UPDATE itemAttachments SET charsetID=" + charsetID
+ " WHERE itemID=" + itemID;
Scholar.DB.query(sql);
}
// Chain fulltext indexer inside the charset callback,
// since it's asynchronous and a prerequisite
Scholar.Fulltext.indexDocument(browser.contentDocument, itemID);
Scholar.Browser.deleteHiddenBrowser(browser);
}
}, itemID);
var url = Components.classes["@mozilla.org/network/protocol;1?name=file"]
.getService(Components.interfaces.nsIFileProtocolHandler)
.getURLSpecFromFile(file);
browser.loadURI(url);
}
}
/*
* Constructor for Collection object

View file

@ -30,6 +30,10 @@ Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader)
.loadSubScript("chrome://scholar/content/xpcom/data_access.js");
Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader)
.loadSubScript("chrome://scholar/content/xpcom/attachments.js");
Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader)
.loadSubScript("chrome://scholar/content/xpcom/notifier.js");