mirror of
https://github.com/laurent22/joplin.git
synced 2025-04-14 11:18:47 +02:00
All: Allow attaching files of unknown mime type
This commit is contained in:
parent
aef2e4845d
commit
dbeff4fd7d
@ -132,7 +132,7 @@ class MdToHtml {
|
|||||||
if (isResourceUrl && !this.supportsResourceLinks_) {
|
if (isResourceUrl && !this.supportsResourceLinks_) {
|
||||||
// In mobile, links to local resources, such as PDF, etc. currently aren't supported.
|
// In mobile, links to local resources, such as PDF, etc. currently aren't supported.
|
||||||
// Ideally they should be opened in the user's browser.
|
// Ideally they should be opened in the user's browser.
|
||||||
return '[Resource not yet supported: '; //+ htmlentities(text) + ']';
|
return '<span style="opacity: 0.5">(Resource not yet supported: '; //+ htmlentities(text) + ']';
|
||||||
} else {
|
} else {
|
||||||
if (isResourceUrl) {
|
if (isResourceUrl) {
|
||||||
const resourceId = Resource.pathToId(href);
|
const resourceId = Resource.pathToId(href);
|
||||||
@ -150,7 +150,7 @@ class MdToHtml {
|
|||||||
const isResourceUrl = Resource.isResourceUrl(href);
|
const isResourceUrl = Resource.isResourceUrl(href);
|
||||||
|
|
||||||
if (isResourceUrl && !this.supportsResourceLinks_) {
|
if (isResourceUrl && !this.supportsResourceLinks_) {
|
||||||
return ']';
|
return ')</span>';
|
||||||
} else {
|
} else {
|
||||||
return '</a>';
|
return '</a>';
|
||||||
}
|
}
|
||||||
@ -159,6 +159,7 @@ class MdToHtml {
|
|||||||
renderTokens_(tokens, options) {
|
renderTokens_(tokens, options) {
|
||||||
let output = [];
|
let output = [];
|
||||||
let previousToken = null;
|
let previousToken = null;
|
||||||
|
let anchorAttrs = [];
|
||||||
for (let i = 0; i < tokens.length; i++) {
|
for (let i = 0; i < tokens.length; i++) {
|
||||||
const t = tokens[i];
|
const t = tokens[i];
|
||||||
const nextToken = i < tokens.length ? tokens[i+1] : null;
|
const nextToken = i < tokens.length ? tokens[i+1] : null;
|
||||||
@ -190,6 +191,7 @@ class MdToHtml {
|
|||||||
|
|
||||||
if (openTag) {
|
if (openTag) {
|
||||||
if (openTag === 'a') {
|
if (openTag === 'a') {
|
||||||
|
anchorAttrs.push(attrs);
|
||||||
output.push(this.renderOpenLink_(attrs, options));
|
output.push(this.renderOpenLink_(attrs, options));
|
||||||
} else {
|
} else {
|
||||||
const attrsHtml = this.renderAttrs_(attrs);
|
const attrsHtml = this.renderAttrs_(attrs);
|
||||||
@ -235,7 +237,7 @@ class MdToHtml {
|
|||||||
|
|
||||||
if (closeTag) {
|
if (closeTag) {
|
||||||
if (closeTag === 'a') {
|
if (closeTag === 'a') {
|
||||||
output.push(this.renderCloseLink_(attrs, options));
|
output.push(this.renderCloseLink_(anchorAttrs.pop(), options));
|
||||||
} else {
|
} else {
|
||||||
output.push('</' + closeTag + '>');
|
output.push('</' + closeTag + '>');
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ const { BackButtonService } = require('lib/services/back-button.js');
|
|||||||
const { BaseModel } = require('lib/base-model.js');
|
const { BaseModel } = require('lib/base-model.js');
|
||||||
const { ActionButton } = require('lib/components/action-button.js');
|
const { ActionButton } = require('lib/components/action-button.js');
|
||||||
const Icon = require('react-native-vector-icons/Ionicons').default;
|
const Icon = require('react-native-vector-icons/Ionicons').default;
|
||||||
const { fileExtension, basename } = require('lib/path-utils.js');
|
const { fileExtension, basename, safeFileExtension } = require('lib/path-utils.js');
|
||||||
const mimeUtils = require('lib/mime-utils.js').mime;
|
const mimeUtils = require('lib/mime-utils.js').mime;
|
||||||
const { ScreenHeader } = require('lib/components/screen-header.js');
|
const { ScreenHeader } = require('lib/components/screen-header.js');
|
||||||
const { time } = require('lib/time-utils.js');
|
const { time } = require('lib/time-utils.js');
|
||||||
@ -295,6 +295,9 @@ class NoteScreenComponent extends BaseScreenComponent {
|
|||||||
resource.id = uuid.create();
|
resource.id = uuid.create();
|
||||||
resource.mime = mimeType;
|
resource.mime = mimeType;
|
||||||
resource.title = pickerResponse.fileName ? pickerResponse.fileName : _('Untitled');
|
resource.title = pickerResponse.fileName ? pickerResponse.fileName : _('Untitled');
|
||||||
|
resource.file_extension = safeFileExtension(fileExtension(pickerResponse.fileName));
|
||||||
|
|
||||||
|
if (!resource.mime) resource.mime = 'application/octet-stream';
|
||||||
|
|
||||||
let targetPath = Resource.fullPath(resource);
|
let targetPath = Resource.fullPath(resource);
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ class JoplinDatabase extends Database {
|
|||||||
// default value and thus might cause problems. In that case, the default value
|
// default value and thus might cause problems. In that case, the default value
|
||||||
// must be set in the synchronizer too.
|
// must be set in the synchronizer too.
|
||||||
|
|
||||||
const existingDatabaseVersions = [0, 1, 2, 3, 4, 5, 6];
|
const existingDatabaseVersions = [0, 1, 2, 3, 4, 5, 6, 7];
|
||||||
|
|
||||||
let currentVersionIndex = existingDatabaseVersions.indexOf(fromVersion);
|
let currentVersionIndex = existingDatabaseVersions.indexOf(fromVersion);
|
||||||
if (currentVersionIndex == existingDatabaseVersions.length - 1) return false;
|
if (currentVersionIndex == existingDatabaseVersions.length - 1) return false;
|
||||||
@ -228,7 +228,7 @@ class JoplinDatabase extends Database {
|
|||||||
);
|
);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
queries.push({ sql: 'DROP TABLE deleted_items' });
|
// queries.push({ sql: 'DROP TABLE deleted_items' });
|
||||||
queries.push({ sql: this.sqlStringToLines(newTableSql)[0] });
|
queries.push({ sql: this.sqlStringToLines(newTableSql)[0] });
|
||||||
queries.push({ sql: "CREATE INDEX deleted_items_sync_target ON deleted_items (sync_target)" });
|
queries.push({ sql: "CREATE INDEX deleted_items_sync_target ON deleted_items (sync_target)" });
|
||||||
}
|
}
|
||||||
@ -259,6 +259,10 @@ class JoplinDatabase extends Database {
|
|||||||
queries.push('CREATE INDEX alarm_note_id ON alarms (note_id)');
|
queries.push('CREATE INDEX alarm_note_id ON alarms (note_id)');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (targetVersion == 7) {
|
||||||
|
queries.push('ALTER TABLE resources ADD COLUMN file_extension TEXT NOT NULL DEFAULT ""');
|
||||||
|
}
|
||||||
|
|
||||||
queries.push({ sql: 'UPDATE version SET version = ?', params: [targetVersion] });
|
queries.push({ sql: 'UPDATE version SET version = ?', params: [targetVersion] });
|
||||||
await this.transactionExecBatch(queries);
|
await this.transactionExecBatch(queries);
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ class Logger {
|
|||||||
output = object.toString();
|
output = object.toString();
|
||||||
if (object.code) output += "\nCode: " + object.code;
|
if (object.code) output += "\nCode: " + object.code;
|
||||||
if (object.headers) output += "\nHeader: " + JSON.stringify(object.headers);
|
if (object.headers) output += "\nHeader: " + JSON.stringify(object.headers);
|
||||||
if (object.request) output += "\nRequest: " + object.request;
|
if (object.request) output += "\nRequest: " + (object.request.substr ? object.request.substr(0, 1024) : '');
|
||||||
if (object.stack) output += "\n" + object.stack;
|
if (object.stack) output += "\n" + object.stack;
|
||||||
} else {
|
} else {
|
||||||
output = JSON.stringify(object);
|
output = JSON.stringify(object);
|
||||||
|
@ -33,7 +33,8 @@ class Resource extends BaseItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static filename(resource) {
|
static filename(resource) {
|
||||||
let extension = resource.mime ? mime.toFileExtension(resource.mime) : '';
|
let extension = resource.file_extension;
|
||||||
|
if (!extension) extension = resource.mime ? mime.toFileExtension(resource.mime) : '';
|
||||||
extension = extension ? '.' + extension : '';
|
extension = extension ? '.' + extension : '';
|
||||||
return resource.id + extension;
|
return resource.id + extension;
|
||||||
}
|
}
|
||||||
|
@ -35,4 +35,9 @@ function isHidden(path) {
|
|||||||
return b[0] === '.';
|
return b[0] === '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { basename, dirname, filename, isHidden, fileExtension };
|
function safeFileExtension(e) {
|
||||||
|
if (!e || !e.replace) return '';
|
||||||
|
return e.replace(/[^a-zA-Z0-9]/g, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { basename, dirname, filename, isHidden, fileExtension, safeFileExtension };
|
@ -82,7 +82,7 @@ function shimInit() {
|
|||||||
shim.attachFileToNote = async function(note, filePath) {
|
shim.attachFileToNote = async function(note, filePath) {
|
||||||
const { Resource } = require('lib/models/resource.js');
|
const { Resource } = require('lib/models/resource.js');
|
||||||
const { uuid } = require('lib/uuid.js');
|
const { uuid } = require('lib/uuid.js');
|
||||||
const { filename } = require('lib/path-utils.js');
|
const { basename, fileExtension, safeFileExtension } = require('lib/path-utils.js');
|
||||||
const mime = require('mime/lite');
|
const mime = require('mime/lite');
|
||||||
const { Note } = require('lib/models/note.js');
|
const { Note } = require('lib/models/note.js');
|
||||||
|
|
||||||
@ -91,7 +91,10 @@ function shimInit() {
|
|||||||
let resource = Resource.new();
|
let resource = Resource.new();
|
||||||
resource.id = uuid.create();
|
resource.id = uuid.create();
|
||||||
resource.mime = mime.getType(filePath);
|
resource.mime = mime.getType(filePath);
|
||||||
resource.title = filename(filePath);
|
resource.title = basename(filePath);
|
||||||
|
resource.file_extension = safeFileExtension(fileExtension(filePath));
|
||||||
|
|
||||||
|
if (!resource.mime) resource.mime = 'application/octet-stream';
|
||||||
|
|
||||||
let targetPath = Resource.fullPath(resource);
|
let targetPath = Resource.fullPath(resource);
|
||||||
|
|
||||||
@ -120,26 +123,6 @@ function shimInit() {
|
|||||||
return shim.fetchWithRetry(() => {
|
return shim.fetchWithRetry(() => {
|
||||||
return nodeFetch(url, options)
|
return nodeFetch(url, options)
|
||||||
}, options);
|
}, options);
|
||||||
|
|
||||||
// if (!options) options = {};
|
|
||||||
// if (!options.timeout) options.timeout = 1000 * 120; // ms
|
|
||||||
// if (!('maxRetry' in options)) options.maxRetry = 5;
|
|
||||||
|
|
||||||
// let retryCount = 0;
|
|
||||||
// while (true) {
|
|
||||||
// try {
|
|
||||||
// const response = await nodeFetch(url, options);
|
|
||||||
// return response;
|
|
||||||
// } catch (error) {
|
|
||||||
// if (fetchRequestCanBeRetried(error)) {
|
|
||||||
// retryCount++;
|
|
||||||
// if (retryCount > options.maxRetry) throw error;
|
|
||||||
// await time.sleep(retryCount * 3);
|
|
||||||
// } else {
|
|
||||||
// throw error;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shim.fetchBlob = async function(url, options) {
|
shim.fetchBlob = async function(url, options) {
|
||||||
@ -204,22 +187,6 @@ function shimInit() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return shim.fetchWithRetry(doFetchOperation, options);
|
return shim.fetchWithRetry(doFetchOperation, options);
|
||||||
|
|
||||||
// let retryCount = 0;
|
|
||||||
// while (true) {
|
|
||||||
// try {
|
|
||||||
// const response = await doFetchOperation();
|
|
||||||
// return response;
|
|
||||||
// } catch (error) {
|
|
||||||
// if (fetchRequestCanBeRetried(error)) {
|
|
||||||
// retryCount++;
|
|
||||||
// if (retryCount > options.maxRetry) throw error;
|
|
||||||
// await time.sleep(retryCount * 3);
|
|
||||||
// } else {
|
|
||||||
// throw error;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,26 +13,6 @@ function shimInit() {
|
|||||||
return shim.fetchWithRetry(() => {
|
return shim.fetchWithRetry(() => {
|
||||||
return shim.nativeFetch_(url, options)
|
return shim.nativeFetch_(url, options)
|
||||||
}, options);
|
}, options);
|
||||||
|
|
||||||
// if (!options) options = {};
|
|
||||||
// if (!options.timeout) options.timeout = 1000 * 120; // ms
|
|
||||||
// if (!('maxRetry' in options)) options.maxRetry = 5;
|
|
||||||
|
|
||||||
// let retryCount = 0;
|
|
||||||
// while (true) {
|
|
||||||
// try {
|
|
||||||
// const response = await nodeFetch(url, options);
|
|
||||||
// return response;
|
|
||||||
// } catch (error) {
|
|
||||||
// if (fetchRequestCanBeRetried(error)) {
|
|
||||||
// retryCount++;
|
|
||||||
// if (retryCount > options.maxRetry) throw error;
|
|
||||||
// await time.sleep(retryCount * 3);
|
|
||||||
// } else {
|
|
||||||
// throw error;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shim.fetchBlob = async function(url, options) {
|
shim.fetchBlob = async function(url, options) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user