Bug 1178256 - shotwell will not import photos from ios8
Summary: shotwell will not import photos from ios8
Keywords:
Status: CLOSED EOL
Alias: None
Product: Fedora
Classification: Fedora
Component: shotwell
Version: 21
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Matthias Clasen
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2015-01-03 11:07 UTC by Lars E. Pettersson
Modified: 2015-12-02 16:56 UTC (History)
11 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2015-12-02 06:47:34 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Lars E. Pettersson 2015-01-03 11:07:40 UTC
Description of problem:

- attach iPhone (5s iOS 8.1.2)
- start shotwell
- chose your iPhone under the "Cameras" folder
- thumbnails of new pictures start to appear
- chose import all
- shotwell comes up with an error saying "16 files failed to import due to a camera error" (i.e. all files to be imported failed)
- Shotwell Import Log.txt says:
Import Results Report (Shotwell 0.20.2 @ 2015-01-03T10:46:45.163293Z)

Attempted to import 16 files. Of these, 0 files were successfully imported.

Photos/Videos Not Imported Due to Camera Errors:

IMG_0125.PNG
	error message: [-107] Error retrieving file object for /store_00010001/D
CIM/957INLAP/IMG_0125.PNG: Unknown error
...

- Trying 'gphoto2 –port=usb: -R -P' retrieves most pictures but ends with '*** Error (-1: 'Unspecified error') ***' (the newest pictures loads well though, so this error might be unrelated) (the downside of this command is that it downloads ALL files, and I only want the new ones)

- nautilus mostly works, i.e. it shows the dcim catalogs and you can transfer photos from it (sometimes it will not open the iPhone "folder", but I think that is an unrelated problem)

- as gphoto2 and nautilus works, the photos are accessible and copy-able so shotwell should be able to retrieve them

(I am not sure if this is related to the update of Fedora (to 21 from 20), or/and an update of iOS. I simply do not remember when this error first occurred.)

On <http://www.neowin.net/forum/topic/1241868-ubuntu-iphone-5s-syncing/> the following is mentioned "according to a linux forum, iphone 5s with ios 8 works only with itunes and the old tricks to use it on linux are not possible anymore, since apple blatantly is just blocking it." but if that was true gphoto2 or nautilus would not work. I.e. I do not think that this is an iPhone "bug".

Version-Release number of selected component (if applicable):

gphoto2-2.5.3-3.fc21.x86_64
gvfs-gphoto2-1.22.2-1.fc21.x86_64
libgphoto2-2.5.3-9.fc21.x86_64
shotwell-0.20.2-1.fc21.x86_64

How reproducible:

Always!

Comment 1 Luis Verissimo 2015-08-15 18:44:42 UTC
I have the same exact issue under Fedora 22 running kernel 4.1.4, shotwell 0.22.0.

Comment 2 obsid 2015-08-20 12:20:26 UTC
Experiencing the same thing as well, Fedora 22, custom kernel 4.2.0-rc6+, shotwell 0.22.0, iOS 8.4.1 running on an iPhone 5.

It's broken at least from Fedora 20 but it hasn't always been like that, so the problem seems to be due to an iOS update.

Thanks a lot for reporting that it works with gphoto2 because I would have given up otherwise. After some investigations, the problem seems to occur in the file "src/camera/GPhoto.vala" at line 272 :

  res = camera.get_file(folder, filename, GPhoto.CameraFileType.NORMAL, camera_file, context);
  if (res != Result.OK) throw new GPhotoError.LIBRARY("[%d] Error retrieving file object for %s/%s: %s", (int) res, folder, filename, res.as_string());

There's three of them in the file, but altering the message string shows that it always happens at the first one. This file is resolved as "src/camera/GPhoto.c" at line 1984 :

  #line 270 "/home/dom/Build/shotwell-0.22.0/src/camera/GPhoto.vala"
      _tmp12_ = gp_camera_file_get (_tmp7_, _tmp8_, _tmp9_, GP_FILE_TYPE_NORMAL, _tmp10_, _tmp11_);



Error -107 is actually a libgphoto2's one and corresponds to GP_ERROR_DIRECTORY_NOT_FOUND, as stated here : http://libgphoto2.sourcearchive.com/documentation/2.4.0/gphoto2-camera_8c_262b1bc840d62b12605e3acc543f714d.html#262b1bc840d62b12605e3acc543f714d



I first wondered if the problem could come from the way the path was written and therefore tried to manually extract a single given file with gphoto2, then received the same -107 code, while it used to work perfectly fine when automatically downloading the whole file set. And as I was checking that my path was correct, I finally end up on this (look at the final subdirectory's name) :

$ gphoto2 --port=usb: -L | grep -B1 0603
There are 2 files in folder '/store_00010001/DCIM/911KWHTS'.
#713   IMG_0603.JPG               rd  1284 KB 2448x3264 image/jpeg
$ gphoto2 --port=usb: -L | grep -B1 0603
There are 2 files in folder '/store_00010001/DCIM/813VOSDD'.
#1     IMG_0603.JPG               rd  1284 KB 2448x3264 image/jpeg
$ gphoto2 --port=usb: -L | grep -B1 0603
There are 2 files in folder '/store_00010001/DCIM/891WYNZY'.
#792   IMG_0603.JPG               rd  1284 KB 2448x3264 image/jpeg
$ gphoto2 --port=usb: -L | grep -B1 0603
There are 2 files in folder '/store_00010001/DCIM/833ZLJVU'.
#211   IMG_0603.JPG               rd  1284 KB 2448x3264 image/jpeg


Which means that iOS seems to store all files in a bunch of subdirectories, and the names of these subdirectories are auto-regenerated for each new connection. As long as the application keeps its connection open, there's no problem, but if gathers all the names first, then try to fetch them later, it is unable to find them back.

Comment 3 obsid 2015-08-30 08:59:43 UTC
Ok, here's a quick patch that will do for the moment. It's a TERRIBLE hack which will need you to quit the application to release the camera, but at least it allowed me to import my 900 snapshots that were pending for almost a year.

Basically, it keeps alive the "camera" object of the ImportPage class. It now calls init() only if the object is null, hence not previously initialized first, and hides every call to exit(), pretending the thing is still done. This neutralize the CameraRefresh routines. However, it now properly calls exit() in the ImportPage class's destructor.

This patch may be applied on version 0.22.0. It works on commit 6bd668604537f9d11bb7d4874e2fd5f77ed63db0 from the shotwell's github repository. I compiled it from there with every debug options just for iOS, and keep installed the standard version from my distribution packages when dealing with other cameras.

Once again, this is rather DIRTY and should be used only as a temporary workaround. Hope it helps anyway. :-)








diff --git a/src/camera/ImportPage.vala b/src/camera/ImportPage.vala
index ba66990..b86c57f 100644
--- a/src/camera/ImportPage.vala
+++ b/src/camera/ImportPage.vala
@@ -766,8 +766,17 @@ class PhotoImportSource : ImportSource {
     ~ImportPage() {
         LibraryPhoto.global.contents_altered.disconnect(on_media_added_removed);
         Video.global.contents_altered.disconnect(on_media_added_removed);
+
+        // iOS 8 issue. Release the camera here
+        if (camera != null) {
+          GPhoto.Result res = camera.exit(spin_idle_context.context);
+          if (res != GPhoto.Result.OK) {
+              // log but don't fail
+              warning("ImportPage destructor: Unable to unlock camera: %s", res.to_full_string());
+          }
+        }
     }
     
     public override Gtk.Toolbar get_toolbar() {
         if (toolbar == null) {
             base.get_toolbar();
@@ -1149,19 +1158,22 @@ public class ImportPage : CheckerboardPage {
     private RefreshResult refresh_camera() {
         if (busy)
             return RefreshResult.BUSY;
             
         update_status(busy, false);
         
         refresh_error = null;
-        refresh_result = camera.init(spin_idle_context.context);
-        if (refresh_result != GPhoto.Result.OK) {
-            warning("Unable to initialize camera: %s", refresh_result.to_full_string());
-            
-            return (refresh_result == GPhoto.Result.IO_LOCK) ? RefreshResult.LOCKED : RefreshResult.LIBRARY_ERROR;
+        // iOS 8 issue
+        if (camera == null) {
+          refresh_result = camera.init(spin_idle_context.context);
+          if (refresh_result != GPhoto.Result.OK) {
+              warning("Unable to initialize camera: %s", refresh_result.to_full_string());
+
+              return (refresh_result == GPhoto.Result.IO_LOCK) ? RefreshResult.LOCKED : RefreshResult.LIBRARY_ERROR;
+          }
         }
 
         update_status(true, refreshed);
         
         on_view_changed();
 
         progress_bar.set_ellipsize(Pango.EllipsizeMode.NONE);
@@ -1261,15 +1272,17 @@ public class ImportPage : CheckerboardPage {
         progress_bar.visible = false;
         progress_bar.set_ellipsize(Pango.EllipsizeMode.NONE);
         progress_bar.set_text("");
         progress_bar.set_fraction(0.0);
-        
+
+#if 0
         GPhoto.Result res = camera.exit(spin_idle_context.context);
         if (res != GPhoto.Result.OK) {
             // log but don't fail
             warning("Unable to unlock camera: %s", res.to_full_string());
         }
-        
+#endif
+
         if (refresh_result == GPhoto.Result.OK) {
             update_status(false, true);
         } else {
             update_status(false, false);
@@ -1628,23 +1641,27 @@ public class ImportPage : CheckerboardPage {
     private void on_import_selected() {
         import(get_view().get_selected());
     }
     
     private void on_import_all() {
         import(get_view().get_all());
     }
     
     private void import(Gee.Iterable<DataObject> items) {
-        GPhoto.Result res = camera.init(spin_idle_context.context);
-        if (res != GPhoto.Result.OK) {
-            AppWindow.error_message(_("Unable to lock camera: %s").printf(res.to_full_string()));
-            
-            return;
+        // We now keep the camera open as long as we can to
+        // work around the iOS 8 directory name shuffling issue.
+        if (camera == null) {
+          GPhoto.Result res = camera.init(spin_idle_context.context);
+          if (res != GPhoto.Result.OK) {
+              AppWindow.error_message(_("Unable to lock camera: %s").printf(res.to_full_string()));
+
+              return;
+          }
         }
 
         update_status(true, refreshed);
         
         on_view_changed();
         progress_bar.visible = false;
 
         SortedList<CameraImportJob> jobs = new SortedList<CameraImportJob>(import_job_comparator);
         Gee.ArrayList<CameraImportJob> already_imported = new Gee.ArrayList<CameraImportJob>();
@@ -1772,18 +1789,21 @@ public class ImportPage : CheckerboardPage {
         // to stop build warnings
         local_ref = null;
     }
 
     private void close_import() {
+// iOS 8 issue
+#if 0
         GPhoto.Result res = camera.exit(spin_idle_context.context);
         if (res != GPhoto.Result.OK) {
             // log but don't fail
             message("Unable to unlock camera: %s", res.to_full_string());
         }
-        
+#endif
+
         update_status(false, refreshed);
         
         on_view_changed();
     }
 
     public override void set_display_titles(bool display) {
         base.set_display_titles(display);

Comment 5 Fedora End Of Life 2015-11-04 10:26:09 UTC
This message is a reminder that Fedora 21 is nearing its end of life.
Approximately 4 (four) weeks from now Fedora will stop maintaining
and issuing updates for Fedora 21. It is Fedora's policy to close all
bug reports from releases that are no longer maintained. At that time
this bug will be closed as EOL if it remains open with a Fedora  'version'
of '21'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version' 
to a later Fedora version.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora 21 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora, you are encouraged  change the 'version' to a later Fedora 
version prior this bug is closed as described in the policy above.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events. Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.

Comment 6 Fedora End Of Life 2015-12-02 06:47:40 UTC
Fedora 21 changed to end-of-life (EOL) status on 2015-12-01. Fedora 21 is
no longer maintained, which means that it will not receive any further
security or bug fix updates. As a result we are closing this bug.

If you can reproduce this bug against a currently maintained version of
Fedora please feel free to reopen this bug against that version. If you
are unable to reopen this bug, please file a new report against the
current release. If you experience problems, please add a comment to this
bug.

Thank you for reporting this bug and we are sorry it could not be fixed.


Note You need to log in before you can comment on or make changes to this bug.