Example #1
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)
Example #2
0
    def set_state(self, state_name):
        """Change state machine's active state
        """
        try:
            # Perform any exit actions of the current state
            if self.active_state is not None:
                self.active_state.exit_actions()
        except Exception as ex:
            if self.failsafe_state and self.active_state != self.failsafe_state:
                LOGGER.error(str(ex))
                if BlockConsoleHandler.is_debug():
                    traceback.print_exc()
                state_name = self.failsafe_state.name
            else:
                raise

        if state_name not in self.states:
            raise ValueError(
                '"{}" not in registered states...'.format(state_name))

        # Switch to the new state and perform its entry actions
        LOGGER.debug("Activate state '%s'", state_name)
        self.active_state = self.states[state_name]

        try:
            self.active_state.entry_actions()
        except Exception as ex:
            if self.failsafe_state and self.active_state != self.failsafe_state:
                LOGGER.error(str(ex))
                if BlockConsoleHandler.is_debug():
                    traceback.print_exc()
                self.set_state(self.failsafe_state.name)
            else:
                raise
Example #3
0
 def _create_or_retrieve_album(self):
     """Find albums created by this app to see if one matches album_title"""
     if self.album_name and self.album_id is None:
         for a in self.get_albums(True):
             if a["title"].lower() == self.album_name.lower():
                 self.album_id = a["id"]
                 LOGGER.info("Uploading into EXISTING photo album -- '%s'",
                             self.album_name)
     if self.album_id is None:
         # No matches, create new album
         create_album_body = json.dumps(
             {"album": {
                 "title": self.album_name
             }})
         # print(create_album_body)
         resp = self.session.post(
             'https://photoslibrary.googleapis.com/v1/albums',
             create_album_body).json()
         LOGGER.debug("Server response: %s", resp)
         if "id" in resp:
             LOGGER.info("Uploading into NEW photo album -- '%s'",
                         self.album_name)
             self.album_id = resp['id']
         else:
             LOGGER.error(
                 "Could not find or create photo album '%s'.\
                          Server Response: %s", self.album_name, resp)
             self.album_id = None
Example #4
0
    def process(self, events):
        """Let the current state do it's thing.
        """
        # Only continue if there is an active state
        if self.active_state is None:
            return

        try:
            # Perform the actions of the active state
            hook = getattr(self.pm.hook, 'state_{}_do'.format(self.active_state))
            hook(cfg=self.cfg, app=self.app, win=self.win, events=events)

            # Check conditions to activate the next state
            hook = getattr(self.pm.hook, 'state_{}_validate'.format(self.active_state))
            new_state_name = hook(cfg=self.cfg, app=self.app, win=self.win, events=events)
        except Exception as ex:
            if self.failsafe_state and self.active_state != self.failsafe_state:
                LOGGER.error(str(ex))
                if BlockConsoleHandler.is_debug():
                    traceback.print_exc()
                new_state_name = self.failsafe_state
            else:
                raise

        if new_state_name is not None:
            self.set_state(new_state_name)
Example #5
0
    def set_state(self, state_name):
        """Change state machine's active state
        """
        try:
            # Perform any exit actions of the current state
            if self.active_state is not None:
                hook = getattr(self.pm.hook, 'state_{}_exit'.format(self.active_state))
                hook(cfg=self.cfg, app=self.app, win=self.win)
        except Exception as ex:
            if self.failsafe_state and self.active_state != self.failsafe_state:
                LOGGER.error(str(ex))
                if BlockConsoleHandler.is_debug():
                    traceback.print_exc()
                state_name = self.failsafe_state
            else:
                raise

        if state_name not in self.states:
            raise ValueError('"{}" not in registered states...'.format(state_name))

        # Switch to the new state and perform its entry actions
        LOGGER.debug("Activate state '%s'", state_name)
        self.active_state = state_name

        try:
            hook = getattr(self.pm.hook, 'state_{}_enter'.format(self.active_state))
            hook(cfg=self.cfg, app=self.app, win=self.win)
        except Exception as ex:
            if self.failsafe_state and self.active_state != self.failsafe_state:
                LOGGER.error(str(ex))
                if BlockConsoleHandler.is_debug():
                    traceback.print_exc()
                self.set_state(self.failsafe_state)
            else:
                raise
Example #6
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)
Example #7
0
    def __init__(self, client_id=None, credentials=None, activate=True):
        """Initialize GoogleUpload instance

        :param client_id: file download from google API
        :type client_id: file
        :param credentials: file create at first run to keep allow API use
        :type credentials: file
        :param activate: use to disable the plugin
        :type activate: bool
        """
        self.scopes = [
            'https://www.googleapis.com/auth/photoslibrary',
            'https://www.googleapis.com/auth/photoslibrary.sharing'
        ]

        # file to store authorization
        self.google_credentials = credentials
        # file with YOUR_CLIENT_ID and YOUR_CLIENT_SECRET generate on google
        self.client_id_file = client_id
        self.credentials = None
        self.session = None
        self.album_id = None
        self.album_name = None
        self.activate = activate
        if not os.path.exists(self.client_id_file) or os.path.getsize(
                self.client_id_file) == 0:
            LOGGER.error(
                "Can't load json file '%s' please check GOOGLE:client_id_file on pibooth config file (DISABLE PLUGIN)",
                self.client_id_file)
            self.activate = False
        if self.activate and self._is_internet():
            self._get_authorized_session()
Example #8
0
    def main_loop(self):
        """Run the main game loop.
        """
        try:
            fps = 40
            clock = pygame.time.Clock()
            self._initialize()
            self._pm.hook.pibooth_startup(cfg=self._config, app=self)
            self._machine.set_state('wait')

            while True:
                events = list(pygame.event.get())

                if self.find_quit_event(events):
                    break

                if self.find_fullscreen_event(events):
                    self._window.toggle_fullscreen()

                event = self.find_resize_event(events)
                if event:
                    self._window.resize(event.size)

                if not self._menu and self.find_settings_event(events):
                    self.camera.stop_preview()
                    self.leds.off()
                    self._menu = PiConfigMenu(self._window, self._config,
                                              self.count)
                    self._menu.show()
                    self.leds.blink(on_time=0.1, off_time=1)
                elif self._menu and self._menu.is_shown():
                    self._menu.process(events)
                elif self._menu and not self._menu.is_shown():
                    self.leds.off()
                    self._initialize()
                    self._machine.set_state('wait')
                    self._menu = None
                else:
                    self._machine.process(events)

                pygame.display.update()
                clock.tick(
                    fps
                )  # Ensure the program will never run at more than <fps> frames per second

        except Exception as ex:
            LOGGER.error(str(ex), exc_info=True)
            LOGGER.error(get_crash_message())
        finally:
            self._pm.hook.pibooth_cleanup(app=self)
            pygame.quit()
Example #9
0
    def create_album(self, album_name):
        """Create a new album and return its ID."""
        LOGGER.info("Creating a new Google Photos album '%s'", album_name)
        create_album_body = json.dumps({"album": {"title": album_name}})

        resp = self._session.post(self.URL + '/albums',
                                  create_album_body).json()
        LOGGER.debug("Google Photos server response: %s", resp)

        if "id" in resp:
            return resp['id']

        LOGGER.error("Can not create Google Photos album '%s'", album_name)
        return None
Example #10
0
 def _on_keyboard_event(self, text):
     """Called after each option changed.
     """
     if self._main_menu.is_enabled():  # Menu may have been closed
         selected = self._main_menu.get_current().get_selected_widget()
         if isinstance(selected, pgm.widgets.TextInput):
             if isinstance(selected, pgm.widgets.ColorInput):
                 try:
                     selected.set_value(tuple([int(c) for c in text.split(',')]))
                 except Exception as ex:
                     LOGGER.error("Invalid color value '%s' (%s)", text, ex)
             else:
                 selected.set_value(text)
             selected.change()
Example #11
0
def pibooth_startup(app, cfg):
    """Create the GooglePhotosUpload instance."""
    app.previous_picture_url = None
    client_id_file = cfg.getpath('GOOGLE', 'client_id_file')

    if not client_id_file:
        LOGGER.debug(
            "No credentials file defined in [GOOGLE][client_id_file], upload deactivated"
        )
    elif not os.path.exists(client_id_file):
        LOGGER.error(
            "No such file [GOOGLE][client_id_file]='%s', please check config",
            client_id_file)
    elif client_id_file and os.path.getsize(client_id_file) == 0:
        LOGGER.error(
            "Empty file [GOOGLE][client_id_file]='%s', please check config",
            client_id_file)
    else:
        app.google_photos = GooglePhotosApi(client_id_file)
Example #12
0
def upload_now(file, crypt_name, url, pwd, app):
    """Upload a file to an ssh server
       param filename: Name and path of local file
       param url: The server address
       param pwd: Password for the user on the server
       """
    upload_status = False
    try:

        with open(file, "rb") as image_file:
            encoded_string = base64.b64encode(image_file.read())
            payload = {'pass': pwd, 'image': encoded_string, 'filename': crypt_name}
        response = requests.post(url, json=payload)
        if response.ok and response.text == 'OK':
            upload_status = True
        else:
            LOGGER.error(response.text.encode('utf8'))
    except Exception as e:
        LOGGER.error("upload failed! " + str(e))

    app.web_upload_sucessful = upload_status
Example #13
0
    def upload_photos(self, local_source_file, album_name, activate):
        """Funtion use to upload list of photos to google album
        :param local_source_file: PAth absolue to loca file to upload
        :type local_source_file: str
        :param album_name: name of albums to upload
        :type album_name: str
        :param activate: use to disable the upload
        :type activate: bool
        """
        self.activate = activate
        # interrupt upload no internet
        if not self._is_internet():
            LOGGER.error("Interrupt upload no internet connexion!!!!")
            return
        # if plugin is disable
        if not self.activate:
            LOGGER.error("Interrupt upload no activated !!!! (%s)",
                         str(self.activate))
            return

        LOGGER.info("In upload_photos Local  (%s)", local_source_file)
        LOGGER.info("In upload_photos Remote  (%s)", album_name)
        if not self.oc.put_file(album_name, local_source_file):
            LOGGER.error("Error while upload file to Nextcloud !!!!")
            return
        else:
            LOGGER.info("Photo upload to Nextcloud !!!!")
Example #14
0
def ftp_upload(filename, uploadpath, serveraddress, user, pwd):
    """Upload a file to an ftp server
    param filename: Name and path of local file
    param uploadpath: Path on the ftp server to store file
    param serveraddress: The server address
    param user: Username for the server
    param pwd: Password for the user on the server 
    """
    ftp_status = False
    ftp = FTP()
    ftp.set_debuglevel(0)
    try:
        ftp.connect(serveraddress, 21)
        ftp.login(user, pwd)
        ftp.cwd(uploadpath)
        fp = open(filename, 'rb')
        ftp.storbinary('STOR %s' % os.path.basename(filename), fp, 1024)
        ftp_status = True
        fp.close()
        ftp.close()
    except Exception as e:
        LOGGER.error("FTP upload failed! " + str(e))
    return ftp_status
Example #15
0
    def process(self, events):
        """Let the current state do it's thing
        """
        # Only continue if there is an active state
        if self.active_state is None:
            return

        try:
            # Perform the actions of the active state
            self.active_state.do_actions(events)

            # Check conditions to activate the next state
            new_state_name = self.active_state.validate_transition(events)
        except Exception as ex:
            if self.failsafe_state and self.active_state != self.failsafe_state:
                LOGGER.error(str(ex))
                if BlockConsoleHandler.is_debug():
                    traceback.print_exc()
                new_state_name = self.failsafe_state.name
            else:
                raise

        if new_state_name is not None:
            self.set_state(new_state_name)
Example #16
0
    def upload_photos(self, photo_file_list, album_name, activate):
        """Funtion use to upload list of photos to google album

        :param photo_file_list: list of photos name with full path
        :type photo_file_list: file
        :param album_name: name of albums to upload
        :type album_name: str
        :param activate: use to disable the upload
        :type activate: bool
        """
        self.activate = activate
        # interrupt upload no internet
        if not self._is_internet():
            LOGGER.error("Interrupt upload no internet connexion!!!!")
            return
        # if plugin is disable
        if not self.activate:
            return
        # plugin is disable at startup but activate after so check credential file
        elif not self.credentials:
            self._get_authorized_session()

        self.album_name = album_name
        self._create_or_retrieve_album()

        # interrupt upload if no album id can't read or create
        if self.album_name and not self.album_id:
            LOGGER.error("Interrupt upload album not found!!!!")
            return

        self.session.headers["Content-type"] = "application/octet-stream"
        self.session.headers["X-Goog-Upload-Protocol"] = "raw"

        for photo_file_name in photo_file_list:

            try:
                photo_file = open(photo_file_name, mode='rb')
                photo_bytes = photo_file.read()
            except OSError as err:
                LOGGER.error("Could not read file '%s' -- %s", photo_file_name,
                             err)
                continue

            self.session.headers["X-Goog-Upload-File-Name"] = os.path.basename(
                photo_file_name)

            LOGGER.info("Uploading photo -- '%s'", photo_file_name)

            upload_token = self.session.post(
                'https://photoslibrary.googleapis.com/v1/uploads', photo_bytes)

            if (upload_token.status_code == 200) and upload_token.content:

                create_body = json.dumps(
                    {
                        "albumId":
                        self.album_id,
                        "newMediaItems": [{
                            "description": "",
                            "simpleMediaItem": {
                                "uploadToken": upload_token.content.decode()
                            }
                        }]
                    },
                    indent=4)

                resp = self.session.post(
                    'https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate',
                    create_body).json()

                LOGGER.debug("Server response: %s", resp)

                if "newMediaItemResults" in resp:
                    status = resp["newMediaItemResults"][0]["status"]
                    if status.get("code") and (status.get("code") > 0):
                        LOGGER.error("Could not add '%s' to library -- %s",
                                     os.path.basename(photo_file_name),
                                     status["message"])
                    else:
                        LOGGER.info("Added '%s' to library and album '%s' ",
                                    os.path.basename(photo_file_name),
                                    album_name)
                else:
                    LOGGER.error(
                        "Could not add '%s' to library. Server Response -- %s",
                        os.path.basename(photo_file_name), resp)

            else:
                LOGGER.error("Could not upload '%s'. Server Response -- %s",
                             os.path.basename(photo_file_name), upload_token)

        try:
            del self.session.headers["Content-type"]
            del self.session.headers["X-Goog-Upload-Protocol"]
            del self.session.headers["X-Goog-Upload-File-Name"]
        except KeyError:
            pass
Example #17
0
    def upload(self, filename, album_name):
        """Upload a photo file to the given Google Photos album.

        :param filename: photo file full path
        :type filename: str
        :param album_name: name of albums to upload
        :type album_name: str

        :returns: URL of the uploaded photo
        :rtype: str
        """
        photo_url = None

        if not self.is_reachable():
            LOGGER.error(
                "Google Photos upload failure: no internet connexion!")
            return photo_url

        if not self._credentials:
            # Plugin was disabled at startup but activated after
            self._session = self._get_authorized_session()

        album_id = self.get_album_id(album_name)
        if not album_id:
            album_id = self.create_album(album_name)
        if not album_id:
            LOGGER.error("Google Photos upload failure: album '%s' not found!",
                         album_name)
            return photo_url

        self._session.headers["Content-type"] = "application/octet-stream"
        self._session.headers["X-Goog-Upload-Protocol"] = "raw"

        with open(filename, mode='rb') as fp:
            data = fp.read()

        self._session.headers["X-Goog-Upload-File-Name"] = os.path.basename(
            filename)

        LOGGER.info("Uploading picture '%s' to Google Photos", filename)
        upload_token = self._session.post(self.URL + '/uploads', data)

        if upload_token.status_code == 200 and upload_token.content:
            create_body = json.dumps({
                "albumId":
                album_id,
                "newMediaItems": [{
                    "description": "",
                    "simpleMediaItem": {
                        "uploadToken": upload_token.content.decode()
                    }
                }]
            })

            resp = self._session.post(self.URL + '/mediaItems:batchCreate',
                                      create_body).json()
            LOGGER.debug("Google Photos server response: %s", resp)

            if "newMediaItemResults" in resp:
                status = resp["newMediaItemResults"][0]["status"]
                if status.get("code") and (status.get("code") > 0):
                    LOGGER.error(
                        "Google Photos upload failure: can not add '%s' to library: %s",
                        os.path.basename(filename), status["message"])
                else:
                    photo_url = resp["newMediaItemResults"][0][
                        'mediaItem'].get('productUrl')
                    LOGGER.info(
                        "Google Photos upload successful: '%s' added to album '%s'",
                        os.path.basename(filename), album_name)
            else:
                LOGGER.error(
                    "Google Photos upload failure: can not add '%s' to library",
                    os.path.basename(filename))

        elif upload_token.status_code != 200:
            LOGGER.error(
                "Google Photos upload failure: can not connect to '%s' (HTTP error %s)",
                self.URL, upload_token.status_code)
        else:
            LOGGER.error(
                "Google Photos upload failure: no response content from server '%s'",
                self.URL)

        try:
            del self._session.headers["Content-type"]
            del self._session.headers["X-Goog-Upload-Protocol"]
            del self._session.headers["X-Goog-Upload-File-Name"]
        except KeyError:
            pass

        return photo_url
Example #18
0
 def state_failsafe_enter(self, win):
     win.show_oops()
     self.failed_view_timer.start()
     LOGGER.error(get_crash_message())