mirror of
https://github.com/SebastianObi/Any2MicronConverter.git
synced 2025-12-22 08:27:14 +00:00
Initial commit
This commit is contained in:
0
CHANGELOG.md
Normal file
0
CHANGELOG.md
Normal file
19
LICENSE
Normal file
19
LICENSE
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2023 Sebastian Obele / obele.eu
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
25
Makefile
Normal file
25
Makefile
Normal file
@@ -0,0 +1,25 @@
|
||||
clean:
|
||||
@echo Cleaning...
|
||||
@-rm -rf ./build
|
||||
@-rm -rf ./dist
|
||||
@-rm -rf ./__pycache__
|
||||
@-rm -rf ./any2micronconverter/__pycache__
|
||||
@-rm -rf ./*.egg-info
|
||||
@echo Done
|
||||
|
||||
cleanall: clean
|
||||
|
||||
preparewheel:
|
||||
pyclean .
|
||||
|
||||
build_wheel:
|
||||
python3 setup.py sdist bdist_wheel
|
||||
|
||||
release: build_wheel
|
||||
|
||||
upload:
|
||||
@echo Ready to publish release, hit enter to continue
|
||||
@read VOID
|
||||
@echo Uploading to PyPi...
|
||||
twine upload dist/*
|
||||
@echo Release published
|
||||
5
Makefile.bat
Normal file
5
Makefile.bat
Normal file
@@ -0,0 +1,5 @@
|
||||
cd any2micronconverter
|
||||
py -m PyInstaller main.spec
|
||||
xcopy /e /v /Y dist ..\dist\
|
||||
del version.rc
|
||||
cd ..
|
||||
125
README.md
Normal file
125
README.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# Any2MicronConverter
|
||||
This program converts any text/markup document into the micron format, which can then be used by a reticlum page server/node.
|
||||
|
||||
At the moment only the DokuWiki format is supported. It is only a very rudimentary functionality, which will be further developed in the future. It is not guaranteed that all formatting will be converted properly.
|
||||
|
||||
|
||||
### Features
|
||||
- Compatible with all Reticulum apps which can display micron pages.
|
||||
- Compatible with the following source file formats:
|
||||
- DokuWiki
|
||||
- ...
|
||||
- Relatively easy to extend to convert additional file formats
|
||||
|
||||
|
||||
## Current Status
|
||||
It should currently be considered beta software and still work in progress.
|
||||
|
||||
All core features are implemented and functioning, but additions will probably occur as real-world use is explored.
|
||||
|
||||
There may be errors or the compatibility after an update is no longer guaranteed.
|
||||
|
||||
The full documentation is not yet available. Due to lack of time I can also not say when this will be further processed.
|
||||
|
||||
|
||||
## Installation manual
|
||||
|
||||
### Linux
|
||||
|
||||
Download the file `any2micronconverter-x.x.x-py3-none-any.whl`.
|
||||
|
||||
Install the dependencies. (CentOS)
|
||||
```
|
||||
yum -y install epel-release.noarch
|
||||
yum -y install python3-pip
|
||||
pip3 install pip --upgrade
|
||||
pip3 install wheel --upgrade
|
||||
```
|
||||
|
||||
Install the dependencies. (Debian/Mint/Raspi OS/Ubuntu)
|
||||
```
|
||||
apt install python3-pip
|
||||
pip3 install pip --upgrade
|
||||
```
|
||||
|
||||
Install the dependencies. (Fedora)
|
||||
```
|
||||
yum -y install make gcc
|
||||
yum -y install python3-pip
|
||||
pip3 install pip --upgrade
|
||||
pip3 install wheel --upgrade
|
||||
```
|
||||
|
||||
Install the dependencies. (Manjaro)
|
||||
```
|
||||
pacman -Sy python-pip
|
||||
pip3 install pip --upgrade
|
||||
```
|
||||
|
||||
Install the dependencies. (openSUSE)
|
||||
```
|
||||
zypper install python310 python310-pip
|
||||
pip3 install pip --upgrade
|
||||
```
|
||||
|
||||
Install the application.
|
||||
`pip3 install any2micronconverter-x.x.x-py3-none-any.whl`
|
||||
|
||||
Done. Launch the application (as user).
|
||||
`any2micronconverter`
|
||||
or in case of an error
|
||||
`./local/bin/any2micronconverter`
|
||||
|
||||
### Windows
|
||||
Download the file `any2micronconverter-x.x.x.exe`.
|
||||
|
||||
Launch it.
|
||||
|
||||
### Startup parameters:
|
||||
```bash
|
||||
usage: main.py [-h] [-m MODE] [-s SRC] [-d DST] [-l LOGLEVEL] [-t] [--link_root LINK_ROOT] [--header HEADER]
|
||||
[--footer FOOTER]
|
||||
|
||||
Any2MicronConverter - Convert any text/makrup document to micron format
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
-m MODE, --mode MODE Mode or type of source data for conversion (Folder name with the command files)
|
||||
-s SRC, --src SRC Path to source directory (All subfolders are included)
|
||||
-d DST, --dst DST Path to destination directory (Folder is overwritten/deleted)
|
||||
-l LOGLEVEL, --loglevel LOGLEVEL
|
||||
-t, --test Running in test mode (No files are deleted or overwritten)
|
||||
--link_root LINK_ROOT
|
||||
Root path of the links (Internal links in the documents)
|
||||
--header HEADER Header string which will be added on all pages
|
||||
--footer FOOTER Footer string which will be added on all pages
|
||||
```
|
||||
|
||||
### Example:
|
||||
The following command converts all files from the source folder `/root/wiki` to the destination folder `/root/.rns_server_page/pages/wiki`.
|
||||
The source file format is `dw2mu`.
|
||||
Internal links start with the text `619d97957a863c8e9d29e2449925fb7c:/page/wiki` to ensure accessibility of the links.
|
||||
```bash
|
||||
any2micronconverter -m dw2mu -s /root/wiki -d /root/.rns_server_page/pages/wiki --link_root 619d97957a863c8e9d29e2449925fb7c:/page/wiki
|
||||
```
|
||||
|
||||
|
||||
## Support / Donations
|
||||
You can help support the continued development by donating via one of the following channels:
|
||||
|
||||
- PayPal: https://paypal.me/SebastianObi
|
||||
- Liberapay: https://liberapay.com/SebastianObi/donate
|
||||
|
||||
|
||||
## Support in another way?
|
||||
You are welcome to participate in the development. Just create a pull request. Or just contact me for further clarifications.
|
||||
|
||||
|
||||
## Do you need a special function or customization?
|
||||
Then feel free to contact me. Customizations or tools developed specifically for you can be realized.
|
||||
|
||||
|
||||
## FAQ
|
||||
|
||||
### How do I start with the software?
|
||||
You should read the `Installation manual` section. There everything is explained briefly. Just work through everything from top to bottom :)
|
||||
5
any2micronconverter/__init__.py
Normal file
5
any2micronconverter/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
import os
|
||||
import glob
|
||||
|
||||
modules = glob.glob(os.path.dirname(__file__)+"/*.py")
|
||||
__all__ = [ os.path.basename(f)[:-3] for f in modules if not f.endswith('__init__.py')]
|
||||
59
any2micronconverter/_version.py
Normal file
59
any2micronconverter/_version.py
Normal file
@@ -0,0 +1,59 @@
|
||||
##############################################################################################################
|
||||
#
|
||||
# Copyright (c) 2023 Sebastian Obele / obele.eu
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# This software uses the following software-parts:
|
||||
# dokuwiki-to-hugo / Copyright (c) 2017 Wouter Groeneveld / https://git.brainbaking.com/wgroeneveld/dokuwiki-to-hugo / MIT License
|
||||
#
|
||||
##############################################################################################################
|
||||
|
||||
|
||||
#################################################
|
||||
# General version information #
|
||||
#################################################
|
||||
|
||||
|
||||
__version__ = "0.0.1"
|
||||
__version_variant__ = "beta"
|
||||
__version_date_time__ = "2023-08-21 00:00"
|
||||
__copyright_short__ = "Copyright (c) 2023 Sebastian Obele / obele.eu / MIT License"
|
||||
__copyright_url__ = "https://www.obele.eu"
|
||||
__title__ = "Any2MicronConverter"
|
||||
__description__ = "Convert any text/makrup document to micron format"
|
||||
__author__ = "Sebastian Obele"
|
||||
__author_email__ = "info@obele.eu"
|
||||
__package_name__ = "any2micronconverter"
|
||||
|
||||
|
||||
#################################################
|
||||
# Configuration #
|
||||
#################################################
|
||||
|
||||
|
||||
__config__ = {}
|
||||
|
||||
__config__["file_extensions_auto"] = {"html": "html2mu", "txt": "dw2mu"}
|
||||
__config__["file_replace"] = {"home.txt": "index.mu", "home.md": "index.mu"}
|
||||
|
||||
__config__["link_root"] = ":/pages"
|
||||
|
||||
__config__["header"] = ""
|
||||
__config__["footer"] = ""
|
||||
55
any2micronconverter/converter.py
Normal file
55
any2micronconverter/converter.py
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python3
|
||||
##############################################################################################################
|
||||
#
|
||||
# Copyright (c) 2023 Sebastian Obele / obele.eu
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# This software uses the following software-parts:
|
||||
# dokuwiki-to-hugo / Copyright (c) 2017 Wouter Groeneveld / https://git.brainbaking.com/wgroeneveld/dokuwiki-to-hugo / MIT License
|
||||
#
|
||||
##############################################################################################################
|
||||
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class Converter:
|
||||
converters = []
|
||||
|
||||
|
||||
@classmethod
|
||||
def register(cls, converter_class):
|
||||
cls.converters.append(converter_class())
|
||||
return converter_class
|
||||
|
||||
|
||||
def __init__(self, file, config, mode):
|
||||
self.file = file
|
||||
self.config = config
|
||||
self.mode = mode
|
||||
|
||||
|
||||
def convert(self):
|
||||
text = Path(self.file).read_text()
|
||||
for converter in Converter.converters:
|
||||
if self.mode != None and self.mode != converter.mode:
|
||||
continue
|
||||
text = converter.convert(text, self.config)
|
||||
return text
|
||||
50
any2micronconverter/dokuwiki/code.py
Normal file
50
any2micronconverter/dokuwiki/code.py
Normal file
@@ -0,0 +1,50 @@
|
||||
import os
|
||||
from sys import platform
|
||||
from re import compile
|
||||
from abc import ABC
|
||||
|
||||
if platform.startswith("win"):
|
||||
from converter import Converter
|
||||
else:
|
||||
from ..converter import Converter
|
||||
|
||||
|
||||
def strip_lang(language):
|
||||
if language == "":
|
||||
return language
|
||||
|
||||
lang = language[1:len(language)]
|
||||
if " " in lang:
|
||||
lang = lang[0:lang.index(" ")]
|
||||
return lang
|
||||
|
||||
|
||||
class BaseCode(ABC):
|
||||
dest = "```"
|
||||
|
||||
|
||||
def __init__(self, tag):
|
||||
self.mode = os.path.basename((os.path.dirname(__file__)))
|
||||
self.tag = tag
|
||||
self.pattern = compile("(<"+tag+"(.*?)>)")
|
||||
|
||||
|
||||
def convert(self, text, config={}):
|
||||
result = text
|
||||
for match in self.pattern.findall(text):
|
||||
language = strip_lang(match[1])
|
||||
result = result.replace(match[0], BaseCode.dest + language)
|
||||
return result.replace("</"+self.tag+">", BaseCode.dest)
|
||||
|
||||
|
||||
@Converter.register
|
||||
class File(BaseCode):
|
||||
def __init__(self):
|
||||
super().__init__("file")
|
||||
|
||||
|
||||
@Converter.register
|
||||
class Code(BaseCode):
|
||||
def __init__(self):
|
||||
super().__init__("code")
|
||||
|
||||
20
any2micronconverter/dokuwiki/comments.py
Normal file
20
any2micronconverter/dokuwiki/comments.py
Normal file
@@ -0,0 +1,20 @@
|
||||
import os
|
||||
import re
|
||||
from sys import platform
|
||||
|
||||
if platform.startswith("win"):
|
||||
from converter import Converter
|
||||
else:
|
||||
from ..converter import Converter
|
||||
|
||||
|
||||
@Converter.register
|
||||
class Cleanup:
|
||||
def __init__(self):
|
||||
self.mode = os.path.basename((os.path.dirname(__file__)))
|
||||
|
||||
|
||||
def convert(self, text, config={}):
|
||||
result = text
|
||||
result = re.sub(r"^>+", "#", result, flags=re.MULTILINE)
|
||||
return result
|
||||
42
any2micronconverter/dokuwiki/emoji.py
Normal file
42
any2micronconverter/dokuwiki/emoji.py
Normal file
@@ -0,0 +1,42 @@
|
||||
import os
|
||||
from sys import platform
|
||||
|
||||
if platform.startswith("win"):
|
||||
from converter import Converter
|
||||
else:
|
||||
from ..converter import Converter
|
||||
|
||||
@Converter.register
|
||||
class Emoji:
|
||||
# http://www.webpagefx.com/tools/emoji-cheat-sheet/
|
||||
config = {
|
||||
"8-)": "sunglasses",
|
||||
"8-O": "flushed",
|
||||
":-(": "worried",
|
||||
":-)": "simple_smile",
|
||||
"=)": "simple_smile",
|
||||
":-/": "confused",
|
||||
":-\\": "confused",
|
||||
":-?": "sweat",
|
||||
":-D": "laughing",
|
||||
":-P": "stuck_out_tongue",
|
||||
":-O": "open_mouth",
|
||||
":-X": "grimacing",
|
||||
":-|": "expressionless",
|
||||
";-)": "wink",
|
||||
"^_^": "smile",
|
||||
":?:": "question",
|
||||
":!:": "exclamation",
|
||||
"LOL": "laughing",
|
||||
}
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.mode = os.path.basename((os.path.dirname(__file__)))
|
||||
|
||||
|
||||
def convert(self, text, config={}):
|
||||
result = text
|
||||
for key, value in Emoji.config.items():
|
||||
result = result.replace(key, ":"+value+":")
|
||||
return result
|
||||
40
any2micronconverter/dokuwiki/headers.py
Normal file
40
any2micronconverter/dokuwiki/headers.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import os
|
||||
from sys import platform
|
||||
from re import compile
|
||||
|
||||
if platform.startswith("win"):
|
||||
from converter import Converter
|
||||
else:
|
||||
from ..converter import Converter
|
||||
|
||||
|
||||
@Converter.register
|
||||
class Header:
|
||||
pattern = compile("(=+)(.*?)(=+)")
|
||||
head = "="
|
||||
config = {
|
||||
"======": 1,
|
||||
"=====": 2,
|
||||
"====": 3,
|
||||
"===": 3,
|
||||
"==": 3,
|
||||
"=": 3
|
||||
}
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.mode = os.path.basename((os.path.dirname(__file__)))
|
||||
|
||||
|
||||
def convert(self, text, config={}):
|
||||
result = text
|
||||
for regex_head in Header.pattern.findall(text):
|
||||
orig_header = "".join(regex_head)
|
||||
src_header = regex_head[0]
|
||||
if src_header in Header.config:
|
||||
new_header = (">" * Header.config[src_header]) + regex_head[1]
|
||||
result = result.replace(orig_header, new_header)
|
||||
else:
|
||||
new_header = (">" * 1) + regex_head[1]
|
||||
result = result.replace(orig_header, new_header)
|
||||
return result
|
||||
62
any2micronconverter/dokuwiki/images.py
Normal file
62
any2micronconverter/dokuwiki/images.py
Normal file
@@ -0,0 +1,62 @@
|
||||
import os
|
||||
from sys import platform
|
||||
from re import compile
|
||||
|
||||
if platform.startswith("win"):
|
||||
from converter import Converter
|
||||
else:
|
||||
from ..converter import Converter
|
||||
|
||||
|
||||
@Converter.register
|
||||
class Images:
|
||||
pattern = compile("{{(\s?)(.*?)(\s?)}}")
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.mode = os.path.basename((os.path.dirname(__file__)))
|
||||
|
||||
|
||||
def parse_style(self, match):
|
||||
style = []
|
||||
left = match[0]
|
||||
src = match[1]
|
||||
right = match[2]
|
||||
|
||||
|
||||
def parse_dimensions():
|
||||
if not "?" in src:
|
||||
return
|
||||
dimensions = src.split("?")[1]
|
||||
if "x" in dimensions:
|
||||
(width, height) = dimensions.split("x")
|
||||
style.append("width: " + width + "px;")
|
||||
style.append("height: " + height + "px;")
|
||||
else:
|
||||
style.append("width: " + dimensions + "px;")
|
||||
|
||||
def parse_position():
|
||||
if len(left) > 0 and len(right) > 0:
|
||||
style.append("margin-left: auto; margin-right: auto;")
|
||||
elif len(left) > 0:
|
||||
style.append("float: left;")
|
||||
elif len(right) > 0:
|
||||
style.append("float: right;")
|
||||
|
||||
parse_position()
|
||||
parse_dimensions()
|
||||
return " ".join(style)
|
||||
|
||||
|
||||
def parse_source(self, src):
|
||||
source = src if not "?" in src else src.split("?")[0]
|
||||
return source.replace(":", "/")
|
||||
|
||||
|
||||
def convert(self, text, config={}):
|
||||
result = text
|
||||
for match in Images.pattern.findall(text):
|
||||
#replaced = "<img style='%s' src='/img/%s'>" % (self.parse_style(match), self.parse_source(match[1]))
|
||||
replaced = ""
|
||||
result = result.replace("{{" + "".join(match) + "}}", replaced)
|
||||
return result
|
||||
99
any2micronconverter/dokuwiki/links.py
Normal file
99
any2micronconverter/dokuwiki/links.py
Normal file
@@ -0,0 +1,99 @@
|
||||
import os
|
||||
import re
|
||||
from os import walk
|
||||
from sys import platform
|
||||
from pathlib import Path
|
||||
|
||||
if platform.startswith("win"):
|
||||
from converter import Converter
|
||||
else:
|
||||
from ..converter import Converter
|
||||
|
||||
|
||||
@Converter.register
|
||||
class Links:
|
||||
pattern = re.compile('(\[\[)(.*?)(\]\])')
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.mode = os.path.basename((os.path.dirname(__file__)))
|
||||
|
||||
|
||||
def convert(self, text, config={}):
|
||||
result = text
|
||||
|
||||
def starts_with_space(match):
|
||||
return match[1][0] == " "
|
||||
|
||||
for regex_link in Links.pattern.findall(text):
|
||||
if starts_with_space(regex_link):
|
||||
continue
|
||||
|
||||
origlink = "".join(regex_link)
|
||||
convertedlink = ""
|
||||
if "http" in origlink or "www" in origlink:
|
||||
convertedlink = self.convert_as_external_link(origlink)
|
||||
elif ">" in origlink and not "<" in origlink:
|
||||
convertedlink = self.convert_as_interwiki_link(origlink)
|
||||
else:
|
||||
convertedlink = self.convert_as_internal_link(origlink, config["file_replace"], config["link_root"])
|
||||
result = result.replace(origlink, convertedlink)
|
||||
return result
|
||||
|
||||
|
||||
def parse_url(self, text):
|
||||
return text[2:text.index('|')]
|
||||
|
||||
|
||||
def parse_title(self, text):
|
||||
return text[text.index('|') + 1: text.index(']]')]
|
||||
|
||||
|
||||
def convert_as_interwiki_link(self, text):
|
||||
interwiki_shortcode = text[2:text.index('>')]
|
||||
#self.assert_interwiki_is_known(interwiki_shortcode)
|
||||
interwiki_urlpart = text[text.index(">") + 1: len(text) - 2]
|
||||
|
||||
return """`[%s`%s]""" % (interwiki_shortcode, interwiki_urlpart)
|
||||
|
||||
def convert_as_internal_link(self, text, file_replace, link_root):
|
||||
url = ""
|
||||
title = ""
|
||||
if "|" not in text:
|
||||
url = text[2:len(text) - 2].replace(":", "/")
|
||||
title = text[2:len(text) - 2].replace(":", "/")
|
||||
else:
|
||||
url = self.parse_url(text).replace(":", "/")
|
||||
title = self.parse_title(text)
|
||||
|
||||
if "." not in url:
|
||||
url = url + ".mu"
|
||||
|
||||
for key, value in file_replace.items():
|
||||
url = url.replace(key, value)
|
||||
|
||||
if not url.endswith(".mu"):
|
||||
url += ".mu"
|
||||
if not url.startswith("/"):
|
||||
url = "/"+url
|
||||
|
||||
return """`[%s`%s%s]""" % (title, link_root, url.replace(' ', '_'))
|
||||
|
||||
|
||||
def convert_as_external_link(self, text):
|
||||
if "|" in text:
|
||||
url = self.parse_url(text)
|
||||
title = self.parse_title(text)
|
||||
return "`[" + title + "`" + url + "]"
|
||||
url = text.replace('[', '').replace(']', '')
|
||||
return "`[" + url + "`" + url + "]"
|
||||
|
||||
|
||||
def assert_interwiki_is_known(self, shortcode):
|
||||
shortcodes = []
|
||||
shortcodes_path = Path(__file__).parents[2].joinpath('layouts/shortcodes')
|
||||
for (dirpath, dirnames, filenames) in walk(shortcodes_path):
|
||||
shortcodes.extend(filenames)
|
||||
break
|
||||
if not (shortcode in map(lambda x: x.replace(".html", ""), shortcodes)):
|
||||
raise ValueError("Unknown Interwiki code " + shortcode + " - please add a shortcode in the layouts dir!")
|
||||
70
any2micronconverter/dokuwiki/lists.py
Normal file
70
any2micronconverter/dokuwiki/lists.py
Normal file
@@ -0,0 +1,70 @@
|
||||
import os
|
||||
import re
|
||||
from sys import platform
|
||||
|
||||
if platform.startswith("win"):
|
||||
from converter import Converter
|
||||
else:
|
||||
from ..converter import Converter
|
||||
|
||||
|
||||
@Converter.register
|
||||
class OrderedList:
|
||||
pattern = re.compile('(^(\s*)-\s)(.*)', re.MULTILINE)
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.mode = os.path.basename((os.path.dirname(__file__)))
|
||||
|
||||
|
||||
def convert(self, text, config={}):
|
||||
lines = text.split('\n')
|
||||
last_used_linenrs = []
|
||||
index = 0
|
||||
result = text
|
||||
|
||||
def deeper_depth(depth):
|
||||
return list(filter(lambda x: x[0] > depth, last_used_linenrs))
|
||||
|
||||
def drop_in_depth_detected(depth):
|
||||
return len(deeper_depth(depth)) > 0
|
||||
|
||||
def remove_deeper_depths(depth):
|
||||
for itm in deeper_depth(depth):
|
||||
last_used_linenrs.remove(itm)
|
||||
|
||||
def last_used_by_depth(depth):
|
||||
return list(filter(lambda x: x[0] == depth, last_used_linenrs))
|
||||
|
||||
def last_used_index(depth):
|
||||
return last_used_by_depth(depth)[0][2]
|
||||
|
||||
def last_used_linenr(depth):
|
||||
linenr_result = last_used_by_depth(depth)
|
||||
if len(linenr_result) == 0:
|
||||
return 0
|
||||
return linenr_result[0][1]
|
||||
|
||||
def set_last_used_linenr(depth, linenr, the_index):
|
||||
last_used_result = list(filter(lambda x: x[0] == depth, last_used_linenrs))
|
||||
if len(last_used_result) > 0:
|
||||
last_used_linenrs.remove(last_used_result[0])
|
||||
last_used_linenrs.append((depth, linenr, the_index))
|
||||
|
||||
for match in OrderedList.pattern.findall(text):
|
||||
current_line = (match[0] + match[2]).replace('\n', '')
|
||||
current_depth = len(match[1].replace('\n', ''))
|
||||
current_linenr = lines.index(current_line)
|
||||
|
||||
if last_used_linenr(current_depth) + 1 is current_linenr:
|
||||
index += 1
|
||||
elif drop_in_depth_detected(current_depth):
|
||||
index = last_used_index(current_depth) + 1
|
||||
remove_deeper_depths(current_depth)
|
||||
else:
|
||||
index = 1
|
||||
set_last_used_linenr(current_depth, current_linenr, index)
|
||||
|
||||
result = result.replace(current_line, match[1].replace('\n', '') + str(index) + '. ' + match[2])
|
||||
|
||||
return result
|
||||
98
any2micronconverter/dokuwiki/simplestyle.py
Normal file
98
any2micronconverter/dokuwiki/simplestyle.py
Normal file
@@ -0,0 +1,98 @@
|
||||
import os
|
||||
from sys import platform
|
||||
from re import compile
|
||||
from abc import ABC
|
||||
|
||||
if platform.startswith("win"):
|
||||
from converter import Converter
|
||||
else:
|
||||
from ..converter import Converter
|
||||
|
||||
|
||||
class NopStyle(ABC):
|
||||
def convert(self, text, config={}):
|
||||
return text
|
||||
|
||||
|
||||
class SimpleReplacementStyle(ABC):
|
||||
def __init__(self, dst_style, src_style):
|
||||
self.mode = os.path.basename((os.path.dirname(__file__)))
|
||||
self.dst_style = dst_style
|
||||
self.src_style = src_style
|
||||
|
||||
def convert(self, text, config={}):
|
||||
return text.replace(self.src_style, self.dst_style)
|
||||
|
||||
|
||||
class SimpleStyleBetweenTags(ABC):
|
||||
def __init__(self, dst_style, src_style_begin, src_style_end=None):
|
||||
self.mode = os.path.basename((os.path.dirname(__file__)))
|
||||
if src_style_end is None:
|
||||
src_style_end = src_style_begin
|
||||
self.pattern = compile("("+src_style_begin+")(.*?)("+src_style_end+")")
|
||||
self.dst_style = dst_style
|
||||
|
||||
def convert(self, text, config={}):
|
||||
result = text
|
||||
for regex_head in self.pattern.findall(text):
|
||||
orig_header = "".join(regex_head)
|
||||
new_header = self.dst_style + regex_head[1] + self.dst_style
|
||||
result = result.replace(orig_header, new_header)
|
||||
return result
|
||||
|
||||
|
||||
@Converter.register
|
||||
class InlineHtml:
|
||||
def __init__(self):
|
||||
self.mode = os.path.basename((os.path.dirname(__file__)))
|
||||
|
||||
def convert(self, text, config={}):
|
||||
return text.replace("<html>", "").replace("</html>", "")
|
||||
|
||||
|
||||
@Converter.register
|
||||
class LineBreak(SimpleStyleBetweenTags):
|
||||
def __init__(self):
|
||||
super().__init__("\n", "\\\\ ?")
|
||||
|
||||
|
||||
@Converter.register
|
||||
class Bold(SimpleStyleBetweenTags):
|
||||
def __init__(self):
|
||||
super().__init__("`!", "\*\*")
|
||||
|
||||
|
||||
@Converter.register
|
||||
class Italic(SimpleStyleBetweenTags):
|
||||
def __init__(self):
|
||||
super().__init__("`*", "//")
|
||||
|
||||
|
||||
@Converter.register
|
||||
class Underline(SimpleStyleBetweenTags):
|
||||
def __init__(self):
|
||||
super().__init__("`_", "__")
|
||||
|
||||
|
||||
@Converter.register
|
||||
class StrikeThrough(SimpleStyleBetweenTags):
|
||||
def __init__(self):
|
||||
super().__init__("~", "<del>", "</del>")
|
||||
|
||||
|
||||
@Converter.register
|
||||
class Subscript(SimpleStyleBetweenTags):
|
||||
def __init__(self):
|
||||
super().__init__("", "<sub>", "</sub>")
|
||||
|
||||
|
||||
@Converter.register
|
||||
class Superscript(SimpleStyleBetweenTags):
|
||||
def __init__(self):
|
||||
super().__init__("", "<sup>", "</sup>")
|
||||
|
||||
|
||||
@Converter.register
|
||||
class InlineCode(SimpleStyleBetweenTags):
|
||||
def __init__(self):
|
||||
super().__init__("", "''", "''")
|
||||
27
any2micronconverter/dokuwiki/todo.py
Normal file
27
any2micronconverter/dokuwiki/todo.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import os
|
||||
from sys import platform
|
||||
from re import compile
|
||||
|
||||
if platform.startswith("win"):
|
||||
from converter import Converter
|
||||
else:
|
||||
from ..converter import Converter
|
||||
|
||||
|
||||
@Converter.register
|
||||
class Todo:
|
||||
pattern = compile("(<todo(\s#)?>)(.*?)(</todo>)")
|
||||
todo = "- [ ] "
|
||||
done = "- [x] "
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.mode = os.path.basename((os.path.dirname(__file__)))
|
||||
|
||||
|
||||
def convert(self, text, config={}):
|
||||
result = text
|
||||
for match in Todo.pattern.findall(text):
|
||||
prefix = Todo.todo if match[1] == "" else Todo.done
|
||||
result = result.replace(match[0]+match[2]+match[3], prefix+match[2])
|
||||
return result
|
||||
29
any2micronconverter/dokuwiki/z_cleanup.py
Normal file
29
any2micronconverter/dokuwiki/z_cleanup.py
Normal file
@@ -0,0 +1,29 @@
|
||||
import os
|
||||
import re
|
||||
from sys import platform
|
||||
|
||||
if platform.startswith("win"):
|
||||
from converter import Converter
|
||||
else:
|
||||
from ..converter import Converter
|
||||
|
||||
|
||||
@Converter.register
|
||||
class Cleanup:
|
||||
def __init__(self):
|
||||
self.mode = os.path.basename((os.path.dirname(__file__)))
|
||||
|
||||
|
||||
def convert(self, text, config={}):
|
||||
result = text
|
||||
|
||||
# Lines with spaces and tabs only
|
||||
result = re.sub(r"^[ \t]+$", "", result, flags=re.MULTILINE)
|
||||
|
||||
# Lines with tabs and spaces at the end
|
||||
result = re.sub(r"[ \t]+$", "", result, flags=re.MULTILINE)
|
||||
|
||||
# Replace more than two consecutive empty lines
|
||||
result = re.sub(r"\n\s*\n\s*\n+", "\n\n\n", result, flags=re.MULTILINE)
|
||||
|
||||
return result
|
||||
291
any2micronconverter/main.py
Executable file
291
any2micronconverter/main.py
Executable file
@@ -0,0 +1,291 @@
|
||||
##############################################################################################################
|
||||
#
|
||||
# Copyright (c) 2023 Sebastian Obele / obele.eu
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# This software uses the following software-parts:
|
||||
# dokuwiki-to-hugo / Copyright (c) 2017 Wouter Groeneveld / https://git.brainbaking.com/wgroeneveld/dokuwiki-to-hugo / MIT License
|
||||
#
|
||||
##############################################################################################################
|
||||
|
||||
|
||||
##############################################################################################################
|
||||
# Include
|
||||
|
||||
|
||||
#### System ####
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import argparse
|
||||
import shutil
|
||||
|
||||
if sys.platform.startswith("win"):
|
||||
#### Version ####
|
||||
from _version import __version__, __version_variant__, __copyright_short__, __title__, __description__, __config__
|
||||
|
||||
#### Converter ####
|
||||
from converter import Converter
|
||||
|
||||
#### Commands - dokuwiki ####
|
||||
from dokuwiki.code import *
|
||||
from dokuwiki.comments import *
|
||||
from dokuwiki.emoji import *
|
||||
from dokuwiki.headers import *
|
||||
from dokuwiki.images import *
|
||||
from dokuwiki.links import *
|
||||
from dokuwiki.lists import *
|
||||
from dokuwiki.simplestyle import *
|
||||
from dokuwiki.todo import *
|
||||
from dokuwiki.z_cleanup import *
|
||||
else:
|
||||
#### Version ####
|
||||
from ._version import __version__, __version_variant__, __copyright_short__, __title__, __description__, __config__
|
||||
|
||||
#### Converter ####
|
||||
from .converter import Converter
|
||||
|
||||
#### Commands - dokuwiki ####
|
||||
from .dokuwiki.code import *
|
||||
from .dokuwiki.comments import *
|
||||
from .dokuwiki.emoji import *
|
||||
from .dokuwiki.headers import *
|
||||
from .dokuwiki.images import *
|
||||
from .dokuwiki.links import *
|
||||
from .dokuwiki.lists import *
|
||||
from .dokuwiki.simplestyle import *
|
||||
from .dokuwiki.todo import *
|
||||
from .dokuwiki.z_cleanup import *
|
||||
|
||||
|
||||
##############################################################################################################
|
||||
# Globals
|
||||
|
||||
|
||||
PATH = os.path.expanduser("~") + "/." + os.path.splitext(os.path.basename(__file__))[0]
|
||||
|
||||
|
||||
##############################################################################################################
|
||||
# Log
|
||||
|
||||
|
||||
LOG_FORCE = -1
|
||||
LOG_CRITICAL = 0
|
||||
LOG_ERROR = 1
|
||||
LOG_WARNING = 2
|
||||
LOG_NOTICE = 3
|
||||
LOG_INFO = 4
|
||||
LOG_VERBOSE = 5
|
||||
LOG_DEBUG = 6
|
||||
LOG_EXTREME = 7
|
||||
|
||||
LOG_LEVEL = LOG_NOTICE
|
||||
LOG_LEVEL_SERVICE = LOG_NOTICE
|
||||
LOG_TIMEFMT = "%Y-%m-%d %H:%M:%S"
|
||||
LOG_MAXSIZE = 5*1024*1024
|
||||
LOG_PREFIX = ""
|
||||
LOG_SUFFIX = ""
|
||||
LOG_FILE = ""
|
||||
|
||||
|
||||
def log(text, level=3, file=None):
|
||||
if not LOG_LEVEL:
|
||||
return
|
||||
|
||||
if LOG_LEVEL >= level:
|
||||
name = "Unknown"
|
||||
if (level == LOG_FORCE):
|
||||
name = ""
|
||||
if (level == LOG_CRITICAL):
|
||||
name = "Critical"
|
||||
if (level == LOG_ERROR):
|
||||
name = "Error"
|
||||
if (level == LOG_WARNING):
|
||||
name = "Warning"
|
||||
if (level == LOG_NOTICE):
|
||||
name = "Notice"
|
||||
if (level == LOG_INFO):
|
||||
name = "Info"
|
||||
if (level == LOG_VERBOSE):
|
||||
name = "Verbose"
|
||||
if (level == LOG_DEBUG):
|
||||
name = "Debug"
|
||||
if (level == LOG_EXTREME):
|
||||
name = "Extra"
|
||||
|
||||
if not isinstance(text, str):
|
||||
text = str(text)
|
||||
|
||||
text = "[" + time.strftime(LOG_TIMEFMT, time.localtime(time.time())) +"] [" + name + "] " + LOG_PREFIX + text + LOG_SUFFIX
|
||||
|
||||
if file == None and LOG_FILE != "":
|
||||
file = LOG_FILE
|
||||
|
||||
if file == None:
|
||||
print(text)
|
||||
else:
|
||||
try:
|
||||
file_handle = open(file, "a")
|
||||
file_handle.write(text + "\n")
|
||||
file_handle.close()
|
||||
|
||||
if os.path.getsize(file) > LOG_MAXSIZE:
|
||||
file_prev = file + ".1"
|
||||
if os.path.isfile(file_prev):
|
||||
os.unlink(file_prev)
|
||||
os.rename(file, file_prev)
|
||||
except:
|
||||
return
|
||||
|
||||
|
||||
##############################################################################################################
|
||||
# System
|
||||
|
||||
|
||||
#### Panic #####
|
||||
def panic():
|
||||
sys.exit(255)
|
||||
|
||||
|
||||
#### Exit #####
|
||||
def exit():
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
##############################################################################################################
|
||||
# Setup/Start
|
||||
|
||||
|
||||
#### Setup #####
|
||||
def setup(mode=None, src=None, dst=None, loglevel=None, test=False, link_root=None, header=None, footer=None):
|
||||
global LOG_LEVEL
|
||||
|
||||
config = __config__
|
||||
|
||||
if loglevel is not None:
|
||||
LOG_LEVEL = loglevel
|
||||
|
||||
log("...............................................................................", LOG_INFO)
|
||||
log(" Name: " + __title__ + " - " + __description__, LOG_INFO)
|
||||
log("Program File: " + __file__, LOG_INFO)
|
||||
log(" Version: " + __version__ + " " + __version_variant__, LOG_INFO)
|
||||
log(" Copyright: " + __copyright_short__, LOG_INFO)
|
||||
log("...............................................................................", LOG_INFO)
|
||||
|
||||
if src == None or dst == None:
|
||||
log("Missing parameters", LOG_ERROR)
|
||||
return
|
||||
|
||||
if src.endswith("/"):
|
||||
src = src[:-1]
|
||||
|
||||
if dst.endswith("/"):
|
||||
dst = dst[:-1]
|
||||
|
||||
if test:
|
||||
log(" Test mode: YES", LOG_NOTICE)
|
||||
|
||||
log(" Mode: " + str(mode), LOG_NOTICE)
|
||||
log(" Source path: " + src, LOG_NOTICE)
|
||||
log(" Dest path: " + dst, LOG_NOTICE)
|
||||
|
||||
if link_root:
|
||||
config["link_root"] = link_root
|
||||
if config["link_root"].endswith("/"):
|
||||
config["link_root"] = config["link_root"][:-1]
|
||||
|
||||
if header:
|
||||
config["header"] = header
|
||||
config["header"] = config["header"].replace("\\n", '\n')
|
||||
|
||||
if footer:
|
||||
config["footer"] = footer
|
||||
config["footer"] = config["footer"].replace("\\n", '\n')
|
||||
|
||||
if os.path.exists(dst):
|
||||
log("Deleting dest directory "+dst, LOG_DEBUG)
|
||||
if not test:
|
||||
shutil.rmtree(dst)
|
||||
if not test:
|
||||
os.makedirs(dst)
|
||||
|
||||
for root, subFolders, files in os.walk(src):
|
||||
dst_dir = dst+root.replace(src, "", 1)
|
||||
if dst_dir.endswith("/"):
|
||||
dst_dir = dst_dir[:-1]
|
||||
files = [f for f in files if not f[0] == '.']
|
||||
for file in files:
|
||||
try:
|
||||
src_file = root+"/"+file
|
||||
|
||||
if file in config["file_replace"]:
|
||||
dst_file = config["file_replace"][file]
|
||||
else:
|
||||
dst_file = os.path.splitext(file)[0] + ".mu"
|
||||
|
||||
log("Converting "+dst_dir+"/"+dst_file+" ("+str(mode)+")", LOG_DEBUG)
|
||||
|
||||
if not os.path.exists(dst_dir):
|
||||
os.makedirs(dst_dir)
|
||||
|
||||
output = Converter(src_file, config, mode).convert()
|
||||
except Exception as e:
|
||||
log("Failed to convert "+file+": "+str(e), LOG_ERROR)
|
||||
output = "Failed to convert: "+str(e)
|
||||
|
||||
try:
|
||||
output = config["header"] + output + config["footer"]
|
||||
if not test:
|
||||
with open(dst_dir+"/"+dst_file, "w", newline="\n") as fh:
|
||||
fh.write(output)
|
||||
except Exception as e:
|
||||
log("Failed to write "+file+": "+str(e), LOG_ERROR)
|
||||
|
||||
|
||||
#### Start ####
|
||||
def main():
|
||||
try:
|
||||
description = __title__ + " - " + __description__
|
||||
parser = argparse.ArgumentParser(description=description)
|
||||
|
||||
parser.add_argument("-m", "--mode", action="store", type=str, default=None, help="Mode or type of source data for conversion (Folder name with the command files)")
|
||||
parser.add_argument("-s", "--src", action="store", type=str, default=None, help="Path to source directory (All subfolders are included)")
|
||||
parser.add_argument("-d", "--dst", action="store", type=str, default=None, help="Path to destination directory (Folder is overwritten/deleted)")
|
||||
parser.add_argument("-l", "--loglevel", action="store", type=int, default=LOG_LEVEL)
|
||||
parser.add_argument("-t", "--test", action="store_true", default=False, help="Running in test mode (No files are deleted or overwritten)")
|
||||
parser.add_argument("--link_root", action="store", type=str, default=None, help="Root path of the links (Internal links in the documents)")
|
||||
parser.add_argument("--header", action="store", type=str, default=None, help="Header string which will be added on all pages")
|
||||
parser.add_argument("--footer", action="store", type=str, default=None, help="Footer string which will be added on all pages")
|
||||
|
||||
params = parser.parse_args()
|
||||
|
||||
setup(mode=params.mode, src=params.src, dst=params.dst, loglevel=params.loglevel, test=params.test, link_root=params.link_root, header=params.header, footer=params.footer)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("Terminated by CTRL-C")
|
||||
exit()
|
||||
|
||||
|
||||
##############################################################################################################
|
||||
# Init
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
101
any2micronconverter/main.spec
Normal file
101
any2micronconverter/main.spec
Normal file
@@ -0,0 +1,101 @@
|
||||
##############################################################################################################
|
||||
#
|
||||
# Copyright (c) 2023 Sebastian Obele / obele.eu
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# This software uses the following software-parts:
|
||||
# dokuwiki-to-hugo / Copyright (c) 2017 Wouter Groeneveld / https://git.brainbaking.com/wgroeneveld/dokuwiki-to-hugo / MIT License
|
||||
#
|
||||
##############################################################################################################
|
||||
|
||||
|
||||
#### Import ####
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
import pyinstaller_versionfile
|
||||
#from kivy_deps import sdl2, glew
|
||||
#from kivymd import hooks_path as kivymd_hooks_path
|
||||
|
||||
|
||||
#### Get Var ####
|
||||
def get_var(file, var) -> str:
|
||||
content = open(file, "rt", encoding="utf-8").read()
|
||||
try:
|
||||
regex = r"(?<=^"+var+" = ['\"])[^'\"]+(?=['\"]$)"
|
||||
value = re.findall(regex, content, re.M)[0]
|
||||
return value
|
||||
except IndexError:
|
||||
raise ValueError(f"Unable to find string {var} in {file}.")
|
||||
return ""
|
||||
|
||||
|
||||
#### Build ####
|
||||
path = os.path.abspath(".")
|
||||
|
||||
version_file = "_version.py"
|
||||
main_file = "main.py"
|
||||
|
||||
pyinstaller_versionfile.create_versionfile(
|
||||
output_file="version.rc",
|
||||
version=get_var(version_file, "__version__")+".0",
|
||||
company_name=get_var(version_file, "__author__"),
|
||||
file_description=get_var(version_file, "__description__"),
|
||||
internal_name=get_var(version_file, "__title__"),
|
||||
legal_copyright=get_var(version_file, "__copyright_short__"),
|
||||
original_filename=get_var(version_file, "__title__")+".exe",
|
||||
product_name=get_var(version_file, "__title__")
|
||||
)
|
||||
|
||||
added_files = [
|
||||
# ("assets", "assets"),
|
||||
]
|
||||
|
||||
a = Analysis(
|
||||
[main_file],
|
||||
pathex=[path],
|
||||
#hiddenimports=["plyer.platforms.win.storagepath"],
|
||||
#hookspath=[kivymd_hooks_path],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=None,
|
||||
noarchive=False,
|
||||
datas=added_files,
|
||||
)
|
||||
|
||||
pyz = PYZ(a.pure, a.zipped_data, cipher=None)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
#*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
|
||||
debug=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
name=get_var(version_file, "__package_name__")+"-"+get_var(version_file, "__version__"),
|
||||
#icon="assets\icon.ico",
|
||||
console=True,
|
||||
version="version.rc",
|
||||
)
|
||||
184
build_git.sh
Executable file
184
build_git.sh
Executable file
@@ -0,0 +1,184 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
##############################################################################################################
|
||||
# Configuration
|
||||
|
||||
|
||||
BRANCH="main"
|
||||
ORIGIN="git@github.com:SebastianObi/Any2MicronConverter.git"
|
||||
FILES_ADD=("*")
|
||||
FILES_REMOVE=(".git/*")
|
||||
COMMENT_COMMIT="$(date +%Y-%m-%d_%H:%M:%S)"
|
||||
COMMENT_CLEAR="Removed history, due to sensitive data"
|
||||
COMMENT_INIT="Initial commit"
|
||||
|
||||
|
||||
##############################################################################################################
|
||||
# Functions
|
||||
|
||||
|
||||
_prompt() {
|
||||
echo -e ""
|
||||
echo -e "Select an option:"
|
||||
options=("Commit/Push" "Clear History" "Init" "Init (Pull only)" "Init (Push only)" "Exit")
|
||||
select opt in "${options[@]}"; do
|
||||
case $opt in
|
||||
"Commit/Push"*)
|
||||
_commit
|
||||
break;;
|
||||
"Clear History"*)
|
||||
_clear
|
||||
break;;
|
||||
"Init (Pull only)"*)
|
||||
_init_pull
|
||||
break;;
|
||||
"Init (Push only)"*)
|
||||
_init_push
|
||||
break;;
|
||||
"Init"*)
|
||||
_init
|
||||
break;;
|
||||
"Exit"*)
|
||||
echo -e ""
|
||||
echo -e "Exit"
|
||||
break;;
|
||||
*)
|
||||
echo -e "Invalid choice!"
|
||||
break;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
_define_files() {
|
||||
for file in ${FILES_ADD[@]}; do
|
||||
git add "${file}"
|
||||
done
|
||||
|
||||
for file in ${FILES_REMOVE[@]}; do
|
||||
git reset -- "${file}"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
_commit() {
|
||||
_define_files
|
||||
|
||||
git diff --numstat
|
||||
|
||||
echo -e ""
|
||||
echo -e "Commit/Push to Git"
|
||||
echo -e "Comment:"
|
||||
|
||||
read VAR
|
||||
if [ -z "${VAR}" ]; then
|
||||
VAR="${COMMENT_COMMIT}"
|
||||
fi
|
||||
|
||||
git commit -a -m "${VAR}"
|
||||
git push
|
||||
}
|
||||
|
||||
|
||||
_clear() {
|
||||
echo -e ""
|
||||
echo -e "Clear History"
|
||||
echo -e "Comment:"
|
||||
|
||||
read VAR
|
||||
if [ -z "${VAR}" ]; then
|
||||
VAR="${COMMENT_CLEAR}"
|
||||
fi
|
||||
|
||||
rm -rf .git
|
||||
|
||||
git init
|
||||
|
||||
_define_files
|
||||
|
||||
git commit -m "${VAR}"
|
||||
git branch -M "${BRANCH}"
|
||||
git remote add origin "${ORIGIN}"
|
||||
git push -f -u origin "${BRANCH}"
|
||||
}
|
||||
|
||||
|
||||
_init() {
|
||||
echo -e ""
|
||||
echo -e "Init"
|
||||
echo -e "Comment:"
|
||||
|
||||
read VAR
|
||||
if [ -z "${VAR}" ]; then
|
||||
VAR="${COMMENT_INIT}"
|
||||
fi
|
||||
|
||||
rm -rf .git
|
||||
|
||||
git init
|
||||
|
||||
_define_files
|
||||
|
||||
git branch -M "${BRANCH}"
|
||||
git remote add origin "${ORIGIN}"
|
||||
|
||||
git pull origin "${BRANCH}"
|
||||
|
||||
git commit -m "${VAR}"
|
||||
|
||||
git push -f -u origin "${BRANCH}"
|
||||
}
|
||||
|
||||
|
||||
_init_pull() {
|
||||
echo -e ""
|
||||
echo -e "Init (Pull only)"
|
||||
|
||||
read VAR
|
||||
if [ -z "${VAR}" ]; then
|
||||
VAR="${COMMENT_INIT}"
|
||||
fi
|
||||
|
||||
rm -rf .git
|
||||
|
||||
git init
|
||||
|
||||
_define_files
|
||||
|
||||
git branch -M "${BRANCH}"
|
||||
git remote add origin "${ORIGIN}"
|
||||
|
||||
git pull origin "${BRANCH}"
|
||||
|
||||
git push -f -u origin "${BRANCH}"
|
||||
}
|
||||
|
||||
|
||||
_init_push() {
|
||||
echo -e ""
|
||||
echo -e "Init (Push only)"
|
||||
|
||||
read VAR
|
||||
if [ -z "${VAR}" ]; then
|
||||
VAR="${COMMENT_INIT}"
|
||||
fi
|
||||
|
||||
rm -rf .git
|
||||
|
||||
git init
|
||||
|
||||
_define_files
|
||||
|
||||
git branch -M "${BRANCH}"
|
||||
git remote add origin "${ORIGIN}"
|
||||
|
||||
git push -f -u origin "${BRANCH}"
|
||||
}
|
||||
|
||||
|
||||
##############################################################################################################
|
||||
# Setup/Start
|
||||
|
||||
|
||||
_prompt
|
||||
100
setup.py
Normal file
100
setup.py
Normal file
@@ -0,0 +1,100 @@
|
||||
##############################################################################################################
|
||||
#
|
||||
# Copyright (c) 2023 Sebastian Obele / obele.eu
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# This software uses the following software-parts:
|
||||
# dokuwiki-to-hugo / Copyright (c) 2017 Wouter Groeneveld / https://git.brainbaking.com/wgroeneveld/dokuwiki-to-hugo / MIT License
|
||||
#
|
||||
##############################################################################################################
|
||||
|
||||
|
||||
#### Import ####
|
||||
import os
|
||||
import re
|
||||
import setuptools
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
#### Get Var ####
|
||||
def get_var(file, var) -> str:
|
||||
content = open(file, "rt", encoding="utf-8").read()
|
||||
try:
|
||||
regex = r"(?<=^"+var+" = ['\"])[^'\"]+(?=['\"]$)"
|
||||
value = re.findall(regex, content, re.M)[0]
|
||||
return value
|
||||
except IndexError:
|
||||
raise ValueError(f"Unable to find string {var} in {file}.")
|
||||
return ""
|
||||
|
||||
|
||||
#### Build ####
|
||||
with open("README.md", "r") as fh:
|
||||
long_description = fh.read()
|
||||
|
||||
version_file = os.path.join(os.path.dirname(__file__), "any2micronconverter", "_version.py")
|
||||
|
||||
def glob_converter():
|
||||
out_files = []
|
||||
src_path = os.path.join(os.path.dirname(__file__), "any2micronconverter")
|
||||
for root, dirs, files in os.walk(src_path):
|
||||
for file in files:
|
||||
filepath = os.path.join(str(Path(*Path(root).parts[1:])), file)
|
||||
print(filepath)
|
||||
out_files.append(filepath.split(f"any2micronconverter{os.sep}")[1])
|
||||
return out_files
|
||||
|
||||
package_data = {
|
||||
"": [
|
||||
"assets/*",
|
||||
*glob_converter()
|
||||
]
|
||||
}
|
||||
|
||||
print("Packaging "+get_var(version_file, "__title__")+" "+get_var(version_file, "__version__")+" "+get_var(version_file, "__version_variant__"))
|
||||
|
||||
setuptools.setup(
|
||||
name=get_var(version_file, "__package_name__"),
|
||||
version=get_var(version_file, "__version__"),
|
||||
author=get_var(version_file, "__author__"),
|
||||
author_email=get_var(version_file, "__author_email__"),
|
||||
description=get_var(version_file, "__description__"),
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
url=get_var(version_file, "__copyright_url__"),
|
||||
packages=setuptools.find_packages(),
|
||||
package_data=package_data,
|
||||
include_package_data=True,
|
||||
classifiers=[
|
||||
"Programming Language :: Python :: 3",
|
||||
"License :: Other/Proprietary License",
|
||||
"Operating System :: OS Independent",
|
||||
],
|
||||
entry_points= {
|
||||
'console_scripts': [
|
||||
get_var(version_file, "__package_name__")+'=any2micronconverter.main:main',
|
||||
]
|
||||
},
|
||||
install_requires=[],
|
||||
extras_require={
|
||||
"macos": ["pyobjus"],
|
||||
},
|
||||
python_requires='>=3.6',
|
||||
)
|
||||
Reference in New Issue
Block a user