Skip to content

Commit

Permalink
Merge branch 'master' into add-iOS-live-photo-support-nightly-branch
Browse files Browse the repository at this point in the history
  • Loading branch information
TheLastGimbus committed Sep 23, 2023
2 parents 33a3756 + 8e4264e commit 547cf85
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 98 deletions.
2 changes: 1 addition & 1 deletion .fvm/fvm_config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"flutterSdkVersion": "3.7.9",
"flutterSdkVersion": "3.13.3",
"flavors": {}
}
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
## 3.4.2

### Bug fixes again 🐛

- (maybe?) fix weird windoza trailing spaces in folder names (literally wtf??) - #212

Not sure about this one so hope there will be no day-1 patch 😇🙏

- update to Dart 3 🔥
- recognize `.mts` files as videos, unlike Apache 😒 - #223
- change shortcuts/symlinks to relative so it doesn't break on folder move 🤦 - #232
- don't fail on set-file-modification errors - turns out there are lot of these - #229

### Happy takeouts 👽

## 3.4.1

- Lot of serious bug fixes
Expand Down
31 changes: 18 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,19 @@ Since `v3.2.0`, `gpth` is interactive 🎉 - you don't need to type any complica

If you want to run it on Synology, have problems with interactive, or just love cmd, look at ["Running manually with cmd"](#running-manually-with-cmd). Otherwise, just:

0. Get all your photos in [Google Takeout](https://takeout.google.com/) 📥
- "deselect all" and then select only Google Photos
### 1. Get all your photos from [Google Takeout](https://takeout.google.com/) 📥
"deselect all" and then select only Google Photos

<img width="75%" alt="gpth usage image tutorial" src="https://user-images.githubusercontent.com/40139196/229353040-14af25c1-5454-4d1f-866a-8b10d5a7c648.png">
1. Unzip them all and merge into one, so that all "Takeout" folders become one
<img width="75%" alt="gpth usage image tutorial" src="https://user-images.githubusercontent.com/40139196/229353040-14af25c1-5454-4d1f-866a-8b10d5a7c648.png">

### 2. Unzip them all and merge into one, so that all "Takeout" folders become one

<img width="75%" alt="Unzip image tutorial" src="https://user-images.githubusercontent.com/40139196/229361367-b9803ab9-2724-4ddf-9af5-4df507e02dfe.png">
2. Download the executable for your system from [releases tab](https://github.com/TheLastGimbus/GooglePhotosTakeoutHelper/releases) 🛒
- [also available on AUR 😏](https://aur.archlinux.org/packages/gpth-bin)
3. - On Windoza: just double-click the downloaded `.exe` 🎉 - tell windoza defender that it's safe, and follow prompted instructions 🧾

### 3. Download the executable for your system from [releases tab](https://github.com/TheLastGimbus/GooglePhotosTakeoutHelper/releases) 🛒 ([also available on AUR 😏](https://aur.archlinux.org/packages/gpth-bin))

### 4. Run `gpth`
- On Windoza: just double-click the downloaded `.exe` 🎉 - tell windoza defender that it's safe, and follow prompted instructions 🧾
- On Mac/Linux: open terminal, `cd` to the folder with downloaded executable and run it:
```bash
# if you have Mac with M1/M2 chip, you need to enable x86 emulation
Expand All @@ -45,15 +48,15 @@ If you want to run it on Synology, have problems with interactive, or just love
./gpth-macos # or ./gpth-linux
# follow prompted instructions 🥰
```
4. Most of your photos should have correct original EXIFs (metadata), but if you want, you can insert them everywhere with `exiftool`, so you won't lose their creation time
### 5. Most of your photos should have correct original EXIFs (metadata), but if you want, you can insert them everywhere with `exiftool`, so you won't lose their creation time
- Download Phil Harvey's exiftool: https://exiftool.sourceforge.net/
- Open the cmd/terminal, and run
```bash
# cd to folder where you downloaded exiftool
cd Downloads
# run it on your output folder:
# (the '*' at the end means "run on all files")
exiftool -overwrite_original -r -P "-AllDates<FileModifyDate" "your/output/folder/ALL_PHOTOS/*"
# (the '-r' means "run on all files/in sub-folders" aka recursively)
exiftool -overwrite_original -r -P "-AllDates<FileModifyDate" "your/output/folder/ALL_PHOTOS/"
```
Done! Enjoy your photos!!!
Expand Down Expand Up @@ -91,7 +94,7 @@ In that case:
# select which album solution you like - see --help for all of them
```

You can check all cmd flags by running `gpth --help` - for exapmle, the `--divide-to-dates` flag
You can check all cmd flags by running `gpth --help` - for example, the `--divide-to-dates` flag

## If I helped you, you can consider donating me ☕
I spent **a lot of** time fixing bugs and making this work stable 💖 - would be super thankful for any donations 🥰
Expand All @@ -109,9 +112,11 @@ I spent **a lot of** time fixing bugs and making this work stable 💖 - would b
### What to do when you got rid of Google Photos? What are the alternatives? 🗺
- I really recommend you using [Syncthing](https://syncthing.net/) for syncing your photos and files across devices. It does so through your local Wi-Fi, so you're not dependent on any service or internet connection. It will also keep original file creation date and metadata, so it resolves Android issue that I mentioned before.
- If you want something more centralized but also self-hosted, [Nextcloud](https://nextcloud.com) is a nice choice, but its approach to photos is still not perfect. (And you need to set up your own server)
- [Immich](https://immich.app/) aims to be full blown GPhotos replacement - it's still under development, but already looks great!

- Same with [Photoprism](https://photoprism.org/), tho this one is in development longer (may be more mature)

- Guys at [Photoprism](https://photoprism.org/) are working on full Google Photos alternative, with search and AI tagging etc, but it's stil work in progress
- If you want something more centralized but also self-hosted, [Nextcloud](https://nextcloud.com) is a nice choice, but its approach to photos is still not perfect. (And you need to set up your own server)

### Other Takeout projects
I used this tool to export my notes to markdown - you can then edit them with any markdown editor you like :)
Expand Down
2 changes: 1 addition & 1 deletion bin/gpth.dart
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ void main(List<String> arguments) async {
// I wish that, thanks to this, we may find some jsons in albums that would
// be broken in shithole of big-ass year folders

print('Finding albums...');
print('Finding albums (this may take some time, dont worry :) ...');
findAlbums(media);

/// #######################
Expand Down
2 changes: 2 additions & 0 deletions lib/extras.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const extraFormats = [
'-modificato',
// FR - for @palijn's problems <3
'-modifié',
// ES - @Sappstal report
'-ha editado',
// Add more "edited" flags in more languages if you want.
// They need to be lowercase.
];
Expand Down
32 changes: 23 additions & 9 deletions lib/moving.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ File findNotExistingName(File initialFile) {
Future<File> createShortcut(Directory location, File target) async {
final name = '${p.basename(target.path)}${Platform.isWindows ? '.lnk' : ''}';
final link = findNotExistingName(File(p.join(location.path, name)));
// this must be relative to not break when user moves whole folder around:
// https://github.com/TheLastGimbus/GooglePhotosTakeoutHelper/issues/232
final targetRelativePath = p.relative(target.path, from: link.parent.path);
if (Platform.isWindows) {
final res = await Process.run(
'powershell.exe',
Expand All @@ -40,7 +43,7 @@ Future<File> createShortcut(Directory location, File target) async {
'-Command',
'\$ws = New-Object -ComObject WScript.Shell; '
'\$s = \$ws.CreateShortcut(\'${link.path}\'); '
'\$s.TargetPath = \'${p.absolute(target.path)}\'; '
'\$s.TargetPath = \'$targetRelativePath\'; '
'\$s.Save()',
],
);
Expand All @@ -53,7 +56,7 @@ Future<File> createShortcut(Directory location, File target) async {
}
return File(link.path);
} else {
return File((await Link(link.path).create(p.absolute(target.path))).path);
return File((await Link(link.path).create(targetRelativePath)).path);
}
}

Expand Down Expand Up @@ -105,15 +108,15 @@ Stream<int> moveFiles(
final folder = Directory(
p.join(
output.path,
file.key ?? 'ALL_PHOTOS', // album or all
divideToDates
? date == null
? 'date-unknown'
: p.join(
file.key?.trim() ?? 'ALL_PHOTOS', // album or all
date == null
? 'date-unknown'
: divideToDates
? p.join(
'${date.year}',
date.month.toString().padLeft(2, '0'),
)
: '',
: '',
),
);
// now folder logic is so complex i'll just create it every time 🤷
Expand Down Expand Up @@ -162,7 +165,18 @@ Stream<int> moveFiles(
'(not supported on Windows) - will be set to 1970-01-01');
time = DateTime(1970);
}
await result.setLastModified(time);
try {
await result.setLastModified(time);
} on OSError catch (e) {
// Sometimes windoza throws error but successes anyway 🙃:
// https://github.com/TheLastGimbus/GooglePhotosTakeoutHelper/issues/229#issuecomment-1685085899
// That's why this is here
if (e.errorCode != 0) {
print("WARNING: Can't set modification time on $result: $e");
}
} catch (e) {
print("WARNING: Can't set modification time on $result: $e");
}

// one copy/move/whatever - one yield
yield ++i;
Expand Down
16 changes: 13 additions & 3 deletions lib/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:proper_filesize/proper_filesize.dart';
import 'media.dart';

// remember to bump this
const version = '3.4.1';
const version = '3.4.2';

/// max file size to read for exif/hash/anything
const maxFileSize = 64 * 1024 * 1024;
Expand All @@ -30,15 +30,25 @@ extension X on Iterable<FileSystemEntity> {
/// Easy extension allowing you to filter for files that are photo or video
Iterable<File> wherePhotoVideo() => whereType<File>().where((e) {
final mime = lookupMimeType(e.path) ?? "";
return mime.startsWith('image/') || mime.startsWith('video/');
return mime.startsWith('image/') ||
mime.startsWith('video/') ||
// https://github.com/TheLastGimbus/GooglePhotosTakeoutHelper/issues/223
// https://github.com/dart-lang/mime/issues/102
// 🙃🙃
mime == 'model/vnd.mts';
});
}

extension Y on Stream<FileSystemEntity> {
/// Easy extension allowing you to filter for files that are photo or video
Stream<File> wherePhotoVideo() => whereType<File>().where((e) {
final mime = lookupMimeType(e.path) ?? "";
return mime.startsWith('image/') || mime.startsWith('video/');
return mime.startsWith('image/') ||
mime.startsWith('video/') ||
// https://github.com/TheLastGimbus/GooglePhotosTakeoutHelper/issues/223
// https://github.com/dart-lang/mime/issues/102
// 🙃🙃
mime == 'model/vnd.mts';
});
}

Expand Down
Loading

0 comments on commit 547cf85

Please sign in to comment.