Skip to content

Commit

Permalink
Accept data: URIs on the command-line
Browse files Browse the repository at this point in the history
  • Loading branch information
dlenski committed Dec 13, 2024
1 parent b89e734 commit e780b1d
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
12 changes: 12 additions & 0 deletions test/test_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,15 @@ def test_bad_file_format_error():
global test_reader
with helper.assertRaises(zxing.BarCodeReaderException):
test_reader.decode(os.path.join(test_barcode_dir, 'bad_format.png'))


def test_data_uris():
def _check_data_uri(uri, contents, suffix):
fobj = zxing.data_uri_to_fobj(uri)
assert fobj.getvalue() == contents
assert fobj.name.endswith(suffix)

yield from ((_check_data_uri, uri, contents, suffix) for (uri, contents, suffix) in (
('data:image/png,ABCD', b'ABCD', '.png'),
('data:image/jpeg;base64,3q2+7w==', bytes.fromhex('deadbeef'), '.jpeg'),
))
20 changes: 19 additions & 1 deletion zxing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
import sys
import urllib.parse
import zipfile
from base64 import b64decode
from enum import Enum
from io import IOBase
from io import BytesIO, IOBase
from itertools import chain

try:
Expand All @@ -34,6 +35,23 @@ def file_uri_to_path(s):
raise ValueError(uri)
return urllib.parse.unquote_plus(uri.path)


def data_uri_to_fobj(s):
r = urllib.parse.urlparse(s)
if r.scheme == 'data' and not r.netloc:
mime, *rest = r.path.split(',', 1)
if rest:
if mime.endswith(';base64') and rest:
mime = mime[:-7]]
data = b64decode(rest[0])
else:
data = rest[0].encode()
ff = BytesIO(data)
ff.name = f'data_uri_{len(data)}_bytes.{mime.split("/")[-1]}'
return ff
raise ValueError("Cannot handle URIs other than data:MIMETYPE[;base64],DATA")


class BarCodeReaderException(Exception):
def __init__(self, message, filename=None):
self.message, self.filename = message, filename
Expand Down
10 changes: 8 additions & 2 deletions zxing/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import csv
from sys import stdout, stdin

from . import BarCodeReader, BarCodeReaderException
from . import BarCodeReader, BarCodeReaderException, data_uri_to_fobj
from .version import __version__


Expand All @@ -24,7 +24,7 @@ def main():
p.add_argument('-c', '--csv', action='store_true')
p.add_argument('--try-harder', action='store_true')
p.add_argument('--pure-barcode', action='store_true')
p.add_argument('image', nargs='+')
p.add_argument('image', nargs='+', help='File path or data: URI of an image containing a barcode')
p.add_argument('-P', '--classpath', help=argparse.SUPPRESS)
p.add_argument('-J', '--java', help=argparse.SUPPRESS)
p.add_argument('-V', '--version', action='store_true')
Expand All @@ -46,6 +46,12 @@ def main():
if fn == '-':
ff = stdin.buffer
fn = ff.name
elif ':' in fn:
try:
ff = data_uri_to_fobj(fn)
fn = ff.name
except ValueError as exc:
p.error(exc.args[0])
else:
ff = fn

Expand Down

0 comments on commit e780b1d

Please sign in to comment.