Logging added
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import configparser, os
|
import configparser, os, logging
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
@@ -29,16 +29,20 @@ class Config:
|
|||||||
|
|
||||||
def defaults(self):
|
def defaults(self):
|
||||||
|
|
||||||
self._cfg.read(os.path.join(os.path.dirname(__file__), 'defaults.cfg'))
|
filename = os.path.join(os.path.dirname(__file__), 'defaults.cfg')
|
||||||
|
logging.info('Reading config file "%s"', filename)
|
||||||
|
self._cfg.read(filename)
|
||||||
|
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
|
|
||||||
|
logging.info('Reading config file "%s"', self._filename)
|
||||||
self._cfg.read(self._filename)
|
self._cfg.read(self._filename)
|
||||||
|
|
||||||
|
|
||||||
def write(self):
|
def write(self):
|
||||||
|
|
||||||
|
logging.info('Writing config file "%s"', self._filename)
|
||||||
with open(self._filename, 'w') as configfile:
|
with open(self._filename, 'w') as configfile:
|
||||||
self._cfg.write(configfile)
|
self._cfg.write(configfile)
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# from time import time, localtime, strftime
|
import logging
|
||||||
|
|
||||||
from PIL import Image, ImageOps
|
from PIL import Image, ImageOps
|
||||||
|
|
||||||
from .PictureList import PictureList
|
|
||||||
from .PictureDimensions import PictureDimensions
|
from .PictureDimensions import PictureDimensions
|
||||||
|
|
||||||
from . import gui
|
from . import gui
|
||||||
|
|
||||||
from.Worker import PictureSaver
|
from .Worker import PictureSaver
|
||||||
|
|
||||||
|
|
||||||
class TeardownException(Exception):
|
class TeardownException(Exception):
|
||||||
@@ -40,30 +39,35 @@ class Photobooth:
|
|||||||
self._cap = camera
|
self._cap = camera
|
||||||
self._pic_dims = PictureDimensions(config, self._cap.getPicture().size)
|
self._pic_dims = PictureDimensions(config, self._cap.getPicture().size)
|
||||||
|
|
||||||
# picture_basename = strftime(config.get('Picture', 'basename'), localtime())
|
|
||||||
# self._pic_list = PictureList(picture_basename)
|
|
||||||
# self._get_next_filename = self._pic_list.getNext
|
|
||||||
|
|
||||||
if ( config.getBool('Photobooth', 'show_preview')
|
if ( config.getBool('Photobooth', 'show_preview')
|
||||||
and self._cap.hasPreview ):
|
and self._cap.hasPreview ):
|
||||||
|
logging.info('Countdown with preview activated')
|
||||||
self._show_counter = self.showCounterPreview
|
self._show_counter = self.showCounterPreview
|
||||||
else:
|
else:
|
||||||
|
logging.info('Countdown without preview activated')
|
||||||
self._show_counter = self.showCounterNoPreview
|
self._show_counter = self.showCounterNoPreview
|
||||||
|
|
||||||
|
|
||||||
def initGpio(self, config):
|
def initGpio(self, config):
|
||||||
|
|
||||||
if config.getBool('Gpio', 'enable'):
|
if config.getBool('Gpio', 'enable'):
|
||||||
|
lamp_pin = config.getInt('Gpio', 'lamp_pin')
|
||||||
|
trigger_pin = config.getInt('Gpio', 'trigger_pin')
|
||||||
|
exit_pin = config.getInt('Gpio', 'exit_pin')
|
||||||
|
|
||||||
|
logging.info('GPIO enabled (lamp_pin=%d, trigger_pin=%d, exit_pin=%d)',
|
||||||
|
lamp_pin, trigger_pin, exit_pin)
|
||||||
|
|
||||||
from Gpio import Gpio
|
from Gpio import Gpio
|
||||||
|
|
||||||
self._gpio = Gpio()
|
self._gpio = Gpio()
|
||||||
|
|
||||||
lamp = self._gpio.setLamp(config.getInt('Gpio', 'lamp_pin'))
|
lamp = self._gpio.setLamp(lamp_pin)
|
||||||
self._lampOn = lambda : self._gpio.lampOn(lamp)
|
self._lampOn = lambda : self._gpio.lampOn(lamp)
|
||||||
self._lampOff = lambda : self._gpio.lampOff(lamp)
|
self._lampOff = lambda : self._gpio.lampOff(lamp)
|
||||||
|
|
||||||
self._gpio.setButton(config.getInt('Gpio', 'trigger_pin'), self.gpioTrigger)
|
self._gpio.setButton(triger_pin, self.gpioTrigger)
|
||||||
self._gpio.setButton(config.getInt('Gpio', 'exit_pin'), self.gpioExit)
|
self._gpio.setButton(exit_pin, self.gpioExit)
|
||||||
else:
|
else:
|
||||||
self._lampOn = lambda : None
|
self._lampOn = lambda : None
|
||||||
self._lampOff = lambda : None
|
self._lampOff = lambda : None
|
||||||
@@ -71,7 +75,7 @@ class Photobooth:
|
|||||||
|
|
||||||
def teardown(self):
|
def teardown(self):
|
||||||
|
|
||||||
print('Camera teardown')
|
logging.info('Teardown of camera')
|
||||||
self.triggerOff()
|
self.triggerOff()
|
||||||
self.setCameraIdle()
|
self.setCameraIdle()
|
||||||
|
|
||||||
@@ -83,7 +87,7 @@ class Photobooth:
|
|||||||
try:
|
try:
|
||||||
event_idx = expected.index(str(event))
|
event_idx = expected.index(str(event))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
print('Photobooth: Unknown event received: ' + str(event))
|
logging.error('Unknown event received: %s', str(event))
|
||||||
raise ValueError('Unknown event received', str(event))
|
raise ValueError('Unknown event received', str(event))
|
||||||
|
|
||||||
return event_idx
|
return event_idx
|
||||||
@@ -94,7 +98,7 @@ class Photobooth:
|
|||||||
events = ['ack', 'cancel', 'teardown']
|
events = ['ack', 'cancel', 'teardown']
|
||||||
|
|
||||||
if self.recvEvent(events) != 0:
|
if self.recvEvent(events) != 0:
|
||||||
print('Teardown of Photobooth requested')
|
logging.info('Teardown of camera requested')
|
||||||
raise TeardownException()
|
raise TeardownException()
|
||||||
|
|
||||||
|
|
||||||
@@ -103,16 +107,10 @@ class Photobooth:
|
|||||||
events = ['triggered', 'teardown']
|
events = ['triggered', 'teardown']
|
||||||
|
|
||||||
if self.recvEvent(events) != 0:
|
if self.recvEvent(events) != 0:
|
||||||
print('Teardown of Photobooth requested')
|
logging.info('Teardown of camera requested')
|
||||||
raise TeardownException()
|
raise TeardownException()
|
||||||
|
|
||||||
|
|
||||||
# @property
|
|
||||||
# def getNextFilename(self):
|
|
||||||
|
|
||||||
# return self._get_next_filename
|
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def showCounter(self):
|
def showCounter(self):
|
||||||
|
|
||||||
@@ -140,7 +138,7 @@ class Photobooth:
|
|||||||
try:
|
try:
|
||||||
self.trigger()
|
self.trigger()
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
print('Camera error: ' + str(e))
|
logging.error('Camera error: %s', str(e))
|
||||||
self._conn.send( gui.ErrorState('Camera error', str(e)) )
|
self._conn.send( gui.ErrorState('Camera error', str(e)) )
|
||||||
self.recvAck()
|
self.recvAck()
|
||||||
|
|
||||||
@@ -175,7 +173,6 @@ class Photobooth:
|
|||||||
|
|
||||||
self._conn.send(gui.CountdownState())
|
self._conn.send(gui.CountdownState())
|
||||||
self.recvAck()
|
self.recvAck()
|
||||||
print('ack received')
|
|
||||||
|
|
||||||
|
|
||||||
def showPose(self):
|
def showPose(self):
|
||||||
@@ -209,11 +206,13 @@ class Photobooth:
|
|||||||
def enqueueWorkerTasks(self, picture):
|
def enqueueWorkerTasks(self, picture):
|
||||||
|
|
||||||
for task in self._worker_list:
|
for task in self._worker_list:
|
||||||
self._queue.put(( task.do, (picture, ) ))
|
self._queue.put(task.get(picture))
|
||||||
|
|
||||||
|
|
||||||
def trigger(self):
|
def trigger(self):
|
||||||
|
|
||||||
|
logging.info('Photobooth triggered')
|
||||||
|
|
||||||
self._conn.send(gui.GreeterState())
|
self._conn.send(gui.GreeterState())
|
||||||
self.triggerOff()
|
self.triggerOff()
|
||||||
self.setCameraActive()
|
self.setCameraActive()
|
||||||
@@ -224,7 +223,6 @@ class Photobooth:
|
|||||||
self._conn.send(gui.AssembleState())
|
self._conn.send(gui.AssembleState())
|
||||||
|
|
||||||
img = self.assemblePictures(pics)
|
img = self.assemblePictures(pics)
|
||||||
# img.save(self.getNextFilename(), 'JPEG')
|
|
||||||
self._conn.send(gui.PictureState(img))
|
self._conn.send(gui.PictureState(img))
|
||||||
|
|
||||||
self.enqueueWorkerTasks(img)
|
self.enqueueWorkerTasks(img)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import os
|
import os, logging
|
||||||
|
|
||||||
from glob import glob
|
from glob import glob
|
||||||
|
|
||||||
@@ -43,11 +43,13 @@ class PictureList:
|
|||||||
else:
|
else:
|
||||||
pictures.sort()
|
pictures.sort()
|
||||||
last_picture = pictures[-1]
|
last_picture = pictures[-1]
|
||||||
self.counter = int(last_picture[-(self.count_width+len(self.suffix)):-len(self.suffix)])
|
self.counter = int(last_picture[
|
||||||
|
-(self.count_width+len(self.suffix)):-len(self.suffix)])
|
||||||
|
|
||||||
# Print initial infos
|
# Print initial infos
|
||||||
print('Info: Number of last existing file: ' + str(self.counter))
|
logging.info('Number of last existing file: %d', self.counter)
|
||||||
print('Info: Saving assembled pictures as: ' + self.basename + (self.count_width * 'X') + '.jpg')
|
logging.info('Saving assembled pictures as "%s%s.%s"', self.basename,
|
||||||
|
self.count_width * 'X', 'jpg')
|
||||||
|
|
||||||
|
|
||||||
def getFilename(self, count):
|
def getFilename(self, count):
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
from time import localtime, strftime
|
from time import localtime, strftime
|
||||||
|
|
||||||
from .PictureList import PictureList
|
from .PictureList import PictureList
|
||||||
@@ -13,7 +15,7 @@ class WorkerTask:
|
|||||||
assert not kwargs
|
assert not kwargs
|
||||||
|
|
||||||
|
|
||||||
def do(self, picture):
|
def get(self, picture):
|
||||||
|
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
@@ -25,21 +27,20 @@ class PictureSaver(WorkerTask):
|
|||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
picture_basename = strftime(config.get('Picture', 'basename'), localtime())
|
basename = strftime(config.get('Picture', 'basename'), localtime())
|
||||||
self._pic_list = PictureList(picture_basename)
|
self._pic_list = PictureList(basename)
|
||||||
self._get_next_filename = self._pic_list.getNext
|
|
||||||
|
|
||||||
|
|
||||||
@property
|
@staticmethod
|
||||||
def getNextFilename(self):
|
def do(picture, filename):
|
||||||
|
|
||||||
return self._get_next_filename
|
logging.info('Saving picture as %s', filename)
|
||||||
|
picture.save(filename, 'JPEG')
|
||||||
|
|
||||||
|
|
||||||
def do(self, picture):
|
def get(self, picture):
|
||||||
|
|
||||||
print('saving picture')
|
return (self.do, (picture, self._pic_list.getNext()))
|
||||||
picture.save(self.getNextFilename(), 'JPEG')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ class Worker:
|
|||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
|
||||||
for func, args in iter(self._queue.get, ('teardown', None)):
|
for func, args in iter(self._queue.get, 'teardown'):
|
||||||
func(*args)
|
func(*args)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ class CameraGphoto2(Camera):
|
|||||||
self.hasIdle = False
|
self.hasIdle = False
|
||||||
self._isActive = False
|
self._isActive = False
|
||||||
|
|
||||||
|
logging.info('Using python-gphoto2 bindings')
|
||||||
|
|
||||||
self._setupLogging()
|
self._setupLogging()
|
||||||
self._setupCamera()
|
self._setupCamera()
|
||||||
|
|
||||||
@@ -27,14 +29,10 @@ class CameraGphoto2(Camera):
|
|||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
|
|
||||||
self._cap.exit(self._ctxt)
|
self._cap.exit(self._ctxt)
|
||||||
# self.setIdle()
|
|
||||||
|
|
||||||
|
|
||||||
def _setupLogging(self):
|
def _setupLogging(self):
|
||||||
|
|
||||||
logging.basicConfig(
|
|
||||||
format='%(levelname)s: %(name)s: %(message)s',
|
|
||||||
level=logging.ERROR)
|
|
||||||
gp.check_result(gp.use_python_logging())
|
gp.check_result(gp.use_python_logging())
|
||||||
|
|
||||||
|
|
||||||
@@ -67,9 +65,7 @@ class CameraGphoto2(Camera):
|
|||||||
# self.setActive()
|
# self.setActive()
|
||||||
|
|
||||||
text = self._cap.get_summary(self._ctxt)
|
text = self._cap.get_summary(self._ctxt)
|
||||||
print('Summary')
|
logging.info('Camera summary: %s', str(text))
|
||||||
print('=======')
|
|
||||||
print(str(text))
|
|
||||||
|
|
||||||
# self.setIdle()
|
# self.setIdle()
|
||||||
|
|
||||||
|
|||||||
@@ -19,10 +19,7 @@ class CameraGphoto2Cffi(Camera):
|
|||||||
self.hasPreview = True
|
self.hasPreview = True
|
||||||
self.hasIdle = True
|
self.hasIdle = True
|
||||||
|
|
||||||
# Avoid output cluttered
|
logging.info('Using gphoto2-cffi bindings')
|
||||||
logging.basicConfig(
|
|
||||||
format='%(levelname)s: %(name)s: %(message)s',
|
|
||||||
level=logging.CRITICAL)
|
|
||||||
|
|
||||||
self._setupCamera()
|
self._setupCamera()
|
||||||
|
|
||||||
@@ -30,7 +27,7 @@ class CameraGphoto2Cffi(Camera):
|
|||||||
def _setupCamera(self):
|
def _setupCamera(self):
|
||||||
|
|
||||||
self._cap = gp.Camera()
|
self._cap = gp.Camera()
|
||||||
print(self._cap.supported_operations)
|
logging.info('Supported operations: %s', self._cap.supported_operations)
|
||||||
|
|
||||||
if 'raw' in self._cap.config['imgsettings']['imageformat'].value.lower():
|
if 'raw' in self._cap.config['imgsettings']['imageformat'].value.lower():
|
||||||
raise RuntimeError('Camera file format is set to RAW')
|
raise RuntimeError('Camera file format is set to RAW')
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import os, subprocess
|
import os, subprocess, logging
|
||||||
|
|
||||||
from . import Camera
|
from . import Camera
|
||||||
|
|
||||||
@@ -15,9 +15,13 @@ class CameraGphoto2CommandLine(Camera):
|
|||||||
self.hasPreview = False
|
self.hasPreview = False
|
||||||
self.hasIdle = False
|
self.hasIdle = False
|
||||||
|
|
||||||
|
logging.info('Using gphoto2 via command line')
|
||||||
|
|
||||||
if os.access('/dev/shm', os.W_OK):
|
if os.access('/dev/shm', os.W_OK):
|
||||||
|
logging.debug('Storing temp files to "/dev/shm/photobooth.jpg"')
|
||||||
self._tmp_filename = '/dev/shm/photobooth.jpg'
|
self._tmp_filename = '/dev/shm/photobooth.jpg'
|
||||||
else:
|
else:
|
||||||
|
logging.debug('Storing temp files to "/tmp/photobooth.jpg"')
|
||||||
self._tmp_filename = '/tmp/photobooth.jpg'
|
self._tmp_filename = '/tmp/photobooth.jpg'
|
||||||
|
|
||||||
self.setActive()
|
self.setActive()
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
@@ -16,6 +18,8 @@ class CameraOpenCV(Camera):
|
|||||||
self.hasPreview = True
|
self.hasPreview = True
|
||||||
self.hasIdle = True
|
self.hasIdle = True
|
||||||
|
|
||||||
|
logging.info('Using OpenCV')
|
||||||
|
|
||||||
self._cap = cv2.VideoCapture()
|
self._cap = cv2.VideoCapture()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QMessageBox
|
from PyQt5.QtWidgets import QMessageBox
|
||||||
|
|
||||||
from .. import printer
|
from .. import printer
|
||||||
@@ -19,6 +21,11 @@ class GuiPostprocess:
|
|||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
def confirm(self, picture):
|
||||||
|
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PrintPostprocess(GuiPostprocess):
|
class PrintPostprocess(GuiPostprocess):
|
||||||
@@ -33,17 +40,15 @@ class PrintPostprocess(GuiPostprocess):
|
|||||||
|
|
||||||
def get(self, picture):
|
def get(self, picture):
|
||||||
|
|
||||||
return PrintState(lambda : self.do(picture))
|
return PrintState(lambda : self.do(picture), False)
|
||||||
|
|
||||||
# reply = QMessageBox.question(parent, 'Print?',
|
|
||||||
# 'Do you want to print the picture?',
|
|
||||||
# QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
|
|
||||||
|
|
||||||
# if reply == QMessageBox.Yes:
|
def confirm(self, picture):
|
||||||
# self._printer.print(picture)
|
|
||||||
|
return PrintState(lambda : None, True)
|
||||||
|
|
||||||
|
|
||||||
def do(self, picture):
|
def do(self, picture):
|
||||||
|
|
||||||
print('Printing')
|
logging.info('Printing picture')
|
||||||
self._printer.print(picture)
|
self._printer.print(picture)
|
||||||
|
|||||||
@@ -147,11 +147,12 @@ class TeardownState(GuiState):
|
|||||||
|
|
||||||
class PrintState(GuiState):
|
class PrintState(GuiState):
|
||||||
|
|
||||||
def __init__(self, handler, **kwargs):
|
def __init__(self, handler, confirmed, **kwargs):
|
||||||
|
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
self.handler = handler
|
self.handler = handler
|
||||||
|
self.confirmed = confirmed
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -167,3 +168,18 @@ class PrintState(GuiState):
|
|||||||
raise ValueError('handler must be callable')
|
raise ValueError('handler must be callable')
|
||||||
|
|
||||||
self._handler = handler
|
self._handler = handler
|
||||||
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def confirmed(self):
|
||||||
|
|
||||||
|
return self._confirmed
|
||||||
|
|
||||||
|
@confirmed.setter
|
||||||
|
def confirmed(self, confirmed):
|
||||||
|
|
||||||
|
if not isinstance(confirmed, bool):
|
||||||
|
raise ValueError('confirmed status must be bool')
|
||||||
|
|
||||||
|
self._confirmed = confirmed
|
||||||
|
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
import multiprocessing as mp
|
import multiprocessing as mp
|
||||||
import queue
|
import queue
|
||||||
|
import logging
|
||||||
|
|
||||||
from PIL import ImageQt
|
from PIL import ImageQt
|
||||||
|
|
||||||
@@ -141,7 +142,6 @@ class PyQt5Gui(Gui):
|
|||||||
elif isinstance(state, PictureState):
|
elif isinstance(state, PictureState):
|
||||||
img = ImageQt.ImageQt(state.picture)
|
img = ImageQt.ImageQt(state.picture)
|
||||||
self._p.setCentralWidget(PyQt5PictureMessage('', img))
|
self._p.setCentralWidget(PyQt5PictureMessage('', img))
|
||||||
# QTimer.singleShot(cfg.getInt('Photobooth', 'display_time') * 1000, self.sendAck)
|
|
||||||
QTimer.singleShot(cfg.getInt('Photobooth', 'display_time') * 1000,
|
QTimer.singleShot(cfg.getInt('Photobooth', 'display_time') * 1000,
|
||||||
lambda : self.postprocessPicture(state.picture))
|
lambda : self.postprocessPicture(state.picture))
|
||||||
|
|
||||||
@@ -179,6 +179,8 @@ class PyQt5Gui(Gui):
|
|||||||
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
|
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
|
||||||
if reply == QMessageBox.Yes:
|
if reply == QMessageBox.Yes:
|
||||||
task.handler()
|
task.handler()
|
||||||
|
QMessageBox.information(self._p, 'Printing',
|
||||||
|
'Picture sent to printer.', QMessageBox.Ok)
|
||||||
else:
|
else:
|
||||||
raise ValueError('Unknown task')
|
raise ValueError('Unknown task')
|
||||||
|
|
||||||
@@ -217,9 +219,9 @@ class PyQt5Gui(Gui):
|
|||||||
|
|
||||||
def showError(self, title, message):
|
def showError(self, title, message):
|
||||||
|
|
||||||
print('ERROR: ' + title + ': ' + message)
|
logging.error('%s: %s', title, message)
|
||||||
reply = QMessageBox.warning(self._p, title, message, QMessageBox.Close | QMessageBox.Retry,
|
reply = QMessageBox.warning(self._p, title, message,
|
||||||
QMessageBox.Retry)
|
QMessageBox.Close | QMessageBox.Retry, QMessageBox.Retry)
|
||||||
if reply == QMessageBox.Retry:
|
if reply == QMessageBox.Retry:
|
||||||
self.sendAck()
|
self.sendAck()
|
||||||
self._lastState()
|
self._lastState()
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ try:
|
|||||||
except DistributionNotFound:
|
except DistributionNotFound:
|
||||||
__version__ = 'unknown'
|
__version__ = 'unknown'
|
||||||
|
|
||||||
import multiprocessing as mp
|
|
||||||
import sys
|
import sys
|
||||||
|
import multiprocessing as mp
|
||||||
|
import logging
|
||||||
|
|
||||||
from . import camera, gui
|
from . import camera, gui
|
||||||
from .Config import Config
|
from .Config import Config
|
||||||
@@ -44,7 +45,7 @@ class CameraProcess(mp.Process):
|
|||||||
if str(event) in ('cancel', 'ack'):
|
if str(event) in ('cancel', 'ack'):
|
||||||
return 123
|
return 123
|
||||||
else:
|
else:
|
||||||
print('Unknown event received: ' + str(event))
|
logging.error('Unknown event received: %s', str(event))
|
||||||
raise RuntimeError('Unknown event received', str(event))
|
raise RuntimeError('Unknown event received', str(event))
|
||||||
|
|
||||||
|
|
||||||
@@ -56,10 +57,11 @@ class CameraProcess(mp.Process):
|
|||||||
event = self.conn.recv()
|
event = self.conn.recv()
|
||||||
|
|
||||||
if str(event) != 'start':
|
if str(event) != 'start':
|
||||||
|
logging.warning('Unknown event received: %s', str(event))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
status_code = self.run_camera()
|
status_code = self.run_camera()
|
||||||
print('Camera exit: ', str(status_code))
|
logging.info('Camera exited with status code %d', status_code)
|
||||||
|
|
||||||
sys.exit(status_code)
|
sys.exit(status_code)
|
||||||
|
|
||||||
@@ -100,13 +102,16 @@ class GuiProcess(mp.Process):
|
|||||||
|
|
||||||
def run(argv):
|
def run(argv):
|
||||||
|
|
||||||
print('Photobooth version:', __version__)
|
logging.info('Photobooth version: %s', __version__)
|
||||||
|
|
||||||
|
# Load configuration
|
||||||
config = Config('photobooth.cfg')
|
config = Config('photobooth.cfg')
|
||||||
|
|
||||||
|
# Create communication objects
|
||||||
gui_conn, camera_conn = mp.Pipe()
|
gui_conn, camera_conn = mp.Pipe()
|
||||||
worker_queue = mp.SimpleQueue()
|
worker_queue = mp.SimpleQueue()
|
||||||
|
|
||||||
|
# Initialize processes
|
||||||
camera_proc = CameraProcess(config, camera_conn, worker_queue)
|
camera_proc = CameraProcess(config, camera_conn, worker_queue)
|
||||||
camera_proc.start()
|
camera_proc.start()
|
||||||
|
|
||||||
@@ -116,11 +121,13 @@ def run(argv):
|
|||||||
gui_proc = GuiProcess(argv, config, gui_conn, worker_queue)
|
gui_proc = GuiProcess(argv, config, gui_conn, worker_queue)
|
||||||
gui_proc.start()
|
gui_proc.start()
|
||||||
|
|
||||||
|
# Close endpoints
|
||||||
gui_conn.close()
|
gui_conn.close()
|
||||||
camera_conn.close()
|
camera_conn.close()
|
||||||
gui_proc.join()
|
|
||||||
|
|
||||||
worker_queue.put(('teardown', None))
|
# Wait for processes to finish
|
||||||
|
gui_proc.join()
|
||||||
|
worker_queue.put('teardown')
|
||||||
worker_proc.join()
|
worker_proc.join()
|
||||||
camera_proc.join(5)
|
camera_proc.join(5)
|
||||||
return gui_proc.exitcode
|
return gui_proc.exitcode
|
||||||
@@ -128,6 +135,9 @@ def run(argv):
|
|||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
|
|
||||||
|
logging.basicConfig(filename='photobooth.log', level=logging.INFO)
|
||||||
|
logging.getLogger().addHandler(logging.StreamHandler())
|
||||||
|
|
||||||
known_status_codes = {
|
known_status_codes = {
|
||||||
999: 'Initializing photobooth',
|
999: 'Initializing photobooth',
|
||||||
123: 'Restarting photobooth and reloading config'
|
123: 'Restarting photobooth and reloading config'
|
||||||
@@ -136,8 +146,10 @@ def main(argv):
|
|||||||
status_code = 999
|
status_code = 999
|
||||||
|
|
||||||
while status_code in known_status_codes:
|
while status_code in known_status_codes:
|
||||||
print(known_status_codes[status_code])
|
logging.info(known_status_codes[status_code])
|
||||||
|
|
||||||
status_code = run(argv)
|
status_code = run(argv)
|
||||||
|
|
||||||
|
logging.info('Exiting photobooth with status code %d', status_code)
|
||||||
|
|
||||||
return status_code
|
return status_code
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
from PIL import ImageQt
|
from PIL import ImageQt
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt, QPoint, QSizeF
|
from PyQt5.QtCore import Qt, QPoint, QSizeF
|
||||||
@@ -18,8 +20,11 @@ class PrinterPyQt5(Printer):
|
|||||||
self._printer = QPrinter(QPrinter.HighResolution)
|
self._printer = QPrinter(QPrinter.HighResolution)
|
||||||
self._printer.setPageSize(QPageSize(QSizeF(*page_size), QPageSize.Millimeter))
|
self._printer.setPageSize(QPageSize(QSizeF(*page_size), QPageSize.Millimeter))
|
||||||
|
|
||||||
|
logging.info('Using printer "%s"', self._printer.printerName())
|
||||||
|
|
||||||
self._print_pdf = print_pdf
|
self._print_pdf = print_pdf
|
||||||
if self._print_pdf:
|
if self._print_pdf:
|
||||||
|
logging.info('Using PDF printer')
|
||||||
self._counter = 0
|
self._counter = 0
|
||||||
self._printer.setOutputFormat(QPrinter.PdfFormat)
|
self._printer.setOutputFormat(QPrinter.PdfFormat)
|
||||||
self._printer.setFullPage(True)
|
self._printer.setFullPage(True)
|
||||||
@@ -32,7 +37,8 @@ class PrinterPyQt5(Printer):
|
|||||||
self._counter += 1
|
self._counter += 1
|
||||||
|
|
||||||
img = ImageQt.ImageQt(picture)
|
img = ImageQt.ImageQt(picture)
|
||||||
img = img.scaled(self._printer.pageRect().size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
img = img.scaled(self._printer.pageRect().size(), Qt.KeepAspectRatio,
|
||||||
|
Qt.SmoothTransformation)
|
||||||
|
|
||||||
printable_size = self._printer.pageRect(QPrinter.DevicePixel)
|
printable_size = self._printer.pageRect(QPrinter.DevicePixel)
|
||||||
origin = ( (printable_size.width() - img.width()) // 2,
|
origin = ( (printable_size.width() - img.width()) // 2,
|
||||||
|
|||||||
Reference in New Issue
Block a user