jim-easterbrook / python-gphoto2

Python interface to libgphoto2
GNU Lesser General Public License v3.0
362 stars 59 forks source link

Is an empty result for GP_STORAGEINFO_DESCRIPTION indicative of a bug? #31

Closed damonlynch closed 6 years ago

damonlynch commented 7 years ago

Hi Jim,

A user with a Nikon D800 is finding that getting storage info description is failing. There is no exception -- it's just there appears to be no value, or else the field is not set. I've not come across this problem with any other camera, although it's possible other users have not reported the problem of course.

Does this look more like "works as expected" or "looks like a bug"?

Here is an excerpt of code to provide a context for the problem:

    def get_storage_descriptions(self, refresh: bool=False) -> List[str]:
        """
        Storage description is used in MTP path names by gvfs and KDE.

        :param refresh: if True, get updated instead of cached values
        :return: the storage description
        """
        self._get_storage_info(refresh)
        descriptions = []
        for media_index in range(len(self.storage_info)):
            info = self.storage_info[media_index]
            if info.fields & gp.GP_STORAGEINFO_DESCRIPTION:
                descriptions.append(info.description)
        return descriptions

    def _get_storage_info(self, refresh: bool):
        """
        Load the gphoto2 storage information
        :param refresh: if True, refresh the storage information, i.e.
         load it
        """
        if not self.storage_info or refresh:
            try:
                self.storage_info = self.camera.get_storageinfo(self.context)
            except gp.GPhoto2Error as e:
                logging.error(
                    "Unable to determine storage info for camera %s: error %s.",
                    self.display_name, e.code
                )
                self.storage_info = []

I've got the user to generate a debug log dump if that would help (i.e. with gphoto2 logging turned on). Let me know if you'd like me to attach it to this report.

If you want to try some code yourself, install Rapid Photo Downloader 0.9.0b4 and run rapid-photo-downloader --camera-info

Thanks.

Best, Damon

jim-easterbrook commented 7 years ago

I doubt it's a bug in the Python interface, especially as other cameras work OK. What does the gphoto2 command line client report? (gphoto2 --storage-info)

If, as I expect, the CLI client also returns nothing then it's a question for the gphoto2 mailing list.

damonlynch commented 7 years ago

I'd wondered the same, but I asked the user to double check and this is what is returned:

$ gphoto2 --storage-info
[Storage 0]                                                                   
label=NIKON D800  [Slot 1]
basedir=/store_00010001
access=2 Nur Lesen und Bilder löschen
type=4 Entfernbarer RAM
fstype=4 Kamera Struktur (DCIM)
totalcapacity=7878464 KB
free=7393472 KB
freeimages=1604
[Storage 1]
label=NIKON D800  [Slot 2]
basedir=/store_00020001
access=2 Nur Lesen und Bilder löschen
type=4 Entfernbarer RAM
fstype=4 Kamera Struktur (DCIM)
totalcapacity=31248384 KB
free=13976416 KB
freeimages=179
jim-easterbrook commented 7 years ago

No description in that result. (-:

PS You can iterate over a list directly, rather than using an index. Instead of

        for media_index in range(len(self.storage_info)):
            info = self.storage_info[media_index]
            ...

just do

        for info in self.storage_info:
            ...
damonlynch commented 7 years ago

Oh yes, you're right. gPhoto2 leaves the entire field out altogether instead of reporting a blank value.

Being able to treat the libgphoto2 result as a proper Python iterable is very useful - was that something you changed at some point? Or perhaps I was too cautious with my code all along. I do have a dim memory of running into the problem of not being able to iterate with some returned result at some point.

jim-easterbrook commented 7 years ago

In this particular case the result is a pure Python list. Other libgphoto2 types that have 'count' and 'index' methods (e.g. gp_abilities_list_count and gp_abilities_list_get_abilities) can behave like lists if I add __len__ and __getitem__ methods in the interface. (See https://docs.python.org/2.7/reference/datamodel.html?highlight=__len__#emulating-container-types) I need to check if I've done this everywhere.

jim-easterbrook commented 7 years ago

If you run into any problems with iteration in future do let me know. With Python 2 & 3, and "builtin" vs non "builtin" versions of SWIG output I don't always find problems in my limited testing.