From 812098ace455ba1da10065b2640bfdea5c2ac9eb Mon Sep 17 00:00:00 2001 From: Grzegorz Godlewski Date: Tue, 17 Oct 2023 19:53:27 +0200 Subject: [PATCH] Update documentation --- .github/workflows/DevelopServerDeploy.yml | 9 +- .gitignore | 3 + Dockerfile | 2 +- README.md | 2 +- apps/ui/assets/layout.css | 1 - apps/ui/assets/main.css | 1 - apps/ui/index.html | 28 --- apps/ui/src/components/NavBar.vue | 17 +- apps/ui/src/components/StaticContent.vue | 2 +- apps/ui/src/components/UtilsMixin.ts | 5 +- apps/ui/src/main.ts | 12 +- apps/ui/src/pages/MainView.vue | 8 + apps/ui/src/pages/StaticView.vue | 109 ++++++++++ config.toml | 4 - hugo/config/_default/config.toml | 14 ++ hugo/config/_default/params.toml | 32 +++ hugo/go.mod | 3 + .../layouts/404.html => hugo/go.sum | 0 hugo/package.json | 6 + hugo/static/images/logo.svg | 33 +++ hugo/themes/wgd-bootstrap/layouts/404.html | 3 + .../_markup/render-codeblock-mermaid.html | 0 .../_default/_markup/render-heading.html | 0 .../layouts/_default/_markup/render-link.html | 0 .../layouts/_default/baseof.html | 13 +- .../wgd-bootstrap/layouts/_default/list.html | 27 +++ .../layouts/_default/single.html | 27 +++ .../layouts/_default}/site-scripts.html | 0 .../wgd-bootstrap/layouts/docs/list.html | 27 +++ .../wgd-bootstrap/layouts/docs/single.html | 27 +++ hugo/themes/wgd-bootstrap/layouts/index.html | 202 ++++++++++++++++++ .../layouts/landing}/content.html | 0 .../layouts/partials/content.html | 1 + .../wgd-bootstrap/layouts/partials/debug.html | 15 ++ .../layouts/partials/docs/sidebar.html | 7 + .../layouts/partials/docs/toc.html | 1 + .../layouts/partials/docs/tree.html | 20 ++ .../themes}/wgd-bootstrap/theme.toml | 0 src/cli/usage.ts | 5 +- src/cli/wikigdrive-server.ts | 6 +- src/cli/wikigdrivectl-inspect.ts | 2 +- src/cli/wikigdrivectl-ps.ts | 2 +- src/containers/server/ServerContainer.ts | 16 +- src/containers/server/auth.ts | 16 +- src/model/CliParams.ts | 4 +- src/utils/idParsers.ts | 4 + src/wikigdrive.sh | 2 +- src/wikigdrivectl.sh | 4 +- .../layouts/_default/single.html | 3 - themes/wgd-bootstrap/layouts/index.html | 28 --- {doc => website}/_index.md | 43 +--- website/docs/_index.md | 171 +++++++++++++++ {doc => website/docs}/developer.md | 8 +- {doc => website/docs}/diagram.svg | 0 website/docs/faq.md | 35 +++ website/docs/install.md | 24 +++ {doc => website/docs}/internals.md | 5 + website/docs/usage/_index.md | 12 ++ .../docs/usage}/wikigdrive_usage.md | 60 +++++- website/docs/usage/wikigdrivectl_usage.md | 31 +++ 60 files changed, 993 insertions(+), 149 deletions(-) delete mode 100644 apps/ui/index.html create mode 100644 apps/ui/src/pages/StaticView.vue delete mode 100644 config.toml create mode 100644 hugo/config/_default/config.toml create mode 100644 hugo/config/_default/params.toml create mode 100644 hugo/go.mod rename themes/wgd-bootstrap/layouts/404.html => hugo/go.sum (100%) create mode 100644 hugo/package.json create mode 100644 hugo/static/images/logo.svg create mode 100644 hugo/themes/wgd-bootstrap/layouts/404.html rename {themes => hugo/themes}/wgd-bootstrap/layouts/_default/_markup/render-codeblock-mermaid.html (100%) rename {themes => hugo/themes}/wgd-bootstrap/layouts/_default/_markup/render-heading.html (100%) rename {themes => hugo/themes}/wgd-bootstrap/layouts/_default/_markup/render-link.html (100%) rename {themes => hugo/themes}/wgd-bootstrap/layouts/_default/baseof.html (81%) create mode 100644 hugo/themes/wgd-bootstrap/layouts/_default/list.html create mode 100644 hugo/themes/wgd-bootstrap/layouts/_default/single.html rename {themes/wgd-bootstrap/layouts/partials => hugo/themes/wgd-bootstrap/layouts/_default}/site-scripts.html (100%) create mode 100644 hugo/themes/wgd-bootstrap/layouts/docs/list.html create mode 100644 hugo/themes/wgd-bootstrap/layouts/docs/single.html create mode 100644 hugo/themes/wgd-bootstrap/layouts/index.html rename {themes/wgd-bootstrap/layouts/partials => hugo/themes/wgd-bootstrap/layouts/landing}/content.html (100%) create mode 100644 hugo/themes/wgd-bootstrap/layouts/partials/content.html create mode 100644 hugo/themes/wgd-bootstrap/layouts/partials/debug.html create mode 100644 hugo/themes/wgd-bootstrap/layouts/partials/docs/sidebar.html create mode 100644 hugo/themes/wgd-bootstrap/layouts/partials/docs/toc.html create mode 100644 hugo/themes/wgd-bootstrap/layouts/partials/docs/tree.html rename {themes => hugo/themes}/wgd-bootstrap/theme.toml (100%) delete mode 100644 themes/wgd-bootstrap/layouts/_default/single.html delete mode 100644 themes/wgd-bootstrap/layouts/index.html rename {doc => website}/_index.md (71%) create mode 100644 website/docs/_index.md rename {doc => website/docs}/developer.md (97%) rename {doc => website/docs}/diagram.svg (100%) create mode 100644 website/docs/faq.md create mode 100644 website/docs/install.md rename {doc => website/docs}/internals.md (99%) create mode 100644 website/docs/usage/_index.md rename {doc => website/docs/usage}/wikigdrive_usage.md (50%) create mode 100644 website/docs/usage/wikigdrivectl_usage.md diff --git a/.github/workflows/DevelopServerDeploy.yml b/.github/workflows/DevelopServerDeploy.yml index c1695602..24bebdf8 100644 --- a/.github/workflows/DevelopServerDeploy.yml +++ b/.github/workflows/DevelopServerDeploy.yml @@ -58,11 +58,10 @@ jobs: - name: Build hugo docs run: | docker run \ - -v "${GITHUB_WORKSPACE}/doc:/site/doc" \ - -v "${GITHUB_WORKSPACE}/themes:/site/themes" \ - -v "${GITHUB_WORKSPACE}/config.toml:/site/config.toml" \ - -v "/var/www/dev.wikigdrive.com:/site/dist/hugo" \ - --env CONFIG_TOML="/site/config.toml" --env BASE_URL="https://dev.wikigdrive.com" \ + -v "${GITHUB_WORKSPACE}/hugo:/site" \ + -v "${GITHUB_WORKSPACE}/website:/site/content" \ + -v "/var/www/dev.wikigdrive.com:/dist/hugo" \ + --env CONFIG_TOML="/site/config/_default/config.toml" --env BASE_URL="https://dev.wikigdrive.com" \ wgd-action-runner:develop /steps/step_render_hugo - name: Start diff --git a/.gitignore b/.gitignore index 6b3d3620..4311cca3 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ node_modules dist content .hugo* +hugo/resources +hugo_stats.json + diff --git a/Dockerfile b/Dockerfile index 58d14957..96d4cc52 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ RUN npm link --location=user EXPOSE 3000 VOLUME /data -RUN cd /usr/src/app/apps/ui && npm install && npm run build +RUN cd /usr/src/app/apps/ui && cp ../../hugo/themes/wgd-bootstrap/layouts/_default/baseof.html index.html && npm install && npm run build WORKDIR "/usr/src/app" diff --git a/README.md b/README.md index 343ded60..1e3e3bb7 120000 --- a/README.md +++ b/README.md @@ -1 +1 @@ -doc/_index.md \ No newline at end of file +website/docs/_index.md \ No newline at end of file diff --git a/apps/ui/assets/layout.css b/apps/ui/assets/layout.css index 1ce6103d..c899955e 100644 --- a/apps/ui/assets/layout.css +++ b/apps/ui/assets/layout.css @@ -43,7 +43,6 @@ body, .mainbar__content { flex: 1 1 auto; text-overflow: ellipsis; - white-space: nowrap; height: calc(100vh - var(--navbar-height)); overflow: auto; } diff --git a/apps/ui/assets/main.css b/apps/ui/assets/main.css index e74a23c5..24fbea43 100644 --- a/apps/ui/assets/main.css +++ b/apps/ui/assets/main.css @@ -8,7 +8,6 @@ nav { justify-content: space-between; display: flex; align-items: center; - background-color: #2196F3; color: #FFF; } diff --git a/apps/ui/index.html b/apps/ui/index.html deleted file mode 100644 index 077e9324..00000000 --- a/apps/ui/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - wikigdrive - - - - - - - - - - - - - - - - - - -
- - - diff --git a/apps/ui/src/components/NavBar.vue b/apps/ui/src/components/NavBar.vue index 5ced8e88..28d064bb 100644 --- a/apps/ui/src/components/NavBar.vue +++ b/apps/ui/src/components/NavBar.vue @@ -11,7 +11,22 @@ WikiGDrive - + + + + diff --git a/config.toml b/config.toml deleted file mode 100644 index 285c5346..00000000 --- a/config.toml +++ /dev/null @@ -1,4 +0,0 @@ -theme="wgd-bootstrap" -contentDir="doc" -publishDir="dist/hugo" -uglyURLs="true" diff --git a/hugo/config/_default/config.toml b/hugo/config/_default/config.toml new file mode 100644 index 00000000..b6f087c1 --- /dev/null +++ b/hugo/config/_default/config.toml @@ -0,0 +1,14 @@ +title = "WikiGDrive" +theme="wgd-bootstrap" +contentDir="../website" +publishDir="../dist/hugo" +#uglyURLs="true" +uglyURLs = false + +[build] +writeStats = true + +[module] +[[module.mounts]] + source = './themes/wgd-bootstrap/layouts/_default/_markup' + target = 'layouts/_default/_markup' diff --git a/hugo/config/_default/params.toml b/hugo/config/_default/params.toml new file mode 100644 index 00000000..5ebd2442 --- /dev/null +++ b/hugo/config/_default/params.toml @@ -0,0 +1,32 @@ +#customCSS = null # To use: uncomment and replace null with value +#customJS = null # To use: uncomment and replace null with value +dateFormat = ":date_long" +description = "Google Drive to MarkDown synchronization" +keywords = "GDrive, CLI, MarkDown, Google Docs, Wiki" +math = true +titleCase = true +viewer = true + +[actionsPanel] +disabled = true + +[post] +featuredImage = true +numberifyHeadings = true +numberifyHeadingsSeparator = "." + +[sidebar] +archives = false +authors = false +fixed = true +recentPosts = false +taxonomiesToggle = false + +[siteVerification] +#baidu = null # To use: uncomment and replace null with value +#baiduUnion = null # To use: uncomment and replace null with value +#bing = null # To use: uncomment and replace null with value +#google = null # To use: uncomment and replace null with value +#shenma = null # To use: uncomment and replace null with value +#so = null # To use: uncomment and replace null with value +#sogou = null # To use: uncomment and replace null with value diff --git a/hugo/go.mod b/hugo/go.mod new file mode 100644 index 00000000..f08af376 --- /dev/null +++ b/hugo/go.mod @@ -0,0 +1,3 @@ +module github.com/mieweb/wikiGDrive + +go 1.21.1 diff --git a/themes/wgd-bootstrap/layouts/404.html b/hugo/go.sum similarity index 100% rename from themes/wgd-bootstrap/layouts/404.html rename to hugo/go.sum diff --git a/hugo/package.json b/hugo/package.json new file mode 100644 index 00000000..8e2f91a4 --- /dev/null +++ b/hugo/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": {}, + "devDependencies": {}, + "name": "wikiGDrive", + "version": "0.1.0" +} diff --git a/hugo/static/images/logo.svg b/hugo/static/images/logo.svg new file mode 100644 index 00000000..841290c8 --- /dev/null +++ b/hugo/static/images/logo.svg @@ -0,0 +1,33 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/hugo/themes/wgd-bootstrap/layouts/404.html b/hugo/themes/wgd-bootstrap/layouts/404.html new file mode 100644 index 00000000..f1e459d0 --- /dev/null +++ b/hugo/themes/wgd-bootstrap/layouts/404.html @@ -0,0 +1,3 @@ +{{- define "main" }} +Not found +{{- end -}} diff --git a/themes/wgd-bootstrap/layouts/_default/_markup/render-codeblock-mermaid.html b/hugo/themes/wgd-bootstrap/layouts/_default/_markup/render-codeblock-mermaid.html similarity index 100% rename from themes/wgd-bootstrap/layouts/_default/_markup/render-codeblock-mermaid.html rename to hugo/themes/wgd-bootstrap/layouts/_default/_markup/render-codeblock-mermaid.html diff --git a/themes/wgd-bootstrap/layouts/_default/_markup/render-heading.html b/hugo/themes/wgd-bootstrap/layouts/_default/_markup/render-heading.html similarity index 100% rename from themes/wgd-bootstrap/layouts/_default/_markup/render-heading.html rename to hugo/themes/wgd-bootstrap/layouts/_default/_markup/render-heading.html diff --git a/themes/wgd-bootstrap/layouts/_default/_markup/render-link.html b/hugo/themes/wgd-bootstrap/layouts/_default/_markup/render-link.html similarity index 100% rename from themes/wgd-bootstrap/layouts/_default/_markup/render-link.html rename to hugo/themes/wgd-bootstrap/layouts/_default/_markup/render-link.html diff --git a/themes/wgd-bootstrap/layouts/_default/baseof.html b/hugo/themes/wgd-bootstrap/layouts/_default/baseof.html similarity index 81% rename from themes/wgd-bootstrap/layouts/_default/baseof.html rename to hugo/themes/wgd-bootstrap/layouts/_default/baseof.html index 7b84a914..0cfc5df8 100644 --- a/themes/wgd-bootstrap/layouts/_default/baseof.html +++ b/hugo/themes/wgd-bootstrap/layouts/_default/baseof.html @@ -3,11 +3,11 @@ - wikigdrive + {{ .Site.Params.title }} - + @@ -22,7 +22,14 @@ -
{{- block "main" . }}{{- end }}
+
+{{- block "layout" . }} +{{- block "sidebar" . }}{{- end }} +{{- block "main" . }}{{- end }} +{{- block "footer" . }}{{- end }} +{{- end }} +
+{{- partial "debug.html" . -}} diff --git a/hugo/themes/wgd-bootstrap/layouts/_default/list.html b/hugo/themes/wgd-bootstrap/layouts/_default/list.html new file mode 100644 index 00000000..ca3f20aa --- /dev/null +++ b/hugo/themes/wgd-bootstrap/layouts/_default/list.html @@ -0,0 +1,27 @@ +{{ define "layout" }} +
+
+ {{- block "sidebar" . }}{{- end }} +
+
+ {{- block "main" . }}{{- end }} +
+ {{ if gt (.TableOfContents | len) 32 }} +
+ +
+ {{ end }} +
+{{- block "footer" . }}{{- end }} +{{ end }} + +{{ define "sidebar" }} +{{- partial "docs/sidebar" . -}} +{{ end }} + +{{ define "main" }} +{{ .Content }} +{{ end }} diff --git a/hugo/themes/wgd-bootstrap/layouts/_default/single.html b/hugo/themes/wgd-bootstrap/layouts/_default/single.html new file mode 100644 index 00000000..ebb7b99f --- /dev/null +++ b/hugo/themes/wgd-bootstrap/layouts/_default/single.html @@ -0,0 +1,27 @@ +{{ define "layout" }} +
+
+ {{- block "sidebar" . }}{{- end }} +
+
+ {{- block "main" . }}{{- end }} +
+
+ {{ if gt (.TableOfContents | len) 32 }} + + {{ end }} +
+
+{{- block "footer" . }}{{- end }} +{{ end }} + +{{ define "sidebar" }} +{{- partial "docs/sidebar" . -}} +{{ end }} + +{{ define "main" }} +{{ .Content }} +{{ end }} diff --git a/themes/wgd-bootstrap/layouts/partials/site-scripts.html b/hugo/themes/wgd-bootstrap/layouts/_default/site-scripts.html similarity index 100% rename from themes/wgd-bootstrap/layouts/partials/site-scripts.html rename to hugo/themes/wgd-bootstrap/layouts/_default/site-scripts.html diff --git a/hugo/themes/wgd-bootstrap/layouts/docs/list.html b/hugo/themes/wgd-bootstrap/layouts/docs/list.html new file mode 100644 index 00000000..ca3f20aa --- /dev/null +++ b/hugo/themes/wgd-bootstrap/layouts/docs/list.html @@ -0,0 +1,27 @@ +{{ define "layout" }} +
+
+ {{- block "sidebar" . }}{{- end }} +
+
+ {{- block "main" . }}{{- end }} +
+ {{ if gt (.TableOfContents | len) 32 }} +
+ +
+ {{ end }} +
+{{- block "footer" . }}{{- end }} +{{ end }} + +{{ define "sidebar" }} +{{- partial "docs/sidebar" . -}} +{{ end }} + +{{ define "main" }} +{{ .Content }} +{{ end }} diff --git a/hugo/themes/wgd-bootstrap/layouts/docs/single.html b/hugo/themes/wgd-bootstrap/layouts/docs/single.html new file mode 100644 index 00000000..ebb7b99f --- /dev/null +++ b/hugo/themes/wgd-bootstrap/layouts/docs/single.html @@ -0,0 +1,27 @@ +{{ define "layout" }} +
+
+ {{- block "sidebar" . }}{{- end }} +
+
+ {{- block "main" . }}{{- end }} +
+
+ {{ if gt (.TableOfContents | len) 32 }} + + {{ end }} +
+
+{{- block "footer" . }}{{- end }} +{{ end }} + +{{ define "sidebar" }} +{{- partial "docs/sidebar" . -}} +{{ end }} + +{{ define "main" }} +{{ .Content }} +{{ end }} diff --git a/hugo/themes/wgd-bootstrap/layouts/index.html b/hugo/themes/wgd-bootstrap/layouts/index.html new file mode 100644 index 00000000..c4b65921 --- /dev/null +++ b/hugo/themes/wgd-bootstrap/layouts/index.html @@ -0,0 +1,202 @@ +{{ define "main" }} +
+
+ Work in Progress Logo +
+

Google Drive to MarkDown synchronization

+
+ Transform Google Docs and Drawings into markdown, collaborate and create websites. +
+ +
+ +
+
+
+ +
+
+

Sync

+

Bidirectional Google Docs to markdown sync.

+
+
+ +
+
+ +
+
+

Open source

+

Both SAS and Self-hosted.

+
+
+ +
+
+ +
+
+

Diagrams

+

Convert Google Docs Drawings into SVG diagrams.

+
+
+ +
+
+ +
+
+

Docs widget

+

Additional docs sidebar and drive menu.

+
+
+ +
+
+ +
+

Search

+

Local search supported.

+
+ +
+
+ +
+
+

Hugo Pipes

+

Build site with the powerful Hugo pipes.

+
+
+ +
+
+ +
+
+

SASS/SCSS

+

Custom theme and Bootstrap via SASS/SCSS variables.

+
+
+ +
+
+ +
+
+

Git

+

Versioning with Git.

+
+
+ +
+
+ +
+
+

GitHub

+

Push to github, create feature branches.

+
+
+ +
+
+ +
+
+

Markdown

+

Markdown preview.

+
+
+ +
+
+ +
+
+

Light/Dark Mode

+

Allow switching to light, dark or auto mode.

+
+
+ +
+
+ +
+
+

Workflows

+

Trigger actions on Google Docs change.

+
+
+ +
+
+
+{{ end }} + +{{ define "footer" }} + + +{{ end }} diff --git a/themes/wgd-bootstrap/layouts/partials/content.html b/hugo/themes/wgd-bootstrap/layouts/landing/content.html similarity index 100% rename from themes/wgd-bootstrap/layouts/partials/content.html rename to hugo/themes/wgd-bootstrap/layouts/landing/content.html diff --git a/hugo/themes/wgd-bootstrap/layouts/partials/content.html b/hugo/themes/wgd-bootstrap/layouts/partials/content.html new file mode 100644 index 00000000..68a09ae6 --- /dev/null +++ b/hugo/themes/wgd-bootstrap/layouts/partials/content.html @@ -0,0 +1 @@ +{{ .Content }} diff --git a/hugo/themes/wgd-bootstrap/layouts/partials/debug.html b/hugo/themes/wgd-bootstrap/layouts/partials/debug.html new file mode 100644 index 00000000..7af2026e --- /dev/null +++ b/hugo/themes/wgd-bootstrap/layouts/partials/debug.html @@ -0,0 +1,15 @@ + diff --git a/hugo/themes/wgd-bootstrap/layouts/partials/docs/sidebar.html b/hugo/themes/wgd-bootstrap/layouts/partials/docs/sidebar.html new file mode 100644 index 00000000..22489f5f --- /dev/null +++ b/hugo/themes/wgd-bootstrap/layouts/partials/docs/sidebar.html @@ -0,0 +1,7 @@ +{{ $path := printf "docs/" }} +{{ $currentLink := .Permalink }} + diff --git a/hugo/themes/wgd-bootstrap/layouts/partials/docs/toc.html b/hugo/themes/wgd-bootstrap/layouts/partials/docs/toc.html new file mode 100644 index 00000000..2eac70be --- /dev/null +++ b/hugo/themes/wgd-bootstrap/layouts/partials/docs/toc.html @@ -0,0 +1 @@ +DOC TOC diff --git a/hugo/themes/wgd-bootstrap/layouts/partials/docs/tree.html b/hugo/themes/wgd-bootstrap/layouts/partials/docs/tree.html new file mode 100644 index 00000000..6abd4fe2 --- /dev/null +++ b/hugo/themes/wgd-bootstrap/layouts/partials/docs/tree.html @@ -0,0 +1,20 @@ +{{ $currentLink := .currentLink}} +{{ if gt (len .ctx.Pages) 0 }} + +{{ end }} diff --git a/themes/wgd-bootstrap/theme.toml b/hugo/themes/wgd-bootstrap/theme.toml similarity index 100% rename from themes/wgd-bootstrap/theme.toml rename to hugo/themes/wgd-bootstrap/theme.toml diff --git a/src/cli/usage.ts b/src/cli/usage.ts index ce8490cb..bad6a77b 100644 --- a/src/cli/usage.ts +++ b/src/cli/usage.ts @@ -40,11 +40,12 @@ export async function usage(filename: string) { const mdFilename = execName + '_usage.md'; - const usageMarkdown = new TextDecoder().decode(fs.readFileSync(path.resolve(__dirname, '..', '..', 'doc', mdFilename))); + const usageMarkdown = new TextDecoder().decode(fs.readFileSync(path.resolve(__dirname, '..', '..', 'website', 'docs', 'usage', mdFilename))); const commandUsage = locateUsage(usageMarkdown, `${execName} ${sectionName}`) || locateUsage(usageMarkdown, `${execName} usage`); const allCommands = locateUsage(usageMarkdown, 'All commands'); + const commonOptions = locateUsage(usageMarkdown, 'Common options'); console.log( - `${pkg.name} version: ${pkg.version}, ${process.env.GIT_SHA}\n\nUsage:\n${commandUsage.trim()}\n\n${allCommands.trim()}`); + `${pkg.name} version: ${pkg.version}, ${process.env.GIT_SHA}\n\nUsage:\n${commandUsage.trim()}\n\n${commonOptions.trim()}\n\n${allCommands.trim()}`); } diff --git a/src/cli/wikigdrive-server.ts b/src/cli/wikigdrive-server.ts index 6fb17354..daa5e2f4 100644 --- a/src/cli/wikigdrive-server.ts +++ b/src/cli/wikigdrive-server.ts @@ -153,19 +153,19 @@ async function main() { const params: CliParams = { args: argv._.slice(1), - drive: argv['drive'], + // drive: argv['drive'], workdir: argv['workdir'] || process.env.WIKIGDRIVE_WORKDIR || '/data', client_id: argv['client_id'] || process.env.CLIENT_ID, client_secret: argv['client_secret'] || process.env.CLIENT_SECRET, - link_mode: argv['link_mode'] || 'mdURLs', + // link_mode: argv['link_mode'] || 'mdURLs', debug: (argv['debug'] || '').split(',').map(str => str.toLocaleString().trim()), service_account: argv['service_account'] || null, share_email: argv['share_email'] || process.env.SHARE_EMAIL || null, - server_port: +argv['server'] + server_port: +argv['server_port'] }; const mainService = new MainService(params); diff --git a/src/cli/wikigdrivectl-inspect.ts b/src/cli/wikigdrivectl-inspect.ts index cd473444..cef03643 100644 --- a/src/cli/wikigdrivectl-inspect.ts +++ b/src/cli/wikigdrivectl-inspect.ts @@ -40,7 +40,7 @@ if (!instance) { process.exit(1); } -const response = await fetch(`http://localhost:${instance.port}/api/drive/${folderId}/inspect`); +const response = await fetch(`http://localhost:${instance.port}/api/inspect/${folderId}`); const json = await response.json(); console.log(json); diff --git a/src/cli/wikigdrivectl-ps.ts b/src/cli/wikigdrivectl-ps.ts index 44b899bf..da1c1cc6 100644 --- a/src/cli/wikigdrivectl-ps.ts +++ b/src/cli/wikigdrivectl-ps.ts @@ -15,7 +15,7 @@ process.env.GIT_SHA = process.env.GIT_SHA || 'dev'; dotenv.config(); const argv = minimist(process.argv.slice(2)); -if (argv._.length < 1 || argv.h || argv.help) { +if (argv.h || argv.help) { await usage(__filename); process.exit(0); } diff --git a/src/containers/server/ServerContainer.ts b/src/containers/server/ServerContainer.ts index 921a0def..b1c32508 100644 --- a/src/containers/server/ServerContainer.ts +++ b/src/containers/server/ServerContainer.ts @@ -124,9 +124,11 @@ export class ServerContainer extends Container { } private async handleStaticHtml(reqPath: string, url: string) { + const hugoPath = path.resolve(MAIN_DIR, 'dist', 'hugo', (reqPath.substring(1) || 'index.html')); + const distPath = path.resolve(HTML_DIR, 'dist'); + const baseHtmlPath = path.resolve(MAIN_DIR, 'hugo', 'themes', 'wgd-bootstrap', 'layouts', '_default', 'baseof.html'); + if (reqPath.startsWith('/drive') || reqPath.startsWith('/gdocs') || reqPath.startsWith('/auth') || reqPath === '/' || reqPath.startsWith('/share-drive') || reqPath.endsWith('.html')) { - const hugoPath = path.resolve(MAIN_DIR, 'dist', 'hugo', (reqPath.substring(1) || 'index.html')); - const distPath = path.resolve(HTML_DIR, 'dist'); if (fs.existsSync(hugoPath)) { const template = fs.readFileSync(hugoPath) @@ -142,7 +144,7 @@ export class ServerContainer extends Container { .replace(/GIT_SHA/g, process.env.GIT_SHA); return template; } else { - const template = fs.readFileSync(HTML_DIR + '/index.html') + const template = fs.readFileSync(baseHtmlPath) .toString() .replace('', process.env.ZIPKIN_URL ? `\n` : '') .replace(/GIT_SHA/g, process.env.GIT_SHA); @@ -196,12 +198,13 @@ export class ServerContainer extends Container { next(); }); - await this.initRouter(app); - await this.initAuth(app); - const distPath = path.resolve(HTML_DIR, 'dist'); app.use(express.static(distPath)); app.use(express.static(path.resolve(MAIN_DIR, 'dist', 'hugo'))); + + await this.initRouter(app); + await this.initAuth(app); + await this.initUiServer(app); app.use(async (req: express.Request, res: express.Response) => { @@ -563,7 +566,6 @@ export class ServerContainer extends Container { const folderRegistryContainer = this.engine.getContainer('folder_registry'); const folders = await folderRegistryContainer.getFolders(); inspected['folder'] = folders[driveId]; - res.json(inspected); } catch (err) { next(err); diff --git a/src/containers/server/auth.ts b/src/containers/server/auth.ts index 5de5fefc..9c03b87a 100644 --- a/src/containers/server/auth.ts +++ b/src/containers/server/auth.ts @@ -232,7 +232,7 @@ export async function getAuth(req, res: Response, next) { driveId: driveId }); setAccessCookie(res, accessToken); - res.redirect(redirectTo || '/'); + res.redirect(redirectTo || '/drive'); return; } @@ -331,8 +331,20 @@ export function authenticateOptionally(logger: Logger, idx = 0) { }; } +function isLocal(req: Request) { + const ip = req.socket.remoteAddress; + const host = req.get('host'); + return ip === '127.0.0.1' || ip === '::ffff:127.0.0.1' || ip === '::1' || host.indexOf('localhost') !== -1; +} + export function authenticate(logger: Logger, idx = 0) { - return async (req, res, next) => { + return async (req: Request, res, next) => { + + if (isLocal(req)) { + next(); + return ; + } + req['driveId'] = ''; req['logger'] = logger; const parts = req.path.split('/'); diff --git a/src/model/CliParams.ts b/src/model/CliParams.ts index 76d1b74a..bc86269f 100644 --- a/src/model/CliParams.ts +++ b/src/model/CliParams.ts @@ -1,9 +1,9 @@ import {LinkMode} from './model'; export interface CliParams { - link_mode: LinkMode; + // link_mode: LinkMode; // TODO: remove ??? workdir: string; - drive: string; + // drive: string; // TODO: remove ??? args: string[]; debug: string[]; diff --git a/src/utils/idParsers.ts b/src/utils/idParsers.ts index 0e669ee1..c060dd5f 100644 --- a/src/utils/idParsers.ts +++ b/src/utils/idParsers.ts @@ -30,6 +30,10 @@ export function urlToFolderId(url: string): string | null { url = url.replace(/drive.google.com\/.*\/open/, 'https://drive.google.com/open'); } + if (url.indexOf('http://drive.google.com') > -1) { + url = url.replace('http://drive.google.com', 'https://drive.google.com'); + } + if (url.indexOf('https://drive.google.com/open?id%3D') > -1) { url = url.replace('https://drive.google.com/open?id%3D', 'https://drive.google.com/open?id='); } diff --git a/src/wikigdrive.sh b/src/wikigdrive.sh index 8ea98290..3388fe7e 100755 --- a/src/wikigdrive.sh +++ b/src/wikigdrive.sh @@ -19,7 +19,7 @@ while [[ $# -gt 0 ]]; do INSPECT="$1" shift # past argument ;; - --link_mode | --workdir | --drive | --debug | --client_id | --client_secret | --service_account | --share_email) + --link_mode | --workdir | --drive | --debug | --client_id | --client_secret | --service_account | --share_email | --server_port) POSITIONAL_ARGS+=("$1") # save positional arg1 POSITIONAL_ARGS+=("$2") # save positional arg2 shift # past argument diff --git a/src/wikigdrivectl.sh b/src/wikigdrivectl.sh index 480b686b..1e958134 100755 --- a/src/wikigdrivectl.sh +++ b/src/wikigdrivectl.sh @@ -11,13 +11,15 @@ POSITIONAL_ARGS=() CMD="" INSPECT="" +ORIG_ARGS=$@ + while [[ $# -gt 0 ]]; do case $1 in --inspect) INSPECT="$1" shift # past argument ;; - --link_mode | --workdir | --drive | --debug | --client_id | --client_secret | --service_account | --share_email) + --server_port) POSITIONAL_ARGS+=("$1") # save positional arg1 POSITIONAL_ARGS+=("$2") # save positional arg2 shift # past argument diff --git a/themes/wgd-bootstrap/layouts/_default/single.html b/themes/wgd-bootstrap/layouts/_default/single.html deleted file mode 100644 index 1c2eb582..00000000 --- a/themes/wgd-bootstrap/layouts/_default/single.html +++ /dev/null @@ -1,3 +0,0 @@ -{{ define "main" }} -{{- partial "content.html" . -}} -{{ end }} diff --git a/themes/wgd-bootstrap/layouts/index.html b/themes/wgd-bootstrap/layouts/index.html deleted file mode 100644 index bc61515a..00000000 --- a/themes/wgd-bootstrap/layouts/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - wikigdrive - - - - - - - - - - - - - - - - - - -
{{- partial "content.html" . -}}
- - - diff --git a/doc/_index.md b/website/_index.md similarity index 71% rename from doc/_index.md rename to website/_index.md index 3a8dc247..d0e989aa 100644 --- a/doc/_index.md +++ b/website/_index.md @@ -1,3 +1,6 @@ +--- +#layout: overridden inside /hugo/themes/wgd-bootstrap/layouts/index.html +--- # wikiGDrive Google Drive to MarkDown synchronization @@ -8,11 +11,11 @@ Google Drive to MarkDown synchronization WikiGDrive is a node app that uses the [Google Drive API](https://developers.google.com/drive/api/v3/quickstart/nodejs) to transform Google Docs and Drawings into markdown. -![Diagram](./diagram.svg) +![Diagram](docs/diagram.svg) [Google Drive Notes](https://docs.google.com/document/d/1H6vwfQXIexdg4ldfaoPUjhOZPnSkNn6h29WD6Fi-SBY/edit#) | [Github Project](https://github.com/mieweb/wikiGDrive/projects) -| [Github Developer Notes](./developer.md) +| [Github Developer Notes](docs/developer.md) With a "Shared Drive" as the key, WikiGDrive: @@ -27,8 +30,8 @@ WikiGDrive scans for changes in the drive and then refresh the local converted f ## Developer Documentation -* [Developer README](./developer.md) -* [Internals](./internals.md) +* [Developer README](docs/developer.md) +* [Internals](docs/internals.md) ## Install from NPM @@ -186,35 +189,3 @@ There are two methods: individual credentials or a service account. * [Service Account](https://developers.google.com/identity/protocols/oauth2/service-account#delegatingauthority) Note: If the authentication is successful, but the account does not have access to documents in gdrive, there is currently no way to know if the directory is empty or just not possible to see. - -## FAQ - -### What is the purpose of this tool? - -To enable collaborative editing of documentation and the ability to publish that documentation as well as linking it to revision control system branches (like in git) - -### Why use Google at all. Why not use markdown and GitHub? - -No collaboration in real-time. Also, markdown requires skill when managing screenshots and diagrams that are not easily accomplished in markdown. - -### Why not just use Google Docs? - -Would love it if it were possible, but drive does not offer the ability to publish pages cleanly. The URLs are not SEO friendly. Would love it if there was a driveId map where every document could be given a friendly name (aka its title on the drive). Then (like Wikipedia has disambiguation pages), a reader could be redirected to the proper content. Google doesn’t, so this project is an attempt to fill that gap. - -Also, Google does not have a good blame system for contributions to a document. Hopefully this is fixed someday but in the meantime, GitHub on markdown can _help_ fill the void. - -### Why markdown? - -All ears for a different preferred format. It's easy to read when editing directly and when doing a diff for changes is clean - -### What about mismatches in Docs vs Markdown - -There are features of Google Docs that are not going to be supported. Like coloring text, page breaks, headers, comments, etc. These features are not core to our goals for clean WYSIYYM. - -Keeping a WYSIWYM style ensures a good mobile experience to view and edit. - -### Why not make a website front end to a Google shared drive? - -Our goals are to be able to take versions of the content and commit them along with a version of the code at a point in time. By just making a website, it would allow for real-time viewing of the content but no way to go to a specific version of the documentation at a given time. - -A website front end is a goal for real-time testing of the viewing experience, but initially, we want to make markdown that can be committed. diff --git a/website/docs/_index.md b/website/docs/_index.md new file mode 100644 index 00000000..68e3e3bd --- /dev/null +++ b/website/docs/_index.md @@ -0,0 +1,171 @@ +--- +title: Introduction +navWeight: 1000 # Upper weight gets higher precedence, optional. +--- +# wikiGDrive + +Google Drive to MarkDown synchronization + +[![Develop Server Deploy](https://github.com/mieweb/wikiGDrive/actions/workflows/DevelopServerDeploy.yml/badge.svg?branch=develop&event=push)](https://github.com/mieweb/wikiGDrive/actions/workflows/DevelopServerDeploy.yml) +[![Prod Server Deploy](https://github.com/mieweb/wikiGDrive/actions/workflows/ProdServerDeploy.yml/badge.svg?branch=master&event=push)](https://github.com/mieweb/wikiGDrive/actions/workflows/ProdServerDeploy.yml) +[![CodeQL](https://github.com/mieweb/wikiGDrive/actions/workflows/codeql-analysis.yml/badge.svg?branch=master&event=push)](https://github.com/mieweb/wikiGDrive/actions/workflows/codeql-analysis.yml?query=event%3Apush+branch%3Amaster+) + +WikiGDrive is a node app that uses the [Google Drive API](https://developers.google.com/drive/api/v3/quickstart/nodejs) to transform Google Docs and Drawings into markdown. + +![Diagram](./diagram.svg) + +[Google Drive Notes](https://docs.google.com/document/d/1H6vwfQXIexdg4ldfaoPUjhOZPnSkNn6h29WD6Fi-SBY/edit#) +| [Github Project](https://github.com/mieweb/wikiGDrive/projects) +| [Github Developer Notes](docs/developer.md) + +With a "Shared Drive" as the key, WikiGDrive: + +* Reads all the files from a Google "Shared Drive" +* Builds a map of the driveId (URL) to the pathname in the "Shared Drive" +* For each Google Document: + * Converts to a Markdown file with the path (instead of the driveId for the file) + * Changes driveId to the path (eg: 12lvdxKgGsD.../edit would be changed to /filename + * Support diagrams as SVG (and map the URLs in the diagram) + +WikiGDrive scans for changes in the drive and then refresh the local converted files. + +## Developer Documentation + +* [Developer README](docs/developer.md) +* [Internals](docs/internals.md) + +## Usage and options + +Init workdir with (creates internal .wgd directory): + +``` +wikigdrive init --drive "https://drive.google.com/drive/folders/FOLDER_ID" + +--service_account=wikigdrive.json +--config /location/of/.wgd - Location of config file +--dest /location/of/downloaded/content - Destination for downloaded and converted markdown files + +--client_id - ID of google app, alternatively can be passed in .env or through environment variable CLIENT_ID; +--client_secret - Secret of google app, alternatively can be passed in .env or through environment variable CLIENT_SECRET; + +--link_mode - Style of internal markdown links +--link_mode mdURLs - `/filename.md` +--link_mode dirURLs - `/filename/` +--link_mode uglyURLs - `/filename.html` - see https://gohugo.io/getting-started/configuration/ +``` + +List available drive ids that wikigdrive has access to on Google: + +``` +wikigdrive drives +``` + +Run one time documents pull + +``` +wikigdrive pull +``` + +Run server mode + +``` +wikigdrive server +``` + +## Example usage with Hugo Generator + +1. Install [hugo](https://gohugo.io/getting-started/quick-start/) + +2. Create a New Site + +``` +hugo new site quickstart +``` + +3. Add a Theme + +``` +cd quickstart +git init +git submodule add https://github.com/budparr/gohugo-theme-ananke.git themes/ananke +echo 'theme = "ananke"' >> config.toml +``` + +4. Install wikigdrive + +``` +npm i -g @mieweb/wikigdrive +``` + +5. Sync GDrive + +``` +wikigdrive init --drive "https://drive.google.com/drive/folders/FOLDER_ID" --dest ./content --link_mode uglyURLs +wikigdrive pull +``` + +Note that by default you need to use [uglyURLs](https://gohugo.io/content-management/urls/#ugly-urls) with Hugo. + +6. Generate HTML + +``` +hugo +``` + +or start server for development: + +``` +hugo server +``` + +## Example usage with Hexo Generator + +1. Install [hexo](https://hexo.io/docs/main.html) + +``` +npm i -g hexo-cli +``` + +2. Create a New Site + +``` +hexo init quickstart +``` + +3. Add a Theme + +By default, hexo installs `landscape` theme. If you need another one check [hexo themes](https://hexo.io/docs/themes) + +4. Install wikigdrive + +``` +npm i -g @mieweb/wikigdrive +``` + +5. Sync GDrive + +``` +wikigdrive init --drive "https://drive.google.com/drive/folders/FOLDER_ID" --dest ./source --link_mode uglyURLs +wikigdrive pull +``` + +6. Generate HTML + +``` +hexo generate +``` + +or start server for development: + +``` +hexo serve +``` + +## Authorization + +There are two methods: individual credentials or a service account. + +* [Individual](https://cloud.google.com/docs/authentication/end-user#creating_your_client_credentials) +* [Service Account](https://developers.google.com/identity/protocols/oauth2/service-account#delegatingauthority) + +Note: If the authentication is successful, but the account does not have access to documents in gdrive, there is currently no way to know if the directory is empty or just not possible to see. diff --git a/doc/developer.md b/website/docs/developer.md similarity index 97% rename from doc/developer.md rename to website/docs/developer.md index b910798c..4ae9b372 100644 --- a/doc/developer.md +++ b/website/docs/developer.md @@ -1,4 +1,8 @@ -# Developer +--- +title: Developer Guide +navWeight: -15 +--- +# Developer Guide See [Node setup on the system](#Node-setup-on-the-system) for prereq. @@ -80,7 +84,7 @@ https://console.cloud.google.com/iam-admin/serviceaccounts/details/1031846960952 This is for configuring Google Apps and their Console to permit the Google Marketplace to the store. -See [app_script](../apps/app-script) +See [app_script](../../apps/app-script) ## Runner diff --git a/doc/diagram.svg b/website/docs/diagram.svg similarity index 100% rename from doc/diagram.svg rename to website/docs/diagram.svg diff --git a/website/docs/faq.md b/website/docs/faq.md new file mode 100644 index 00000000..c9e896f7 --- /dev/null +++ b/website/docs/faq.md @@ -0,0 +1,35 @@ +--- +title: FAQ +navWeight: -10 +--- +## FAQ + +### What is the purpose of this tool? + +To enable collaborative editing of documentation and the ability to publish that documentation as well as linking it to revision control system branches (like in git) + +### Why use Google at all. Why not use markdown and GitHub? + +No collaboration in real-time. Also, markdown requires skill when managing screenshots and diagrams that are not easily accomplished in markdown. + +### Why not just use Google Docs? + +Would love it if it were possible, but drive does not offer the ability to publish pages cleanly. The URLs are not SEO friendly. Would love it if there was a driveId map where every document could be given a friendly name (aka its title on the drive). Then (like Wikipedia has disambiguation pages), a reader could be redirected to the proper content. Google doesn’t, so this project is an attempt to fill that gap. + +Also, Google does not have a good blame system for contributions to a document. Hopefully this is fixed someday but in the meantime, GitHub on markdown can _help_ fill the void. + +### Why markdown? + +All ears for a different preferred format. It's easy to read when editing directly and when doing a diff for changes is clean + +### What about mismatches in Docs vs Markdown + +There are features of Google Docs that are not going to be supported. Like coloring text, page breaks, headers, comments, etc. These features are not core to our goals for clean WYSIYYM. + +Keeping a WYSIWYM style ensures a good mobile experience to view and edit. + +### Why not make a website front end to a Google shared drive? + +Our goals are to be able to take versions of the content and commit them along with a version of the code at a point in time. By just making a website, it would allow for real-time viewing of the content but no way to go to a specific version of the documentation at a given time. + +A website front end is a goal for real-time testing of the viewing experience, but initially, we want to make markdown that can be committed. diff --git a/website/docs/install.md b/website/docs/install.md new file mode 100644 index 00000000..5307f376 --- /dev/null +++ b/website/docs/install.md @@ -0,0 +1,24 @@ +--- +title: Installation Guide +navWeight: 990 # Upper weight gets higher precedence, optional. +--- +## Install from NPM + +*Not currently working* +See https://github.com/mieweb/wikiGDrive/issues/297 for status. + +[![View this project on NPM](https://img.shields.io/npm/v/@mieweb/wikigdrive.svg)](https://www.npmjs.com/package/@mieweb/wikigdrive) +[![NPM downloads](https://img.shields.io/npm/dm/@mieweb/wikigdrive.svg)](https://www.npmjs.com/package/@mieweb/wikigdrive) +![Publish wikigdrive to NPM](https://github.com/mieweb/wikiGDrive/workflows/Publish%20wikigdrive%20to%20NPM/badge.svg) + +``` +npm i -g @mieweb/wikigdrive +``` + +## App setup + +1. Go to [console](https://console.developers.google.com/) +2. Create New Project +3. Enable Apis -> add Google Drive API +4. Enable Apis -> Add Google Docs API +5. Credentials -> Create Credentials (OAuth Client ID) -> Other ( see authorization section ) diff --git a/doc/internals.md b/website/docs/internals.md similarity index 99% rename from doc/internals.md rename to website/docs/internals.md index c8aa891b..4692d8e2 100644 --- a/doc/internals.md +++ b/website/docs/internals.md @@ -1,3 +1,8 @@ +--- +title: Internals +navWeight: -15 +--- + # Internals ## File Structure on Server diff --git a/website/docs/usage/_index.md b/website/docs/usage/_index.md new file mode 100644 index 00000000..a66906b7 --- /dev/null +++ b/website/docs/usage/_index.md @@ -0,0 +1,12 @@ +--- +title: Usage +--- +# Usage + +## Command tool + +TODO + +## Server UI + +TODO diff --git a/doc/wikigdrive_usage.md b/website/docs/usage/wikigdrive_usage.md similarity index 50% rename from doc/wikigdrive_usage.md rename to website/docs/usage/wikigdrive_usage.md index 141170e8..0e56b983 100644 --- a/doc/wikigdrive_usage.md +++ b/website/docs/usage/wikigdrive_usage.md @@ -1,8 +1,11 @@ +--- +title: wikigdrive +--- # Usage ## wikigdrive usage -$ wikigdrive [args] [] + $ wikigdrive [args] [] Main commands: @@ -11,12 +14,12 @@ Main commands: --client_secret --service_account=./private_key.json - wikigdrive service + wikigdrive server + --link_mode [mdURLs|dirURLs|uglyURLs] - wikigdrive add [folder_id_or_url] + wikigdrive register [drive_id_or_url] --drive [shared drive url] --workdir (current working folder) - --link_mode [mdURLs|dirURLs|uglyURLs] wikigdrive pull [URL to specific file] @@ -30,16 +33,16 @@ Other commands: wikigdrive download wikigdrive transform -Options: ---workdir (current working folder) - Examples: -$ wikigdrive init -$ wikigdrive add https://google.drive... -## wikigdrive drives usage + $ wikigdrive init + $ wikigdrive add https://google.drive... + +## wikigdrive config usage -$ wikigdrive drives [] + $ wikigdrive config [] + +Stores authentication config inside /auth_config.json to avoid specifying authentication options each time Options: @@ -47,11 +50,32 @@ Options: --client_secret GOOGLE_DRIVE_API CLIENT_SECRET --service_account GOOGLE_DRIVE_API SERVICE_ACCOUNT_JSON file location +## wikigdrive drives usage + + $ wikigdrive drives [] + +Displays drives available to user or service account + Examples: wikigdrive drives --client_id=AAA --client_secret=BBB wikigdrive drives --service_account=./private_key.json +## wikigdrive server usage + + $ wikigdrive server [] + +Starts wikigdrive in multiuser server mode + +Options: + + --share_email Email to share drives with + --server_port Server port (default 3000) + +Examples: + + $ wikigdrive server --share_email=example@example.com --server_port=3000 + ## All commands Other commands: @@ -61,3 +85,17 @@ Other commands: wikigdrive sync wikigdrive download wikigdrive transform + +## Common options + +Options available for each command: + +### Data location + + --workdir (current working folder) + +### Authentication + + --client_id GOOGLE_DRIVE_API CLIENT_ID + --client_secret GOOGLE_DRIVE_API CLIENT_SECRET + --service_account GOOGLE_DRIVE_API SERVICE_ACCOUNT_JSON file location diff --git a/website/docs/usage/wikigdrivectl_usage.md b/website/docs/usage/wikigdrivectl_usage.md new file mode 100644 index 00000000..ac92d5bc --- /dev/null +++ b/website/docs/usage/wikigdrivectl_usage.md @@ -0,0 +1,31 @@ +--- +title: wikigdrivectl +--- +# Usage + +Command wikigdrivectl is used to control locally running wikigdrive server. + +## wikigdrivectl usage + + $ wikigdrivectl [args] [] + +Main commands: + + ps + inspect [drive_id_or_url] + +## wikigdrivectl ps + + $ wikigdrive ps + +Displays all drives with a job count + +## wikigdrivectl inspect + + $ wikigdrive inspect [drive_id_or_url] + +Displays jobs queue for specific drive + +Examples: + + wikigdrive inspect http://drive.google.com/open?id=FOLDER_ID