mirror of
				https://github.com/python-escpos/python-escpos
				synced 2025-10-23 09:30:00 +00:00 
			
		
		
		
	Compare commits
	
		
			5 Commits
		
	
	
		
			appveyor
			...
			debian/jes
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 83185bf2f3 | ||
|   | 57ce8389d7 | ||
|   | b2ce102ca5 | ||
|   | d50c407edb | ||
|   | 2a2ba9a0e2 | 
							
								
								
									
										11
									
								
								.mailmap
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								.mailmap
									
									
									
									
									
								
							| @@ -1,11 +0,0 @@ | ||||
| <dev@pkanzler.de>                                    <patrick.kanzler@fablab.fau.de> | ||||
| <manpaz@gmail.com>                                   <manpaz@bashlinux.com> | ||||
| Manuel F Martinez <manpaz@gmail.com>                 manpaz <manpaz@bashlinux.com> | ||||
| <emailofdavis@gmail.com>                             <davis.goglin@oregonicecream.com> | ||||
| Davis Goglin <emailofdavis@gmail.com>                davisgoglin <emailofdavis@gmail.com> | ||||
| Michael Billington <michael.billington@gmail.com>    Michael <michael.billington@gmail.com> | ||||
| Cody (Quantified Code Bot) <cody@quantifiedcode.com> Cody <cody@quantifiedcode.com> | ||||
| Renato Lorenzi <renato.lorenzi@senior.com.br>        Renato.Lorenzi <renato.lorenzi@senior.com.br> | ||||
| Ahmed Tahri <nyuubi.10@gmail.com>                    TAHRI Ahmed <nyuubi.10@gmail.com> | ||||
| Michael Elsdörfer <michael@elsdoerfer.com>           Michael Elsdörfer <michael@elsdoerfer.info> | ||||
| csoft2k <csoft2k@hotmail.com> | ||||
| @@ -1,8 +1,6 @@ | ||||
| language: python | ||||
| sudo: false | ||||
| cache: pip | ||||
| git: | ||||
|   depth: 100000 | ||||
| addons: | ||||
|   apt: | ||||
|     packages: | ||||
| @@ -39,7 +37,6 @@ matrix: | ||||
|     - python: pypy3 | ||||
| before_install: | ||||
|     - pip install tox codecov 'sphinx>=1.5.1' | ||||
|     - ./doc/generate_authors.sh --check | ||||
| script: | ||||
|     - tox | ||||
|     - codecov | ||||
|   | ||||
							
								
								
									
										27
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								AUTHORS
									
									
									
									
									
								
							| @@ -1,27 +0,0 @@ | ||||
| Ahmed Tahri | ||||
| Asuki Kono | ||||
| belono | ||||
| Christoph Heuel | ||||
| Cody (Quantified Code Bot) | ||||
| csoft2k | ||||
| Curtis // mashedkeyboard | ||||
| Davis Goglin | ||||
| Dean Rispin | ||||
| Dmytro Katyukha | ||||
| Hark | ||||
| Joel Lehtonen | ||||
| Kristi | ||||
| ldos | ||||
| Manuel F Martinez | ||||
| Michael Billington | ||||
| Michael Elsdörfer | ||||
| Nathan Bookham | ||||
| Patrick Kanzler | ||||
| Qian Linfeng | ||||
| Renato Lorenzi | ||||
| Romain Porte | ||||
| Sam Cheng | ||||
| Stephan Sokolow | ||||
| Thijs Triemstra | ||||
| Thomas van den Berg | ||||
| ysuolmai | ||||
| @@ -12,15 +12,6 @@ The pull requests and issues will be prefilled with templates. Please fill in yo | ||||
| This project uses `semantic versioning <http://semver.org/>`_ and tries to adhere to the proposed rules as | ||||
| well as possible. | ||||
|  | ||||
| Author-list | ||||
| ----------- | ||||
|  | ||||
| This project keeps a list of authors. This can be auto-generated by calling `./doc/generate-authors.sh`. | ||||
| When contributing the first time, please include a commit with the output of this script in place. | ||||
| Otherwise the integration-check will fail. | ||||
|  | ||||
| When you change your username or mail-address, please also update the `.mailmap` and the authors-list. | ||||
|  | ||||
| Style-Guide | ||||
| ----------- | ||||
|  | ||||
|   | ||||
| @@ -47,11 +47,10 @@ Dependencies | ||||
|  | ||||
| This library makes use of: | ||||
|  | ||||
| * `pyusb <https://github.com/walac/pyusb>`_ for USB-printers | ||||
| * `Pillow <https://github.com/python-pillow/Pillow>`_ for image printing | ||||
| * `qrcode <https://github.com/lincolnloop/python-qrcode>`_ for the generation of QR-codes | ||||
| * `pyserial <https://github.com/pyserial/pyserial>`_ for serial printers | ||||
| * `viivakoodi <https://github.com/kxepal/viivakoodi>`_ for the generation of barcodes | ||||
|     * pyusb for USB-printers | ||||
|     * Pillow for image printing | ||||
|     * qrcode for the generation of QR-codes | ||||
|     * pyserial for serial printers | ||||
|  | ||||
| Documentation and Usage | ||||
| ----------------------- | ||||
|   | ||||
							
								
								
									
										125
									
								
								appveyor.yml
									
									
									
									
									
								
							
							
						
						
									
										125
									
								
								appveyor.yml
									
									
									
									
									
								
							| @@ -1,125 +0,0 @@ | ||||
| environment: | ||||
|   global: | ||||
|     # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the | ||||
|     # /E:ON and /V:ON options are not enabled in the batch script intepreter | ||||
|     # See: http://stackoverflow.com/a/13751649/163740 | ||||
|     CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd" | ||||
|  | ||||
|   matrix: | ||||
|  | ||||
|     # Python 2.7.10 is the latest version and is not pre-installed. | ||||
|  | ||||
|     - PYTHON: "C:\\Python27.10" | ||||
|       PYTHON_VERSION: "2.7.10" | ||||
|       PYTHON_ARCH: "32" | ||||
|  | ||||
|     - PYTHON: "C:\\Python27.10-x64" | ||||
|       PYTHON_VERSION: "2.7.10" | ||||
|       PYTHON_ARCH: "64" | ||||
|  | ||||
|     # Pre-installed Python versions, which Appveyor may upgrade to | ||||
|     # a later point release. | ||||
|     # See: http://www.appveyor.com/docs/installed-software#python | ||||
|  | ||||
|     - PYTHON: "C:\\Python27" | ||||
|       PYTHON_VERSION: "2.7.x" # currently 2.7.9 | ||||
|       PYTHON_ARCH: "32" | ||||
|  | ||||
|     - PYTHON: "C:\\Python27-x64" | ||||
|       PYTHON_VERSION: "2.7.x" # currently 2.7.9 | ||||
|       PYTHON_ARCH: "64" | ||||
|  | ||||
|     - PYTHON: "C:\\Python33" | ||||
|       PYTHON_VERSION: "3.3.x" # currently 3.3.5 | ||||
|       PYTHON_ARCH: "32" | ||||
|  | ||||
|     - PYTHON: "C:\\Python33-x64" | ||||
|       PYTHON_VERSION: "3.3.x" # currently 3.3.5 | ||||
|       PYTHON_ARCH: "64" | ||||
|  | ||||
|     - PYTHON: "C:\\Python34" | ||||
|       PYTHON_VERSION: "3.4.x" # currently 3.4.3 | ||||
|       PYTHON_ARCH: "32" | ||||
|  | ||||
|     - PYTHON: "C:\\Python34-x64" | ||||
|       PYTHON_VERSION: "3.4.x" # currently 3.4.3 | ||||
|       PYTHON_ARCH: "64" | ||||
|  | ||||
|     # Python versions not pre-installed | ||||
|  | ||||
|     - PYTHON: "C:\\Python35" | ||||
|       PYTHON_VERSION: "3.5.0" | ||||
|       PYTHON_ARCH: "32" | ||||
|  | ||||
|     - PYTHON: "C:\\Python35-x64" | ||||
|       PYTHON_VERSION: "3.5.0" | ||||
|       PYTHON_ARCH: "64" | ||||
|  | ||||
|     # Major and minor releases (i.e x.0.0 and x.y.0) prior to 3.3.0 use | ||||
|     # a different naming scheme. | ||||
|  | ||||
|     - PYTHON: "C:\\Python270" | ||||
|       PYTHON_VERSION: "2.7.0" | ||||
|       PYTHON_ARCH: "32" | ||||
|  | ||||
|     - PYTHON: "C:\\Python270-x64" | ||||
|       PYTHON_VERSION: "2.7.0" | ||||
|       PYTHON_ARCH: "64" | ||||
|  | ||||
| install: | ||||
|   # If there is a newer build queued for the same PR, cancel this one. | ||||
|   # The AppVeyor 'rollout builds' option is supposed to serve the same | ||||
|   # purpose but it is problematic because it tends to cancel builds pushed | ||||
|   # directly to master instead of just PR builds (or the converse). | ||||
|   # credits: JuliaLang developers. | ||||
|   - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod ` | ||||
|         https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | ` | ||||
|         Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { ` | ||||
|           throw "There are newer queued builds for this pull request, failing early." } | ||||
|   - ECHO "Filesystem root:" | ||||
|   - ps: "ls \"C:/\"" | ||||
|  | ||||
|   - ECHO "Installed SDKs:" | ||||
|   - ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\"" | ||||
|  | ||||
|   # Install Python (from the official .msi of http://python.org) and pip when | ||||
|   # not already installed. | ||||
|   - ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 } | ||||
|  | ||||
|   # Prepend newly installed Python to the PATH of this build (this cannot be | ||||
|   # done from inside the powershell script as it would require to restart | ||||
|   # the parent CMD process). | ||||
|   - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" | ||||
|  | ||||
|   # Check that we have the expected version and architecture for Python | ||||
|   - "python --version" | ||||
|   - "python -c \"import struct; print(struct.calcsize('P') * 8)\"" | ||||
|  | ||||
|   # Upgrade to the latest version of pip to avoid it displaying warnings | ||||
|   # about it being out of date. | ||||
|   - "pip install --disable-pip-version-check --user --upgrade pip" | ||||
|  | ||||
|   # Install the build dependencies of the project. If some dependencies contain | ||||
|   # compiled extensions and are not provided as pre-built wheel packages, | ||||
|   # pip will build them from source using the MSVC compiler matching the | ||||
|   # target Python version and architecture | ||||
|   - "%CMD_IN_ENV% pip install -r requirements.txt" | ||||
|  | ||||
| build_script: | ||||
|   # Build the compiled extension | ||||
|   - "%CMD_IN_ENV% python setup.py build" | ||||
|  | ||||
| test_script: | ||||
|   # Run the project tests | ||||
|   - "%CMD_IN_ENV% python setup.py test" | ||||
|  | ||||
| after_test: | ||||
|   # If tests are successful, create binary packages for the project. | ||||
|   - "%CMD_IN_ENV% python setup.py bdist_wheel" | ||||
|   - "%CMD_IN_ENV% python setup.py bdist_wininst" | ||||
|   - "%CMD_IN_ENV% python setup.py bdist_msi" | ||||
|   - ps: "ls dist" | ||||
|  | ||||
| artifacts: | ||||
|   # Archive the generated packages in the ci.appveyor.com build report. | ||||
|   - path: dist\* | ||||
| @@ -1,229 +0,0 @@ | ||||
| # Sample script to install Python and pip under Windows | ||||
| # Authors: Olivier Grisel, Jonathan Helmus, Kyle Kastner, and Alex Willmer | ||||
| # License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ | ||||
|  | ||||
| $MINICONDA_URL = "http://repo.continuum.io/miniconda/" | ||||
| $BASE_URL = "https://www.python.org/ftp/python/" | ||||
| $GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py" | ||||
| $GET_PIP_PATH = "C:\get-pip.py" | ||||
|  | ||||
| $PYTHON_PRERELEASE_REGEX = @" | ||||
| (?x) | ||||
| (?<major>\d+) | ||||
| \. | ||||
| (?<minor>\d+) | ||||
| \. | ||||
| (?<micro>\d+) | ||||
| (?<prerelease>[a-z]{1,2}\d+) | ||||
| "@ | ||||
|  | ||||
|  | ||||
| function Download ($filename, $url) { | ||||
|     $webclient = New-Object System.Net.WebClient | ||||
|  | ||||
|     $basedir = $pwd.Path + "\" | ||||
|     $filepath = $basedir + $filename | ||||
|     if (Test-Path $filename) { | ||||
|         Write-Host "Reusing" $filepath | ||||
|         return $filepath | ||||
|     } | ||||
|  | ||||
|     # Download and retry up to 3 times in case of network transient errors. | ||||
|     Write-Host "Downloading" $filename "from" $url | ||||
|     $retry_attempts = 2 | ||||
|     for ($i = 0; $i -lt $retry_attempts; $i++) { | ||||
|         try { | ||||
|             $webclient.DownloadFile($url, $filepath) | ||||
|             break | ||||
|         } | ||||
|         Catch [Exception]{ | ||||
|             Start-Sleep 1 | ||||
|         } | ||||
|     } | ||||
|     if (Test-Path $filepath) { | ||||
|         Write-Host "File saved at" $filepath | ||||
|     } else { | ||||
|         # Retry once to get the error message if any at the last try | ||||
|         $webclient.DownloadFile($url, $filepath) | ||||
|     } | ||||
|     return $filepath | ||||
| } | ||||
|  | ||||
|  | ||||
| function ParsePythonVersion ($python_version) { | ||||
|     if ($python_version -match $PYTHON_PRERELEASE_REGEX) { | ||||
|         return ([int]$matches.major, [int]$matches.minor, [int]$matches.micro, | ||||
|                 $matches.prerelease) | ||||
|     } | ||||
|     $version_obj = [version]$python_version | ||||
|     return ($version_obj.major, $version_obj.minor, $version_obj.build, "") | ||||
| } | ||||
|  | ||||
|  | ||||
| function DownloadPython ($python_version, $platform_suffix) { | ||||
|     $major, $minor, $micro, $prerelease = ParsePythonVersion $python_version | ||||
|  | ||||
|     if (($major -le 2 -and $micro -eq 0) ` | ||||
|         -or ($major -eq 3 -and $minor -le 2 -and $micro -eq 0) ` | ||||
|         ) { | ||||
|         $dir = "$major.$minor" | ||||
|         $python_version = "$major.$minor$prerelease" | ||||
|     } else { | ||||
|         $dir = "$major.$minor.$micro" | ||||
|     } | ||||
|  | ||||
|     if ($prerelease) { | ||||
|         if (($major -le 2) ` | ||||
|             -or ($major -eq 3 -and $minor -eq 1) ` | ||||
|             -or ($major -eq 3 -and $minor -eq 2) ` | ||||
|             -or ($major -eq 3 -and $minor -eq 3) ` | ||||
|             ) { | ||||
|             $dir = "$dir/prev" | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (($major -le 2) -or ($major -le 3 -and $minor -le 4)) { | ||||
|         $ext = "msi" | ||||
|         if ($platform_suffix) { | ||||
|             $platform_suffix = ".$platform_suffix" | ||||
|         } | ||||
|     } else { | ||||
|         $ext = "exe" | ||||
|         if ($platform_suffix) { | ||||
|             $platform_suffix = "-$platform_suffix" | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     $filename = "python-$python_version$platform_suffix.$ext" | ||||
|     $url = "$BASE_URL$dir/$filename" | ||||
|     $filepath = Download $filename $url | ||||
|     return $filepath | ||||
| } | ||||
|  | ||||
|  | ||||
| function InstallPython ($python_version, $architecture, $python_home) { | ||||
|     Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home | ||||
|     if (Test-Path $python_home) { | ||||
|         Write-Host $python_home "already exists, skipping." | ||||
|         return $false | ||||
|     } | ||||
|     if ($architecture -eq "32") { | ||||
|         $platform_suffix = "" | ||||
|     } else { | ||||
|         $platform_suffix = "amd64" | ||||
|     } | ||||
|     $installer_path = DownloadPython $python_version $platform_suffix | ||||
|     $installer_ext = [System.IO.Path]::GetExtension($installer_path) | ||||
|     Write-Host "Installing $installer_path to $python_home" | ||||
|     $install_log = $python_home + ".log" | ||||
|     if ($installer_ext -eq '.msi') { | ||||
|         InstallPythonMSI $installer_path $python_home $install_log | ||||
|     } else { | ||||
|         InstallPythonEXE $installer_path $python_home $install_log | ||||
|     } | ||||
|     if (Test-Path $python_home) { | ||||
|         Write-Host "Python $python_version ($architecture) installation complete" | ||||
|     } else { | ||||
|         Write-Host "Failed to install Python in $python_home" | ||||
|         Get-Content -Path $install_log | ||||
|         Exit 1 | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| function InstallPythonEXE ($exepath, $python_home, $install_log) { | ||||
|     $install_args = "/quiet InstallAllUsers=1 TargetDir=$python_home" | ||||
|     RunCommand $exepath $install_args | ||||
| } | ||||
|  | ||||
|  | ||||
| function InstallPythonMSI ($msipath, $python_home, $install_log) { | ||||
|     $install_args = "/qn /log $install_log /i $msipath TARGETDIR=$python_home" | ||||
|     $uninstall_args = "/qn /x $msipath" | ||||
|     RunCommand "msiexec.exe" $install_args | ||||
|     if (-not(Test-Path $python_home)) { | ||||
|         Write-Host "Python seems to be installed else-where, reinstalling." | ||||
|         RunCommand "msiexec.exe" $uninstall_args | ||||
|         RunCommand "msiexec.exe" $install_args | ||||
|     } | ||||
| } | ||||
|  | ||||
| function RunCommand ($command, $command_args) { | ||||
|     Write-Host $command $command_args | ||||
|     Start-Process -FilePath $command -ArgumentList $command_args -Wait -Passthru | ||||
| } | ||||
|  | ||||
|  | ||||
| function InstallPip ($python_home) { | ||||
|     $pip_path = $python_home + "\Scripts\pip.exe" | ||||
|     $python_path = $python_home + "\python.exe" | ||||
|     if (-not(Test-Path $pip_path)) { | ||||
|         Write-Host "Installing pip..." | ||||
|         $webclient = New-Object System.Net.WebClient | ||||
|         $webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH) | ||||
|         Write-Host "Executing:" $python_path $GET_PIP_PATH | ||||
|         & $python_path $GET_PIP_PATH | ||||
|     } else { | ||||
|         Write-Host "pip already installed." | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| function DownloadMiniconda ($python_version, $platform_suffix) { | ||||
|     if ($python_version -eq "3.4") { | ||||
|         $filename = "Miniconda3-3.5.5-Windows-" + $platform_suffix + ".exe" | ||||
|     } else { | ||||
|         $filename = "Miniconda-3.5.5-Windows-" + $platform_suffix + ".exe" | ||||
|     } | ||||
|     $url = $MINICONDA_URL + $filename | ||||
|     $filepath = Download $filename $url | ||||
|     return $filepath | ||||
| } | ||||
|  | ||||
|  | ||||
| function InstallMiniconda ($python_version, $architecture, $python_home) { | ||||
|     Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home | ||||
|     if (Test-Path $python_home) { | ||||
|         Write-Host $python_home "already exists, skipping." | ||||
|         return $false | ||||
|     } | ||||
|     if ($architecture -eq "32") { | ||||
|         $platform_suffix = "x86" | ||||
|     } else { | ||||
|         $platform_suffix = "x86_64" | ||||
|     } | ||||
|     $filepath = DownloadMiniconda $python_version $platform_suffix | ||||
|     Write-Host "Installing" $filepath "to" $python_home | ||||
|     $install_log = $python_home + ".log" | ||||
|     $args = "/S /D=$python_home" | ||||
|     Write-Host $filepath $args | ||||
|     Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru | ||||
|     if (Test-Path $python_home) { | ||||
|         Write-Host "Python $python_version ($architecture) installation complete" | ||||
|     } else { | ||||
|         Write-Host "Failed to install Python in $python_home" | ||||
|         Get-Content -Path $install_log | ||||
|         Exit 1 | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| function InstallMinicondaPip ($python_home) { | ||||
|     $pip_path = $python_home + "\Scripts\pip.exe" | ||||
|     $conda_path = $python_home + "\Scripts\conda.exe" | ||||
|     if (-not(Test-Path $pip_path)) { | ||||
|         Write-Host "Installing pip..." | ||||
|         $args = "install --yes pip" | ||||
|         Write-Host $conda_path $args | ||||
|         Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru | ||||
|     } else { | ||||
|         Write-Host "pip already installed." | ||||
|     } | ||||
| } | ||||
|  | ||||
| function main () { | ||||
|     InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON | ||||
|     InstallPip $env:PYTHON | ||||
| } | ||||
|  | ||||
| main | ||||
| @@ -1,88 +0,0 @@ | ||||
| :: To build extensions for 64 bit Python 3, we need to configure environment | ||||
| :: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of: | ||||
| :: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1) | ||||
| :: | ||||
| :: To build extensions for 64 bit Python 2, we need to configure environment | ||||
| :: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of: | ||||
| :: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0) | ||||
| :: | ||||
| :: 32 bit builds, and 64-bit builds for 3.5 and beyond, do not require specific | ||||
| :: environment configurations. | ||||
| :: | ||||
| :: Note: this script needs to be run with the /E:ON and /V:ON flags for the | ||||
| :: cmd interpreter, at least for (SDK v7.0) | ||||
| :: | ||||
| :: More details at: | ||||
| :: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows | ||||
| :: http://stackoverflow.com/a/13751649/163740 | ||||
| :: | ||||
| :: Author: Olivier Grisel | ||||
| :: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ | ||||
| :: | ||||
| :: Notes about batch files for Python people: | ||||
| :: | ||||
| :: Quotes in values are literally part of the values: | ||||
| ::      SET FOO="bar" | ||||
| :: FOO is now five characters long: " b a r " | ||||
| :: If you don't want quotes, don't include them on the right-hand side. | ||||
| :: | ||||
| :: The CALL lines at the end of this file look redundant, but if you move them | ||||
| :: outside of the IF clauses, they do not run properly in the SET_SDK_64==Y | ||||
| :: case, I don't know why. | ||||
| @ECHO OFF | ||||
|  | ||||
| SET COMMAND_TO_RUN=%* | ||||
| SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows | ||||
| SET WIN_WDK=c:\Program Files (x86)\Windows Kits\10\Include\wdf | ||||
|  | ||||
| :: Extract the major and minor versions, and allow for the minor version to be | ||||
| :: more than 9.  This requires the version number to have two dots in it. | ||||
| SET MAJOR_PYTHON_VERSION=%PYTHON_VERSION:~0,1% | ||||
| IF "%PYTHON_VERSION:~3,1%" == "." ( | ||||
|     SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1% | ||||
| ) ELSE ( | ||||
|     SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,2% | ||||
| ) | ||||
|  | ||||
| :: Based on the Python version, determine what SDK version to use, and whether | ||||
| :: to set the SDK for 64-bit. | ||||
| IF %MAJOR_PYTHON_VERSION% == 2 ( | ||||
|     SET WINDOWS_SDK_VERSION="v7.0" | ||||
|     SET SET_SDK_64=Y | ||||
| ) ELSE ( | ||||
|     IF %MAJOR_PYTHON_VERSION% == 3 ( | ||||
|         SET WINDOWS_SDK_VERSION="v7.1" | ||||
|         IF %MINOR_PYTHON_VERSION% LEQ 4 ( | ||||
|             SET SET_SDK_64=Y | ||||
|         ) ELSE ( | ||||
|             SET SET_SDK_64=N | ||||
|             IF EXIST "%WIN_WDK%" ( | ||||
|                 :: See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/ | ||||
|                 REN "%WIN_WDK%" 0wdf | ||||
|             ) | ||||
|         ) | ||||
|     ) ELSE ( | ||||
|         ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%" | ||||
|         EXIT 1 | ||||
|     ) | ||||
| ) | ||||
|  | ||||
| IF %PYTHON_ARCH% == 64 ( | ||||
|     IF %SET_SDK_64% == Y ( | ||||
|         ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture | ||||
|         SET DISTUTILS_USE_SDK=1 | ||||
|         SET MSSdk=1 | ||||
|         "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION% | ||||
|         "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release | ||||
|         ECHO Executing: %COMMAND_TO_RUN% | ||||
|         call %COMMAND_TO_RUN% || EXIT 1 | ||||
|     ) ELSE ( | ||||
|         ECHO Using default MSVC build environment for 64 bit architecture | ||||
|         ECHO Executing: %COMMAND_TO_RUN% | ||||
|         call %COMMAND_TO_RUN% || EXIT 1 | ||||
|     ) | ||||
| ) ELSE ( | ||||
|     ECHO Using default MSVC build environment for 32 bit architecture | ||||
|     ECHO Executing: %COMMAND_TO_RUN% | ||||
|     call %COMMAND_TO_RUN% || EXIT 1 | ||||
| ) | ||||
							
								
								
									
										94
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | ||||
| python-escpos (1.0.8-3) unstable; urgency=medium | ||||
|  | ||||
|   [ Christoph Heuel ] | ||||
|   * Fix text wrapping error after image | ||||
|  | ||||
|   [ Patrick Kanzler ] | ||||
|   * moved .hgignore to .gitignore | ||||
|   * REFACTOR chained boolean expression in escpos | ||||
|   * REFACTOR use new-style class for Escpos | ||||
|   * REFACTOR style and PEP8, fixes #66 | ||||
|   * REFACTOR do not shadow built-ins | ||||
|   * ADD requirements.txt and requirements to setup.py | ||||
|   * DOC, IMPROVE improve docstrings and add abstract method _raw to Escpos | ||||
|   * FIX constant definition for PC1252 | ||||
|  | ||||
|  -- Christoph Heuel <mail@christoph-heuel.net>  Sun, 13 Dec 2015 14:27:27 +0100 | ||||
|  | ||||
| python-escpos (1.0.8-2) unstable; urgency=low | ||||
|  | ||||
|   * Imported source  | ||||
|   * First debianization | ||||
|  | ||||
|  -- Christoph Heuel <mail@christoph-heuel.net>  Sat, 12 Dec 2015 19:13:33 +0100 | ||||
|  | ||||
| python-escpos (1.0.8-1) unstable; urgency=low | ||||
|  | ||||
|   [ Manuel F Martinez ] | ||||
|   * Added donation message | ||||
|  | ||||
|   [ Joel Lehtonen ] | ||||
|   * Support for images vertically longer than 256 pixels | ||||
|  | ||||
|   [ Christoph Heuel ] | ||||
|   * Fix mixed tabs/space error | ||||
|  | ||||
|   [ Hark ] | ||||
|   * Prevent crash when using libusb0 printers | ||||
|  | ||||
|   [ Manuel F Martinez ] | ||||
|   * Updated README and documentation | ||||
|  | ||||
|   [ Christoph Heuel ] | ||||
|   * Add flush function | ||||
|   * Debian packaging | ||||
|  | ||||
|  -- Manuel F Martinez <manpaz@gmail.com>  Sat, 12 Dec 2015 20:59:53 +0100 | ||||
|  | ||||
| python-escpos (1.0.7-1) unstable; urgency=low | ||||
|  | ||||
|   [ Kristi ] | ||||
|   * Raising the right error when wrong charcode is used | ||||
|  | ||||
|   [ Christoph Heuel ] | ||||
|   * After running 2to3 tool | ||||
|   * Fix for string operation | ||||
|   * Integer is needed, not float | ||||
|   * Add text wrapping | ||||
|  | ||||
|   [ Manuel F Martinez ] | ||||
|   * Updated URL for the documentation | ||||
|   * Updated documentation URL to local wiki | ||||
|   * Updated setup URLs | ||||
|  | ||||
|   [ Christoph Heuel ] | ||||
|   * Introduce new direct_image | ||||
|  | ||||
|   [ Manuel F Martinez ] | ||||
|   * Fixed License version mismatch | ||||
|  | ||||
|   [ Christoph Heuel ] | ||||
|   * Use unhexlify | ||||
|   * Hexlify text | ||||
|  | ||||
|   [ Manuel F Martinez ] | ||||
|   * Updated accordingly to the wiki | ||||
|  | ||||
|   [ ldos ] | ||||
|   * Extended params for serial printers | ||||
|  | ||||
|   [ Manuel F Martinez ] | ||||
|   * Fixed issues with transparent images | ||||
|   * Updated project version | ||||
|  | ||||
|  -- Manuel F Martinez <manpaz@gmail.com>  Sat, 12 Dec 2015 20:59:53 +0100 | ||||
|  | ||||
| python-escpos (1.0.4-1) unstable; urgency=medium | ||||
|  | ||||
|   [ Manuel F Martinez ] | ||||
|   * Added density support | ||||
|   * Added quad support | ||||
|   * fixed code tabulators | ||||
|   * Updated version | ||||
|  | ||||
|  -- Manuel F Martinez <manpaz@gmail.com>  Sat, 12 Dec 2015 20:59:53 +0100 | ||||
							
								
								
									
										1
									
								
								debian/compat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								debian/compat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| 9 | ||||
							
								
								
									
										55
									
								
								debian/control
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								debian/control
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| Source: python-escpos | ||||
| Section: unknown | ||||
| Priority: optional | ||||
| Maintainer: Christoph Heuel <mail@christoph-heuel.net> | ||||
| Build-Depends: debhelper (>= 9), dh-python | ||||
| Standards-Version: 3.9.5 | ||||
| Homepage: https://github.com/braveheuel/python-escpos | ||||
| #Vcs-Git: git@github.com:braveheuel/python-escpos.git | ||||
| #Vcs-Browser: https://github.com/braveheuel/python-escpos | ||||
|  | ||||
| Package: python-escpos | ||||
| Architecture: all | ||||
| Depends: ${misc:Depends} | ||||
| Description: Python library to manipulate ESC/POS Printers (Python 2) | ||||
|  Python ESC/POS is a library which lets the user have access to all | ||||
|  those printers handled by ESC/POS commands, as defined by Epson, | ||||
|  from a Python application. | ||||
|  . | ||||
|  The standard usage is send raw text to the printer, but in also  | ||||
|  helps the user to enhance the experience with those printers by | ||||
|  facilitating the bar code printing in many different standards, | ||||
|  as well as manipulating images so they can be printed as brand | ||||
|  logo or any other usage images migh have.  | ||||
|  . | ||||
|  Text can be aligned/justified and fonts can be changed by size, | ||||
|  type and weight. | ||||
|  . | ||||
|  Also, this module handles some hardware functionalities like, cut | ||||
|  paper, carrier return, printer reset and others concerned to the | ||||
|  carriage alignment. | ||||
|  . | ||||
|  This package covers Python 2 code. | ||||
|  | ||||
| Package: python3-escpos | ||||
| Architecture: all | ||||
| Depends: ${misc:Depends} | ||||
| Description: Python library to manipulate ESC/POS Printers (Python 3) | ||||
|  Python ESC/POS is a library which lets the user have access to all | ||||
|  those printers handled by ESC/POS commands, as defined by Epson, | ||||
|  from a Python application. | ||||
|  . | ||||
|  The standard usage is send raw text to the printer, but in also  | ||||
|  helps the user to enhance the experience with those printers by | ||||
|  facilitating the bar code printing in many different standards, | ||||
|  as well as manipulating images so they can be printed as brand | ||||
|  logo or any other usage images migh have.  | ||||
|  . | ||||
|  Text can be aligned/justified and fonts can be changed by size, | ||||
|  type and weight. | ||||
|  . | ||||
|  Also, this module handles some hardware functionalities like, cut | ||||
|  paper, carrier return, printer reset and others concerned to the | ||||
|  carriage alignment. | ||||
|  . | ||||
|  This package covers Python 3 code. | ||||
							
								
								
									
										26
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ | ||||
| Upstream-Name: python-escpos | ||||
| Source: https://github.com/manpaz/python-escpos | ||||
|  | ||||
| Files: * | ||||
| Copyright: 2015 Manuel F Martinez <manpaz@bashlinux.com> | ||||
| License: GPL v3 | ||||
|  | ||||
| Files: debian/* | ||||
| Copyright: 2015 Christoph Heuel <mail@christoph-heuel.net> | ||||
| License: GPL-2+ | ||||
|  This package 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 2 of the License, or | ||||
|  (at your option) any later version. | ||||
|  . | ||||
|  This package is distributed in the hope that it will be useful, | ||||
|  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  GNU General Public License for more details. | ||||
|  . | ||||
|  You should have received a copy of the GNU General Public License | ||||
|  along with this program. If not, see <http://www.gnu.org/licenses/> | ||||
|  . | ||||
|  On Debian systems, the complete text of the GNU General | ||||
|  Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". | ||||
							
								
								
									
										1
									
								
								debian/docs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								debian/docs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| README.rst | ||||
							
								
								
									
										6
									
								
								debian/gbp.conf
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								debian/gbp.conf
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| [DEFAULT] | ||||
| upstream-branch=master | ||||
| upstream-tree = tag  | ||||
| debian-branch = debian/jessie | ||||
| upstream-tag = v%(version)s | ||||
| debian-tag = v%(version)s | ||||
							
								
								
									
										28
									
								
								debian/rules
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										28
									
								
								debian/rules
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| #!/usr/bin/make -f | ||||
| # See debhelper(7) (uncomment to enable) | ||||
| # output every command that modifies files on the build system. | ||||
| #DH_VERBOSE = 1 | ||||
|  | ||||
| # see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* | ||||
| DPKG_EXPORT_BUILDFLAGS = 1 | ||||
| include /usr/share/dpkg/default.mk | ||||
|  | ||||
| # see FEATURE AREAS in dpkg-buildflags(1) | ||||
| #export DEB_BUILD_MAINT_OPTIONS = hardening=+all | ||||
|  | ||||
| # see ENVIRONMENT in dpkg-buildflags(1) | ||||
| # package maintainers to append CFLAGS | ||||
| #export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic | ||||
| # package maintainers to append LDFLAGS | ||||
| #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed | ||||
|  | ||||
|  | ||||
| # main packaging script based on dh7 syntax | ||||
| %: | ||||
| 	dh $@ --with python2,python3 --buildsystem=pybuild | ||||
|  | ||||
| # debmake generated override targets | ||||
| # This is example for Cmake (See http://bugs.debian.org/641051 ) | ||||
| #override_dh_auto_configure: | ||||
| #	dh_auto_configure -- \ | ||||
| #	-DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) | ||||
							
								
								
									
										1
									
								
								debian/source/format
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								debian/source/format
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| 3.0 (quilt) | ||||
| @@ -1,19 +0,0 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| GENLIST=$(git shortlog -s -n | cut -f2 | sort) | ||||
| AUTHORSFILE="$(dirname $0)/../AUTHORS" | ||||
| TEMPAUTHORSFILE="/tmp/python-escpos-authorsfile" | ||||
|  | ||||
| if [ "$#" -eq 1 ] | ||||
|     then | ||||
|         echo "$GENLIST">$TEMPAUTHORSFILE | ||||
| 	echo "\nAuthorsfile in version control:\n" | ||||
| 	cat $AUTHORSFILE | ||||
| 	echo "\nNew authorsfile:\n" | ||||
| 	cat $TEMPAUTHORSFILE | ||||
| 	echo "\nUsing diff on files...\n" | ||||
|         diff -q --from-file $AUTHORSFILE $TEMPAUTHORSFILE | ||||
|     else | ||||
| 	echo "$GENLIST">$AUTHORSFILE | ||||
| fi | ||||
|  | ||||
| @@ -1,7 +1,6 @@ | ||||
| ***** | ||||
| Usage | ||||
| ***** | ||||
| :Last Reviewed: 2017-06-10 | ||||
|  | ||||
| Define your printer | ||||
| ------------------- | ||||
| @@ -134,13 +133,13 @@ format. For windows it is probably at:: | ||||
|  | ||||
| And for linux:: | ||||
|  | ||||
|     $HOME/.config/python-escpos/config.yaml | ||||
|         $HOME/.config/python-escpos/config.yaml | ||||
|  | ||||
| If you aren't sure, run:: | ||||
|  | ||||
|     from escpos import config | ||||
|     c = config.Config() | ||||
|     c.load() | ||||
|         from escpos import config | ||||
|         c = config.Config() | ||||
|         c.load() | ||||
|  | ||||
| If it can't find the configuration file in the default location, it will tell | ||||
| you where it's looking. You can always pass a path, or a list of paths, to | ||||
| @@ -148,9 +147,9 @@ the ``load()`` method. | ||||
|  | ||||
| To load the configured printer, run:: | ||||
|  | ||||
|     from escpos import config | ||||
|     c = config.Config() | ||||
|     printer = c.printer() | ||||
|         from escpos import config | ||||
|         c = config.Config() | ||||
|         printer = c.printer() | ||||
|  | ||||
|  | ||||
| The printer section | ||||
| @@ -158,34 +157,23 @@ The printer section | ||||
|  | ||||
| The ``printer`` configuration section defines a default printer to create. | ||||
|  | ||||
| The only required paramter is ``type``. The value of this has to be one of the | ||||
| The only required paramter is ``type``. The value of this should be one of the | ||||
| printers defined in :doc:`/user/printers`. | ||||
|  | ||||
| The rest of the given parameters will be passed on to the initialization of the printer class. | ||||
| Use these to overwrite the default values as specified in :doc:`/user/printers`. | ||||
| This implies that the parameters have to match the parameter-names of the respective printer class. | ||||
| The rest of the parameters are whatever you want to pass to the printer. | ||||
|  | ||||
| An example file printer:: | ||||
|  | ||||
|     printer: | ||||
|             type: File | ||||
|             devfile: /dev/someprinter | ||||
|         printer: | ||||
|                 type: File | ||||
|                 devfile: /dev/someprinter | ||||
|  | ||||
| And for a network printer:: | ||||
|  | ||||
|     printer: | ||||
|             type: Network | ||||
|             host: 127.0.0.1 | ||||
|             port: 9000 | ||||
|  | ||||
| An USB-printer could be defined by:: | ||||
|  | ||||
|     printer: | ||||
|             type: Usb | ||||
|             idVendor: 0x1234 | ||||
|             idProduct: 0x5678 | ||||
|             in_ep: 0x66 | ||||
|             out_ep: 0x01 | ||||
|         printer: | ||||
|                 type: network | ||||
|                 host: 127.0.0.1 | ||||
|                 port: 9000 | ||||
|  | ||||
| Printing text right | ||||
| ------------------- | ||||
|   | ||||
| @@ -1,19 +0,0 @@ | ||||
| import sys | ||||
|  | ||||
| from escpos.printer import Usb | ||||
|  | ||||
|  | ||||
| def usage(): | ||||
|     print("usage: qr_code.py <content>") | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     if len(sys.argv) != 2: | ||||
|         usage() | ||||
|         sys.exit(1) | ||||
|  | ||||
|     content = sys.argv[1] | ||||
|  | ||||
|     # Adapt to your needs | ||||
|     p = Usb(0x0416, 0x5011, profile="POS-5890") | ||||
|     p.qr(content) | ||||
| @@ -1,9 +0,0 @@ | ||||
| from escpos.printer import Usb | ||||
|  | ||||
|  | ||||
| # Adapt to your needs | ||||
| p = Usb(0x0416, 0x5011, profile="POS-5890") | ||||
|  | ||||
| # Some software barcodes | ||||
| p.soft_barcode('code128', 'Hello') | ||||
| p.soft_barcode('code39', '123456') | ||||
							
								
								
									
										5
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								setup.py
									
									
									
									
									
								
							| @@ -100,8 +100,6 @@ setup( | ||||
|         'Programming Language :: Python :: 3.3', | ||||
|         'Programming Language :: Python :: 3.4', | ||||
|         'Programming Language :: Python :: 3.5', | ||||
|         'Programming Language :: Python :: 3.6', | ||||
|         'Programming Language :: Python :: 3.7', | ||||
|         'Programming Language :: Python :: Implementation :: CPython', | ||||
|         'Programming Language :: Python :: Implementation :: PyPy', | ||||
|         'Topic :: Software Development :: Libraries :: Python Modules', | ||||
| @@ -117,8 +115,7 @@ setup( | ||||
|         'pyyaml', | ||||
|         'argparse', | ||||
|         'argcomplete', | ||||
|         'future', | ||||
|         'viivakoodi>=0.8' | ||||
|         'future' | ||||
|     ], | ||||
|     setup_requires=[ | ||||
|         'setuptools_scm', | ||||
|   | ||||
| @@ -64,11 +64,6 @@ _PANEL_BUTTON = lambda n: ESC + b'c5' + six.int2byte(n) | ||||
| PANEL_BUTTON_ON = _PANEL_BUTTON(0)  # enable all panel buttons | ||||
| PANEL_BUTTON_OFF = _PANEL_BUTTON(1)  # disable all panel buttons | ||||
|  | ||||
| # Line display printing | ||||
| LINE_DISPLAY_OPEN = ESC + b'\x3d\x02' | ||||
| LINE_DISPLAY_CLEAR = ESC + b'\x40' | ||||
| LINE_DISPLAY_CLOSE = ESC + b'\x3d\x01' | ||||
|  | ||||
| # Sheet modes | ||||
| SHEET_SLIP_MODE = ESC + b'\x63\x30\x04'  # slip paper | ||||
| SHEET_ROLL_MODE = ESC + b'\x63\x30\x01'  # paper roll | ||||
| @@ -76,90 +71,51 @@ SHEET_ROLL_MODE = ESC + b'\x63\x30\x01'  # paper roll | ||||
| # Text format | ||||
| # TODO: Acquire the "ESC/POS Application Programming Guide for Paper Roll | ||||
| #       Printers" and tidy up this stuff too. | ||||
| TXT_FLIP_ON    = ESC + b'\x7b\x01' | ||||
| TXT_FLIP_OFF   = ESC + b'\x7b\x00' | ||||
| TXT_SMOOTH_ON  = GS + b'\x62\x01' | ||||
| TXT_SMOOTH_OFF = GS + b'\x62\x00' | ||||
| TXT_SIZE       = GS + b'!' | ||||
|  | ||||
| TXT_WIDTH      = {1: 0x00, | ||||
|                   2: 0x10, | ||||
|                   3: 0x20, | ||||
|                   4: 0x30, | ||||
|                   5: 0x40, | ||||
|                   6: 0x50, | ||||
|                   7: 0x60, | ||||
|                   8: 0x70} | ||||
| TXT_HEIGHT     = {1: 0x00, | ||||
|                   2: 0x01, | ||||
|                   3: 0x02, | ||||
|                   4: 0x03, | ||||
|                   5: 0x04, | ||||
|                   6: 0x05, | ||||
|                   7: 0x06, | ||||
|                   8: 0x07} | ||||
| TXT_NORMAL     = ESC + b'!\x00'     # Normal text | ||||
|  | ||||
|  | ||||
| TXT_STYLE = { | ||||
|     'bold': { | ||||
|         False: ESC + b'\x45\x00',               # Bold font OFF | ||||
|         True: ESC + b'\x45\x01'                 # Bold font ON | ||||
|     }, | ||||
|     'underline': { | ||||
|         0: ESC + b'\x2d\x00',                   # Underline font OFF | ||||
|         1: ESC + b'\x2d\x01',                   # Underline font 1-dot ON | ||||
|         2: ESC + b'\x2d\x02'                    # Underline font 2-dot ON | ||||
|     }, | ||||
|     'size': { | ||||
|         'normal': TXT_NORMAL + ESC + b'!\x00',  # Normal text | ||||
|         '2h': TXT_NORMAL + ESC + b'!\x10',      # Double height text | ||||
|         '2w': TXT_NORMAL + ESC + b'!\x20',      # Double width text | ||||
|         '2x': TXT_NORMAL + ESC + b'!\x30'       # Quad area text | ||||
|     }, | ||||
|     'font': { | ||||
|         'a': ESC + b'\x4d\x00',                 # Font type A | ||||
|         'b': ESC + b'\x4d\x00'                  # Font type B | ||||
|     }, | ||||
|     'align': { | ||||
|         'left': ESC + b'\x61\x00',              # Left justification | ||||
|         'center': ESC + b'\x61\x01',            # Centering | ||||
|         'right': ESC + b'\x61\x02'              # Right justification | ||||
|     }, | ||||
|     'invert': { | ||||
|         True: GS  + b'\x42\x01',                # Inverse Printing ON | ||||
|         False: GS  + b'\x42\x00'                # Inverse Printing OFF | ||||
|     }, | ||||
|     'color': { | ||||
|         'black': ESC + b'\x72\x00',             # Default Color | ||||
|         'red': ESC + b'\x72\x01'                # Alternative Color, Usually Red | ||||
|     }, | ||||
|     'flip': { | ||||
|         True: ESC + b'\x7b\x01',                # Flip ON | ||||
|         False: ESC + b'\x7b\x00'                # Flip OFF | ||||
|     }, | ||||
|     'density': { | ||||
|         0: GS + b'\x7c\x00',                    # Printing Density -50% | ||||
|         1: GS + b'\x7c\x01',                    # Printing Density -37.5% | ||||
|         2: GS + b'\x7c\x02',                    # Printing Density -25% | ||||
|         3: GS + b'\x7c\x03',                    # Printing Density -12.5% | ||||
|         4: GS + b'\x7c\x04',                    # Printing Density  0% | ||||
|         5: GS + b'\x7c\x08',                    # Printing Density +50% | ||||
|         6: GS + b'\x7c\x07',                    # Printing Density +37.5% | ||||
|         7: GS + b'\x7c\x06',                    # Printing Density +25% | ||||
|         8: GS + b'\x7c\x05'                     # Printing Density +12.5% | ||||
|     }, | ||||
|     'smooth': { | ||||
|         True: GS + b'\x62\x01',                 # Smooth ON | ||||
|         False: GS + b'\x62\x00'                 # Smooth OFF | ||||
|     }, | ||||
|     'height': {                                 # Custom text height | ||||
|         1: 0x00, | ||||
|         2: 0x01, | ||||
|         3: 0x02, | ||||
|         4: 0x03, | ||||
|         5: 0x04, | ||||
|         6: 0x05, | ||||
|         7: 0x06, | ||||
|         8: 0x07 | ||||
|     }, | ||||
|     'width': {                                  # Custom text width | ||||
|         1: 0x00, | ||||
|         2: 0x10, | ||||
|         3: 0x20, | ||||
|         4: 0x30, | ||||
|         5: 0x40, | ||||
|         6: 0x50, | ||||
|         7: 0x60, | ||||
|         8: 0x70 | ||||
|     } | ||||
| } | ||||
| TXT_2HEIGHT    = ESC + b'!\x10'     # Double height text | ||||
| TXT_2WIDTH     = ESC + b'!\x20'     # Double width text | ||||
| TXT_4SQUARE    = ESC + b'!\x30'     # Quad area text | ||||
| TXT_UNDERL_OFF = ESC + b'\x2d\x00'  # Underline font OFF | ||||
| TXT_UNDERL_ON  = ESC + b'\x2d\x01'  # Underline font 1-dot ON | ||||
| TXT_UNDERL2_ON = ESC + b'\x2d\x02'  # Underline font 2-dot ON | ||||
| TXT_BOLD_OFF   = ESC + b'\x45\x00'  # Bold font OFF | ||||
| TXT_BOLD_ON    = ESC + b'\x45\x01'  # Bold font ON | ||||
| TXT_ALIGN_LT   = ESC + b'\x61\x00'  # Left justification | ||||
| TXT_ALIGN_CT   = ESC + b'\x61\x01'  # Centering | ||||
| TXT_ALIGN_RT   = ESC + b'\x61\x02'  # Right justification | ||||
| TXT_INVERT_ON  = GS  + b'\x42\x01'  # Inverse Printing ON | ||||
| TXT_INVERT_OFF = GS  + b'\x42\x00'  # Inverse Printing OFF | ||||
|  | ||||
| # Fonts | ||||
| SET_FONT = lambda n: ESC + b'\x4d' + n | ||||
| TXT_FONT_A     = SET_FONT(b'\x00')  # Font type A | ||||
| TXT_FONT_B     = SET_FONT(b'\x01')  # Font type B | ||||
|  | ||||
| # Text colors | ||||
| TXT_COLOR_BLACK = ESC + b'\x72\x00'  # Default Color | ||||
| TXT_COLOR_RED = ESC + b'\x72\x01'    # Alternative Color (Usually Red) | ||||
|  | ||||
| # Spacing | ||||
| LINESPACING_RESET = ESC + b'2' | ||||
| LINESPACING_FUNCS = { | ||||
| @@ -250,6 +206,13 @@ S_RASTER_2W = _PRINT_RASTER_IMG(b'\x01')  # Set raster image double width | ||||
| S_RASTER_2H = _PRINT_RASTER_IMG(b'\x02')  # Set raster image double height | ||||
| S_RASTER_Q  = _PRINT_RASTER_IMG(b'\x03')  # Set raster image quadruple | ||||
|  | ||||
| # Status Command | ||||
| RT_STATUS_ONLINE = DLE + EOT +  b'\x01'; | ||||
| RT_MASK_ONLINE = 8; | ||||
| # Printing Density | ||||
| PD_N50 = GS + b'\x7c\x00'  # Printing Density -50% | ||||
| PD_N37 = GS + b'\x7c\x01'  # Printing Density -37.5% | ||||
| PD_N25 = GS + b'\x7c\x02'  # Printing Density -25% | ||||
| PD_N12 = GS + b'\x7c\x03'  # Printing Density -12.5% | ||||
| PD_0   = GS + b'\x7c\x04'  # Printing Density  0% | ||||
| PD_P50 = GS + b'\x7c\x08'  # Printing Density +50% | ||||
| PD_P37 = GS + b'\x7c\x07'  # Printing Density +37.5% | ||||
| PD_P25 = GS + b'\x7c\x06'  # Printing Density +25% | ||||
| PD_P12 = GS + b'\x7c\x05'  # Printing Density +12.5% | ||||
|   | ||||
| @@ -18,28 +18,22 @@ from __future__ import unicode_literals | ||||
| import qrcode | ||||
| import textwrap | ||||
| import six | ||||
| import time | ||||
|  | ||||
| import barcode | ||||
| from barcode.writer import ImageWriter | ||||
|  | ||||
| from .constants import ESC, GS, NUL, QR_ECLEVEL_L, QR_ECLEVEL_M, QR_ECLEVEL_H, QR_ECLEVEL_Q | ||||
| from .constants import QR_MODEL_1, QR_MODEL_2, QR_MICRO, BARCODE_TYPES, BARCODE_HEIGHT, BARCODE_WIDTH | ||||
| from .constants import BARCODE_FONT_A, BARCODE_FONT_B | ||||
| from .constants import TXT_ALIGN_CT, TXT_ALIGN_LT, TXT_ALIGN_RT, BARCODE_FONT_A, BARCODE_FONT_B | ||||
| from .constants import BARCODE_TXT_OFF, BARCODE_TXT_BTH, BARCODE_TXT_ABV, BARCODE_TXT_BLW | ||||
| from .constants import TXT_SIZE, TXT_NORMAL | ||||
| from .constants import SET_FONT | ||||
| from .constants import LINESPACING_FUNCS, LINESPACING_RESET | ||||
| from .constants import LINE_DISPLAY_OPEN, LINE_DISPLAY_CLEAR, LINE_DISPLAY_CLOSE | ||||
| from .constants import TXT_HEIGHT, TXT_WIDTH, TXT_SIZE, TXT_NORMAL, TXT_SMOOTH_OFF, TXT_SMOOTH_ON | ||||
| from .constants import TXT_FLIP_OFF, TXT_FLIP_ON, TXT_2WIDTH, TXT_2HEIGHT, TXT_4SQUARE | ||||
| from .constants import TXT_UNDERL_OFF, TXT_UNDERL_ON, TXT_BOLD_OFF, TXT_BOLD_ON, SET_FONT, TXT_UNDERL2_ON | ||||
| from .constants import TXT_INVERT_OFF, TXT_INVERT_ON, LINESPACING_FUNCS, LINESPACING_RESET | ||||
| from .constants import PD_0, PD_N12, PD_N25, PD_N37, PD_N50, PD_P50, PD_P37, PD_P25, PD_P12 | ||||
| from .constants import CD_KICK_DEC_SEQUENCE, CD_KICK_5, CD_KICK_2, PAPER_FULL_CUT, PAPER_PART_CUT | ||||
| from .constants import HW_RESET, HW_SELECT, HW_INIT | ||||
| from .constants import CTL_VT, CTL_CR, CTL_FF, CTL_LF, CTL_SET_HT, PANEL_BUTTON_OFF, PANEL_BUTTON_ON | ||||
| from .constants import TXT_STYLE | ||||
| from .constants import RT_STATUS_ONLINE, RT_MASK_ONLINE | ||||
| from .constants import CTL_VT, CTL_HT, CTL_CR, CTL_FF, CTL_LF, CTL_SET_HT, PANEL_BUTTON_OFF, PANEL_BUTTON_ON | ||||
|  | ||||
| from .exceptions import BarcodeTypeError, BarcodeSizeError, TabPosError | ||||
| from .exceptions import CashDrawerError, SetVariableError, BarcodeCodeError | ||||
| from .exceptions import ImageWidthError | ||||
|  | ||||
| from .magicencode import MagicEncode | ||||
|  | ||||
| @@ -79,12 +73,6 @@ class Escpos(object): | ||||
|         """ | ||||
|         pass | ||||
|  | ||||
|     def _read(self, msg): | ||||
|         """ Returns a NotImplementedError if the instance of the class doesn't override this method. | ||||
|         :raises NotImplementedError | ||||
|         """ | ||||
|         raise NotImplementedError() | ||||
|  | ||||
|     def image(self, img_source, high_density_vertical=True, high_density_horizontal=True, impl="bitImageRaster", | ||||
|               fragment_height=960): | ||||
|         """ Print an image | ||||
| @@ -111,17 +99,6 @@ class Escpos(object): | ||||
|         """ | ||||
|         im = EscposImage(img_source) | ||||
|  | ||||
|         try: | ||||
|             max_width = int(self.profile.profile_data['media']['width']['pixels']) | ||||
|             if im.width > max_width: | ||||
|                 raise ImageWidthError('{} > {}'.format(im.width, max_width)) | ||||
|         except KeyError: | ||||
|             # If the printer's pixel width is not known, print anyways... | ||||
|             pass | ||||
|         except ValueError: | ||||
|             # If the max_width cannot be converted to an int, print anyways... | ||||
|             pass | ||||
|  | ||||
|         if im.height > fragment_height: | ||||
|             fragments = im.split(fragment_height) | ||||
|             for fragment in fragments: | ||||
| @@ -211,10 +188,7 @@ class Escpos(object): | ||||
|             qr_img = qr_code.make_image() | ||||
|             im = qr_img._img.convert("RGB") | ||||
|             # Convert the RGB image in printable image | ||||
|             self.text('\n') | ||||
|             self.image(im) | ||||
|             self.text('\n') | ||||
|             self.text('\n') | ||||
|             return | ||||
|         # Native 2D code printing | ||||
|         cn = b'1'  # Code type for QR code | ||||
| @@ -382,7 +356,7 @@ class Escpos(object): | ||||
|  | ||||
|         # Align Bar Code() | ||||
|         if align_ct: | ||||
|             self._raw(TXT_STYLE['align']['center']) | ||||
|             self._raw(TXT_ALIGN_CT) | ||||
|         # Height | ||||
|         if 1 <= height <= 255: | ||||
|             self._raw(BARCODE_HEIGHT + six.int2byte(height)) | ||||
| @@ -422,31 +396,6 @@ class Escpos(object): | ||||
|         if function_type.upper() == "A": | ||||
|             self._raw(NUL) | ||||
|  | ||||
|     def soft_barcode(self, barcode_type, data, impl='bitImageColumn', | ||||
|                      module_height=5, module_width=0.2, text_distance=1): | ||||
|  | ||||
|         image_writer = ImageWriter() | ||||
|  | ||||
|         # Check if barcode type exists | ||||
|         if barcode_type not in barcode.PROVIDED_BARCODES: | ||||
|             raise BarcodeTypeError( | ||||
|                 'Barcode type {} not supported by software barcode renderer' | ||||
|                 .format(barcode_type)) | ||||
|  | ||||
|         # Render the barcode to a fake file | ||||
|         barcode_class = barcode.get_barcode_class(barcode_type) | ||||
|         my_code = barcode_class(data, writer=image_writer) | ||||
|  | ||||
|         my_code.write("/dev/null", { | ||||
|             'module_height': module_height, | ||||
|             'module_width': module_width, | ||||
|             'text_distance': text_distance | ||||
|         }) | ||||
|  | ||||
|         # Retrieve the Pillow image and print it | ||||
|         image = my_code.writer._image | ||||
|         self.image(image, impl=impl) | ||||
|  | ||||
|     def text(self, txt): | ||||
|         """ Print alpha-numeric text | ||||
|  | ||||
| @@ -465,85 +414,126 @@ class Escpos(object): | ||||
|         Text has to be encoded in unicode. | ||||
|  | ||||
|         :param txt: text to be printed | ||||
|         :param font: font to be used, can be :code:`a` or :code:`b` | ||||
|         :param font: font to be used, can be :code:`a` or :code`b` | ||||
|         :param columns: amount of columns | ||||
|         :return: None | ||||
|         """ | ||||
|         col_count = self.profile.get_columns(font) if columns is None else columns | ||||
|         self.text(textwrap.fill(txt, col_count)) | ||||
|  | ||||
|     def set(self, align='left', font='a', bold=False, underline=0, width=1, | ||||
|             height=1, density=9, invert=False, smooth=False, flip=False, | ||||
|             double_width=False, double_height=False, custom_size=False): | ||||
|     def set(self, align='left', font='a', text_type='normal', width=1, | ||||
|             height=1, density=9, invert=False, smooth=False, flip=False): | ||||
|         """ Set text properties by sending them to the printer | ||||
|  | ||||
|         :param align: horizontal position for text, possible values are: | ||||
|  | ||||
|             * 'center' | ||||
|             * 'left' | ||||
|             * 'right' | ||||
|             * CENTER | ||||
|             * LEFT | ||||
|             * RIGHT | ||||
|  | ||||
|             *default*: 'left' | ||||
|             *default*: LEFT | ||||
|  | ||||
|         :param font: font given as an index, a name, or one of the | ||||
|             special values 'a' or 'b', referring to fonts 0 and 1. | ||||
|         :param bold: text in bold, *default*: False | ||||
|         :param underline: underline mode for text, decimal range 0-2,  *default*: 0 | ||||
|         :param double_height: doubles the height of the text | ||||
|         :param double_width: doubles the width of the text | ||||
|         :param custom_size: uses custom size specified by width and height | ||||
|             parameters. Cannot be used with double_width or double_height. | ||||
|         :param width: text width multiplier when custom_size is used, decimal range 1-8,  *default*: 1 | ||||
|         :param height: text height multiplier when custom_size is used, decimal range 1-8, *default*: 1 | ||||
|             special values 'a' or 'b', refering to fonts 0 and 1. | ||||
|         :param text_type: text type, possible values are: | ||||
|  | ||||
|             * B for bold | ||||
|             * U for underlined | ||||
|             * U2 for underlined, version 2 | ||||
|             * BU for bold and underlined | ||||
|             * BU2 for bold and underlined, version 2 | ||||
|             * NORMAL for normal text | ||||
|  | ||||
|             *default*: NORMAL | ||||
|         :param width: text width multiplier, decimal range 1-8,  *default*: 1 | ||||
|         :param height: text height multiplier, decimal range 1-8, *default*: 1 | ||||
|         :param density: print density, value from 0-8, if something else is supplied the density remains unchanged | ||||
|         :param invert: True enables white on black printing, *default*: False | ||||
|         :param smooth: True enables text smoothing. Effective on 4x4 size text and larger, *default*: False | ||||
|         :param flip: True enables upside-down printing, *default*: False | ||||
|  | ||||
|         :type font: str | ||||
|         :type invert: bool | ||||
|         :type bold: bool | ||||
|         :type underline: bool | ||||
|         :type smooth: bool | ||||
|         :type flip: bool | ||||
|         :type custom_size: bool | ||||
|         :type double_width: bool | ||||
|         :type double_height: bool | ||||
|         :type align: str | ||||
|         :type width: int | ||||
|         :type height: int | ||||
|         :type density: int | ||||
|         """ | ||||
|  | ||||
|         if custom_size: | ||||
|             if 1 <= width <= 8 and 1 <= height <= 8 and isinstance(width, int) and\ | ||||
|               isinstance(height, int): | ||||
|                 size_byte = TXT_STYLE['width'][width] + TXT_STYLE['height'][height] | ||||
|                 self._raw(TXT_SIZE + six.int2byte(size_byte)) | ||||
|             else: | ||||
|                 raise SetVariableError() | ||||
|         else: | ||||
|         # Width | ||||
|         if height == 2 and width == 2: | ||||
|             self._raw(TXT_NORMAL) | ||||
|             if double_width and double_height: | ||||
|                 self._raw(TXT_STYLE['size']['2x']) | ||||
|             elif double_width: | ||||
|                 self._raw(TXT_STYLE['size']['2w']) | ||||
|             elif double_height: | ||||
|                 self._raw(TXT_STYLE['size']['2h']) | ||||
|             else: | ||||
|                 self._raw(TXT_STYLE['size']['normal']) | ||||
|  | ||||
|         self._raw(TXT_STYLE['flip'][flip]) | ||||
|         self._raw(TXT_STYLE['smooth'][smooth]) | ||||
|         self._raw(TXT_STYLE['bold'][bold]) | ||||
|         self._raw(TXT_STYLE['underline'][underline]) | ||||
|             self._raw(TXT_4SQUARE) | ||||
|         elif height == 2 and width == 1: | ||||
|             self._raw(TXT_NORMAL) | ||||
|             self._raw(TXT_2HEIGHT) | ||||
|         elif width == 2 and height == 1: | ||||
|             self._raw(TXT_NORMAL) | ||||
|             self._raw(TXT_2WIDTH) | ||||
|         elif width == 1 and height == 1: | ||||
|             self._raw(TXT_NORMAL) | ||||
|         elif 1 <= width <= 8 and 1 <= height <= 8 and isinstance(width, int) and isinstance(height, int): | ||||
|             self._raw(TXT_SIZE + six.int2byte(TXT_WIDTH[width] + TXT_HEIGHT[height])) | ||||
|         else: | ||||
|             raise SetVariableError() | ||||
|         # Upside down | ||||
|         if flip: | ||||
|             self._raw(TXT_FLIP_ON) | ||||
|         else: | ||||
|             self._raw(TXT_FLIP_OFF) | ||||
|         # Smoothing | ||||
|         if smooth: | ||||
|             self._raw(TXT_SMOOTH_ON) | ||||
|         else: | ||||
|             self._raw(TXT_SMOOTH_OFF) | ||||
|         # Type | ||||
|         if text_type.upper() == "B": | ||||
|             self._raw(TXT_BOLD_ON) | ||||
|             self._raw(TXT_UNDERL_OFF) | ||||
|         elif text_type.upper() == "U": | ||||
|             self._raw(TXT_BOLD_OFF) | ||||
|             self._raw(TXT_UNDERL_ON) | ||||
|         elif text_type.upper() == "U2": | ||||
|             self._raw(TXT_BOLD_OFF) | ||||
|             self._raw(TXT_UNDERL2_ON) | ||||
|         elif text_type.upper() == "BU": | ||||
|             self._raw(TXT_BOLD_ON) | ||||
|             self._raw(TXT_UNDERL_ON) | ||||
|         elif text_type.upper() == "BU2": | ||||
|             self._raw(TXT_BOLD_ON) | ||||
|             self._raw(TXT_UNDERL2_ON) | ||||
|         elif text_type.upper() == "NORMAL": | ||||
|             self._raw(TXT_BOLD_OFF) | ||||
|             self._raw(TXT_UNDERL_OFF) | ||||
|         # Font | ||||
|         self._raw(SET_FONT(six.int2byte(self.profile.get_font(font)))) | ||||
|         self._raw(TXT_STYLE['align'][align]) | ||||
|  | ||||
|         if density != 9: | ||||
|             self._raw(TXT_STYLE['density'][density]) | ||||
|  | ||||
|         self._raw(TXT_STYLE['invert'][invert]) | ||||
|         # Align | ||||
|         if align.upper() == "CENTER": | ||||
|             self._raw(TXT_ALIGN_CT) | ||||
|         elif align.upper() == "RIGHT": | ||||
|             self._raw(TXT_ALIGN_RT) | ||||
|         elif align.upper() == "LEFT": | ||||
|             self._raw(TXT_ALIGN_LT) | ||||
|         # Density | ||||
|         if density == 0: | ||||
|             self._raw(PD_N50) | ||||
|         elif density == 1: | ||||
|             self._raw(PD_N37) | ||||
|         elif density == 2: | ||||
|             self._raw(PD_N25) | ||||
|         elif density == 3: | ||||
|             self._raw(PD_N12) | ||||
|         elif density == 4: | ||||
|             self._raw(PD_0) | ||||
|         elif density == 5: | ||||
|             self._raw(PD_P12) | ||||
|         elif density == 6: | ||||
|             self._raw(PD_P25) | ||||
|         elif density == 7: | ||||
|             self._raw(PD_P37) | ||||
|         elif density == 8: | ||||
|             self._raw(PD_P50) | ||||
|         else:  # DEFAULT: DOES NOTHING | ||||
|             pass | ||||
|         # Invert Printing | ||||
|         if invert: | ||||
|             self._raw(TXT_INVERT_ON) | ||||
|         else: | ||||
|             self._raw(TXT_INVERT_OFF) | ||||
|  | ||||
|     def line_spacing(self, spacing=None, divisor=180): | ||||
|         """ Set line character spacing. | ||||
| @@ -574,7 +564,7 @@ class Escpos(object): | ||||
|  | ||||
|         self._raw(LINESPACING_FUNCS[divisor] + six.int2byte(spacing)) | ||||
|  | ||||
|     def cut(self, mode='FULL', feed=True): | ||||
|     def cut(self, mode='FULL'): | ||||
|         """ Cut paper. | ||||
|  | ||||
|         Without any arguments the paper will be cut completely. With 'mode=PART' a partial cut will | ||||
| @@ -584,14 +574,8 @@ class Escpos(object): | ||||
|         .. todo:: Check this function on TM-T88II. | ||||
|  | ||||
|         :param mode: set to 'PART' for a partial cut. default: 'FULL' | ||||
|         :param feed: print and feed before cutting. default: true | ||||
|         :raises ValueError: if mode not in ('FULL', 'PART') | ||||
|         """ | ||||
|  | ||||
|         if not feed: | ||||
|             self._raw(GS + b'V' + six.int2byte(66) + b'\x00') | ||||
|             return | ||||
|  | ||||
|         self.print_and_feed(6) | ||||
|  | ||||
|         mode = mode.upper() | ||||
| @@ -628,41 +612,6 @@ class Escpos(object): | ||||
|             except: | ||||
|                 raise CashDrawerError() | ||||
|  | ||||
|     def linedisplay_select(self, select_display=False): | ||||
|         """ Selects the line display or the printer | ||||
|  | ||||
|         This method is used for line displays that are daisy-chained between your computer and printer. | ||||
|         If you set `select_display` to true, only the display is selected and if you set it to false, | ||||
|         only the printer is selected. | ||||
|  | ||||
|         :param select_display: whether the display should be selected or the printer | ||||
|         :type select_display: bool | ||||
|         """ | ||||
|         if select_display: | ||||
|             self._raw(LINE_DISPLAY_OPEN) | ||||
|         else: | ||||
|             self._raw(LINE_DISPLAY_CLOSE) | ||||
|  | ||||
|     def linedisplay_clear(self): | ||||
|         """ Clears the line display and resets the cursor | ||||
|  | ||||
|         This method is used for line displays that are daisy-chained between your computer and printer. | ||||
|         """ | ||||
|         self._raw(LINE_DISPLAY_CLEAR) | ||||
|  | ||||
|     def linedisplay(self, text): | ||||
|         """ | ||||
|         Display text on a line display connected to your printer | ||||
|  | ||||
|         You should connect a line display to your printer. You can do this by daisy-chaining | ||||
|         the display between your computer and printer. | ||||
|         :param text: Text to display | ||||
|         """ | ||||
|         self.linedisplay_select(select_display=True) | ||||
|         self.linedisplay_clear() | ||||
|         self.text(text) | ||||
|         self.linedisplay_select(select_display=False) | ||||
|  | ||||
|     def hw(self, hw): | ||||
|         """ Hardware operations | ||||
|  | ||||
| @@ -695,7 +644,7 @@ class Escpos(object): | ||||
|         else: | ||||
|             raise ValueError("n must be betwen 0 and 255") | ||||
|  | ||||
|     def control(self, ctl, count=5, tab_size=8): | ||||
|     def control(self, ctl, pos=4): | ||||
|         """ Feed control sequences | ||||
|  | ||||
|         :param ctl: string for the following control sequences: | ||||
| @@ -706,8 +655,7 @@ class Escpos(object): | ||||
|             * HT *for Horizontal Tab* | ||||
|             * VT *for Vertical Tab* | ||||
|  | ||||
|         :param count: integer between 1 and 32, controls the horizontal tab count. Defaults to 5. | ||||
|         :param tab_size: integer between 1 and 255, controls the horizontal tab size in characters. Defaults to 8 | ||||
|         :param pos: integer between 1 and 16, controls the horizontal tab position | ||||
|         :raises: :py:exc:`~escpos.exceptions.TabPosError` | ||||
|         """ | ||||
|         # Set position | ||||
| @@ -718,16 +666,13 @@ class Escpos(object): | ||||
|         elif ctl.upper() == "CR": | ||||
|             self._raw(CTL_CR) | ||||
|         elif ctl.upper() == "HT": | ||||
|             if not (0 <= count <= 32 and | ||||
|                     1 <= tab_size <= 255 and | ||||
|                     count * tab_size < 256): | ||||
|             if not (1 <= pos <= 16): | ||||
|                 raise TabPosError() | ||||
|             else: | ||||
|                 # Set tab positions | ||||
|                 self._raw(CTL_SET_HT) | ||||
|                 for iterator in range(1, count): | ||||
|                     self._raw(six.int2byte(iterator * tab_size)) | ||||
|                 self._raw(NUL) | ||||
|                 self._raw(CTL_SET_HT + six.int2byte(pos)) | ||||
|  | ||||
|             self._raw(CTL_HT) | ||||
|         elif ctl.upper() == "VT": | ||||
|             self._raw(CTL_VT) | ||||
|  | ||||
| @@ -754,20 +699,6 @@ class Escpos(object): | ||||
|         else: | ||||
|             self._raw(PANEL_BUTTON_OFF) | ||||
|  | ||||
|     def query_status(self): | ||||
|         """ Queries the printer for its status, and returns an array of integers containing it. | ||||
|         :rtype: array(integer)""" | ||||
|         self._raw(RT_STATUS_ONLINE) | ||||
|         time.sleep(1) | ||||
|         status = self._read() | ||||
|         return status or [RT_MASK_ONLINE] | ||||
|  | ||||
|     def is_online(self): | ||||
|         """ Queries the printer its online status. | ||||
|         When online, returns True; False otherwise. | ||||
|         :rtype: bool: True if online, False if offline.""" | ||||
|         return not (self.query_status()[0] & RT_MASK_ONLINE) | ||||
|  | ||||
|  | ||||
| class EscposIO(object): | ||||
|     """ESC/POS Printer IO object | ||||
|   | ||||
| @@ -8,7 +8,6 @@ Result/Exit codes: | ||||
|     - `20` = Barcode size values are out of range :py:exc:`~escpos.exceptions.BarcodeSizeError` | ||||
|     - `30` = Barcode text not supplied :py:exc:`~escpos.exceptions.BarcodeCodeError` | ||||
|     - `40` = Image height is too large :py:exc:`~escpos.exceptions.ImageSizeError` | ||||
|     - `41` = Image width is too large :py:exc:`~escpos.exceptions.ImageWidthError` | ||||
|     - `50` = No string supplied to be printed :py:exc:`~escpos.exceptions.TextError` | ||||
|     - `60` = Invalid pin to send Cash Drawer pulse :py:exc:`~escpos.exceptions.CashDrawerError` | ||||
|     - `70` = Invalid number of tab positions :py:exc:`~escpos.exceptions.TabPosError` | ||||
| @@ -105,20 +104,6 @@ class ImageSizeError(Error): | ||||
|         return "Image height is longer than 255px and can't be printed ({msg})".format(msg=self.msg) | ||||
|  | ||||
|  | ||||
| class ImageWidthError(Error): | ||||
|     """ Image width is too large. | ||||
|  | ||||
|     The return code for this exception is `41`. | ||||
|     """ | ||||
|     def __init__(self, msg=""): | ||||
|         Error.__init__(self, msg) | ||||
|         self.msg = msg | ||||
|         self.resultcode = 41 | ||||
|  | ||||
|     def __str__(self): | ||||
|         return "Image width is too large ({msg})".format(msg=self.msg) | ||||
|  | ||||
|  | ||||
| class TextError(Error): | ||||
|     """ Text string must be supplied to the `text()` method. | ||||
|  | ||||
| @@ -150,8 +135,7 @@ class CashDrawerError(Error): | ||||
|  | ||||
|  | ||||
| class TabPosError(Error): | ||||
|     """ Valid tab positions must be set by using from 1 to 32 tabs, and between 1 and 255 tab size values. | ||||
|     Both values multiplied must not exceed 255, since it is the maximum tab value. | ||||
|     """ Valid tab positions must be in the range 0 to 16. | ||||
|  | ||||
|     This exception is raised by :py:meth:`escpos.escpos.Escpos.control`. | ||||
|     The returncode for this exception is `70`. | ||||
|   | ||||
| @@ -84,10 +84,6 @@ class Usb(Escpos): | ||||
|         """ | ||||
|         self.device.write(self.out_ep, msg, self.timeout) | ||||
|  | ||||
|     def _read(self): | ||||
|         """ Reads a data buffer and returns it to the caller. """ | ||||
|         return self.device.read(self.in_ep, 16) | ||||
|  | ||||
|     def close(self): | ||||
|         """ Release USB interface """ | ||||
|         if self.device: | ||||
| @@ -135,8 +131,6 @@ class Serial(Escpos): | ||||
|  | ||||
|     def open(self): | ||||
|         """ Setup serial port and set is as escpos device """ | ||||
|         if self.device is not None and self.device.is_open: | ||||
|             self.close() | ||||
|         self.device = serial.Serial(port=self.devfile, baudrate=self.baudrate, | ||||
|                                     bytesize=self.bytesize, parity=self.parity, | ||||
|                                     stopbits=self.stopbits, timeout=self.timeout, | ||||
| @@ -157,7 +151,7 @@ class Serial(Escpos): | ||||
|  | ||||
|     def close(self): | ||||
|         """ Close Serial interface """ | ||||
|         if self.device is not None and self.device.is_open: | ||||
|         if self.device is not None: | ||||
|             self.device.flush() | ||||
|             self.device.close() | ||||
|  | ||||
|   | ||||
| @@ -1,17 +0,0 @@ | ||||
| from __future__ import absolute_import | ||||
| from __future__ import division | ||||
| from __future__ import print_function | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| import six | ||||
|  | ||||
| import escpos.printer as printer | ||||
| from escpos.constants import GS | ||||
|  | ||||
|  | ||||
| def test_cut_without_feed(): | ||||
|     """Test cut without feeding paper""" | ||||
|     instance = printer.Dummy() | ||||
|     instance.cut(feed=False) | ||||
|     expected = GS + b'V' + six.int2byte(66) + b'\x00' | ||||
|     assert(instance.output == expected) | ||||
| @@ -12,12 +12,8 @@ from __future__ import division | ||||
| from __future__ import print_function | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| import pytest | ||||
|  | ||||
| from PIL import Image | ||||
|  | ||||
| import escpos.printer as printer | ||||
| from escpos.exceptions import ImageWidthError | ||||
| from PIL import Image | ||||
|  | ||||
|  | ||||
| # Raster format print | ||||
| @@ -143,22 +139,3 @@ def test_large_graphics(): | ||||
|     instance = printer.Dummy() | ||||
|     instance.image('test/resources/black_white.png', impl="bitImageRaster", fragment_height=1) | ||||
|     assert(instance.output == b'\x1dv0\x00\x01\x00\x01\x00\xc0\x1dv0\x00\x01\x00\x01\x00\x00') | ||||
|  | ||||
|  | ||||
| def test_width_too_large(): | ||||
|     """ | ||||
|     Test printing an image that is too large in width. | ||||
|     """ | ||||
|     instance = printer.Dummy() | ||||
|     instance.profile.profile_data = { | ||||
|         'media': { | ||||
|             'width': { | ||||
|                 'pixels': 384 | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     with pytest.raises(ImageWidthError): | ||||
|         instance.image(Image.new("RGB", (385, 200))) | ||||
|  | ||||
|     instance.image(Image.new("RGB", (384, 200))) | ||||
| @@ -1,35 +0,0 @@ | ||||
| #!/usr/bin/python | ||||
| """tests for line display | ||||
|  | ||||
| :author: `Patrick Kanzler <patrick.kanzler@fablab.fau.de>`_ | ||||
| :organization: `python-escpos <https://github.com/python-escpos>`_ | ||||
| :copyright: Copyright (c) 2017 `python-escpos <https://github.com/python-escpos>`_ | ||||
| :license: MIT | ||||
| """ | ||||
|  | ||||
| from __future__ import absolute_import | ||||
| from __future__ import division | ||||
| from __future__ import print_function | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| import escpos.printer as printer | ||||
|  | ||||
|  | ||||
| def test_function_linedisplay_select_on(): | ||||
|     """test the linedisplay_select function (activate)""" | ||||
|     instance = printer.Dummy() | ||||
|     instance.linedisplay_select(select_display=True) | ||||
|     assert(instance.output == b'\x1B\x3D\x02') | ||||
|  | ||||
| def test_function_linedisplay_select_off(): | ||||
|     """test the linedisplay_select function (deactivate)""" | ||||
|     instance = printer.Dummy() | ||||
|     instance.linedisplay_select(select_display=False) | ||||
|     assert(instance.output == b'\x1B\x3D\x01') | ||||
|  | ||||
| def test_function_linedisplay_clear(): | ||||
|     """test the linedisplay_clear function""" | ||||
|     instance = printer.Dummy() | ||||
|     instance.linedisplay_clear() | ||||
|     assert(instance.output == b'\x1B\x40') | ||||
|  | ||||
| @@ -12,18 +12,43 @@ from __future__ import division | ||||
| from __future__ import print_function | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| from nose.tools import with_setup | ||||
|  | ||||
| import escpos.printer as printer | ||||
| import os | ||||
|  | ||||
| devfile = 'testfile' | ||||
|  | ||||
|  | ||||
| def setup_testfile(): | ||||
|     """create a testfile as devfile""" | ||||
|     fhandle = open(devfile, 'a') | ||||
|     try: | ||||
|         os.utime(devfile, None) | ||||
|     finally: | ||||
|         fhandle.close() | ||||
|  | ||||
|  | ||||
| def teardown_testfile(): | ||||
|     """destroy testfile again""" | ||||
|     os.remove(devfile) | ||||
|  | ||||
|  | ||||
| @with_setup(setup_testfile, teardown_testfile) | ||||
| def test_function_panel_button_on(): | ||||
|     """test the panel button function (enabling) by comparing output""" | ||||
|     instance = printer.Dummy() | ||||
|     instance = printer.File(devfile=devfile) | ||||
|     instance.panel_buttons() | ||||
|     assert(instance.output == b'\x1B\x63\x35\x00') | ||||
|     instance.flush() | ||||
|     with open(devfile, "rb") as f: | ||||
|         assert(f.read() == b'\x1B\x63\x35\x00') | ||||
|  | ||||
|  | ||||
| @with_setup(setup_testfile, teardown_testfile) | ||||
| def test_function_panel_button_off(): | ||||
|     """test the panel button function (disabling) by comparing output""" | ||||
|     instance = printer.Dummy() | ||||
|     instance = printer.File(devfile=devfile) | ||||
|     instance.panel_buttons(False) | ||||
|     assert(instance.output == b'\x1B\x63\x35\x01') | ||||
|     instance.flush() | ||||
|     with open(devfile, "rb") as f: | ||||
|         assert(f.read() == b'\x1B\x63\x35\x01') | ||||
|   | ||||
| @@ -86,11 +86,9 @@ def test_image(): | ||||
|     instance = printer.Dummy() | ||||
|     instance.qr("1", native=False, size=1) | ||||
|     print(instance.output) | ||||
|     expected = b'\x1bt\x00\n' \ | ||||
|         b'\x1dv0\x00\x03\x00\x17\x00\x00\x00\x00\x7f]\xfcA\x19\x04]it]et' \ | ||||
|     expected = b'\x1dv0\x00\x03\x00\x17\x00\x00\x00\x00\x7f]\xfcA\x19\x04]it]et' \ | ||||
|         b']ItA=\x04\x7fU\xfc\x00\x0c\x00y~t4\x7f =\xa84j\xd9\xf0\x05\xd4\x90\x00' \ | ||||
|         b'i(\x7f<\xa8A \xd8]\'\xc4]y\xf8]E\x80Ar\x94\x7fR@\x00\x00\x00' \ | ||||
|         b'\n\n' | ||||
|         b'i(\x7f<\xa8A \xd8]\'\xc4]y\xf8]E\x80Ar\x94\x7fR@\x00\x00\x00' | ||||
|     assert(instance.output == expected) | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,280 +0,0 @@ | ||||
| from __future__ import absolute_import | ||||
| from __future__ import division | ||||
| from __future__ import print_function | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| import six | ||||
|  | ||||
| import escpos.printer as printer | ||||
| from escpos.constants import TXT_NORMAL, TXT_STYLE, SET_FONT | ||||
| from escpos.constants import TXT_SIZE | ||||
|  | ||||
|  | ||||
| # Default test, please copy and paste this block to test set method calls | ||||
|  | ||||
| def test_default_values(): | ||||
|     instance = printer.Dummy() | ||||
|     instance.set() | ||||
|  | ||||
|     expected_sequence = ( | ||||
|         TXT_NORMAL, TXT_STYLE['size']['normal'],  # Normal text size | ||||
|         TXT_STYLE['flip'][False],  # Flip OFF | ||||
|         TXT_STYLE['smooth'][False],  # Smooth OFF | ||||
|         TXT_STYLE['bold'][False],  # Bold OFF | ||||
|         TXT_STYLE['underline'][0],  # Underline OFF | ||||
|         SET_FONT(b'\x00'),  # Default font | ||||
|         TXT_STYLE['align']['left'],  # Align left | ||||
|         TXT_STYLE['invert'][False]  # Inverted OFF | ||||
|     ) | ||||
|  | ||||
|     assert(instance.output == b''.join(expected_sequence)) | ||||
|  | ||||
| # Size tests | ||||
|  | ||||
| def test_set_size_2h(): | ||||
|     instance = printer.Dummy() | ||||
|     instance.set(double_height=True) | ||||
|  | ||||
|     expected_sequence = ( | ||||
|         TXT_NORMAL, TXT_STYLE['size']['2h'],  # Double height text size | ||||
|         TXT_STYLE['flip'][False],  # Flip OFF | ||||
|         TXT_STYLE['smooth'][False],  # Smooth OFF | ||||
|         TXT_STYLE['bold'][False],  # Bold OFF | ||||
|         TXT_STYLE['underline'][0],  # Underline OFF | ||||
|         SET_FONT(b'\x00'),  # Default font | ||||
|         TXT_STYLE['align']['left'],  # Align left | ||||
|         TXT_STYLE['invert'][False]  # Inverted OFF | ||||
|     ) | ||||
|  | ||||
|     assert (instance.output == b''.join(expected_sequence)) | ||||
|  | ||||
|  | ||||
| def test_set_size_2w(): | ||||
|     instance = printer.Dummy() | ||||
|     instance.set(double_width=True) | ||||
|  | ||||
|     expected_sequence = ( | ||||
|         TXT_NORMAL, TXT_STYLE['size']['2w'],  # Double width text size | ||||
|         TXT_STYLE['flip'][False],  # Flip OFF | ||||
|         TXT_STYLE['smooth'][False],  # Smooth OFF | ||||
|         TXT_STYLE['bold'][False],  # Bold OFF | ||||
|         TXT_STYLE['underline'][0],  # Underline OFF | ||||
|         SET_FONT(b'\x00'),  # Default font | ||||
|         TXT_STYLE['align']['left'],  # Align left | ||||
|         TXT_STYLE['invert'][False]  # Inverted OFF | ||||
|     ) | ||||
|  | ||||
|     assert (instance.output == b''.join(expected_sequence)) | ||||
|  | ||||
|  | ||||
| def test_set_size_2x(): | ||||
|     instance = printer.Dummy() | ||||
|     instance.set(double_height=True, double_width=True) | ||||
|  | ||||
|     expected_sequence = ( | ||||
|         TXT_NORMAL, TXT_STYLE['size']['2x'],  # Double text size | ||||
|         TXT_STYLE['flip'][False],  # Flip OFF | ||||
|         TXT_STYLE['smooth'][False],  # Smooth OFF | ||||
|         TXT_STYLE['bold'][False],  # Bold OFF | ||||
|         TXT_STYLE['underline'][0],  # Underline OFF | ||||
|         SET_FONT(b'\x00'),  # Default font | ||||
|         TXT_STYLE['align']['left'],  # Align left | ||||
|         TXT_STYLE['invert'][False]  # Inverted OFF | ||||
|     ) | ||||
|  | ||||
|     assert (instance.output == b''.join(expected_sequence)) | ||||
|  | ||||
|  | ||||
| def test_set_size_custom(): | ||||
|     instance = printer.Dummy() | ||||
|     instance.set(custom_size=True, width=8, height=7) | ||||
|  | ||||
|     expected_sequence = ( | ||||
|         TXT_SIZE,  # Custom text size, no normal reset | ||||
|         six.int2byte(TXT_STYLE['width'][8] + TXT_STYLE['height'][7]), | ||||
|         TXT_STYLE['flip'][False],  # Flip OFF | ||||
|         TXT_STYLE['smooth'][False],  # Smooth OFF | ||||
|         TXT_STYLE['bold'][False],  # Bold OFF | ||||
|         TXT_STYLE['underline'][0],  # Underline OFF | ||||
|         SET_FONT(b'\x00'),  # Default font | ||||
|         TXT_STYLE['align']['left'],  # Align left | ||||
|         TXT_STYLE['invert'][False]  # Inverted OFF | ||||
|     ) | ||||
|  | ||||
|     assert (instance.output == b''.join(expected_sequence)) | ||||
|  | ||||
| # Flip | ||||
|  | ||||
| def test_set_flip(): | ||||
|     instance = printer.Dummy() | ||||
|     instance.set(flip=True) | ||||
|  | ||||
|     expected_sequence = ( | ||||
|         TXT_NORMAL, TXT_STYLE['size']['normal'],  # Normal text size | ||||
|         TXT_STYLE['flip'][True],  # Flip ON | ||||
|         TXT_STYLE['smooth'][False],  # Smooth OFF | ||||
|         TXT_STYLE['bold'][False],  # Bold OFF | ||||
|         TXT_STYLE['underline'][0],  # Underline OFF | ||||
|         SET_FONT(b'\x00'),  # Default font | ||||
|         TXT_STYLE['align']['left'],  # Align left | ||||
|         TXT_STYLE['invert'][False]  # Inverted OFF | ||||
|     ) | ||||
|  | ||||
|     assert (instance.output == b''.join(expected_sequence)) | ||||
|  | ||||
| # Smooth | ||||
|  | ||||
| def test_smooth(): | ||||
|     instance = printer.Dummy() | ||||
|     instance.set(smooth=True) | ||||
|  | ||||
|     expected_sequence = ( | ||||
|         TXT_NORMAL, TXT_STYLE['size']['normal'],  # Normal text size | ||||
|         TXT_STYLE['flip'][False],  # Flip OFF | ||||
|         TXT_STYLE['smooth'][True],  # Smooth ON | ||||
|         TXT_STYLE['bold'][False],  # Bold OFF | ||||
|         TXT_STYLE['underline'][0],  # Underline OFF | ||||
|         SET_FONT(b'\x00'),  # Default font | ||||
|         TXT_STYLE['align']['left'],  # Align left | ||||
|         TXT_STYLE['invert'][False]  # Inverted OFF | ||||
|     ) | ||||
|  | ||||
|     assert(instance.output == b''.join(expected_sequence)) | ||||
|  | ||||
|  | ||||
| # Type | ||||
|  | ||||
|  | ||||
| def test_set_bold(): | ||||
|     instance = printer.Dummy() | ||||
|     instance.set(bold=True) | ||||
|  | ||||
|     expected_sequence = ( | ||||
|         TXT_NORMAL, TXT_STYLE['size']['normal'],  # Normal text size | ||||
|         TXT_STYLE['flip'][False],  # Flip OFF | ||||
|         TXT_STYLE['smooth'][False],  # Smooth OFF | ||||
|         TXT_STYLE['bold'][True],  # Bold ON | ||||
|         TXT_STYLE['underline'][0],  # Underline OFF | ||||
|         SET_FONT(b'\x00'),  # Default font | ||||
|         TXT_STYLE['align']['left'],  # Align left | ||||
|         TXT_STYLE['invert'][False]  # Inverted OFF | ||||
|     ) | ||||
|  | ||||
|     assert (instance.output == b''.join(expected_sequence)) | ||||
|  | ||||
|  | ||||
| def test_set_underline(): | ||||
|     instance = printer.Dummy() | ||||
|     instance.set(underline=1) | ||||
|  | ||||
|     expected_sequence = ( | ||||
|         TXT_NORMAL, TXT_STYLE['size']['normal'],  # Normal text size | ||||
|         TXT_STYLE['flip'][False],  # Flip OFF | ||||
|         TXT_STYLE['smooth'][False],  # Smooth OFF | ||||
|         TXT_STYLE['bold'][False],  # Bold OFF | ||||
|         TXT_STYLE['underline'][1],  # Underline ON, type 1 | ||||
|         SET_FONT(b'\x00'),  # Default font | ||||
|         TXT_STYLE['align']['left'],  # Align left | ||||
|         TXT_STYLE['invert'][False]  # Inverted OFF | ||||
|     ) | ||||
|  | ||||
|     assert (instance.output == b''.join(expected_sequence)) | ||||
|  | ||||
|  | ||||
| def test_set_underline2(): | ||||
|     instance = printer.Dummy() | ||||
|     instance.set(underline=2) | ||||
|  | ||||
|     expected_sequence = ( | ||||
|         TXT_NORMAL, TXT_STYLE['size']['normal'],  # Normal text size | ||||
|         TXT_STYLE['flip'][False],  # Flip OFF | ||||
|         TXT_STYLE['smooth'][False],  # Smooth OFF | ||||
|         TXT_STYLE['bold'][False],  # Bold OFF | ||||
|         TXT_STYLE['underline'][2],  # Underline ON, type 2 | ||||
|         SET_FONT(b'\x00'),  # Default font | ||||
|         TXT_STYLE['align']['left'],  # Align left | ||||
|         TXT_STYLE['invert'][False]  # Inverted OFF | ||||
|     ) | ||||
|  | ||||
|     assert (instance.output == b''.join(expected_sequence)) | ||||
|  | ||||
|  | ||||
| # Align | ||||
|  | ||||
| def test_align_center(): | ||||
|     instance = printer.Dummy() | ||||
|     instance.set(align='center') | ||||
|  | ||||
|     expected_sequence = ( | ||||
|         TXT_NORMAL, TXT_STYLE['size']['normal'],  # Normal text size | ||||
|         TXT_STYLE['flip'][False],  # Flip OFF | ||||
|         TXT_STYLE['smooth'][False],  # Smooth OFF | ||||
|         TXT_STYLE['bold'][False],  # Bold OFF | ||||
|         TXT_STYLE['underline'][0],  # Underline OFF | ||||
|         SET_FONT(b'\x00'),  # Default font | ||||
|         TXT_STYLE['align']['center'],  # Align center | ||||
|         TXT_STYLE['invert'][False]  # Inverted OFF | ||||
|     ) | ||||
|  | ||||
|     assert(instance.output == b''.join(expected_sequence)) | ||||
|  | ||||
|  | ||||
| def test_align_right(): | ||||
|     instance = printer.Dummy() | ||||
|     instance.set(align='right') | ||||
|  | ||||
|     expected_sequence = ( | ||||
|         TXT_NORMAL, TXT_STYLE['size']['normal'],  # Normal text size | ||||
|         TXT_STYLE['flip'][False],  # Flip OFF | ||||
|         TXT_STYLE['smooth'][False],  # Smooth OFF | ||||
|         TXT_STYLE['bold'][False],  # Bold OFF | ||||
|         TXT_STYLE['underline'][0],  # Underline OFF | ||||
|         SET_FONT(b'\x00'),  # Default font | ||||
|         TXT_STYLE['align']['right'],  # Align right | ||||
|         TXT_STYLE['invert'][False]  # Inverted OFF | ||||
|     ) | ||||
|  | ||||
|     assert(instance.output == b''.join(expected_sequence)) | ||||
|  | ||||
|  | ||||
| # Densities | ||||
|  | ||||
| def test_densities(): | ||||
|  | ||||
|     for density in range(8): | ||||
|         instance = printer.Dummy() | ||||
|         instance.set(density=density) | ||||
|  | ||||
|         expected_sequence = ( | ||||
|             TXT_NORMAL, TXT_STYLE['size']['normal'],  # Normal text size | ||||
|             TXT_STYLE['flip'][False],  # Flip OFF | ||||
|             TXT_STYLE['smooth'][False],  # Smooth OFF | ||||
|             TXT_STYLE['bold'][False],  # Bold OFF | ||||
|             TXT_STYLE['underline'][0],  # Underline OFF | ||||
|             SET_FONT(b'\x00'),  # Default font | ||||
|             TXT_STYLE['align']['left'],  # Align left | ||||
|             TXT_STYLE['density'][density],  # Custom density from 0 to 8 | ||||
|             TXT_STYLE['invert'][False]  # Inverted OFF | ||||
|         ) | ||||
|  | ||||
|         assert(instance.output == b''.join(expected_sequence)) | ||||
|  | ||||
|  | ||||
| # Invert | ||||
|  | ||||
| def test_invert(): | ||||
|     instance = printer.Dummy() | ||||
|     instance.set(invert=True) | ||||
|  | ||||
|     expected_sequence = ( | ||||
|         TXT_NORMAL, TXT_STYLE['size']['normal'],  # Normal text size | ||||
|         TXT_STYLE['flip'][False],  # Flip OFF | ||||
|         TXT_STYLE['smooth'][False],  # Smooth OFF | ||||
|         TXT_STYLE['bold'][False],  # Bold OFF | ||||
|         TXT_STYLE['underline'][0],  # Underline OFF | ||||
|         SET_FONT(b'\x00'),  # Default font | ||||
|         TXT_STYLE['align']['left'],  # Align left | ||||
|         TXT_STYLE['invert'][True]  # Inverted ON | ||||
|     ) | ||||
|  | ||||
|     assert(instance.output == b''.join(expected_sequence)) | ||||
| @@ -12,10 +12,30 @@ from __future__ import division | ||||
| from __future__ import print_function | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| from nose.tools import with_setup | ||||
|  | ||||
| import escpos.printer as printer | ||||
| import os | ||||
|  | ||||
| devfile = 'testfile' | ||||
|  | ||||
|  | ||||
| def setup_testfile(): | ||||
|     """create a testfile as devfile""" | ||||
|     fhandle = open(devfile, 'a') | ||||
|     try: | ||||
|         os.utime(devfile, None) | ||||
|     finally: | ||||
|         fhandle.close() | ||||
|  | ||||
|  | ||||
| def teardown_testfile(): | ||||
|     """destroy testfile again""" | ||||
|     os.remove(devfile) | ||||
|  | ||||
|  | ||||
| @with_setup(setup_testfile, teardown_testfile) | ||||
| def test_instantiation(): | ||||
|     """test the instantiation of a escpos-printer class and basic printing""" | ||||
|     instance = printer.Dummy() | ||||
|     instance = printer.File(devfile=devfile) | ||||
|     instance.text('This is a test\n') | ||||
|   | ||||
		Reference in New Issue
	
	Block a user