YANO's digital garage

Copyright ©YANO All rights reserved. https://www.bravotouring.com/~yano/

Last-modified: 2024-03-20 (水)


[一語一絵/IT系]

eyefiserver2 / 2014-06-09 (月)

4月にTrusty化したML110G7でまだ十分に動作確認ができていなかったのが、昨年5月に導入、1月に改修した[External]eyefiserver2

先日Trusty化したGT110bではすんなり動いているように思っていたのだが、実はpyexiv2関連で発生したExceptionによってSOAPの応答が発行されず、電源が入る度にEye-Fiカードがアップロードを繰り返していた事が判明。

よくよく調べてみると、昨年5月のUbuntu 10.04では[External]lucidなpython-pyexiv2がバージョン 0.1.3だったので、APIはレガシーなpyexiv2.Imageやexif.readMetadataを使用する必要があったのだが、[External]preciseなpython-pyexiv2以降はバージョン 0.3.2になっているのでpyexiv2関連のAPIはモダンなpyexiv2.ImageMetadataやexif.readに戻す必要があったという事だ。

*** eyefiserver.py.orig 2012-06-28 13:16:46.000000000 +0900
--- eyefiserver.py      2014-06-10 00:14:38.685191477 +0900
***************
*** 56,61 ****
--- 56,62 ----
  from datetime import datetime
  import ConfigParser

+ import re

  class Daemon:
      """
***************
*** 566,578 ****
      eyeFiLogger.debug("Using file_mode " + file_mode)
      eyeFiLogger.debug("Using dir_mode " + dir_mode)

!     tempDir = os.path.dirname(self.server.config.get('EyeFiServer','upload_dir'))


      imageTarPath = os.path.join(tempDir, imageTarfileName)
      eyeFiLogger.debug("Generated path " + imageTarPath)

-
      fileHandle = open(imageTarPath, 'wb')
      eyeFiLogger.debug("Opened file " + imageTarPath + " for binary writing")

--- 567,581 ----
      eyeFiLogger.debug("Using file_mode " + file_mode)
      eyeFiLogger.debug("Using dir_mode " + dir_mode)

!     tempDir = os.path.dirname(self.server.config.get('EyeFiServer','temp_dir'))
!     if not os.path.isdir(tempDir):
!       eyeFiLogger.info("Creating folder " + tempDir)
!       os.makedirs(tempDir)


      imageTarPath = os.path.join(tempDir, imageTarfileName)
      eyeFiLogger.debug("Generated path " + imageTarPath)

      fileHandle = open(imageTarPath, 'wb')
      eyeFiLogger.debug("Opened file " + imageTarPath + " for binary writing")

***************
*** 586,634 ****
      imageTarfile = tarfile.open(imageTarPath)

      for member in imageTarfile.getmembers():
!       #timezone = self.server.config.getint('EyeFiServer','timezone')
!       timezone = -7
        imageDate = datetime.fromtimestamp(member.mtime) - timedelta(hours=timezone)
        uploadDir = imageDate.strftime(self.server.config.get('EyeFiServer','upload_dir'))
-       eyeFiLogger.debug("Creating folder " + uploadDir)
        if not os.path.isdir(uploadDir):
            os.makedirs(uploadDir)
            if uid != 0 and gid != 0:
                 os.chown(uploadDir, uid, gid)
            if file_mode != "":
                 os.chmod(uploadDir, string.atoi(dir_mode))

!       f=imageTarfile.extract(member, uploadDir)
!       imagePath = os.path.join(uploadDir, member.name)
!       eyeFiLogger.debug("imamgePath " + imagePath)
        if uid != 0 and gid != 0:
!         os.chown(imagePath, uid, gid)
        if file_mode != "":
!         os.chmod(imagePath, string.atoi(file_mode))
!
!     eyeFiLogger.debug("Closing TAR file " + imageTarPath)
!     imageTarfile.close()

!     eyeFiLogger.debug("Deleting TAR file " + imageTarPath)
!     os.remove(imageTarPath)


      try:
          import pyexiv2

!         metadata = pyexiv2.ImageMetadata(imagePath)
!         metadata.read()
!         if 'Exif.Image.DateTime' in metadata.exif_keys:
!             d = metadata['Exif.Image.DateTime'].value
              seconds = time.mktime(d.timetuple())
              os.utime(imagePath, (seconds, seconds))
          else:
              eyeFiLogger.error("Could not find Exif.Image.DateTime field in EXIF information")
      except ImportError, e:
!         eyeFiLogger.error("pyexiv2 module not present. Could not read EXIF information.")
          if e.message != 'No module named pyexiv2':
              raise

      # Create the XML document to send back
      doc = xml.dom.minidom.Document()

--- 589,674 ----
      imageTarfile = tarfile.open(imageTarPath)

      for member in imageTarfile.getmembers():
!       timezone = self.server.config.getint('EyeFiServer','timezone')
!       # timezone = -7
        imageDate = datetime.fromtimestamp(member.mtime) - timedelta(hours=timezone)
        uploadDir = imageDate.strftime(self.server.config.get('EyeFiServer','upload_dir'))
        if not os.path.isdir(uploadDir):
+           eyeFiLogger.info("Creating folder " + uploadDir)
            os.makedirs(uploadDir)
            if uid != 0 and gid != 0:
                 os.chown(uploadDir, uid, gid)
            if file_mode != "":
                 os.chmod(uploadDir, string.atoi(dir_mode))

!       eyeFiLogger.debug("member.name " + member.name)
!       if re.match(r'^.+\.(LOG)$(?i)', member.name) is not None:
!           continue
!
!       extractFilePath = os.path.join(uploadDir, member.name)
!       if os.path.exists(extractFilePath):
!           eyeFiLogger.info(extractFilePath + " is exist.")
!           continue
!
!       f = imageTarfile.extract(member, uploadDir)
!       eyeFiLogger.info("extractFilePath " + extractFilePath)
        if uid != 0 and gid != 0:
!         os.chown(extractFilePath, uid, gid)
        if file_mode != "":
!         os.chmod(extractFilePath, string.atoi(file_mode))
!         seconds = time.mktime(imageDate.timetuple())
!         os.utime(extractFilePath, (seconds, seconds))

!       if re.match(r'^.+\.(JPE?G)$(?i)', member.name) is None:
!           continue

+       imagePath = extractFilePath;
+       eyeFiLogger.debug("imagePath " + extractFilePath)

          try:
              import pyexiv2

!             eyeFiLogger.debug("pyexiv2.Image: " + imagePath)
!             exif = pyexiv2.ImageMetadata(imagePath)
!             exif.read()
!             if 'Exif.Image.DateTime' in exif.exif_keys:
!                 d = exif['Exif.Image.DateTime'].value
                  seconds = time.mktime(d.timetuple())
                  os.utime(imagePath, (seconds, seconds))
              else:
                  eyeFiLogger.error("Could not find Exif.Image.DateTime field in EXIF information")
          except ImportError, e:
!             eyeFiLogger.exception("pyexiv2 module not present. Could not read EXIF information.")
              if e.message != 'No module named pyexiv2':
                  raise

+         except Exception, e:
+             eyeFiLogger.exception(e.message)
+             raise
+
+     eyeFiLogger.debug("Closing TAR file " + imageTarPath)
+     imageTarfile.close()
+
+     eyeFiLogger.debug("Deleting TAR file " + imageTarPath)
+     os.remove(imageTarPath)
+
+ #    try:
+ #        import pyexiv2
+ #
+ #     eyeFiLogger.debug("pyexiv2.Image: " + imagePath)
+ #        exif = pyexiv2.Image(imagePath)
+ #        exif.readMetadata()
+ #        if 'Exif.Image.DateTime' in exif.exifKeys():
+ #            d = exif['Exif.Image.DateTime']
+ #            seconds = time.mktime(d.timetuple())
+ #            os.utime(imagePath, (seconds, seconds))
+ #        else:
+ #            eyeFiLogger.error("Could not find Exif.Image.DateTime field in EXIF information")
+ #    except ImportError, e:
+ #        eyeFiLogger.error("pyexiv2 module not present. Could not read EXIF information.")
+ #        if e.message != 'No module named pyexiv2':
+ #            raise
+
      # Create the XML document to send back
      doc = xml.dom.minidom.Document()

***************
*** 799,804 ****
--- 839,846 ----
    fileHandler.setFormatter(eyeFiLoggingFormat)
    eyeFiLogger.addHandler(fileHandler)

+   eyeFiLogger.setLevel(config.getint('EyeFiServer','loglevel'))
+   eyeFiLogger.info("Eye-Fi server started loglevel=" + str(config.getint('EyeFiServer','loglevel')))

    server_address = (config.get('EyeFiServer','host_name'), config.getint('EyeFiServer','host_port'))

***************
*** 839,844 ****
--- 881,888 ----
      config = ConfigParser.SafeConfigParser()
      config.read(configfile)

+     eyeFiLogger.setLevel(config.getint('EyeFiServer','loglevel'))
+     eyeFiLogger.info("Eye-Fi server reload loglevel=" + str(config.getint('EyeFiServer','loglevel')))

  class MyDaemon(Daemon):
    def run(self):

参考まで、[External]Python系のライブラリパッケージ導入手順は

yano@GT110b:~$ sudo apt-get install python-pyexiv2 python-dateutil python-tz python-parsedatetime python-configglue python-regex

もう一つついでに"A standalone Eye-Fi server for Linux"で母体としているhttps://code.google.com/p/eyefiserver2/"defunct"となってしまった。代わりに"fork"した[External]dgrant/eyefiserver2 · GitHubが健在という事なので差分を採ってみたところ、1月に改修したLOGファイルが含まれる問題もケアされていそうなので、手が空いたら調査してみたい。

【参照】
●eyefiserver2 - A standalone Eye-Fi Server in python, for linux https://code.google.com/p/eyefiserver2/
●dgrant/eyefiserver2 · GitHub https://github.com/dgrant/eyefiserver2
●eyefi in Launchpad https://launchpad.net/eyefi