Skip to content

Commit 7aad53e

Browse files
authored
Merge pull request #20 from OUDON/develop
release: v1.2.0
2 parents 8d5fa95 + 80a5572 commit 7aad53e

24 files changed

+1205
-906
lines changed

.github/dependabot.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# To get started with Dependabot version updates, you'll need to specify which
2+
# package ecosystems to update and where the package manifests are located.
3+
# Please see the documentation for all configuration options:
4+
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5+
6+
version: 2
7+
updates:
8+
- package-ecosystem: "pip" # See documentation for possible values
9+
directory: "/" # Location of package manifests
10+
schedule:
11+
interval: "weekly"

.github/workflows/python-app.yml

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,11 @@ jobs:
2424
- name: Install dependencies
2525
run: |
2626
python -m pip install --upgrade pip
27-
pip install flake8 pytest
28-
pip install .
27+
pip install .[dev]
2928
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
30-
- name: Lint with flake8
29+
- name: Lint
3130
run: |
32-
# stop the build if there are Python syntax errors or undefined names
33-
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
34-
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
35-
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
31+
make lint
3632
- name: Test with pytest
3733
run: |
3834
python -m pytest

CONTRIBUTING.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Contributing to rmqrcode-python
2+
Thank you for interesting in contributing to rmqrcode-python! Any suggestions are welcome.
3+
4+
## Style Guides
5+
6+
### Docstrings
7+
This project uses [Google-Style format](https://google.github.io/styleguide/pyguide.html#381-docstrings) docstrings.
8+
9+
### Git Commit Message
10+
Consider starting commit message with one of the following prefixes.
11+
- `feat:` : New feature
12+
- `fix:` : Bug fix
13+
- `refactor:` : Refactoring
14+
- `chore:` : Little things
15+
- `ci`: CI
16+
- `doc:` : Documentation
17+
18+
## Pull Requests
19+
Before make a pull request, please do the following.
20+
1. `make format`
21+
2. `make lint`
22+
3. `python -m pytest` and make sure all tests are passed.

Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.PHONY: lint
2+
lint:
3+
flake8 src
4+
isort --check --diff src
5+
black --check src
6+
7+
.PHONY: format
8+
format:
9+
isort src
10+
black src

README.md

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,21 @@
22
![reop-url](https://user-images.githubusercontent.com/14174940/172978619-accbf9d0-9dd8-4b19-b47e-ad139a68dcc9.png)
33

44

5-
This is an rMQR Code image generator implemented in Python. This is implemented based on [ISO/IEC 23941:2022](https://www.iso.org/standard/77404.html).
5+
The rMQR Code is a rectangular two-dimensional barcode. This package can generate an rMQR Code image. This is implemented based on [ISO/IEC 23941: Rectangular Micro QR Code (rMQR) bar code symbology specification](https://www.iso.org/standard/77404.html).
66

7+
[![pytest](https://github.com/OUDON/rmqrcode-python/actions/workflows/python-app.yml/badge.svg?branch=main)](https://github.com/OUDON/rmqrcode-python/actions/workflows/python-app.yml)
8+
![PyPI](https://img.shields.io/pypi/v/rmqrcode?color=blue)
9+
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/rmqrcode)
10+
![PyPI - Downloads](https://img.shields.io/pypi/dm/rmqrcode?color=orange)
711

8-
## 📌 Important Notice
12+
## 🎮 Online Demo Site
13+
You can try this online: https://rmqr.oudon.xyz .
14+
15+
## 📌 Notice
916
- Please verify an image generated by this software whether it can decode correctly before use.
1017
- Because this is in early stage, QR Code readers may have not been supported rMQR Code yet.
1118

19+
1220
## 🚀 Installation
1321
```
1422
pip install rmqrcode
@@ -64,7 +72,7 @@ The `fit_strategy` parameter is enum value of `rmqrcode.FitStrategy` to specify
6472
- **`FitStrategy.BALANCED`**: Try to keep balance of width and height.
6573

6674
Here is an example of images genereated by each fit strategies for data `Test test test`:
67-
![Example of fit strategies](https://user-images.githubusercontent.com/14174940/172822478-4f2b5fb8-49bd-464f-b6b2-c7347f71cbf5.png)
75+
![Example of fit strategies](https://user-images.githubusercontent.com/14174940/175759120-7fb5ec71-c258-4646-9b91-6865b3eeac3f.png)
6876

6977
### Save as image
7078
```py
@@ -76,7 +84,7 @@ image.save("my_qr.png")
7684
```
7785

7886

79-
## 📚 Advanced Usage
87+
## 📙 Advanced Usage
8088
### Select rMQR Code size manually
8189
To select rMQR Code size manually, use `rMQR()` constructor.
8290
```py
@@ -108,6 +116,17 @@ The rMQR Code has the four encoding modes Numeric, Alphanumeric, Byte and Kanji
108116
|Byte||
109117
|Kanji||
110118

119+
120+
## 🤝 Contiributing
121+
Any suggestions are welcome! If you are interesting in contiributing, please read [CONTRIBUTING](https://github.com/OUDON/rmqrcode-python/blob/develop/CONTRIBUTING.md).
122+
123+
124+
## 📚 References
125+
- [Rectangular Micro QR Code (rMQR) bar code symbology specification: ISO/IEC 23941](https://www.iso.org/standard/77404.html)
126+
- [rMQR Code | QRcode.com | DENSO WAVE](https://www.qrcode.com/en/codes/rmqr.html)
127+
- [Creating a QR Code step by step](https://www.nayuki.io/page/creating-a-qr-code-step-by-step)
128+
129+
111130
----
112131
The word "QR Code" is registered trademark of DENSO WAVE Incorporated.<br>
113132
http://www.denso-wave.com/qrcode/faqpatent-e.html

example.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@
66
import logging
77

88

9+
try:
10+
import numpy
11+
import cv2
12+
USE_NUMPY = True
13+
except ImportError:
14+
USE_NUMPY = False
15+
16+
917
def main():
1018
data = "https://oudon.xyz"
1119
error_correction_level = ErrorCorrectionLevel.M
@@ -26,6 +34,13 @@ def main():
2634
image.show()
2735
image.save("my_qr.png")
2836

37+
# Convert to numpy array
38+
if USE_NUMPY:
39+
img = image.get_ndarray()
40+
cv2.imshow("img", img)
41+
cv2.waitKey(0)
42+
cv2.destroyAllWindows()
43+
2944

3045
def _init_logger():
3146
logger = logging.getLogger()

pyproject.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
[build-system]
22
requires = ["setuptools>=42"]
3-
build-backend = "setuptools.build_meta"
3+
build-backend = "setuptools.build_meta"
4+
5+
[tool.black]
6+
line-length = 119
7+
exclude = "generator_polynomials.py"

setup.cfg

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = rmqrcode
3-
version = 0.1.3
3+
version = 0.2.0
44
author = Takahiro Tomita
55
author_email = [email protected]
66
description = An rMQR Code Generetor
@@ -23,10 +23,21 @@ install_requires =
2323
[options.extras_require]
2424
dev =
2525
pytest
26+
flake8
27+
isort
28+
black
2629

2730
[options.packages.find]
2831
where = src
2932

3033
[options.entry_points]
3134
console_scripts =
32-
rmqr = rmqrcode.console:main
35+
rmqr = rmqrcode.console:main
36+
37+
[flake8]
38+
max-line-length = 119
39+
extend-ignore = E203
40+
exclude = src/rmqrcode/format/generator_polynomials.py
41+
42+
[isort]
43+
profile=black

src/rmqrcode/__init__.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
from .rmqrcode import rMQR
2-
from .rmqrcode import FitStrategy
3-
from .rmqrcode import DataTooLongError
4-
from .rmqrcode import IllegalVersionError
1+
from .format.error_correction_level import ErrorCorrectionLevel
52
from .qr_image import QRImage
6-
from .format.error_correction_level import ErrorCorrectionLevel
3+
from .rmqrcode import DataTooLongError, FitStrategy, IllegalVersionError, rMQR
4+
5+
__all__ = ("rMQR", "DataTooLongError", "FitStrategy", "IllegalVersionError", "QRImage", "ErrorCorrectionLevel")

src/rmqrcode/console.py

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
#!/usr/bin/env python
2-
import rmqrcode
3-
from rmqrcode import rMQR
4-
from rmqrcode import QRImage
5-
from rmqrcode import ErrorCorrectionLevel
6-
from rmqrcode import FitStrategy
7-
from rmqrcode import DataTooLongError
8-
from rmqrcode import IllegalVersionError
9-
102
import argparse
113
import sys
124

5+
from rmqrcode import (
6+
DataTooLongError,
7+
ErrorCorrectionLevel,
8+
FitStrategy,
9+
IllegalVersionError,
10+
QRImage,
11+
rMQR,
12+
)
13+
1314

1415
def _show_error_and_exit(msg):
1516
print(msg, file=sys.stderr)
1617
sys.exit(1)
1718

1819

1920
def _make_qr(data, ecc, version, fit_strategy):
20-
if version == None:
21+
if version is None:
2122
qr = rMQR.fit(data, ecc=ecc, fit_strategy=fit_strategy)
2223
else:
2324
try:
@@ -29,7 +30,6 @@ def _make_qr(data, ecc, version, fit_strategy):
2930
return qr
3031

3132

32-
3333
def _save_image(qr, output):
3434
image = QRImage(qr)
3535
try:
@@ -42,24 +42,19 @@ def main():
4242
parser = _init_argparser()
4343
args = parser.parse_args()
4444

45-
if args.ecc == 'M':
45+
if args.ecc == "M":
4646
ecc = ErrorCorrectionLevel.M
47-
elif args.ecc == 'H':
47+
elif args.ecc == "H":
4848
ecc = ErrorCorrectionLevel.H
4949

5050
fit_strategy = FitStrategy.BALANCED
51-
if args.fit_strategy == 'min_width':
51+
if args.fit_strategy == "min_width":
5252
fit_strategy = FitStrategy.MINIMIZE_WIDTH
53-
elif args.fit_strategy == 'min_height':
53+
elif args.fit_strategy == "min_height":
5454
fit_strategy = FitStrategy.MINIMIZE_HEIGHT
5555

5656
try:
57-
qr = _make_qr(
58-
args.DATA,
59-
ecc=ecc,
60-
version=args.version,
61-
fit_strategy=fit_strategy
62-
)
57+
qr = _make_qr(args.DATA, ecc=ecc, version=args.version, fit_strategy=fit_strategy)
6358
except DataTooLongError:
6459
_show_error_and_exit("Error: The data is too long.")
6560

@@ -68,13 +63,20 @@ def main():
6863

6964
def _init_argparser():
7065
parser = argparse.ArgumentParser()
71-
parser.add_argument('DATA', type=str, help="Data to encode.")
72-
parser.add_argument('OUTPUT', type=str, help="Output file path")
73-
parser.add_argument('--ecc', help="Error correction level. (default: M)", type=str, choices=["M", "H"], default='M')
74-
parser.add_argument('--version', help="rMQR Code version like 'R11x139'.")
75-
parser.add_argument('--fit-strategy', choices=["min_width", "min_height", "balanced"], help="Strategy how to determine rMQR Code size.", dest="fit_strategy")
66+
parser.add_argument("DATA", type=str, help="Data to encode.")
67+
parser.add_argument("OUTPUT", type=str, help="Output file path")
68+
parser.add_argument(
69+
"--ecc", help="Error correction level. (default: M)", type=str, choices=["M", "H"], default="M"
70+
)
71+
parser.add_argument("--version", help="rMQR Code version like 'R11x139'.")
72+
parser.add_argument(
73+
"--fit-strategy",
74+
choices=["min_width", "min_height", "balanced"],
75+
help="Strategy how to determine rMQR Code size.",
76+
dest="fit_strategy",
77+
)
7678
return parser
7779

7880

7981
if __name__ == "__main__":
80-
main()
82+
main()

0 commit comments

Comments
 (0)