nextcloud / nextcloud/ios

"Upload whole camera roll" uses same name for several files when syncing files that are originally from Android, which leads to missed files and lock errors

Open
#2,865 0 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Swift
Stars
2.5k
Forks
1k
Avg merge
2d 18h
Merged PRs (30d)
13

Description

Steps to reproduce
  1. Use a phone with many photos that have been migrated several times between phones and originate from an Android phone.
  2. Enable "upload complete camera roll" with standard settings
  3. Follow the instructions
Expected behaviour

The whole camera roll should be uploaded. Files with identical time stamps should get different numbers as last part of the file name.

Actual behaviour

Files are named and "18-11-09 18-43-28 2018.jpg", etc. So instead of using ascending numbers for the last part of the file name, the app uses a year, which leads to many errors if there are files with identical time stamps. The number seems to be the same for all files. If one opens the Nextcloud Photos folder on the desktop, one can see photos being synchronized and instantly replaced. The app shows many "locked file" errors.
Manually changing the file name mask to "YY-MM-DD HH-mm-ss" shows "24-04-01 16-13-29 0001.jpg" as example, but the behavior stays the same.
The files that have been synced before enabling the "upload complete camera roll" option all have different numbers in the last part of the file name.
On a second try files were named "17-10-22 09-37-26 2017.jpeg" ,"18-11-09 18-44-38 2017.jpg", etc. I don't know how the last part is generated. It might be important to mention, that all of the files, that have been synced so far, show a timestamp that says they have been changed on 2018-11-09 or 2018-11-10, which is when I migrated from Android to iOS. Some were taken in 2017, some in 2018.

Screenshots

24-04-01 16-18-57 5330

Logs
{"reqId":"ErENUzhoO7OJgWunn4Is","level":3,"time":"2024-04-01T14:19:22+00:00","remoteAddr":"11.22.33.44","user":"admin","app":"no app in context","method":"PUT","url":"/remote.php/dav/files/admin/Photos/18-11-09%2018-44-39%202017.jpg","message":"\"Photos/18-11-09 18-44-39 2017.jpg\" is locked, existing lock on file: 2 shared locks","userAgent":"Mozilla/5.0 (iOS) Nextcloud-iOS/5.2.4","version":"28.0.3.2","exception":{"Exception":"OCA\\DAV\\Connector\\Sabre\\Exception\\FileLocked","Message":"\"Photos/18-11-09 18-44-39 2017.jpg\" is locked, existing lock on file: 2 shared locks","Code":0,"Trace":[{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":1137,"function":"put","class":"OCA\\DAV\\Connector\\Sabre\\File","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/CorePlugin.php","line":492,"function":"updateFile","class":"Sabre\\DAV\\Server","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/3rdparty/sabre/event/lib/WildcardEmitterTrait.php","line":89,"function":"httpPut","class":"Sabre\\DAV\\CorePlugin","type":"->","args":[["Sabre\\HTTP\\Request"],["Sabre\\HTTP\\Response"]]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":472,"function":"emit","class":"Sabre\\DAV\\Server","type":"->","args":["method:PUT",[["Sabre\\HTTP\\Request"],["Sabre\\HTTP\\Response"]]]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":253,"function":"invokeMethod","class":"Sabre\\DAV\\Server","type":"->","args":[["Sabre\\HTTP\\Request"],["Sabre\\HTTP\\Response"]]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":321,"function":"start","class":"Sabre\\DAV\\Server","type":"->","args":[]},{"file":"/var/www/html/apps/dav/lib/Server.php","line":373,"function":"exec","class":"Sabre\\DAV\\Server","type":"->","args":[]},{"file":"/var/www/html/apps/dav/appinfo/v2/remote.php","line":35,"function":"exec","class":"OCA\\DAV\\Server","type":"->","args":[]},{"file":"/var/www/html/remote.php","line":172,"args":["/var/www/html/apps/dav/appinfo/v2/remote.php"],"function":"require_once"}],"File":"/var/www/html/apps/dav/lib/Connector/Sabre/File.php","Line":206,"Previous":{"Exception":"OCP\\Lock\\LockedException","Message":"\"Photos/18-11-09 18-44-39 2017.jpg\" is locked, existing lock on file: 2 shared locks","Code":0,"Trace":[{"file":"/var/www/html/apps/dav/lib/Connector/Sabre/Node.php","line":413,"function":"changeLock","class":"OC\\Files\\View","type":"->","args":["/Photos/18-11-09 18-44-39 2017.jpg",2]},{"file":"/var/www/html/apps/dav/lib/Connector/Sabre/File.php","line":193,"function":"changeLock","class":"OCA\\DAV\\Connector\\Sabre\\Node","type":"->","args":[2]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":1137,"function":"put","class":"OCA\\DAV\\Connector\\Sabre\\File","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/CorePlugin.php","line":492,"function":"updateFile","class":"Sabre\\DAV\\Server","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/3rdparty/sabre/event/lib/WildcardEmitterTrait.php","line":89,"function":"httpPut","class":"Sabre\\DAV\\CorePlugin","type":"->","args":[["Sabre\\HTTP\\Request"],["Sabre\\HTTP\\Response"]]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":472,"function":"emit","class":"Sabre\\DAV\\Server","type":"->","args":["method:PUT",[["Sabre\\HTTP\\Request"],["Sabre\\HTTP\\Response"]]]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":253,"function":"invokeMethod","class":"Sabre\\DAV\\Server","type":"->","args":[["Sabre\\HTTP\\Request"],["Sabre\\HTTP\\Response"]]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":321,"function":"start","class":"Sabre\\DAV\\Server","type":"->","args":[]},{"file":"/var/www/html/apps/dav/lib/Server.php","line":373,"function":"exec","class":"Sabre\\DAV\\Server","type":"->","args":[]},{"file":"/var/www/html/apps/dav/appinfo/v2/remote.php","line":35,"function":"exec","class":"OCA\\DAV\\Server","type":"->","args":[]},{"file":"/var/www/html/remote.php","line":172,"args":["/var/www/html/apps/dav/appinfo/v2/remote.php"],"function":"require_once"}],"File":"/var/www/html/lib/private/Files/View.php","Line":1984,"Previous":{"Exception":"OCP\\Lock\\LockedException","Message":"\"files/eefc1210155d7d3c1a4b73c5fe212bf6\"(\"files/Photos/18-11-09 18-44-39 2017.jpg\") is locked, existing lock on file: 2 shared locks","Code":0,"Trace":[{"file":"/var/www/html/lib/private/Files/Storage/Wrapper/Wrapper.php","line":629,"function":"changeLock","class":"OC\\Files\\Storage\\Common","type":"->","args":["files/Photos/18-11-09 18-44-39 2017.jpg",2,["OC\\Lock\\MemcacheLockingProvider"]]},{"file":"/var/www/html/lib/private/Files/Storage/Wrapper/Wrapper.php","line":629,"function":"changeLock","class":"OC\\Files\\Storage\\Wrapper\\Wrapper","type":"->","args":["files/Photos/18-11-09 18-44-39 2017.jpg",2,["OC\\Lock\\MemcacheLockingProvider"]]},{"file":"/var/www/html/lib/private/Files/View.php","line":1975,"function":"changeLock","class":"OC\\Files\\Storage\\Wrapper\\Wrapper","type":"->","args":["files/Photos/18-11-09 18-44-39 2017.jpg",2,["OC\\Lock\\MemcacheLockingProvider"]]},{"file":"/var/www/html/apps/dav/lib/Connector/Sabre/Node.php","line":413,"function":"changeLock","class":"OC\\Files\\View","type":"->","args":["/Photos/18-11-09 18-44-39 2017.jpg",2]},{"file":"/var/www/html/apps/dav/lib/Connector/Sabre/File.php","line":193,"function":"changeLock","class":"OCA\\DAV\\Connector\\Sabre\\Node","type":"->","args":[2]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":1137,"function":"put","class":"OCA\\DAV\\Connector\\Sabre\\File","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/CorePlugin.php","line":492,"function":"updateFile","class":"Sabre\\DAV\\Server","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/3rdparty/sabre/event/lib/WildcardEmitterTrait.php","line":89,"function":"httpPut","class":"Sabre\\DAV\\CorePlugin","type":"->","args":[["Sabre\\HTTP\\Request"],["Sabre\\HTTP\\Response"]]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":472,"function":"emit","class":"Sabre\\DAV\\Server","type":"->","args":["method:PUT",[["Sabre\\HTTP\\Request"],["Sabre\\HTTP\\Response"]]]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":253,"function":"invokeMethod","class":"Sabre\\DAV\\Server","type":"->","args":[["Sabre\\HTTP\\Request"],["Sabre\\HTTP\\Response"]]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":321,"function":"start","class":"Sabre\\DAV\\Server","type":"->","args":[]},{"file":"/var/www/html/apps/dav/lib/Server.php","line":373,"function":"exec","class":"Sabre\\DAV\\Server","type":"->","args":[]},{"file":"/var/www/html/apps/dav/appinfo/v2/remote.php","line":35,"function":"exec","class":"OCA\\DAV\\Server","type":"->","args":[]},{"file":"/var/www/html/remote.php","line":172,"args":["/var/www/html/apps/dav/appinfo/v2/remote.php"],"function":"require_once"}],"File":"/var/www/html/lib/private/Files/Storage/Common.php","Line":833,"Previous":{"Exception":"OCP\\Lock\\LockedException","Message":"\"files/eefc1210155d7d3c1a4b73c5fe212bf6\" is locked, existing lock on file: 2 shared locks","Code":0,"Trace":[{"file":"/var/www/html/lib/private/Files/Storage/Common.php","line":831,"function":"changeLock","class":"OC\\Lock\\MemcacheLockingProvider","type":"->","args":["files/eefc1210155d7d3c1a4b73c5fe212bf6",2]},{"file":"/var/www/html/lib/private/Files/Storage/Wrapper/Wrapper.php","line":629,"function":"changeLock","class":"OC\\Files\\Storage\\Common","type":"->","args":["files/Photos/18-11-09 18-44-39 2017.jpg",2,["OC\\Lock\\MemcacheLockingProvider"]]},{"file":"/var/www/html/lib/private/Files/Storage/Wrapper/Wrapper.php","line":629,"function":"changeLock","class":"OC\\Files\\Storage\\Wrapper\\Wrapper","type":"->","args":["files/Photos/18-11-09 18-44-39 2017.jpg",2,["OC\\Lock\\MemcacheLockingProvider"]]},{"file":"/var/www/html/lib/private/Files/View.php","line":1975,"function":"changeLock","class":"OC\\Files\\Storage\\Wrapper\\Wrapper","type":"->","args":["files/Photos/18-11-09 18-44-39 2017.jpg",2,["OC\\Lock\\MemcacheLockingProvider"]]},{"file":"/var/www/html/apps/dav/lib/Connector/Sabre/Node.php","line":413,"function":"changeLock","class":"OC\\Files\\View","type":"->","args":["/Photos/18-11-09 18-44-39 2017.jpg",2]},{"file":"/var/www/html/apps/dav/lib/Connector/Sabre/File.php","line":193,"function":"changeLock","class":"OCA\\DAV\\Connector\\Sabre\\Node","type":"->","args":[2]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":1137,"function":"put","class":"OCA\\DAV\\Connector\\Sabre\\File","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/CorePlugin.php","line":492,"function":"updateFile","class":"Sabre\\DAV\\Server","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/3rdparty/sabre/event/lib/WildcardEmitterTrait.php","line":89,"function":"httpPut","class":"Sabre\\DAV\\CorePlugin","type":"->","args":[["Sabre\\HTTP\\Request"],["Sabre\\HTTP\\Response"]]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":472,"function":"emit","class":"Sabre\\DAV\\Server","type":"->","args":["method:PUT",[["Sabre\\HTTP\\Request"],["Sabre\\HTTP\\Response"]]]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":253,"function":"invokeMethod","class":"Sabre\\DAV\\Server","type":"->","args":[["Sabre\\HTTP\\Request"],["Sabre\\HTTP\\Response"]]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":321,"function":"start","class":"Sabre\\DAV\\Server","type":"->","args":[]},{"file":"/var/www/html/apps/dav/lib/Server.php","line":373,"function":"exec","class":"Sabre\\DAV\\Server","type":"->","args":[]},{"file":"/var/www/html/apps/dav/appinfo/v2/remote.php","line":35,"function":"exec","class":"OCA\\DAV\\Server","type":"->","args":[]},{"file":"/var/www/html/remote.php","line":172,"args":["/var/www/html/apps/dav/appinfo/v2/remote.php"],"function":"require_once"}],"File":"/var/www/html/lib/private/Lock/MemcacheLockingProvider.php","Line":145}}},"message":"\"Photos/18-11-09 18-44-39 2017.jpg\" is locked, existing lock on file: 2 shared locks","exception":[],"CustomMessage":"\"Photos/18-11-09 18-44-39 2017.jpg\" is locked, existing lock on file: 2 shared locks"},"id":"660ac52c0a6ac"}
Reasoning or why should it be changed/implemented?

So the whole camera roll can be uploaded without skipped files.

Environment data

iOS version: 17.3.1

Nextcloud iOS app version: 5.2.4.2

Server operating system: Debian 12/Openmediavault 7

Web server: Nextcloud AIO v8.0.0

Database: Nextcloud AIO v8.0.0

PHP version: Nextcloud AIO v8.0.0

Nextcloud version: Nextcloud Hub 7 (28.0.3)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the complete camera-roll upload with migrated Android-origin photos and inspect the generated filenames and lock errors in the provided logs. Trace the iOS upload and filename-generation entry points, then verify that files sharing timestamps receive distinct suffixes and upload without replacement or lock failures.

Written by the indexing model from the issue text.

Assessment

Tech stack
ios, swift
Domain
mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.