File renaming: Match content type prefixes, add UI (#4431)

This commit is contained in:
Abe Jellinek 2024-07-27 03:01:43 -04:00 committed by GitHub
parent 4653059536
commit 4187819cd1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 152 additions and 45 deletions

View file

@ -476,7 +476,7 @@
case 'fileTypeID':
var rows = Zotero.FileTypes.getTypes().map(type => ({
name: Zotero.getString('fileTypes.' + type.name),
name: Zotero.getString('file-type-' + type.name),
value: type.id
}));

View file

@ -217,10 +217,30 @@ Zotero_Preferences.General = {
}
}),
setAutoRenameFileTypes: function () {
let typesBox = document.getElementById('zotero-prefpane-file-renaming-file-types-box');
let enabledTypes = new Set(Zotero.Prefs.get('autoRenameFiles.fileTypes').split(','));
for (let checkbox of typesBox.querySelectorAll('checkbox')) {
if (checkbox.checked) {
enabledTypes.add(checkbox.dataset.contentType);
}
else {
enabledTypes.delete(checkbox.dataset.contentType);
}
}
Zotero.Prefs.set('autoRenameFiles.fileTypes', [...enabledTypes].join(','));
},
updateAutoRenameFilesUI: function () {
setTimeout(() => {
document.getElementById('rename-linked-files').disabled = !Zotero.Prefs.get('autoRenameFiles');
});
let typesBox = document.getElementById('zotero-prefpane-file-renaming-file-types-box');
let enabledTypes = Zotero.Prefs.get('autoRenameFiles.fileTypes').split(',');
for (let checkbox of typesBox.querySelectorAll('checkbox')) {
checkbox.checked = enabledTypes.includes(checkbox.dataset.contentType);
}
},
//

View file

@ -116,6 +116,40 @@
preference="extensions.zotero.autoRenameFiles.linked"
oncommand="Zotero_Preferences.General.updateAutoRenameFilesUI()" native="true"
/>
<label data-l10n-id="preferences-file-renaming-file-types"/>
<hbox
id="zotero-prefpane-file-renaming-file-types-box"
class="indented-pref"
oncommand="Zotero_Preferences.General.setAutoRenameFileTypes()"
>
<checkbox
data-l10n-id="preferences-file-renaming-file-type-pdf"
data-content-type="application/pdf"
native="true"
/>
<checkbox
data-l10n-id="preferences-file-renaming-file-type-epub"
data-content-type="application/epub+zip"
native="true"
/>
<checkbox
data-l10n-id="preferences-file-renaming-file-type-image"
data-content-type="image/"
native="true"
/>
<checkbox
data-l10n-id="preferences-file-renaming-file-type-audio"
data-content-type="audio/"
native="true"
/>
<checkbox
data-l10n-id="preferences-file-renaming-file-type-video"
data-content-type="video/"
native="true"
/>
</hbox>
<button id="file-renaming-button"
data-l10n-id="preferences-file-renaming-customize-button"
data-search-strings="preferences-file-renaming-format-title, preferences-file-renaming-format-template"

View file

@ -580,7 +580,7 @@ Zotero.Attachments = new function () {
// Save using remote web browser persist
var externalHandlerImport = async function (contentType) {
// Rename attachment
if (renameIfAllowedType && !fileBaseName && this.getRenamedFileTypes().includes(contentType)) {
if (renameIfAllowedType && !fileBaseName && this.isRenameAllowedForType(contentType)) {
let parentItem = Zotero.Items.get(parentItemID);
fileBaseName = this.getFileBaseNameFromItem(parentItem);
}
@ -2443,24 +2443,38 @@ Zotero.Attachments = new function () {
}
this.getRenamedFileTypes = function () {
this.isRenameAllowedForType = function (contentType) {
let typePrefixes;
try {
var types = Zotero.Prefs.get('autoRenameFiles.fileTypes');
return types ? types.split(',') : [];
typePrefixes = (Zotero.Prefs.get('autoRenameFiles.fileTypes') || '')
.split(',');
}
catch (e) {
return [];
typePrefixes = [];
}
return typePrefixes.some(prefix => contentType.startsWith(prefix));
};
/**
* @deprecated
*/
this.getRenamedFileTypes = function () {
Zotero.debug('Zotero.Attachments.getRenamedFileTypes() is deprecated -- use isRenameAllowedForType()');
return Zotero.Prefs.get('autoRenameFiles.fileTypes')
.split(',')
// Don't include prefixes
.filter(type => /.+\/.+/.test(type));
};
this.getRenamedFileBaseNameIfAllowedType = async function (parentItem, file) {
var types = this.getRenamedFileTypes();
var contentType = file.endsWith('.pdf')
// Don't bother reading file if there's a .pdf extension
? 'application/pdf'
: await Zotero.MIME.getMIMETypeFromFile(file);
if (!types.includes(contentType)) {
if (!this.isRenameAllowedForType(contentType)) {
return false;
}
return this.getFileBaseNameFromItem(parentItem);

View file

@ -499,7 +499,7 @@ Zotero.Feed.prototype._updateFeed = Zotero.Promise.coroutine(function* () {
for (let attachment of attachmentsToAdd) {
if (attachment.url.indexOf('pdf') != -1 || attachment.contentType.indexOf('pdf') != -1) {
attachment.parentItemID = attachment.parentItem.id;
attachment.title = Zotero.getString('fileTypes.pdf');
attachment.title = Zotero.getString('file-type-pdf');
yield Zotero.Attachments.linkFromURL(attachment);
}
}

View file

@ -3864,16 +3864,29 @@ Zotero.Item.prototype.clearBestAttachmentState = function () {
Zotero.Item.prototype._getDefaultTitleForAttachmentContentType = function () {
switch (this.attachmentContentType) {
case 'application/pdf':
return Zotero.getString('fileTypes.pdf');
case 'application/epub+zip':
return Zotero.getString('fileTypes.ebook');
case 'text/html':
return Zotero.getString('fileTypes.webpage');
default:
return null;
let contentType = this.attachmentContentType;
if (!contentType) {
return null;
}
if (contentType === 'application/pdf') {
return Zotero.getString('file-type-pdf');
}
if (contentType === 'application/epub+zip') {
return Zotero.getString('file-type-ebook');
}
if (contentType === 'text/html') {
return Zotero.getString('file-type-webpage');
}
if (contentType.startsWith('image/')) {
return Zotero.getString('file-type-image');
}
if (contentType.startsWith('audio/')) {
return Zotero.getString('file-type-audio');
}
if (contentType.startsWith('video/')) {
return Zotero.getString('file-type-video');
}
return null;
};

View file

@ -150,7 +150,7 @@ class EditorInstance {
let fp = new FilePicker();
fp.init(this._iframeWindow, Zotero.getString('noteEditor.saveImageAs'), fp.modeSave);
fp.appendFilters(fp.filterImages);
fp.defaultString = Zotero.getString('fileTypes.image').toLowerCase() + '.' + ext;
fp.defaultString = Zotero.getString('file-type-image').toLowerCase() + '.' + ext;
let rv = await fp.show();
if (rv === fp.returnOK || rv === fp.returnReplace) {
let outputPath = fp.file;

View file

@ -28,6 +28,7 @@ Zotero.Intl = new function () {
let intlProps;
let pluralFormGet;
let pluralFormNumForms;
let ftl;
// Get settings from language pack (extracted by zotero-build/locale/merge_mozilla_files)
this.init = function () {
@ -88,6 +89,14 @@ Zotero.Intl = new function () {
this.strings[regexpResult[1]] = regexpResult[2];
}
}
// Provide synchronous access to Fluent strings for getString()
ftl = new Localization([
'zotero.ftl',
// More FTL files can be hardcoded here, or added later with
// Zotero.ftl.addResourceIds(['...'])
], true);
Zotero.ftl = ftl;
};
@ -108,11 +117,17 @@ Zotero.Intl = new function () {
}
l10n = bundle.formatStringFromName(name, params, params.length);
}
else if (this.strings[name]) {
return this.strings[name];
}
else {
l10n = bundle.GetStringFromName(name);
let ftlString = ftl.formatValueSync(name);
if (ftlString) {
return ftlString;
}
else if (this.strings[name]) {
return this.strings[name];
}
else {
l10n = bundle.GetStringFromName(name);
}
}
if (num !== undefined) {
let availableForms = l10n.split(/;/);

View file

@ -451,7 +451,7 @@ class ReaderInstance {
let fp = new FilePicker();
fp.init(this._iframeWindow, Zotero.getString('pdfReader.saveImageAs'), fp.modeSave);
fp.appendFilter("PNG", "*.png");
fp.defaultString = Zotero.getString('fileTypes.image').toLowerCase() + '.png';
fp.defaultString = Zotero.getString('file-type-image').toLowerCase() + '.png';
let rv = await fp.show();
if (rv === fp.returnOK || rv === fp.returnReplace) {
let outputPath = fp.file;

View file

@ -8,6 +8,17 @@ preferences-file-renaming-title = File Renaming
preferences-file-renaming-intro = { -app-name } automatically renames downloaded files based on the details of the parent item (title, author, etc.). You can choose to rename files added from your computer as well.
preferences-file-renaming-auto-rename-files =
.label = Automatically rename locally added files
preferences-file-renaming-file-types = Rename files of these types:
preferences-file-renaming-file-type-pdf =
.label = { file-type-pdf }
preferences-file-renaming-file-type-epub =
.label = { file-type-ebook }
preferences-file-renaming-file-type-image =
.label = { file-type-image }
preferences-file-renaming-file-type-audio =
.label = { file-type-audio }
preferences-file-renaming-file-type-video =
.label = { file-type-video }
preferences-file-renaming-customize-button =
.label = Customize Filename Format…

View file

@ -659,3 +659,12 @@ find-pdf-files-added = { $count ->
select-items-dialog =
.buttonlabelaccept = Select
file-type-webpage = Webpage
file-type-image = Image
file-type-pdf = PDF
file-type-audio = Audio
file-type-video = Video
file-type-presentation = Presentation
file-type-document = Document
file-type-ebook = Ebook

View file

@ -643,15 +643,6 @@ creatorTypes.reviewedAuthor = Reviewed Author
creatorTypes.cosponsor = Cosponsor
creatorTypes.bookAuthor = Book Author
fileTypes.webpage = Webpage
fileTypes.image = Image
fileTypes.pdf = PDF
fileTypes.audio = Audio
fileTypes.video = Video
fileTypes.presentation = Presentation
fileTypes.document = Document
fileTypes.ebook = Ebook
save.error.cannotMakeChangesToCollection = You cannot make changes to the currently selected collection.
save.error.cannotAddFilesToCollection = You cannot add files to the currently selected collection.
save.error.cannotAddToMyPublications = You cannot save items directly to My Publications. To add items, drag them from elsewhere in your library.

View file

@ -111,7 +111,7 @@ describe("Zotero.Attachments", function() {
file: file,
parentItemID: parent.id,
});
assert.equal(attachment.getField('title'), Zotero.getString('fileTypes.pdf'));
assert.equal(attachment.getField('title'), Zotero.getString('file-type-pdf'));
await parent.eraseTx();
});
})
@ -152,7 +152,7 @@ describe("Zotero.Attachments", function() {
file: file,
parentItemID: parent.id,
});
assert.equal(attachment.getField('title'), Zotero.getString('fileTypes.pdf'));
assert.equal(attachment.getField('title'), Zotero.getString('file-type-pdf'));
await parent.eraseTx();
});
})

View file

@ -1573,7 +1573,7 @@ describe("Zotero.ItemTree", function() {
// Add a PDF attachment, which will get a default title
let pdfAttachment1 = Zotero.Items.get((await promise)[0]);
assert.equal(pdfAttachment1.parentItemID, parentItem.id);
assert.equal(pdfAttachment1.getField('title'), Zotero.getString('fileTypes.pdf'));
assert.equal(pdfAttachment1.getField('title'), Zotero.getString('file-type-pdf'));
promise = waitForItemEvent('add');
drop(parentRow, 0, dataTransfer);

View file

@ -70,7 +70,7 @@ describe("Document Recognition", function() {
// The title should have changed
assert.equal(
attachment.getField('title'),
Zotero.getString('fileTypes.pdf')
Zotero.getString('file-type-pdf')
);
});
@ -103,7 +103,7 @@ describe("Document Recognition", function() {
// The title should have changed
assert.equal(
attachment.getField('title'),
Zotero.getString('fileTypes.pdf')
Zotero.getString('file-type-pdf')
);
});
@ -276,7 +276,7 @@ describe("Document Recognition", function() {
// The title should have changed
assert.equal(
attachment.getField('title'),
Zotero.getString('fileTypes.pdf')
Zotero.getString('file-type-pdf')
);
});
@ -317,7 +317,7 @@ describe("Document Recognition", function() {
// The title should have changed
assert.equal(
attachment.getField('title'),
Zotero.getString('fileTypes.pdf')
Zotero.getString('file-type-pdf')
);
});
});
@ -370,7 +370,7 @@ describe("Document Recognition", function() {
// The title should have changed
assert.equal(
attachment.getField('title'),
Zotero.getString('fileTypes.ebook')
Zotero.getString('file-type-ebook')
);
translateStub.restore();
@ -408,7 +408,7 @@ describe("Document Recognition", function() {
// The title should have changed
assert.equal(
attachment.getField('title'),
Zotero.getString('fileTypes.ebook')
Zotero.getString('file-type-ebook')
);
});

View file

@ -2293,7 +2293,7 @@ describe("Zotero.Translate.ItemGetter", function() {
// Set fields
assert.equal(attachment.itemType, 'attachment', prefix + 'itemType is correct' + suffix);
assert.include([Zotero.getString('fileTypes.pdf'), 'empty'], attachment.title, prefix + 'title is correct' + suffix);
assert.include([Zotero.getString('file-type-pdf'), 'empty'], attachment.title, prefix + 'title is correct' + suffix);
assert.equal(attachment.url, 'http://example.com', prefix + 'url is correct' + suffix);
assert.equal(attachment.note, 'note', prefix + 'note is correct' + suffix);

View file

@ -1650,7 +1650,7 @@ describe("ZoteroPane", function() {
file.append('test.pdf');
let [pdfAttachment1] = await zp.addAttachmentFromDialog(false, parentItem.id, [file.path]);
assert.equal(parentItem.getAttachments().length, 2);
assert.equal(pdfAttachment1.getField('title'), Zotero.getString('fileTypes.pdf'));
assert.equal(pdfAttachment1.getField('title'), Zotero.getString('file-type-pdf'));
// Add a second, which will get a title based on its filename
let [pdfAttachment2] = await zp.addAttachmentFromDialog(false, parentItem.id, [file.path]);
@ -1662,7 +1662,7 @@ describe("ZoteroPane", function() {
file.append('stub.epub');
let [epubAttachment] = await zp.addAttachmentFromDialog(false, parentItem.id, [file.path]);
assert.equal(parentItem.getAttachments().length, 4);
assert.equal(epubAttachment.getField('title'), Zotero.getString('fileTypes.ebook'));
assert.equal(epubAttachment.getField('title'), Zotero.getString('file-type-ebook'));
});
});
})