diff --git a/fiduswriter/gitrepo_export/helpers/github.py b/fiduswriter/gitrepo_export/helpers/github.py index 0d8915c..759a08d 100644 --- a/fiduswriter/gitrepo_export/helpers/github.py +++ b/fiduswriter/gitrepo_export/helpers/github.py @@ -22,7 +22,7 @@ async def proxy(path, user, query_string, body, method): if not any(regex.match(path) for regex in ALLOWED_PATHS): raise Exception("Path not permitted.") - social_token = SocialToken.objects.get( + social_token = await SocialToken.objects.aget( account__user=user, account__provider="github" ) headers = get_headers(social_token.token) diff --git a/fiduswriter/gitrepo_export/helpers/gitlab.py b/fiduswriter/gitrepo_export/helpers/gitlab.py index 9a866e6..557a275 100644 --- a/fiduswriter/gitrepo_export/helpers/gitlab.py +++ b/fiduswriter/gitrepo_export/helpers/gitlab.py @@ -8,7 +8,7 @@ async def proxy(path, user, query_string, body, method): - social_token = SocialToken.objects.get( + social_token = await SocialToken.objects.aget( account__user=user, account__provider="gitlab" ) headers = get_headers(social_token.token) diff --git a/fiduswriter/gitrepo_export/migrations/0002_bookrepository_export_docx_bookrepository_export_odt.py b/fiduswriter/gitrepo_export/migrations/0002_bookrepository_export_docx_bookrepository_export_odt.py new file mode 100644 index 0000000..2bb21fd --- /dev/null +++ b/fiduswriter/gitrepo_export/migrations/0002_bookrepository_export_docx_bookrepository_export_odt.py @@ -0,0 +1,25 @@ +# Generated by Django 4.2.15 on 2024-09-20 11:13 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("gitrepo_export", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="bookrepository", + name="export_docx", + field=models.BooleanField(default=False), + preserve_default=False, + ), + migrations.AddField( + model_name="bookrepository", + name="export_odt", + field=models.BooleanField(default=False), + preserve_default=False, + ), + ] diff --git a/fiduswriter/gitrepo_export/models.py b/fiduswriter/gitrepo_export/models.py index 7c99c5a..18040c8 100644 --- a/fiduswriter/gitrepo_export/models.py +++ b/fiduswriter/gitrepo_export/models.py @@ -23,6 +23,8 @@ class BookRepository(models.Model): export_html = models.BooleanField() export_unified_html = models.BooleanField() export_latex = models.BooleanField() + export_odt = models.BooleanField() + export_docx = models.BooleanField() class Meta(object): verbose_name_plural = "Book repositories" 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 1a64504..82860df 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 @@ -253,12 +253,20 @@ export class GitrepoExporterBooksOverview { const exportLatex = document.querySelector( "#book-settings-repository-latex" ).checked + const exportDocx = document.querySelector( + "#book-settings-repository-docx" + ).checked + const exportOdt = document.querySelector( + "#book-settings-repository-odt" + ).checked if ( !exportEpub && !exportUnpackedEpub && !exportHtml && !exportUnifiedHtml && - !exportLatex + !exportLatex && + !exportDocx && + !exportOdt ) { // No export formats selected. Reset repository. repoId = 0 @@ -274,7 +282,10 @@ export class GitrepoExporterBooksOverview { this.bookRepos[book.id].export_html !== exportHtml || this.bookRepos[book.id].export_unified_html !== exportUnifiedHtml || - this.bookRepos[book.id].export_latex !== exportLatex)) + this.bookRepos[book.id].export_latex !== exportLatex || + this.bookRepos[book.id].export_odt !== exportOdt || + this.bookRepos[book.id].export_docx !== exportDocx + )) ) { const postData = { book_id: book.id, @@ -289,6 +300,8 @@ export class GitrepoExporterBooksOverview { postData["export_html"] = exportHtml postData["export_unified_html"] = exportUnifiedHtml postData["export_latex"] = exportLatex + postData["export_odt"] = exportOdt + postData["export_docx"] = exportDocx } return post( "/api/gitrepo_export/update_book_repo/", @@ -306,7 +319,9 @@ export class GitrepoExporterBooksOverview { export_unpacked_epub: exportUnpackedEpub, export_html: exportHtml, export_unified_html: exportUnifiedHtml, - export_latex: exportLatex + export_latex: exportLatex, + export_odt: exportOdt, + export_docx: exportDocx } } }) 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 e87a9db..527c9e9 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 @@ -4,6 +4,8 @@ import { SingleFileHTMLBookExporter } from "../../books/exporter/html" import {LatexBookExporter} from "../../books/exporter/latex" +import {ODTBookExporter} from "../../books/exporter/odt" +import {DOCXBookExporter} from "../../books/exporter/docx" import {commitFile, commitZipContents} from "./tools" export class EpubBookGithubExporter extends EpubBookExporter { @@ -91,3 +93,33 @@ export class LatexBookGithubExporter extends LatexBookExporter { ) } } + +export class DOCXBookGithubExporter extends DOCXBookExporter { + constructor(schema, csl, book, user, docList, updated, repo) { + super(schema, csl, book, user, docList, updated) + this.repo = repo + } + + download(blob) { + return () => + commitFile(this.repo, blob, "book.docx").then(response => [ + response + ]) + } + +} + +export class ODTBookGithubExporter extends ODTBookExporter { + constructor(schema, csl, book, user, docList, updated, repo) { + super(schema, csl, book, user, docList, updated) + this.repo = repo + } + + download(blob) { + return () => + commitFile(this.repo, blob, "book.odt").then(response => [ + response + ]) + } + +} 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 70fff1a..f695263 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 @@ -4,7 +4,9 @@ import { UnpackedEpubBookGithubExporter, HTMLBookGithubExporter, LatexBookGithubExporter, - SingleFileHTMLBookGithubExporter + SingleFileHTMLBookGithubExporter, + DOCXBookGithubExporter, + ODTBookGithubExporter } from "./book_exporters" import {promiseChain, commitTree} from "./tools" @@ -133,6 +135,32 @@ export class GithubBookProcessor { ) commitInitiators.push(latexExporter.init()) } + + if (this.bookRepo.export_docx) { + const docxExporter = new DOCXBookGithubExporter( + this.booksOverview.schema, + this.booksOverview.app.csl, + this.book, + this.booksOverview.user, + this.booksOverview.documentList, + new Date(this.book.updated * 1000), + this.userRepo + ) + commitInitiators.push(docxExporter.init()) + } + + if (this.bookRepo.export_odt) { + const odtExporter = new ODTBookGithubExporter( + this.booksOverview.schema, + this.booksOverview.app.csl, + this.book, + this.booksOverview.user, + this.booksOverview.documentList, + new Date(this.book.updated * 1000), + this.userRepo + ) + commitInitiators.push(odtExporter.init()) + } return Promise.all(commitInitiators).then(commitFunctions => promiseChain(commitFunctions.flat()).then(responses => { const responseCodes = responses.flat() 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 6602ac9..5be46af 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 @@ -3,6 +3,8 @@ import { HTMLBookExporter, SingleFileHTMLBookExporter } from "../../books/exporter/html" +import {ODTBookExporter} from "../../books/exporter/odt" +import {DOCXBookExporter} from "../../books/exporter/docx" import {LatexBookExporter} from "../../books/exporter/latex" import {zipToBlobs} from "./tools" @@ -77,3 +79,31 @@ export class LatexBookGitlabExporter extends LatexBookExporter { return zipToBlobs(this.textFiles, this.httpFiles, [], "latex/") } } + +export class DOCXBookGitlabExporter extends DOCXBookExporter { + constructor(schema, csl, book, user, docList, updated, repo) { + super(schema, csl, book, user, docList, updated) + this.repo = repo + } + + download(blob) { + return Promise.resolve({ + "book.docx": blob + }) + } + +} + +export class ODTBookGitlabExporter extends ODTBookExporter { + constructor(schema, csl, book, user, docList, updated, repo) { + super(schema, csl, book, user, docList, updated) + this.repo = repo + } + + download(blob) { + return Promise.resolve({ + "book.odt": blob + }) + } + +} 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 470e8f6..12cbf98 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 @@ -4,7 +4,9 @@ import { UnpackedEpubBookGitlabExporter, HTMLBookGitlabExporter, LatexBookGitlabExporter, - SingleFileHTMLBookGitlabExporter + SingleFileHTMLBookGitlabExporter, + DOCXBookGitlabExporter, + ODTBookGitlabExporter } from "./book_exporters" import {commitFiles} from "./tools" @@ -133,6 +135,31 @@ export class GitlabBookProcessor { ) fileGetters.push(latexExporter.init()) } + if (this.bookRepo.export_docx) { + const docxExporter = new DOCXBookGitlabExporter( + this.booksOverview.schema, + this.booksOverview.app.csl, + this.book, + this.booksOverview.user, + this.booksOverview.documentList, + new Date(this.book.updated * 1000), + this.userRepo + ) + fileGetters.push(docxExporter.init()) + } + + if (this.bookRepo.export_odt) { + const odtExporter = new ODTBookGitlabExporter( + this.booksOverview.schema, + this.booksOverview.app.csl, + this.book, + this.booksOverview.user, + this.booksOverview.documentList, + new Date(this.book.updated * 1000), + this.userRepo + ) + fileGetters.push(odtExporter.init()) + } return Promise.all(fileGetters) .then(files => commitFiles( 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 cad2aa7..b8df033 100644 --- a/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/templates.js +++ b/fiduswriter/gitrepo_export/static/js/modules/gitrepo_export/templates.js @@ -113,6 +113,30 @@ export const repoSelectorTemplate = ({ + + + + +

${gettext("Export ODT")}

+ + + + + + + +

${gettext("Export DOCX")}

+ + + ` diff --git a/fiduswriter/gitrepo_export/views.py b/fiduswriter/gitrepo_export/views.py index 4996063..5b72ee4 100644 --- a/fiduswriter/gitrepo_export/views.py +++ b/fiduswriter/gitrepo_export/views.py @@ -76,6 +76,8 @@ def update_book_repo(request): export_html=request.POST["export_html"] == "true", export_unified_html=request.POST["export_unified_html"] == "true", export_latex=request.POST["export_latex"] == "true", + export_docx=request.POST["export_docx"] == "true", + export_odt=request.POST["export_odt"] == "true", ) status = 201 return HttpResponse(status=status) @@ -87,20 +89,20 @@ def update_book_repo(request): @async_to_sync async def get_git_repos(request, reload=False): social_tokens = { - "github": SocialToken.objects.filter( + "github": await SocialToken.objects.filter( account__user=request.user, account__provider="github" - ).first(), - "gitlab": SocialToken.objects.filter( + ).afirst(), + "gitlab": await SocialToken.objects.filter( account__user=request.user, account__provider="gitlab" - ).first(), + ).afirst(), } if not social_tokens["github"] and not social_tokens["gitlab"]: return HttpResponseForbidden() - repo_info = models.RepoInfo.objects.filter(user=request.user).first() + repo_info = await models.RepoInfo.objects.filter(user=request.user).afirst() if repo_info: if reload: - repo_info.delete() + await repo_info.adelete() else: return JsonResponse({"repos": repo_info.content}, status=200) repos = [] @@ -119,11 +121,11 @@ async def get_git_repos(request, reload=False): return [] except Exception as e: return HttpResponse("Error: %s" % e, status=500) - repo_info, created = models.RepoInfo.objects.get_or_create( + repo_info, created = await models.RepoInfo.objects.aget_or_create( user=request.user ) repo_info.content = repos - repo_info.save() + await repo_info.asave() return JsonResponse({"repos": repos}, status=200)