ソースを参照

add support of `prompt` for `filenameConflictAction` with:
- WebDAV
- GitHub
- Google Drive

Gildas 2 年 前
コミット
8f351e68e0
4 ファイル変更52 行追加12 行削除
  1. 25 8
      src/core/bg/downloads.js
  2. 5 1
      src/core/content/content.js
  3. 13 2
      src/lib/gdrive/gdrive.js
  4. 9 1
      src/lib/github/github.js

+ 25 - 8
src/core/bg/downloads.js

@@ -43,6 +43,7 @@ const SCOPES = ["https://www.googleapis.com/auth/drive.file"];
 const CONFLICT_ACTION_SKIP = "skip";
 const CONFLICT_ACTION_UNIQUIFY = "uniquify";
 const CONFLICT_ACTION_OVERWRITE = "overwrite";
+const CONFLICT_ACTION_PROMPT = "prompt";
 const REGEXP_ESCAPE = /([{}()^$&.*?/+|[\\\\]|\]|-)/g;
 
 const gDrive = new GDrive(GDRIVE_CLIENT_ID, GDRIVE_CLIENT_KEY, SCOPES);
@@ -134,18 +135,23 @@ async function downloadTabPage(message, tab) {
 
 async function downloadContent(contents, tab, incognito, message) {
 	try {
+		const prompt = filename => promptFilename(tab.id, filename);
 		let response;
 		if (message.saveWithWebDAV) {
-			response = await saveWithWebDAV(message.taskId, encodeSharpCharacter(message.filename), contents.join(""), message.webDAVURL, message.webDAVUser, message.webDAVPassword, message.filenameConflictAction);
+			response = await saveWithWebDAV(message.taskId, encodeSharpCharacter(message.filename), contents.join(""), message.webDAVURL, message.webDAVUser, message.webDAVPassword, { filenameConflictAction: message.filenameConflictAction, prompt });
 		} else if (message.saveToGDrive) {
 			await saveToGDrive(message.taskId, encodeSharpCharacter(message.filename), new Blob(contents, { type: MIMETYPE_HTML }), {
 				forceWebAuthFlow: message.forceWebAuthFlow
 			}, {
 				onProgress: (offset, size) => ui.onUploadProgress(tab.id, offset, size),
-				filenameConflictAction: message.filenameConflictAction
+				filenameConflictAction: message.filenameConflictAction,
+				prompt
 			});
 		} else if (message.saveToGitHub) {
-			response = await saveToGitHub(message.taskId, encodeSharpCharacter(message.filename), contents.join(""), message.githubToken, message.githubUser, message.githubRepository, message.githubBranch, message.filenameConflictAction);
+			response = await saveToGitHub(message.taskId, encodeSharpCharacter(message.filename), contents.join(""), message.githubToken, message.githubUser, message.githubRepository, message.githubBranch, { 
+				filenameConflictAction: message.filenameConflictAction,
+				prompt
+			});
 			await response.pushPromise;
 		} else if (message.saveWithCompanion) {
 			await companion.save({
@@ -214,10 +220,10 @@ async function getAuthInfo(authOptions, force) {
 	return authInfo;
 }
 
-async function saveToGitHub(taskId, filename, content, githubToken, githubUser, githubRepository, githubBranch, filenameConflictAction) {
+async function saveToGitHub(taskId, filename, content, githubToken, githubUser, githubRepository, githubBranch, { filenameConflictAction, prompt }) {
 	const taskInfo = business.getTaskInfo(taskId);
 	if (!taskInfo || !taskInfo.cancelled) {
-		const pushInfo = pushGitHub(githubToken, githubUser, githubRepository, githubBranch, filename, content, { filenameConflictAction });
+		const pushInfo = pushGitHub(githubToken, githubUser, githubRepository, githubBranch, filename, content, { filenameConflictAction, prompt });
 		business.setCancelCallback(taskId, pushInfo.cancelPush);
 		try {
 			await (await pushInfo).pushPromise;
@@ -228,7 +234,7 @@ async function saveToGitHub(taskId, filename, content, githubToken, githubUser,
 	}
 }
 
-async function saveWithWebDAV(taskId, filename, content, url, username, password, filenameConflictAction) {
+async function saveWithWebDAV(taskId, filename, content, url, username, password, { filenameConflictAction, prompt }) {
 	const taskInfo = business.getTaskInfo(taskId);
 	const controller = new AbortController();
 	const { signal } = controller;
@@ -250,7 +256,7 @@ async function saveWithWebDAV(taskId, filename, content, url, username, password
 						if (response.status >= 400) {
 							throw new Error("Error " + response.status);
 						}
-						return saveWithWebDAV(taskId, filename, content, url, username, password, filenameConflictAction);
+						return saveWithWebDAV(taskId, filename, content, url, username, password, { filenameConflictAction, prompt });
 					}
 				} else if (filenameConflictAction == CONFLICT_ACTION_UNIQUIFY) {
 					let filenameWithoutExtension = filename;
@@ -266,11 +272,18 @@ async function saveWithWebDAV(taskId, filename, content, url, username, password
 						filename = filenameWithoutExtension + " (" + indexFilename + ")." + extension;
 						const response = await sendRequest(url + filename, "HEAD");
 						if (response.status == 404) {
-							return saveWithWebDAV(taskId, filename, content, url, username, password, filenameConflictAction);
+							return saveWithWebDAV(taskId, filename, content, url, username, password, { filenameConflictAction, prompt });
 						} else {
 							indexFilename++;
 						}
 					}
+				} else if (filenameConflictAction == CONFLICT_ACTION_PROMPT) {
+					filename = await prompt(filename);
+					if (filename) {
+						return saveWithWebDAV(taskId, filename, content, url, username, password, { filenameConflictAction, prompt });
+					} else {
+						return response;
+					}
 				} else if (filenameConflictAction == CONFLICT_ACTION_SKIP) {
 					return response;
 				}
@@ -352,6 +365,10 @@ async function saveToGDrive(taskId, filename, blob, authOptions, uploadOptions)
 	}
 }
 
+function promptFilename(tabId, filename) {
+	return browser.tabs.sendMessage(tabId, { method: "content.prompt", message: "Filename conflict, please enter a new filename", value: filename });
+}
+
 async function downloadPage(pageData, options) {
 	const filenameConflictAction = options.filenameConflictAction;
 	let skipped;

+ 5 - 1
src/core/content/content.js

@@ -37,7 +37,7 @@ let processor, processing;
 
 singlefile.init({ fetch, frameFetch });
 browser.runtime.onMessage.addListener(message => {
-	if (message.method == "content.save" || message.method == "content.cancelSave" || message.method == "content.getSelectedLinks" || message.method == "content.error") {
+	if (message.method == "content.save" || message.method == "content.cancelSave" || message.method == "content.getSelectedLinks" || message.method == "content.error"|| message.method == "content.prompt") {
 		return onMessage(message);
 	}
 });
@@ -66,6 +66,10 @@ async function onMessage(message) {
 		}
 		if (message.method == "content.error") {
 			onError(message.error, message.link);
+			return {};
+		}
+		if (message.method == "content.prompt") {
+			return ui.prompt(message.message, message.value);
 		}
 	}
 }

+ 13 - 2
src/lib/gdrive/gdrive.js

@@ -31,6 +31,7 @@ const GDRIVE_UPLOAD_URL = "https://www.googleapis.com/upload/drive/v3/files";
 const CONFLICT_ACTION_UNIQUIFY = "uniquify";
 const CONFLICT_ACTION_OVERWRITE = "overwrite";
 const CONFLICT_ACTION_SKIP = "skip";
+const CONFLICT_ACTION_PROMPT = "prompt";
 
 class GDrive {
 	constructor(clientId, clientKey, scopes) {
@@ -140,7 +141,8 @@ class GDrive {
 			parents: [parentFolderId],
 			filename,
 			onProgress: options.onProgress,
-			filenameConflictAction: options.filenameConflictAction
+			filenameConflictAction: options.filenameConflictAction,
+			prompt: options.prompt
 		});
 		try {
 			if (setCancelCallback) {
@@ -173,6 +175,7 @@ class MediaUploader {
 		this.offset = 0;
 		this.chunkSize = options.chunkSize || 512 * 1024;
 		this.filenameConflictAction = options.filenameConflictAction;
+		this.prompt = options.prompt;
 	}
 	async upload(indexFilename = 1) {
 		let method = "POST";
@@ -210,8 +213,16 @@ class MediaUploader {
 				} else {
 					this.metadata.name = name;
 				}
+			} else if (this.filenameConflictAction == CONFLICT_ACTION_PROMPT) {
+				const name = await this.prompt(this.metadata.name);
+				if (name) {
+					this.metadata.name = name;
+					return this.upload();
+				} else {
+					return response;
+				}
 			} else if (this.filenameConflictAction == CONFLICT_ACTION_SKIP) {
-				return {};
+				return response;
 			}
 		}
 		const httpResponse = getResponse(await fetch(GDRIVE_UPLOAD_URL + (fileId ? "/" + fileId : "") + "?uploadType=resumable", {

+ 9 - 1
src/lib/github/github.js

@@ -26,12 +26,13 @@
 const CONFLICT_ACTION_SKIP = "skip";
 const CONFLICT_ACTION_UNIQUIFY = "uniquify";
 const CONFLICT_ACTION_OVERWRITE = "overwrite";
+const CONFLICT_ACTION_PROMPT = "prompt";
 
 export { pushGitHub };
 
 let pendingPush;
 
-async function pushGitHub(token, userName, repositoryName, branchName, path, content, { filenameConflictAction } = {}) {
+async function pushGitHub(token, userName, repositoryName, branchName, path, content, { filenameConflictAction, prompt }) {
 	while (pendingPush) {
 		await pendingPush;
 	}
@@ -85,6 +86,13 @@ async function pushGitHub(token, userName, repositoryName, branchName, path, con
 					}
 				} else if (filenameConflictAction == CONFLICT_ACTION_SKIP) {
 					return responseData;
+				} else if (filenameConflictAction == CONFLICT_ACTION_PROMPT) {
+					path = await prompt(path); 
+					if (path) {
+						return createContent({ path, content, message }, signal);
+					} else {
+						return responseData;
+					}
 				} else {
 					throw new Error("File already exists");
 				}