Compare commits
11 Commits
Author | SHA1 | Date |
---|---|---|
Mauricio Baeza | 5f1207836a | |
Mauricio Baeza | 35d356a698 | |
Mauricio Baeza | b3d8674a9e | |
Mauricio Baeza | 490975b268 | |
Mauricio Baeza | 86c7224b5b | |
Mauricio Baeza | 8714c7b75c | |
Mauricio Baeza | 91a5ce7861 | |
Mauricio Baeza | e5b37216ba | |
Mauricio Baeza | f410bf3d19 | |
Mauricio Baeza | 04aa7eea7c | |
Mauricio Baeza | 0360b5a774 |
|
@ -1,3 +1,8 @@
|
|||
v 0.7.0 [-oct-2020]
|
||||
---------------------
|
||||
- Update libraries
|
||||
|
||||
|
||||
v 0.6.0 [15-nov-2019]
|
||||
---------------------
|
||||
- Call by code
|
||||
|
|
|
@ -4,6 +4,7 @@ Extension for insert barcode in LibreOffice documents, with Python, of course.
|
|||
|
||||
Barcodes provided
|
||||
|
||||
* qrcode
|
||||
* code39
|
||||
* code128
|
||||
* ean
|
||||
|
@ -19,7 +20,6 @@ Barcodes provided
|
|||
* pzn
|
||||
* upc
|
||||
* upca
|
||||
* qrcode
|
||||
|
||||
|
||||
Requirements:
|
||||
|
@ -45,6 +45,10 @@ BCH: `qztd3l00xle5tffdqvh2snvadkuau2ml0uqm4n875d`
|
|||
|
||||
BTC: `3FhiXcXmAesmQzrNEngjHFnvaJRhU1AGWV`
|
||||
|
||||
ETH: `0x61a4f614a30ff686445751ed8328b82b77ecfc69`
|
||||
|
||||
LTC: `MBcgQ3LQJA4W2wsXknTdm2fxRSysLaBJHS`
|
||||
|
||||
|
||||
* [Look the wiki](https://gitlab.com/mauriciobaeza/zaz-barcode/wikis/home)
|
||||
* [Mira la wiki](https://gitlab.com/mauriciobaeza/zaz-barcode/wikis/home_es)
|
||||
|
|
282
conf.py
282
conf.py
|
@ -25,24 +25,24 @@ import logging
|
|||
# ~ 3 = Calc addin
|
||||
TYPE_EXTENSION = 1
|
||||
|
||||
# ~ https://semver.org/
|
||||
VERSION = '0.6.0'
|
||||
|
||||
# ~ Your great extension name, not used spaces
|
||||
NAME = 'ZAZBarCode'
|
||||
|
||||
# ~ https://semver.org/
|
||||
VERSION = '0.7.0'
|
||||
|
||||
# ~ Should be unique, used URL inverse
|
||||
ID = 'net.elmau.zaz.BarCode'
|
||||
|
||||
# ~ If you extension will be multilanguage set: True
|
||||
# ~ This feature used gettext, set pythonpath and easymacro in True
|
||||
# ~ Yu can used PoEdit for edit PO files and generate MO files.
|
||||
# ~ You can used PoEdit for edit PO files and generate MO files.
|
||||
# ~ https://poedit.net/
|
||||
USE_LOCALES = True
|
||||
DOMAIN = 'base'
|
||||
PATH_LOCALES = 'locales'
|
||||
# ~ locate pygettext.py
|
||||
PATH_PYGETTEXT = '/usr/lib/python3.7/Tools/i18n/pygettext.py'
|
||||
PATH_PYGETTEXT = '/usr/lib/python3.8/Tools/i18n/pygettext.py'
|
||||
# ~ You can use PoEdit for update locales too
|
||||
PATH_MSGMERGE = 'msgmerge'
|
||||
|
||||
|
||||
|
@ -57,9 +57,6 @@ ICON = 'images/logo.png'
|
|||
# ~ Name inside extensions
|
||||
ICON_EXT = f'{NAME.lower()}.png'
|
||||
|
||||
# ~ For example
|
||||
# ~ DEPENDENCIES_MINIMAL = '6.0'
|
||||
DEPENDENCIES_MINIMAL = ''
|
||||
|
||||
# ~ Change for you favorite license
|
||||
LICENSE_EN = f"""This file is part of {NAME}.
|
||||
|
@ -93,17 +90,6 @@ INFO = {
|
|||
}
|
||||
|
||||
|
||||
CONTEXT = {
|
||||
'calc': 'com.sun.star.sheet.SpreadsheetDocument',
|
||||
'writer': 'com.sun.star.text.TextDocument',
|
||||
'impress': 'com.sun.star.presentation.PresentationDocument',
|
||||
'draw': 'com.sun.star.drawing.DrawingDocument',
|
||||
'base': 'com.sun.star.sdb.OfficeDatabaseDocument',
|
||||
'math': 'com.sun.star.formula.FormulaProperties',
|
||||
'basic': 'com.sun.star.script.BasicIDE',
|
||||
}
|
||||
|
||||
|
||||
# ~ Menus, only for TYPE_EXTENSION = 1
|
||||
# ~ Parent can be: AddonMenu or OfficeMenuBar
|
||||
# ~ For icons con name: NAME_16.bmp, used only NAME
|
||||
|
@ -123,7 +109,7 @@ MENU_MAIN = {
|
|||
MENUS = (
|
||||
{
|
||||
'title': {'en': 'Insert BarCode', 'es': 'Insertar Código'},
|
||||
'argument': 'ask',
|
||||
'argument': 'used_dialog',
|
||||
'context': 'calc,writer,impress,draw',
|
||||
'icon': 'barcode',
|
||||
'toolbar': False,
|
||||
|
@ -302,9 +288,8 @@ FILES = {
|
|||
|
||||
# ~ URLs for update for example
|
||||
# ~ URL_XML_UPDATE = 'https://gitlab.com/USER/PROYECT/raw/BRANCH/FOLDERs/FILE_NAME'
|
||||
URL_BASE = 'https://gitlab.com/mauriciobaeza/zaz-barcode/raw/master/files/'
|
||||
URL_XML_UPDATE = URL_BASE + FILES['update']
|
||||
URL_OXT = URL_BASE + FILES['oxt']
|
||||
URL_XML_UPDATE = ''
|
||||
URL_OXT = ''
|
||||
|
||||
|
||||
# ~ Default program for test: --calc, --writer, --draw
|
||||
|
@ -372,7 +357,7 @@ elif TYPE_EXTENSION == 3:
|
|||
METHODS = _methods()
|
||||
|
||||
|
||||
FILE_PY = f"""import uno
|
||||
DATA_PY = f"""import uno
|
||||
import unohelper
|
||||
{SRV_IMPORT}
|
||||
|
||||
|
@ -392,177 +377,6 @@ g_ImplementationHelper = unohelper.ImplementationHelper()
|
|||
g_ImplementationHelper.addImplementation({NAME}, ID_EXTENSION, SERVICE)
|
||||
"""
|
||||
|
||||
|
||||
tmp = ' <name lang="{}">{}</name>'
|
||||
node = [tmp.format(k, v['display_name']) for k, v in INFO.items()]
|
||||
NODE_DISPLAY_NAME = '\n'.join(node)
|
||||
|
||||
tmp = ' <src lang="{0}" xlink:href="description/desc_{0}.txt" />'
|
||||
node = [tmp.format(k) for k, v in INFO.items()]
|
||||
NODE_EXTENSION_DESCRIPTION = '\n'.join(node)
|
||||
|
||||
NODE_ICON = ''
|
||||
if ICON:
|
||||
NODE_ICON = f' <default xlink:href="images/{ICON_EXT}" />'
|
||||
|
||||
NODE_PUBLISHER = ''
|
||||
if PUBLISHER:
|
||||
tmp = ' <name xlink:href="{}" lang="{}">{}</name>'
|
||||
node = [tmp.format(v['link'], k, v['text']) for k, v in PUBLISHER.items()]
|
||||
NODE_PUBLISHER = '\n'.join(node)
|
||||
|
||||
NODE_DEPENDENCIES_MINIMAL = ''
|
||||
if DEPENDENCIES_MINIMAL:
|
||||
NODE_DEPENDENCIES_MINIMAL = f"""\n <dependencies>
|
||||
<OpenOffice.org-minimal-version value="{DEPENDENCIES_MINIMAL}" d:name="LibreOffice {DEPENDENCIES_MINIMAL}"/>
|
||||
</dependencies>"""
|
||||
|
||||
tmp = ' <license-text xlink:href="{0}/license_{1}.txt" lang="{1}" />'
|
||||
node = [tmp.format(DIRS['registration'], k) for k in INFO.keys()]
|
||||
NODE_LICENSE = '\n'.join(node)
|
||||
|
||||
NODE_UPDATE = ''
|
||||
if URL_XML_UPDATE:
|
||||
NODE_UPDATE = f"""
|
||||
<update-information>
|
||||
<src xlink:href="{URL_XML_UPDATE}" />
|
||||
</update-information>"""
|
||||
|
||||
FILE_DESCRIPTION = f"""<?xml version='1.0' encoding='UTF-8'?>
|
||||
<description xmlns="http://openoffice.org/extensions/description/2006" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:d="http://openoffice.org/extensions/description/2006">
|
||||
<identifier value="{ID}" />
|
||||
<version value="{VERSION}" />
|
||||
<display-name>
|
||||
{NODE_DISPLAY_NAME}
|
||||
</display-name>
|
||||
<extension-description>
|
||||
{NODE_EXTENSION_DESCRIPTION}
|
||||
</extension-description>
|
||||
<icon>
|
||||
{NODE_ICON}
|
||||
</icon>
|
||||
<publisher>
|
||||
{NODE_PUBLISHER}
|
||||
</publisher>
|
||||
<registration>
|
||||
<simple-license accept-by="user" suppress-on-update="true" >
|
||||
{NODE_LICENSE}
|
||||
</simple-license>
|
||||
</registration>{NODE_DEPENDENCIES_MINIMAL}{NODE_UPDATE}
|
||||
</description>
|
||||
"""
|
||||
|
||||
NODE_MENU = """ <node oor:name="{id}.{index}" oor:op="{opt}">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
{titles}
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:{id}?{argument}</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>{context}</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/{folder}/{icon}</value>
|
||||
</prop>
|
||||
</node>"""
|
||||
|
||||
opt = 'fuse'
|
||||
if PARENT == 'OfficeMenuBar':
|
||||
opt = 'replace'
|
||||
|
||||
|
||||
def _get_context(args):
|
||||
if not args:
|
||||
return ''
|
||||
c = []
|
||||
for v in args.split(','):
|
||||
c.append(CONTEXT[v])
|
||||
return ','.join(c)
|
||||
|
||||
|
||||
menus = []
|
||||
toolbar = []
|
||||
tmp = ' <value xml:lang="{}">{}</value>'
|
||||
for i, m in enumerate(MENUS):
|
||||
titles = [tmp.format(k, v) for k, v in m['title'].items()]
|
||||
values = {
|
||||
'id': ID,
|
||||
'index': i+101,
|
||||
'opt': opt,
|
||||
'titles': '\n'.join(titles),
|
||||
'argument': m['argument'],
|
||||
'context': _get_context(m['context']),
|
||||
'folder': DIRS['images'],
|
||||
'icon': m['icon'],
|
||||
}
|
||||
menus.append(NODE_MENU.format(**values))
|
||||
if m['toolbar']:
|
||||
values['index'] = f't{i+1}'
|
||||
toolbar.append(NODE_MENU.format(**values))
|
||||
|
||||
NODE_TOOLBAR = ''
|
||||
NODE_MENUS = ''
|
||||
if TYPE_EXTENSION == 1:
|
||||
if PARENT == 'AddonMenu':
|
||||
NODE_MENUS = '\n'.join(menus)
|
||||
elif PARENT == 'OfficeMenuBar':
|
||||
tmp = ' <value xml:lang="{}">{}</value>'
|
||||
titles = '\n'.join([tmp.format(k, v) for k, v in MENU_MAIN.items()])
|
||||
SUBMENUS = '<node oor:name="Submenu">\n ' + '\n'.join(menus) + '\n </node>'
|
||||
NODE_MENUS = f""" <node oor:name="{ID}" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
{titles}
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
{SUBMENUS}
|
||||
</node>"""
|
||||
|
||||
if toolbar:
|
||||
node_toolbars = '\n'.join(toolbar)
|
||||
NODE_TOOLBAR = f""" <node oor:name="OfficeToolBar">
|
||||
<node oor:name="{ID}" oor:op="replace">
|
||||
{node_toolbars}
|
||||
</node>
|
||||
</node>"""
|
||||
|
||||
FILE_ADDONS = f"""<?xml version='1.0' encoding='UTF-8'?>
|
||||
<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="Addons" oor:package="org.openoffice.Office">
|
||||
<node oor:name="AddonUI">
|
||||
<node oor:name="{PARENT}">
|
||||
{NODE_MENUS}
|
||||
</node>
|
||||
{NODE_TOOLBAR}
|
||||
</node>
|
||||
</oor:component-data>
|
||||
"""
|
||||
|
||||
|
||||
FILE_UPDATE = ''
|
||||
if URL_XML_UPDATE:
|
||||
FILE_UPDATE = f"""<?xml version="1.0" encoding="UTF-8"?>
|
||||
<description
|
||||
xmlns="http://openoffice.org/extensions/update/2006"
|
||||
xmlns:d="http://openoffice.org/extensions/description/2006"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
|
||||
<identifier value="{ID}" />
|
||||
<version value="{VERSION}" />
|
||||
|
||||
<update-download>
|
||||
<src xlink:href="{URL_OXT}"/>
|
||||
</update-download>
|
||||
<release-notes>
|
||||
</release-notes>
|
||||
|
||||
</description>"""
|
||||
|
||||
|
||||
def _functions():
|
||||
a = '[in] any {}'
|
||||
t = ' any {}({});'
|
||||
|
@ -679,72 +493,42 @@ FILE_ADDIN = f"""<?xml version="1.0" encoding="UTF-8"?>
|
|||
</oor:component-data>"""
|
||||
|
||||
|
||||
NODE_SHORTCUT = """ {0}<node oor:name="{1}" oor:op="fuse">
|
||||
{0}<prop oor:name="Command">
|
||||
{0}<value xml:lang="en-US">service:{2}?{3}</value>
|
||||
{0}</prop>
|
||||
{0}</node>
|
||||
"""
|
||||
|
||||
NODE_SHORTCUTS = ''
|
||||
if TYPE_EXTENSION == 1:
|
||||
node_global = []
|
||||
node_module = {}
|
||||
for m in MENUS:
|
||||
if not m.get('shortcut', ''):
|
||||
continue
|
||||
if m['context']:
|
||||
for c in m['context'].split(','):
|
||||
if not c in node_module:
|
||||
node_module[c] = []
|
||||
node = NODE_SHORTCUT.format(' ', m['shortcut'], ID, m['argument'])
|
||||
node_module[c].append(node)
|
||||
continue
|
||||
node = NODE_SHORTCUT.format('', m['shortcut'], ID, m['argument'])
|
||||
node_global.append(node)
|
||||
if node_global:
|
||||
NODE_SHORTCUTS = ' <node oor:name="Global">\n'
|
||||
NODE_SHORTCUTS += '\n'.join(node_global)
|
||||
NODE_SHORTCUTS += ' </node>'
|
||||
if node_module:
|
||||
NODE_SHORTCUTS += ' <node oor:name="Modules">\n'
|
||||
for c, n in node_module.items():
|
||||
NODE_SHORTCUTS += ' <node oor:name="{}">\n'.format(CONTEXT[c])
|
||||
NODE_SHORTCUTS += '\n'.join(n)
|
||||
NODE_SHORTCUTS += ' </node>\n'
|
||||
NODE_SHORTCUTS += ' </node>'
|
||||
|
||||
FILE_SHORTCUTS = f"""<?xml version="1.0" encoding="UTF-8"?>
|
||||
<oor:component-data
|
||||
xmlns:oor="http://openoffice.org/2001/registry"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
oor:name="Accelerators"
|
||||
oor:package="org.openoffice.Office">
|
||||
<node oor:name="PrimaryKeys">
|
||||
{NODE_SHORTCUTS}
|
||||
</node>
|
||||
</oor:component-data>
|
||||
"""
|
||||
|
||||
|
||||
DATA_MANIFEST = [FILES['py'], f"Office/{FILES['shortcut']}", 'Addons.xcu']
|
||||
if TYPE_EXTENSION > 1:
|
||||
DATA_MANIFEST.append(FILES['rdb'])
|
||||
if TYPE_EXTENSION == 3:
|
||||
DATA_MANIFEST.append('CalcAddIn.xcu')
|
||||
|
||||
DATA_DESCRIPTION = {
|
||||
'identifier': {'value': ID},
|
||||
'version': {'value': VERSION},
|
||||
'display-name': {k: v['display_name'] for k, v in INFO.items()},
|
||||
'icon': ICON_EXT,
|
||||
'publisher': PUBLISHER,
|
||||
'update': URL_XML_UPDATE,
|
||||
}
|
||||
|
||||
DATA_ADDONS = {
|
||||
'parent': PARENT,
|
||||
'images': DIRS['images'],
|
||||
'main': MENU_MAIN,
|
||||
'menus': MENUS,
|
||||
}
|
||||
|
||||
DATA = {
|
||||
'py': FILE_PY,
|
||||
'py': DATA_PY,
|
||||
'manifest': DATA_MANIFEST,
|
||||
'description': FILE_DESCRIPTION,
|
||||
'addons': FILE_ADDONS,
|
||||
'update': FILE_UPDATE,
|
||||
'description': DATA_DESCRIPTION,
|
||||
'addons': DATA_ADDONS,
|
||||
'update': URL_OXT,
|
||||
'idl': FILE_IDL,
|
||||
'addin': FILE_ADDIN,
|
||||
'shortcut': FILE_SHORTCUTS,
|
||||
}
|
||||
|
||||
|
||||
with open('VERSION', 'w') as f:
|
||||
f.write(VERSION)
|
||||
|
||||
|
||||
# ~ LICENSE_ACCEPT_BY = 'user' # or admin
|
||||
# ~ LICENSE_SUPPRESS_ON_UPDATE = True
|
||||
|
|
8509
easymacro.py
8509
easymacro.py
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -1,16 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<description
|
||||
xmlns="http://openoffice.org/extensions/update/2006"
|
||||
xmlns:d="http://openoffice.org/extensions/description/2006"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
|
||||
<identifier value="net.elmau.zaz.BarCode" />
|
||||
<version value="0.6.0" />
|
||||
|
||||
<update-download>
|
||||
<src xlink:href="https://gitlab.com/mauriciobaeza/zaz-barcode/raw/master/files/ZAZBarCode_v0.6.0.oxt"/>
|
||||
</update-download>
|
||||
<release-notes>
|
||||
</release-notes>
|
||||
|
||||
</description>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<description xmlns="http://openoffice.org/extensions/update/2006" xmlns:d="http://openoffice.org/extensions/description/2006" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<identifier value="net.elmau.zaz.BarCode"/>
|
||||
<version value="0.7.0"/>
|
||||
<update-download>
|
||||
<src xlink:href="https://gitlab.com/mauriciobaeza/zaz-barcode/raw/master/files/ZAZBarCode_v0.7.0.oxt"/>
|
||||
</update-download>
|
||||
<release-notes/>
|
||||
</description>
|
||||
|
|
|
@ -1,325 +1,324 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="Addons" oor:package="org.openoffice.Office">
|
||||
<node oor:name="AddonUI">
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<oor:component-data xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:oor="http://openoffice.org/2001/registry" oor:name="Addons" oor:package="org.openoffice.Office">
|
||||
<node oor:name="AddonUI">
|
||||
<node oor:name="OfficeMenuBar">
|
||||
<node oor:name="net.elmau.zaz.BarCode" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">ZAZ BarCode</value>
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">ZAZ BarCode</value>
|
||||
<value xml:lang="es">ZAZ BarCode</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<node oor:name="Submenu">
|
||||
<node oor:name="m0" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert BarCode</value>
|
||||
<value xml:lang="es">Insertar Código</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument,com.sun.star.presentation.PresentationDocument,com.sun.star.drawing.DrawingDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?used_dialog</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<node oor:name="Submenu">
|
||||
<node oor:name="net.elmau.zaz.BarCode.101" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert BarCode</value>
|
||||
<value xml:lang="es">Insertar Código</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?ask</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument,com.sun.star.presentation.PresentationDocument,com.sun.star.drawing.DrawingDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name="net.elmau.zaz.BarCode.102" oor:op="replace">
|
||||
<node oor:name="m1" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert CODE39</value>
|
||||
<value xml:lang="es">Insertar CODE39</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?code39</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
<value xml:lang="en">Insert CODE39</value>
|
||||
<value xml:lang="es">Insertar CODE39</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?code39</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name="net.elmau.zaz.BarCode.103" oor:op="replace">
|
||||
<node oor:name="m2" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert CODE128</value>
|
||||
<value xml:lang="es">Insertar CODE128</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?code128</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
<value xml:lang="en">Insert CODE128</value>
|
||||
<value xml:lang="es">Insertar CODE128</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?code128</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name="net.elmau.zaz.BarCode.104" oor:op="replace">
|
||||
<node oor:name="m3" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert EAN</value>
|
||||
<value xml:lang="es">Insertar EAN</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?ean</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
<value xml:lang="en">Insert EAN</value>
|
||||
<value xml:lang="es">Insertar EAN</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?ean</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name="net.elmau.zaz.BarCode.105" oor:op="replace">
|
||||
<node oor:name="m4" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert EAN8</value>
|
||||
<value xml:lang="es">Insertar EAN8</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?ean8</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
<value xml:lang="en">Insert EAN8</value>
|
||||
<value xml:lang="es">Insertar EAN8</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?ean8</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name="net.elmau.zaz.BarCode.106" oor:op="replace">
|
||||
<node oor:name="m5" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert EAN13</value>
|
||||
<value xml:lang="es">Insertar EAN13</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?ean13</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
<value xml:lang="en">Insert EAN13</value>
|
||||
<value xml:lang="es">Insertar EAN13</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?ean13</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name="net.elmau.zaz.BarCode.107" oor:op="replace">
|
||||
<node oor:name="m6" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert GS1</value>
|
||||
<value xml:lang="es">Insertar GS1</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?gs1</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
<value xml:lang="en">Insert GS1</value>
|
||||
<value xml:lang="es">Insertar GS1</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?gs1</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name="net.elmau.zaz.BarCode.108" oor:op="replace">
|
||||
<node oor:name="m7" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert GTIN</value>
|
||||
<value xml:lang="es">Insertar GTIN</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?gtin</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
<value xml:lang="en">Insert GTIN</value>
|
||||
<value xml:lang="es">Insertar GTIN</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?gtin</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name="net.elmau.zaz.BarCode.109" oor:op="replace">
|
||||
<node oor:name="m8" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert ISBN</value>
|
||||
<value xml:lang="es">Insertar ISBN</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?isbn</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
<value xml:lang="en">Insert ISBN</value>
|
||||
<value xml:lang="es">Insertar ISBN</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?isbn</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name="net.elmau.zaz.BarCode.110" oor:op="replace">
|
||||
<node oor:name="m9" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert ISBN10</value>
|
||||
<value xml:lang="es">Insertar ISBN10</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?isbn10</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
<value xml:lang="en">Insert ISBN10</value>
|
||||
<value xml:lang="es">Insertar ISBN10</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?isbn10</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name="net.elmau.zaz.BarCode.111" oor:op="replace">
|
||||
<node oor:name="m10" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert ISBN13</value>
|
||||
<value xml:lang="es">Insertar ISBN13</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?isbn13</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
<value xml:lang="en">Insert ISBN13</value>
|
||||
<value xml:lang="es">Insertar ISBN13</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?isbn13</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name="net.elmau.zaz.BarCode.112" oor:op="replace">
|
||||
<node oor:name="m11" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert ISSN</value>
|
||||
<value xml:lang="es">Insertar ISSN</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?issn</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
<value xml:lang="en">Insert ISSN</value>
|
||||
<value xml:lang="es">Insertar ISSN</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?issn</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name="net.elmau.zaz.BarCode.113" oor:op="replace">
|
||||
<node oor:name="m12" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert JAN</value>
|
||||
<value xml:lang="es">Insertar JAN</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?jan</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
<value xml:lang="en">Insert JAN</value>
|
||||
<value xml:lang="es">Insertar JAN</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?jan</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name="net.elmau.zaz.BarCode.114" oor:op="replace">
|
||||
<node oor:name="m13" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert PZN</value>
|
||||
<value xml:lang="es">Insertar PZN</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?pzn</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
<value xml:lang="en">Insert PZN</value>
|
||||
<value xml:lang="es">Insertar PZN</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?pzn</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name="net.elmau.zaz.BarCode.115" oor:op="replace">
|
||||
<node oor:name="m14" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert UPC</value>
|
||||
<value xml:lang="es">Insertar UPC</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?upc</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
<value xml:lang="en">Insert UPC</value>
|
||||
<value xml:lang="es">Insertar UPC</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?upc</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name="net.elmau.zaz.BarCode.116" oor:op="replace">
|
||||
<node oor:name="m15" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert UPCA</value>
|
||||
<value xml:lang="es">Insertar UPCA</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?upca</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
<value xml:lang="en">Insert UPCA</value>
|
||||
<value xml:lang="es">Insertar UPCA</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?upca</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name="net.elmau.zaz.BarCode.117" oor:op="replace">
|
||||
<node oor:name="m16" oor:op="replace">
|
||||
<prop oor:name="Title" oor:type="xs:string">
|
||||
<value xml:lang="en">Insert QRCODE</value>
|
||||
<value xml:lang="es">Insertar QRCODE</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?qrcode</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
<value xml:lang="en">Insert QRCODE</value>
|
||||
<value xml:lang="es">Insertar QRCODE</value>
|
||||
</prop>
|
||||
<prop oor:name="Context" oor:type="xs:string">
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
<value>com.sun.star.sheet.SpreadsheetDocument,com.sun.star.text.TextDocument</value>
|
||||
</prop>
|
||||
<prop oor:name="URL" oor:type="xs:string">
|
||||
<value>service:net.elmau.zaz.BarCode?qrcode</value>
|
||||
</prop>
|
||||
<prop oor:name="Target" oor:type="xs:string">
|
||||
<value>_self</value>
|
||||
</prop>
|
||||
<prop oor:name="ImageIdentifier" oor:type="xs:string">
|
||||
<value>%origin%/images/barcode</value>
|
||||
<value>%origin%/images/barcode</value>
|
||||
</prop>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
||||
</node>
|
||||
</node>
|
||||
</oor:component-data>
|
||||
|
|
|
@ -1,36 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<oor:component-data
|
||||
xmlns:oor="http://openoffice.org/2001/registry"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
oor:name="Accelerators"
|
||||
oor:package="org.openoffice.Office">
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<oor:component-data xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:oor="http://openoffice.org/2001/registry" oor:name="Accelerators" oor:package="org.openoffice.Office">
|
||||
<node oor:name="PrimaryKeys">
|
||||
<node oor:name="Modules">
|
||||
<node oor:name="com.sun.star.sheet.SpreadsheetDocument">
|
||||
<node oor:name="I_SHIFT_MOD1_MOD2" oor:op="fuse">
|
||||
<prop oor:name="Command">
|
||||
<value xml:lang="en-US">service:net.elmau.zaz.BarCode?ask</value>
|
||||
<value xml:lang="en-US">service:net.elmau.zaz.BarCode?used_dialog</value>
|
||||
</prop>
|
||||
</node>
|
||||
</node>
|
||||
<node oor:name="com.sun.star.text.TextDocument">
|
||||
<node oor:name="I_SHIFT_MOD1_MOD2" oor:op="fuse">
|
||||
<prop oor:name="Command">
|
||||
<value xml:lang="en-US">service:net.elmau.zaz.BarCode?ask</value>
|
||||
<value xml:lang="en-US">service:net.elmau.zaz.BarCode?used_dialog</value>
|
||||
</prop>
|
||||
</node>
|
||||
</node>
|
||||
<node oor:name="com.sun.star.presentation.PresentationDocument">
|
||||
<node oor:name="I_SHIFT_MOD1_MOD2" oor:op="fuse">
|
||||
<prop oor:name="Command">
|
||||
<value xml:lang="en-US">service:net.elmau.zaz.BarCode?ask</value>
|
||||
<value xml:lang="en-US">service:net.elmau.zaz.BarCode?used_dialog</value>
|
||||
</prop>
|
||||
</node>
|
||||
</node>
|
||||
<node oor:name="com.sun.star.drawing.DrawingDocument">
|
||||
<node oor:name="I_SHIFT_MOD1_MOD2" oor:op="fuse">
|
||||
<prop oor:name="Command">
|
||||
<value xml:lang="en-US">service:net.elmau.zaz.BarCode?ask</value>
|
||||
<value xml:lang="en-US">service:net.elmau.zaz.BarCode?used_dialog</value>
|
||||
</prop>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
@ -2,55 +2,17 @@ import gettext
|
|||
import uno
|
||||
import unohelper
|
||||
from com.sun.star.task import XJobExecutor, XJob
|
||||
import easymacro as app
|
||||
|
||||
import qrcode
|
||||
import qrcode.image.svg as svg
|
||||
from barcode import generate
|
||||
import main
|
||||
|
||||
|
||||
ID_EXTENSION = 'net.elmau.zaz.BarCode'
|
||||
SERVICE = ('com.sun.star.task.Job',)
|
||||
TITLE = 'ZAZ BarCode'
|
||||
QR = 'qrcode'
|
||||
|
||||
|
||||
_ = app.install_locales(__file__)
|
||||
|
||||
|
||||
class Controllers(object):
|
||||
|
||||
def __init__(self, dlg):
|
||||
self.d = dlg
|
||||
|
||||
def listbox_item_changed(self, event):
|
||||
self.d.text.set_focus()
|
||||
return
|
||||
|
||||
def button_action(self, event):
|
||||
if not self.d.listbox.value:
|
||||
self.d.listbox.set_focus()
|
||||
msg = _('Select barcode type')
|
||||
app.warning(msg, TITLE)
|
||||
return
|
||||
if not self.d.text.value.strip():
|
||||
self.d.text.set_focus()
|
||||
msg = _('Data field is mandatory')
|
||||
app.warning(msg, TITLE)
|
||||
return
|
||||
|
||||
self.d.close(1)
|
||||
return
|
||||
|
||||
|
||||
class ZAZBarCode(unohelper.Base, XJob, XJobExecutor):
|
||||
|
||||
def __init__(self, ctx):
|
||||
self.ctx = ctx
|
||||
self._data = ''
|
||||
self._type = ''
|
||||
self._ask = False
|
||||
self._path = ''
|
||||
|
||||
def execute(self, args):
|
||||
data = app.property_to_dict(args)
|
||||
|
@ -72,178 +34,10 @@ class ZAZBarCode(unohelper.Base, XJob, XJobExecutor):
|
|||
return self._path
|
||||
|
||||
def trigger(self, args):
|
||||
self._type = args
|
||||
if args == 'ask' and not self._get_values():
|
||||
return
|
||||
|
||||
doc = app.get_document()
|
||||
getattr(self, '_insert_in_{}'.format(doc.type))(doc)
|
||||
app.kill(self._path)
|
||||
main.ID_EXTENSION = ID_EXTENSION
|
||||
main.run(args, __file__)
|
||||
return
|
||||
|
||||
def _create_code(self, path=''):
|
||||
if not path:
|
||||
path = app.get_temp_file(True)
|
||||
if self._type == QR:
|
||||
factory = svg.SvgImage
|
||||
img = qrcode.make(self._data, border=2, image_factory=factory)
|
||||
img.save(path)
|
||||
else:
|
||||
try:
|
||||
path = generate(self._type, self._data, output=path)
|
||||
except Exception as e:
|
||||
app.error(e)
|
||||
return str(e)
|
||||
|
||||
if app.is_created(path):
|
||||
self._path = path
|
||||
return ''
|
||||
|
||||
return _('Not generated')
|
||||
|
||||
def _get_values(self):
|
||||
self._type = ''
|
||||
dlg = self._create_dialog()
|
||||
if dlg.open():
|
||||
self._data = dlg.text.value.strip()
|
||||
self._type = dlg.listbox.value
|
||||
self._ask = True
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _insert_in_calc(self, doc):
|
||||
cell = doc.get_cell()
|
||||
if not self._data:
|
||||
self._data = cell.value
|
||||
if not self._data:
|
||||
msg = _('Select data')
|
||||
self._show_error(msg)
|
||||
return
|
||||
|
||||
result = self._create_code()
|
||||
if result:
|
||||
self._show_error(result)
|
||||
return
|
||||
|
||||
if not self._ask:
|
||||
cell = cell.offset(0, 1)
|
||||
|
||||
cell.insert_image(self._path)
|
||||
return
|
||||
|
||||
def _insert_in_writer(self, doc):
|
||||
doc = app.get_document()
|
||||
if not self._data:
|
||||
sel = app.get_selection()
|
||||
self._data = sel.string
|
||||
if not self._data:
|
||||
msg = _('Select data')
|
||||
self._show_error(msg)
|
||||
return
|
||||
|
||||
result = self._create_code()
|
||||
if result:
|
||||
self._show_error(result)
|
||||
return
|
||||
|
||||
doc.insert_image(self._path)
|
||||
return
|
||||
|
||||
def _insert_in_draw(self, doc):
|
||||
result = self._create_code()
|
||||
if result:
|
||||
self._show_error(result)
|
||||
return
|
||||
|
||||
doc.insert_image(self._path)
|
||||
return
|
||||
|
||||
def _insert_in_impress(self, doc):
|
||||
self._insert_in_draw(doc)
|
||||
return
|
||||
|
||||
def _show_error(self, error):
|
||||
msg = _('Error in: {}\n\n{}').format(self._type, error)
|
||||
app.error(error)
|
||||
app.errorbox(msg, TITLE)
|
||||
return
|
||||
|
||||
def _create_dialog(self):
|
||||
args = {
|
||||
'Name': 'dialog',
|
||||
'Title': TITLE,
|
||||
'Width': 160,
|
||||
'Height': 160,
|
||||
}
|
||||
dlg = app.create_dialog(args)
|
||||
dlg.events = Controllers(dlg)
|
||||
dlg.id_extension = ID_EXTENSION
|
||||
|
||||
args = {
|
||||
'Type': 'Label',
|
||||
'Name': 'lbl_barcode',
|
||||
'Label': _('~Select barcode type'),
|
||||
'Width': 70,
|
||||
'Height': 15,
|
||||
'X': 10,
|
||||
'Y': 10,
|
||||
'VerticalAlign': 1,
|
||||
}
|
||||
dlg.add_control(args)
|
||||
|
||||
args = {
|
||||
'Type': 'Label',
|
||||
'Name': 'lbl_data',
|
||||
'Label': _('~Capture data for barcode'),
|
||||
'Width': 100,
|
||||
'Height': 15,
|
||||
'VerticalAlign': 1,
|
||||
}
|
||||
dlg.add_control(args)
|
||||
|
||||
args = {
|
||||
'Type': 'ListBox',
|
||||
'Name': 'listbox',
|
||||
'Width': 65,
|
||||
'Height': 15,
|
||||
'Dropdown': True,
|
||||
}
|
||||
dlg.add_control(args)
|
||||
data = ('code39', 'code128', 'ean', 'ean8', 'ean13', 'gs1', 'gtin',
|
||||
'isbn', 'isbn10', 'isbn13', 'issn', 'jan', 'pzn', 'upc', 'upca',
|
||||
'qrcode')
|
||||
dlg.listbox.data = data
|
||||
|
||||
args = {
|
||||
'Type': 'Text',
|
||||
'Name': 'text',
|
||||
'Width': 140,
|
||||
'Height': 75,
|
||||
'MultiLine': True,
|
||||
'VScroll': True,
|
||||
}
|
||||
dlg.add_control(args)
|
||||
|
||||
args = {
|
||||
'Type': 'Button',
|
||||
'Name': 'button',
|
||||
'Label': _('~Insert Barcode'),
|
||||
'Width': 70,
|
||||
'Height': 15,
|
||||
'ImageURL': 'qr.png',
|
||||
'ImagePosition': 1,
|
||||
}
|
||||
dlg.add_control(args)
|
||||
|
||||
dlg.listbox.move(dlg.lbl_barcode, 5, 0)
|
||||
dlg.lbl_data.move(dlg.lbl_barcode)
|
||||
dlg.text.move(dlg.lbl_data)
|
||||
dlg.button.move(dlg.text, 0, 10)
|
||||
dlg.button.center()
|
||||
|
||||
return dlg
|
||||
|
||||
|
||||
g_ImplementationHelper = unohelper.ImplementationHelper()
|
||||
g_ImplementationHelper.addImplementation(ZAZBarCode, ID_EXTENSION, SERVICE)
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<description xmlns="http://openoffice.org/extensions/description/2006" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:d="http://openoffice.org/extensions/description/2006">
|
||||
<identifier value="net.elmau.zaz.BarCode" />
|
||||
<version value="0.6.0" />
|
||||
<identifier value="net.elmau.zaz.BarCode"/>
|
||||
<version value="0.7.0"/>
|
||||
<display-name>
|
||||
<name lang="en">ZAZ Bar Code</name>
|
||||
<name lang="es">ZAZ Códigos de Barras</name>
|
||||
</display-name>
|
||||
<extension-description>
|
||||
<src lang="en" xlink:href="description/desc_en.txt" />
|
||||
<src lang="es" xlink:href="description/desc_es.txt" />
|
||||
<src lang="en" xlink:href="description/desc_en.txt"/>
|
||||
<src lang="es" xlink:href="description/desc_es.txt"/>
|
||||
</extension-description>
|
||||
<icon>
|
||||
<default xlink:href="images/zazbarcode.png" />
|
||||
<default xlink:href="images/zazbarcode.png"/>
|
||||
</icon>
|
||||
<publisher>
|
||||
<name xlink:href="https://gitlab.com/mauriciobaeza" lang="en">El Mau</name>
|
||||
<name xlink:href="https://gitlab.com/mauriciobaeza" lang="es">El Mau</name>
|
||||
</publisher>
|
||||
<registration>
|
||||
<simple-license accept-by="user" suppress-on-update="true" >
|
||||
<license-text xlink:href="registration/license_en.txt" lang="en" />
|
||||
<license-text xlink:href="registration/license_es.txt" lang="es" />
|
||||
<simple-license accept-by="user" suppress-on-update="true">
|
||||
<license-text xlink:href="registration/license_en.txt" lang="en"/>
|
||||
<license-text xlink:href="registration/license_es.txt" lang="es"/>
|
||||
</simple-license>
|
||||
</registration>
|
||||
<update-information>
|
||||
<src xlink:href="https://gitlab.com/mauriciobaeza/zaz-barcode/raw/master/files/zazbarcode.update.xml" />
|
||||
</update-information>
|
||||
<update-information>
|
||||
<src xlink:href="https://gitlab.com/mauriciobaeza/zaz-barcode/raw/master/files/zazbarcode.update.xml"/>
|
||||
</update-information>
|
||||
</description>
|
||||
|
|
|
@ -1,57 +1,73 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
||||
pyBarcode
|
||||
=========
|
||||
|
||||
This package provides a simple way to create standard barcodes.
|
||||
"""This package provides a simple way to create standard barcodes.
|
||||
It needs no external packages to be installed, the barcodes are
|
||||
created as SVG objects. If Pillow is installed, the barcodes can also be
|
||||
rendered as images (all formats supported by Pillow).
|
||||
"""
|
||||
import os
|
||||
from typing import BinaryIO
|
||||
from typing import Dict
|
||||
from typing import Union
|
||||
|
||||
from barcode.codex import Code128
|
||||
from barcode.codex import Code39
|
||||
from barcode.codex import Gs1_128
|
||||
from barcode.codex import PZN
|
||||
from barcode.ean import EAN13
|
||||
from barcode.ean import EAN14
|
||||
from barcode.ean import EAN8
|
||||
from barcode.ean import JAN
|
||||
from barcode.errors import BarcodeNotFoundError
|
||||
from barcode.codex import Code39, PZN, Code128, Gs1_128
|
||||
from barcode.ean import EAN8, EAN13, EAN14, JAN
|
||||
from barcode.isxn import ISBN10, ISBN13, ISSN
|
||||
from barcode.upc import UPCA
|
||||
from barcode.isxn import ISBN10
|
||||
from barcode.isxn import ISBN13
|
||||
from barcode.isxn import ISSN
|
||||
from barcode.itf import ITF
|
||||
from barcode.upc import UPCA
|
||||
from barcode.version import version # noqa: F401
|
||||
|
||||
|
||||
__BARCODE_MAP = dict(
|
||||
ean8=EAN8,
|
||||
ean13=EAN13,
|
||||
ean=EAN13,
|
||||
gtin=EAN14,
|
||||
ean14=EAN14,
|
||||
jan=JAN,
|
||||
upc=UPCA,
|
||||
upca=UPCA,
|
||||
isbn=ISBN13,
|
||||
isbn13=ISBN13,
|
||||
gs1=ISBN13,
|
||||
isbn10=ISBN10,
|
||||
issn=ISSN,
|
||||
code39=Code39,
|
||||
pzn=PZN,
|
||||
code128=Code128,
|
||||
itf=ITF,
|
||||
gs1_128=Gs1_128,
|
||||
)
|
||||
__BARCODE_MAP = {
|
||||
"ean8": EAN8,
|
||||
"ean13": EAN13,
|
||||
"ean": EAN13,
|
||||
"gtin": EAN14,
|
||||
"ean14": EAN14,
|
||||
"jan": JAN,
|
||||
"upc": UPCA,
|
||||
"upca": UPCA,
|
||||
"isbn": ISBN13,
|
||||
"isbn13": ISBN13,
|
||||
"gs1": ISBN13,
|
||||
"isbn10": ISBN10,
|
||||
"issn": ISSN,
|
||||
"code39": Code39,
|
||||
"pzn": PZN,
|
||||
"code128": Code128,
|
||||
"itf": ITF,
|
||||
"gs1_128": Gs1_128,
|
||||
}
|
||||
|
||||
PROVIDED_BARCODES = list(__BARCODE_MAP)
|
||||
PROVIDED_BARCODES.sort()
|
||||
|
||||
|
||||
def get(name, code=None, writer=None, options=None):
|
||||
"""Helper method for getting a generator or even a generated code.
|
||||
|
||||
:param str name: The name of the type of barcode desired.
|
||||
:param str code: The actual information to encode. If this parameter is
|
||||
provided, a generated barcode is returned. Otherwise, the barcode class
|
||||
is returned.
|
||||
:param Writer writer: An alternative writer to use when generating the
|
||||
barcode.
|
||||
:param dict options: Additional options to be passed on to the barcode when
|
||||
generating.
|
||||
"""
|
||||
options = options or {}
|
||||
try:
|
||||
barcode = __BARCODE_MAP[name.lower()]
|
||||
except KeyError:
|
||||
raise BarcodeNotFoundError('The barcode {0!r} you requested is not '
|
||||
'known.'.format(name))
|
||||
raise BarcodeNotFoundError(
|
||||
"The barcode {!r} you requested is not known.".format(name)
|
||||
)
|
||||
if code is not None:
|
||||
return barcode(code, writer, **options)
|
||||
else:
|
||||
|
@ -62,17 +78,38 @@ def get_class(name):
|
|||
return get_barcode(name)
|
||||
|
||||
|
||||
def generate(name, code, writer=None, output=None, writer_options=None,
|
||||
text=None, pil=False):
|
||||
options = writer_options or {}
|
||||
barcode = get(name, code, writer, options)
|
||||
if pil:
|
||||
return barcode.render(writer_options, text)
|
||||
def generate(
|
||||
name: str,
|
||||
code: str,
|
||||
writer=None,
|
||||
output: Union[str, os.PathLike, BinaryIO] = None,
|
||||
writer_options: Dict = None,
|
||||
text: str = None,
|
||||
):
|
||||
"""Shortcut to generate a barcode in one line.
|
||||
|
||||
:param name: Name of the type of barcode to use.
|
||||
:param code: Data to encode into the barcode.
|
||||
:param writer: A writer to use (e.g.: ImageWriter or SVGWriter).
|
||||
:param output: Destination file-like or path-like where to save the generated
|
||||
barcode.
|
||||
:param writer_options: Options to pass on to the writer instance.
|
||||
:param text: Text to render under the barcode.
|
||||
"""
|
||||
from barcode.base import Barcode
|
||||
|
||||
writer = writer or Barcode.default_writer()
|
||||
writer.set_options(writer_options or {})
|
||||
|
||||
barcode = get(name, code, writer)
|
||||
|
||||
if isinstance(output, str):
|
||||
fullname = barcode.save(output, options, text)
|
||||
fullname = barcode.save(output, writer_options, text)
|
||||
return fullname
|
||||
elif output:
|
||||
barcode.write(output, writer_options, text)
|
||||
else:
|
||||
barcode.write(output, options, text)
|
||||
raise TypeError("'output' cannot be None")
|
||||
|
||||
|
||||
get_barcode = get
|
||||
|
|
|
@ -1,43 +1,37 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
"""barcode.base
|
||||
|
||||
"""
|
||||
|
||||
from barcode.writer import SVGWriter
|
||||
|
||||
|
||||
class Barcode(object):
|
||||
class Barcode:
|
||||
|
||||
name = ''
|
||||
name = ""
|
||||
|
||||
digits = 0
|
||||
|
||||
default_writer = SVGWriter
|
||||
|
||||
default_writer_options = {
|
||||
'module_width': 0.2,
|
||||
'module_height': 15.0,
|
||||
'quiet_zone': 6.5,
|
||||
'font_size': 10,
|
||||
'text_distance': 5.0,
|
||||
'background': 'white',
|
||||
'foreground': 'black',
|
||||
'write_text': True,
|
||||
'text': '',
|
||||
"module_width": 0.2,
|
||||
"module_height": 15.0,
|
||||
"quiet_zone": 6.5,
|
||||
"font_size": 10,
|
||||
"text_distance": 5.0,
|
||||
"background": "white",
|
||||
"foreground": "black",
|
||||
"write_text": True,
|
||||
"text": "",
|
||||
}
|
||||
|
||||
def to_ascii(self):
|
||||
code = self.build()
|
||||
for i, line in enumerate(code):
|
||||
code[i] = line.replace('1', 'X').replace('0', ' ')
|
||||
return '\n'.join(code)
|
||||
code[i] = line.replace("1", "X").replace("0", " ")
|
||||
return "\n".join(code)
|
||||
|
||||
def __repr__(self):
|
||||
return '<{0}({1!r})>'.format(self.__class__.__name__,
|
||||
self.get_fullcode())
|
||||
return "<{}({!r})>".format(self.__class__.__name__, self.get_fullcode())
|
||||
|
||||
def build(self):
|
||||
raise NotImplementedError
|
||||
|
@ -59,7 +53,7 @@ class Barcode(object):
|
|||
extension).
|
||||
options : Dict
|
||||
The same as in `self.render`.
|
||||
text : str (unicode on Python 2)
|
||||
text : str
|
||||
Text to render under the barcode.
|
||||
|
||||
:returns: The full filename with extension.
|
||||
|
@ -82,14 +76,11 @@ class Barcode(object):
|
|||
Object to write the raw data in.
|
||||
options : Dict
|
||||
The same as in `self.render`.
|
||||
text : str (unicode on Python 2)
|
||||
text : str
|
||||
Text to render under the barcode.
|
||||
"""
|
||||
output = self.render(options, text)
|
||||
if hasattr(output, 'tostring'):
|
||||
output.save(fp, format=self.writer.format)
|
||||
else:
|
||||
fp.write(output)
|
||||
self.writer.write(output, fp)
|
||||
|
||||
def render(self, writer_options=None, text=None):
|
||||
"""Renders the barcode using `self.writer`.
|
||||
|
@ -97,18 +88,18 @@ class Barcode(object):
|
|||
:parameters:
|
||||
writer_options : Dict
|
||||
Options for `self.writer`, see writer docs for details.
|
||||
text : str (unicode on Python 2)
|
||||
text : str
|
||||
Text to render under the barcode.
|
||||
|
||||
:returns: Output of the writers render method.
|
||||
"""
|
||||
options = Barcode.default_writer_options.copy()
|
||||
options.update(writer_options or {})
|
||||
if options['write_text'] or text is not None:
|
||||
if options["write_text"] or text is not None:
|
||||
if text is not None:
|
||||
options['text'] = text
|
||||
options["text"] = text
|
||||
else:
|
||||
options['text'] = self.get_fullcode()
|
||||
options["text"] = self.get_fullcode()
|
||||
self.writer.set_options(options)
|
||||
code = self.build()
|
||||
raw = self.writer.render(code)
|
||||
|
|
|
@ -1,64 +1,223 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import string
|
||||
|
||||
# Charsets for code 128
|
||||
|
||||
_common = (
|
||||
' ', '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',',
|
||||
'-', '.', '/',
|
||||
) + tuple(string.digits) + (
|
||||
':', ';', '<', '=', '>', '?', '@',
|
||||
) + tuple(string.ascii_uppercase) + (
|
||||
'[', '\\', ']', '^', '_',
|
||||
(
|
||||
" ",
|
||||
"!",
|
||||
'"',
|
||||
"#",
|
||||
"$",
|
||||
"%",
|
||||
"&",
|
||||
"'",
|
||||
"(",
|
||||
")",
|
||||
"*",
|
||||
"+",
|
||||
",",
|
||||
"-",
|
||||
".",
|
||||
"/",
|
||||
)
|
||||
+ tuple(string.digits)
|
||||
+ (
|
||||
":",
|
||||
";",
|
||||
"<",
|
||||
"=",
|
||||
">",
|
||||
"?",
|
||||
"@",
|
||||
)
|
||||
+ tuple(string.ascii_uppercase)
|
||||
+ (
|
||||
"[",
|
||||
"\\",
|
||||
"]",
|
||||
"^",
|
||||
"_",
|
||||
)
|
||||
)
|
||||
|
||||
_charset_a = _common + (
|
||||
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08',
|
||||
'\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11',
|
||||
'\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', '\x1a',
|
||||
'\x1b', '\x1c', '\x1d', '\x1e', '\x1f', '\xf3', '\xf2', 'SHIFT', 'TO_C',
|
||||
'TO_B', '\xf4', '\xf1',
|
||||
"\x00",
|
||||
"\x01",
|
||||
"\x02",
|
||||
"\x03",
|
||||
"\x04",
|
||||
"\x05",
|
||||
"\x06",
|
||||
"\x07",
|
||||
"\x08",
|
||||
"\x09",
|
||||
"\x0a",
|
||||
"\x0b",
|
||||
"\x0c",
|
||||
"\x0d",
|
||||
"\x0e",
|
||||
"\x0f",
|
||||
"\x10",
|
||||
"\x11",
|
||||
"\x12",
|
||||
"\x13",
|
||||
"\x14",
|
||||
"\x15",
|
||||
"\x16",
|
||||
"\x17",
|
||||
"\x18",
|
||||
"\x19",
|
||||
"\x1a",
|
||||
"\x1b",
|
||||
"\x1c",
|
||||
"\x1d",
|
||||
"\x1e",
|
||||
"\x1f",
|
||||
"\xf3",
|
||||
"\xf2",
|
||||
"SHIFT",
|
||||
"TO_C",
|
||||
"TO_B",
|
||||
"\xf4",
|
||||
"\xf1",
|
||||
)
|
||||
|
||||
_charset_b = _common + ('`',) + tuple(string.ascii_lowercase) + (
|
||||
'{', '|', '}', '~', '\x7f', '\xf3', '\xf2', 'SHIFT', 'TO_C', '\xf4',
|
||||
'TO_A', '\xf1',
|
||||
_charset_b = (
|
||||
_common
|
||||
+ ("`",)
|
||||
+ tuple(string.ascii_lowercase)
|
||||
+ (
|
||||
"{",
|
||||
"|",
|
||||
"}",
|
||||
"~",
|
||||
"\x7f",
|
||||
"\xf3",
|
||||
"\xf2",
|
||||
"SHIFT",
|
||||
"TO_C",
|
||||
"\xf4",
|
||||
"TO_A",
|
||||
"\xf1",
|
||||
)
|
||||
)
|
||||
|
||||
ALL = set(_common + _charset_a + _charset_b)
|
||||
A = dict(((c, i) for i, c in enumerate(_charset_a)))
|
||||
B = dict(((c, i) for i, c in enumerate(_charset_b)))
|
||||
C = {'TO_B': 100, 'TO_A': 101, '\xf1': 102}
|
||||
A = {c: i for i, c in enumerate(_charset_a)}
|
||||
B = {c: i for i, c in enumerate(_charset_b)}
|
||||
C = {"TO_B": 100, "TO_A": 101, "\xf1": 102}
|
||||
|
||||
CODES = (
|
||||
'11011001100', '11001101100', '11001100110', '10010011000', '10010001100',
|
||||
'10001001100', '10011001000', '10011000100', '10001100100', '11001001000',
|
||||
'11001000100', '11000100100', '10110011100', '10011011100', '10011001110',
|
||||
'10111001100', '10011101100', '10011100110', '11001110010', '11001011100',
|
||||
'11001001110', '11011100100', '11001110100', '11101101110', '11101001100',
|
||||
'11100101100', '11100100110', '11101100100', '11100110100', '11100110010',
|
||||
'11011011000', '11011000110', '11000110110', '10100011000', '10001011000',
|
||||
'10001000110', '10110001000', '10001101000', '10001100010', '11010001000',
|
||||
'11000101000', '11000100010', '10110111000', '10110001110', '10001101110',
|
||||
'10111011000', '10111000110', '10001110110', '11101110110', '11010001110',
|
||||
'11000101110', '11011101000', '11011100010', '11011101110', '11101011000',
|
||||
'11101000110', '11100010110', '11101101000', '11101100010', '11100011010',
|
||||
'11101111010', '11001000010', '11110001010', '10100110000', '10100001100',
|
||||
'10010110000', '10010000110', '10000101100', '10000100110', '10110010000',
|
||||
'10110000100', '10011010000', '10011000010', '10000110100', '10000110010',
|
||||
'11000010010', '11001010000', '11110111010', '11000010100', '10001111010',
|
||||
'10100111100', '10010111100', '10010011110', '10111100100', '10011110100',
|
||||
'10011110010', '11110100100', '11110010100', '11110010010', '11011011110',
|
||||
'11011110110', '11110110110', '10101111000', '10100011110', '10001011110',
|
||||
'10111101000', '10111100010', '11110101000', '11110100010', '10111011110',
|
||||
'10111101110', '11101011110', '11110101110', '11010000100', '11010010000',
|
||||
'11010011100',
|
||||
"11011001100",
|
||||
"11001101100",
|
||||
"11001100110",
|
||||
"10010011000",
|
||||
"10010001100",
|
||||
"10001001100",
|
||||
"10011001000",
|
||||
"10011000100",
|
||||
"10001100100",
|
||||
"11001001000",
|
||||
"11001000100",
|
||||
"11000100100",
|
||||
"10110011100",
|
||||
"10011011100",
|
||||
"10011001110",
|
||||
"10111001100",
|
||||
"10011101100",
|
||||
"10011100110",
|
||||
"11001110010",
|
||||
"11001011100",
|
||||
"11001001110",
|
||||
"11011100100",
|
||||
"11001110100",
|
||||
"11101101110",
|
||||
"11101001100",
|
||||
"11100101100",
|
||||
"11100100110",
|
||||
"11101100100",
|
||||
"11100110100",
|
||||
"11100110010",
|
||||
"11011011000",
|
||||
"11011000110",
|
||||
"11000110110",
|
||||
"10100011000",
|
||||
"10001011000",
|
||||
"10001000110",
|
||||
"10110001000",
|
||||
"10001101000",
|
||||
"10001100010",
|
||||
"11010001000",
|
||||
"11000101000",
|
||||
"11000100010",
|
||||
"10110111000",
|
||||
"10110001110",
|
||||
"10001101110",
|
||||
"10111011000",
|
||||
"10111000110",
|
||||
"10001110110",
|
||||
"11101110110",
|
||||
"11010001110",
|
||||
"11000101110",
|
||||
"11011101000",
|
||||
"11011100010",
|
||||
"11011101110",
|
||||
"11101011000",
|
||||
"11101000110",
|
||||
"11100010110",
|
||||
"11101101000",
|
||||
"11101100010",
|
||||
"11100011010",
|
||||
"11101111010",
|
||||
"11001000010",
|
||||
"11110001010",
|
||||
"10100110000",
|
||||
"10100001100",
|
||||
"10010110000",
|
||||
"10010000110",
|
||||
"10000101100",
|
||||
"10000100110",
|
||||
"10110010000",
|
||||
"10110000100",
|
||||
"10011010000",
|
||||
"10011000010",
|
||||
"10000110100",
|
||||
"10000110010",
|
||||
"11000010010",
|
||||
"11001010000",
|
||||
"11110111010",
|
||||
"11000010100",
|
||||
"10001111010",
|
||||
"10100111100",
|
||||
"10010111100",
|
||||
"10010011110",
|
||||
"10111100100",
|
||||
"10011110100",
|
||||
"10011110010",
|
||||
"11110100100",
|
||||
"11110010100",
|
||||
"11110010010",
|
||||
"11011011110",
|
||||
"11011110110",
|
||||
"11110110110",
|
||||
"10101111000",
|
||||
"10100011110",
|
||||
"10001011110",
|
||||
"10111101000",
|
||||
"10111100010",
|
||||
"11110101000",
|
||||
"11110100010",
|
||||
"10111011110",
|
||||
"10111101110",
|
||||
"11101011110",
|
||||
"11110101110",
|
||||
"11010000100",
|
||||
"11010010000",
|
||||
"11010011100",
|
||||
)
|
||||
|
||||
STOP = '11000111010'
|
||||
STOP = "11000111010"
|
||||
|
||||
START_CODES = {'A': 103, 'B': 104, 'C': 105}
|
||||
TO = {101: START_CODES['A'], 100: START_CODES['B'], 99: START_CODES['C']}
|
||||
START_CODES = {"A": 103, "B": 104, "C": 105}
|
||||
TO = {101: START_CODES["A"], 100: START_CODES["B"], 99: START_CODES["C"]}
|
||||
|
|
|
@ -1,34 +1,61 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import string
|
||||
|
||||
# Charsets for code 39
|
||||
REF = (tuple(string.digits) + tuple(string.ascii_uppercase) +
|
||||
('-', '.', ' ', '$', '/', '+', '%'))
|
||||
B = '1'
|
||||
E = '0'
|
||||
REF = (
|
||||
tuple(string.digits)
|
||||
+ tuple(string.ascii_uppercase)
|
||||
+ ("-", ".", " ", "$", "/", "+", "%")
|
||||
)
|
||||
B = "1"
|
||||
E = "0"
|
||||
CODES = (
|
||||
'101000111011101', '111010001010111', '101110001010111',
|
||||
'111011100010101', '101000111010111', '111010001110101',
|
||||
'101110001110101', '101000101110111', '111010001011101',
|
||||
'101110001011101', '111010100010111', '101110100010111',
|
||||
'111011101000101', '101011100010111', '111010111000101',
|
||||
'101110111000101', '101010001110111', '111010100011101',
|
||||
'101110100011101', '101011100011101', '111010101000111',
|
||||
'101110101000111', '111011101010001', '101011101000111',
|
||||
'111010111010001', '101110111010001', '101010111000111',
|
||||
'111010101110001', '101110101110001', '101011101110001',
|
||||
'111000101010111', '100011101010111', '111000111010101',
|
||||
'100010111010111', '111000101110101', '100011101110101',
|
||||
'100010101110111', '111000101011101', '100011101011101',
|
||||
'100010001000101', '100010001010001', '100010100010001',
|
||||
'101000100010001',
|
||||
"101000111011101",
|
||||
"111010001010111",
|
||||
"101110001010111",
|
||||
"111011100010101",
|
||||
"101000111010111",
|
||||
"111010001110101",
|
||||
"101110001110101",
|
||||
"101000101110111",
|
||||
"111010001011101",
|
||||
"101110001011101",
|
||||
"111010100010111",
|
||||
"101110100010111",
|
||||
"111011101000101",
|
||||
"101011100010111",
|
||||
"111010111000101",
|
||||
"101110111000101",
|
||||
"101010001110111",
|
||||
"111010100011101",
|
||||
"101110100011101",
|
||||
"101011100011101",
|
||||
"111010101000111",
|
||||
"101110101000111",
|
||||
"111011101010001",
|
||||
"101011101000111",
|
||||
"111010111010001",
|
||||
"101110111010001",
|
||||
"101010111000111",
|
||||
"111010101110001",
|
||||
"101110101110001",
|
||||
"101011101110001",
|
||||
"111000101010111",
|
||||
"100011101010111",
|
||||
"111000111010101",
|
||||
"100010111010111",
|
||||
"111000101110101",
|
||||
"100011101110101",
|
||||
"100010101110111",
|
||||
"111000101011101",
|
||||
"100011101011101",
|
||||
"100010001000101",
|
||||
"100010001010001",
|
||||
"100010100010001",
|
||||
"101000100010001",
|
||||
)
|
||||
|
||||
EDGE = '100010111011101'
|
||||
MIDDLE = '0'
|
||||
EDGE = "100010111011101"
|
||||
MIDDLE = "0"
|
||||
|
||||
# MAP for assigning every symbol (REF) to (reference number, barcode)
|
||||
MAP = dict(zip(REF, enumerate(CODES)))
|
||||
|
|
|
@ -1,17 +1,52 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
EDGE = '101'
|
||||
MIDDLE = '01010'
|
||||
EDGE = "101"
|
||||
MIDDLE = "01010"
|
||||
CODES = {
|
||||
'A': ('0001101', '0011001', '0010011', '0111101', '0100011',
|
||||
'0110001', '0101111', '0111011', '0110111', '0001011'),
|
||||
'B': ('0100111', '0110011', '0011011', '0100001', '0011101',
|
||||
'0111001', '0000101', '0010001', '0001001', '0010111'),
|
||||
'C': ('1110010', '1100110', '1101100', '1000010', '1011100',
|
||||
'1001110', '1010000', '1000100', '1001000', '1110100'),
|
||||
"A": (
|
||||
"0001101",
|
||||
"0011001",
|
||||
"0010011",
|
||||
"0111101",
|
||||
"0100011",
|
||||
"0110001",
|
||||
"0101111",
|
||||
"0111011",
|
||||
"0110111",
|
||||
"0001011",
|
||||
),
|
||||
"B": (
|
||||
"0100111",
|
||||
"0110011",
|
||||
"0011011",
|
||||
"0100001",
|
||||
"0011101",
|
||||
"0111001",
|
||||
"0000101",
|
||||
"0010001",
|
||||
"0001001",
|
||||
"0010111",
|
||||
),
|
||||
"C": (
|
||||
"1110010",
|
||||
"1100110",
|
||||
"1101100",
|
||||
"1000010",
|
||||
"1011100",
|
||||
"1001110",
|
||||
"1010000",
|
||||
"1000100",
|
||||
"1001000",
|
||||
"1110100",
|
||||
),
|
||||
}
|
||||
LEFT_PATTERN = ('AAAAAA', 'AABABB', 'AABBAB', 'AABBBA', 'ABAABB',
|
||||
'ABBAAB', 'ABBBAA', 'ABABAB', 'ABABBA', 'ABBABA')
|
||||
LEFT_PATTERN = (
|
||||
"AAAAAA",
|
||||
"AABABB",
|
||||
"AABBAB",
|
||||
"AABBBA",
|
||||
"ABAABB",
|
||||
"ABBAAB",
|
||||
"ABBBAA",
|
||||
"ABABAB",
|
||||
"ABABBA",
|
||||
"ABBABA",
|
||||
)
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# W = Wide bar
|
||||
# w = wide space
|
||||
# N = Narrow bar
|
||||
# n = narrow space
|
||||
|
||||
START = 'NnNn'
|
||||
STOP = 'WnN'
|
||||
CODES = ('NNWWN', 'WNNNW', 'NWNNW', 'WWNNN', 'NNWNW', 'WNWNN', 'NWWNN', 'NNNWW', 'WNNWN', 'NWNWN')
|
||||
START = "NnNn"
|
||||
STOP = "WnN"
|
||||
CODES = (
|
||||
"NNWWN",
|
||||
"WNNNW",
|
||||
"NWNNW",
|
||||
"WWNNN",
|
||||
"NNWNW",
|
||||
"WNWNN",
|
||||
"NWWNN",
|
||||
"NNNWW",
|
||||
"WNNWN",
|
||||
"NWNWN",
|
||||
)
|
||||
|
|
|
@ -1,13 +1,28 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
EDGE = '101'
|
||||
MIDDLE = '01010'
|
||||
EDGE = "101"
|
||||
MIDDLE = "01010"
|
||||
CODES = {
|
||||
'L': ('0001101', '0011001', '0010011', '0111101', '0100011',
|
||||
'0110001', '0101111', '0111011', '0110111', '0001011'),
|
||||
'R': ('1110010', '1100110', '1101100', '1000010', '1011100',
|
||||
'1001110', '1010000', '1000100', '1001000', '1110100')
|
||||
"L": (
|
||||
"0001101",
|
||||
"0011001",
|
||||
"0010011",
|
||||
"0111101",
|
||||
"0100011",
|
||||
"0110001",
|
||||
"0101111",
|
||||
"0111011",
|
||||
"0110111",
|
||||
"0001011",
|
||||
),
|
||||
"R": (
|
||||
"1110010",
|
||||
"1100110",
|
||||
"1101100",
|
||||
"1000010",
|
||||
"1011100",
|
||||
"1001110",
|
||||
"1010000",
|
||||
"1000100",
|
||||
"1001000",
|
||||
"1110100",
|
||||
),
|
||||
}
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from barcode.base import Barcode
|
||||
from barcode.charsets import code128, code39
|
||||
from barcode.errors import *
|
||||
|
||||
"""Module: barcode.codex
|
||||
|
||||
:Provided barcodes: Code 39, Code 128, PZN
|
||||
"""
|
||||
__docformat__ = 'restructuredtext en'
|
||||
from barcode.base import Barcode
|
||||
from barcode.charsets import code128
|
||||
from barcode.charsets import code39
|
||||
from barcode.errors import BarcodeError
|
||||
from barcode.errors import IllegalCharacterError
|
||||
from barcode.errors import NumberOfDigitsError
|
||||
|
||||
__docformat__ = "restructuredtext en"
|
||||
|
||||
# Sizes
|
||||
MIN_SIZE = 0.2
|
||||
|
@ -25,43 +23,40 @@ def check_code(code, name, allowed):
|
|||
wrong.append(char)
|
||||
if wrong:
|
||||
raise IllegalCharacterError(
|
||||
'The following characters are not valid for '
|
||||
'{name}: {wrong}'.format(name=name, wrong=', '.join(wrong))
|
||||
"The following characters are not valid for {name}: {wrong}".format(
|
||||
name=name, wrong=", ".join(wrong)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class Code39(Barcode):
|
||||
"""Initializes a new Code39 instance.
|
||||
"""A Code39 barcode implementation"""
|
||||
|
||||
:parameters:
|
||||
code : String
|
||||
Code 39 string without \* and checksum (added automatically if
|
||||
`add_checksum` is True).
|
||||
writer : barcode.writer Instance
|
||||
The writer to render the barcode (default: SVGWriter).
|
||||
add_checksum : Boolean
|
||||
Add the checksum to code or not (default: True).
|
||||
"""
|
||||
name = "Code 39"
|
||||
|
||||
name = 'Code 39'
|
||||
def __init__(self, code: str, writer=None, add_checksum: bool = True):
|
||||
r"""
|
||||
:param code: Code 39 string without \* and without checksum.
|
||||
:param writer: A ``barcode.writer`` instance used to render the barcode
|
||||
(default: SVGWriter).
|
||||
:param add_checksum: Add the checksum to code or not
|
||||
"""
|
||||
|
||||
def __init__(self, code, writer=None, add_checksum=True):
|
||||
self.code = code.upper()
|
||||
if add_checksum:
|
||||
self.code += self.calculate_checksum()
|
||||
self.writer = writer or Barcode.default_writer()
|
||||
check_code(self.code, self.name, code39.REF)
|
||||
|
||||
def __unicode__(self):
|
||||
def __str__(self):
|
||||
return self.code
|
||||
|
||||
__str__ = __unicode__
|
||||
|
||||
def get_fullcode(self):
|
||||
def get_fullcode(self) -> str:
|
||||
""":returns: The full code as it will be encoded."""
|
||||
return self.code
|
||||
|
||||
def calculate_checksum(self):
|
||||
check = sum([code39.MAP[x][0] for x in self.code]) % 43
|
||||
check = sum(code39.MAP[x][0] for x in self.code) % 43
|
||||
for k, v in code39.MAP.items():
|
||||
if check == v[0]:
|
||||
return k
|
||||
|
@ -74,7 +69,7 @@ class Code39(Barcode):
|
|||
return [code39.MIDDLE.join(chars)]
|
||||
|
||||
def render(self, writer_options=None, text=None):
|
||||
options = dict(module_width=MIN_SIZE, quiet_zone=MIN_QUIET_ZONE)
|
||||
options = {"module_width": MIN_SIZE, "quiet_zone": MIN_QUIET_ZONE}
|
||||
options.update(writer_options or {})
|
||||
return Barcode.render(self, options, text)
|
||||
|
||||
|
@ -89,30 +84,30 @@ class PZN7(Code39):
|
|||
The writer to render the barcode (default: SVGWriter).
|
||||
"""
|
||||
|
||||
name = 'Pharmazentralnummer'
|
||||
name = "Pharmazentralnummer"
|
||||
|
||||
digits = 6
|
||||
|
||||
def __init__(self, pzn, writer=None):
|
||||
pzn = pzn[:self.digits]
|
||||
pzn = pzn[: self.digits]
|
||||
if not pzn.isdigit():
|
||||
raise IllegalCharacterError('PZN can only contain numbers.')
|
||||
raise IllegalCharacterError("PZN can only contain numbers.")
|
||||
if len(pzn) != self.digits:
|
||||
raise NumberOfDigitsError('PZN must have {0} digits, not '
|
||||
'{1}.'.format(self.digits, len(pzn)))
|
||||
raise NumberOfDigitsError(
|
||||
"PZN must have {} digits, not {}.".format(self.digits, len(pzn))
|
||||
)
|
||||
self.pzn = pzn
|
||||
self.pzn = '{0}{1}'.format(pzn, self.calculate_checksum())
|
||||
Code39.__init__(self, 'PZN-{0}'.format(self.pzn), writer,
|
||||
add_checksum=False)
|
||||
self.pzn = "{}{}".format(pzn, self.calculate_checksum())
|
||||
Code39.__init__(self, "PZN-{}".format(self.pzn), writer, add_checksum=False)
|
||||
|
||||
def get_fullcode(self):
|
||||
return 'PZN-{0}'.format(self.pzn)
|
||||
return "PZN-{}".format(self.pzn)
|
||||
|
||||
def calculate_checksum(self):
|
||||
sum_ = sum([int(x) * int(y) for x, y in enumerate(self.pzn, start=2)])
|
||||
sum_ = sum(int(x) * int(y) for x, y in enumerate(self.pzn, start=2))
|
||||
checksum = sum_ % 11
|
||||
if checksum == 10:
|
||||
raise BarcodeError('Checksum can not be 10 for PZN.')
|
||||
raise BarcodeError("Checksum can not be 10 for PZN.")
|
||||
else:
|
||||
return checksum
|
||||
|
||||
|
@ -134,20 +129,18 @@ class Code128(Barcode):
|
|||
The writer to render the barcode (default: SVGWriter).
|
||||
"""
|
||||
|
||||
name = 'Code 128'
|
||||
name = "Code 128"
|
||||
|
||||
def __init__(self, code, writer=None):
|
||||
self.code = code
|
||||
self.writer = writer or Barcode.default_writer()
|
||||
self._charset = 'B'
|
||||
self._buffer = ''
|
||||
self._charset = "B"
|
||||
self._buffer = ""
|
||||
check_code(self.code, self.name, code128.ALL)
|
||||
|
||||
def __unicode__(self):
|
||||
def __str__(self):
|
||||
return self.code
|
||||
|
||||
__str__ = __unicode__
|
||||
|
||||
@property
|
||||
def encoded(self):
|
||||
return self._build()
|
||||
|
@ -156,18 +149,18 @@ class Code128(Barcode):
|
|||
return self.code
|
||||
|
||||
def _new_charset(self, which):
|
||||
if which == 'A':
|
||||
code = self._convert('TO_A')
|
||||
elif which == 'B':
|
||||
code = self._convert('TO_B')
|
||||
elif which == 'C':
|
||||
code = self._convert('TO_C')
|
||||
if which == "A":
|
||||
code = self._convert("TO_A")
|
||||
elif which == "B":
|
||||
code = self._convert("TO_B")
|
||||
elif which == "C":
|
||||
code = self._convert("TO_C")
|
||||
self._charset = which
|
||||
return [code]
|
||||
|
||||
def _maybe_switch_charset(self, pos):
|
||||
char = self.code[pos]
|
||||
next_ = self.code[pos:pos + 10]
|
||||
next_ = self.code[pos : pos + 10]
|
||||
|
||||
def look_next():
|
||||
digits = 0
|
||||
|
@ -176,44 +169,44 @@ class Code128(Barcode):
|
|||
digits += 1
|
||||
else:
|
||||
break
|
||||
return digits > 3
|
||||
return digits > 3 and (digits % 2) == 0
|
||||
|
||||
codes = []
|
||||
if self._charset == 'C' and not char.isdigit():
|
||||
if self._charset == "C" and not char.isdigit():
|
||||
if char in code128.B:
|
||||
codes = self._new_charset('B')
|
||||
codes = self._new_charset("B")
|
||||
elif char in code128.A:
|
||||
codes = self._new_charset('A')
|
||||
codes = self._new_charset("A")
|
||||
if len(self._buffer) == 1:
|
||||
codes.append(self._convert(self._buffer[0]))
|
||||
self._buffer = ''
|
||||
elif self._charset == 'B':
|
||||
self._buffer = ""
|
||||
elif self._charset == "B":
|
||||
if look_next():
|
||||
codes = self._new_charset('C')
|
||||
codes = self._new_charset("C")
|
||||
elif char not in code128.B:
|
||||
if char in code128.A:
|
||||
codes = self._new_charset('A')
|
||||
elif self._charset == 'A':
|
||||
codes = self._new_charset("A")
|
||||
elif self._charset == "A":
|
||||
if look_next():
|
||||
codes = self._new_charset('C')
|
||||
codes = self._new_charset("C")
|
||||
elif char not in code128.A:
|
||||
if char in code128.B:
|
||||
codes = self._new_charset('B')
|
||||
codes = self._new_charset("B")
|
||||
return codes
|
||||
|
||||
def _convert(self, char):
|
||||
if self._charset == 'A':
|
||||
if self._charset == "A":
|
||||
return code128.A[char]
|
||||
elif self._charset == 'B':
|
||||
elif self._charset == "B":
|
||||
return code128.B[char]
|
||||
elif self._charset == 'C':
|
||||
elif self._charset == "C":
|
||||
if char in code128.C:
|
||||
return code128.C[char]
|
||||
elif char.isdigit():
|
||||
self._buffer += char
|
||||
if len(self._buffer) == 2:
|
||||
value = int(self._buffer)
|
||||
self._buffer = ''
|
||||
self._buffer = ""
|
||||
return value
|
||||
|
||||
def _try_to_optimize(self, encoded):
|
||||
|
@ -236,24 +229,24 @@ class Code128(Barcode):
|
|||
encoded.append(code_num)
|
||||
# Finally look in the buffer
|
||||
if len(self._buffer) == 1:
|
||||
encoded.extend(self._new_charset('B'))
|
||||
encoded.extend(self._new_charset("B"))
|
||||
encoded.append(self._convert(self._buffer[0]))
|
||||
self._buffer = ''
|
||||
self._buffer = ""
|
||||
encoded = self._try_to_optimize(encoded)
|
||||
return encoded
|
||||
|
||||
def build(self):
|
||||
encoded = self._build()
|
||||
encoded.append(self._calculate_checksum(encoded))
|
||||
code = ''
|
||||
code = ""
|
||||
for code_num in encoded:
|
||||
code += code128.CODES[code_num]
|
||||
code += code128.STOP
|
||||
code += '11'
|
||||
code += "11"
|
||||
return [code]
|
||||
|
||||
def render(self, writer_options=None, text=None):
|
||||
options = dict(module_width=MIN_SIZE, quiet_zone=MIN_QUIET_ZONE)
|
||||
options = {"module_width": MIN_SIZE, "quiet_zone": MIN_QUIET_ZONE}
|
||||
options.update(writer_options or {})
|
||||
return Barcode.render(self, options, text)
|
||||
|
||||
|
@ -266,16 +259,16 @@ class Gs1_128(Code128):
|
|||
https://www.gs1-128.info/
|
||||
"""
|
||||
|
||||
name = 'GS1-128'
|
||||
name = "GS1-128"
|
||||
|
||||
FNC1_CHAR = '\xf1'
|
||||
FNC1_CHAR = "\xf1"
|
||||
|
||||
def __init__(self, code, writer=None):
|
||||
code = self.FNC1_CHAR + code
|
||||
super(Gs1_128, self).__init__(code, writer)
|
||||
super().__init__(code, writer)
|
||||
|
||||
def get_fullcode(self):
|
||||
return super(Gs1_128, self).get_fullcode()[1:]
|
||||
return super().get_fullcode()[1:]
|
||||
|
||||
|
||||
# For pre 0.8 compatibility
|
||||
|
|
|
@ -1,27 +1,32 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from barcode.base import Barcode
|
||||
from barcode.charsets import ean as _ean
|
||||
from barcode.errors import *
|
||||
|
||||
"""Module: barcode.ean
|
||||
|
||||
:Provided barcodes: EAN-14, EAN-13, EAN-8, JAN
|
||||
"""
|
||||
__docformat__ = 'restructuredtext en'
|
||||
__docformat__ = "restructuredtext en"
|
||||
|
||||
# Python 3
|
||||
try:
|
||||
reduce
|
||||
except NameError:
|
||||
from functools import reduce
|
||||
from functools import reduce
|
||||
|
||||
from barcode.base import Barcode
|
||||
from barcode.charsets import ean as _ean
|
||||
from barcode.errors import (
|
||||
IllegalCharacterError,
|
||||
NumberOfDigitsError,
|
||||
WrongCountryCodeError,
|
||||
)
|
||||
|
||||
# EAN13 Specs (all sizes in mm)
|
||||
SIZES = dict(SC0=0.27, SC1=0.297, SC2=0.33, SC3=0.363, SC4=0.396, SC5=0.445,
|
||||
SC6=0.495, SC7=0.544, SC8=0.61, SC9=0.66)
|
||||
SIZES = {
|
||||
"SC0": 0.27,
|
||||
"SC1": 0.297,
|
||||
"SC2": 0.33,
|
||||
"SC3": 0.363,
|
||||
"SC4": 0.396,
|
||||
"SC5": 0.445,
|
||||
"SC6": 0.495,
|
||||
"SC7": 0.544,
|
||||
"SC8": 0.61,
|
||||
"SC9": 0.66,
|
||||
}
|
||||
|
||||
|
||||
class EuropeanArticleNumber13(Barcode):
|
||||
|
@ -34,37 +39,36 @@ class EuropeanArticleNumber13(Barcode):
|
|||
The writer to render the barcode (default: SVGWriter).
|
||||
"""
|
||||
|
||||
name = 'EAN-13'
|
||||
name = "EAN-13"
|
||||
|
||||
digits = 12
|
||||
|
||||
def __init__(self, ean, writer=None, **kwargs):
|
||||
no_checksum = False
|
||||
if "no_checksum" in kwargs.keys():
|
||||
no_checksum = kwargs["no_checksum"]
|
||||
ean = ean[:self.digits]
|
||||
def __init__(self, ean, writer=None, no_checksum=False):
|
||||
ean = ean[: self.digits]
|
||||
if not ean.isdigit():
|
||||
raise IllegalCharacterError('EAN code can only contain numbers.')
|
||||
raise IllegalCharacterError("EAN code can only contain numbers.")
|
||||
if len(ean) != self.digits:
|
||||
raise NumberOfDigitsError('EAN must have {0} digits, not '
|
||||
'{1}.'.format(self.digits, len(ean)))
|
||||
raise NumberOfDigitsError(
|
||||
"EAN must have {} digits, not {}.".format(
|
||||
self.digits,
|
||||
len(ean),
|
||||
)
|
||||
)
|
||||
self.ean = ean
|
||||
# If no checksum
|
||||
if no_checksum:
|
||||
# Add a thirteen char if given in parameter,
|
||||
# otherwise pad with zero
|
||||
self.ean = '{0}{1}'.format(
|
||||
self.ean = "{}{}".format(
|
||||
ean, ean[self.digits] if len(ean) > self.digits else 0
|
||||
)
|
||||
else:
|
||||
self.ean = '{0}{1}'.format(ean, self.calculate_checksum())
|
||||
self.ean = "{}{}".format(ean, self.calculate_checksum())
|
||||
self.writer = writer or Barcode.default_writer()
|
||||
|
||||
def __unicode__(self):
|
||||
def __str__(self):
|
||||
return self.ean
|
||||
|
||||
__str__ = __unicode__
|
||||
|
||||
def get_fullcode(self):
|
||||
return self.ean
|
||||
|
||||
|
@ -74,7 +78,10 @@ class EuropeanArticleNumber13(Barcode):
|
|||
:returns: The checksum for `self.ean`.
|
||||
:rtype: Integer
|
||||
"""
|
||||
def sum_(x, y): return int(x) + int(y)
|
||||
|
||||
def sum_(x, y):
|
||||
return int(x) + int(y)
|
||||
|
||||
evensum = reduce(sum_, self.ean[-2::-2])
|
||||
oddsum = reduce(sum_, self.ean[-1::-2])
|
||||
return (10 - ((evensum + oddsum * 3) % 10)) % 10
|
||||
|
@ -91,7 +98,7 @@ class EuropeanArticleNumber13(Barcode):
|
|||
code += _ean.CODES[pattern[i]][int(number)]
|
||||
code += _ean.MIDDLE
|
||||
for number in self.ean[7:]:
|
||||
code += _ean.CODES['C'][int(number)]
|
||||
code += _ean.CODES["C"][int(number)]
|
||||
code += _ean.EDGE
|
||||
return [code]
|
||||
|
||||
|
@ -102,11 +109,11 @@ class EuropeanArticleNumber13(Barcode):
|
|||
"""
|
||||
code = self.build()
|
||||
for i, line in enumerate(code):
|
||||
code[i] = line.replace('1', '|').replace('0', ' ')
|
||||
return '\n'.join(code)
|
||||
code[i] = line.replace("1", "|").replace("0", " ")
|
||||
return "\n".join(code)
|
||||
|
||||
def render(self, writer_options=None, text=None):
|
||||
options = dict(module_width=SIZES['SC2'])
|
||||
options = {"module_width": SIZES["SC2"]}
|
||||
options.update(writer_options or {})
|
||||
return Barcode.render(self, options, text)
|
||||
|
||||
|
@ -121,14 +128,15 @@ class JapanArticleNumber(EuropeanArticleNumber13):
|
|||
The writer to render the barcode (default: SVGWriter).
|
||||
"""
|
||||
|
||||
name = 'JAN'
|
||||
name = "JAN"
|
||||
|
||||
valid_country_codes = list(range(450, 460)) + list(range(490, 500))
|
||||
|
||||
def __init__(self, jan, writer=None):
|
||||
if int(jan[:3]) not in JapanArticleNumber.valid_country_codes:
|
||||
raise WrongCountryCodeError("Country code isn't between 450-460 "
|
||||
"or 490-500.")
|
||||
raise WrongCountryCodeError(
|
||||
"Country code isn't between 450-460 or 490-500."
|
||||
)
|
||||
EuropeanArticleNumber13.__init__(self, jan, writer)
|
||||
|
||||
|
||||
|
@ -142,7 +150,7 @@ class EuropeanArticleNumber8(EuropeanArticleNumber13):
|
|||
The writer to render the barcode (default: SVGWriter).
|
||||
"""
|
||||
|
||||
name = 'EAN-8'
|
||||
name = "EAN-8"
|
||||
|
||||
digits = 7
|
||||
|
||||
|
@ -157,10 +165,10 @@ class EuropeanArticleNumber8(EuropeanArticleNumber13):
|
|||
"""
|
||||
code = _ean.EDGE[:]
|
||||
for number in self.ean[:4]:
|
||||
code += _ean.CODES['A'][int(number)]
|
||||
code += _ean.CODES["A"][int(number)]
|
||||
code += _ean.MIDDLE
|
||||
for number in self.ean[4:]:
|
||||
code += _ean.CODES['C'][int(number)]
|
||||
code += _ean.CODES["C"][int(number)]
|
||||
code += _ean.EDGE
|
||||
return [code]
|
||||
|
||||
|
@ -175,7 +183,7 @@ class EuropeanArticleNumber14(EuropeanArticleNumber13):
|
|||
The writer to render the barcode (default: SVGWriter).
|
||||
"""
|
||||
|
||||
name = 'EAN-14'
|
||||
name = "EAN-14"
|
||||
digits = 13
|
||||
|
||||
def calculate_checksum(self):
|
||||
|
@ -185,7 +193,8 @@ class EuropeanArticleNumber14(EuropeanArticleNumber13):
|
|||
:rtype: Integer
|
||||
"""
|
||||
|
||||
def sum_(x, y): return int(x) + int(y)
|
||||
def sum_(x, y):
|
||||
return int(x) + int(y)
|
||||
|
||||
evensum = reduce(sum_, self.ean[::2])
|
||||
oddsum = reduce(sum_, self.ean[1::2])
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
"""barcode.errors
|
||||
"""
|
||||
__docformat__ = 'restructuredtext en'
|
||||
"""barcode.errors"""
|
||||
__docformat__ = "restructuredtext en"
|
||||
|
||||
|
||||
class BarcodeError(Exception):
|
||||
|
|
|
@ -1,10 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from barcode.ean import EuropeanArticleNumber13
|
||||
from barcode.errors import *
|
||||
|
||||
"""Module: barcode.isxn
|
||||
|
||||
:Provided barcodes: ISBN-13, ISBN-10, ISSN
|
||||
|
@ -18,17 +11,21 @@ Example::
|
|||
>>> from barcode import get_barcode
|
||||
>>> ISBN = get_barcode('isbn10')
|
||||
>>> isbn = ISBN('0132354187')
|
||||
>>> unicode(isbn)
|
||||
>>> isbn
|
||||
'0132354187'
|
||||
>>> isbn.get_fullcode()
|
||||
'9780132354189'
|
||||
>>> # Test with wrong checksum
|
||||
>>> isbn = ISBN('0132354180')
|
||||
>>> unicode(isbn)
|
||||
>>> isbn
|
||||
'0132354187'
|
||||
|
||||
"""
|
||||
__docformat__ = 'restructuredtext en'
|
||||
from barcode.ean import EuropeanArticleNumber13
|
||||
from barcode.errors import BarcodeError
|
||||
from barcode.errors import WrongCountryCodeError
|
||||
|
||||
__docformat__ = "restructuredtext en"
|
||||
|
||||
|
||||
class InternationalStandardBookNumber13(EuropeanArticleNumber13):
|
||||
|
@ -41,16 +38,16 @@ class InternationalStandardBookNumber13(EuropeanArticleNumber13):
|
|||
The writer to render the barcode (default: SVGWriter).
|
||||
"""
|
||||
|
||||
name = 'ISBN-13'
|
||||
name = "ISBN-13"
|
||||
|
||||
def __init__(self, isbn, writer=None):
|
||||
isbn = isbn.replace('-', '')
|
||||
isbn = isbn.replace("-", "")
|
||||
self.isbn13 = isbn
|
||||
if isbn[:3] not in ('978', '979'):
|
||||
raise WrongCountryCodeError('ISBN must start with 978 or 979.')
|
||||
if isbn[:3] == '979':
|
||||
if isbn[3:5] not in ('10', '11'):
|
||||
raise BarcodeError('ISBN must start with 97910 or 97911.')
|
||||
if isbn[:3] not in ("978", "979"):
|
||||
raise WrongCountryCodeError("ISBN must start with 978 or 979.")
|
||||
if isbn[:3] == "979":
|
||||
if isbn[3:5] not in ("10", "11"):
|
||||
raise BarcodeError("ISBN must start with 97910 or 97911.")
|
||||
EuropeanArticleNumber13.__init__(self, isbn, writer)
|
||||
|
||||
|
||||
|
@ -65,30 +62,27 @@ class InternationalStandardBookNumber10(InternationalStandardBookNumber13):
|
|||
The writer to render the barcode (default: SVGWriter).
|
||||
"""
|
||||
|
||||
name = 'ISBN-10'
|
||||
name = "ISBN-10"
|
||||
|
||||
digits = 9
|
||||
|
||||
def __init__(self, isbn, writer=None):
|
||||
isbn = isbn.replace('-', '')
|
||||
isbn = isbn[:self.digits]
|
||||
isbn = isbn.replace("-", "")
|
||||
isbn = isbn[: self.digits]
|
||||
self.isbn10 = isbn
|
||||
self.isbn10 = '{0}{1}'.format(isbn, self._calculate_checksum())
|
||||
InternationalStandardBookNumber13.__init__(self, '978' + isbn, writer)
|
||||
self.isbn10 = "{}{}".format(isbn, self._calculate_checksum())
|
||||
InternationalStandardBookNumber13.__init__(self, "978" + isbn, writer)
|
||||
|
||||
def _calculate_checksum(self):
|
||||
tmp = sum([x * int(y) for x, y in enumerate(self.isbn10[:9],
|
||||
start=1)]) % 11
|
||||
tmp = sum(x * int(y) for x, y in enumerate(self.isbn10[:9], start=1)) % 11
|
||||
if tmp == 10:
|
||||
return 'X'
|
||||
return "X"
|
||||
else:
|
||||
return tmp
|
||||
|
||||
def __unicode__(self):
|
||||
def __str__(self):
|
||||
return self.isbn10
|
||||
|
||||
__str__ = __unicode__
|
||||
|
||||
|
||||
class InternationalStandardSerialNumber(EuropeanArticleNumber13):
|
||||
"""Initializes new ISSN barcode. This code is rendered as EAN-13
|
||||
|
@ -101,33 +95,34 @@ class InternationalStandardSerialNumber(EuropeanArticleNumber13):
|
|||
The writer to render the barcode (default: SVGWriter).
|
||||
"""
|
||||
|
||||
name = 'ISSN'
|
||||
name = "ISSN"
|
||||
|
||||
digits = 7
|
||||
|
||||
def __init__(self, issn, writer=None):
|
||||
issn = issn.replace('-', '')
|
||||
issn = issn[:self.digits]
|
||||
issn = issn.replace("-", "")
|
||||
issn = issn[: self.digits]
|
||||
self.issn = issn
|
||||
self.issn = '{0}{1}'.format(issn, self._calculate_checksum())
|
||||
self.issn = "{}{}".format(issn, self._calculate_checksum())
|
||||
EuropeanArticleNumber13.__init__(self, self.make_ean(), writer)
|
||||
|
||||
def _calculate_checksum(self):
|
||||
tmp = 11 - sum([x * int(y) for x, y in
|
||||
enumerate(reversed(self.issn[:7]), start=2)]) % 11
|
||||
tmp = (
|
||||
11
|
||||
- sum(x * int(y) for x, y in enumerate(reversed(self.issn[:7]), start=2))
|
||||
% 11
|
||||
)
|
||||
if tmp == 10:
|
||||
return 'X'
|
||||
return "X"
|
||||
else:
|
||||
return tmp
|
||||
|
||||
def make_ean(self):
|
||||
return '977{0}00{1}'.format(self.issn[:7], self._calculate_checksum())
|
||||
return "977{}00{}".format(self.issn[:7], self._calculate_checksum())
|
||||
|
||||
def __unicode__(self):
|
||||
def __str__(self):
|
||||
return self.issn
|
||||
|
||||
__str__ = __unicode__
|
||||
|
||||
|
||||
# Shortcuts
|
||||
ISBN13 = InternationalStandardBookNumber13
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from barcode.base import Barcode
|
||||
from barcode.charsets import itf
|
||||
from barcode.errors import *
|
||||
|
||||
"""Module: barcode.itf
|
||||
|
||||
:Provided barcodes: Interleaved 2 of 5
|
||||
"""
|
||||
__docformat__ = 'restructuredtext en'
|
||||
__docformat__ = "restructuredtext en"
|
||||
|
||||
from barcode.base import Barcode
|
||||
from barcode.charsets import itf
|
||||
from barcode.errors import IllegalCharacterError
|
||||
|
||||
MIN_SIZE = 0.2
|
||||
MIN_QUIET_ZONE = 6.4
|
||||
|
@ -32,24 +27,22 @@ class ITF(Barcode):
|
|||
wide/narrow must be in the range 2..3
|
||||
"""
|
||||
|
||||
name = 'ITF'
|
||||
name = "ITF"
|
||||
|
||||
def __init__(self, code, writer=None, narrow=2, wide=5):
|
||||
if not code.isdigit():
|
||||
raise IllegalCharacterError('ITF code can only contain numbers.')
|
||||
raise IllegalCharacterError("ITF code can only contain numbers.")
|
||||
# Length must be even, prepend 0 if necessary
|
||||
if len(code) % 2 != 0:
|
||||
code = '0' + code
|
||||
code = "0" + code
|
||||
self.code = code
|
||||
self.writer = writer or Barcode.default_writer()
|
||||
self.narrow = narrow
|
||||
self.wide = wide
|
||||
|
||||
def __unicode__(self):
|
||||
def __str__(self):
|
||||
return self.code
|
||||
|
||||
__str__ = __unicode__
|
||||
|
||||
def get_fullcode(self):
|
||||
return self.code
|
||||
|
||||
|
@ -57,25 +50,27 @@ class ITF(Barcode):
|
|||
data = itf.START
|
||||
for i in range(0, len(self.code), 2):
|
||||
bars_digit = int(self.code[i])
|
||||
spaces_digit = int(self.code[i+1])
|
||||
spaces_digit = int(self.code[i + 1])
|
||||
for j in range(5):
|
||||
data += itf.CODES[bars_digit][j].upper()
|
||||
data += itf.CODES[spaces_digit][j].lower()
|
||||
data += itf.STOP
|
||||
raw = ''
|
||||
raw = ""
|
||||
for e in data:
|
||||
if e == 'W':
|
||||
raw += '1' * self.wide
|
||||
if e == 'w':
|
||||
raw += '0' * self.wide
|
||||
if e == 'N':
|
||||
raw += '1' * self.narrow
|
||||
if e == 'n':
|
||||
raw += '0' * self.narrow
|
||||
if e == "W":
|
||||
raw += "1" * self.wide
|
||||
if e == "w":
|
||||
raw += "0" * self.wide
|
||||
if e == "N":
|
||||
raw += "1" * self.narrow
|
||||
if e == "n":
|
||||
raw += "0" * self.narrow
|
||||
return [raw]
|
||||
|
||||
def render(self, writer_options, text=None):
|
||||
options = dict(module_width=MIN_SIZE/self.narrow,
|
||||
quiet_zone=MIN_QUIET_ZONE)
|
||||
options = {
|
||||
"module_width": MIN_SIZE / self.narrow,
|
||||
"quiet_zone": MIN_QUIET_ZONE,
|
||||
}
|
||||
options.update(writer_options or {})
|
||||
return Barcode.render(self, options, text)
|
||||
|
|
|
@ -1,115 +1,97 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
|
||||
import barcode
|
||||
|
||||
from argparse import ArgumentParser
|
||||
|
||||
from barcode.writer import ImageWriter, SVGWriter
|
||||
import barcode
|
||||
from barcode.version import version
|
||||
from barcode.writer import ImageWriter
|
||||
from barcode.writer import SVGWriter
|
||||
|
||||
# Optional PyQt4 GUI
|
||||
try:
|
||||
from PyQt4 import QtCore
|
||||
except ImportError:
|
||||
QtCore = None # lint:ok
|
||||
|
||||
# No GUI available yet
|
||||
QtCore = None
|
||||
IMG_FORMATS = ('BMP', 'GIF', 'JPEG', 'MSP', 'PCX', 'PNG', 'TIFF', 'XBM')
|
||||
|
||||
|
||||
def open_gui(args, parser=None):
|
||||
pass
|
||||
IMG_FORMATS = ("BMP", "GIF", "JPEG", "MSP", "PCX", "PNG", "TIFF", "XBM")
|
||||
|
||||
|
||||
def list_types(args, parser=None):
|
||||
print('\npyBarcode available barcode formats:')
|
||||
print(', '.join(barcode.PROVIDED_BARCODES))
|
||||
print('\n')
|
||||
print('Available image formats')
|
||||
print('Standard: svg')
|
||||
print("\npython-barcode available barcode formats:")
|
||||
print(", ".join(barcode.PROVIDED_BARCODES))
|
||||
print("\n")
|
||||
print("Available image formats")
|
||||
print("Standard: svg")
|
||||
if ImageWriter is not None:
|
||||
print('Pillow:', ', '.join(IMG_FORMATS))
|
||||
print("Pillow:", ", ".join(IMG_FORMATS))
|
||||
else:
|
||||
print('Pillow: disabled')
|
||||
print('\n')
|
||||
print("Pillow: disabled")
|
||||
print("\n")
|
||||
|
||||
|
||||
def create_barcode(args, parser):
|
||||
args.type = args.type.upper()
|
||||
if args.type != 'SVG' and args.type not in IMG_FORMATS:
|
||||
if args.type != "SVG" and args.type not in IMG_FORMATS:
|
||||
parser.error(
|
||||
'Unknown type {type}. Try list action for available '
|
||||
'types.'.format(type=args.type)
|
||||
"Unknown type {type}. Try list action for available types.".format(
|
||||
type=args.type
|
||||
)
|
||||
)
|
||||
args.barcode = args.barcode.lower()
|
||||
if args.barcode not in barcode.PROVIDED_BARCODES:
|
||||
parser.error(
|
||||
'Unknown barcode {bc}. Try list action for available '
|
||||
'barcodes.'.format(bc=args.barcode)
|
||||
"Unknown barcode {bc}. Try list action for available barcodes.".format(
|
||||
bc=args.barcode
|
||||
)
|
||||
)
|
||||
if args.type != 'SVG':
|
||||
opts = dict(format=args.type)
|
||||
if args.type != "SVG":
|
||||
opts = {"format": args.type}
|
||||
writer = ImageWriter()
|
||||
else:
|
||||
opts = dict(compress=args.compress)
|
||||
opts = {"compress": args.compress}
|
||||
writer = SVGWriter()
|
||||
out = os.path.normpath(os.path.abspath(args.output))
|
||||
name = barcode.generate(args.barcode, args.code, writer, out, opts,
|
||||
args.text)
|
||||
print('New barcode saved as {0}.'.format(name))
|
||||
name = barcode.generate(args.barcode, args.code, writer, out, opts, args.text)
|
||||
print("New barcode saved as {}.".format(name))
|
||||
|
||||
|
||||
def main():
|
||||
msg = []
|
||||
if ImageWriter is None:
|
||||
msg.append(
|
||||
'Image output disabled (Pillow not found), --type option disabled.'
|
||||
)
|
||||
msg.append("Image output disabled (Pillow not found), --type option disabled.")
|
||||
else:
|
||||
msg.append(
|
||||
'Image output enabled, use --type option to give image '
|
||||
'format (png, jpeg, ...).'
|
||||
"Image output enabled, use --type option to give image "
|
||||
"format (png, jpeg, ...)."
|
||||
)
|
||||
if QtCore is None:
|
||||
msg.append('PyQt not found, gui action disabled.')
|
||||
else:
|
||||
msg.append('PyQt found. Use gui action to get a simple GUI.')
|
||||
parser = ArgumentParser(
|
||||
description='Create standard barcodes via cli.', epilog=' '.join(msg)
|
||||
description="Create standard barcodes via cli.", epilog=" ".join(msg)
|
||||
)
|
||||
parser.add_argument('-v', '--version', action='version',
|
||||
version='%(prog)s ' + version)
|
||||
subparsers = parser.add_subparsers(title='Actions')
|
||||
create_parser = subparsers.add_parser('create', help='Create a barcode '
|
||||
'with the given options.')
|
||||
create_parser.add_argument('code', help='Code to render as barcode.')
|
||||
create_parser.add_argument('output', help='Filename for output '
|
||||
'without extension, e. g. mybarcode.')
|
||||
parser.add_argument(
|
||||
"-v", "--version", action="version", version="%(prog)s " + version
|
||||
)
|
||||
subparsers = parser.add_subparsers(title="Actions")
|
||||
create_parser = subparsers.add_parser(
|
||||
"create", help="Create a barcode with the given options."
|
||||
)
|
||||
create_parser.add_argument("code", help="Code to render as barcode.")
|
||||
create_parser.add_argument(
|
||||
'-c', '--compress', action='store_true',
|
||||
help='Compress output, only recognized if type is svg.'
|
||||
"output", help="Filename for output without extension, e. g. mybarcode."
|
||||
)
|
||||
create_parser.add_argument('-b', '--barcode', help='Barcode to use '
|
||||
'[default: %(default)s].')
|
||||
create_parser.add_argument('--text', help='Text to show under the '
|
||||
'barcode.')
|
||||
create_parser.add_argument(
|
||||
"-c",
|
||||
"--compress",
|
||||
action="store_true",
|
||||
help="Compress output, only recognized if type is svg.",
|
||||
)
|
||||
create_parser.add_argument(
|
||||
"-b", "--barcode", help="Barcode to use [default: %(default)s]."
|
||||
)
|
||||
create_parser.add_argument("--text", help="Text to show under the barcode.")
|
||||
if ImageWriter is not None:
|
||||
create_parser.add_argument('-t', '--type', help='Type of output '
|
||||
'[default: %(default)s].')
|
||||
list_parser = subparsers.add_parser('list', help='List available '
|
||||
'image and code types.')
|
||||
create_parser.add_argument(
|
||||
"-t", "--type", help="Type of output [default: %(default)s]."
|
||||
)
|
||||
list_parser = subparsers.add_parser(
|
||||
"list", help="List available image and code types."
|
||||
)
|
||||
list_parser.set_defaults(func=list_types)
|
||||
if QtCore is not None:
|
||||
gui_parser = subparsers.add_parser('gui', help='Opens a simple '
|
||||
'PyQt GUI to create barcodes.')
|
||||
gui_parser.set_defaults(func=open_gui)
|
||||
create_parser.set_defaults(type='svg', compress=False, func=create_barcode,
|
||||
barcode='code39', text=None)
|
||||
create_parser.set_defaults(
|
||||
type="svg", compress=False, func=create_barcode, barcode="code39", text=None
|
||||
)
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
func = args.func
|
||||
|
@ -119,5 +101,5 @@ def main():
|
|||
func(args, parser)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -1,61 +1,57 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from barcode.base import Barcode
|
||||
from barcode.charsets import upc as _upc
|
||||
from barcode.errors import *
|
||||
|
||||
try:
|
||||
reduce
|
||||
except NameError:
|
||||
from functools import reduce
|
||||
|
||||
"""Module: barcode.upc
|
||||
|
||||
:Provided barcodes: UPC-A
|
||||
"""
|
||||
__docformat__ = 'restructuredtext en'
|
||||
__docformat__ = "restructuredtext en"
|
||||
|
||||
from functools import reduce
|
||||
|
||||
from barcode.base import Barcode
|
||||
from barcode.charsets import upc as _upc
|
||||
from barcode.errors import IllegalCharacterError, NumberOfDigitsError
|
||||
|
||||
|
||||
class UniversalProductCodeA(Barcode):
|
||||
"""Initializes new UPC-A barcode.
|
||||
"""Universal Product Code (UPC) barcode.
|
||||
|
||||
:parameters:
|
||||
upc : String
|
||||
The upc number as string.
|
||||
writer : barcode.writer Instance
|
||||
The writer to render the barcode (default: SVGWriter).
|
||||
make_ean: boolean
|
||||
UPC-A consists of 12 numeric digits.
|
||||
"""
|
||||
|
||||
name = 'UPC-A'
|
||||
name = "UPC-A"
|
||||
|
||||
digits = 11
|
||||
|
||||
def __init__(self, upc, writer=None, make_ean=False):
|
||||
"""Initializes new UPC-A barcode.
|
||||
|
||||
:param str upc: The upc number as string.
|
||||
:param writer: barcode.writer instance. The writer to render the
|
||||
barcode (default: SVGWriter).
|
||||
:param bool make_ean: Indicates if a leading zero should be added to
|
||||
the barcode. This converts the UPC into a valid European Article
|
||||
Number (EAN).
|
||||
"""
|
||||
self.ean = make_ean
|
||||
upc = upc[:self.digits]
|
||||
upc = upc[: self.digits]
|
||||
if not upc.isdigit():
|
||||
raise IllegalCharacterError('UPC code can only contain numbers.')
|
||||
raise IllegalCharacterError("UPC code can only contain numbers.")
|
||||
if len(upc) != self.digits:
|
||||
raise NumberOfDigitsError('UPC must have {0} digits, not '
|
||||
'{1}.'.format(self.digits, len(upc)))
|
||||
raise NumberOfDigitsError(
|
||||
"UPC must have {} digits, not {}.".format(self.digits, len(upc))
|
||||
)
|
||||
self.upc = upc
|
||||
self.upc = '{}{}'.format(upc, self.calculate_checksum())
|
||||
self.upc = "{}{}".format(upc, self.calculate_checksum())
|
||||
self.writer = writer or Barcode.default_writer()
|
||||
|
||||
def __unicode__(self):
|
||||
def __str__(self):
|
||||
if self.ean:
|
||||
return '0' + self.upc
|
||||
return "0" + self.upc
|
||||
else:
|
||||
return self.upc
|
||||
|
||||
__str__ = __unicode__
|
||||
|
||||
def get_fullcode(self):
|
||||
if self.ean:
|
||||
return '0' + self.upc
|
||||
return "0" + self.upc
|
||||
else:
|
||||
return self.upc
|
||||
|
||||
|
@ -63,10 +59,13 @@ class UniversalProductCodeA(Barcode):
|
|||
"""Calculates the checksum for UPCA/UPC codes
|
||||
|
||||
:return: The checksum for 'self.upc'
|
||||
:rtype: Integer
|
||||
:rtype: int
|
||||
"""
|
||||
def sum_(x, y): return int(x) + int(y)
|
||||
upc = self.upc[0:self.digits]
|
||||
|
||||
def sum_(x, y):
|
||||
return int(x) + int(y)
|
||||
|
||||
upc = self.upc[0 : self.digits]
|
||||
oddsum = reduce(sum_, upc[::2])
|
||||
evensum = reduce(sum_, upc[1::2])
|
||||
check = (evensum + oddsum * 3) % 10
|
||||
|
@ -79,17 +78,17 @@ class UniversalProductCodeA(Barcode):
|
|||
"""Builds the barcode pattern from 'self.upc'
|
||||
|
||||
:return: The pattern as string
|
||||
:rtype: String
|
||||
:rtype: str
|
||||
"""
|
||||
code = _upc.EDGE[:]
|
||||
|
||||
for i, number in enumerate(self.upc[0:6]):
|
||||
code += _upc.CODES['L'][int(number)]
|
||||
for _i, number in enumerate(self.upc[0:6]):
|
||||
code += _upc.CODES["L"][int(number)]
|
||||
|
||||
code += _upc.MIDDLE
|
||||
|
||||
for number in self.upc[6:]:
|
||||
code += _upc.CODES['R'][int(number)]
|
||||
code += _upc.CODES["R"][int(number)]
|
||||
|
||||
code += _upc.EDGE
|
||||
|
||||
|
@ -98,17 +97,18 @@ class UniversalProductCodeA(Barcode):
|
|||
def to_ascii(self):
|
||||
"""Returns an ascii representation of the barcode.
|
||||
|
||||
:rtype: String
|
||||
:rtype: str
|
||||
"""
|
||||
|
||||
code = self.build()
|
||||
for i, line in enumerate(code):
|
||||
code[i] = line.replace('1', '|').replace('0', '_')
|
||||
return '\n'.join(code)
|
||||
code[i] = line.replace("1", "|").replace("0", "_")
|
||||
return "\n".join(code)
|
||||
|
||||
def render(self, writer_options=None, text=None):
|
||||
options = dict(module_width=0.33)
|
||||
options = {"module_width": 0.33}
|
||||
options.update(writer_options or {})
|
||||
return Barcode.render(self, options, text)
|
||||
|
||||
|
||||
UPCA = UniversalProductCodeA
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# coding: utf-8
|
||||
# file generated by setuptools_scm
|
||||
# don't change, don't track in version control
|
||||
version = '0.10.0'
|
||||
#!/usr/bin/env python3
|
||||
|
||||
version = '0.0.0'
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import gzip
|
||||
import os
|
||||
import xml.dom
|
||||
from typing import BinaryIO
|
||||
|
||||
from barcode.version import version
|
||||
|
||||
|
@ -17,8 +14,9 @@ except ImportError:
|
|||
from PIL import Image, ImageDraw, ImageFont # lint:ok
|
||||
except ImportError:
|
||||
import logging
|
||||
log = logging.getLogger('pyBarcode')
|
||||
log.info('Pillow not found. Image output disabled')
|
||||
|
||||
log = logging.getLogger("pyBarcode")
|
||||
log.info("Pillow not found. Image output disabled")
|
||||
Image = ImageDraw = ImageFont = None # lint:ok
|
||||
|
||||
|
||||
|
@ -35,26 +33,26 @@ def _set_attributes(element, **attributes):
|
|||
element.setAttribute(key, value)
|
||||
|
||||
|
||||
def create_svg_object():
|
||||
def create_svg_object(with_doctype=False):
|
||||
imp = xml.dom.getDOMImplementation()
|
||||
doctype = imp.createDocumentType(
|
||||
'svg',
|
||||
'-//W3C//DTD SVG 1.1//EN',
|
||||
'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'
|
||||
"svg",
|
||||
"-//W3C//DTD SVG 1.1//EN",
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd",
|
||||
)
|
||||
document = imp.createDocument(None, "svg", doctype if with_doctype else None)
|
||||
_set_attributes(
|
||||
document.documentElement, version="1.1", xmlns="http://www.w3.org/2000/svg"
|
||||
)
|
||||
document = imp.createDocument(None, 'svg', doctype)
|
||||
_set_attributes(document.documentElement, version='1.1',
|
||||
xmlns='http://www.w3.org/2000/svg')
|
||||
return document
|
||||
|
||||
|
||||
SIZE = '{0:.3f}mm'
|
||||
COMMENT = 'Autogenerated with python-barcode {0}'.format(version)
|
||||
SIZE = "{0:.3f}mm"
|
||||
COMMENT = "Autogenerated with python-barcode {}".format(version)
|
||||
PATH = os.path.dirname(os.path.abspath(__file__))
|
||||
FONT = os.path.join(PATH, 'DejaVuSansMono.ttf')
|
||||
|
||||
|
||||
class BaseWriter(object):
|
||||
class BaseWriter:
|
||||
"""Baseclass for all writers.
|
||||
|
||||
Initializes the basic writer options. Childclasses can add more
|
||||
|
@ -79,21 +77,26 @@ class BaseWriter(object):
|
|||
rendered output.
|
||||
"""
|
||||
|
||||
def __init__(self, initialize=None, paint_module=None, paint_text=None,
|
||||
finish=None):
|
||||
self._callbacks = dict(
|
||||
initialize=initialize, paint_module=paint_module,
|
||||
paint_text=paint_text, finish=finish
|
||||
)
|
||||
def __init__(
|
||||
self, initialize=None, paint_module=None, paint_text=None, finish=None
|
||||
):
|
||||
self._callbacks = {
|
||||
"initialize": initialize,
|
||||
"paint_module": paint_module,
|
||||
"paint_text": paint_text,
|
||||
"finish": finish,
|
||||
}
|
||||
self.module_width = 10
|
||||
self.module_height = 10
|
||||
self.font_path = os.path.join(PATH, "fonts", "DejaVuSansMono.ttf")
|
||||
self.font_size = 10
|
||||
self.quiet_zone = 6.5
|
||||
self.background = 'white'
|
||||
self.foreground = 'black'
|
||||
self.text = ''
|
||||
self.human = '' # human readable text
|
||||
self.background = "white"
|
||||
self.foreground = "black"
|
||||
self.text = ""
|
||||
self.human = "" # human readable text
|
||||
self.text_distance = 5
|
||||
self.text_line_distance = 1
|
||||
self.center_text = True
|
||||
|
||||
def calculate_size(self, modules_per_line, number_of_lines, dpi=300):
|
||||
|
@ -112,8 +115,12 @@ class BaseWriter(object):
|
|||
"""
|
||||
width = 2 * self.quiet_zone + modules_per_line * self.module_width
|
||||
height = 2.0 + self.module_height * number_of_lines
|
||||
number_of_text_lines = len(self.text.splitlines())
|
||||
if self.font_size and self.text:
|
||||
height += pt2mm(self.font_size) / 2 + self.text_distance
|
||||
height += (
|
||||
pt2mm(self.font_size) / 2 * number_of_text_lines + self.text_distance
|
||||
)
|
||||
height += self.text_line_distance * (number_of_text_lines - 1)
|
||||
return int(mm2px(width, dpi)), int(mm2px(height, dpi))
|
||||
|
||||
def save(self, filename, output):
|
||||
|
@ -154,7 +161,7 @@ class BaseWriter(object):
|
|||
:rtype: None
|
||||
"""
|
||||
for key, val in options.items():
|
||||
key = key.lstrip('_')
|
||||
key = key.lstrip("_")
|
||||
if hasattr(self, key):
|
||||
setattr(self, key, val)
|
||||
|
||||
|
@ -167,8 +174,8 @@ class BaseWriter(object):
|
|||
List of strings matching the writer spec
|
||||
(only contain 0 or 1).
|
||||
"""
|
||||
if self._callbacks['initialize'] is not None:
|
||||
self._callbacks['initialize'](code)
|
||||
if self._callbacks["initialize"] is not None:
|
||||
self._callbacks["initialize"](code)
|
||||
ypos = 1.0
|
||||
for cc, line in enumerate(code):
|
||||
"""
|
||||
|
@ -176,11 +183,11 @@ class BaseWriter(object):
|
|||
result in aliasing gaps
|
||||
'11010111' -> [2, -1, 1, -1, 3]
|
||||
"""
|
||||
line += ' '
|
||||
line += " "
|
||||
c = 1
|
||||
mlist = []
|
||||
for i in range(0, len(line) - 1):
|
||||
if line[i] == line[i+1]:
|
||||
if line[i] == line[i + 1]:
|
||||
c += 1
|
||||
else:
|
||||
if line[i] == "1":
|
||||
|
@ -197,141 +204,194 @@ class BaseWriter(object):
|
|||
else:
|
||||
color = self.foreground
|
||||
# remove painting for background colored tiles?
|
||||
self._callbacks['paint_module'](
|
||||
self._callbacks["paint_module"](
|
||||
xpos, ypos, self.module_width * abs(mod), color
|
||||
)
|
||||
xpos += self.module_width * abs(mod)
|
||||
bxe = xpos
|
||||
# Add right quiet zone to every line, except last line,
|
||||
# quiet zone already provided with background,
|
||||
# should it be removed complety?
|
||||
# should it be removed completely?
|
||||
if (cc + 1) != len(code):
|
||||
self._callbacks['paint_module'](
|
||||
self._callbacks["paint_module"](
|
||||
xpos, ypos, self.quiet_zone, self.background
|
||||
)
|
||||
ypos += self.module_height
|
||||
if self.text and self._callbacks['paint_text'] is not None:
|
||||
if self.text and self._callbacks["paint_text"] is not None:
|
||||
ypos += self.text_distance
|
||||
if self.center_text:
|
||||
# better center position for text
|
||||
xpos = bxs + ((bxe - bxs) / 2.0)
|
||||
else:
|
||||
xpos = bxs
|
||||
self._callbacks['paint_text'](xpos, ypos)
|
||||
return self._callbacks['finish']()
|
||||
self._callbacks["paint_text"](xpos, ypos)
|
||||
return self._callbacks["finish"]()
|
||||
|
||||
|
||||
class SVGWriter(BaseWriter):
|
||||
|
||||
def __init__(self):
|
||||
BaseWriter.__init__(self, self._init, self._create_module,
|
||||
self._create_text, self._finish)
|
||||
BaseWriter.__init__(
|
||||
self, self._init, self._create_module, self._create_text, self._finish
|
||||
)
|
||||
self.compress = False
|
||||
self.dpi = 25.4
|
||||
self.with_doctype = True
|
||||
self._document = None
|
||||
self._root = None
|
||||
self._group = None
|
||||
|
||||
def _init(self, code):
|
||||
width, height = self.calculate_size(len(code[0]), len(code), self.dpi)
|
||||
self._document = create_svg_object()
|
||||
self._document = create_svg_object(self.with_doctype)
|
||||
self._root = self._document.documentElement
|
||||
attributes = dict(width=SIZE.format(width), height=SIZE.format(height))
|
||||
attributes = {
|
||||
"width": SIZE.format(width),
|
||||
"height": SIZE.format(height),
|
||||
}
|
||||
_set_attributes(self._root, **attributes)
|
||||
self._root.appendChild(self._document.createComment(COMMENT))
|
||||
# create group for easier handling in 3rd party software
|
||||
# like corel draw, inkscape, ...
|
||||
group = self._document.createElement('g')
|
||||
attributes = dict(id='barcode_group')
|
||||
group = self._document.createElement("g")
|
||||
attributes = {"id": "barcode_group"}
|
||||
_set_attributes(group, **attributes)
|
||||
self._group = self._root.appendChild(group)
|
||||
background = self._document.createElement('rect')
|
||||
attributes = dict(width='100%', height='100%',
|
||||
style='fill:{0}'.format(self.background))
|
||||
background = self._document.createElement("rect")
|
||||
attributes = {
|
||||
"width": "100%",
|
||||
"height": "100%",
|
||||
"style": "fill:{}".format(self.background),
|
||||
}
|
||||
_set_attributes(background, **attributes)
|
||||
self._group.appendChild(background)
|
||||
|
||||
def _create_module(self, xpos, ypos, width, color):
|
||||
element = self._document.createElement('rect')
|
||||
attributes = dict(x=SIZE.format(xpos), y=SIZE.format(ypos),
|
||||
width=SIZE.format(width),
|
||||
height=SIZE.format(self.module_height),
|
||||
style='fill:{0};'.format(color))
|
||||
element = self._document.createElement("rect")
|
||||
attributes = {
|
||||
"x": SIZE.format(xpos),
|
||||
"y": SIZE.format(ypos),
|
||||
"width": SIZE.format(width),
|
||||
"height": SIZE.format(self.module_height),
|
||||
"style": "fill:{};".format(color),
|
||||
}
|
||||
_set_attributes(element, **attributes)
|
||||
self._group.appendChild(element)
|
||||
|
||||
def _create_text(self, xpos, ypos):
|
||||
element = self._document.createElement('text')
|
||||
attributes = dict(x=SIZE.format(xpos), y=SIZE.format(ypos),
|
||||
style='fill:{0};font-size:{1}pt;text-anchor:'
|
||||
'middle;'.format(self.foreground,
|
||||
self.font_size))
|
||||
_set_attributes(element, **attributes)
|
||||
# check option to override self.text with self.human (barcode as
|
||||
# human readable data, can be used to print own formats)
|
||||
if self.human != '':
|
||||
if self.human != "":
|
||||
barcodetext = self.human
|
||||
else:
|
||||
barcodetext = self.text
|
||||
text_element = self._document.createTextNode(barcodetext)
|
||||
element.appendChild(text_element)
|
||||
self._group.appendChild(element)
|
||||
for subtext in barcodetext.split("\n"):
|
||||
element = self._document.createElement("text")
|
||||
attributes = {
|
||||
"x": SIZE.format(xpos),
|
||||
"y": SIZE.format(ypos),
|
||||
"style": "fill:{};font-size:{}pt;text-anchor:middle;".format(
|
||||
self.foreground,
|
||||
self.font_size,
|
||||
),
|
||||
}
|
||||
_set_attributes(element, **attributes)
|
||||
text_element = self._document.createTextNode(subtext)
|
||||
element.appendChild(text_element)
|
||||
self._group.appendChild(element)
|
||||
ypos += pt2mm(self.font_size) + self.text_line_distance
|
||||
|
||||
def _finish(self):
|
||||
if self.compress:
|
||||
return self._document.toxml(encoding='UTF-8')
|
||||
return self._document.toxml(encoding="UTF-8")
|
||||
else:
|
||||
return self._document.toprettyxml(indent=4 * ' ', newl=os.linesep,
|
||||
encoding='UTF-8')
|
||||
return self._document.toprettyxml(
|
||||
indent=4 * " ", newl=os.linesep, encoding="UTF-8"
|
||||
)
|
||||
|
||||
def save(self, filename, output):
|
||||
if self.compress:
|
||||
_filename = '{0}.svgz'.format(filename)
|
||||
f = gzip.open(_filename, 'wb')
|
||||
_filename = "{}.svgz".format(filename)
|
||||
f = gzip.open(_filename, "wb")
|
||||
f.write(output)
|
||||
f.close()
|
||||
else:
|
||||
_filename = '{0}.svg'.format(filename)
|
||||
with open(_filename, 'wb') as f:
|
||||
_filename = "{}.svg".format(filename)
|
||||
with open(_filename, "wb") as f:
|
||||
f.write(output)
|
||||
return _filename
|
||||
|
||||
def write(self, content, fp: BinaryIO):
|
||||
"""Write `content` into a file-like object.
|
||||
|
||||
Content should be a barcode rendered by this writer.
|
||||
"""
|
||||
fp.write(content)
|
||||
|
||||
|
||||
if Image is None:
|
||||
ImageWriter = None
|
||||
else:
|
||||
class ImageWriter(BaseWriter):
|
||||
|
||||
def __init__(self):
|
||||
BaseWriter.__init__(self, self._init, self._paint_module,
|
||||
self._paint_text, self._finish)
|
||||
self.format = 'PNG'
|
||||
class ImageWriter(BaseWriter): # type: ignore
|
||||
format: str
|
||||
mode: str
|
||||
dpi: int
|
||||
|
||||
def __init__(self, format="PNG", mode="RGB"):
|
||||
"""Initialise a new write instance.
|
||||
|
||||
:params format: The file format for the generated image. This parameter can
|
||||
take any value that Pillow accepts.
|
||||
:params mode: The colour-mode for the generated image. Set this to RGBA if
|
||||
you wish to use colours with transparency.
|
||||
"""
|
||||
BaseWriter.__init__(
|
||||
self, self._init, self._paint_module, self._paint_text, self._finish
|
||||
)
|
||||
self.format = format
|
||||
self.mode = mode
|
||||
self.dpi = 300
|
||||
self._image = None
|
||||
self._draw = None
|
||||
|
||||
def _init(self, code):
|
||||
size = self.calculate_size(len(code[0]), len(code), self.dpi)
|
||||
self._image = Image.new('RGB', size, self.background)
|
||||
self._image = Image.new(self.mode, size, self.background)
|
||||
self._draw = ImageDraw.Draw(self._image)
|
||||
|
||||
def _paint_module(self, xpos, ypos, width, color):
|
||||
size = [(mm2px(xpos, self.dpi), mm2px(ypos, self.dpi)),
|
||||
(mm2px(xpos + width, self.dpi),
|
||||
mm2px(ypos + self.module_height, self.dpi))]
|
||||
size = [
|
||||
(mm2px(xpos, self.dpi), mm2px(ypos, self.dpi)),
|
||||
(
|
||||
mm2px(xpos + width, self.dpi),
|
||||
mm2px(ypos + self.module_height, self.dpi),
|
||||
),
|
||||
]
|
||||
self._draw.rectangle(size, outline=color, fill=color)
|
||||
|
||||
def _paint_text(self, xpos, ypos):
|
||||
font = ImageFont.truetype(FONT, self.font_size * 2)
|
||||
width, height = font.getsize(self.text)
|
||||
pos = (mm2px(xpos, self.dpi) - width // 2,
|
||||
mm2px(ypos, self.dpi) - height // 4)
|
||||
self._draw.text(pos, self.text, font=font, fill=self.foreground)
|
||||
font = ImageFont.truetype(self.font_path, self.font_size * 2)
|
||||
for subtext in self.text.split("\n"):
|
||||
width, height = font.getsize(subtext)
|
||||
# determine the maximum width of each line
|
||||
pos = (
|
||||
mm2px(xpos, self.dpi) - width // 2,
|
||||
mm2px(ypos, self.dpi) - height // 4,
|
||||
)
|
||||
self._draw.text(pos, subtext, font=font, fill=self.foreground)
|
||||
ypos += pt2mm(self.font_size) / 2 + self.text_line_distance
|
||||
|
||||
def _finish(self):
|
||||
return self._image
|
||||
|
||||
def save(self, filename, output):
|
||||
filename = '{0}.{1}'.format(filename, self.format.lower())
|
||||
filename = "{}.{}".format(filename, self.format.lower())
|
||||
output.save(filename, self.format.upper())
|
||||
return filename
|
||||
|
||||
def write(self, content, fp: BinaryIO):
|
||||
"""Write `content` into a file-like object.
|
||||
|
||||
Content should be a barcode rendered by this writer.
|
||||
"""
|
||||
content.save(fp, format=self.format)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,174 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import easymacro as app
|
||||
import qrcode
|
||||
import qrcode.image.svg as svg
|
||||
from barcode import generate
|
||||
|
||||
|
||||
ID_EXTENSION = ''
|
||||
_ = None
|
||||
|
||||
TITLE = 'ZAZ BarCode'
|
||||
QR = 'qrcode'
|
||||
|
||||
|
||||
class Controllers(object):
|
||||
|
||||
def __init__(self, dlg):
|
||||
self.d = dlg
|
||||
|
||||
def listbox_item_changed(self, event):
|
||||
self.d.text.set_focus()
|
||||
return
|
||||
|
||||
def button_action(self, event):
|
||||
if not self.d.listbox.value:
|
||||
self.d.listbox.set_focus()
|
||||
msg = _('Select barcode type')
|
||||
app.warning(msg, TITLE)
|
||||
return
|
||||
if not self.d.text.value.strip():
|
||||
self.d.text.set_focus()
|
||||
msg = _('Data field is mandatory')
|
||||
app.warning(msg, TITLE)
|
||||
return
|
||||
|
||||
self.d.close(1)
|
||||
return
|
||||
|
||||
|
||||
@app.catch_exception
|
||||
def _use_dialog():
|
||||
dlg = _create_dialog()
|
||||
if not dlg.open():
|
||||
return
|
||||
|
||||
data = dlg.text.value.strip()
|
||||
type_code = dlg.listbox.value
|
||||
path = _make_code(type_code, data)
|
||||
app.selection.insert_image(path)
|
||||
app.paths.kill(path)
|
||||
return
|
||||
|
||||
|
||||
def _make_code(type_code, data):
|
||||
path = app.paths.tmp()
|
||||
|
||||
if type_code == QR:
|
||||
factory = svg.SvgImage
|
||||
img = qrcode.make(data, border=2, image_factory=factory)
|
||||
img.save(path)
|
||||
else:
|
||||
try:
|
||||
generate(type_code, data, output=open(path, 'wb'))
|
||||
except Exception as e:
|
||||
app.errorbox(e)
|
||||
return ''
|
||||
|
||||
return path
|
||||
|
||||
|
||||
def _create_dialog():
|
||||
args = {
|
||||
'Name': 'dialog',
|
||||
'Title': TITLE,
|
||||
'Width': 160,
|
||||
'Height': 160,
|
||||
}
|
||||
dlg = app.create_dialog(args)
|
||||
dlg.id = ID_EXTENSION
|
||||
dlg.events = Controllers
|
||||
|
||||
args = {
|
||||
'Type': 'Label',
|
||||
'Name': 'lbl_barcode',
|
||||
'Label': _('~Select barcode type'),
|
||||
'Width': 70,
|
||||
'Height': 15,
|
||||
'X': 10,
|
||||
'Y': 10,
|
||||
'VerticalAlign': 1,
|
||||
}
|
||||
dlg.add_control(args)
|
||||
|
||||
args = {
|
||||
'Type': 'Label',
|
||||
'Name': 'lbl_data',
|
||||
'Label': _('~Capture data for barcode'),
|
||||
'Width': 100,
|
||||
'Height': 15,
|
||||
'VerticalAlign': 1,
|
||||
}
|
||||
dlg.add_control(args)
|
||||
|
||||
args = {
|
||||
'Type': 'ListBox',
|
||||
'Name': 'listbox',
|
||||
'Width': 65,
|
||||
'Height': 15,
|
||||
'Dropdown': True,
|
||||
}
|
||||
dlg.add_control(args)
|
||||
data = ('code39', 'code128', 'ean', 'ean8', 'ean13', 'gs1', 'gtin',
|
||||
'isbn', 'isbn10', 'isbn13', 'issn', 'jan', 'pzn', 'upc', 'upca',
|
||||
'qrcode')
|
||||
dlg.listbox.data = data
|
||||
|
||||
args = {
|
||||
'Type': 'Text',
|
||||
'Name': 'text',
|
||||
'Width': 140,
|
||||
'Height': 75,
|
||||
'MultiLine': True,
|
||||
'VScroll': True,
|
||||
}
|
||||
dlg.add_control(args)
|
||||
|
||||
args = {
|
||||
'Type': 'Button',
|
||||
'Name': 'button',
|
||||
'Label': _('~Insert Barcode'),
|
||||
'Width': 70,
|
||||
'Height': 15,
|
||||
'ImageURL': 'qr.png',
|
||||
'ImagePosition': 1,
|
||||
}
|
||||
dlg.add_control(args)
|
||||
|
||||
dlg.listbox.move(dlg.lbl_barcode, 5, 0)
|
||||
dlg.lbl_data.move(dlg.lbl_barcode)
|
||||
dlg.text.move(dlg.lbl_data)
|
||||
dlg.button.move(dlg.text, 0, 10)
|
||||
dlg.button.center()
|
||||
|
||||
return dlg
|
||||
|
||||
|
||||
@app.catch_exception
|
||||
def _insert_code(type_code):
|
||||
sel = app.selection
|
||||
data = sel.value
|
||||
if not data:
|
||||
msg = _('Select data')
|
||||
app.errorbox(msg)
|
||||
return
|
||||
|
||||
path = _make_code(type_code, data)
|
||||
|
||||
sel.offset().insert_image(path)
|
||||
app.paths.kill(path)
|
||||
return
|
||||
|
||||
|
||||
def run(args, path_locales):
|
||||
global _
|
||||
|
||||
_ = app.install_locales(path_locales)
|
||||
|
||||
if args == 'used_dialog':
|
||||
_use_dialog()
|
||||
else:
|
||||
_insert_code(args)
|
||||
|
||||
return
|
|
@ -1,12 +1,8 @@
|
|||
import struct
|
||||
from bisect import bisect_left
|
||||
|
||||
from qrcode import constants, exceptions, util
|
||||
from qrcode.image.base import BaseImage
|
||||
|
||||
|
||||
def int2byte(value):
|
||||
return struct.Struct('>B').pack(value)
|
||||
import six
|
||||
from bisect import bisect_left
|
||||
|
||||
|
||||
def make(data=None, **kwargs):
|
||||
|
@ -46,13 +42,21 @@ class QRCode(object):
|
|||
# Spec says border should be at least four boxes wide, but allow for
|
||||
# any (e.g. for producing printable QR codes).
|
||||
self.border = int(border)
|
||||
_check_mask_pattern(mask_pattern)
|
||||
self.mask_pattern = mask_pattern
|
||||
self.image_factory = image_factory
|
||||
if image_factory is not None:
|
||||
assert issubclass(image_factory, BaseImage)
|
||||
self.clear()
|
||||
|
||||
@property
|
||||
def mask_pattern(self):
|
||||
return self._mask_pattern
|
||||
|
||||
@mask_pattern.setter
|
||||
def mask_pattern(self, pattern):
|
||||
_check_mask_pattern(pattern)
|
||||
self._mask_pattern = pattern
|
||||
|
||||
def clear(self):
|
||||
"""
|
||||
Reset the internal data.
|
||||
|
@ -240,7 +244,7 @@ class QRCode(object):
|
|||
self.make()
|
||||
|
||||
modcount = self.modules_count
|
||||
codes = [int2byte(code).decode('cp437')
|
||||
codes = [six.int2byte(code).decode('cp437')
|
||||
for code in (255, 223, 220, 219)]
|
||||
if tty:
|
||||
invert = True
|
||||
|
@ -381,7 +385,7 @@ class QRCode(object):
|
|||
|
||||
data_len = len(data)
|
||||
|
||||
for col in range(self.modules_count - 1, 0, -2):
|
||||
for col in six.moves.xrange(self.modules_count - 1, 0, -2):
|
||||
|
||||
if col <= 6:
|
||||
col -= 1
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import re
|
||||
import math
|
||||
|
||||
# ~ import six
|
||||
# ~ from six.moves import xrange
|
||||
import six
|
||||
from six.moves import xrange
|
||||
|
||||
from qrcode import base, exceptions, LUT
|
||||
|
||||
|
@ -32,10 +32,8 @@ MODE_SIZE_LARGE = {
|
|||
MODE_KANJI: 12,
|
||||
}
|
||||
|
||||
|
||||
ALPHA_NUM = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:'.encode("latin-1")
|
||||
RE_ALPHA_NUM = re.compile('^['.encode("latin-1") + re.escape(ALPHA_NUM) + r']*\Z'.encode("latin-1"))
|
||||
|
||||
ALPHA_NUM = six.b('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:')
|
||||
RE_ALPHA_NUM = re.compile(six.b('^[') + re.escape(ALPHA_NUM) + six.b(r']*\Z'))
|
||||
|
||||
# The number of bits for numeric delimited data lengths.
|
||||
NUMBER_LENGTH = {3: 10, 2: 7, 1: 4}
|
||||
|
@ -98,8 +96,8 @@ PAD1 = 0x11
|
|||
_data_count = lambda block: block.data_count
|
||||
BIT_LIMIT_TABLE = [
|
||||
[0] + [8*sum(map(_data_count, base.rs_blocks(version, error_correction)))
|
||||
for version in range(1, 41)]
|
||||
for error_correction in range(4)
|
||||
for version in xrange(1, 41)]
|
||||
for error_correction in xrange(4)
|
||||
]
|
||||
|
||||
|
||||
|
@ -194,7 +192,7 @@ def lost_point(modules):
|
|||
def _lost_point_level1(modules, modules_count):
|
||||
lost_point = 0
|
||||
|
||||
modules_range = range(modules_count)
|
||||
modules_range = xrange(modules_count)
|
||||
container = [0] * (modules_count + 1)
|
||||
|
||||
for row in modules_range:
|
||||
|
@ -227,7 +225,7 @@ def _lost_point_level1(modules, modules_count):
|
|||
container[length] += 1
|
||||
|
||||
lost_point += sum(container[each_length] * (each_length - 2)
|
||||
for each_length in range(5, modules_count + 1))
|
||||
for each_length in xrange(5, modules_count + 1))
|
||||
|
||||
return lost_point
|
||||
|
||||
|
@ -235,7 +233,7 @@ def _lost_point_level1(modules, modules_count):
|
|||
def _lost_point_level2(modules, modules_count):
|
||||
lost_point = 0
|
||||
|
||||
modules_range = range(modules_count - 1)
|
||||
modules_range = xrange(modules_count - 1)
|
||||
for row in modules_range:
|
||||
this_row = modules[row]
|
||||
next_row = modules[row + 1]
|
||||
|
@ -264,8 +262,8 @@ def _lost_point_level3(modules, modules_count):
|
|||
# row/column, preceded or followed by light area 4 modules wide. From ISOIEC.
|
||||
# pattern1: 10111010000
|
||||
# pattern2: 00001011101
|
||||
modules_range = range(modules_count)
|
||||
modules_range_short = range(modules_count-10)
|
||||
modules_range = xrange(modules_count)
|
||||
modules_range_short = xrange(modules_count-10)
|
||||
lost_point = 0
|
||||
|
||||
for row in modules_range:
|
||||
|
@ -350,14 +348,14 @@ def optimal_data_chunks(data, minimum=4):
|
|||
:param minimum: The minimum number of bytes in a row to split as a chunk.
|
||||
"""
|
||||
data = to_bytestring(data)
|
||||
num_pattern = r'\d'.encode("latin-1")
|
||||
alpha_pattern = '['.encode("latin-1") + re.escape(ALPHA_NUM) + ']'.encode("latin-1")
|
||||
num_pattern = six.b(r'\d')
|
||||
alpha_pattern = six.b('[') + re.escape(ALPHA_NUM) + six.b(']')
|
||||
if len(data) <= minimum:
|
||||
num_pattern = re.compile('^'.encode("latin-1") + num_pattern + '+$'.encode("latin-1"))
|
||||
alpha_pattern = re.compile('^'.encode("latin-1") + alpha_pattern + '+$'.encode("latin-1"))
|
||||
num_pattern = re.compile(six.b('^') + num_pattern + six.b('+$'))
|
||||
alpha_pattern = re.compile(six.b('^') + alpha_pattern + six.b('+$'))
|
||||
else:
|
||||
re_repeat = (
|
||||
'{'.encode("latin-1") + str(minimum).encode('ascii') + ',}'.encode("latin-1"))
|
||||
six.b('{') + six.text_type(minimum).encode('ascii') + six.b(',}'))
|
||||
num_pattern = re.compile(num_pattern + re_repeat)
|
||||
alpha_pattern = re.compile(alpha_pattern + re_repeat)
|
||||
num_bits = _optimal_split(data, num_pattern)
|
||||
|
@ -392,8 +390,8 @@ def to_bytestring(data):
|
|||
Convert data to a (utf-8 encoded) byte-string if it isn't a byte-string
|
||||
already.
|
||||
"""
|
||||
if not isinstance(data, bytes):
|
||||
data = str(data).encode('utf-8')
|
||||
if not isinstance(data, six.binary_type):
|
||||
data = six.text_type(data).encode('utf-8')
|
||||
return data
|
||||
|
||||
|
||||
|
@ -441,12 +439,12 @@ class QRData(object):
|
|||
|
||||
def write(self, buffer):
|
||||
if self.mode == MODE_NUMBER:
|
||||
for i in range(0, len(self.data), 3):
|
||||
for i in xrange(0, len(self.data), 3):
|
||||
chars = self.data[i:i + 3]
|
||||
bit_length = NUMBER_LENGTH[len(chars)]
|
||||
buffer.put(int(chars), bit_length)
|
||||
elif self.mode == MODE_ALPHA_NUM:
|
||||
for i in range(0, len(self.data), 2):
|
||||
for i in xrange(0, len(self.data), 2):
|
||||
chars = self.data[i:i + 2]
|
||||
if len(chars) > 1:
|
||||
buffer.put(
|
||||
|
@ -455,13 +453,12 @@ class QRData(object):
|
|||
else:
|
||||
buffer.put(ALPHA_NUM.find(chars), 6)
|
||||
else:
|
||||
# ~ if six.PY3:
|
||||
if six.PY3:
|
||||
# Iterating a bytestring in Python 3 returns an integer,
|
||||
# no need to ord().
|
||||
# ~ data = self.data
|
||||
# ~ else:
|
||||
# ~ data = [ord(c) for c in self.data]
|
||||
data = self.data
|
||||
data = self.data
|
||||
else:
|
||||
data = [ord(c) for c in self.data]
|
||||
for c in data:
|
||||
buffer.put(c, 8)
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
# ~ This file is part of ZAZ.
|
||||
|
||||
# ~ https://git.elmau.net/elmau/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
|
||||
|
@ -19,6 +21,7 @@
|
|||
|
||||
import argparse
|
||||
import os
|
||||
import py_compile
|
||||
import re
|
||||
import sys
|
||||
import zipfile
|
||||
|
@ -43,9 +46,22 @@ from conf import (
|
|||
log)
|
||||
|
||||
|
||||
EASYMACRO = 'easymacro.py'
|
||||
|
||||
|
||||
class LiboXML(object):
|
||||
CONTEXT = {
|
||||
'calc': 'com.sun.star.sheet.SpreadsheetDocument',
|
||||
'writer': 'com.sun.star.text.TextDocument',
|
||||
'impress': 'com.sun.star.presentation.PresentationDocument',
|
||||
'draw': 'com.sun.star.drawing.DrawingDocument',
|
||||
'base': 'com.sun.star.sdb.OfficeDatabaseDocument',
|
||||
'math': 'com.sun.star.formula.FormulaProperties',
|
||||
'basic': 'com.sun.star.script.BasicIDE',
|
||||
}
|
||||
TYPES = {
|
||||
'py': 'application/vnd.sun.star.uno-component;type=Python',
|
||||
'pyc': 'application/binary',
|
||||
'zip': 'application/binary',
|
||||
'xcu': 'application/vnd.sun.star.configuration-data',
|
||||
'rdb': 'application/vnd.sun.star.uno-typelibrary;type=RDB',
|
||||
|
@ -53,18 +69,34 @@ class LiboXML(object):
|
|||
'help': 'application/vnd.sun.star.help',
|
||||
'component': 'application/vnd.sun.star.uno-components',
|
||||
}
|
||||
NAME_SPACES = {
|
||||
NS_MANIFEST = {
|
||||
'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',
|
||||
}
|
||||
NS_DESCRIPTION = {
|
||||
'xmlns': 'http://openoffice.org/extensions/description/2006',
|
||||
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
|
||||
'xmlns:d': 'http://openoffice.org/extensions/description/2006',
|
||||
}
|
||||
NS_ADDONS = {
|
||||
'xmlns:xs': 'http://www.w3.org/2001/XMLSchema',
|
||||
'xmlns:oor': 'http://openoffice.org/2001/registry',
|
||||
}
|
||||
NS_UPDATE = {
|
||||
'xmlns': 'http://openoffice.org/extensions/update/2006',
|
||||
'xmlns:d': 'http://openoffice.org/extensions/description/2006',
|
||||
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
self._manifest = None
|
||||
self._paths = []
|
||||
self._path_images = ''
|
||||
self._toolbars = []
|
||||
|
||||
def _save_path(self, attr):
|
||||
self._paths.append(attr['{{{}}}full-path'.format(self.NAME_SPACES['manifest'])])
|
||||
self._paths.append(attr['{{{}}}full-path'.format(self.NS_MANIFEST['manifest'])])
|
||||
return
|
||||
|
||||
def _clean(self, name, nodes):
|
||||
|
@ -86,18 +118,18 @@ class LiboXML(object):
|
|||
|
||||
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'],
|
||||
'manifest:version': self.NS_MANIFEST['manifest_version'],
|
||||
'xmlns:manifest': self.NS_MANIFEST['manifest'],
|
||||
'xmlns:loext': self.NS_MANIFEST['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'])
|
||||
ET.register_namespace('manifest', self.NS_MANIFEST['manifest'])
|
||||
self._manifest = ET.fromstring(data)
|
||||
data = {'xmlns:loext': self.NAME_SPACES['xmlns:loext']}
|
||||
self._manifest.attrib.update(**data)
|
||||
attr = {'xmlns:loext': self.NS_MANIFEST['xmlns:loext']}
|
||||
self._manifest.attrib.update(**attr)
|
||||
self._clean('manifest', self._manifest)
|
||||
return
|
||||
|
||||
|
@ -116,6 +148,217 @@ class LiboXML(object):
|
|||
ET.SubElement(self._manifest, node_name, attr)
|
||||
return self._get_xml(self._manifest)
|
||||
|
||||
def new_description(self, data):
|
||||
doc = ET.Element('description', self.NS_DESCRIPTION)
|
||||
|
||||
key = 'identifier'
|
||||
ET.SubElement(doc, key, data[key])
|
||||
|
||||
key = 'version'
|
||||
ET.SubElement(doc, key, data[key])
|
||||
|
||||
key = 'display-name'
|
||||
node = ET.SubElement(doc, key)
|
||||
for k, v in data[key].items():
|
||||
sn = ET.SubElement(node, 'name', {'lang': k})
|
||||
sn.text = v
|
||||
|
||||
node = ET.SubElement(doc, 'extension-description')
|
||||
for k in data[key].keys():
|
||||
attr = {
|
||||
'lang': k,
|
||||
'xlink:href': f'description/desc_{k}.txt',
|
||||
}
|
||||
ET.SubElement(node, 'src', attr)
|
||||
|
||||
key = 'icon'
|
||||
node = ET.SubElement(doc, key)
|
||||
attr = {'xlink:href': f"images/{data[key]}"}
|
||||
ET.SubElement(node, 'default', attr)
|
||||
|
||||
key = 'publisher'
|
||||
node = ET.SubElement(doc, key)
|
||||
for k, v in data[key].items():
|
||||
attr = {
|
||||
'xlink:href': v['link'],
|
||||
'lang': k,
|
||||
}
|
||||
sn = ET.SubElement(node, 'name', attr)
|
||||
sn.text = v['text']
|
||||
|
||||
key = 'display-name'
|
||||
node = ET.SubElement(doc, 'registration')
|
||||
attr = {
|
||||
'accept-by': 'user',
|
||||
'suppress-on-update': 'true',
|
||||
}
|
||||
node = ET.SubElement(node, 'simple-license', attr)
|
||||
for k in data[key].keys():
|
||||
attr = {
|
||||
'xlink:href': f"{DIRS['registration']}/license_{k}.txt",
|
||||
'lang': k
|
||||
}
|
||||
ET.SubElement(node, 'license-text', attr)
|
||||
|
||||
if data['update']:
|
||||
node = ET.SubElement(doc, 'update-information')
|
||||
ET.SubElement(node, 'src', {'xlink:href': data['update']})
|
||||
|
||||
return self._get_xml(doc)
|
||||
|
||||
def _get_context(self, args):
|
||||
if not args:
|
||||
return ''
|
||||
context = ','.join([self.CONTEXT[v] for v in args.split(',')])
|
||||
return context
|
||||
|
||||
def _add_node_value(self, node, name, value='_self'):
|
||||
attr = {'oor:name': name, 'oor:type': 'xs:string'}
|
||||
sn = ET.SubElement(node, 'prop', attr)
|
||||
sn = ET.SubElement(sn, 'value')
|
||||
sn.text = value
|
||||
return
|
||||
|
||||
def _add_menu(self, id_extension, node, index, menu, in_menu_bar=True):
|
||||
if in_menu_bar:
|
||||
attr = {
|
||||
'oor:name': index,
|
||||
'oor:op': 'replace',
|
||||
}
|
||||
subnode = ET.SubElement(node, 'node', attr)
|
||||
else:
|
||||
subnode = node
|
||||
|
||||
attr = {'oor:name': 'Title', 'oor:type': 'xs:string'}
|
||||
sn1 = ET.SubElement(subnode, 'prop', attr)
|
||||
for k, v in menu['title'].items():
|
||||
sn2 = ET.SubElement(sn1, 'value', {'xml:lang': k})
|
||||
sn2.text = v
|
||||
value = self._get_context(menu['context'])
|
||||
self._add_node_value(subnode, 'Context', value)
|
||||
|
||||
if 'submenu' in menu:
|
||||
sn = ET.SubElement(subnode, 'node', {'oor:name': 'Submenu'})
|
||||
for i, m in enumerate(menu['submenu']):
|
||||
self._add_menu(id_extension, sn, f'{index}.s{i}', m)
|
||||
if m.get('toolbar', False):
|
||||
self._toolbars.append(m)
|
||||
return
|
||||
|
||||
value = f"service:{id_extension}?{menu['argument']}"
|
||||
self._add_node_value(subnode, 'URL', value)
|
||||
self._add_node_value(subnode, 'Target')
|
||||
value = f"%origin%/{self._path_images}/{menu['icon']}"
|
||||
self._add_node_value(subnode, 'ImageIdentifier', value)
|
||||
return
|
||||
|
||||
def new_addons(self, id_extension, data):
|
||||
in_menu_bar = data['parent'] == 'OfficeMenuBar'
|
||||
self._path_images = data['images']
|
||||
attr = {
|
||||
'oor:name': 'Addons',
|
||||
'oor:package': 'org.openoffice.Office',
|
||||
}
|
||||
attr.update(self.NS_ADDONS)
|
||||
doc = ET.Element('oor:component-data', attr)
|
||||
parent = ET.SubElement(doc, 'node', {'oor:name': 'AddonUI'})
|
||||
node = ET.SubElement(parent, 'node', {'oor:name': data['parent']})
|
||||
|
||||
op = 'fuse'
|
||||
if in_menu_bar:
|
||||
op = 'replace'
|
||||
|
||||
attr = {'oor:name': id_extension, 'oor:op': op}
|
||||
node = ET.SubElement(node, 'node', attr)
|
||||
|
||||
if in_menu_bar:
|
||||
attr = {'oor:name': 'Title', 'oor:type': 'xs:string'}
|
||||
subnode = ET.SubElement(node, 'prop', attr)
|
||||
for k, v in data['main'].items():
|
||||
sn = ET.SubElement(subnode, 'value', {'xml:lang': k})
|
||||
sn.text = v
|
||||
|
||||
self._add_node_value(node, 'Target')
|
||||
node = ET.SubElement(node, 'node', {'oor:name': 'Submenu'})
|
||||
|
||||
for i, menu in enumerate(data['menus']):
|
||||
self._add_menu(id_extension, node, f'm{i}', menu, in_menu_bar)
|
||||
if menu.get('toolbar', False):
|
||||
self._toolbars.append(menu)
|
||||
|
||||
if self._toolbars:
|
||||
attr = {'oor:name': 'OfficeToolBar'}
|
||||
toolbar = ET.SubElement(parent, 'node', attr)
|
||||
attr = {'oor:name': id_extension, 'oor:op': 'replace'}
|
||||
toolbar = ET.SubElement(toolbar, 'node', attr)
|
||||
for t, menu in enumerate(self._toolbars):
|
||||
self._add_menu(id_extension, toolbar, f't{t}', menu)
|
||||
|
||||
return self._get_xml(doc)
|
||||
|
||||
def _add_shortcut(self, node, key, id_extension, arg):
|
||||
attr = {'oor:name': key, 'oor:op': 'fuse'}
|
||||
subnode = ET.SubElement(node, 'node', attr)
|
||||
subnode = ET.SubElement(subnode, 'prop', {'oor:name': 'Command'})
|
||||
subnode = ET.SubElement(subnode, 'value', {'xml:lang': 'en-US'})
|
||||
subnode.text = f"service:{id_extension}?{arg}"
|
||||
return
|
||||
|
||||
def _get_acceleartors(self, menu):
|
||||
if 'submenu' in menu:
|
||||
for m in menu['submenu']:
|
||||
return self._get_acceleartors(m)
|
||||
|
||||
if not menu.get('shortcut', ''):
|
||||
return ''
|
||||
|
||||
return menu
|
||||
|
||||
def new_accelerators(self, id_extension, menus):
|
||||
attr = {
|
||||
'oor:name': 'Accelerators',
|
||||
'oor:package': 'org.openoffice.Office',
|
||||
}
|
||||
attr.update(self.NS_ADDONS)
|
||||
doc = ET.Element('oor:component-data', attr)
|
||||
parent = ET.SubElement(doc, 'node', {'oor:name': 'PrimaryKeys'})
|
||||
|
||||
data = []
|
||||
for m in menus:
|
||||
info = self._get_acceleartors(m)
|
||||
if info:
|
||||
data.append(info)
|
||||
|
||||
node_global = None
|
||||
node_modules = None
|
||||
for m in data:
|
||||
if m['context']:
|
||||
if node_modules is None:
|
||||
node_modules = ET.SubElement(
|
||||
parent, 'node', {'oor:name': 'Modules'})
|
||||
for app in m['context'].split(','):
|
||||
node = ET.SubElement(
|
||||
node_modules, 'node', {'oor:name': self.CONTEXT[app]})
|
||||
self._add_shortcut(
|
||||
node, m['shortcut'], id_extension, m['argument'])
|
||||
else:
|
||||
if node_global is None:
|
||||
node_global = ET.SubElement(
|
||||
parent, 'node', {'oor:name': 'Global'})
|
||||
self._add_shortcut(
|
||||
node_global, m['shortcut'], id_extension, m['argument'])
|
||||
|
||||
return self._get_xml(doc)
|
||||
|
||||
def new_update(self, extension, url_oxt):
|
||||
doc = ET.Element('description', self.NS_UPDATE)
|
||||
ET.SubElement(doc, 'identifier', {'value': extension['id']})
|
||||
ET.SubElement(doc, 'version', {'value': extension['version']})
|
||||
node = ET.SubElement(doc, 'update-download')
|
||||
ET.SubElement(node, 'src', {'xlink:href': url_oxt})
|
||||
node = ET.SubElement(doc, 'release-notes')
|
||||
return self._get_xml(doc)
|
||||
|
||||
def _get_xml(self, doc):
|
||||
xml = parseString(ET.tostring(doc, encoding='utf-8'))
|
||||
return xml.toprettyxml(indent=' ', encoding='utf-8').decode('utf-8')
|
||||
|
@ -155,11 +398,7 @@ def _get_files(path, filters=''):
|
|||
def _compress_oxt():
|
||||
log.info('Compress OXT extension...')
|
||||
|
||||
path = DIRS['files']
|
||||
if not _exists(path):
|
||||
_mkdir(path)
|
||||
|
||||
path_oxt = _join(path, FILES['oxt'])
|
||||
path_oxt = _join(DIRS['files'], FILES['oxt'])
|
||||
|
||||
z = zipfile.ZipFile(path_oxt, 'w', compression=zipfile.ZIP_DEFLATED)
|
||||
root_len = len(os.path.abspath(DIRS['source']))
|
||||
|
@ -173,10 +412,6 @@ def _compress_oxt():
|
|||
z.write(fullpath, file_name, zipfile.ZIP_DEFLATED)
|
||||
z.close()
|
||||
|
||||
if DATA['update']:
|
||||
path_xml = _join(path, FILES['update'])
|
||||
_save(path_xml, DATA['update'])
|
||||
|
||||
log.info('Extension OXT created sucesfully...')
|
||||
return
|
||||
|
||||
|
@ -294,6 +529,10 @@ def _compile_idl():
|
|||
|
||||
|
||||
def _update_files():
|
||||
path_files = DIRS['files']
|
||||
if not _exists(path_files):
|
||||
_mkdir(path_files)
|
||||
|
||||
path_source = DIRS['source']
|
||||
|
||||
for k, v in INFO.items():
|
||||
|
@ -315,7 +554,7 @@ def _update_files():
|
|||
copyfile(source, target)
|
||||
|
||||
if FILES['easymacro']:
|
||||
source = 'easymacro.py'
|
||||
source = EASYMACRO
|
||||
target = _join(path_source, 'pythonpath', source)
|
||||
copyfile(source, target)
|
||||
|
||||
|
@ -325,16 +564,21 @@ def _update_files():
|
|||
data = xml.new_manifest(DATA['manifest'])
|
||||
_save(path, data)
|
||||
|
||||
path = _join(path_source, DIRS['office'])
|
||||
_mkdir(path)
|
||||
path = _join(path_source, DIRS['office'], FILES['shortcut'])
|
||||
_save(path, DATA['shortcut'])
|
||||
|
||||
path = _join(path_source, FILES['addons'])
|
||||
_save(path, DATA['addons'])
|
||||
|
||||
path = _join(path_source, FILES['description'])
|
||||
_save(path, DATA['description'])
|
||||
data = xml.new_description(DATA['description'])
|
||||
_save(path, data)
|
||||
|
||||
if TYPE_EXTENSION == 1:
|
||||
path = _join(path_source, FILES['addons'])
|
||||
data = xml.new_addons(EXTENSION['id'], DATA['addons'])
|
||||
_save(path, data)
|
||||
|
||||
path = _join(path_source, DIRS['office'])
|
||||
_mkdir(path)
|
||||
path = _join(path_source, DIRS['office'], FILES['shortcut'])
|
||||
data = xml.new_accelerators(EXTENSION['id'], DATA['addons']['menus'])
|
||||
_save(path, data)
|
||||
|
||||
|
||||
if TYPE_EXTENSION == 3:
|
||||
path = _join(path_source, FILES['addin'])
|
||||
|
@ -342,16 +586,21 @@ def _update_files():
|
|||
|
||||
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)
|
||||
log.info(msg)
|
||||
|
||||
if DATA['update']:
|
||||
path_xml = _join(path_files, FILES['update'])
|
||||
data = xml.new_update(EXTENSION, DATA['update'])
|
||||
_save(path_xml, data)
|
||||
|
||||
_compile_idl()
|
||||
return
|
||||
|
||||
|
||||
def _new():
|
||||
def _create():
|
||||
if not _validate_new():
|
||||
return
|
||||
|
||||
|
@ -373,7 +622,7 @@ def _get_info_path(path):
|
|||
|
||||
def _zip_embed(source, files):
|
||||
PATH = 'Scripts/python/'
|
||||
EASYMACRO = 'easymacro.'
|
||||
FILE_PYC = 'easymacro.pyc'
|
||||
|
||||
p, f, name, e = _get_info_path(source)
|
||||
now = datetime.now().strftime('_%Y%m%d_%H%M%S')
|
||||
|
@ -381,12 +630,10 @@ def _zip_embed(source, files):
|
|||
copyfile(source, path_source)
|
||||
target = source
|
||||
|
||||
with zipfile.PyZipFile(EASYMACRO + 'zip', mode='w') as zf:
|
||||
zf.writepy(EASYMACRO + 'py')
|
||||
|
||||
py_compile.compile(EASYMACRO, FILE_PYC)
|
||||
xml = LiboXML()
|
||||
|
||||
path_easymacro = PATH + EASYMACRO + 'zip'
|
||||
path_easymacro = PATH + FILE_PYC
|
||||
names = [f[1] for f in files] + [path_easymacro]
|
||||
nodes = []
|
||||
with zipfile.ZipFile(target, 'w', compression=zipfile.ZIP_DEFLATED) as zt:
|
||||
|
@ -405,14 +652,14 @@ def _zip_embed(source, files):
|
|||
data.append(name)
|
||||
zt.write(path, name)
|
||||
|
||||
zt.write(EASYMACRO + 'zip', path_easymacro)
|
||||
zt.write(FILE_PYC, 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')
|
||||
os.unlink(FILE_PYC)
|
||||
return
|
||||
|
||||
|
||||
|
@ -450,8 +697,6 @@ def _embed(args):
|
|||
|
||||
|
||||
def _locales(args):
|
||||
EASYMACRO = 'easymacro.py'
|
||||
|
||||
if args.files:
|
||||
files = args.files.split(',')
|
||||
else:
|
||||
|
@ -483,8 +728,39 @@ def _update():
|
|||
return
|
||||
|
||||
|
||||
def _new(args):
|
||||
if not args.target:
|
||||
msg = 'Add argument target: -t PATH_TARGET'
|
||||
log.error(msg)
|
||||
return
|
||||
|
||||
if not args.name:
|
||||
msg = 'Add argument name: -n name-new-extension'
|
||||
log.error(msg)
|
||||
return
|
||||
|
||||
path = _join(args.target, args.name)
|
||||
_mkdir(path)
|
||||
_mkdir(_join(path, 'files'))
|
||||
_mkdir(_join(path, 'images'))
|
||||
path_logo = 'images/pymacros.png'
|
||||
copyfile(path_logo, _join(path, 'images/logo.png'))
|
||||
copyfile('zaz.py', _join(path, 'zaz.py'))
|
||||
copyfile(EASYMACRO, _join(path, 'easymacro.py'))
|
||||
copyfile('conf.py.example', _join(path, 'conf.py'))
|
||||
|
||||
msg = 'Folders and files copy successfully for new extension.'
|
||||
log.info(msg)
|
||||
msg = f'Change to folder: {path}'
|
||||
log.info(msg)
|
||||
return
|
||||
|
||||
|
||||
def main(args):
|
||||
if args.new:
|
||||
_new(args)
|
||||
return
|
||||
|
||||
if args.update:
|
||||
_update()
|
||||
return
|
||||
|
@ -497,14 +773,16 @@ def main(args):
|
|||
_embed(args)
|
||||
return
|
||||
|
||||
if args.new:
|
||||
_new()
|
||||
if args.create:
|
||||
_create()
|
||||
return
|
||||
|
||||
if not _validate_update():
|
||||
return
|
||||
|
||||
_update_files()
|
||||
if not args.only_compress:
|
||||
_update_files()
|
||||
|
||||
_compress_oxt()
|
||||
|
||||
if args.install:
|
||||
|
@ -517,9 +795,13 @@ def main(args):
|
|||
def _process_command_line_arguments():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Make LibreOffice extensions')
|
||||
parser.add_argument('-i', '--install', dest='install', action='store_true',
|
||||
parser.add_argument('-new', '--new', dest='new', action='store_true',
|
||||
default=False, required=False)
|
||||
parser.add_argument('-n', '--new', dest='new', action='store_true',
|
||||
parser.add_argument('-t', '--target', dest='target', default='')
|
||||
parser.add_argument('-n', '--name', dest='name', default='', required=False)
|
||||
parser.add_argument('-c', '--create', dest='create', action='store_true',
|
||||
default=False, required=False)
|
||||
parser.add_argument('-i', '--install', dest='install', action='store_true',
|
||||
default=False, required=False)
|
||||
parser.add_argument('-e', '--embed', dest='embed', action='store_true',
|
||||
default=False, required=False)
|
||||
|
@ -529,6 +811,8 @@ def _process_command_line_arguments():
|
|||
default=False, required=False)
|
||||
parser.add_argument('-u', '--update', dest='update', action='store_true',
|
||||
default=False, required=False)
|
||||
parser.add_argument('-oc', '--only_compress', dest='only_compress',
|
||||
action='store_true', default=False, required=False)
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue