icloud-photos-downloader / icloud_photos_downloader

A command-line tool to download photos from iCloud
MIT License
6.69k stars 544 forks source link

Change locale for folder structure for example #897

Closed holomekc closed 2 months ago

holomekc commented 3 months ago

I want to be able to change the locale for the python process. The reason is to define folder patterns like this: --folder-structure {:%Y/%m\ %B}

But at the moment this will create something like this: .../2024/07 July

But I want the german translation .../2024/07 Juli

I am a python noob so not 100% sure how and where. Otherwise, I could create a PR. I think though you need to add only this: https://docs.python.org/3/library/locale.html#locale.setlocale

import locale
locale.setlocale(locale.LC_ALL, '')

Although, I am not sure if it needs to be locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')

AndreyNikiforov commented 3 months ago

That is interesting use case. IIUC you want icloudpd to use locale of the OS. I haven't used anything other than en for long time, so I need to learn how locale work. Is it possible to change locale just for one process from OS shell?

holomekc commented 3 months ago

Hi @AndreyNikiforov thx for the quick answer. I do not think so. At least they say something like this: https://stackoverflow.com/questions/48270191/python-does-not-use-locale-from-environment

Initially, when a program is started, the locale is the C locale, no matter what the user’s preferred locale is.

But as I mentioned, I am not that of an python expert.

Edit: Or maybe. I think you can set environment variable LC_ALL to de_DE.UTF-8, but I think python still needs the code I posted originally.

holomekc commented 3 months ago

I had this in the past, but it was a mess and I am pretty sure that I did not understand everything properly. Furthermore, it does not work with the new version anymore. Not sure why though:

FROM python:3.12-alpine

WORKDIR /app

ENV CARGO_NET_GIT_FETCH_WITH_CLI=true

RUN set -xe \
  && apk update \
  && apk add git curl binutils gcc libc-dev libffi-dev zlib-dev openssl-dev python3-dev cargo rust tzdata

RUN git clone https://github.com/icloud-photos-downloader/icloud_photos_downloader.git . && \
  git checkout tags/v1.17.1 -b main && \
  echo "import locale" >> /app/src/icloudpd/__init__.py && \
  echo "locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')" >> /app/src/icloudpd/__init__.py

ENV MUSL_LOCPATH="/usr/share/i18n/locales/musl"
RUN apk add --no-cache musl-locales musl-locales-lang \
    && cd "$MUSL_LOCPATH" \
    && for i in de_DE.UTF-8; do cp -a "$i" "${i%%.UTF-8}"; done

RUN pip3 install -e .[dev]

RUN pyinstaller -y --collect-all keyrings.alt --hidden-import pkgutil --collect-all tzdata --onefile src/starters/icloudpd_ex.py

RUN adduser -D worker -u 1024
USER worker
RUN mkdir -p /home/worker/app

USER 0
RUN cp /app/dist/icloudpd_ex /home/worker/app && \
    rm -R /app/dist/icloudpd_ex

USER worker
WORKDIR /home/worker
ENV PATH="/home/worker/.local/bin:${PATH}"

RUN python -m pip install --upgrade pip && \
  pip install --user keyrings.alt keyring

ENV TZ Europe/Berlin \
    LANG de_DE.UTF-8 \
    LANGUAGE de_DE.UTF-8 \
    LC_ALL de_DE.UTF-8

ENV PATH="/home/worker/app:${PATH}"

RUN cd /home/worker/app && ls -la

ENTRYPOINT ["/home/worker/app/icloudpd_ex"]

It was a quick fix when the auth was not working and I just copy pasted a lot of stuff.

AndreyNikiforov commented 3 months ago

What I have found: To show available locales:

locale -a

To Install all:

sudo apt-get update
sudo apt-get install locales locales-all

python test.py code:

import datetime
from locale import LC_ALL, setlocale
setlocale(LC_ALL, '')
print(f"{datetime.datetime.now():%B}")

to test different locales

LANG=de_DE.UTF-8 python test.py

@holomekc check that works as expected and I'll update icloudpd to support reading locales from OS (with the flag)

holomekc commented 3 months ago

Hi @AndreyNikiforov

FROM python:bookworm

RUN apt-get update && apt-get install locales locales-all -y

RUN locale

RUN echo 'import datetime\nfrom locale import LC_ALL, setlocale\n\nsetlocale(LC_ALL, "")\nprint(f"{datetime.datetime.now():%B}")' > test.py

RUN LANG=de_DE.UTF-8 python test.py
Sending build context to Docker daemon  2.048kB
Step 1/5 : FROM python:bookworm
 ---> fa2a2a87a538
Step 2/5 : RUN apt-get update && apt-get install locales locales-all -y
 ---> Using cache
 ---> 0c3aa0d3fafa
Step 3/5 : RUN locale
 ---> Running in e35e457d779e
LANG=C.UTF-8
LANGUAGE=
LC_CTYPE="C.UTF-8"
LC_NUMERIC="C.UTF-8"
LC_TIME="C.UTF-8"
LC_COLLATE="C.UTF-8"
LC_MONETARY="C.UTF-8"
LC_MESSAGES="C.UTF-8"
LC_PAPER="C.UTF-8"
LC_NAME="C.UTF-8"
LC_ADDRESS="C.UTF-8"
LC_TELEPHONE="C.UTF-8"
LC_MEASUREMENT="C.UTF-8"
LC_IDENTIFICATION="C.UTF-8"
LC_ALL=
Removing intermediate container e35e457d779e
 ---> 51cf133ede5d
Step 4/5 : RUN echo 'import datetime\nfrom locale import LC_ALL, setlocale\n\nsetlocale(LC_ALL, "")\nprint(f"{datetime.datetime.now():%B}")' > test.py
 ---> Running in 1ac3f44c2520
Removing intermediate container 1ac3f44c2520
 ---> 5a338c32e909
Step 5/5 : RUN LANG=de_DE.UTF-8 python test.py
 ---> Running in c4760d5c9e74
Juli
Removing intermediate container c4760d5c9e74
 ---> 4367c0fde5a8
Successfully built 4367c0fde5a8
Successfully tagged test:latest

Yes this works. "Juli" is printed. I did not log the locale -a, because it prints a lot of different languages, but locale shows that currently locale C is configured, but due to the python script and the env it works fine.

Would be great if you can include this.

AndreyNikiforov commented 2 months ago

v1.22.0 has --use-os-locale flag. During testing, I learnt more about locales and building compatibility for tz & locale in each release - while there is an opportunity to improve, I hope your issue is resolved.

holomekc commented 2 months ago

Thank you so much for the hard work!