#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import json
import shutil
import tempfile
import subprocess
from .common import isRoot
from .common import rootPath
from .common import saveFile
from .common import projectUrl
from .common import projectDesc
from .common import releaseInfo
from .common import createFolder
from .common import resourceInfo
from .sequence import txtSerialize
from .sequence import jsonSerialize
from .sequence import htmlSerialize
from .sequence import gitbookSummary
from .sequence import gitbookChapters
from .sequence import gitbookMetadata
def txtRelease(metadata: dict, content: dict) -> None:
saveFile(releaseInfo['txt'], txtSerialize(metadata, content))
def jsonRelease(metadata: dict, content: dict) -> None:
saveFile(releaseInfo['json'], jsonSerialize(metadata, content))
def gitbookRelease(metadata: dict, content: dict) -> None:
createFolder(releaseInfo['gitbook'])
createFolder(os.path.join(releaseInfo['gitbook'], './assets/'))
createFolder(os.path.join(releaseInfo['gitbook'], './chapter/'))
cover = gitbookMetadata(metadata)
for (resName, resUrls) in resourceInfo.items():
cover += '{% hint style="success" %}\n' \
+ '### >>> [%s](%s) <<<\n' % (resName, resUrls[0]) \
+ '{% endhint %}\n\n'
cover += '{%% embed url="%s" %%}\n项目地址\n{%% endembed %%}\n' % projectUrl
saveFile(os.path.join(releaseInfo['gitbook'], 'README.md'), cover)
saveFile(os.path.join(releaseInfo['gitbook'], 'SUMMARY.md'), gitbookSummary(content))
for (chapterPath, chapterContent) in gitbookChapters(content).items():
saveFile(os.path.join(releaseInfo['gitbook'], chapterPath), chapterContent)
shutil.copy( # gitbook cover
os.path.join(rootPath, './assets/cover.jpg'),
os.path.join(releaseInfo['gitbook'], './assets/cover.jpg')
)
def staticDepends(workDir: str, metadata: dict, content: dict) -> None:
createFolder(os.path.join(workDir, './assets/'))
createFolder(os.path.join(workDir, './chapter/'))
cover = gitbookMetadata(metadata) + '
\n'
for (resName, resUrls) in resourceInfo.items():
cover += '\n{% hint style="tip" %}\n' \
+ '#### [%s](%s)([备用地址](%s))\n' % (resName, resUrls[0], resUrls[1]) \
+ '{% endhint %}\n'
bookInfo = json.dumps({
'title': metadata['name'],
'author': metadata['author'],
'description': projectDesc,
"language": "zh-hans",
'plugins': [
'-lunr', '-search', '-sharing', 'hints', 'github',
'hide-element', 'fontsettings', 'image-captions', 'back-to-top-button'
],
'pluginsConfig': {
'github': {'url': projectUrl},
'hide-element': {
'elements': ['.gitbook-link']
}
}
})
saveFile(os.path.join(workDir, 'README.md'), cover)
saveFile(os.path.join(workDir, 'book.json'), bookInfo)
saveFile(os.path.join(workDir, 'SUMMARY.md'), gitbookSummary(content))
for (chapterPath, chapterContent) in gitbookChapters(content).items():
saveFile(os.path.join(workDir, chapterPath), chapterContent)
shutil.copy( # gitbook cover
os.path.join(rootPath, './assets/cover.jpg'),
os.path.join(workDir, './assets/cover.jpg')
)
def htmlCompress(file: str) -> None:
rawHtml = open(file).read().split('\n')
with open(file, 'w') as fileObj:
fileObj.write('\n'.join([x.strip() for x in rawHtml if x.strip() != '']) + '\n')
def staticBuild(workDir: str) -> None:
buildDir = '/xxrs/'
nodeImage = 'node:10-alpine'
buildCommand = 'docker run --rm -v %s:%s --entrypoint sh %s -c "%s"' % (
workDir, buildDir, nodeImage,
'npm install gitbook-cli -g && gitbook install %s && gitbook build %s --log=debug' % (
buildDir, buildDir
)
)
print('Gitbook Build -> %s' % workDir)
subprocess.Popen(buildCommand, shell = True).wait() # blocking wait
os.rename(os.path.join(workDir, '_book'), os.path.join(workDir, 'XXRS'))
htmlCompress(os.path.join(workDir, './XXRS/index.html'))
chapterFolder = os.path.join(workDir, './XXRS/chapter/')
for file in os.listdir(chapterFolder): # compress html content
htmlCompress(os.path.join(chapterFolder, file))
os.system('cd %s && tar cJf %s XXRS' % (workDir, releaseInfo['static']))
def staticRelease(metadata: dict, content: dict) -> None:
if not isRoot():
print('\033[0;33mDue to the permission problems, it is recommended to run under root user.\033[0m')
return
tempDir = tempfile.TemporaryDirectory() # access temporary directory
staticDepends(tempDir.name, metadata, content)
staticBuild(tempDir.name)
tempDir.cleanup()
def calibreDepends(workDir: str, metadata: dict, content: dict) -> None:
metaInfo = [
'',
'',
'',
'',
'',
'',
]
opfInfo = [
'',
'',
'',
'%s' % metadata['name'],
'zho',
'Dnomd343',
'%(aut)s' % {'aut': metadata['author']},
'%s' % projectUrl,
'%s' % '<div>%s</div>' % (
''.join(['<p>%s</p>' % x for x in metadata['desc']])
),
'' % metadata['author'],
'' % metadata['name'],
'',
'',
' ',
' ',
'',
'', '', '',
'',
]
createFolder(os.path.join(workDir, 'META-INF'))
saveFile(os.path.join(workDir, 'mimetype'), 'application/epub+zip')
saveFile(os.path.join(workDir, 'content.opf'), '\n'.join(opfInfo) + '\n')
saveFile(os.path.join(workDir, 'xxrs.html'), htmlSerialize(metadata, content))
saveFile(os.path.join(workDir, 'META-INF', 'container.xml'), '\n'.join(metaInfo) + '\n')
def calibreRelease(metadata: dict, content: dict) -> None:
tempDir = tempfile.TemporaryDirectory() # access temporary directory
calibreDepends(tempDir.name, metadata, content)
os.system('cd %s && zip -r xxrs.zip *' % tempDir.name)
shutil.move(os.path.join(tempDir.name, 'xxrs.zip'), releaseInfo['calibre'])
tempDir.cleanup()
def calibreBuild(workDir: str, suffix: str, extOption: list, metadata: dict, content: dict) -> None:
buildDir = '/xxrs/'
calibreImage = 'linuxserver/calibre'
calibreCommand = [
'ebook-convert',
'xxrs.zip', 'xxrs%s' % suffix,
'--output-profile=generic_eink',
'--level1-toc=\'//h:h2\'',
'--cover=cover.jpg',
'--toc-title=目录',
'--remove-paragraph-spacing',
'--remove-paragraph-spacing-indent-size=2',
'--verbose',
]
buildCommand = 'docker run --rm -t -v %s:%s --workdir %s --entrypoint bash %s -c "%s"' % (
workDir, buildDir, buildDir, calibreImage, ' '.join(calibreCommand + extOption)
)
calibreDepends(workDir, metadata, content) # generate calibre input
os.system('cd %s && zip -r xxrs.zip *' % workDir) # compress as zip file
shutil.copy(
os.path.join(rootPath, './assets/cover.jpg'),
os.path.join(workDir, './cover.jpg') # load ebook cover
)
subprocess.Popen(buildCommand, shell = True).wait() # blocking wait
def epubRelease(metadata: dict, content: dict) -> None:
tempDir = tempfile.TemporaryDirectory() # access temporary directory
print('Calibre EPUB Build -> %s' % tempDir.name)
calibreBuild(tempDir.name, '.epub', [], metadata, content)
shutil.copy(os.path.join(tempDir.name, './xxrs.epub'), releaseInfo['epub'])
tempDir.cleanup()
# MOBI Type: KF7 = 0 (old) / KF7 + KF8 = 1 (both) / KF8 = 2 (new)
def mobiRelease(metadata: dict, content: dict, mobiType: int = 1) -> None:
mobiOption = ['--mobi-toc-at-start']
if mobiType == 0:
mobiOption.append('--mobi-file-type=old')
elif mobiType == 1:
mobiOption.append('--mobi-file-type=both')
elif mobiType == 2:
mobiOption.append('--mobi-file-type=new')
else:
print('Unknown MOBI type')
return
tempDir = tempfile.TemporaryDirectory() # access temporary directory
print('Calibre MOBI Build -> %s' % tempDir.name)
calibreBuild(tempDir.name, '.mobi', mobiOption, metadata, content)
shutil.copy(os.path.join(tempDir.name, './xxrs.mobi'), releaseInfo['mobi'])
tempDir.cleanup()
def setPdocMark(originFile: str, targetFile: str) -> None:
jdkImage = 'openjdk:17-alpine'
tempDir = tempfile.TemporaryDirectory() # access temporary directory
suffix = os.path.splitext(originFile)[-1]
shutil.copy(originFile, os.path.join(tempDir.name, 'xxrs%s' % suffix))
shutil.copy(
os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mobi-meta.jar'), # script folder
os.path.join(tempDir.name, 'mobi-meta.jar')
)
dockerCommand = 'docker run --rm -v %(src)s:%(tmp)s --workdir %(tmp)s --entrypoint sh %(img)s -c "%(cmd)s"' % {
'src': tempDir.name,
'tmp': '/xxrs/',
'img': jdkImage,
'cmd': 'java -jar mobi-meta.jar edit xxrs%s xxrs_mod%s --pdoc' % (suffix, suffix),
}
subprocess.Popen(dockerCommand, shell = True).wait() # blocking wait
shutil.copy(os.path.join(tempDir.name, 'xxrs_mod%s' % suffix), targetFile)
tempDir.cleanup()
def azw3Release(metadata: dict, content: dict) -> None:
tempDir = tempfile.TemporaryDirectory() # access temporary directory
print('Calibre AZW3 Build -> %s' % tempDir.name)
calibreBuild(tempDir.name, '.azw3', ['--mobi-toc-at-start'], metadata, content)
setPdocMark(os.path.join(tempDir.name, './xxrs.azw3'), releaseInfo['azw3'])
tempDir.cleanup()