janten / dpt-rp1-py

Python script to manage a Sony DPT-RP1 without the Digital Paper App
MIT License
540 stars 135 forks source link

dptmount: file tree representation breaks on first read operation #89

Closed alex-fu27 closed 4 years ago

alex-fu27 commented 5 years ago

I tried dptmount for the first time today. I love the idea to be able to mount the device just like any other drive. So i created a config.yaml and a directory test. I called

python -m dptrp1.cli.dptmount --config config.yaml --verbose test/

in the repository's directory on my pc. Using a second shell, in the same directory I issued:

cp "test/Studium/Theo II/blatt01.pdf" ~/uni/theo2/

Which works well on the first time:

...
DEBUG:fuse.log-mixin:-> read /Studium/Theo II/blatt01.pdf (40960, 0, 1)
DEBUG:fuse.log-mixin:<- read b'%PDF-1.7\n%\xc7\xec\x8f\xa2\n5 0 obj\n<</Length
...

But when I run the same cp command a second time, I get "cp: cannot stat (...) invalid argument". The log of dptmount lists the following exception:

DEBUG:fuse.log-mixin:-> getattr /Studium/Theo II/blatt01.pdf (None,)
DEBUG:fuse.log-mixin:<- getattr '[Unhandled Exception]'
ERROR:fuse:Uncaught exception from FUSE operation getattr, returning errno.EINVAL.
Traceback (most recent call last):
  File "/usr/lib/python3.7/site-packages/fuse.py", line 734, in _wrapper
    return func(*args, **kwargs) or 0
  File "/usr/lib/python3.7/site-packages/fuse.py", line 774, in getattr
    return self.fgetattr(path, buf, None)
  File "/usr/lib/python3.7/site-packages/fuse.py", line 1027, in fgetattr
    attrs = self.operations('getattr', self._decode_optional_path(path), fh)
  File "/usr/lib/python3.7/site-packages/fuse.py", line 1251, in __call__
    ret = getattr(self, op)(path, *args)
  File "/mnt/c/Users/Alexander/projects/dpt/dpt-rp1-py/dptrp1/cli/dptmount.py", line 180, in getattr
    node = self._map_local_remote(path)
  File "/mnt/c/Users/Alexander/projects/dpt/dpt-rp1-py/dptrp1/cli/dptmount.py", line 160, in _map_local_remote
    return anytree.search.find(self.root, filter_=lambda node: node.localpath == full_local)
  File "/usr/lib/python3.7/site-packages/anytree/search.py", line 161, in find
    return _find(node, filter_=filter_, stop=stop, maxlevel=maxlevel)
  File "/usr/lib/python3.7/site-packages/anytree/search.py", line 213, in _find
    items = _findall(node, filter_, stop=stop, maxlevel=maxlevel, maxcount=1)
  File "/usr/lib/python3.7/site-packages/anytree/search.py", line 225, in _findall
    raise CountError(msg % (maxcount, resultlen), result)
anytree.search.CountError: Expecting 1 elements at maximum, but found 2. (Node('/Document/Studium/Theo II/blatt01.pdf', item={'created_date': '2019-10-17T08:49:13Z', 'current_page': '1', 'document_source': '8192339f-4f4f-40ba-9f14-11f239bf6549', 'document_type': 'normal', 'entry_id': 'e4b0f675-8b94-4f3e-9f1e-6fadd005e90c', 'entry_name': 'blatt01.pdf', 'entry_path': 'Document/Studium/Theo II/blatt01.pdf', 'entry_type': 'document', 'file_revision': '6fadd005e90c.1.0', 'file_size': '38539', 'is_new': 'true', 'mime_type': 'application/pdf', 'modified_date': '2019-10-17T08:49:13Z', 'parent_folder_id': 'fdb61eb6-6686-4408-91dd-c7c737317d1f', 'title': 'blatt1.dvi', 'total_page': '2'}, localpath='/Studium/Theo II/blatt01.pdf', lstat={'st_atime': 1571302172.7793748, 'st_gid': 985, 'st_uid': 1000, 'st_ctime': 1571302153, 'st_mode': 33188, 'st_mtime': 1571302153, 'st_nlink': 1, 'st_size': 38539}, remote_path='Document/Studium/Theo II/blatt01.pdf'), Node('/Document/Studium/Theo II/blatt01.pdf', item={'created_date': '2019-10-17T08:49:44Z', 'current_page': '1', 'document_source': '8192339f-4f4f-40ba-9f14-11f239bf6549', 'document_type': 'normal', 'entry_id': '5dfcaf61-3e3c-41d0-bc7d-9d772831bf70', 'entry_name': 'blatt01.pdf', 'entry_path': 'Document/Studium/Theo II/blatt01.pdf', 'entry_type': 'document', 'ext_id': '', 'file_revision': '9d772831bf70.1.0', 'file_size': '38539', 'is_new': 'true', 'mime_type': 'application/pdf', 'modified_date': '2019-10-17T08:49:44Z', 'parent_folder_id': 'fdb61eb6-6686-4408-91dd-c7c737317d1f', 'title': 'blatt1.dvi', 'total_page': '2'}, localpath='/Studium/Theo II/blatt01.pdf', lstat={'st_atime': 1571302172.7793748, 'st_gid': 985, 'st_uid': 1000, 'st_ctime': 1571302184, 'st_mode': 33188, 'st_mtime': 1571302184, 'st_nlink': 1, 'st_size': 38539}, remote_path='Document/Studium/Theo II/blatt01.pdf'))

It looks like all entries are listed twice now.

alex-fu27 commented 5 years ago

Ok, the problem seems to be the flush operation which calls _add_remote_path_to_tree to update the cached file information.

janten commented 5 years ago

Most parts of dptmount were contributed by @jgrigera. Maybe he has an idea how to fix this?

jgrigera commented 5 years ago

Hi @janten - definitely. I will and commit something to fix this probably by this time next week!