Пример #1
0
    def do_actions(self, events):
        if self.app.find_print_event(
                events
        ) and self.app.previous_picture_file and self.app.printer.is_installed(
        ):

            if self.app.nbr_printed >= self.app.config.getint(
                    'PRINTER', 'max_duplicates'):
                LOGGER.warning(
                    "Too many duplicates sent to the printer (%s max)",
                    self.app.config.getint('PRINTER', 'max_duplicates'))
                return

            with timeit("Send final picture to printer"):
                self.app.led_print.switch_on()
                self.app.printer.print_file(
                    self.app.previous_picture_file,
                    self.app.config.getint('PRINTER', 'nbr_copies'))

            time.sleep(1)  # Just to let the LED switched on
            self.app.nbr_printed += 1

            if self.app.nbr_printed >= self.app.config.getint(
                    'PRINTER', 'max_duplicates'):
                self.app.window.show_intro(self.app.previous_picture, False)
                self.app.led_print.switch_off()
            else:
                self.app.led_print.blink()

        event = self.app.find_print_status_event(events)
        if event:
            self.app.window.set_print_number(len(event.tasks))
Пример #2
0
    def _post_process_capture(self, capture_data):
        """Rework capture data.

        :param capture_data: couple (frame, effect)
        :type capture_data: tuple
        """
        frame, effect = capture_data

        image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        # Crop to keep aspect ratio of the resolution
        height, width = image.shape[:2]
        cropped = sizing.new_size_by_croping_ratio((width, height),
                                                   self.resolution)
        image = image[cropped[1]:cropped[3], cropped[0]:cropped[2]]
        # Resize to fit the resolution
        height, width = image.shape[:2]
        size = sizing.new_size_keep_aspect_ratio((width, height),
                                                 self.resolution, 'outer')
        image = cv2.resize(image, size, interpolation=cv2.INTER_AREA)

        if self._capture_hflip:
            image = cv2.flip(image, 1)

        if effect != 'none':
            LOGGER.warning("Effect with OpenCV camera is not implemented")

        return Image.fromarray(image)
Пример #3
0
def regenerate_all_images(plugin_manager, config, basepath):
    """Regenerate the pibboth images from the raw images and the config.
    """
    if not osp.isdir(osp.join(basepath, 'raw')):
        return

    capture_choices = config.gettuple('PICTURE', 'captures', int, 2)

    for captures_folder in os.listdir(osp.join(basepath, 'raw')):
        captures_folder_path = osp.join(basepath, 'raw', captures_folder)
        if not osp.isdir(captures_folder_path):
            continue
        captures = get_captures(captures_folder_path)
        LOGGER.info("Generating image from raws in folder %s",
                    captures_folder_path)

        if len(captures) == capture_choices[0]:
            idx = 0
        elif len(captures) == capture_choices[1]:
            idx = 1
        else:
            LOGGER.warning(
                "Folder %s doesn't contain the correct number of pictures",
                captures_folder_path)
            continue

        default_factory = get_picture_factory(
            captures, config.get('PICTURE', 'orientation'))
        factory = plugin_manager.hook.pibooth_setup_picture_factory(
            cfg=config, opt_index=idx, factory=default_factory)

        picture_file = osp.join(basepath, captures_folder + "_pibooth.jpg")
        factory.save(picture_file)
Пример #4
0
 def set_config_value(self, section, option, value):
     """Set camera configuration.
     """
     try:
         LOGGER.debug('Setting option %s/%s=%s', section, option, value)
         config = self._cam.get_config()
         child = config.get_child_by_name(section).get_child_by_name(option)
         if child.get_type() == gp.GP_WIDGET_RADIO:
             choices = [c for c in child.get_choices()]
         else:
             choices = None
         data_type = type(child.get_value())
         value = data_type(value)  # Cast value
         if choices and value not in choices:
             if value == 'Memory card' and 'card' in choices:
                 value = 'card'  # Fix for Sony ZV-1
             elif value == 'Memory card' and 'card+sdram' in choices:
                 value = 'card+sdram'  # Fix for Sony ILCE-6400
             else:
                 LOGGER.warning(
                     "Invalid value '%s' for option %s (possible choices: %s), trying to set it anyway",
                     value, option, choices)
         child.set_value(value)
         self._cam.set_config(config)
     except gp.GPhoto2Error as ex:
         LOGGER.error(
             'Unsupported option %s/%s=%s (%s), configure your DSLR manually',
             section, option, value, ex)
Пример #5
0
def write_exif(filename, capture_nbr, pic_id):
	"""Adding Exif data to image files
	"""
	try:
		im = Image.open(filename)
		exif_dict = piexif.load(filename)
		# process im and exif_dict...
		w, h = im.size
		exif_dict["0th"][piexif.ImageIFD.XResolution] = (w, 1)
		exif_dict["0th"][piexif.ImageIFD.YResolution] = (h, 1)
		exif_dict["0th"][piexif.ImageIFD.Model] = "Fotobox vom Prinsenhof"
		exif_dict["0th"][piexif.ImageIFD.Make] = "Prinsenhof"
		exif_dict["0th"][piexif.ImageIFD.Software] = "pibooth"
		exif_dict["0th"][piexif.ImageIFD.ImageDescription] = "Ein Foto aus der Fotobooth vom Prinsenhof in Porta Westfalica"
		exif_dict["0th"][piexif.ImageIFD.DocumentName] = "Fotobox Image"
		exif_dict["0th"][piexif.ImageIFD.Artist] = "bpw23"
		exif_dict["0th"][piexif.ImageIFD.HostComputer] = "www.prinsenhof.de"
		exif_dict["0th"][piexif.ImageIFD.ImageNumber] = capture_nbr
		exif_dict["0th"][piexif.ImageIFD.Copyright] = "www.prinsenhof.de"
		exif_dict["Exif"][piexif.ExifIFD.ImageUniqueID] = str(pic_id)
		exif_dict["Exif"][piexif.ExifIFD.CameraOwnerName] = "Prinsenhof"
		exif_dict["GPS"][piexif.GPSIFD.GPSLatitudeRef] = "N"
		exif_dict["GPS"][piexif.GPSIFD.GPSLongitudeRef] = "O"		
		#exif_dict["GPS"][piexif.ImageIFD.GPSLatitude] = ()
		#exif_dict["GPS"][piexif.ImageIFD.GPSLongitude] = ()	
		exif_bytes = piexif.dump(exif_dict)
		LOGGER.info("EXIF: adding metadata to image file")
		im.save(filename, "jpeg", exif=exif_bytes)
	except Exception as e:
		LOGGER.warning(f"EXIF: couldn't add exif informations to picture [{e}]")
Пример #6
0
    def __init__(self, filename, clear=False):
        ConfigParser.__init__(self)
        self.filename = osp.abspath(osp.expanduser(filename))

        if not osp.isfile(self.filename) or clear:
            LOGGER.info("Generate the configuration file in '%s'",
                        self.filename)
            dirname = osp.dirname(self.filename)
            if not osp.isdir(dirname):
                os.makedirs(dirname)
            generate_default_config(self.filename)

        self.read(self.filename)

        # Handle the language configuration, save it as a class attribute for easy access
        path = osp.join(osp.dirname(osp.abspath(__file__)), 'pictures')
        possibles = [
            name for name in os.listdir(path)
            if osp.isdir(osp.join(path, name))
        ]
        language = self.get('GENERAL', 'language')
        if language not in possibles:
            LOGGER.warning("Unsupported language '%s', fallback to English",
                           language)
            PtbConfigParser.language = 'en'
        else:
            PtbConfigParser.language = language
Пример #7
0
 def set_config_value(self, section, option, value):
     """Set camera configuration. This method don't send the updated
     configuration to the camera (avoid connection flooding if several
     values have to be changed)
     """
     try:
         LOGGER.debug('Setting option %s/%s=%s', section, option, value)
         config = self._cam.get_config()
         child = config.get_child_by_name(section).get_child_by_name(option)
         if child.get_type() == gp.GP_WIDGET_RADIO:
             choices = [c for c in child.get_choices()]
         else:
             choices = None
         data_type = type(child.get_value())
         value = data_type(value)  # Cast value
         if choices and value not in choices:
             LOGGER.warning(
                 "Invalid value '%s' for option %s (possible choices: %s), trying to set it anyway",
                 value, option, choices)
         child.set_value(value)
         self._cam.set_config(config)
     except gp.GPhoto2Error as ex:
         LOGGER.error(
             'Unsupported option %s/%s=%s (%s), configure your DSLR manually',
             section, option, value, ex)
Пример #8
0
    def _get_authorized_session(self):
        """Create credentials file if required and open a new session."""
        if not os.path.exists(self.credentials_file) or \
                os.path.getsize(self.credentials_file) == 0:
            self._credentials = self._auth()
            LOGGER.debug(
                "First use of pibooth-google-photo: generate credentials file %s",
                self.credentials_file)
            try:
                self._save_credentials(self._credentials)
            except OSError as err:
                LOGGER.warning(
                    "Can not save Google Photos credentials in '%s': %s",
                    self.credentials_file, err)
        else:
            try:
                self._credentials = Credentials.from_authorized_user_file(
                    self.credentials_file, self.SCOPES)
                if self._credentials.expired:
                    self._credentials.refresh(Request())
                    self._save_credentials(self._credentials)
            except ValueError:
                LOGGER.debug(
                    "Error loading Google Photos OAuth tokens: incorrect format"
                )

        if self._credentials:
            return AuthorizedSession(self._credentials)
        return None
Пример #9
0
def regenerate_all_images(config):

    captures_folders = config.getpath('GENERAL', 'directory')
    capture_choices = config.gettuple('PICTURE', 'captures', int)

    # Part that fetch the captures
    for captures_folder in os.listdir(osp.join(captures_folders, 'raw')):
        captures_folder_path = osp.join(captures_folders, 'raw',
                                        captures_folder)
        captures = get_captures(captures_folder_path)
        LOGGER.info("Generating image from raws in folder %s" %
                    (captures_folder_path))
        backgrounds = config.gettuple('PICTURE', 'backgrounds',
                                      ('color', 'path'), 2)
        if len(captures) == capture_choices[0]:
            background = backgrounds[0]
        elif len(captures) == capture_choices[1]:
            background = backgrounds[1]
        else:
            LOGGER.warning(
                "Folder %s doesn't contain the correct number of pictures" %
                captures_folder_path)
            continue

        overlays = config.gettuple('PICTURE', 'overlays', 'path', 2)
        if len(captures) == capture_choices[0]:
            overlay = overlays[0]
        else:
            overlay = overlays[1]

        texts = [
            config.get('PICTURE', 'footer_text1').strip('"'),
            config.get('PICTURE', 'footer_text2').strip('"')
        ]
        colors = config.gettuple('PICTURE', 'text_colors', 'color', len(texts))
        text_fonts = config.gettuple('PICTURE', 'text_fonts', str, len(texts))
        alignments = config.gettuple('PICTURE', 'text_alignments', str,
                                     len(texts))

        def _setup_maker(m):
            m.set_background(background)
            if any(elem != '' for elem in texts):
                for params in zip(texts, text_fonts, colors, alignments):
                    m.add_text(*params)
            if config.getboolean('PICTURE', 'captures_cropping'):
                m.set_cropping()
            if overlay:
                m.set_overlay(overlay)
            if config.getboolean('GENERAL', 'debug'):
                m.set_outlines()

        maker = get_picture_maker(captures,
                                  config.get('PICTURE', 'orientation'),
                                  force_pil=True)
        _setup_maker(maker)

        previous_picture_file = osp.join(captures_folders,
                                         captures_folder + "_pibooth.jpg")
        maker.save(previous_picture_file)
Пример #10
0
 def _is_internet(self):
     """check internet connexion"""
     try:
         requests.get('https://www.google.com/').status_code
         return True
     except requests.ConnectionError:
         LOGGER.warning("No internet connection!!!!")
         return False
 def check_ability_I2C(self):
     """use to disable the plugin if system not able to use I2C like raspberry pi
     """
     try:
         super().__init__()
     except ImportError as e:
         self._DISABLE = True
         LOGGER.warning(
             "System not support I2C, 'Pimoroni11x7' plugins is disable")
Пример #12
0
    def do_actions(self, events):
        if self.app.config.getboolean(
                'WINDOW', 'animate'
        ) and self.app.previous_animated and self.timer.is_timeout():
            previous_picture = next(self.app.previous_animated)
            self.app.window.show_intro(
                previous_picture,
                self.app.printer.is_installed()
                and self.app.nbr_duplicates < self.app.config.getint(
                    'PRINTER', 'max_duplicates')
                and not self.app.printer_unavailable)
            self.timer.start()
        else:
            previous_picture = self.app.previous_picture

        if self.app.find_print_event(events) and self.app.previous_picture_file and self.app.printer.is_installed()\
                and not (self.final_display_timer and self.final_display_timer.is_timeout()):

            if self.app.nbr_duplicates >= self.app.config.getint(
                    'PRINTER', 'max_duplicates'):
                LOGGER.warning(
                    "Too many duplicates sent to the printer (%s max)",
                    self.app.config.getint('PRINTER', 'max_duplicates'))
                return

            elif self.app.printer_unavailable:
                LOGGER.warning(
                    "Maximum number of printed pages reached (%s/%s max)",
                    self.app.printer.nbr_printed,
                    self.app.config.getint('PRINTER', 'max_pages'))
                return

            with timeit("Send final picture to printer"):
                self.app.led_print.switch_on()
                self.app.printer.print_file(
                    self.app.previous_picture_file,
                    self.app.config.getint('PRINTER', 'pictures_per_page'))

            time.sleep(1)  # Just to let the LED switched on
            self.app.nbr_duplicates += 1

            if self.app.nbr_duplicates >= self.app.config.getint(
                    'PRINTER',
                    'max_duplicates') or self.app.printer_unavailable:
                self.app.window.show_intro(previous_picture, False)
                self.app.led_print.switch_off()
            else:
                self.app.led_print.blink()

        event = self.app.find_print_status_event(events)
        if event:
            self.app.window.set_print_number(len(event.tasks),
                                             self.app.printer_unavailable)

        if self.final_display_timer and self.final_display_timer.is_timeout():
            self.app.window.show_intro(None, False)
Пример #13
0
def regenerate_all_images(config):
    """Regenerate the pibboth images from the raw images and the config
    """
    captures_folders = config.getpath('GENERAL', 'directory')
    capture_choices = config.gettuple('PICTURE', 'captures', int, 2)

    backgrounds = config.gettuple('PICTURE', 'backgrounds', ('color', 'path'),
                                  2)
    overlays = config.gettuple('PICTURE', 'overlays', 'path', 2)

    texts = [
        config.get('PICTURE', 'footer_text1').strip('"'),
        config.get('PICTURE', 'footer_text2').strip('"')
    ]
    colors = config.gettuple('PICTURE', 'text_colors', 'color', len(texts))
    text_fonts = config.gettuple('PICTURE', 'text_fonts', str, len(texts))
    alignments = config.gettuple('PICTURE', 'text_alignments', str, len(texts))

    # Part that fetch the captures
    for captures_folder in os.listdir(osp.join(captures_folders, 'raw')):
        captures_folder_path = osp.join(captures_folders, 'raw',
                                        captures_folder)
        if not osp.isdir(captures_folder_path):
            continue
        captures = get_captures(captures_folder_path)
        LOGGER.info("Generating image from raws in folder %s",
                    captures_folder_path)

        if len(captures) == capture_choices[0]:
            overlay = overlays[0]
            background = backgrounds[0]
        elif len(captures) == capture_choices[1]:
            overlay = overlays[1]
            background = backgrounds[1]
        else:
            LOGGER.warning(
                "Folder %s doesn't contain the correct number of pictures",
                captures_folder_path)
            continue

        factory = get_picture_factory(captures,
                                      config.get('PICTURE', 'orientation'))

        factory.set_background(background)
        if any(elem != '' for elem in texts):
            for params in zip(texts, text_fonts, colors, alignments):
                factory.add_text(*params)
        if config.getboolean('PICTURE', 'captures_cropping'):
            factory.set_cropping()
        if overlay:
            factory.set_overlay(overlay)

        picture_file = osp.join(captures_folders,
                                captures_folder + "_pibooth.jpg")
        factory.save(picture_file)
Пример #14
0
    def initialize(self):
        """Restore the application with initial parameters defined in the
        configuration file.
        Only parameters that can be changed at runtime are restored.
        """
        # Handle the language configuration
        language.CURRENT = self.config.get('GENERAL', 'language')
        fonts.CURRENT = fonts.get_filename(
            self.config.gettuple('PICTURE', 'text_fonts', str)[0])

        # Set the captures choices
        choices = self.config.gettuple('PICTURE', 'captures', int)
        for chx in choices:
            if chx not in [1, 2, 3, 4]:
                LOGGER.warning(
                    "Invalid captures number '%s' in config, fallback to '%s'",
                    chx, self.capture_choices)
                choices = self.capture_choices
                break
        self.capture_choices = choices

        # Reset printed pages number
        self.printer.nbr_printed = 0

        # Handle autostart of the application
        self.config.enable_autostart(
            self.config.getboolean('GENERAL', 'autostart'))

        self.window.arrow_location = self.config.get('WINDOW', 'arrows')
        self.window.arrow_offset = self.config.getint('WINDOW',
                                                      'arrows_x_offset')
        self.window.drop_cache()

        # Handle window size
        size = self.config.gettyped('WINDOW', 'size')
        if isinstance(size, str) and size.lower() == 'fullscreen':
            if not self.window.is_fullscreen:
                self.window.toggle_fullscreen()
        else:
            if self.window.is_fullscreen:
                self.window.toggle_fullscreen()
        self.window.debug = self.config.getboolean('GENERAL', 'debug')

        # Handle debug mode
        if not self.config.getboolean('GENERAL', 'debug'):
            set_logging_level()  # Restore default level
            self.state_machine.add_failsafe_state(StateFailSafe(2))
        else:
            set_logging_level(logging.DEBUG)
            self.state_machine.remove_state('failsafe')

        # Initialize state machine
        self.state_machine.set_state('wait')
Пример #15
0
 def synchronize_pics(self, local_rep, rep_event):
     """ Upload Photos to Nextcloud
     """
     if (self.is_connected == False):
         LOGGER.warning("Synchronize No internet connection")
     else:
         #Syncho repertoire nextcloud / upload
         USER_NC = self.nuser
         PASS_NC = self.npassword
         LOCAL_PATH_NC = local_rep
         REMOTE_PATH_NC = self.nhost + "/remote.php/webdav/" + rep_event
         nextcloudcmd = "nextcloudcmd" + " -u " + USER_NC + " -p " + PASS_NC + " -s  " + LOCAL_PATH_NC + " " + REMOTE_PATH_NC
         os.system(nextcloudcmd)
Пример #16
0
 def capture(self, effect=None):
     """Capture a new picture.
     """
     retry = 0
     max_retry = 2
     while retry < max_retry:
         try:
             return super(GpCameraRetry, self).capture(effect)
         except Exception:
             LOGGER.warning("Gphoto2 fails to capture, trying again...")
         retry += 1
     raise EnvironmentError(
         "Gphoto2 fails to capture {} times".format(max_retry))
Пример #17
0
    def initialize(self):
        """Restore the application with initial parameters defined in the
        configuration file.
        Only parameters that can be changed at runtime are restored.
        """
        # Handle the language configuration, save it as a class attribute for easy access
        language = self.config.get('GENERAL', 'language')
        if language not in get_supported_languages():
            LOGGER.warning("Unsupported language '%s', fallback to English",
                           language)
        else:
            PiConfigParser.language = language

        # Set the captures choices
        choices = self.config.gettuple('PICTURE', 'captures', int)
        for chx in choices:
            if chx not in [1, 2, 3, 4]:
                LOGGER.warning(
                    "Invalid captures number '%s' in config, fallback to '%s'",
                    chx, self.capture_choices)
                choices = self.capture_choices
                break
        self.capture_choices = choices

        # Reset printed pages number
        self.printer.nbr_printed = 0

        # Handle autostart of the application
        self.config.enable_autostart(
            self.config.getboolean('GENERAL', 'autostart'))

        self.window.arrow_location = self.config.get('WINDOW', 'arrows')
        self.window.arrow_offset = self.config.getint('WINDOW',
                                                      'arrows_x_offset')
        self.window.drop_cache()

        # Handle window size
        size = self.config.gettyped('WINDOW', 'size')
        if isinstance(size, str) and size.lower() == 'fullscreen':
            if not self.window.is_fullscreen:
                self.window.toggle_fullscreen()
        else:
            if self.window.is_fullscreen:
                self.window.toggle_fullscreen()

        # Initialize state machine
        if self.config.getboolean('GENERAL', 'failsafe'):
            self.state_machine.add_failsafe_state(StateFailSafe(2))
        else:
            self.state_machine.remove_state('failsafe')
        self.state_machine.set_state('wait')
Пример #18
0
    def _initialize(self):
        """Camera initialisation
        """
        self._cam = gp.Camera()
        self._cam.init()

        try:
            self.get_config_value('actions', 'viewfinder')
            self._preview_compatible = True
        except ValueError:
            LOGGER.warning("The connected DSLR camera is not compatible with preview")
            self._preview_compatible = False
        self.set_config_value('imgsettings', 'iso', self._iso)
        self.set_config_value('settings', 'capturetarget', 'Memory card')
Пример #19
0
    def reload(self):
        """Reload current configuration file.
        """
        self.read(self.filename)

        # Handle the language configuration, save it as a class attribute for easy access
        language = self.get('GENERAL', 'language')
        if language not in get_supported_languages():
            LOGGER.warning("Unsupported language '%s', fallback to English", language)
        else:
            PiConfigParser.language = language

        # Handle autostart of the application
        self.enable_autostart(self.getboolean('GENERAL', 'autostart'))
Пример #20
0
    def state_wait_do(self, cfg, app, events):
        if app.find_print_event(events) and app.previous_picture_file and app.printer.is_installed():

            if app.count.remaining_duplicates <= 0:
                LOGGER.warning("Too many duplicates sent to the printer (%s max)",
                               cfg.getint('PRINTER', 'max_duplicates'))
                return

            elif not app.printer.is_ready():
                LOGGER.warning("Maximum number of printed pages reached (%s/%s max)", app.count.printed,
                               cfg.getint('PRINTER', 'max_pages'))
                return

            self.print_picture(cfg, app)
Пример #21
0
 def _set_config_value(self, section, option, value):
     """Set camera configuration. This method dont send the updated
     configuration to the camera (avoid connection flooding if several
     values to be changed)
     """
     try:
         LOGGER.debug('Setting option %s/%s=%s', section, option, value)
         child = self._config.get_child_by_name(section).get_child_by_name(option)
         choices = [c for c in child.get_choices()]
         if not choices or value in choices:
             child.set_value(str(value))
         else:
             LOGGER.warning("Invalid value '%s' for option %s (possible choices: %s)", value, option, choices)
     except gp.GPhoto2Error:
         raise ValueError('Unsupported setting {}/{}={}'.format(section, option, value))
Пример #22
0
    def __init__(self, name='default'):
        self._conn = cups.Connection() if cups else None
        self._notif_server = NotificationServer(self._conn)
        self.name = None
        if not cups:
            LOGGER.warning("No printer found (pycups not installed)")
            return  # CUPS is not installed
        elif not name or name.lower() == 'default':
            self.name = self._conn.getDefault()
            if not self.name and self._conn.getPrinters():
                self.name = list(self._conn.getPrinters().keys())[0]  # Take first one
        elif name in self._conn.getPrinters():
            self.name = name

        if not self.name:
            LOGGER.warning("No printer found (nothing defined in CUPS)")
Пример #23
0
def get_translated_text(key):
    """Return the text corresponding to the key in the language defined in the config.

    :param key: key in the translation file
    :type key: str
    """
    if not getattr(PARSER, 'filename', None):
        raise EnvironmentError("Translation system is not initialized")

    if PARSER.has_section(CURRENT) and PARSER.has_option(CURRENT, key):
        return PARSER.get(CURRENT, key).strip('"')
    elif PARSER.has_option('en', key):
        LOGGER.warning("Unsupported language '%s', fallback to English", CURRENT)
        return PARSER.get('en', key).strip('"')

    LOGGER.debug("No translation defined for '%s/%s' key", CURRENT, key)
    return None
Пример #24
0
    def do_PUT(self):
        """Serve a PUT request.
        """
        chunk_size = self.get_chunk_size()
        if chunk_size == 0:
            LOGGER.warning("Notification without data received")
        else:
            chunk_data = self.get_chunk_data(chunk_size)
            root = ElementTree.fromstring(chunk_data.decode('utf-8'))
            for channel in root.iterfind('channel'):
                for item in reversed([e for e in channel.iterfind('item')]):
                    txt = ElementTree.tostring(item, encoding='utf8')
                    if txt not in NotificationHandler._last_notif:
                        # Print only the new notifications
                        LOGGER.info("%s - %s", item.findtext('pubDate'), item.findtext('title'))
                        NotificationHandler._last_notif.append(txt)

        self.send_response(200)
        self.end_headers()
Пример #25
0
def gp_camera_connected():
    """Return True if a camera compatible with gPhoto2 is found.
    """
    if not gp:
        LOGGER.warning("gphoto2 lib not found!")
        return False  # gPhoto2 is not installed
    if hasattr(gp, 'gp_camera_autodetect'):
        # gPhoto2 version 2.5+
        cameras = gp.check_result(gp.gp_camera_autodetect())
    else:
        port_info_list = gp.PortInfoList()
        port_info_list.load()
        abilities_list = gp.CameraAbilitiesList()
        abilities_list.load()
        cameras = abilities_list.detect(port_info_list)
    if cameras:
        return True

    return False
Пример #26
0
    def _specific_initialization(self):
        """Camera initialization.
        """
        self._gp_logcb = gp.check_result(
            gp.gp_log_add_func(gp.GP_LOG_VERBOSE, gp_log_callback))
        abilities = self._cam.get_abilities()
        self._preview_compatible = gp.GP_OPERATION_CAPTURE_PREVIEW ==\
            abilities.operations & gp.GP_OPERATION_CAPTURE_PREVIEW
        if not self._preview_compatible:
            LOGGER.warning(
                "The connected DSLR camera is not compatible with preview")
        else:
            try:
                self.get_config_value('actions', 'viewfinder')
                self._preview_viewfinder = True
            except ValueError:
                self._preview_viewfinder = False

        self.set_config_value('imgsettings', 'iso', self.preview_iso)
        self.set_config_value('settings', 'capturetarget', 'Memory card')
Пример #27
0
def gp_set_config_value(config, section, option, value):
    """Set camera configuration. This method don't send the updated
    configuration to the camera (avoid connection flooding if several
    values have to be changed)
    """
    try:
        value = GP_PARAMS.get(PiConfigParser.language, 'en').get(value, value)
        LOGGER.debug('Setting option %s/%s=%s', section, option, value)
        child = config.get_child_by_name(section).get_child_by_name(option)
        choices = [c for c in child.get_choices()]
        if value not in choices:
            LOGGER.warning(
                "Invalid value '%s' for option %s (possible choices: %s), still trying to set it",
                value, option, choices)
            child.set_value(str(value))
        else:
            child.set_value(str(value))
    except gp.GPhoto2Error:
        raise ValueError('Unsupported setting {}/{}={}'.format(
            section, option, value))
Пример #28
0
    def do_PUT(self):
        """Serve a PUT request and trasfert event to server callback.
        """
        chunk_size = self.get_chunk_size()
        if chunk_size == 0:
            LOGGER.warning("Notification without data received")
        else:
            chunk_data = self.get_chunk_data(chunk_size)
            root = ElementTree.fromstring(chunk_data.decode('utf-8'))
            for channel in root.iterfind('channel'):
                for item in reversed([e for e in channel.iterfind('item')]):
                    txt = ElementTree.tostring(item, encoding='utf8')
                    if txt not in NotificationHandler._last_notif:
                        NotificationHandler._last_notif.append(txt)
                        self.server.callback(
                            dict((elem.tag, elem.text) for elem in item.iter()
                                 if elem.text.strip()))

        self.send_response(200)
        self.end_headers()
Пример #29
0
    def _initialize(self):
        """Camera initialisation
        """
        self._cam = gp.Camera()
        self._cam.init()

        abilities = self._cam.get_abilities()
        self._preview_compatible = gp.GP_OPERATION_CAPTURE_PREVIEW ==\
            abilities.operations & gp.GP_OPERATION_CAPTURE_PREVIEW
        if not self._preview_compatible:
            LOGGER.warning(
                "The connected DSLR camera is not compatible with preview")
        else:
            try:
                self.get_config_value('actions', 'viewfinder')
                self._preview_viewfinder = True
            except ValueError:
                self._preview_viewfinder = False

        self.set_config_value('imgsettings', 'iso', self.iso_preview)
        self.set_config_value('settings', 'capturetarget', 'Memory card')
Пример #30
0
    def __init__(self, name='default', max_pages=-1):
        self._conn = cups.Connection() if cups else None
        self._notifier = Subscriber(self._conn) if cups else None
        self.name = None
        self.max_pages = max_pages
        self.nbr_printed = 0
        if not cups:
            LOGGER.warning(
                "No printer found (pycups or pycups-notify not installed)")
            return  # CUPS is not installed
        elif not name or name.lower() == 'default':
            self.name = self._conn.getDefault()
            if not self.name and self._conn.getPrinters():
                self.name = list(
                    self._conn.getPrinters().keys())[0]  # Take first one
        elif name in self._conn.getPrinters():
            self.name = name

        if not self.name:
            if name.lower() == 'default':
                LOGGER.warning(
                    "No printer configured in CUPS (see http://localhost:631)")
            else:
                LOGGER.warning(
                    "No printer named '%s' in CUPS (see http://localhost:631)",
                    name)
        else:
            LOGGER.info("Connected to printer '%s'", self.name)