gramps-project / gramps-web-api

A RESTful web API for Gramps
GNU Affero General Public License v3.0
78 stars 41 forks source link

Relative Windows paths in media objects #187

Open brucejackson opened 3 years ago

brucejackson commented 3 years ago

Environment:

Issue: When browsing my family tree via with Gramps.js and gramps-webapi, no media images are visible in the browser.

Details. I reviewed the docker log files and noted this error message: FileNotFoundError: [Errno 2] No such file or directory: '/app/media/People\\H\\Henders__Dorothy_Estelle\\Henders__Dorothy_Estelle-Gravestone-2005.jpg'

I then opened the CLI for the docker container to confirm the images were accessible within the docker container. They appear to be. (asterisks added for emphasis)

# pwd
**/app/media/People/H/Henders__Dorothy_Estelle**
# ls -l
total 49632
-rwxrwxrwx 1 root root  2756941 Oct 24  2020 '02_0048_edited-2 (1).jpg'
-rwxrwxrwx 1 root root  2112105 Dec  2  2020  2020-12-02-0001.jpg
-rwxrwxrwx 1 root root      142 Oct 21  2020 'citation-Page B6. (2005, Oct 08). Toronto Star.txt'
-rwxrwxrwx 1 root root  2534702 Dec  3  2020  Henders__Dorothey-Confirmation.jpg
-rwxrwxrwx 1 root root  1947023 Dec  3  2020  Henders__Dorothy-1928.jpg
-rwxrwxrwx 1 root root 11277112 Dec  4  2020  Henders__Dorothy_Estelle-age-18.jpg
-rwxrwxrwx 1 root root  1377495 Dec  4  2020  Henders__Dorothy_Estelle-age-2-5a.jpg
-rwxrwxrwx 1 root root  1418379 Dec  4  2020  Henders__Dorothy_Estelle-age-2.5.jpg
-rwxrwxrwx 1 root root  3936919 Dec  1  2020  Henders__Dorothy_Estelle-age-6months.jpg
-rwxrwxrwx 1 root root   130418 Oct  5  2020  Henders__Dorothy_Estelle-Birth+Baptism-1910.jpg
-rwxrwxrwx 1 root root    21462 Dec  3  2020  Henders__Dorothy_Estelle-BirthNotice.jpg
-rwxrwxrwx 1 root root    96154 Dec  3  2020  Henders__Dorothy_Estelle-DeathNotice.JPG
**-rwxrwxrwx 1 root root  1159633 Dec  3  2020  Henders__Dorothy_Estelle-Gravestone-2005.jpg**

My docker-compose.yml is: (asterisks added for emphasis)

version: "3.7"

services:
  gramps_webapi:
    image: dmstraub/gramps-webapi:latest
    restart: always
    ports:
      - "5000:5000"
    volumes:
      - gramps_users:/app/users
      - gramps_index:/app/indexdir
      - gramps_thumb_cache:/app/thumbnail_cache
      - /C/docker-files/gramps-webapi/config.cfg:/app/config/config.cfg  # set the path before ':'
      - /c/docker-files/gramps-webapi/grampsdb:/root/.gramps/grampsdb  # set the path before ':'
      - **/c/Users/Public/Documents/Genealogy-Gramps:/app/media**   # set the path before ':'

volumes:
  gramps_users:
  gramps_index:
  gramps_thumb_cache:

In my config.cfg for the Gramps-webapi, I have the following set: MEDIA_BASE_DIR="/app/media"

In Gramps I use relative paths: Screenshot 2021-07-13 082250

Thanks, Bruce.

DavidMStraub commented 3 years ago

Oh, interesting! / vs. \. That's indeed a bug. Let me check.

DavidMStraub commented 3 years ago

Now that's tricky. We're just joining the base dir with the relative path here:

https://github.com/gramps-project/gramps-webapi/blob/master/gramps_webapi/api/file.py#L78

The problem is, Linux allows backslashes in file names. So it's not easy for us to know whether the relative path is supposed to be a Unix filename with backslashes or a Windows file path. AFAIK Gramps does not keep track of what kind of path it stores.

The only fix that comes to my mind is to try the file, if it doesn't exist, try treating it as a path.

brucejackson commented 3 years ago

Another option could be to create a new configuration variable:
MEDIA_PATH_WINDOWS = True; Backslash are directories and need to be converted MEDIA_PATH_WINDOWS = False; Carry on with existing logic.

Or, could you check the value of the "Base Path for Relative Media"? If it starts with a drive letter and a colon, the database was probably created on a windows platform. If it starts with a '/' it should be a Linux or Mac platform.
image

Nick-Hall commented 3 years ago

Yes. Functions like os.path.normpath don't help here.

DavidMStraub commented 3 years ago

Checking for the drive letter is a good idea, but it doesn't really help in full generality as F:\ happens to be a perfectly valid filename on POSIX systems!

So I think the most robust & simple solution is to check whether the POSIX interpretation works, and check the Windows one second. It would also work with Datbases that have a mix of both styles. While this sounds crazy, it might actually start happening when we allow file uploads via the web API to a database running on a Linux server that was previously used with Windows.