adafruit / Adafruit_CircuitPython_PyPortal

CircuitPython driver for Adafruit PyPortal.
MIT License
45 stars 56 forks source link

Update fetch() for portrait oriented images #60

Closed cogliano closed 4 years ago

cogliano commented 4 years ago

This code was added to allow multiple fetch() commands to work correctly when there is a mix of portrait and landscape oriented images to display on the PyPortal. An additional parameter, image_dim_json_path, was added to init() to point to the JSON section that contains the original width and height of the image. If this parameter (a width and height tuple) is not present, the fetch should work as before with no portrait mode considerations.

Here is an example of the feature being used. I commented out some of the lines so the code could run without external file dependencies. Specific landscape and portrait itemids can be uncommented for testing, or use the randomint() function.

More info on the api used in the example is here: https://openaccess-api.clevelandart.org/

import time
import board
import random
from adafruit_pyportal import PyPortal
from adafruit_display_shapes.circle import Circle

WIDTH = board.DISPLAY.width
HEIGHT = board.DISPLAY.height

apiurl = "https://openaccess-api.clevelandart.org/api/artworks?cc0=1&has_image=1&indent=2&limit=1&skip="

pyportal = PyPortal(
                    # default_bg=background_file,
                    image_json_path=["data",0,"images","web","url"],
                    image_dim_json_path=(["data",0,"images","web","width"],["data",0,"images","web","height"]),
                    image_resize=(WIDTH, HEIGHT - 15),
                    image_position=(0, 0),
                    #text_font="/fonts/OpenSans-9.bdf",
                    #json_path=["data",0,"title"],
                    #text_position=(4,HEIGHT - 9),
                    #text_color =0xFFFFFF
                    )

circle = Circle(312, 233, 5, fill=0)
pyportal.splash.append(circle)
loopcount = 0
errorcount = 0
while True:
    response = None
    try:
        circle.fill = 0xFF0000
        itemid = random.randint(1, 30000)
        # itemid = 20 # portrait mode example
        # itemid = 21 # landscape mode example
        print("retrieving url:", apiurl +str(itemid))
        response = pyportal.fetch(apiurl + str(itemid))
        circle.fill = 0
        print("Response is", response)
        loopcount = loopcount + 1

    except (RuntimeError, KeyError) as e:
        print("An error occured, retrying! -", e)
        print("loop counter:", loopcount)
        assert errorcount < 20, "Too many errors, stopping"
        errorcount = errorcount + 1
        continue

    errorcount = 0
    stamp = time.monotonic()
    # wait 5 minutes before getting again
    while (time.monotonic() - stamp) < (5*60):
        # or, if they touch the screen, fetch immediately!
        if pyportal.touchscreen.touch_point:
            break
kattni commented 4 years ago

Thanks for the update, @cogliano! Thank you for testing this, @FoamyGuy!

cogliano commented 4 years ago

Thank you @kattni and @FoamyGuy. This feature will be included in an upcoming learning guide I am working on.

kattni commented 4 years ago

@cogliano Thanks for letting me know. I did a release so your update will be included in the version in the library bundle. It will go in when the bundle builds next, likely today.