diff --git a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/books_overview.js b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/books_overview.js index e99b8ed..1a64504 100644 --- a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/books_overview.js +++ b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/books_overview.js @@ -14,28 +14,32 @@ export class GitrepoExporterBooksOverview { } init() { - const githubAccount = this.booksOverview.app.config.user.socialaccounts.find(account => account.provider === "github") - const gitlabAccount = this.booksOverview.app.config.user.socialaccounts.find(account => account.provider === "gitlab") + const githubAccount = + this.booksOverview.app.config.user.socialaccounts.find( + account => account.provider === "github" + ) + const gitlabAccount = + this.booksOverview.app.config.user.socialaccounts.find( + account => account.provider === "gitlab" + ) if (!githubAccount && !gitlabAccount) { return } - Promise.all([ - this.getUserRepos(), - this.getBookRepos() - ]).then( - () => { - this.finishedLoading = true - const spinner = document.querySelector("tbody.gitrepo-repository .fa-spinner") - if (spinner) { - document.querySelector("tbody.gitrepo-repository").innerHTML = repoSelectorTemplate({ + Promise.all([this.getUserRepos(), this.getBookRepos()]).then(() => { + this.finishedLoading = true + const spinner = document.querySelector( + "tbody.gitrepo-repository .fa-spinner" + ) + if (spinner) { + document.querySelector("tbody.gitrepo-repository").innerHTML = + repoSelectorTemplate({ book: this.openedBook, userRepos: this.userRepos, bookRepos: this.bookRepos, userReposMultitype: this.userReposMultitype }) - } } - ) + }) this.addButton() this.addDialogPart() this.addDialogSaveMethod() @@ -59,23 +63,24 @@ export class GitrepoExporterBooksOverview { this.finishedLoading = false const repoSelector = document.querySelector("tbody.gitrepo-repository") if (repoSelector) { - repoSelector.innerHTML = "" + repoSelector.innerHTML = + "" } - this.getUserRepos(true).then( - () => { - this.finishedLoading = true - const repoSelector = document.querySelector("tbody.gitrepo-repository") - if (repoSelector) { - repoSelector.innerHTML = repoSelectorTemplate({ - book: this.openedBook, - userRepos: this.userRepos, - bookRepos: this.bookRepos, - userReposMultitype: this.userReposMultitype - }) - } + this.getUserRepos(true).then(() => { + this.finishedLoading = true + const repoSelector = document.querySelector( + "tbody.gitrepo-repository" + ) + if (repoSelector) { + repoSelector.innerHTML = repoSelectorTemplate({ + book: this.openedBook, + userRepos: this.userRepos, + bookRepos: this.bookRepos, + userReposMultitype: this.userReposMultitype + }) } - ) + }) } getUserRepos(reload = false) { @@ -85,17 +90,15 @@ export class GitrepoExporterBooksOverview { } return getJson( `/api/gitrepo_export/get_git_repos/${reload ? "reload/" : ""}` - ).then( - ({repos}) => { - const initialType = repos.length ? repos[0].type : "" - repos.forEach(entry => { - this.userRepos[entry.type + "-" + entry.id] = entry - if (entry.type !== initialType) { - this.userReposMultitype = true - } - }) - } - ) + ).then(({repos}) => { + const initialType = repos.length ? repos[0].type : "" + repos.forEach(entry => { + this.userRepos[entry.type + "-" + entry.id] = entry + if (entry.type !== initialType) { + this.userReposMultitype = true + } + }) + }) } getBookRepos() { @@ -109,12 +112,23 @@ export class GitrepoExporterBooksOverview { getRepos(book) { const bookRepo = this.bookRepos[book.id] if (!bookRepo) { - addAlert("error", `${gettext("There is no git repository registered for the book:")} ${book.title}`) + addAlert( + "error", + `${gettext( + "There is no git repository registered for the book:" + )} ${book.title}` + ) return [false, false] } - const userRepo = this.userRepos[bookRepo.repo_type + "-" + bookRepo.repo_id] + const userRepo = + this.userRepos[bookRepo.repo_type + "-" + bookRepo.repo_id] if (!userRepo) { - addAlert("error", `${gettext("You do not have access to the repository:")} ${bookRepo.github_repo_full_name}`) + addAlert( + "error", + `${gettext("You do not have access to the repository:")} ${ + bookRepo.github_repo_full_name + }` + ) return [bookRepo, false] } return [bookRepo, userRepo] @@ -127,30 +141,31 @@ export class GitrepoExporterBooksOverview { action: overview => { const ids = overview.getSelected() if (ids.length) { - overview.bookList.filter(book => ids.includes(book.id)).forEach( - book => { + overview.bookList + .filter(book => ids.includes(book.id)) + .forEach(book => { const [bookRepo, userRepo] = this.getRepos(book) if (!userRepo) { return } - const processor = userRepo.type === "github" ? - new GithubBookProcessor( - overview.app, - overview, - book, - bookRepo, - userRepo - ) : - new GitlabBookProcessor( - overview.app, - overview, - book, - bookRepo, - userRepo - ) + const processor = + userRepo.type === "github" + ? new GithubBookProcessor( + overview.app, + overview, + book, + bookRepo, + userRepo + ) + : new GitlabBookProcessor( + overview.app, + overview, + book, + bookRepo, + userRepo + ) processor.init() - } - ) + }) } }, disabled: overview => !overview.getSelected().length @@ -159,31 +174,30 @@ export class GitrepoExporterBooksOverview { title: gettext("Export to Git Repository"), tooltip: gettext("Export book to git repository."), action: ({saveBook, book, overview}) => { - saveBook().then( - () => { - const [bookRepo, userRepo] = this.getRepos(book) - if (!userRepo) { - return - } - const processor = userRepo.type === "github" ? - new GithubBookProcessor( + saveBook().then(() => { + const [bookRepo, userRepo] = this.getRepos(book) + if (!userRepo) { + return + } + const processor = + userRepo.type === "github" + ? new GithubBookProcessor( overview.app, overview, book, bookRepo, userRepo - ) : - new GitlabBookProcessor( + ) + : new GitlabBookProcessor( overview.app, overview, book, bookRepo, userRepo ) - processor.init() - } - ) - }, + processor.init() + }) + } }) } @@ -196,91 +210,107 @@ export class GitrepoExporterBooksOverview { return ` ${ - this.finishedLoading ? - repoSelectorTemplate({ + this.finishedLoading + ? repoSelectorTemplate({ book, userRepos: this.userRepos, bookRepos: this.bookRepos, - userReposMultitype: this.userReposMultitype - }) : - "" + userReposMultitype: + this.userReposMultitype + }) + : "" }
` } - }) } addDialogSaveMethod() { - this.booksOverview.mod.actions.onSave.push( - book => { - const repoSelector = document.querySelector("#book-settings-repository") - if (!repoSelector) { - // Dialog may have been closed before the repoSelector was loaded - return + this.booksOverview.mod.actions.onSave.push(book => { + const repoSelector = document.querySelector( + "#book-settings-repository" + ) + if (!repoSelector) { + // Dialog may have been closed before the repoSelector was loaded + return + } + const selected = repoSelector.value.split("-") + const repoType = selected[0] + let repoId = parseInt(selected[1]) + const exportEpub = document.querySelector( + "#book-settings-repository-epub" + ).checked + const exportUnpackedEpub = document.querySelector( + "#book-settings-repository-unpacked-epub" + ).checked + const exportHtml = document.querySelector( + "#book-settings-repository-html" + ).checked + const exportUnifiedHtml = document.querySelector( + "#book-settings-repository-unified-html" + ).checked + const exportLatex = document.querySelector( + "#book-settings-repository-latex" + ).checked + if ( + !exportEpub && + !exportUnpackedEpub && + !exportHtml && + !exportUnifiedHtml && + !exportLatex + ) { + // No export formats selected. Reset repository. + repoId = 0 + } + if ( + (repoId === 0 && this.bookRepos[book.id]) || + (repoId > 0 && + (!this.bookRepos[book.id] || + this.bookRepos[book.id].repo_id !== repoId || + this.bookRepos[book.id].export_epub !== exportEpub || + this.bookRepos[book.id].export_unpacked_epub !== + exportUnpackedEpub || + this.bookRepos[book.id].export_html !== exportHtml || + this.bookRepos[book.id].export_unified_html !== + exportUnifiedHtml || + this.bookRepos[book.id].export_latex !== exportLatex)) + ) { + const postData = { + book_id: book.id, + repo_type: repoType, + repo_id: repoId } - const selected = repoSelector.value.split("-") - const repoType = selected[0] - let repoId = parseInt(selected[1]) - const exportEpub = document.querySelector("#book-settings-repository-epub").checked - const exportUnpackedEpub = document.querySelector("#book-settings-repository-unpacked-epub").checked - const exportHtml = document.querySelector("#book-settings-repository-html").checked - const exportUnifiedHtml = document.querySelector("#book-settings-repository-unified-html").checked - const exportLatex = document.querySelector("#book-settings-repository-latex").checked - if (!exportEpub && !exportUnpackedEpub && !exportHtml && !exportUnifiedHtml && !exportLatex) { - // No export formats selected. Reset repository. - repoId = 0 + if (repoId > 0) { + postData["repo_name"] = + this.userRepos[`${repoType}-${repoId}`].name + postData["export_epub"] = exportEpub + postData["export_unpacked_epub"] = exportUnpackedEpub + postData["export_html"] = exportHtml + postData["export_unified_html"] = exportUnifiedHtml + postData["export_latex"] = exportLatex } - if ( - (repoId === 0 && this.bookRepos[book.id]) || - (repoId > 0 && - ( - !this.bookRepos[book.id] || - this.bookRepos[book.id].repo_id !== repoId || - this.bookRepos[book.id].export_epub !== exportEpub || - this.bookRepos[book.id].export_unpacked_epub !== exportUnpackedEpub || - this.bookRepos[book.id].export_html !== exportHtml || - this.bookRepos[book.id].export_unified_html !== exportUnifiedHtml || - this.bookRepos[book.id].export_latex !== exportLatex - ) - ) - ) { - const postData = { - book_id: book.id, - repo_type: repoType, - repo_id: repoId - } - if (repoId > 0) { - postData["repo_name"] = this.userRepos[`${repoType}-${repoId}`].name - postData["export_epub"] = exportEpub - postData["export_unpacked_epub"] = exportUnpackedEpub - postData["export_html"] = exportHtml - postData["export_unified_html"] = exportUnifiedHtml - postData["export_latex"] = exportLatex - } - return post("/api/gitrepo_export/update_book_repo/", postData).then( - () => { - if (repoId === 0) { - delete this.bookRepos[book.id] - } else { - this.bookRepos[book.id] = { - repo_id: repoId, - repo_type: repoType, - repo_name: this.userRepos[`${repoType}-${repoId}`].name, - export_epub: exportEpub, - export_unpacked_epub: exportUnpackedEpub, - export_html: exportHtml, - export_unified_html: exportUnifiedHtml, - export_latex: exportLatex - } - } - + return post( + "/api/gitrepo_export/update_book_repo/", + postData + ).then(() => { + if (repoId === 0) { + delete this.bookRepos[book.id] + } else { + this.bookRepos[book.id] = { + repo_id: repoId, + repo_type: repoType, + repo_name: + this.userRepos[`${repoType}-${repoId}`].name, + export_epub: exportEpub, + export_unpacked_epub: exportUnpackedEpub, + export_html: exportHtml, + export_unified_html: exportUnifiedHtml, + export_latex: exportLatex } - ) - } + } + }) } - ) + }) } - } diff --git a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/book_exporters.js b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/book_exporters.js index 98300f4..e87a9db 100644 --- a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/book_exporters.js +++ b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/book_exporters.js @@ -1,5 +1,8 @@ import {EpubBookExporter} from "../../books/exporter/epub" -import {HTMLBookExporter, SingleFileHTMLBookExporter} from "../../books/exporter/html" +import { + HTMLBookExporter, + SingleFileHTMLBookExporter +} from "../../books/exporter/html" import {LatexBookExporter} from "../../books/exporter/latex" import {commitFile, commitZipContents} from "./tools" @@ -10,13 +13,10 @@ export class EpubBookGithubExporter extends EpubBookExporter { } download(blob) { - return () => commitFile( - this.repo, - blob, - "book.epub" - ).then( - response => [response] - ) + return () => + commitFile(this.repo, blob, "book.epub").then(response => [ + response + ]) } } @@ -27,13 +27,14 @@ export class UnpackedEpubBookGithubExporter extends EpubBookExporter { } createZip() { - return () => commitZipContents( - this.repo, - this.outputList, - this.binaryFiles, - this.includeZips, - "epub/" - ) + return () => + commitZipContents( + this.repo, + this.outputList, + this.binaryFiles, + this.includeZips, + "epub/" + ) } } @@ -44,13 +45,14 @@ export class HTMLBookGithubExporter extends HTMLBookExporter { } createZip() { - return () => commitZipContents( - this.repo, - this.outputList, - this.binaryFiles, - this.includeZips, - "html/" - ) + return () => + commitZipContents( + this.repo, + this.outputList, + this.binaryFiles, + this.includeZips, + "html/" + ) } } @@ -61,13 +63,14 @@ export class SingleFileHTMLBookGithubExporter extends SingleFileHTMLBookExporter } createZip() { - return () => commitZipContents( - this.repo, - this.outputList, - this.binaryFiles, - this.includeZips, - "uhtml/" - ) + return () => + commitZipContents( + this.repo, + this.outputList, + this.binaryFiles, + this.includeZips, + "uhtml/" + ) } } @@ -78,12 +81,13 @@ export class LatexBookGithubExporter extends LatexBookExporter { } createZip() { - return () => commitZipContents( - this.repo, - this.textFiles, - this.httpFiles, - [], - "latex/" - ) + return () => + commitZipContents( + this.repo, + this.textFiles, + this.httpFiles, + [], + "latex/" + ) } } diff --git a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/book_processor.js b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/book_processor.js index cbfe47d..70fff1a 100644 --- a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/book_processor.js +++ b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/book_processor.js @@ -1,5 +1,11 @@ import {addAlert, Dialog, escapeText} from "../../common" -import {EpubBookGithubExporter, UnpackedEpubBookGithubExporter, HTMLBookGithubExporter, LatexBookGithubExporter, SingleFileHTMLBookGithubExporter} from "./book_exporters" +import { + EpubBookGithubExporter, + UnpackedEpubBookGithubExporter, + HTMLBookGithubExporter, + LatexBookGithubExporter, + SingleFileHTMLBookGithubExporter +} from "./book_exporters" import {promiseChain, commitTree} from "./tools" export class GithubBookProcessor { @@ -12,11 +18,9 @@ export class GithubBookProcessor { } init() { - return this.getCommitMessage().then( - commitMessage => this.publishBook(commitMessage) - ).catch( - () => {} - ) + return this.getCommitMessage() + .then(commitMessage => this.publishBook(commitMessage)) + .catch(() => {}) } getCommitMessage() { @@ -26,7 +30,9 @@ export class GithubBookProcessor { text: gettext("Submit"), classes: "fw-dark", click: () => { - const commitMessage = dialog.dialogEl.querySelector(".commit-message").value || gettext("Update from Fidus Writer") + const commitMessage = + dialog.dialogEl.querySelector(".commit-message") + .value || gettext("Update from Fidus Writer") dialog.close() resolve(commitMessage) } @@ -45,7 +51,9 @@ export class GithubBookProcessor { height: 150, body: `

${gettext("Updating")}: ${escapeText(this.book.title)} - +

`, buttons }) @@ -69,9 +77,7 @@ export class GithubBookProcessor { new Date(this.book.updated * 1000), this.userRepo ) - commitInitiators.push( - epubExporter.init() - ) + commitInitiators.push(epubExporter.init()) } if (this.bookRepo.export_unpacked_epub) { @@ -85,9 +91,7 @@ export class GithubBookProcessor { new Date(this.book.updated * 1000), this.userRepo ) - commitInitiators.push( - unpackedEpubExporter.init() - ) + commitInitiators.push(unpackedEpubExporter.init()) } if (this.bookRepo.export_html) { @@ -101,9 +105,7 @@ export class GithubBookProcessor { new Date(this.book.updated * 1000), this.userRepo ) - commitInitiators.push( - htmlExporter.init() - ) + commitInitiators.push(htmlExporter.init()) } if (this.bookRepo.export_unified_html) { @@ -117,9 +119,7 @@ export class GithubBookProcessor { new Date(this.book.updated * 1000), this.userRepo ) - commitInitiators.push( - unifiedHtmlExporter.init() - ) + commitInitiators.push(unifiedHtmlExporter.init()) } if (this.bookRepo.export_latex) { @@ -131,26 +131,46 @@ export class GithubBookProcessor { new Date(this.book.updated * 1000), this.userRepo ) - commitInitiators.push( - latexExporter.init() - ) + commitInitiators.push(latexExporter.init()) } - return Promise.all(commitInitiators).then(commitFunctions => promiseChain(commitFunctions.flat()).then( - responses => { + return Promise.all(commitInitiators).then(commitFunctions => + promiseChain(commitFunctions.flat()).then(responses => { const responseCodes = responses.flat() if (responseCodes.every(code => code === 304)) { - addAlert("info", gettext("Book already up to date in repository.")) + addAlert( + "info", + gettext("Book already up to date in repository.") + ) } else if (responseCodes.every(code => code === 400)) { - addAlert("error", gettext("Could not publish book to repository.")) + addAlert( + "error", + gettext("Could not publish book to repository.") + ) } else if (responseCodes.find(code => code === 400)) { - addAlert("error", gettext("Could not publish some parts of book to repository.")) + addAlert( + "error", + gettext( + "Could not publish some parts of book to repository." + ) + ) } else { // The responses looks fine, but we are not done yet. - commitTree(responseCodes.filter(response => typeof(response) === "object"), commitMessage, this.userRepo).then( - () => addAlert("info", gettext("Book published to repository successfully!")) + commitTree( + responseCodes.filter( + response => typeof response === "object" + ), + commitMessage, + this.userRepo + ).then(() => + addAlert( + "info", + gettext( + "Book published to repository successfully!" + ) + ) ) } - } - )) + }) + ) } } diff --git a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/tools/commit_file.js b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/tools/commit_file.js index cff9d20..1a2c421 100644 --- a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/tools/commit_file.js +++ b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/tools/commit_file.js @@ -1,31 +1,42 @@ import {getJson, getCookie} from "../../../common" import {gitHashObject, readBlobPromise} from "../../tools" -export function commitFile(repo, blob, filename, parentDir = "", repoDirCache = {}) { - const dirUrl = `/api/gitrepo_export/proxy_github/repos/${repo.name}/contents/${parentDir}`.replace(/\/\//, "/") - const getDirJsonPromise = repoDirCache[dirUrl] ? - Promise.resolve(repoDirCache[dirUrl]) : - getJson(dirUrl).then( - json => { +export function commitFile( + repo, + blob, + filename, + parentDir = "", + repoDirCache = {} +) { + const dirUrl = + `/api/gitrepo_export/proxy_github/repos/${repo.name}/contents/${parentDir}`.replace( + /\/\//, + "/" + ) + const getDirJsonPromise = repoDirCache[dirUrl] + ? Promise.resolve(repoDirCache[dirUrl]) + : getJson(dirUrl) + .then(json => { repoDirCache[dirUrl] = json return Promise.resolve(json) - } - ).catch( - error => { - if (error.status === 302) {// Redirect - which means the directory does not exist. + }) + .catch(error => { + if (error.status === 302) { + // Redirect - which means the directory does not exist. return Promise.resolve(false) } throw error - } - ) + }) const csrfToken = getCookie("csrftoken") - return Promise.resolve(getDirJsonPromise).then(json => { - const fileEntry = Array.isArray(json) ? json.find(entry => entry.name === filename) : false - const commitData = { - encoding: "base64", - } - return readBlobPromise(blob).then( - content => { + return Promise.resolve(getDirJsonPromise) + .then(json => { + const fileEntry = Array.isArray(json) + ? json.find(entry => entry.name === filename) + : false + const commitData = { + encoding: "base64" + } + return readBlobPromise(blob).then(content => { commitData.content = content if (!fileEntry) { return Promise.resolve(commitData) @@ -39,51 +50,49 @@ export function commitFile(repo, blob, filename, parentDir = "", repoDirCache = // UTF-8 files seem to have no type set. // Not sure if this is actually a viable way to distinguish between utf-8 and binary files. !blob.type.length - ).then( - sha => { - if (sha === fileEntry.sha) { - return Promise.resolve(304) - } else { - return Promise.resolve(commitData) - } + ).then(sha => { + if (sha === fileEntry.sha) { + return Promise.resolve(304) + } else { + return Promise.resolve(commitData) } - ) + }) + }) + }) + .then(commitData => { + if (!commitData || commitData === 304) { + return Promise.resolve(304) } - ) - - }).then(commitData => { - if (!commitData || commitData === 304) { - return Promise.resolve(304) - } - return fetch(`/api/gitrepo_export/proxy_github/repos/${repo.name}/git/blobs`.replace(/\/\//, "/"), { - method: "POST", - headers: { - "X-CSRFToken": csrfToken, - }, - credentials: "include", - body: JSON.stringify(commitData) - }).then( - response => { + return fetch( + `/api/gitrepo_export/proxy_github/repos/${repo.name}/git/blobs`.replace( + /\/\//, + "/" + ), + { + method: "POST", + headers: { + "X-CSRFToken": csrfToken + }, + credentials: "include", + body: JSON.stringify(commitData) + } + ).then(response => { if (response.ok) { - return response.json().then( - json => { - const treeObject = { - path: `${parentDir}${filename}`, - sha: json.sha, - mode: "100644", - type: "blob" - } - return treeObject + return response.json().then(json => { + const treeObject = { + path: `${parentDir}${filename}`, + sha: json.sha, + mode: "100644", + type: "blob" } - ) + return treeObject + }) } else { return Promise.resolve(400) } - } - ) - }).catch( - _error => { + }) + }) + .catch(_error => { return Promise.resolve(400) - } - ) + }) } diff --git a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/tools/commit_tree.js b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/tools/commit_tree.js index 3e57bd2..34272fc 100644 --- a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/tools/commit_tree.js +++ b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/tools/commit_tree.js @@ -3,19 +3,32 @@ import {getJson, getCookie} from "../../../common" export function commitTree(tree, commitMessage, repo) { let branch, parentSha const csrfToken = getCookie("csrftoken") - return getJson(`/api/gitrepo_export/proxy_github/repos/${repo.name}`.replace(/\/\//, "/")).then( - repoJson => { + return getJson( + `/api/gitrepo_export/proxy_github/repos/${repo.name}`.replace( + /\/\//, + "/" + ) + ) + .then(repoJson => { branch = repoJson.default_branch - return getJson(`/api/gitrepo_export/proxy_github/repos/${repo.name}/git/refs/heads/${branch}`.replace(/\/\//, "/")) - }).then( - refsJson => { + return getJson( + `/api/gitrepo_export/proxy_github/repos/${repo.name}/git/refs/heads/${branch}`.replace( + /\/\//, + "/" + ) + ) + }) + .then(refsJson => { parentSha = refsJson.object.sha return fetch( - `/api/gitrepo_export/proxy_github/repos/${repo.name}/git/trees`.replace(/\/\//, "/"), + `/api/gitrepo_export/proxy_github/repos/${repo.name}/git/trees`.replace( + /\/\//, + "/" + ), { method: "POST", headers: { - "X-CSRFToken": csrfToken, + "X-CSRFToken": csrfToken }, credentials: "include", body: JSON.stringify({ @@ -24,39 +37,45 @@ export function commitTree(tree, commitMessage, repo) { }) } ) - }).then( - response => response.json() - ).then( - treeJson => fetch( - `/api/gitrepo_export/proxy_github/repos/${repo.name}/git/commits`.replace(/\/\//, "/"), - { - method: "POST", - headers: { - "X-CSRFToken": csrfToken, - }, - credentials: "include", - body: JSON.stringify({ - tree: treeJson.sha, - parents: [parentSha], - message: commitMessage - }) - } + }) + .then(response => response.json()) + .then(treeJson => + fetch( + `/api/gitrepo_export/proxy_github/repos/${repo.name}/git/commits`.replace( + /\/\//, + "/" + ), + { + method: "POST", + headers: { + "X-CSRFToken": csrfToken + }, + credentials: "include", + body: JSON.stringify({ + tree: treeJson.sha, + parents: [parentSha], + message: commitMessage + }) + } + ) ) - ).then( - response => response.json() - ).then( - commitJson => fetch( - `/api/gitrepo_export/proxy_github/repos/${repo.name}/git/refs/heads/${branch}`.replace(/\/\//, "/"), - { - method: "PATCH", - headers: { - "X-CSRFToken": csrfToken, - }, - credentials: "include", - body: JSON.stringify({ - sha: commitJson.sha - }) - } + .then(response => response.json()) + .then(commitJson => + fetch( + `/api/gitrepo_export/proxy_github/repos/${repo.name}/git/refs/heads/${branch}`.replace( + /\/\//, + "/" + ), + { + method: "PATCH", + headers: { + "X-CSRFToken": csrfToken + }, + credentials: "include", + body: JSON.stringify({ + sha: commitJson.sha + }) + } + ) ) - ) } diff --git a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/tools/commit_zip_contents.js b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/tools/commit_zip_contents.js index 58a90d4..fa047e9 100644 --- a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/tools/commit_zip_contents.js +++ b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/tools/commit_zip_contents.js @@ -2,69 +2,87 @@ import {commitFile} from "./commit_file" import {promiseChain} from "./promise_chain" import {get, getCookie} from "../../../common" -export function commitZipContents(repo, outputList, binaryFiles, includeZips, parentDir = "") { +export function commitZipContents( + repo, + outputList, + binaryFiles, + includeZips, + parentDir = "" +) { const csrfToken = getCookie("csrftoken") const repoDirCache = {} const textCommitFunctions = outputList.map(file => { const blob = new Blob([file.contents]) const filepathParts = file.filename.split("/") const filename = filepathParts.pop() - const subDir = `${parentDir}${filepathParts.join("/")}/`.replace(/\/\//, "/") - return () => commitFile( - repo, - blob, - filename, - subDir, - repoDirCache + const subDir = `${parentDir}${filepathParts.join("/")}/`.replace( + /\/\//, + "/" ) + return () => commitFile(repo, blob, filename, subDir, repoDirCache) }) - const commitBinaries = binaryFiles.map(file => get(file.url).then(response => response.blob()).then(blob => { - const filepathParts = file.filename.split("/") - const filename = filepathParts.pop() - const subDir = `${parentDir}${filepathParts.join("/")}/`.replace(/\/\//, "/") - return () => commitFile( - repo, - blob, - filename, - subDir, - repoDirCache - ) - })) + const commitBinaries = binaryFiles.map(file => + get(file.url) + .then(response => response.blob()) + .then(blob => { + const filepathParts = file.filename.split("/") + const filename = filepathParts.pop() + const subDir = `${parentDir}${filepathParts.join( + "/" + )}/`.replace(/\/\//, "/") + return () => + commitFile(repo, blob, filename, subDir, repoDirCache) + }) + ) const commitZips = import("jszip").then(({default: JSZip}) => { - return includeZips.map( - zipFile => get(zipFile.url).then(response => response.blob()).then(blob => { - const zipfs = new JSZip() - return zipfs.loadAsync(blob).then( - () => { + return includeZips.map(zipFile => + get(zipFile.url) + .then(response => response.blob()) + .then(blob => { + const zipfs = new JSZip() + return zipfs.loadAsync(blob).then(() => { const files = [] zipfs.forEach(file => files.push(file)) - return Promise.all(files.map(filepath => zipfs.files[filepath].async("blob"))).then( - blobs => blobs.map((blob, index) => { + return Promise.all( + files.map(filepath => + zipfs.files[filepath].async("blob") + ) + ).then(blobs => + blobs.map((blob, index) => { const filepath = files[index] const filepathParts = filepath.split("/") const filename = filepathParts.pop() - const dir = zipFile.directory ? [zipFile.directory].concat(filepathParts) : filepathParts - const subDir = `${parentDir}${dir.join("/")}/`.replace(/\/\//, "/") - return () => commitFile( - repo, - blob, - filename, - subDir, - repoDirCache, - csrfToken - ) + const dir = zipFile.directory + ? [zipFile.directory].concat(filepathParts) + : filepathParts + const subDir = `${parentDir}${dir.join( + "/" + )}/`.replace(/\/\//, "/") + return () => + commitFile( + repo, + blob, + filename, + subDir, + repoDirCache, + csrfToken + ) }) ) - } - ) - }) + }) + }) ) }) - return Promise.resolve(commitZips).then( - zips => Promise.all(commitBinaries).then((binaryCommitFunctions) => Promise.all(zips).then( - zipCommitFunctions => textCommitFunctions.concat(binaryCommitFunctions).concat(zipCommitFunctions).flat() - )) - ).then( - commitFunctions => promiseChain(commitFunctions) - ) + return Promise.resolve(commitZips) + .then(zips => + Promise.all(commitBinaries).then(binaryCommitFunctions => + Promise.all(zips).then(zipCommitFunctions => + textCommitFunctions + .concat(binaryCommitFunctions) + .concat(zipCommitFunctions) + .flat() + ) + ) + ) + .then(commitFunctions => promiseChain(commitFunctions)) } diff --git a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/tools/promise_chain.js b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/tools/promise_chain.js index 24f9798..1039ef7 100644 --- a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/tools/promise_chain.js +++ b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/github/tools/promise_chain.js @@ -3,9 +3,10 @@ export function promiseChain(tasks) { return tasks.reduce((promiseChain, currentTask) => { return promiseChain.then(chainResults => - currentTask().then(currentResult => - [...chainResults, currentResult] - ) + currentTask().then(currentResult => [ + ...chainResults, + currentResult + ]) ) }, Promise.resolve([])) } diff --git a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/gitlab/book_exporters.js b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/gitlab/book_exporters.js index 86528ed..6602ac9 100644 --- a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/gitlab/book_exporters.js +++ b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/gitlab/book_exporters.js @@ -1,5 +1,8 @@ import {EpubBookExporter} from "../../books/exporter/epub" -import {HTMLBookExporter, SingleFileHTMLBookExporter} from "../../books/exporter/html" +import { + HTMLBookExporter, + SingleFileHTMLBookExporter +} from "../../books/exporter/html" import {LatexBookExporter} from "../../books/exporter/latex" import {zipToBlobs} from "./tools" @@ -71,11 +74,6 @@ export class LatexBookGitlabExporter extends LatexBookExporter { } createZip() { - return zipToBlobs( - this.textFiles, - this.httpFiles, - [], - "latex/" - ) + return zipToBlobs(this.textFiles, this.httpFiles, [], "latex/") } } diff --git a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/gitlab/book_processor.js b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/gitlab/book_processor.js index af7463d..470e8f6 100644 --- a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/gitlab/book_processor.js +++ b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/gitlab/book_processor.js @@ -1,5 +1,11 @@ import {addAlert, Dialog, escapeText} from "../../common" -import {EpubBookGitlabExporter, UnpackedEpubBookGitlabExporter, HTMLBookGitlabExporter, LatexBookGitlabExporter, SingleFileHTMLBookGitlabExporter} from "./book_exporters" +import { + EpubBookGitlabExporter, + UnpackedEpubBookGitlabExporter, + HTMLBookGitlabExporter, + LatexBookGitlabExporter, + SingleFileHTMLBookGitlabExporter +} from "./book_exporters" import {commitFiles} from "./tools" export class GitlabBookProcessor { @@ -11,13 +17,10 @@ export class GitlabBookProcessor { this.userRepo = userRepo } - init() { - return this.getCommitMessage().then( - commitMessage => this.publishBook(commitMessage) - ).catch( - () => {} - ) + return this.getCommitMessage() + .then(commitMessage => this.publishBook(commitMessage)) + .catch(() => {}) } getCommitMessage() { @@ -27,7 +30,9 @@ export class GitlabBookProcessor { text: gettext("Submit"), classes: "fw-dark", click: () => { - const commitMessage = dialog.dialogEl.querySelector(".commit-message").value || gettext("Update from Fidus Writer") + const commitMessage = + dialog.dialogEl.querySelector(".commit-message") + .value || gettext("Update from Fidus Writer") dialog.close() resolve(commitMessage) } @@ -46,7 +51,9 @@ export class GitlabBookProcessor { height: 150, body: `

${gettext("Updating")}: ${escapeText(this.book.title)} - +

`, buttons }) @@ -70,9 +77,7 @@ export class GitlabBookProcessor { new Date(this.book.updated * 1000), this.userRepo ) - fileGetters.push( - epubExporter.init() - ) + fileGetters.push(epubExporter.init()) } if (this.bookRepo.export_unpacked_epub) { @@ -86,9 +91,7 @@ export class GitlabBookProcessor { new Date(this.book.updated * 1000), this.userRepo ) - fileGetters.push( - unpackedEpubExporter.init() - ) + fileGetters.push(unpackedEpubExporter.init()) } if (this.bookRepo.export_html) { @@ -102,9 +105,7 @@ export class GitlabBookProcessor { new Date(this.book.updated * 1000), this.userRepo ) - fileGetters.push( - htmlExporter.init() - ) + fileGetters.push(htmlExporter.init()) } if (this.bookRepo.export_unified_html) { @@ -118,9 +119,7 @@ export class GitlabBookProcessor { new Date(this.book.updated * 1000), this.userRepo ) - fileGetters.push( - unifiedHtmlExporter.init() - ) + fileGetters.push(unifiedHtmlExporter.init()) } if (this.bookRepo.export_latex) { @@ -132,27 +131,39 @@ export class GitlabBookProcessor { new Date(this.book.updated * 1000), this.userRepo ) - fileGetters.push( - latexExporter.init() - ) + fileGetters.push(latexExporter.init()) } - return Promise.all(fileGetters).then( - files => commitFiles(this.userRepo, commitMessage, Object.assign(...files)) - ).then( - returnCode => { + return Promise.all(fileGetters) + .then(files => + commitFiles( + this.userRepo, + commitMessage, + Object.assign(...files) + ) + ) + .then(returnCode => { switch (returnCode) { case 201: - addAlert("info", gettext("Book published to repository successfully!")) + addAlert( + "info", + gettext( + "Book published to repository successfully!" + ) + ) break case 304: - addAlert("info", gettext("Book already up to date in repository.")) + addAlert( + "info", + gettext("Book already up to date in repository.") + ) break case 400: - addAlert("error", gettext("Could not publish book to repository.")) + addAlert( + "error", + gettext("Could not publish book to repository.") + ) break } - - } - ) + }) } } diff --git a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/gitlab/tools/commit.js b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/gitlab/tools/commit.js index f9d50f4..ad6970c 100644 --- a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/gitlab/tools/commit.js +++ b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/gitlab/tools/commit.js @@ -6,14 +6,15 @@ export function commitFiles(repo, commitMessage, fileBlobs) { ({files}) => { const commitUrl = `/api/gitrepo_export/proxy_gitlab/projects/${repo.id}/repository/commits` const getActions = Object.entries(fileBlobs).map( - ([file_path, blob]) => readBlobPromise(blob).then( - content => { - const fileEntry = Array.isArray(files) ? files.find( - entry => ( - entry.type === "blob" && - entry.path === file_path + ([file_path, blob]) => + readBlobPromise(blob).then(content => { + const fileEntry = Array.isArray(files) + ? files.find( + entry => + entry.type === "blob" && + entry.path === file_path ) - ) : false + : false if (!fileEntry) { return { action: "create", @@ -24,53 +25,45 @@ export function commitFiles(repo, commitMessage, fileBlobs) { } return gitHashObject( // Gitlab converts all line endings of text files to unix file line endings. - blob.type.length ? - atob(content) : - atob(content).replace(/\r\n/g, "\n"), + blob.type.length + ? atob(content) + : atob(content).replace(/\r\n/g, "\n"), // UTF-8 files seem to have no type set. // Not sure if this is actually a viable way to distinguish between utf-8 and binary files. !blob.type.length - ).then( - sha => { - if (sha === fileEntry.id) { - return false - } else { - return { - action: "update", - encoding: "base64", - file_path, - content - } + ).then(sha => { + if (sha === fileEntry.id) { + return false + } else { + return { + action: "update", + encoding: "base64", + file_path, + content } } - ) - - } - ) + }) + }) ) - return Promise.all(getActions).then( - actions => { - actions = actions.filter(action => action) // Remove files that are not to be updated/added. - if (!actions.length) { - return 304 - } - const commitData = { - branch: "main", - commit_message: commitMessage, - actions - } - return fetch(commitUrl, { - method: "POST", - credentials: "include", - headers: { - "X-CSRFToken": getCookie("csrftoken"), - }, - body: JSON.stringify(commitData) - }).then( - () => 201 - ) + return Promise.all(getActions).then(actions => { + actions = actions.filter(action => action) // Remove files that are not to be updated/added. + if (!actions.length) { + return 304 } - ) + const commitData = { + branch: "main", + commit_message: commitMessage, + actions + } + return fetch(commitUrl, { + method: "POST", + credentials: "include", + headers: { + "X-CSRFToken": getCookie("csrftoken") + }, + body: JSON.stringify(commitData) + }).then(() => 201) + }) } ) } diff --git a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/gitlab/tools/zip2blobs.js b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/gitlab/tools/zip2blobs.js index 90b87b3..2095e12 100644 --- a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/gitlab/tools/zip2blobs.js +++ b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/gitlab/tools/zip2blobs.js @@ -1,34 +1,43 @@ import {get} from "../../../common" -export function zipToBlobs(outputList, binaryFiles, includeZips, parentDir = "") { +export function zipToBlobs( + outputList, + binaryFiles, + includeZips, + parentDir = "" +) { const outputFiles = {} outputList.forEach(file => { outputFiles[`${parentDir}${file.filename}`] = new Blob([file.contents]) }) - const commitBinaries = binaryFiles.map(file => get(file.url).then(response => response.blob()).then(blob => { - outputFiles[`${parentDir}${file.filename}`] = blob - })) + const commitBinaries = binaryFiles.map(file => + get(file.url) + .then(response => response.blob()) + .then(blob => { + outputFiles[`${parentDir}${file.filename}`] = blob + }) + ) const commitZips = import("jszip").then(({default: JSZip}) => { - return includeZips.map( - zipFile => get(zipFile.url).then(response => response.blob()).then(blob => { - const zipfs = new JSZip() - return zipfs.loadAsync(blob).then( - () => { + return includeZips.map(zipFile => + get(zipFile.url) + .then(response => response.blob()) + .then(blob => { + const zipfs = new JSZip() + return zipfs.loadAsync(blob).then(() => { const files = [] zipfs.forEach(file => files.push(file)) return Promise.all( - files.map( - filepath => zipfs.files[filepath].async("blob") + files.map(filepath => + zipfs.files[filepath].async("blob") ) - ).then( - blobs => blobs.map((blob, index) => { + ).then(blobs => + blobs.map((blob, index) => { const filepath = files[index] outputFiles[`${parentDir}${filepath}`] = blob }) ) - } - ) - }) + }) + }) ) }) return Promise.all(commitBinaries.concat(commitZips)).then( diff --git a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/templates.js b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/templates.js index 00dea71..cad2aa7 100644 --- a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/templates.js +++ b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/templates.js @@ -12,8 +12,12 @@ function repoName(name, type, userReposMultitype) { return escapeText(name) } - -export const repoSelectorTemplate = ({book, bookRepos, userRepos, userReposMultitype}) => { +export const repoSelectorTemplate = ({ + book, + bookRepos, + userRepos, + userReposMultitype +}) => { const bookRepo = bookRepos[book.id] return ` @@ -24,23 +28,31 @@ export const repoSelectorTemplate = ({book, bookRepos, userRepos, userReposMulti
@@ -57,15 +69,21 @@ export const repoSelectorTemplate = ({book, bookRepos, userRepos, userReposMulti

${gettext("Export EPUB")}

- + -

${gettext("Export unpacked EPUB")}

+

${gettext( + "Export unpacked EPUB" + )}

- + @@ -73,7 +91,9 @@ export const repoSelectorTemplate = ({book, bookRepos, userRepos, userReposMulti

${gettext("Export HTML")}

- + @@ -81,7 +101,9 @@ export const repoSelectorTemplate = ({book, bookRepos, userRepos, userReposMulti

${gettext("Export Unified HTML")}

- + @@ -89,7 +111,9 @@ export const repoSelectorTemplate = ({book, bookRepos, userRepos, userReposMulti

${gettext("Export LaTeX")}

- + ` } diff --git a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/tools.js b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/tools.js index 3b3bd3a..1c13fbd 100644 --- a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/tools.js +++ b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/tools.js @@ -10,20 +10,24 @@ export function gitHashObject(content, utf8 = true) { contentArray[i] = content.charCodeAt(i) } } - const prefixArray = new TextEncoder().encode("blob " + contentArray.byteLength + "\0") // encode as (utf-8) Uint8Array + const prefixArray = new TextEncoder().encode( + "blob " + contentArray.byteLength + "\0" + ) // encode as (utf-8) Uint8Array // Join arrays - const unifiedArray = new Uint8Array(prefixArray.byteLength + contentArray.byteLength) + const unifiedArray = new Uint8Array( + prefixArray.byteLength + contentArray.byteLength + ) unifiedArray.set(new Uint8Array(prefixArray), 0) unifiedArray.set(new Uint8Array(contentArray), prefixArray.byteLength) - return crypto.subtle.digest("SHA-1", unifiedArray).then( - hashBuffer => { - const hashArray = Array.from(new Uint8Array(hashBuffer)) // convert buffer to byte array - const hashHex = hashArray.map(b => b.toString(16).padStart(2, "0")).join("") // convert bytes to hex string - return hashHex - } - ) + return crypto.subtle.digest("SHA-1", unifiedArray).then(hashBuffer => { + const hashArray = Array.from(new Uint8Array(hashBuffer)) // convert buffer to byte array + const hashHex = hashArray + .map(b => b.toString(16).padStart(2, "0")) + .join("") // convert bytes to hex string + return hashHex + }) } export function readBlobPromise(blob) {