forked from cgoldberg/py-slideshow
-
Notifications
You must be signed in to change notification settings - Fork 2
/
slideshow.py
executable file
·173 lines (134 loc) · 4.51 KB
/
slideshow.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/usr/bin/env python
#
# Copyright (c) 2015, Jamin W. Collins <[email protected]>
# Dev: https://github.com/jamincollins/py-slideshow
#
# Based on work done by Corey Goldberg
# Copyright (c) 2013, 2015, Corey Goldberg
#
# Dev: https://github.com/cgoldberg/py-slideshow
# License: GPLv3
import argparse
import os
import queue
import random
import select
import subprocess
import sys
import threading
import time
import inotify # https://github.com/jamincollins/python-inotify
import pyglet
from inotify import watcher
def update_pan_zoom_speeds():
global _pan_speed_x
global _pan_speed_y
global _zoom_speed
_pan_speed_x = random.randint(-8, 8)
_pan_speed_y = random.randint(-8, 8)
_zoom_speed = random.uniform(-0.02, 0.02)
return _pan_speed_x, _pan_speed_y, _zoom_speed
def update_pan(dt):
sprite.x += dt * _pan_speed_x
sprite.y += dt * _pan_speed_y
def update_zoom(dt):
sprite.scale += dt * _zoom_speed
def update_image(dt):
if not new_pics.empty():
# if there are images in queue, load the next, and add to known
filename = new_pics.get()
image_paths.append(filename)
elif not image_paths:
return
else:
# otherwise load a random existing image
filename = random.choice(image_paths)
try:
img = pyglet.image.load(filename)
sprite.image = img
sprite.scale = get_scale(window, img)
sprite.x = 0
sprite.y = 0
update_pan_zoom_speeds()
window.clear()
except FileNotFoundError:
# remove image from the list
image_paths.remove(filename)
def get_image_paths(input_dir='.'):
paths = []
while not paths:
for root, dirs, files in os.walk(input_dir, topdown=True):
for filename in sorted(files):
if filename.endswith(('jpg', 'png', 'gif')):
path = os.path.abspath(os.path.join(root, filename))
paths.append(path)
time.sleep(.5)
return paths
def get_scale(window, image):
if image.width > image.height:
scale = float(window.width) / image.width
else:
scale = float(window.height) / image.height
return scale
def watch_for_new_images(input_dir):
w = watcher.AutoWatcher()
try:
# Watch all paths recursively, and all events on them.
w.add_all(input_dir, inotify.IN_ALL_EVENTS)
except OSError as err:
print('%s: %s' % (err.filename, err.strerror), file=sys.stderr)
poll = select.poll()
poll.register(w, select.POLLIN)
timeout = None
threshold = watcher.Threshold(w, 512)
while True:
events = poll.poll(timeout)
nread = 0
if threshold() or not events:
print('reading,', threshold.readable(), 'bytes available')
for evt in w.read(0):
nread += 1
events = inotify.decode_mask(evt.mask)
if 'IN_MOVED_TO' in events:
filename = evt.fullpath
if filename.endswith(('jpg', 'png', 'gif')):
print("adding %s to the queue" % filename)
new_pics.put(filename)
if nread:
timeout = None
poll.register(w, select.POLLIN)
else:
timeout = 1000
poll.unregister(w)
def shove_mouse(dt):
get_vertical = "xdotool getdisplaygeometry | awk '{print $2}'"
cmd = "xdotool mousemove 0 $({0})".format(get_vertical)
subprocess.call(cmd, shell=True)
def main():
global sprite
global image_paths
global window
global new_pics
new_pics = queue.Queue()
_pan_speed_x, _pan_speed_y, _zoom_speed = update_pan_zoom_speeds()
parser = argparse.ArgumentParser()
parser.add_argument('dir', help='directory of images',
nargs='?', default=os.getcwd())
args = parser.parse_args()
image_paths = get_image_paths(args.dir)
thread = threading.Thread(target=watch_for_new_images, args=(args.dir,))
thread.start()
window = pyglet.window.Window(fullscreen=True)
@window.event
def on_draw():
sprite.draw()
img = pyglet.image.load(random.choice(image_paths))
sprite = pyglet.sprite.Sprite(img)
sprite.scale = get_scale(window, img)
pyglet.clock.schedule_interval(update_image, 6.0)
pyglet.clock.schedule_interval(shove_mouse, 6.0)
# pyglet.clock.schedule_interval(update_pan, 1/60.0)
# pyglet.clock.schedule_interval(update_zoom, 1/60.0)
pyglet.app.run()
if __name__ == '__main__':
main()