2019-09-06 21:08:48 +00:00
|
|
|
#!/usr/bin/env python3
|
2015-06-06 09:05:21 +00:00
|
|
|
"""
|
|
|
|
Make single page versions of the documentation for release and
|
|
|
|
conversion into man pages etc.
|
|
|
|
"""
|
|
|
|
|
|
|
|
import os
|
|
|
|
import re
|
2020-07-13 13:07:00 +00:00
|
|
|
import time
|
2015-06-06 09:05:21 +00:00
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
docpath = "docs/content"
|
|
|
|
outfile = "MANUAL.md"
|
|
|
|
|
|
|
|
# Order to add docs segments to make outfile
|
|
|
|
docs = [
|
2020-05-15 17:17:46 +00:00
|
|
|
"_index.md",
|
2015-06-06 09:05:21 +00:00
|
|
|
"install.md",
|
|
|
|
"docs.md",
|
2016-01-07 15:20:32 +00:00
|
|
|
"remote_setup.md",
|
2015-09-27 15:13:20 +00:00
|
|
|
"filtering.md",
|
2019-08-25 19:32:41 +00:00
|
|
|
"gui.md",
|
2018-03-05 11:44:16 +00:00
|
|
|
"rc.md",
|
2015-09-02 22:37:42 +00:00
|
|
|
"overview.md",
|
2019-06-20 15:18:02 +00:00
|
|
|
"flags.md",
|
2021-07-20 18:45:41 +00:00
|
|
|
"docker.md",
|
2022-03-18 11:22:23 +00:00
|
|
|
"bisync.md",
|
2023-09-11 14:59:44 +00:00
|
|
|
"release_signing.md",
|
2017-07-08 22:31:58 +00:00
|
|
|
|
|
|
|
# Keep these alphabetical by full name
|
2019-06-26 18:39:01 +00:00
|
|
|
"fichier.md",
|
2018-02-06 18:23:47 +00:00
|
|
|
"alias.md",
|
2015-06-06 09:05:21 +00:00
|
|
|
"s3.md",
|
2017-07-08 22:31:58 +00:00
|
|
|
"b2.md",
|
|
|
|
"box.md",
|
2017-11-12 17:54:25 +00:00
|
|
|
"cache.md",
|
2019-08-30 14:18:40 +00:00
|
|
|
"chunker.md",
|
2019-08-27 21:50:07 +00:00
|
|
|
"sharefile.md",
|
2017-07-08 22:31:58 +00:00
|
|
|
"crypt.md",
|
2020-12-02 00:47:07 +00:00
|
|
|
"compress.md",
|
2022-04-20 16:57:43 +00:00
|
|
|
"combine.md",
|
2015-06-06 09:05:21 +00:00
|
|
|
"dropbox.md",
|
2020-08-11 14:09:00 +00:00
|
|
|
"filefabric.md",
|
2024-07-23 15:41:40 +00:00
|
|
|
"filescom.md",
|
2017-07-08 22:31:58 +00:00
|
|
|
"ftp.md",
|
2024-07-25 15:53:19 +00:00
|
|
|
"gofile.md",
|
2015-06-06 09:05:21 +00:00
|
|
|
"googlecloudstorage.md",
|
2017-07-08 22:31:58 +00:00
|
|
|
"drive.md",
|
2019-06-17 16:50:58 +00:00
|
|
|
"googlephotos.md",
|
2021-11-01 15:42:05 +00:00
|
|
|
"hasher.md",
|
2020-09-28 17:29:44 +00:00
|
|
|
"hdfs.md",
|
2022-07-07 17:58:22 +00:00
|
|
|
"hidrive.md",
|
2017-07-08 22:31:58 +00:00
|
|
|
"http.md",
|
2023-11-24 18:18:01 +00:00
|
|
|
"imagekit.md",
|
2022-04-12 09:38:44 +00:00
|
|
|
"internetarchive.md",
|
2018-08-07 18:51:12 +00:00
|
|
|
"jottacloud.md",
|
2019-02-22 15:50:04 +00:00
|
|
|
"koofr.md",
|
2023-11-26 15:59:12 +00:00
|
|
|
"linkbox.md",
|
2019-09-09 20:56:16 +00:00
|
|
|
"mailru.md",
|
2017-10-15 10:45:39 +00:00
|
|
|
"mega.md",
|
2018-05-03 15:31:06 +00:00
|
|
|
"memory.md",
|
2021-10-14 22:01:46 +00:00
|
|
|
"netstorage.md",
|
2017-07-25 14:18:13 +00:00
|
|
|
"azureblob.md",
|
2023-11-15 09:37:57 +00:00
|
|
|
"azurefiles.md",
|
2017-07-08 22:31:58 +00:00
|
|
|
"onedrive.md",
|
2017-07-17 05:36:45 +00:00
|
|
|
"opendrive.md",
|
2024-09-08 15:21:56 +00:00
|
|
|
"oracleobjectstorage/_index.md",
|
2017-06-25 23:47:54 +00:00
|
|
|
"qingstor.md",
|
2023-09-08 13:31:29 +00:00
|
|
|
"quatrix.md",
|
2021-11-01 15:42:05 +00:00
|
|
|
"sia.md",
|
2017-07-08 22:31:58 +00:00
|
|
|
"swift.md",
|
2017-09-19 15:09:43 +00:00
|
|
|
"pcloud.md",
|
2023-04-04 15:33:48 +00:00
|
|
|
"pikpak.md",
|
2024-08-12 12:35:44 +00:00
|
|
|
"pixeldrain.md",
|
2019-08-26 14:25:20 +00:00
|
|
|
"premiumizeme.md",
|
2023-07-22 09:46:21 +00:00
|
|
|
"protondrive.md",
|
2019-08-06 12:47:52 +00:00
|
|
|
"putio.md",
|
2023-09-10 10:55:37 +00:00
|
|
|
"protondrive.md",
|
2020-04-25 17:55:18 +00:00
|
|
|
"seafile.md",
|
2017-01-31 20:34:11 +00:00
|
|
|
"sftp.md",
|
2022-09-30 15:10:57 +00:00
|
|
|
"smb.md",
|
2022-02-04 17:58:04 +00:00
|
|
|
"storj.md",
|
2019-10-24 11:35:50 +00:00
|
|
|
"sugarsync.md",
|
2024-03-26 09:46:47 +00:00
|
|
|
"ulozto.md",
|
2021-04-19 15:18:18 +00:00
|
|
|
"uptobox.md",
|
2018-09-07 14:08:29 +00:00
|
|
|
"union.md",
|
2017-10-02 19:29:23 +00:00
|
|
|
"webdav.md",
|
2017-07-08 22:31:58 +00:00
|
|
|
"yandex.md",
|
2020-10-07 22:17:50 +00:00
|
|
|
"zoho.md",
|
2017-07-08 22:31:58 +00:00
|
|
|
|
2015-06-06 09:05:21 +00:00
|
|
|
"local.md",
|
|
|
|
"changelog.md",
|
|
|
|
"bugs.md",
|
2015-07-30 19:26:29 +00:00
|
|
|
"faq.md",
|
2015-06-06 09:05:21 +00:00
|
|
|
"licence.md",
|
|
|
|
"authors.md",
|
|
|
|
"contact.md",
|
|
|
|
]
|
|
|
|
|
2016-08-03 20:36:28 +00:00
|
|
|
# Order to put the commands in - any not on here will be in sorted order
|
|
|
|
commands_order = [
|
|
|
|
"rclone_config.md",
|
|
|
|
"rclone_copy.md",
|
|
|
|
"rclone_sync.md",
|
|
|
|
"rclone_move.md",
|
|
|
|
"rclone_delete.md",
|
|
|
|
"rclone_purge.md",
|
|
|
|
"rclone_mkdir.md",
|
|
|
|
"rclone_rmdir.md",
|
|
|
|
"rclone_check.md",
|
|
|
|
"rclone_ls.md",
|
|
|
|
"rclone_lsd.md",
|
|
|
|
"rclone_lsl.md",
|
|
|
|
"rclone_md5sum.md",
|
|
|
|
"rclone_sha1sum.md",
|
|
|
|
"rclone_size.md",
|
|
|
|
"rclone_version.md",
|
|
|
|
"rclone_cleanup.md",
|
|
|
|
"rclone_dedupe.md",
|
|
|
|
]
|
|
|
|
|
2015-06-06 09:05:21 +00:00
|
|
|
# Docs which aren't made into outfile
|
|
|
|
ignore_docs = [
|
|
|
|
"downloads.md",
|
2015-08-19 21:10:04 +00:00
|
|
|
"privacy.md",
|
2023-07-17 13:19:16 +00:00
|
|
|
"sponsor.md",
|
2024-01-25 16:35:33 +00:00
|
|
|
"amazonclouddrive.md",
|
2015-06-06 09:05:21 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
def read_doc(doc):
|
|
|
|
"""Read file as a string"""
|
|
|
|
path = os.path.join(docpath, doc)
|
|
|
|
with open(path) as fd:
|
|
|
|
contents = fd.read()
|
|
|
|
parts = contents.split("---\n", 2)
|
|
|
|
if len(parts) != 3:
|
|
|
|
raise ValueError("Couldn't find --- markers: found %d parts" % len(parts))
|
|
|
|
contents = parts[2].strip()+"\n\n"
|
|
|
|
# Remove icons
|
|
|
|
contents = re.sub(r'<i class="fa.*?</i>\s*', "", contents)
|
2020-05-22 11:22:52 +00:00
|
|
|
# Interpret img shortcodes
|
|
|
|
# {{< img ... >}}
|
|
|
|
contents = re.sub(r'\{\{<\s*img\s+(.*?)>\}\}', r"<img \1>", contents)
|
2020-05-21 16:28:03 +00:00
|
|
|
# Make any img tags absolute
|
|
|
|
contents = re.sub(r'(<img.*?src=")/', r"\1https://rclone.org/", contents)
|
2015-06-06 09:05:21 +00:00
|
|
|
# Make [...](/links/) absolute
|
2020-02-28 13:45:04 +00:00
|
|
|
contents = re.sub(r'\]\((\/.*?\/(#.*)?)\)', r"](https://rclone.org\1)", contents)
|
2020-05-21 16:28:03 +00:00
|
|
|
# Add additional links on the front page
|
2020-05-22 11:22:52 +00:00
|
|
|
contents = re.sub(r'\{\{< rem MAINPAGELINK >\}\}', "- [Donate.](https://rclone.org/donate/)", contents)
|
2017-09-25 16:55:19 +00:00
|
|
|
# Interpret provider shortcode
|
|
|
|
# {{< provider name="Amazon S3" home="https://aws.amazon.com/s3/" config="/s3/" >}}
|
2020-05-22 11:22:52 +00:00
|
|
|
contents = re.sub(r'\{\{<\s*provider.*?name="(.*?)".*?>\}\}', r"- \1", contents)
|
|
|
|
# Remove remaining shortcodes
|
|
|
|
contents = re.sub(r'\{\{<.*?>\}\}', r"", contents)
|
|
|
|
contents = re.sub(r'\{\{%.*?%\}\}', r"", contents)
|
2015-06-06 09:05:21 +00:00
|
|
|
return contents
|
|
|
|
|
|
|
|
def check_docs(docpath):
|
|
|
|
"""Check all the docs are in docpath"""
|
|
|
|
files = set(f for f in os.listdir(docpath) if f.endswith(".md"))
|
2024-09-08 15:21:56 +00:00
|
|
|
files.update(f for f in docs if os.path.exists(os.path.join(docpath,f)))
|
2015-06-06 09:05:21 +00:00
|
|
|
files -= set(ignore_docs)
|
|
|
|
docs_set = set(docs)
|
|
|
|
if files == docs_set:
|
|
|
|
return
|
2019-09-06 21:08:48 +00:00
|
|
|
print("Files on disk but not in docs variable: %s" % ", ".join(files - docs_set))
|
|
|
|
print("Files in docs variable but not on disk: %s" % ", ".join(docs_set - files))
|
2015-06-06 09:05:21 +00:00
|
|
|
raise ValueError("Missing files")
|
|
|
|
|
2016-08-03 20:36:28 +00:00
|
|
|
def read_command(command):
|
|
|
|
doc = read_doc("commands/"+command)
|
|
|
|
doc = re.sub(r"### Options inherited from parent commands.*$", "", doc, 0, re.S)
|
|
|
|
doc = doc.strip()+"\n"
|
|
|
|
return doc
|
|
|
|
|
|
|
|
def read_commands(docpath):
|
|
|
|
"""Reads the commands an makes them into a single page"""
|
|
|
|
files = set(f for f in os.listdir(docpath + "/commands") if f.endswith(".md"))
|
|
|
|
docs = []
|
|
|
|
for command in commands_order:
|
|
|
|
docs.append(read_command(command))
|
|
|
|
files.remove(command)
|
|
|
|
for command in sorted(files):
|
|
|
|
if command != "rclone.md":
|
|
|
|
docs.append(read_command(command))
|
|
|
|
return "\n".join(docs)
|
2020-07-13 13:07:00 +00:00
|
|
|
|
2015-06-06 09:05:21 +00:00
|
|
|
def main():
|
|
|
|
check_docs(docpath)
|
2019-09-06 21:08:48 +00:00
|
|
|
command_docs = read_commands(docpath).replace("\\", "\\\\") # escape \ so we can use command_docs in re.sub
|
2020-07-13 13:07:00 +00:00
|
|
|
build_date = datetime.utcfromtimestamp(
|
|
|
|
int(os.environ.get('SOURCE_DATE_EPOCH', time.time())))
|
2015-06-06 09:05:21 +00:00
|
|
|
with open(outfile, "w") as out:
|
|
|
|
out.write("""\
|
|
|
|
%% rclone(1) User Manual
|
|
|
|
%% Nick Craig-Wood
|
|
|
|
%% %s
|
|
|
|
|
2020-07-13 13:07:00 +00:00
|
|
|
""" % build_date.strftime("%b %d, %Y"))
|
2015-06-06 09:05:21 +00:00
|
|
|
for doc in docs:
|
2016-08-03 20:36:28 +00:00
|
|
|
contents = read_doc(doc)
|
|
|
|
# Substitute the commands into doc.md
|
|
|
|
if doc == "docs.md":
|
|
|
|
contents = re.sub(r"The main rclone commands.*?for the full list.", command_docs, contents, 0, re.S)
|
|
|
|
out.write(contents)
|
2019-09-06 21:08:48 +00:00
|
|
|
print("Written '%s'" % outfile)
|
2015-06-06 09:05:21 +00:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|