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:
- 🌐 Go to Google Takeout:
- Visit Google Takeout in your browser.
- 🖼️ Select Google Photos:
- Scroll down and select Google Photos. You can select all albums or specific ones you want to export.
- ⚙️ 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.
- Choose the file type and size for the export. Google Takeout will create a compressed
- ▶️ 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.
- 📥 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:
- 🔍 Searches for media files such as
.jpg
,.jpeg
,.png
,.mp4
,.mov
, and other common formats. - 📅 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 month99
to be easily identified in the file manager. - 🗂️ Creates directories in the format
/nextcloud/YEAR/MONTH
to organize the files. - 📦 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:
- ⚙️ Install the Memories app in Nextcloud:
- In your Nextcloud instance, go to Apps and search for Memories. Install it if you haven’t already.
- ⬆️ Upload the Files:
- Upload the organized files into your Nextcloud instance under the folder where you placed your organized photos and videos.
- 🎉 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:
- 📲 Install the Nextcloud Mobile App:
- Download the Nextcloud app for iOS or Android from your respective app store.
- ⚙️ 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.
- 🔧 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.