mirror of
				https://github.com/pimoroni/st7735-python.git
				synced 2025-01-05 22:40:25 +03:00 
			
		
		
		
	Initial commit.
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| build | ||||
| *.egg-info | ||||
| *.pyc | ||||
| setuptools-* | ||||
							
								
								
									
										326
									
								
								Adafruit_ILI9341/ILI9341.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										326
									
								
								Adafruit_ILI9341/ILI9341.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,326 @@ | ||||
| # Copyright (c) 2014 Adafruit Industries | ||||
| # Author: Tony DiCola | ||||
| # | ||||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| # of this software and associated documentation files (the "Software"), to deal | ||||
| # in the Software without restriction, including without limitation the rights | ||||
| # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| # copies of the Software, and to permit persons to whom the Software is | ||||
| # furnished to do so, subject to the following conditions: | ||||
| # | ||||
| # The above copyright notice and this permission notice shall be included in | ||||
| # all copies or substantial portions of the Software. | ||||
| # | ||||
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| # THE SOFTWARE. | ||||
| import numbers | ||||
| import time | ||||
|  | ||||
| import Image | ||||
| import ImageDraw | ||||
|  | ||||
| import Adafruit_GPIO as GPIO | ||||
| import Adafruit_GPIO.SPI as SPI | ||||
|  | ||||
|  | ||||
| # Constants for interacting with display registers. | ||||
| ILI9341_TFTWIDTH    = 240 | ||||
| ILI9341_TFTHEIGHT   = 320 | ||||
|  | ||||
| ILI9341_NOP         = 0x00 | ||||
| ILI9341_SWRESET     = 0x01 | ||||
| ILI9341_RDDID       = 0x04 | ||||
| ILI9341_RDDST       = 0x09 | ||||
|  | ||||
| ILI9341_SLPIN       = 0x10 | ||||
| ILI9341_SLPOUT      = 0x11 | ||||
| ILI9341_PTLON       = 0x12 | ||||
| ILI9341_NORON       = 0x13 | ||||
|  | ||||
| ILI9341_RDMODE      = 0x0A | ||||
| ILI9341_RDMADCTL    = 0x0B | ||||
| ILI9341_RDPIXFMT    = 0x0C | ||||
| ILI9341_RDIMGFMT    = 0x0A | ||||
| ILI9341_RDSELFDIAG  = 0x0F | ||||
|  | ||||
| ILI9341_INVOFF      = 0x20 | ||||
| ILI9341_INVON       = 0x21 | ||||
| ILI9341_GAMMASET    = 0x26 | ||||
| ILI9341_DISPOFF     = 0x28 | ||||
| ILI9341_DISPON      = 0x29 | ||||
|  | ||||
| ILI9341_CASET       = 0x2A | ||||
| ILI9341_PASET       = 0x2B | ||||
| ILI9341_RAMWR       = 0x2C | ||||
| ILI9341_RAMRD       = 0x2E | ||||
|  | ||||
| ILI9341_PTLAR       = 0x30 | ||||
| ILI9341_MADCTL      = 0x36 | ||||
| ILI9341_PIXFMT      = 0x3A | ||||
|  | ||||
| ILI9341_FRMCTR1     = 0xB1 | ||||
| ILI9341_FRMCTR2     = 0xB2 | ||||
| ILI9341_FRMCTR3     = 0xB3 | ||||
| ILI9341_INVCTR      = 0xB4 | ||||
| ILI9341_DFUNCTR     = 0xB6 | ||||
|  | ||||
| ILI9341_PWCTR1      = 0xC0 | ||||
| ILI9341_PWCTR2      = 0xC1 | ||||
| ILI9341_PWCTR3      = 0xC2 | ||||
| ILI9341_PWCTR4      = 0xC3 | ||||
| ILI9341_PWCTR5      = 0xC4 | ||||
| ILI9341_VMCTR1      = 0xC5 | ||||
| ILI9341_VMCTR2      = 0xC7 | ||||
|  | ||||
| ILI9341_RDID1       = 0xDA | ||||
| ILI9341_RDID2       = 0xDB | ||||
| ILI9341_RDID3       = 0xDC | ||||
| ILI9341_RDID4       = 0xDD | ||||
|  | ||||
| ILI9341_GMCTRP1     = 0xE0 | ||||
| ILI9341_GMCTRN1     = 0xE1 | ||||
|  | ||||
| ILI9341_PWCTR6      = 0xFC | ||||
|  | ||||
| ILI9341_BLACK       = 0x0000 | ||||
| ILI9341_BLUE        = 0x001F | ||||
| ILI9341_RED         = 0xF800 | ||||
| ILI9341_GREEN       = 0x07E0 | ||||
| ILI9341_CYAN        = 0x07FF | ||||
| ILI9341_MAGENTA     = 0xF81F | ||||
| ILI9341_YELLOW      = 0xFFE0   | ||||
| ILI9341_WHITE       = 0xFFFF | ||||
|  | ||||
|  | ||||
| def color565(r, g, b): | ||||
| 	"""Convert red, green, blue components to a 16-bit 565 RGB value. Components | ||||
| 	should be values 0 to 255. | ||||
| 	""" | ||||
| 	return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3) | ||||
|  | ||||
| def image_to_data(image): | ||||
| 	"""Generator function to convert a PIL image to 16-bit 565 RGB bytes.""" | ||||
| 	pixels = image.convert('RGB').load() | ||||
| 	width, height = image.size | ||||
| 	for x in range(width): | ||||
| 		for y in range(height): | ||||
| 			r,g,b = pixels[(x,y)] | ||||
| 			color = color565(r, g, b) | ||||
| 			yield (color >> 8) & 0xFF | ||||
| 			yield color & 0xFF | ||||
|  | ||||
|  | ||||
| class ILI9341(object): | ||||
| 	"""Representation of an ILI9341 TFT LCD.""" | ||||
|  | ||||
| 	def __init__(self, dc, spi, rst=None, gpio=GPIO.get_platform_gpio(), | ||||
| 		width=ILI9341_TFTWIDTH, height=ILI9341_TFTHEIGHT): | ||||
| 		"""Create an instance of the display using SPI communication.  Must | ||||
| 		provide the GPIO pin number for the D/C pin and the SPI driver.  Can | ||||
| 		optionally provide the GPIO pin number for the reset pin as the rst | ||||
| 		parameter. | ||||
| 		""" | ||||
| 		self._dc = dc | ||||
| 		self._rst = rst | ||||
| 		self._spi = spi | ||||
| 		self._gpio = gpio | ||||
| 		self.width = width | ||||
| 		self.height = height | ||||
| 		# Set DC as output. | ||||
| 		gpio.setup(dc, GPIO.OUT) | ||||
| 		# Setup reset as output (if provided). | ||||
| 		if rst is not None: | ||||
| 			gpio.setup(rst, GPIO.OUT) | ||||
| 		# Set SPI to mode 0, MSB first. | ||||
| 		spi.set_mode(0) | ||||
| 		spi.set_bit_order(SPI.MSBFIRST) | ||||
| 		# Create an image buffer. | ||||
| 		self.buffer = Image.new('RGB', (width, height)) | ||||
|  | ||||
| 	def send(self, data, is_data=True, chunk_size=4096): | ||||
| 		"""Write a byte or array of bytes to the display. Is_data parameter | ||||
| 		controls if byte should be interpreted as display data (True) or command | ||||
| 		data (False).  Chunk_size is an optional size of bytes to write in a | ||||
| 		single SPI transaction, with a default of 4096. | ||||
| 		""" | ||||
| 		# Set DC low for command, high for data. | ||||
| 		self._gpio.output(self._dc, is_data) | ||||
| 		# Convert scalar argument to list so either can be passed as parameter. | ||||
| 		if isinstance(data, numbers.Number): | ||||
| 			data = [data & 0xFF] | ||||
| 		# Write data a chunk at a time. | ||||
| 		for start in range(0, len(data), chunk_size): | ||||
| 			end = min(start+chunk_size, len(data)) | ||||
| 			self._spi.write(data[start:end]) | ||||
|  | ||||
| 	def command(self, data): | ||||
| 		"""Write a byte or array of bytes to the display as command data.""" | ||||
| 		self.send(data, False) | ||||
|  | ||||
| 	def data(self, data): | ||||
| 		"""Write a byte or array of bytes to the display as display data.""" | ||||
| 		self.send(data, True) | ||||
|  | ||||
| 	def reset(self): | ||||
| 		"""Reset the display, if reset pin is connected.""" | ||||
| 		if self._rst is not None: | ||||
| 			self._gpio.set_high(self._rst) | ||||
| 			time.sleep(0.005) | ||||
| 			self._gpio.set_low(self._rst) | ||||
| 			time.sleep(0.02) | ||||
| 			self._gpio.set_high(self._rst) | ||||
| 			time.sleep(0.150) | ||||
|  | ||||
| 	def _init(self): | ||||
| 		# Initialize the display.  Broken out as a separate function so it can | ||||
| 		# be overridden by other displays in the future. | ||||
| 		self.command(0xEF) | ||||
| 		self.data(0x03) | ||||
| 		self.data(0x80) | ||||
| 		self.data(0x02) | ||||
| 		self.command(0xCF) | ||||
| 		self.data(0x00) | ||||
| 		self.data(0XC1) | ||||
| 		self.data(0X30) | ||||
| 		self.command(0xED) | ||||
| 		self.data(0x64) | ||||
| 		self.data(0x03) | ||||
| 		self.data(0X12) | ||||
| 		self.data(0X81) | ||||
| 		self.command(0xE8) | ||||
| 		self.data(0x85) | ||||
| 		self.data(0x00) | ||||
| 		self.data(0x78) | ||||
| 		self.command(0xCB) | ||||
| 		self.data(0x39) | ||||
| 		self.data(0x2C) | ||||
| 		self.data(0x00) | ||||
| 		self.data(0x34) | ||||
| 		self.data(0x02) | ||||
| 		self.command(0xF7) | ||||
| 		self.data(0x20) | ||||
| 		self.command(0xEA) | ||||
| 		self.data(0x00) | ||||
| 		self.data(0x00) | ||||
| 		self.command(ILI9341_PWCTR1)	# Power control  | ||||
| 		self.data(0x23)					# VRH[5:0]  | ||||
| 		self.command(ILI9341_PWCTR2)	# Power control  | ||||
| 		self.data(0x10)					# SAP[2:0];BT[3:0]  | ||||
| 		self.command(ILI9341_VMCTR1)	# VCM control  | ||||
| 		self.data(0x3e) | ||||
| 		self.data(0x28) | ||||
| 		self.command(ILI9341_VMCTR2)	# VCM control2  | ||||
| 		self.data(0x86)					# -- | ||||
| 		self.command(ILI9341_MADCTL)	#  Memory Access Control  | ||||
| 		self.data(0x48) | ||||
| 		self.command(ILI9341_PIXFMT) | ||||
| 		self.data(0x55) | ||||
| 		self.command(ILI9341_FRMCTR1) | ||||
| 		self.data(0x00) | ||||
| 		self.data(0x18) | ||||
| 		self.command(ILI9341_DFUNCTR)	#  Display Function Control  | ||||
| 		self.data(0x08) | ||||
| 		self.data(0x82) | ||||
| 		self.data(0x27) | ||||
| 		self.command(0xF2)				#  3Gamma Function Disable  | ||||
| 		self.data(0x00) | ||||
| 		self.command(ILI9341_GAMMASET)	# Gamma curve selected  | ||||
| 		self.data(0x01) | ||||
| 		self.command(ILI9341_GMCTRP1)	# Set Gamma  | ||||
| 		self.data(0x0F) | ||||
| 		self.data(0x31) | ||||
| 		self.data(0x2B) | ||||
| 		self.data(0x0C) | ||||
| 		self.data(0x0E) | ||||
| 		self.data(0x08) | ||||
| 		self.data(0x4E) | ||||
| 		self.data(0xF1) | ||||
| 		self.data(0x37) | ||||
| 		self.data(0x07) | ||||
| 		self.data(0x10) | ||||
| 		self.data(0x03) | ||||
| 		self.data(0x0E) | ||||
| 		self.data(0x09) | ||||
| 		self.data(0x00) | ||||
| 		self.command(ILI9341_GMCTRN1)	# Set Gamma  | ||||
| 		self.data(0x00) | ||||
| 		self.data(0x0E) | ||||
| 		self.data(0x14) | ||||
| 		self.data(0x03) | ||||
| 		self.data(0x11) | ||||
| 		self.data(0x07) | ||||
| 		self.data(0x31) | ||||
| 		self.data(0xC1) | ||||
| 		self.data(0x48) | ||||
| 		self.data(0x08) | ||||
| 		self.data(0x0F) | ||||
| 		self.data(0x0C) | ||||
| 		self.data(0x31) | ||||
| 		self.data(0x36) | ||||
| 		self.data(0x0F) | ||||
| 		self.command(ILI9341_SLPOUT)	# Exit Sleep  | ||||
| 		time.sleep(0.120) | ||||
| 		self.command(ILI9341_DISPON)	# Display on  | ||||
|  | ||||
| 	def begin(self): | ||||
| 		"""Initialize the display.  Should be called once before other calls that | ||||
| 		interact with the display are called. | ||||
| 		""" | ||||
| 		self.reset() | ||||
| 		self._init()	 | ||||
| 	 | ||||
| 	def set_window(self, x0=0, y0=0, x1=None, y1=None): | ||||
| 		"""Set the pixel address window for proceeding drawing commands. x0 and | ||||
| 		x1 should define the minimum and maximum x pixel bounds.  y0 and y1  | ||||
| 		should define the minimum and maximum y pixel bound.  If no parameters  | ||||
| 		are specified the default will be to update the entire display from 0,0 | ||||
| 		to 239,319. | ||||
| 		""" | ||||
| 		if x1 is None: | ||||
| 			x1 = self.width-1 | ||||
| 		if y1 is None: | ||||
| 			y1 = self.height-1 | ||||
| 		self.command(ILI9341_CASET)		# Column addr set | ||||
| 		self.data(x0 >> 8) | ||||
| 		self.data(x0)					# XSTART  | ||||
| 		self.data(x1 >> 8) | ||||
| 		self.data(x1)					# XEND | ||||
| 		self.command(ILI9341_PASET)		# Row addr set | ||||
| 		self.data(y0 >> 8) | ||||
| 		self.data(y0)					# YSTART | ||||
| 		self.data(y1 >> 8) | ||||
| 		self.data(y1)					# YEND | ||||
| 		self.command(ILI9341_RAMWR)		# write to RAM | ||||
|  | ||||
| 	def display(self, image=None): | ||||
| 		"""Write the display buffer or provided image to the hardware.  If no | ||||
| 		image parameter is provided the display buffer will be written to the | ||||
| 		hardware.  If an image is provided, it should be RGB format and the | ||||
| 		same dimensions as the display hardware. | ||||
| 		""" | ||||
| 		# By default write the internal buffer to the display. | ||||
| 		if image is None: | ||||
| 			image = self.buffer | ||||
| 		# Set address bounds to entire display. | ||||
| 		self.set_window() | ||||
| 		# Convert image to array of 16bit 565 RGB data bytes. | ||||
| 		# Unfortunate that this copy has to occur, but the SPI byte writing | ||||
| 		# function needs to take an array of bytes and PIL doesn't natively | ||||
| 		# store images in 16-bit 565 RGB format. | ||||
| 		pixelbytes = list(image_to_data(image)) | ||||
| 		# Write data to hardware. | ||||
| 		self.data(pixelbytes) | ||||
|  | ||||
| 	def clear(self, color=(0,0,0)): | ||||
| 		"""Clear the image buffer to the specified RGB color (default black).""" | ||||
| 		width, height = self.buffer.size | ||||
| 		self.buffer.putdata([color]*(width*height)) | ||||
|  | ||||
| 	def draw(self): | ||||
| 		"""Return a PIL ImageDraw instance for 2D drawing on the image buffer.""" | ||||
| 		return ImageDraw(self.buffer) | ||||
							
								
								
									
										21
									
								
								Adafruit_ILI9341/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Adafruit_ILI9341/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| # Copyright (c) 2014 Adafruit Industries | ||||
| # Author: Tony DiCola | ||||
| # | ||||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| # of this software and associated documentation files (the "Software"), to deal | ||||
| # in the Software without restriction, including without limitation the rights | ||||
| # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| # copies of the Software, and to permit persons to whom the Software is | ||||
| # furnished to do so, subject to the following conditions: | ||||
| # | ||||
| # The above copyright notice and this permission notice shall be included in | ||||
| # all copies or substantial portions of the Software. | ||||
| # | ||||
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| # THE SOFTWARE. | ||||
| from ILI9341 import * | ||||
							
								
								
									
										
											BIN
										
									
								
								examples/cat.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								examples/cat.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 26 KiB | 
							
								
								
									
										53
									
								
								examples/image.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								examples/image.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| # Copyright (c) 2014 Adafruit Industries | ||||
| # Author: Tony DiCola | ||||
| # | ||||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| # of this software and associated documentation files (the "Software"), to deal | ||||
| # in the Software without restriction, including without limitation the rights | ||||
| # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| # copies of the Software, and to permit persons to whom the Software is | ||||
| # furnished to do so, subject to the following conditions: | ||||
| # | ||||
| # The above copyright notice and this permission notice shall be included in | ||||
| # all copies or substantial portions of the Software. | ||||
| # | ||||
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| # THE SOFTWARE. | ||||
| import Image | ||||
|  | ||||
| import Adafruit_ILI9341 as TFT | ||||
| import Adafruit_GPIO as GPIO | ||||
| import Adafruit_GPIO.SPI as SPI | ||||
|  | ||||
|  | ||||
| # Raspberry Pi configuration. | ||||
| DC = 18 | ||||
| RST = 23 | ||||
| SPI_PORT = 0 | ||||
| SPI_DEVICE = 0 | ||||
|  | ||||
| # BeagleBone Black configuration. | ||||
| # DC = 'P9_15' | ||||
| # RST = 'P9_12' | ||||
| # SPI_PORT = 1 | ||||
| # SPI_DEVICE = 0 | ||||
|  | ||||
| # Create TFT LCD display class. | ||||
| disp = TFT.ILI9341(DC, rst=RST, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=64000000)) | ||||
|  | ||||
| # Initialize display. | ||||
| disp.begin() | ||||
|  | ||||
| # Load an image. | ||||
| # Make sure the image is 320x240 pixels! | ||||
| print 'Loading image...' | ||||
| image = Image.open('cat.jpg') | ||||
|  | ||||
| # Draw the image on the display hardware. | ||||
| print 'Drawing image' | ||||
| disp.display(image) | ||||
							
								
								
									
										332
									
								
								ez_setup.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										332
									
								
								ez_setup.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,332 @@ | ||||
| #!/usr/bin/env python | ||||
| """Bootstrap setuptools installation | ||||
|  | ||||
| To use setuptools in your package's setup.py, include this | ||||
| file in the same directory and add this to the top of your setup.py:: | ||||
|  | ||||
|     from ez_setup import use_setuptools | ||||
|     use_setuptools() | ||||
|  | ||||
| To require a specific version of setuptools, set a download | ||||
| mirror, or use an alternate download directory, simply supply | ||||
| the appropriate options to ``use_setuptools()``. | ||||
|  | ||||
| This file can also be run as a script to install or upgrade setuptools. | ||||
| """ | ||||
| import os | ||||
| import shutil | ||||
| import sys | ||||
| import tempfile | ||||
| import zipfile | ||||
| import optparse | ||||
| import subprocess | ||||
| import platform | ||||
| import textwrap | ||||
| import contextlib | ||||
|  | ||||
| from distutils import log | ||||
|  | ||||
| try: | ||||
|     from site import USER_SITE | ||||
| except ImportError: | ||||
|     USER_SITE = None | ||||
|  | ||||
| DEFAULT_VERSION = "3.5.1" | ||||
| DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/" | ||||
|  | ||||
| def _python_cmd(*args): | ||||
|     """ | ||||
|     Return True if the command succeeded. | ||||
|     """ | ||||
|     args = (sys.executable,) + args | ||||
|     return subprocess.call(args) == 0 | ||||
|  | ||||
|  | ||||
| def _install(archive_filename, install_args=()): | ||||
|     with archive_context(archive_filename): | ||||
|         # installing | ||||
|         log.warn('Installing Setuptools') | ||||
|         if not _python_cmd('setup.py', 'install', *install_args): | ||||
|             log.warn('Something went wrong during the installation.') | ||||
|             log.warn('See the error message above.') | ||||
|             # exitcode will be 2 | ||||
|             return 2 | ||||
|  | ||||
|  | ||||
| def _build_egg(egg, archive_filename, to_dir): | ||||
|     with archive_context(archive_filename): | ||||
|         # building an egg | ||||
|         log.warn('Building a Setuptools egg in %s', to_dir) | ||||
|         _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) | ||||
|     # returning the result | ||||
|     log.warn(egg) | ||||
|     if not os.path.exists(egg): | ||||
|         raise IOError('Could not build the egg.') | ||||
|  | ||||
|  | ||||
| def get_zip_class(): | ||||
|     """ | ||||
|     Supplement ZipFile class to support context manager for Python 2.6 | ||||
|     """ | ||||
|     class ContextualZipFile(zipfile.ZipFile): | ||||
|         def __enter__(self): | ||||
|             return self | ||||
|         def __exit__(self, type, value, traceback): | ||||
|             self.close | ||||
|     return zipfile.ZipFile if hasattr(zipfile.ZipFile, '__exit__') else \ | ||||
|         ContextualZipFile | ||||
|  | ||||
|  | ||||
| @contextlib.contextmanager | ||||
| def archive_context(filename): | ||||
|     # extracting the archive | ||||
|     tmpdir = tempfile.mkdtemp() | ||||
|     log.warn('Extracting in %s', tmpdir) | ||||
|     old_wd = os.getcwd() | ||||
|     try: | ||||
|         os.chdir(tmpdir) | ||||
|         with get_zip_class()(filename) as archive: | ||||
|             archive.extractall() | ||||
|  | ||||
|         # going in the directory | ||||
|         subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) | ||||
|         os.chdir(subdir) | ||||
|         log.warn('Now working in %s', subdir) | ||||
|         yield | ||||
|  | ||||
|     finally: | ||||
|         os.chdir(old_wd) | ||||
|         shutil.rmtree(tmpdir) | ||||
|  | ||||
|  | ||||
| def _do_download(version, download_base, to_dir, download_delay): | ||||
|     egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg' | ||||
|                        % (version, sys.version_info[0], sys.version_info[1])) | ||||
|     if not os.path.exists(egg): | ||||
|         archive = download_setuptools(version, download_base, | ||||
|                                       to_dir, download_delay) | ||||
|         _build_egg(egg, archive, to_dir) | ||||
|     sys.path.insert(0, egg) | ||||
|  | ||||
|     # Remove previously-imported pkg_resources if present (see | ||||
|     # https://bitbucket.org/pypa/setuptools/pull-request/7/ for details). | ||||
|     if 'pkg_resources' in sys.modules: | ||||
|         del sys.modules['pkg_resources'] | ||||
|  | ||||
|     import setuptools | ||||
|     setuptools.bootstrap_install_from = egg | ||||
|  | ||||
|  | ||||
| def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, | ||||
|         to_dir=os.curdir, download_delay=15): | ||||
|     to_dir = os.path.abspath(to_dir) | ||||
|     rep_modules = 'pkg_resources', 'setuptools' | ||||
|     imported = set(sys.modules).intersection(rep_modules) | ||||
|     try: | ||||
|         import pkg_resources | ||||
|     except ImportError: | ||||
|         return _do_download(version, download_base, to_dir, download_delay) | ||||
|     try: | ||||
|         pkg_resources.require("setuptools>=" + version) | ||||
|         return | ||||
|     except pkg_resources.DistributionNotFound: | ||||
|         return _do_download(version, download_base, to_dir, download_delay) | ||||
|     except pkg_resources.VersionConflict as VC_err: | ||||
|         if imported: | ||||
|             msg = textwrap.dedent(""" | ||||
|                 The required version of setuptools (>={version}) is not available, | ||||
|                 and can't be installed while this script is running. Please | ||||
|                 install a more recent version first, using | ||||
|                 'easy_install -U setuptools'. | ||||
|  | ||||
|                 (Currently using {VC_err.args[0]!r}) | ||||
|                 """).format(VC_err=VC_err, version=version) | ||||
|             sys.stderr.write(msg) | ||||
|             sys.exit(2) | ||||
|  | ||||
|         # otherwise, reload ok | ||||
|         del pkg_resources, sys.modules['pkg_resources'] | ||||
|         return _do_download(version, download_base, to_dir, download_delay) | ||||
|  | ||||
| def _clean_check(cmd, target): | ||||
|     """ | ||||
|     Run the command to download target. If the command fails, clean up before | ||||
|     re-raising the error. | ||||
|     """ | ||||
|     try: | ||||
|         subprocess.check_call(cmd) | ||||
|     except subprocess.CalledProcessError: | ||||
|         if os.access(target, os.F_OK): | ||||
|             os.unlink(target) | ||||
|         raise | ||||
|  | ||||
| def download_file_powershell(url, target): | ||||
|     """ | ||||
|     Download the file at url to target using Powershell (which will validate | ||||
|     trust). Raise an exception if the command cannot complete. | ||||
|     """ | ||||
|     target = os.path.abspath(target) | ||||
|     cmd = [ | ||||
|         'powershell', | ||||
|         '-Command', | ||||
|         "(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)" % vars(), | ||||
|     ] | ||||
|     _clean_check(cmd, target) | ||||
|  | ||||
| def has_powershell(): | ||||
|     if platform.system() != 'Windows': | ||||
|         return False | ||||
|     cmd = ['powershell', '-Command', 'echo test'] | ||||
|     devnull = open(os.path.devnull, 'wb') | ||||
|     try: | ||||
|         try: | ||||
|             subprocess.check_call(cmd, stdout=devnull, stderr=devnull) | ||||
|         except Exception: | ||||
|             return False | ||||
|     finally: | ||||
|         devnull.close() | ||||
|     return True | ||||
|  | ||||
| download_file_powershell.viable = has_powershell | ||||
|  | ||||
| def download_file_curl(url, target): | ||||
|     cmd = ['curl', url, '--silent', '--output', target] | ||||
|     _clean_check(cmd, target) | ||||
|  | ||||
| def has_curl(): | ||||
|     cmd = ['curl', '--version'] | ||||
|     devnull = open(os.path.devnull, 'wb') | ||||
|     try: | ||||
|         try: | ||||
|             subprocess.check_call(cmd, stdout=devnull, stderr=devnull) | ||||
|         except Exception: | ||||
|             return False | ||||
|     finally: | ||||
|         devnull.close() | ||||
|     return True | ||||
|  | ||||
| download_file_curl.viable = has_curl | ||||
|  | ||||
| def download_file_wget(url, target): | ||||
|     cmd = ['wget', url, '--quiet', '--output-document', target] | ||||
|     _clean_check(cmd, target) | ||||
|  | ||||
| def has_wget(): | ||||
|     cmd = ['wget', '--version'] | ||||
|     devnull = open(os.path.devnull, 'wb') | ||||
|     try: | ||||
|         try: | ||||
|             subprocess.check_call(cmd, stdout=devnull, stderr=devnull) | ||||
|         except Exception: | ||||
|             return False | ||||
|     finally: | ||||
|         devnull.close() | ||||
|     return True | ||||
|  | ||||
| download_file_wget.viable = has_wget | ||||
|  | ||||
| def download_file_insecure(url, target): | ||||
|     """ | ||||
|     Use Python to download the file, even though it cannot authenticate the | ||||
|     connection. | ||||
|     """ | ||||
|     try: | ||||
|         from urllib.request import urlopen | ||||
|     except ImportError: | ||||
|         from urllib2 import urlopen | ||||
|     src = dst = None | ||||
|     try: | ||||
|         src = urlopen(url) | ||||
|         # Read/write all in one block, so we don't create a corrupt file | ||||
|         # if the download is interrupted. | ||||
|         data = src.read() | ||||
|         dst = open(target, "wb") | ||||
|         dst.write(data) | ||||
|     finally: | ||||
|         if src: | ||||
|             src.close() | ||||
|         if dst: | ||||
|             dst.close() | ||||
|  | ||||
| download_file_insecure.viable = lambda: True | ||||
|  | ||||
| def get_best_downloader(): | ||||
|     downloaders = [ | ||||
|         download_file_powershell, | ||||
|         download_file_curl, | ||||
|         download_file_wget, | ||||
|         download_file_insecure, | ||||
|     ] | ||||
|  | ||||
|     for dl in downloaders: | ||||
|         if dl.viable(): | ||||
|             return dl | ||||
|  | ||||
| def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, | ||||
|         to_dir=os.curdir, delay=15, downloader_factory=get_best_downloader): | ||||
|     """ | ||||
|     Download setuptools from a specified location and return its filename | ||||
|  | ||||
|     `version` should be a valid setuptools version number that is available | ||||
|     as an egg for download under the `download_base` URL (which should end | ||||
|     with a '/'). `to_dir` is the directory where the egg will be downloaded. | ||||
|     `delay` is the number of seconds to pause before an actual download | ||||
|     attempt. | ||||
|  | ||||
|     ``downloader_factory`` should be a function taking no arguments and | ||||
|     returning a function for downloading a URL to a target. | ||||
|     """ | ||||
|     # making sure we use the absolute path | ||||
|     to_dir = os.path.abspath(to_dir) | ||||
|     zip_name = "setuptools-%s.zip" % version | ||||
|     url = download_base + zip_name | ||||
|     saveto = os.path.join(to_dir, zip_name) | ||||
|     if not os.path.exists(saveto):  # Avoid repeated downloads | ||||
|         log.warn("Downloading %s", url) | ||||
|         downloader = downloader_factory() | ||||
|         downloader(url, saveto) | ||||
|     return os.path.realpath(saveto) | ||||
|  | ||||
| def _build_install_args(options): | ||||
|     """ | ||||
|     Build the arguments to 'python setup.py install' on the setuptools package | ||||
|     """ | ||||
|     return ['--user'] if options.user_install else [] | ||||
|  | ||||
| def _parse_args(): | ||||
|     """ | ||||
|     Parse the command line for options | ||||
|     """ | ||||
|     parser = optparse.OptionParser() | ||||
|     parser.add_option( | ||||
|         '--user', dest='user_install', action='store_true', default=False, | ||||
|         help='install in user site package (requires Python 2.6 or later)') | ||||
|     parser.add_option( | ||||
|         '--download-base', dest='download_base', metavar="URL", | ||||
|         default=DEFAULT_URL, | ||||
|         help='alternative URL from where to download the setuptools package') | ||||
|     parser.add_option( | ||||
|         '--insecure', dest='downloader_factory', action='store_const', | ||||
|         const=lambda: download_file_insecure, default=get_best_downloader, | ||||
|         help='Use internal, non-validating downloader' | ||||
|     ) | ||||
|     parser.add_option( | ||||
|         '--version', help="Specify which version to download", | ||||
|         default=DEFAULT_VERSION, | ||||
|     ) | ||||
|     options, args = parser.parse_args() | ||||
|     # positional arguments are ignored | ||||
|     return options | ||||
|  | ||||
| def main(): | ||||
|     """Install or upgrade setuptools and EasyInstall""" | ||||
|     options = _parse_args() | ||||
|     archive = download_setuptools( | ||||
|         version=options.version, | ||||
|         download_base=options.download_base, | ||||
|         downloader_factory=options.downloader_factory, | ||||
|     ) | ||||
|     return _install(archive, _build_install_args(options)) | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     sys.exit(main()) | ||||
							
								
								
									
										21
									
								
								setup.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								setup.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| # Workaround for issue in Python 2.7.3 | ||||
| # See http://bugs.python.org/issue15881#msg170215 | ||||
| try: | ||||
|     import multiprocessing | ||||
| except ImportError: | ||||
|     pass | ||||
|  | ||||
| from ez_setup import use_setuptools | ||||
| use_setuptools() | ||||
| from setuptools import setup, find_packages | ||||
|  | ||||
| setup(name              = 'Adafruit_ILI9341', | ||||
|       version           = '1.0.0', | ||||
|       author            = 'Tony DiCola', | ||||
|       author_email      = 'tdicola@adafruit.com', | ||||
|       description       = 'Library to control an ILI9341 TFT LCD display.', | ||||
|       license           = 'MIT', | ||||
|       url               = 'https://github.com/adafruit/Adafruit_Python_ILI9341/', | ||||
|       dependency_links  = ['https://github.com/adafruit/Adafruit_Python_GPIO/tarball/master#egg=Adafruit-GPIO-0.4.0'], | ||||
|       install_requires  = ['Adafruit-GPIO>=0.4.0'], | ||||
|       packages          = find_packages()) | ||||
		Reference in New Issue
	
	Block a user
	 Tony DiCola
					Tony DiCola