mirror of
https://github.com/zotero/zotero.git
synced 2026-09-09 22:31:05 +00:00
File sync: Rename single HTML file within multi-file ZIP to known name
If a file was renamed remotely and a new copy wasn't uploaded for some reason, the ZIP wouldn't contain the new filename. We already renamed a single file within the ZIP to match the new filename, but now we also rename a single HTML file in old multi-file snapshot ZIPs. If there are multiple HTML files for some reason (old-style ZIP with iframes?), we let the user fix it. And then we can stop reuploading files after renames.
This commit is contained in:
parent
33bd1327a0
commit
bab0237727
2 changed files with 90 additions and 6 deletions
|
|
@ -622,11 +622,11 @@ Zotero.Sync.Storage.Local = {
|
|||
}
|
||||
|
||||
if (!path) {
|
||||
// This can happen if an HTML snapshot filename was changed and synced
|
||||
// elsewhere but the renamed file wasn't synced, so the ZIP doesn't
|
||||
// contain a file with the known name
|
||||
Components.utils.reportError("File '" + item.attachmentFilename
|
||||
+ "' not found after processing download " + item.libraryKey);
|
||||
// This generally shouldn't happen, since if the ZIP doesn't contain the primary file,
|
||||
// and there's only one HTML file within it, we rename it to the current filename, but
|
||||
// it could occur if there are multiple HTML files or there's an error renaming the file.
|
||||
Zotero.logError("File '" + item.attachmentFilename + "' not found after processing "
|
||||
+ "download " + item.libraryKey);
|
||||
return new Zotero.Sync.Storage.Result({
|
||||
localChanges: false
|
||||
});
|
||||
|
|
@ -795,6 +795,7 @@ Zotero.Sync.Storage.Local = {
|
|||
|
||||
var itemFileName = item.attachmentFilename;
|
||||
|
||||
var createdFiles = new Set();
|
||||
var entries = zipReader.findEntries(null);
|
||||
while (entries.hasMore()) {
|
||||
var entryName = entries.getNext();
|
||||
|
|
@ -835,7 +836,7 @@ Zotero.Sync.Storage.Local = {
|
|||
filtered = true;
|
||||
}
|
||||
|
||||
var destPath = OS.Path.join(parentDir, ...filePath.split('/'));
|
||||
let destPath = OS.Path.join(parentDir, ...filePath.split('/'));
|
||||
|
||||
// If only one file in zip and it doesn't match the known filename,
|
||||
// take our chances and use that name
|
||||
|
|
@ -910,6 +911,7 @@ Zotero.Sync.Storage.Local = {
|
|||
|
||||
try {
|
||||
zipReader.extract(entryName, Zotero.File.pathToFile(destPath));
|
||||
createdFiles.add(PathUtils.filename(destPath));
|
||||
}
|
||||
catch (e) {
|
||||
try {
|
||||
|
|
@ -968,6 +970,23 @@ Zotero.Sync.Storage.Local = {
|
|||
zipFile.remove(false);
|
||||
}
|
||||
|
||||
// If multiple files and none match known filename, but there's only one HTML file, rename it
|
||||
if (!createdFiles.has(itemFileName)) {
|
||||
Zotero.debug(`${itemFileName} not found among extracted files`);
|
||||
let htmlFiles = [...createdFiles].filter(x => /\.html?$/.test(x));
|
||||
if (htmlFiles.length == 1) {
|
||||
let destPath = PathUtils.join(parentDir, itemFileName);
|
||||
try {
|
||||
Zotero.debug(`Renaming ${htmlFiles[0]} to ${itemFileName}`);
|
||||
await IOUtils.move(PathUtils.join(parentDir, htmlFiles[0]), destPath);
|
||||
returnFile = destPath;
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.logError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnFile;
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -549,6 +549,71 @@ describe("Zotero.Sync.Storage.Local", function () {
|
|||
);
|
||||
assert.equal(await item.attachmentModificationTime, mtime);
|
||||
});
|
||||
|
||||
|
||||
it("should rename a single HTML file in an old multi-file ZIP to match the current primary filename", async function () {
|
||||
var libraryID = Zotero.Libraries.userLibraryID;
|
||||
var parentItem = await createDataObject('item');
|
||||
var key = Zotero.DataObjectUtilities.generateKey();
|
||||
|
||||
var oldFilename = "a.html";
|
||||
var auxFilename = "a.gif";
|
||||
var newFilename = "b.html";
|
||||
var fileContents = Zotero.Utilities.randomString();
|
||||
var tmpDir = Zotero.getTempDirectory().path;
|
||||
var zipFile = OS.Path.join(tmpDir, key + '.tmp');
|
||||
|
||||
// Create ZIP file
|
||||
var tmpDir = Zotero.getTempDirectory().path;
|
||||
var zipDir = await getTempDirectory();
|
||||
await Zotero.File.putContentsAsync(PathUtils.join(zipDir, oldFilename), fileContents);
|
||||
await Zotero.File.putContentsAsync(PathUtils.join(zipDir, auxFilename), '');
|
||||
await Zotero.File.zipDirectory(zipDir, zipFile);
|
||||
await removeDir(zipDir);
|
||||
|
||||
var md5 = Zotero.Utilities.Internal.md5(Zotero.File.pathToFile(zipFile));
|
||||
var mtime = 1445667239000;
|
||||
|
||||
var json = {
|
||||
key,
|
||||
version: 10,
|
||||
itemType: 'attachment',
|
||||
linkMode: 'imported_url',
|
||||
url: 'https://example.com/foo.html',
|
||||
filename: 'b.html',
|
||||
contentType: 'text/plain',
|
||||
charset: 'utf-8',
|
||||
md5,
|
||||
mtime
|
||||
};
|
||||
await Zotero.Sync.Data.Local.processObjectsFromJSON('item', libraryID, [json]);
|
||||
|
||||
var item = await Zotero.Items.getByLibraryAndKeyAsync(libraryID, key);
|
||||
|
||||
await Zotero.Sync.Storage.Local.processDownload({
|
||||
item,
|
||||
md5,
|
||||
mtime,
|
||||
compressed: true
|
||||
});
|
||||
await OS.File.remove(zipFile);
|
||||
|
||||
var storageDir = Zotero.Attachments.getStorageDirectory(item).path;
|
||||
|
||||
// Make sure path is set correctly
|
||||
assert.equal(item.getFilePath(), PathUtils.join(storageDir, newFilename));
|
||||
// Make sure previous file doesn't exist
|
||||
assert.isFalse(await IOUtils.exists(PathUtils.join(storageDir, oldFilename)));
|
||||
// And new ones do
|
||||
assert.isTrue(await IOUtils.exists(PathUtils.join(storageDir, newFilename)));
|
||||
assert.isTrue(await IOUtils.exists(PathUtils.join(storageDir, auxFilename)));
|
||||
|
||||
// Make sure main file matches attachment hash and mtime
|
||||
assert.equal(
|
||||
await item.attachmentHash, Zotero.Utilities.Internal.md5(fileContents)
|
||||
);
|
||||
assert.equal(await item.attachmentModificationTime, mtime);
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue