Advertisement
pwtenny

Do a useful thing with Google Photos backups

Dec 30th, 2021
1,831
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 2.75 KB | None | 0 0
  1. # fixdates.pl (pwtenny AT the place where google mail goes)
  2. # 2021-12-30
  3. # Extract time/date stamps from JSON files in Google Photos backups/exports and set them
  4. # for all the archived photos and videos on the local file system. Or something.
  5.  
  6. # Where to start looking for photos. Everything in this directory is searched recursively.
  7. # $start shouldn't have ANY photos in it, if it does, they aren't going to get got.
  8. $start = "D:/Documents/Downloads/takeout-20211229T132532Z-001/Takeout/Google Photos/";
  9.  
  10. opendir($dh, $start) || die "The \$start var isn't a valid directory. It's not my fault. IT'S NOT MY FAULT.\n";
  11.  
  12. # Iterate through every file/folder in $start
  13. while(readdir $dh)
  14. {
  15.     # Trying to open ".." will briefly read the parent directory of $start, and "." will make us read $start twice.
  16.     next if($_ eq '..' || $_ eq '.');
  17.  
  18.     if(-d $_)
  19.     {
  20.         search_directory($start.$_);
  21.     }
  22. }
  23.  
  24. # Iterate through everything in a sub-directory of $start, ignoring .JSON files.
  25. sub search_directory
  26. {
  27.     $where = shift;
  28.     opendir($ldh, $where);
  29.  
  30.     # This is not a recursive search. AFAIK Google Photo exports everything in one-layer-deep directories
  31.     # and that's it. No sub-directories in any of them. (Perhaps that's possible?)
  32.     while(readdir $ldh)
  33.     {
  34.         next if($_ eq '..' || $_ eq '.');
  35.         next if($_ =~ /\.json/);  # Don't want these.
  36.  
  37.         print "$where: ".$_."\n"; # Delete this if you don't want a bunch of console spam. But you should. Spam is delicious.
  38.         set_datetime($where.'/'.$_);
  39.     }
  40.     print "\n";
  41. }
  42.  
  43. # Open a .JSON file and DIRTY parse out a timestamp, then set the file attributes accordingly.
  44. # I honestly don't know if every JSON file has both a photoTakenTime and a creationTime,
  45. # but I do know that we want photoTakenTime if it exists, since creationTime is *always* when the file
  46. # was uploaded to Google Photos.
  47. sub set_datetime
  48. {
  49.     $file = shift;
  50.     $json = $file.".json";
  51.     $ts = "";
  52.  
  53.     open(fh,$json);
  54.     $json_data = join("", <fh>);
  55.     close fh;
  56.  
  57.     if($json_data =~ /photoTakenTime/)
  58.     {
  59.         ($photoTakenTime) = $json_data =~ /"photoTakenTime": \{(.*?)\}/gs;
  60.         ($ts) = $photoTakenTime =~ /"timestamp": "(.*?)",/gs;
  61.     }
  62.     else
  63.     {
  64.         ($ts) = $json_data =~ /"timestamp": "(.*?)",/gs;
  65.     }
  66.  
  67.     use Win32API::File::Time qw{:win};
  68.     $truefalse = SetFileTime($file, $ts, $ts, $ts);
  69.     # Notice how I didn't check the return code to see if it worked?
  70. }
  71.  
  72. #   Code Monkey get up get coffee
  73. #   Code Monkey go to job
  74. #   Code Monkey have boring meeting
  75. #   With boring manager Rob
  76. #   Rob say Code Monkey very dilligent
  77. #   But his output stink
  78. #   His code not “functional” or “elegant”
  79. #   What do Code Monkey think?
  80. #   Code Monkey think maybe manager want to write god damned login page himself
  81. #   Code Monkey not say it out loud
  82. #   Code Monkey not crazy, just proud
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement