1
0
mirror of https://github.com/python-escpos/python-escpos synced 2025-09-13 09:09:58 +00:00

1 Commits

Author SHA1 Message Date
Patrick Kanzler
7014572ed8 add appveyor configuration 2017-07-27 16:40:38 +02:00
26 changed files with 456 additions and 270 deletions

View File

@@ -15,7 +15,6 @@ ldos
Manuel F Martinez Manuel F Martinez
Michael Billington Michael Billington
Michael Elsdörfer Michael Elsdörfer
mrwunderbar666
Nathan Bookham Nathan Bookham
Patrick Kanzler Patrick Kanzler
Qian Linfeng Qian Linfeng

View File

@@ -2,37 +2,6 @@
Changelog Changelog
********* *********
2017-08-04 - Version 3.0a2 - "It's My Party And I'll Sing If I Want To"
-----------------------------------------------------------------------
This release is the third alpha release of the new version 3.0. Please
be aware that the API will still change until v3.0 is released.
changes
^^^^^^^
- refactor of the set-method
- preliminary support of POS "line display" printing
- improvement of tests
- added ImageWidthError
- list authors in repository
- add support for software-based barcode-rendering
- fix SerialException when trying to close device on __del__
- added the DLE EOT querying command for USB and Serial
- ensure QR codes have a large enough border
- make feed for cut optional
- fix the behavior of horizontal tabs
- added test script for hard an soft barcodes
- implemented paper sensor querying command
- added weather forecast example script
- added a method for simpler newlines
contributors
^^^^^^^^^^^^
- csoft2k
- Patrick Kanzler
- mrwunderbar666
- Romain Porte
- Ahmed Tahri
2017-03-29 - Version 3.0a1 - "Headcrash" 2017-03-29 - Version 3.0a1 - "Headcrash"
---------------------------------------- ----------------------------------------
This release is the second alpha release of the new version 3.0. Please This release is the second alpha release of the new version 3.0. Please

View File

@@ -6,6 +6,10 @@ python-escpos - Python library to manipulate ESC/POS Printers
:target: https://travis-ci.org/python-escpos/python-escpos :target: https://travis-ci.org/python-escpos/python-escpos
:alt: Continous Integration :alt: Continous Integration
.. image:: https://www.quantifiedcode.com/api/v1/project/95748b89a3974700800b85e4ed3d32c4/badge.svg
:target: https://www.quantifiedcode.com/app/project/95748b89a3974700800b85e4ed3d32c4
:alt: Code issues
.. image:: https://landscape.io/github/python-escpos/python-escpos/master/landscape.svg?style=flat .. image:: https://landscape.io/github/python-escpos/python-escpos/master/landscape.svg?style=flat
:target: https://landscape.io/github/python-escpos/python-escpos/master :target: https://landscape.io/github/python-escpos/python-escpos/master
:alt: Code Health :alt: Code Health

125
appveyor.yml Normal file
View File

@@ -0,0 +1,125 @@
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\*

229
appveyor/install.ps1 Normal file
View File

@@ -0,0 +1,229 @@
# 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

88
appveyor/run_with_env.cmd Normal file
View File

@@ -0,0 +1,88 @@
:: 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
)

View File

@@ -5,4 +5,3 @@ pyserial
sphinx-rtd-theme sphinx-rtd-theme
setuptools-scm setuptools-scm
docutils>=0.12 docutils>=0.12
viivakoodi

View File

@@ -1,11 +0,0 @@
from escpos.printer import Usb
# Adapt to your needs
p = Usb(0x0416, 0x5011, profile="POS-5890")
# Print software and then hardware barcode with the same content
p.soft_barcode('code39', '123456')
p.text('\n')
p.text('\n')
p.barcode('123456', 'CODE39')

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

View File

@@ -1,10 +0,0 @@
# Climacons by Adam Whitcroft
75 climatically categorised pictographs for web and UI design by [@adamwhitcroft](http://www.twitter.com/#!/adamwhitcroft).
Visit the [Climacons](http://adamwhitcroft.com/climacons/) website for more information.
Visit [Adam Whitcroft on GitHub](https://github.com/AdamWhitcroft)
## License
You are free to use any of the Climacons Icons (the "icons") in any personal or commercial work without obligation of payment (monetary or otherwise) or attribution, however a credit for the work would be appreciated. **Do not** redistribute or sell and **do not** claim creative credit. Intellectual property rights are not transferred with the download of the icons.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -1,127 +0,0 @@
#!/usr/bin/python
# Adapted script from Adafruit
# Weather forecast for Raspberry Pi w/Adafruit Mini Thermal Printer.
# Retrieves data from DarkSky.net's API, prints current conditions and
# forecasts for next two days.
# Weather example using nice bitmaps.
# Written by Adafruit Industries. MIT license.
# Adapted and enhanced for escpos library by MrWunderbar666
# Icons taken from http://adamwhitcroft.com/climacons/
# Check out his github: https://github.com/AdamWhitcroft/climacons
from __future__ import print_function
from datetime import datetime
import calendar
import urllib
import json
import time
import os
from escpos.printer import Usb
""" Setting up the main pathing """
this_dir, this_filename = os.path.split(__file__)
GRAPHICS_PATH = os.path.join(this_dir, "graphics/climacons/")
# Adapt to your needs
printer = Usb(0x0416, 0x5011, profile="POS-5890")
# You can get your API Key on www.darksky.net and register a dev account.
# Technically you can use any other weather service, of course :)
API_KEY = "YOUR API KEY"
LAT = "22.345490" # Your Location
LONG = "114.189945" # Your Location
def forecast_icon(idx):
icon = data['daily']['data'][idx]['icon']
image = GRAPHICS_PATH + icon + ".png"
return image
# Dumps one forecast line to the printer
def forecast(idx):
date = datetime.fromtimestamp(int(data['daily']['data'][idx]['time']))
day = calendar.day_name[date.weekday()]
lo = data['daily']['data'][idx]['temperatureMin']
hi = data['daily']['data'][idx]['temperatureMax']
cond = data['daily']['data'][idx]['summary']
print(date)
print(day)
print(lo)
print(hi)
print(cond)
time.sleep(1)
printer.set(
font='a',
height=2,
align='left',
bold=False,
double_height=False)
printer.text(day + ' \n ')
time.sleep(5) # Sleep to prevent printer buffer overflow
printer.text('\n')
printer.image(forecast_icon(idx))
printer.text('low ' + str(lo))
printer.text(deg)
printer.text('\n')
printer.text(' high ' + str(hi))
printer.text(deg)
printer.text('\n')
# take care of pesky unicode dash
printer.text(cond.replace(u'\u2013', '-').encode('utf-8'))
printer.text('\n \n')
def icon():
icon = data['currently']['icon']
image = GRAPHICS_PATH + icon + ".png"
return image
deg = ' C' # Degree symbol on thermal printer, need to find a better way to use a proper degree symbol
# if you want Fahrenheit change units= to 'us'
url = "https://api.darksky.net/forecast/" + API_KEY + "/" + LAT + "," + LONG + \
"?exclude=[alerts,minutely,hourly,flags]&units=si" # change last bit to 'us' for Fahrenheit
response = urllib.urlopen(url)
data = json.loads(response.read())
printer.print_and_feed(n=1)
printer.control("LF")
printer.set(font='a', height=2, align='center', bold=True, double_height=True)
printer.text("Weather Forecast")
printer.text("\n")
printer.set(align='center')
# Print current conditions
printer.set(font='a', height=2, align='center', bold=True, double_height=False)
printer.text('Current conditions: \n')
printer.image(icon())
printer.text("\n")
printer.set(font='a', height=2, align='left', bold=False, double_height=False)
temp = data['currently']['temperature']
cond = data['currently']['summary']
printer.text(temp)
printer.text(' ')
printer.text(deg)
printer.text(' ')
printer.text('\n')
printer.text('Sky: ' + cond)
printer.text('\n')
printer.text('\n')
# Print forecast
printer.set(font='a', height=2, align='center', bold=True, double_height=False)
printer.text('Forecast: \n')
forecast(0)
forecast(1)
printer.cut
printer.control("LF")

View File

@@ -126,7 +126,7 @@ setup(
tests_require=[ tests_require=[
'jaconv', 'jaconv',
'tox', 'tox',
'pytest!=3.2.0', 'pytest',
'pytest-cov', 'pytest-cov',
'pytest-mock', 'pytest-mock',
'nose', 'nose',

View File

@@ -251,10 +251,5 @@ 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 S_RASTER_Q = _PRINT_RASTER_IMG(b'\x03') # Set raster image quadruple
# Status Command # Status Command
RT_STATUS = DLE + EOT RT_STATUS_ONLINE = DLE + EOT + b'\x01';
RT_STATUS_ONLINE = RT_STATUS + b'\x01' RT_MASK_ONLINE = 8;
RT_STATUS_PAPER = RT_STATUS + b'\x04'
RT_MASK_ONLINE = 8
RT_MASK_PAPER = 18
RT_MASK_LOWPAPER = 30
RT_MASK_NOPAPER = 114

View File

@@ -36,7 +36,6 @@ 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 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 TXT_STYLE
from .constants import RT_STATUS_ONLINE, RT_MASK_ONLINE from .constants import RT_STATUS_ONLINE, RT_MASK_ONLINE
from .constants import RT_STATUS_PAPER, RT_MASK_PAPER, RT_MASK_LOWPAPER, RT_MASK_NOPAPER
from .exceptions import BarcodeTypeError, BarcodeSizeError, TabPosError from .exceptions import BarcodeTypeError, BarcodeSizeError, TabPosError
from .exceptions import CashDrawerError, SetVariableError, BarcodeCodeError from .exceptions import CashDrawerError, SetVariableError, BarcodeCodeError
@@ -251,9 +250,9 @@ class Escpos(object):
""" """
max_input = (256 << (out_bytes * 8) - 1) max_input = (256 << (out_bytes * 8) - 1)
if not 1 <= out_bytes <= 4: if not 1 <= out_bytes <= 4:
raise ValueError("Can only output 1-4 bytes") raise ValueError("Can only output 1-4 byes")
if not 0 <= inp_number <= max_input: if not 0 <= inp_number <= max_input:
raise ValueError("Number too large. Can only output up to {0} in {1} bytes".format(max_input, out_bytes)) raise ValueError("Number too large. Can only output up to {0} in {1} byes".format(max_input, out_bytes))
outp = b'' outp = b''
for _ in range(0, out_bytes): for _ in range(0, out_bytes):
outp += six.int2byte(inp_number % 256) outp += six.int2byte(inp_number % 256)
@@ -460,28 +459,6 @@ class Escpos(object):
txt = six.text_type(txt) txt = six.text_type(txt)
self.magic.write(txt) self.magic.write(txt)
def textln(self, txt=''):
"""Print alpha-numeric text with a newline
The text has to be encoded in the currently selected codepage.
The input text has to be encoded in unicode.
:param txt: text to be printed with a newline
:raises: :py:exc:`~escpos.exceptions.TextError`
"""
self.text('{}\n'.format(txt))
def ln(self, count=1):
"""Print a newline or more
:param count: number of newlines to print
:raises: :py:exc:`ValueError` if count < 0
"""
if count < 0:
raise ValueError('Count cannot be lesser than 0')
if count > 0:
self.text('\n' * count)
def block_text(self, txt, font=None, columns=None): def block_text(self, txt, font=None, columns=None):
""" Text is printed wrapped to specified columns """ Text is printed wrapped to specified columns
@@ -777,40 +754,19 @@ class Escpos(object):
else: else:
self._raw(PANEL_BUTTON_OFF) self._raw(PANEL_BUTTON_OFF)
def query_status(self, mode): def query_status(self):
""" Queries the printer for its status, and returns an array of integers containing it. """ Queries the printer for its status, and returns an array of integers containing it.
:param mode: Integer that sets the status mode queried to the printer.
RT_STATUS_ONLINE: Printer status.
RT_STATUS_PAPER: Paper sensor.
:rtype: array(integer)""" :rtype: array(integer)"""
self._raw(mode) self._raw(RT_STATUS_ONLINE)
time.sleep(1) time.sleep(1)
status = self._read() status = self._read()
return status return status or [RT_MASK_ONLINE]
def is_online(self): def is_online(self):
""" Queries the printer its online status. """ Queries the printer its online status.
When online, returns True; False otherwise. When online, returns True; False otherwise.
:rtype: bool: True if online, False if offline.""" :rtype: bool: True if online, False if offline."""
status = self.query_status(RT_STATUS_ONLINE) return not (self.query_status()[0] & RT_MASK_ONLINE)
if len(status) == 0:
return False
return not (status & RT_MASK_ONLINE)
def paper_status(self):
""" Queries the printer its paper status.
Returns 2 if there is plenty of paper, 1 if the paper has arrived to
the near-end sensor and 0 if there is no paper.
:rtype: int: 2: Paper is adequate. 1: Paper ending. 0: No paper."""
status = self.query_status(RT_STATUS_PAPER)
if len(status) == 0:
return 2
if (status[0] & RT_MASK_NOPAPER == RT_MASK_NOPAPER):
return 0
if (status[0] & RT_MASK_LOWPAPER == RT_MASK_LOWPAPER):
return 1
if (status[0] & RT_MASK_PAPER == RT_MASK_PAPER):
return 2
class EscposIO(object): class EscposIO(object):

View File

@@ -155,10 +155,6 @@ class Serial(Escpos):
""" """
self.device.write(msg) self.device.write(msg)
def _read(self):
""" Reads a data buffer and returns it to the caller. """
return self.device.read(16)
def close(self): def close(self):
""" Close Serial interface """ """ Close Serial interface """
if self.device is not None and self.device.is_open: if self.device is not None and self.device.is_open:

View File

@@ -39,27 +39,3 @@ def test_block_text():
"All the presidents men were eating falafel for breakfast.", font='a') "All the presidents men were eating falafel for breakfast.", font='a')
assert printer.output == \ assert printer.output == \
b'All the presidents men were eating falafel\nfor breakfast.' b'All the presidents men were eating falafel\nfor breakfast.'
def test_textln():
printer = get_printer()
printer.textln('hello, world')
assert printer.output == b'hello, world\n'
def test_textln_empty():
printer = get_printer()
printer.textln()
assert printer.output == b'\n'
def test_ln():
printer = get_printer()
printer.ln()
assert printer.output == b'\n'
def test_multiple_ln():
printer = get_printer()
printer.ln(3)
assert printer.output == b'\n\n\n'

View File

@@ -7,11 +7,10 @@ deps = nose
coverage coverage
scripttest scripttest
mock mock
pytest!=3.2.0 pytest
pytest-cov pytest-cov
pytest-mock pytest-mock
hypothesis hypothesis
viivakoodi
commands = py.test --cov escpos commands = py.test --cov escpos
[testenv:docs] [testenv:docs]
@@ -19,7 +18,6 @@ basepython = python
changedir = doc changedir = doc
deps = sphinx>=1.5.1 deps = sphinx>=1.5.1
setuptools_scm setuptools_scm
viivakoodi
commands = sphinx-build -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html commands = sphinx-build -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html
[testenv:flake8] [testenv:flake8]