Post

Migrating Photos from Google and Import Them to Nextcloud

Migrating Photos from Google and Import Them to Nextcloud

Google Photos is a great platform for storing and organizing your pictures and videos. However, if you’re looking to move your photos and videos to another cloud service, such as Nextcloud, you can export your data from Google Photos using Google Takeout and then organize and prepare your files for easy management with the Memories app in Nextcloud.

In this article, we will guide you through the process of exporting Google Photos and preparing the file structure for Nextcloud using a shell script. This script will automatically organize your media files by year and month, based on their EXIF metadata, which is how the Memories app in Nextcloud organizes photos.

Additionally, we’ll explain how photos from your smartphone can be automatically uploaded to Nextcloud using the Nextcloud mobile app, ensuring a seamless process for backing up your media.


🛠️ Steps to Export Google Photos via Google Takeout

📤 1. Export Google Photos Data with Google Takeout

To export your Google Photos, follow these steps:

  1. 🌐 Go to Google Takeout:
  2. 🖼️ Select Google Photos:
    • Scroll down and select Google Photos. You can select all albums or specific ones you want to export.
  3. ⚙️ Choose Export Settings:
    • Choose the file type and size for the export. Google Takeout will create a compressed .zip or .tgz file, which can be quite large depending on the volume of your photos and videos.
  4. ▶️ Start the Export:
    • Click on the Next Step button and then click on Create Export. Google will prepare your files, which can take some time depending on the volume of media. Once ready, you will receive an email with a link to download your exported files.
  5. 📥 Download the Export:
    • Download the exported files from the link provided by Google. After the download completes, you’ll have a folder containing your photos and videos, typically in a zip archive.

🗂️ 2. Preparing Files for Nextcloud with the Memories App

Once you have your Google Photos exported, the next step is to organize your files for Nextcloud and ensure they are properly managed using the Memories app.

The Memories app in Nextcloud organizes photos into albums based on date and time. The script below will help you organize the files into folders based on the year and month derived from the EXIF metadata of your media files.


🖥️ 3. The Script: Organizing Your Photos

The following script processes your photos and videos by extracting their EXIF metadata (date and time) to categorize them into appropriate directories in your Nextcloud folder. This organization is required for proper handling in the Memories app.

Here is the script (which has been heavily tuned because the Google Takeout with photos over two decades was a pure mess):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/bin/bash

# Directory where the photos are stored (Google Takeout export folder)
SOURCE_DIR="Google Fotos"

# Directory where the photos will be moved (Nextcloud storage folder)
DEST_DIR="nextcloud"

# Function to set EXIF creation date
set_exif_creation_date() {
    local image_path=$1
    local date=$2
    exiftool -overwrite_original -DateTimeOriginal="$date" "$image_path" > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo "EXIF data successfully set for $image_path."
    else
        echo "Error setting EXIF data for $image_path."
    fi
}

# Function to extract the date and possibly time from the filename
extract_date_from_filename() {
    local filename=$1
    # Pattern for various file formats
    if [[ "$filename" =~ (20[0-2][1-9]})-([0-1][0-9])-([0-3][0-9]) ]]; then
        # Format: YYYY-MM-DD
        echo "${BASH_REMATCH[1]}-${BASH_REMATCH[2]}-${BASH_REMATCH[3]} 00:00:00"
    elif [[ "$filename" =~ (20[0-2][1-9]})([0-1][0-9])([0-3][0-9]) ]]; then
        # Format: YYYYMMDD
        echo "${BASH_REMATCH[1]}-${BASH_REMATCH[2]}-${BASH_REMATCH[3]} 00:00:00"
    elif [[ "$filename" =~ (20[0-2][1-9]})([0-1][0-9])([0-3][0-9])_([0-9]{6}) ]]; then
        # Format: YYYYMMDD_hhmmss
        echo "${BASH_REMATCH[1]}-${BASH_REMATCH[2]}-${BASH_REMATCH[3]} ${BASH_REMATCH[4]:0:2}:${BASH_REMATCH[4]:2:2}:${BASH_REMATCH[4]:4:2}"
    else
        echo ""
    fi
}

# Function to move the file - if the filename already exists and the file size differs, the filename will be changed
move_file() {
  src_file=$1
  extension="${src_file##*.}"
  dest_dir="$2/"
  dest_file="${dest_dir}$(basename "$src_file")"

  # Check if the destination file exists
  if [ -e "$dest_file" ]; then
    # Compare file sizes
    src_size=$(stat --format=%s "$src_file")
    dest_size=$(stat --format=%s "$dest_file")

    # If the sizes are different, rename the source file before moving
    if [ "$src_size" -ne "$dest_size" ]; then
      # Start checking for a suffix (e.g., -1, -2, etc.)
      suffix=1
      while [ -e "${dest_dir}$(basename "$src_file" ".$extension")-${suffix}.${extension}" ]; do
        ((suffix++))  # Increment suffix if the file exists
      done
      dest_file="${dest_dir}$(basename "$src_file" ".$extension")-${suffix}.${extension}"
    fi
  fi

  # Move (or rename) the file
  mv "$src_file" "$dest_file"
  echo "Moving $src_file to $dest_file"
}

# Recursively search for images
find "$SOURCE_DIR" -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.tif" -o -iname "*.png" -o -iname "*.gif" -o -iname "*.nef" -o -iname "*.tiff" -o -iname "*.mp4" -o -iname "*.mp" -o -iname "*.mp~2" -o -iname "*.mov" -o -iname "*.avi" -o -iname "*.mpg" -o -iname "*.m4v" -o -iname "*.3gp" \) | while read FILE; do
    echo "$FILE"

    # Read EXIF data (year and month)
    YEAR=$(exiftool -DateTimeOriginal -d "%Y" "$FILE" | awk -F': ' '{print $2}')

    if [ -z "$YEAR" ] || [[ "$YEAR" == 00* ]] || [[ "${YEAR}" -lt 2000 ]] || [[ "${YEAR}" -gt 2025 ]]; then
        YEAR=$(exiftool -CreateDate -d "%Y" "$FILE" | awk -F': ' '{print $2}')
    fi

    MONTH=$(exiftool -DateTimeOriginal -d "%m" "$FILE" | awk -F': ' '{print $2}')
    if [ -z "$MONTH" ] || [[ "$MONTH" == 00* ]]; then
        MONTH=$(exiftool -CreateDate -d "%m" "$FILE" | awk -F': ' '{print $2}')
    fi
    
    if [ -z "$YEAR" ] || [[ "$YEAR" == 00* ]] || [[ "${YEAR}" -lt 2000 ]] || [[ "${YEAR}" -gt 2025 ]] || [ -z "$MONTH" ] || [ "$MONTH" == "00" ]; then
      # If no EXIF data is available, check if the date can be extracted from the filename
      date=$(extract_date_from_filename "$(basename "$FILE")")
      if [ ! -z "$date" ]; then
          set_exif_creation_date "$FILE" "$date"    
    	  YEAR=$(echo "$date" | cut -d '-' -f 1)
          MONTH=$(echo "$date" | cut -d '-' -f 2)
      fi
    fi
    
    # some special cases
    if [ -z "$YEAR" ] || [[ "$YEAR" == 00* ]] || [[ "${YEAR}" -lt 2000 ]] || [[ "${YEAR}" -gt 2025 ]]; then
        YEAR=$(exiftool -DateTime -d "%Y" "$FILE" | awk -F': ' '{print $2}')
    fi

    if [ -z "$MONTH" ] || [[ "$MONTH" == 00* ]]; then
        MONTH=$(exiftool -DateTime -d "%m" "$FILE" | awk -F': ' '{print $2}')
    fi
    
    # If no EXIF data is available, check if there is a .json file where the data is present
    if [ -z "$YEAR" ] || [[ "$YEAR" == 00* ]] || [[ "${YEAR}" -lt 2000 ]] || [[ "${YEAR}" -gt 2025 ]] || [ -z "$MONTH" ] || [[ "$MONTH" == 00* ]]; then
      filename=$(basename "$FILE")
      json_file=$(find "$(dirname "$FILE")" -type f -name "${filename}*.json" -print -quit 2>/dev/null)

      if [ -z "${json_file//[[:space:]]/}" ] && [[ "$filename" == *"-bearbeitet"* ]]; then
      	json_file=$(find "$(dirname "$FILE")" -type f -name "${filename//\-bearbeitet/}*.json" -print -quit 2>/dev/null)
      fi
      
      if [ -z "${json_file//[[:space:]]/}" ] && [[ "$filename" =~ (\([0-9]+\)) ]]; then
      	json_file=$(find "$(dirname "$FILE")" -type f -name "${filename//${BASH_REMATCH[1]}/}*${BASH_REMATCH[1]}.json" -print -quit 2>/dev/null)
      fi
      
      echo "$json_file"
            
      if [[ ! -z "${json_file//[[:space:]]/}" ]]; then     
        date=$(jq -r '.photoTakenTime.formatted | strptime("%d.%m.%Y, %H:%M:%S UTC") | strftime("%Y-%m-%d %H:%M:%S")' "$json_file")
        if [ ! -z "$date" ]; then
      	  set_exif_creation_date "$FILE" "$date"

	  YEAR=$(jq -r '.photoTakenTime.formatted | strptime("%d.%m.%Y, %H:%M:%S UTC") | strftime("%Y")' "$json_file")
      	  MONTH=$(jq -r '.photoTakenTime.formatted | strptime("%d.%m.%Y, %H:%M:%S UTC") | strftime("%m")' "$json_file")
        fi
      
      fi	
      
    fi
    
    # If nothing was found, skip it
    if [ -z "$YEAR" ] || [[ "$YEAR" == 00* ]] || [[ "${YEAR}" -lt 2000 ]] || [[ "${YEAR}" -gt 2025 ]] || [ -z "$MONTH" ] || [[ "$MONTH" == 00* ]]; then
        continue
    fi
    
    # Create target folder
    DEST="$DEST_DIR/$YEAR/$MONTH"
    mkdir -p "$DEST"
    
    # Move the file
    move_file "$FILE" "$DEST"
    
done

🔧 4. How the Script Works

  • 📂 SOURCE_DIR: Set this variable to the directory where you stored your exported Google Photos data (the folder you downloaded from Google Takeout).
  • 📁 DEST_DIR: This is the directory where the files will be moved or copied in Nextcloud.

The script does the following:

  1. 🔍 Searches for media files such as .jpg, .jpeg, .png, .mp4, .mov, and other common formats.
  2. 📅 Extracts the year and month from the EXIF metadata of each file. If the metadata is missing, it falls back to the year 9999 and month 99 to be easily identified in the file manager.
  3. 🗂️ Creates directories in the format /nextcloud/YEAR/MONTH to organize the files.
  4. 📦 Copies the files into the correct directory. If you want to move the files (instead of copying them), uncomment the line mv "$FILE" "$DEST_FILE".

📅 5. Using the Organized Files in Nextcloud with Memories App

Once the photos and videos are organized in the Nextcloud directory, you can use the Memories app in Nextcloud to automatically detect and manage your media files. Here’s how to integrate the files with the Memories app:

  1. ⚙️ Install the Memories app in Nextcloud:
    • In your Nextcloud instance, go to Apps and search for Memories. Install it if you haven’t already.
  2. ⬆️ Upload the Files:
    • Upload the organized files into your Nextcloud instance under the folder where you placed your organized photos and videos.
  3. 🎉 Enjoy the Memories App:
    • Once uploaded, the Memories app will automatically categorize and display your media based on date and time. The app organizes your photos into albums based on the EXIF metadata, so you can easily browse your photos by year and month.

📲 6. Automatic Upload from Smartphone to Nextcloud

For those who want to continue using Nextcloud for backing up their photos directly from their smartphones, the Nextcloud mobile app is a perfect solution. The app allows you to automatically upload photos and videos to your Nextcloud server as soon as they’re taken on your smartphone.

Steps to Enable Automatic Upload in the Nextcloud Mobile App:

  1. 📲 Install the Nextcloud Mobile App:
    • Download the Nextcloud app for iOS or Android from your respective app store.
  2. ⚙️ Enable Auto Upload:
    • Open the Nextcloud app, log in to your account, and navigate to Settings.
    • Enable the Auto Upload feature under the Camera Upload settings.
  3. 🔧 Configure Auto Upload:
    • Choose whether to upload photos only over Wi-Fi or both Wi-Fi and mobile data.
    • You can also choose specific folders within your Nextcloud instance where the photos will be uploaded.

Once activated, the Nextcloud app will automatically upload photos and videos as you capture them, ensuring your media is always backed up in real-time without having to manually transfer files.


🧠 Final Thoughts

By exporting your Google Photos via Google Takeout and organizing them using the provided script, you can ensure that your media is properly organized in Nextcloud and managed by the Memories app. This process helps you transition your photos from Google’s cloud service to your own private cloud, ensuring that your data stays under your control while still maintaining easy access and organization.

Additionally, with the Nextcloud mobile app, you can seamlessly upload photos and videos directly from your smartphone to your Nextcloud instance, keeping your media synced and backed up effortlessly.

This method is highly customizable and can be adapted for different cloud platforms or photo management systems. By making the switch to Nextcloud and using the Memories app, you can take full control of your media and enjoy enhanced privacy and organization.

This post is licensed under CC BY 4.0 by the author.