2019-09-09 22:42:38 -05:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
# == Rapid Develop Macros in LibreOffice ==
|
|
|
|
|
|
|
|
# ~ This file is part of ZAZ.
|
|
|
|
|
|
|
|
# ~ ZAZ is free software: you can redistribute it and/or modify
|
|
|
|
# ~ it under the terms of the GNU General Public License as published by
|
|
|
|
# ~ the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# ~ (at your option) any later version.
|
|
|
|
|
|
|
|
# ~ ZAZ is distributed in the hope that it will be useful,
|
|
|
|
# ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# ~ GNU General Public License for more details.
|
|
|
|
|
|
|
|
# ~ You should have received a copy of the GNU General Public License
|
|
|
|
# ~ along with ZAZ. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
import os
|
2019-11-10 15:25:24 -06:00
|
|
|
import re
|
2019-09-09 22:42:38 -05:00
|
|
|
import sys
|
2019-11-10 15:25:24 -06:00
|
|
|
import zipfile
|
|
|
|
from datetime import datetime
|
2019-09-16 10:42:29 -05:00
|
|
|
from pathlib import Path
|
2019-09-09 22:42:38 -05:00
|
|
|
from shutil import copyfile
|
|
|
|
from subprocess import call
|
2019-11-10 15:25:24 -06:00
|
|
|
from xml.etree import ElementTree as ET
|
|
|
|
from xml.dom.minidom import parseString
|
|
|
|
|
2019-09-09 22:42:38 -05:00
|
|
|
|
|
|
|
from conf import (
|
|
|
|
DATA,
|
|
|
|
DIRS,
|
2019-11-10 15:25:24 -06:00
|
|
|
DOMAIN,
|
2019-09-09 22:42:38 -05:00
|
|
|
EXTENSION,
|
|
|
|
FILES,
|
|
|
|
INFO,
|
|
|
|
PATHS,
|
|
|
|
TYPE_EXTENSION,
|
2019-09-16 10:42:29 -05:00
|
|
|
USE_LOCALES,
|
2019-09-09 22:42:38 -05:00
|
|
|
log)
|
|
|
|
|
|
|
|
|
2019-11-10 15:25:24 -06:00
|
|
|
class LiboXML(object):
|
|
|
|
TYPES = {
|
|
|
|
'py': 'application/vnd.sun.star.uno-component;type=Python',
|
|
|
|
'zip': 'application/binary',
|
|
|
|
'xcu': 'application/vnd.sun.star.configuration-data',
|
|
|
|
'rdb': 'application/vnd.sun.star.uno-typelibrary;type=RDB',
|
|
|
|
'xcs': 'application/vnd.sun.star.configuration-schema',
|
|
|
|
'help': 'application/vnd.sun.star.help',
|
|
|
|
'component': 'application/vnd.sun.star.uno-components',
|
|
|
|
}
|
|
|
|
NAME_SPACES = {
|
|
|
|
'manifest_version': '1.2',
|
|
|
|
'manifest': 'urn:oasis:names:tc:opendocument:xmlns:manifest:1.0',
|
|
|
|
'xmlns:loext': 'urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0',
|
|
|
|
}
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
self._manifest = None
|
|
|
|
self._paths = []
|
|
|
|
|
|
|
|
def _save_path(self, attr):
|
|
|
|
self._paths.append(attr['{{{}}}full-path'.format(self.NAME_SPACES['manifest'])])
|
|
|
|
return
|
|
|
|
|
|
|
|
def _clean(self, name, nodes):
|
|
|
|
has_words = re.compile('\\w')
|
|
|
|
|
|
|
|
if not re.search(has_words, str(nodes.tail)):
|
|
|
|
nodes.tail = ''
|
|
|
|
if not re.search(has_words, str(nodes.text)):
|
|
|
|
nodes.text = ''
|
|
|
|
|
|
|
|
for node in nodes:
|
|
|
|
if name == 'manifest':
|
|
|
|
self._save_path(node.attrib)
|
|
|
|
if not re.search(has_words, str(node.tail)):
|
|
|
|
node.tail = ''
|
|
|
|
if not re.search(has_words, str(node.text)):
|
|
|
|
node.text = ''
|
|
|
|
return
|
|
|
|
|
|
|
|
def new_manifest(self, data):
|
|
|
|
attr = {
|
|
|
|
'manifest:version': self.NAME_SPACES['manifest_version'],
|
|
|
|
'xmlns:manifest': self.NAME_SPACES['manifest'],
|
|
|
|
'xmlns:loext': self.NAME_SPACES['xmlns:loext'],
|
|
|
|
}
|
|
|
|
self._manifest = ET.Element('manifest:manifest', attr)
|
|
|
|
return self.add_data_manifest(data)
|
|
|
|
|
|
|
|
def parse_manifest(self, data):
|
|
|
|
ET.register_namespace('manifest', self.NAME_SPACES['manifest'])
|
|
|
|
self._manifest = ET.fromstring(data)
|
|
|
|
data = {'xmlns:loext': self.NAME_SPACES['xmlns:loext']}
|
|
|
|
self._manifest.attrib.update(**data)
|
|
|
|
self._clean('manifest', self._manifest)
|
|
|
|
return
|
|
|
|
|
|
|
|
def add_data_manifest(self, data):
|
|
|
|
node_name = 'manifest:file-entry'
|
|
|
|
attr = {
|
|
|
|
'manifest:full-path': '',
|
|
|
|
'manifest:media-type': '',
|
|
|
|
}
|
|
|
|
for path in data:
|
|
|
|
if path in self._paths:
|
|
|
|
continue
|
|
|
|
ext = path.split('.')[-1]
|
|
|
|
attr['manifest:full-path'] = path
|
|
|
|
attr['manifest:media-type'] = self.TYPES.get(ext, '')
|
|
|
|
ET.SubElement(self._manifest, node_name, attr)
|
|
|
|
return self._get_xml(self._manifest)
|
|
|
|
|
|
|
|
def _get_xml(self, doc):
|
|
|
|
xml = parseString(ET.tostring(doc, encoding='utf-8'))
|
|
|
|
return xml.toprettyxml(indent=' ', encoding='utf-8').decode('utf-8')
|
|
|
|
|
|
|
|
|
2019-09-09 22:42:38 -05:00
|
|
|
def _exists(path):
|
|
|
|
return os.path.exists(path)
|
|
|
|
|
|
|
|
|
|
|
|
def _join(*paths):
|
|
|
|
return os.path.join(*paths)
|
|
|
|
|
|
|
|
|
|
|
|
def _mkdir(path):
|
2019-09-16 10:42:29 -05:00
|
|
|
return Path(path).mkdir(parents=True, exist_ok=True)
|
2019-09-09 22:42:38 -05:00
|
|
|
|
|
|
|
|
|
|
|
def _save(path, data):
|
|
|
|
with open(path, 'w') as f:
|
|
|
|
f.write(data)
|
|
|
|
return
|
|
|
|
|
|
|
|
|
2019-11-10 15:25:24 -06:00
|
|
|
def _get_files(path, filters=''):
|
|
|
|
paths = []
|
|
|
|
if filters in ('*', '*.*'):
|
|
|
|
filters = ''
|
|
|
|
for folder, _, files in os.walk(path):
|
|
|
|
if filters:
|
|
|
|
pattern = re.compile(r'\.(?:{})$'.format(filters), re.IGNORECASE)
|
|
|
|
paths += [_join(folder, f) for f in files if pattern.search(f)]
|
|
|
|
else:
|
|
|
|
paths += files
|
|
|
|
return paths
|
|
|
|
|
|
|
|
|
2019-09-09 22:42:38 -05:00
|
|
|
def _compress_oxt():
|
|
|
|
log.info('Compress OXT extension...')
|
|
|
|
|
|
|
|
path = DIRS['files']
|
|
|
|
if not _exists(path):
|
|
|
|
_mkdir(path)
|
|
|
|
|
|
|
|
path_oxt = _join(path, FILES['oxt'])
|
|
|
|
|
|
|
|
z = zipfile.ZipFile(path_oxt, 'w', compression=zipfile.ZIP_DEFLATED)
|
|
|
|
root_len = len(os.path.abspath(DIRS['source']))
|
|
|
|
for root, dirs, files in os.walk(DIRS['source']):
|
|
|
|
relative = os.path.abspath(root)[root_len:]
|
|
|
|
for f in files:
|
|
|
|
fullpath = _join(root, f)
|
|
|
|
file_name = _join(relative, f)
|
|
|
|
if file_name == FILES['idl']:
|
|
|
|
continue
|
|
|
|
z.write(fullpath, file_name, zipfile.ZIP_DEFLATED)
|
|
|
|
z.close()
|
|
|
|
|
2019-09-14 15:19:45 -05:00
|
|
|
if DATA['update']:
|
|
|
|
path_xml = _join(path, FILES['update'])
|
|
|
|
_save(path_xml, DATA['update'])
|
|
|
|
|
2019-09-09 22:42:38 -05:00
|
|
|
log.info('Extension OXT created sucesfully...')
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def _install_and_test():
|
|
|
|
path_oxt = (_join(DIRS['files'], FILES['oxt']),)
|
|
|
|
call(PATHS['install'] + path_oxt)
|
|
|
|
log.info('Install extension sucesfully...')
|
|
|
|
log.info('Start LibreOffice...')
|
|
|
|
call(PATHS['soffice'])
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def _validate_new():
|
|
|
|
path_source = DIRS['source']
|
|
|
|
if not _exists(path_source):
|
|
|
|
return True
|
|
|
|
|
|
|
|
msg = f'Path: {path_source}, exists, delete first'
|
|
|
|
log.error(msg)
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
def _create_new_directories():
|
|
|
|
path_source = DIRS['source']
|
|
|
|
_mkdir(path_source)
|
|
|
|
path = _join(path_source, DIRS['meta'])
|
|
|
|
_mkdir(path)
|
|
|
|
path = _join(path_source, DIRS['description'])
|
|
|
|
_mkdir(path)
|
|
|
|
path = _join(path_source, DIRS['images'])
|
|
|
|
_mkdir(path)
|
|
|
|
path = _join(path_source, DIRS['registration'])
|
|
|
|
_mkdir(path)
|
2019-09-16 10:42:29 -05:00
|
|
|
path = _join(path_source, DIRS['office'])
|
|
|
|
_mkdir(path)
|
2019-09-09 22:42:38 -05:00
|
|
|
|
|
|
|
if FILES['easymacro'] or DIRS['pythonpath']:
|
|
|
|
path = _join(path_source, 'pythonpath')
|
|
|
|
_mkdir(path)
|
|
|
|
|
|
|
|
path = DIRS['files']
|
|
|
|
if not _exists(path):
|
|
|
|
_mkdir(path)
|
|
|
|
|
|
|
|
msg = 'Created directories...'
|
|
|
|
log.info(msg)
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def _create_new_files():
|
|
|
|
path_source = DIRS['source']
|
|
|
|
|
|
|
|
for k, v in INFO.items():
|
|
|
|
file_name = f'license_{k}.txt'
|
|
|
|
path = _join(path_source, DIRS['registration'], file_name)
|
|
|
|
_save(path, v['license'])
|
|
|
|
|
|
|
|
if TYPE_EXTENSION > 1:
|
|
|
|
path = _join(path_source, FILES['idl'])
|
|
|
|
_save(path, DATA['idl'])
|
|
|
|
|
|
|
|
path = _join(path_source, FILES['py'])
|
|
|
|
_save(path, DATA['py'])
|
|
|
|
|
|
|
|
|
|
|
|
msg = 'Created files...'
|
|
|
|
log.info(msg)
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def _validate_update():
|
|
|
|
if TYPE_EXTENSION == 1:
|
|
|
|
return True
|
|
|
|
|
|
|
|
if not _exists(PATHS['idlc']):
|
|
|
|
msg = 'Binary: "idlc" not found'
|
|
|
|
log.error(msg)
|
|
|
|
return False
|
|
|
|
|
|
|
|
if not _exists(PATHS['include']):
|
|
|
|
msg = 'Directory: "include" not found'
|
|
|
|
log.error(msg)
|
|
|
|
return False
|
|
|
|
|
|
|
|
if not _exists(PATHS['regmerge']):
|
|
|
|
msg = 'Binary: "regmerge" not found'
|
|
|
|
log.error(msg)
|
|
|
|
return False
|
|
|
|
|
|
|
|
path = _join(DIRS['source'], FILES['idl'])
|
|
|
|
if not _exists(path):
|
|
|
|
msg = f'File: "{FILES["idl"]}" not found'
|
|
|
|
log.error(msg)
|
|
|
|
return False
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
def _compile_idl():
|
|
|
|
if TYPE_EXTENSION == 1:
|
|
|
|
return
|
|
|
|
|
|
|
|
log.info('Compilate IDL...')
|
|
|
|
path_rdb = _join(DIRS['source'], FILES['rdb'])
|
|
|
|
path_urd = _join(DIRS['source'], FILES['urd'])
|
|
|
|
|
|
|
|
path = _join(DIRS['source'], FILES['idl'])
|
|
|
|
call([PATHS['idlc'], '-I', PATHS['include'], path])
|
|
|
|
call([PATHS['regmerge'], path_rdb, '/UCR', path_urd])
|
|
|
|
os.remove(path_urd)
|
|
|
|
|
|
|
|
log.info('Compilate IDL sucesfully...')
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def _update_files():
|
|
|
|
path_source = DIRS['source']
|
|
|
|
|
|
|
|
for k, v in INFO.items():
|
|
|
|
file_name = FILES['ext_desc'].format(k)
|
|
|
|
path = _join(path_source, DIRS['description'], file_name)
|
|
|
|
_save(path, v['description'])
|
|
|
|
|
|
|
|
path_logo = EXTENSION['icon'][0]
|
|
|
|
if _exists(path_logo):
|
|
|
|
file_name = EXTENSION['icon'][1]
|
|
|
|
path = _join(path_source, DIRS['images'], file_name)
|
|
|
|
copyfile(path_logo, path)
|
|
|
|
|
|
|
|
files = os.listdir(DIRS['images'])
|
|
|
|
for f in files:
|
|
|
|
if f[-3:].lower() == 'bmp':
|
|
|
|
source = _join(DIRS['images'], f)
|
|
|
|
target = _join(path_source, DIRS['images'], f)
|
|
|
|
copyfile(source, target)
|
|
|
|
|
|
|
|
if FILES['easymacro']:
|
|
|
|
source = 'easymacro.py'
|
|
|
|
target = _join(path_source, 'pythonpath', source)
|
|
|
|
copyfile(source, target)
|
|
|
|
|
2019-11-10 15:25:24 -06:00
|
|
|
xml = LiboXML()
|
|
|
|
|
2019-09-09 22:42:38 -05:00
|
|
|
path = _join(path_source, DIRS['meta'], FILES['manifest'])
|
2019-11-10 15:25:24 -06:00
|
|
|
data = xml.new_manifest(DATA['manifest'])
|
|
|
|
_save(path, data)
|
2019-09-09 22:42:38 -05:00
|
|
|
|
2019-09-16 10:42:29 -05:00
|
|
|
path = _join(path_source, DIRS['office'])
|
|
|
|
_mkdir(path)
|
|
|
|
path = _join(path_source, DIRS['office'], FILES['shortcut'])
|
|
|
|
_save(path, DATA['shortcut'])
|
|
|
|
|
2019-09-09 22:42:38 -05:00
|
|
|
path = _join(path_source, FILES['addons'])
|
|
|
|
_save(path, DATA['addons'])
|
|
|
|
|
|
|
|
path = _join(path_source, FILES['description'])
|
|
|
|
_save(path, DATA['description'])
|
|
|
|
|
|
|
|
if TYPE_EXTENSION == 3:
|
|
|
|
path = _join(path_source, FILES['addin'])
|
|
|
|
_save(path, DATA['addin'])
|
|
|
|
|
2019-09-16 10:42:29 -05:00
|
|
|
if USE_LOCALES:
|
|
|
|
msg = "Don't forget generate DOMAIN.pot for locales"
|
|
|
|
log.info(msg)
|
|
|
|
for lang in EXTENSION['languages']:
|
|
|
|
path = _join(path_source, DIRS['locales'], lang, 'LC_MESSAGES')
|
|
|
|
Path(path).mkdir(parents=True, exist_ok=True)
|
|
|
|
|
2019-09-09 22:42:38 -05:00
|
|
|
_compile_idl()
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def _new():
|
|
|
|
if not _validate_new():
|
|
|
|
return
|
|
|
|
|
|
|
|
_create_new_directories()
|
|
|
|
_create_new_files()
|
|
|
|
_update_files()
|
|
|
|
|
|
|
|
msg = f"New extension: {EXTENSION['name']} make sucesfully...\n"
|
|
|
|
msg += '\tNow, you can install and test: zaz.py -i'
|
|
|
|
log.info(msg)
|
|
|
|
return
|
|
|
|
|
|
|
|
|
2019-11-10 15:25:24 -06:00
|
|
|
def _get_info_path(path):
|
|
|
|
path, filename = os.path.split(path)
|
|
|
|
name, extension = os.path.splitext(filename)
|
|
|
|
return (path, filename, name, extension)
|
|
|
|
|
|
|
|
|
|
|
|
def _zip_embed(source, files):
|
|
|
|
PATH = 'Scripts/python/'
|
|
|
|
EASYMACRO = 'easymacro.'
|
|
|
|
|
|
|
|
p, f, name, e = _get_info_path(source)
|
|
|
|
now = datetime.now().strftime('_%Y%m%d_%H%M%S')
|
|
|
|
path_source = _join(p, name + now + e)
|
|
|
|
copyfile(source, path_source)
|
|
|
|
target = source
|
|
|
|
|
|
|
|
with zipfile.PyZipFile(EASYMACRO + 'zip', mode='w') as zf:
|
|
|
|
zf.writepy(EASYMACRO + 'py')
|
|
|
|
|
|
|
|
xml = LiboXML()
|
|
|
|
|
|
|
|
path_easymacro = PATH + EASYMACRO + 'zip'
|
|
|
|
names = [f[1] for f in files] + [path_easymacro]
|
|
|
|
nodes = []
|
|
|
|
with zipfile.ZipFile(target, 'w', compression=zipfile.ZIP_DEFLATED) as zt:
|
|
|
|
with zipfile.ZipFile(path_source, compression=zipfile.ZIP_DEFLATED) as zs:
|
|
|
|
for name in zs.namelist():
|
|
|
|
if FILES['manifest'] in name:
|
|
|
|
path_manifest = name
|
|
|
|
xml_manifest = zs.open(name).read()
|
|
|
|
elif name in names:
|
|
|
|
continue
|
|
|
|
else:
|
|
|
|
zt.writestr(name, zs.open(name).read())
|
|
|
|
|
|
|
|
data = []
|
|
|
|
for path, name in files:
|
|
|
|
data.append(name)
|
|
|
|
zt.write(path, name)
|
|
|
|
|
|
|
|
zt.write(EASYMACRO + 'zip', path_easymacro)
|
|
|
|
data.append(path_easymacro)
|
|
|
|
|
|
|
|
xml.parse_manifest(xml_manifest)
|
|
|
|
xml_manifest = xml.add_data_manifest(data)
|
|
|
|
zt.writestr(path_manifest, xml_manifest)
|
|
|
|
|
|
|
|
os.unlink(EASYMACRO + 'zip')
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def _embed(args):
|
|
|
|
PATH = 'Scripts/python'
|
|
|
|
PYTHONPATH = 'pythonpath'
|
|
|
|
|
|
|
|
doc = args.document
|
|
|
|
if not doc:
|
|
|
|
msg = '-d/--document Path file to embed is mandatory'
|
|
|
|
log.error(msg)
|
|
|
|
return
|
|
|
|
if not _exists(doc):
|
|
|
|
msg = 'Path file not exists'
|
|
|
|
log.error(msg)
|
|
|
|
return
|
|
|
|
|
|
|
|
files = []
|
|
|
|
if args.files:
|
|
|
|
files = args.files.split(',')
|
|
|
|
source = _join(PATHS['profile'], PATH)
|
|
|
|
content = os.listdir(source)
|
|
|
|
if PYTHONPATH in content:
|
|
|
|
content.remove(PYTHONPATH)
|
|
|
|
|
|
|
|
if files:
|
|
|
|
files = [(_join(source, f), _join(PATH, f)) for f in files if f in content]
|
|
|
|
else:
|
|
|
|
files = [(_join(source, f), _join(PATH, f)) for f in content]
|
|
|
|
|
|
|
|
_zip_embed(doc, files)
|
|
|
|
|
|
|
|
log.info('Embedded macros successfully...')
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def _locales(args):
|
|
|
|
EASYMACRO = 'easymacro.py'
|
|
|
|
|
|
|
|
if args.files:
|
|
|
|
files = args.files.split(',')
|
|
|
|
else:
|
|
|
|
files = _get_files(DIRS['source'], 'py')
|
|
|
|
paths = ' '.join([f for f in files if not EASYMACRO in f])
|
|
|
|
path_pot = _join(DIRS['source'], DIRS['locales'], '{}.pot'.format(DOMAIN))
|
|
|
|
call([PATHS['gettext'], '-o', path_pot, paths])
|
|
|
|
log.info('POT generate successfully...')
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def _update():
|
|
|
|
path_locales = _join(DIRS['source'], DIRS['locales'])
|
|
|
|
path_pot = _join(DIRS['source'], DIRS['locales'], '{}.pot'.format(DOMAIN))
|
|
|
|
if not _exists(path_pot):
|
|
|
|
log.error('Not exists file POT...')
|
|
|
|
return
|
|
|
|
|
|
|
|
files = _get_files(path_locales, 'po')
|
|
|
|
if not files:
|
|
|
|
log.error('First, generate files PO...')
|
|
|
|
return
|
|
|
|
|
|
|
|
for f in files:
|
|
|
|
call([PATHS['msgmerge'], '-U', f, path_pot])
|
|
|
|
log.info('\tUpdate: {}'.format(f))
|
|
|
|
|
|
|
|
log.info('Locales update successfully...')
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-09-09 22:42:38 -05:00
|
|
|
def main(args):
|
2019-11-10 15:25:24 -06:00
|
|
|
if args.update:
|
|
|
|
_update()
|
|
|
|
return
|
|
|
|
|
|
|
|
if args.locales:
|
|
|
|
_locales(args)
|
|
|
|
return
|
|
|
|
|
|
|
|
if args.embed:
|
|
|
|
_embed(args)
|
|
|
|
return
|
|
|
|
|
2019-09-09 22:42:38 -05:00
|
|
|
if args.new:
|
|
|
|
_new()
|
|
|
|
return
|
|
|
|
|
|
|
|
if not _validate_update():
|
|
|
|
return
|
|
|
|
|
|
|
|
_update_files()
|
|
|
|
_compress_oxt()
|
|
|
|
|
|
|
|
if args.install:
|
|
|
|
_install_and_test()
|
|
|
|
|
2019-11-10 15:25:24 -06:00
|
|
|
log.info('Extension make successfully...')
|
2019-09-09 22:42:38 -05:00
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def _process_command_line_arguments():
|
|
|
|
parser = argparse.ArgumentParser(
|
|
|
|
description='Make LibreOffice extensions')
|
|
|
|
parser.add_argument('-i', '--install', dest='install', action='store_true',
|
|
|
|
default=False, required=False)
|
|
|
|
parser.add_argument('-n', '--new', dest='new', action='store_true',
|
|
|
|
default=False, required=False)
|
2019-11-10 15:25:24 -06:00
|
|
|
parser.add_argument('-e', '--embed', dest='embed', action='store_true',
|
|
|
|
default=False, required=False)
|
|
|
|
parser.add_argument('-d', '--document', dest='document', default='')
|
|
|
|
parser.add_argument('-f', '--files', dest='files', default='')
|
|
|
|
parser.add_argument('-l', '--locales', dest='locales', action='store_true',
|
|
|
|
default=False, required=False)
|
|
|
|
parser.add_argument('-u', '--update', dest='update', action='store_true',
|
|
|
|
default=False, required=False)
|
2019-09-09 22:42:38 -05:00
|
|
|
return parser.parse_args()
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
args = _process_command_line_arguments()
|
|
|
|
main(args)
|
|
|
|
|