Switch back to SingleFile from SingleFileZ (#1904)
Our SingleFileZ integration would save images inside directories following the SingleFileZ format. However, Zotero does not support syncing sub-directories of attachments. This commit switch back to a single HTML file with base64 encoded resources. We think that the 33% increase in resources will be offset by the compression of HTML and removal of JavaScript and unused CSS. This commit does not fix past snapshots that were saved using SingleFileZ.
This commit is contained in:
parent
3a684308cd
commit
76ae5d9f59
13 changed files with 404 additions and 418 deletions
|
@ -772,8 +772,7 @@ describe("Connector Server", function () {
|
|||
connectorServerPath + "/connector/saveSnapshot",
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"zotero-allowed-request": "true"
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
}
|
||||
|
@ -792,33 +791,16 @@ describe("Connector Server", function () {
|
|||
// Promise for attachment save
|
||||
promise = waitForItemEvent('add');
|
||||
|
||||
let body = new FormData();
|
||||
let uuid = 'binary-' + Zotero.Utilities.randomString();
|
||||
body.append("payload", JSON.stringify(Object.assign(payload, {
|
||||
pageData: {
|
||||
content: await Zotero.File.getContentsAsync(indexPath),
|
||||
resources: {
|
||||
images: [
|
||||
{
|
||||
name: "img.gif",
|
||||
content: uuid,
|
||||
binary: true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})));
|
||||
|
||||
let imagePath = OS.Path.join(testDataDirectory, 'snapshot', 'img.gif');
|
||||
body.append(uuid, await File.createFromFileName(imagePath));
|
||||
let body = JSON.stringify(Object.assign(payload, {
|
||||
snapshotContent: await Zotero.File.getContentsAsync(indexPath)
|
||||
}));
|
||||
|
||||
await Zotero.HTTP.request(
|
||||
'POST',
|
||||
connectorServerPath + "/connector/saveSingleFile",
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
"zotero-allowed-request": "true"
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body
|
||||
}
|
||||
|
@ -840,13 +822,6 @@ describe("Connector Server", function () {
|
|||
let contents = await Zotero.File.getContentsAsync(path);
|
||||
let expectedContents = await Zotero.File.getContentsAsync(indexPath);
|
||||
assert.equal(contents, expectedContents);
|
||||
|
||||
// Check attachment binary file
|
||||
path = OS.Path.join(attachmentDirectory, 'img.gif');
|
||||
assert.isTrue(await OS.File.exists(path));
|
||||
contents = await Zotero.File.getBinaryContentsAsync(path);
|
||||
expectedContents = await Zotero.File.getBinaryContentsAsync(imagePath);
|
||||
assert.equal(contents, expectedContents);
|
||||
});
|
||||
|
||||
it("should save a webpage item with /saveItems", async function () {
|
||||
|
@ -907,6 +882,88 @@ describe("Connector Server", function () {
|
|||
let testDataDirectory = getTestDataDirectory().path;
|
||||
let indexPath = OS.Path.join(testDataDirectory, 'snapshot', 'index.html');
|
||||
|
||||
let body = JSON.stringify(Object.assign(payload, {
|
||||
snapshotContent: await Zotero.File.getContentsAsync(indexPath)
|
||||
}));
|
||||
|
||||
req = await Zotero.HTTP.request(
|
||||
'POST',
|
||||
connectorServerPath + "/connector/saveSingleFile",
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body
|
||||
}
|
||||
);
|
||||
assert.equal(req.status, 201);
|
||||
|
||||
// Await attachment save
|
||||
let attachmentIDs = await promise;
|
||||
|
||||
// Check attachment
|
||||
assert.lengthOf(attachmentIDs, 1);
|
||||
item = Zotero.Items.get(attachmentIDs[0]);
|
||||
assert.isTrue(item.isImportedAttachment());
|
||||
assert.equal(item.getField('title'), 'Snapshot');
|
||||
|
||||
// Check attachment html file
|
||||
let attachmentDirectory = Zotero.Attachments.getStorageDirectory(item).path;
|
||||
let path = OS.Path.join(attachmentDirectory, 'attachment.html');
|
||||
assert.isTrue(await OS.File.exists(path));
|
||||
let contents = await Zotero.File.getContentsAsync(path);
|
||||
let expectedContents = await Zotero.File.getContentsAsync(indexPath);
|
||||
assert.equal(contents, expectedContents);
|
||||
});
|
||||
|
||||
it("should override SingleFileZ from old connector in /saveSnapshot", async function () {
|
||||
Components.utils.import("resource://gre/modules/FileUtils.jsm");
|
||||
var collection = await createDataObject('collection');
|
||||
await waitForItemsLoad(win);
|
||||
|
||||
// Promise for item save
|
||||
let promise = waitForItemEvent('add');
|
||||
|
||||
let testDataDirectory = getTestDataDirectory().path;
|
||||
let indexPath = OS.Path.join(testDataDirectory, 'snapshot', 'index.html');
|
||||
|
||||
let prefix = '/' + Zotero.Utilities.randomString() + '/';
|
||||
let uri = OS.Path.join(getTestDataDirectory().path, 'snapshot');
|
||||
httpd.registerDirectory(prefix, new FileUtils.File(uri));
|
||||
|
||||
let title = Zotero.Utilities.randomString();
|
||||
let sessionID = Zotero.Utilities.randomString();
|
||||
let payload = {
|
||||
sessionID,
|
||||
url: testServerPath + prefix + 'index.html',
|
||||
title,
|
||||
singleFile: true
|
||||
};
|
||||
|
||||
await Zotero.HTTP.request(
|
||||
'POST',
|
||||
connectorServerPath + "/connector/saveSnapshot",
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
}
|
||||
);
|
||||
|
||||
// Await item save
|
||||
let parentIDs = await promise;
|
||||
|
||||
// Check parent item
|
||||
assert.lengthOf(parentIDs, 1);
|
||||
var item = Zotero.Items.get(parentIDs[0]);
|
||||
assert.equal(Zotero.ItemTypes.getName(item.itemTypeID), 'webpage');
|
||||
assert.isTrue(collection.hasItem(item.id));
|
||||
assert.equal(item.getField('title'), title);
|
||||
|
||||
// Promise for attachment save
|
||||
promise = waitForItemEvent('add');
|
||||
|
||||
let body = new FormData();
|
||||
let uuid = 'binary-' + Zotero.Utilities.randomString();
|
||||
body.append("payload", JSON.stringify(Object.assign(payload, {
|
||||
|
@ -924,8 +981,113 @@ describe("Connector Server", function () {
|
|||
}
|
||||
})));
|
||||
|
||||
let imagePath = OS.Path.join(testDataDirectory, 'snapshot', 'img.gif');
|
||||
body.append(uuid, await File.createFromFileName(imagePath));
|
||||
await Zotero.HTTP.request(
|
||||
'POST',
|
||||
connectorServerPath + "/connector/saveSingleFile",
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
"zotero-allowed-request": "true"
|
||||
},
|
||||
body
|
||||
}
|
||||
);
|
||||
|
||||
// Await attachment save
|
||||
let attachmentIDs = await promise;
|
||||
|
||||
// Check attachment
|
||||
assert.lengthOf(attachmentIDs, 1);
|
||||
item = Zotero.Items.get(attachmentIDs[0]);
|
||||
assert.isTrue(item.isImportedAttachment());
|
||||
assert.equal(item.getField('title'), title);
|
||||
|
||||
// Check attachment html file
|
||||
let attachmentDirectory = Zotero.Attachments.getStorageDirectory(item).path;
|
||||
let path = OS.Path.join(attachmentDirectory, item.attachmentFilename);
|
||||
assert.isTrue(await OS.File.exists(path));
|
||||
let contents = await Zotero.File.getContentsAsync(path);
|
||||
assert.match(contents, /^<html style><!--\n Page saved with SingleFile \n url:/);
|
||||
});
|
||||
|
||||
it("should override SingleFileZ from old connector in /saveItems", async function () {
|
||||
let collection = await createDataObject('collection');
|
||||
await waitForItemsLoad(win);
|
||||
|
||||
let prefix = '/' + Zotero.Utilities.randomString() + '/';
|
||||
let uri = OS.Path.join(getTestDataDirectory().path, 'snapshot');
|
||||
httpd.registerDirectory(prefix, new FileUtils.File(uri));
|
||||
|
||||
let title = Zotero.Utilities.randomString();
|
||||
let sessionID = Zotero.Utilities.randomString();
|
||||
let payload = {
|
||||
sessionID: sessionID,
|
||||
items: [
|
||||
{
|
||||
itemType: "newspaperArticle",
|
||||
title: title,
|
||||
creators: [
|
||||
{
|
||||
firstName: "First",
|
||||
lastName: "Last",
|
||||
creatorType: "author"
|
||||
}
|
||||
],
|
||||
attachments: [
|
||||
{
|
||||
title: "Snapshot",
|
||||
url: testServerPath + prefix + 'index.html',
|
||||
mimeType: "text/html",
|
||||
singleFile: true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
uri: "http://example.com"
|
||||
};
|
||||
|
||||
let promise = waitForItemEvent('add');
|
||||
let req = await Zotero.HTTP.request(
|
||||
'POST',
|
||||
connectorServerPath + "/connector/saveItems",
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
}
|
||||
);
|
||||
assert.equal(req.status, 201);
|
||||
|
||||
// Check parent item
|
||||
let itemIDs = await promise;
|
||||
assert.lengthOf(itemIDs, 1);
|
||||
let item = Zotero.Items.get(itemIDs[0]);
|
||||
assert.equal(Zotero.ItemTypes.getName(item.itemTypeID), 'newspaperArticle');
|
||||
assert.isTrue(collection.hasItem(item.id));
|
||||
|
||||
// Promise for attachment save
|
||||
promise = waitForItemEvent('add');
|
||||
|
||||
let testDataDirectory = getTestDataDirectory().path;
|
||||
let indexPath = OS.Path.join(testDataDirectory, 'snapshot', 'index.html');
|
||||
|
||||
let body = new FormData();
|
||||
let uuid = 'binary-' + Zotero.Utilities.randomString();
|
||||
body.append("payload", JSON.stringify(Object.assign(payload, {
|
||||
pageData: {
|
||||
content: 'Foobar content',
|
||||
resources: {
|
||||
images: [
|
||||
{
|
||||
name: "img.gif",
|
||||
content: uuid,
|
||||
binary: true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})));
|
||||
|
||||
req = await Zotero.HTTP.request(
|
||||
'POST',
|
||||
|
@ -951,18 +1113,10 @@ describe("Connector Server", function () {
|
|||
|
||||
// Check attachment html file
|
||||
let attachmentDirectory = Zotero.Attachments.getStorageDirectory(item).path;
|
||||
let path = OS.Path.join(attachmentDirectory, 'attachment.html');
|
||||
let path = OS.Path.join(attachmentDirectory, item.attachmentFilename);
|
||||
assert.isTrue(await OS.File.exists(path));
|
||||
let contents = await Zotero.File.getContentsAsync(path);
|
||||
let expectedContents = await Zotero.File.getContentsAsync(indexPath);
|
||||
assert.equal(contents, expectedContents);
|
||||
|
||||
// Check attachment binary file
|
||||
path = OS.Path.join(attachmentDirectory, 'img.gif');
|
||||
assert.isTrue(await OS.File.exists(path));
|
||||
contents = await Zotero.File.getBinaryContentsAsync(path);
|
||||
expectedContents = await Zotero.File.getBinaryContentsAsync(imagePath);
|
||||
assert.equal(contents, expectedContents);
|
||||
assert.match(contents, /^<html style><!--\n Page saved with SingleFile \n url:/);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1573,28 +1727,22 @@ describe("Connector Server", function () {
|
|||
connectorServerPath + "/connector/saveSnapshot",
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"zotero-allowed-request": "true"
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
}
|
||||
);
|
||||
|
||||
let body = new FormData();
|
||||
body.append("payload", JSON.stringify(Object.assign(payload, {
|
||||
pageData: {
|
||||
content: '<html><head><title>Title</title><body>Body',
|
||||
resources: {}
|
||||
}
|
||||
})));
|
||||
let body = JSON.stringify(Object.assign(payload, {
|
||||
snapshotContent: '<html><head><title>Title</title><body>Body'
|
||||
}));
|
||||
|
||||
let req = await Zotero.HTTP.request(
|
||||
'POST',
|
||||
connectorServerPath + "/connector/saveSingleFile",
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
"zotero-allowed-request": "true"
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body
|
||||
}
|
||||
|
@ -1701,8 +1849,7 @@ describe("Connector Server", function () {
|
|||
connectorServerPath + "/connector/saveSnapshot",
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"zotero-allowed-request": "true"
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
}
|
||||
|
@ -1739,21 +1886,16 @@ describe("Connector Server", function () {
|
|||
assert.equal(item2.libraryID, group.libraryID);
|
||||
assert.equal(item2.numAttachments(), 0);
|
||||
|
||||
let body = new FormData();
|
||||
body.append("payload", JSON.stringify(Object.assign(payload, {
|
||||
pageData: {
|
||||
content: '<html><head><title>Title</title><body>Body',
|
||||
resources: {}
|
||||
}
|
||||
})));
|
||||
let body = JSON.stringify(Object.assign(payload, {
|
||||
snapshotContent: '<html><head><title>Title</title><body>Body'
|
||||
}));
|
||||
|
||||
req = await Zotero.HTTP.request(
|
||||
'POST',
|
||||
connectorServerPath + "/connector/saveSingleFile",
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
"zotero-allowed-request": "true"
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body
|
||||
}
|
||||
|
@ -1854,28 +1996,22 @@ describe("Connector Server", function () {
|
|||
connectorServerPath + "/connector/saveItems",
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"zotero-allowed-request": "true"
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
}
|
||||
);
|
||||
|
||||
let body = new FormData();
|
||||
body.append("payload", JSON.stringify(Object.assign(payload, {
|
||||
pageData: {
|
||||
content: '<html><head><title>Title</title><body>Body',
|
||||
resources: {}
|
||||
}
|
||||
})));
|
||||
let body = JSON.stringify(Object.assign(payload, {
|
||||
snapshotContent: '<html><head><title>Title</title><body>Body'
|
||||
}));
|
||||
|
||||
let req = await Zotero.HTTP.request(
|
||||
'POST',
|
||||
connectorServerPath + "/connector/saveSingleFile",
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
"zotero-allowed-request": "true"
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body
|
||||
}
|
||||
|
@ -2001,8 +2137,7 @@ describe("Connector Server", function () {
|
|||
connectorServerPath + "/connector/saveItems",
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"zotero-allowed-request": "true"
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
}
|
||||
|
@ -2039,21 +2174,16 @@ describe("Connector Server", function () {
|
|||
assert.equal(item2.libraryID, group.libraryID);
|
||||
assert.equal(item2.numAttachments(), 0);
|
||||
|
||||
let body = new FormData();
|
||||
body.append("payload", JSON.stringify(Object.assign(payload, {
|
||||
pageData: {
|
||||
content: '<html><head><title>Title</title><body>Body',
|
||||
resources: {}
|
||||
}
|
||||
})));
|
||||
let body = JSON.stringify(Object.assign(payload, {
|
||||
snapshotContent: '<html><head><title>Title</title><body>Body'
|
||||
}));
|
||||
|
||||
req = await Zotero.HTTP.request(
|
||||
'POST',
|
||||
connectorServerPath + "/connector/saveSingleFile",
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
"zotero-allowed-request": "true"
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue