DEV Community

Cover image for Manage your Google Photo account with Python! (p.1)

Manage your Google Photo account with Python! (p.1)

Davide Del Papa on May 17, 2020

(Photo by Brandon Erlinger-Ford on Unsplash) Chances are that if you have an Android device with a Google account connected to it, you have alread...
Collapse
 
clanmills profile image
Robin Mills • Edited

Wow. Great Work. Your code worked first time for me and showed me a photo from my Google Photo Library that I took on Thursday.

Now, I'm going to read your code and discover how you did that. Amazing.

I'm the retired maintainer of Exiv2 the C++ Metadata Library. exiv2.org

I'm rebuilding my web-site from scratch because it's 20 years old, has 80,000 photos in 2000 albums, 400,000 files and occupies 10GB on the web-server. I'm going to store the photos on Google Photos and generate the photo albums in JavaScript. I've made good progress and confident that the web-site will be less than 100mb by the end of September. Here's a typical album web-page: clanmills.com/2021/Lizzie

The code for the page is:

505 rmills@rmillsm1:~/clanmills $ cat 2021/Lizzie/default.shtml 
<!--#include virtual="/albumhead.inc" -->
<!--#include virtual="/menu.inc" -->
<!--#include virtual="/albumtail.inc" -->
<script type="text/javascript">
   var title   = "Lizzie"
   var data    = 'https://photos.app.goo.gl/sQRaVMZiyTr5T74y8'
   var updated = '2021-08-20 14:52:25'
   buildPage();
</script>
506 rmills@rmillsm1:~/clanmills $ 
Enter fullscreen mode Exit fullscreen mode

The next job is to understand enough Python/REST/Photos magic to generate the list of album files automatically. The script will run once a day at home and update clanmills.com. So, when I take photos with my phone, they be posted on clanmills.com without moving a finger.

Thanks to your python code, I'm confident of success. Thank You Very Much.

Collapse
 
davidedelpapa profile image
Davide Del Papa

You are welcome. I made the lib to script access to my wedding pics myself, so I guess your use case should be not too difficult to tackle as well.
Good luck 🤞

Collapse
 
clanmills profile image
Robin Mills

Davide: I love your code. It's beautiful and clear.

I fixed a tiny bug in album.py. When I iterate the albums (I have 250 albums) the loop dies at the end saying "object isn't interable:"

    'title': 'BoysInSanJose2002'}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Python/3.8/site-packages/gphotospy/album.py", line 533, in list
    for album in curr_list:
TypeError: 'NoneType' object is not iterable
Enter fullscreen mode Exit fullscreen mode

Here's my fix:

0a1
> from collections.abc import Iterable
533,534c534,536
<             for album in curr_list:
<                 yield album
---
>             if isinstance(curr_list, Iterable):
>                 for album in curr_list:
>                     yield album
Enter fullscreen mode Exit fullscreen mode

Question. Is the code in GitHub. Can I provide a PR if I find other issues?

Collapse
 
happy985 profile image
Happy985

Hello,

When I creat "OAuth client ID" I choose "Web application" because there are not "other"in the new version.
So I download my Json file as you said. but I execute this line code
"service = authorize.init(CLIENT_SECRET_FILE)"
I obtain this Error.
So what is the problem please
Thank you

File "C:\Users\Admin\Anaconda3\lib\site-packages\gphotospy\authorize.py", line 55, in init
credentials = get_credentials(secrets)

File "C:\Users\Admin\Anaconda3\lib\site-packages\gphotospy\authorize.py", line 34, in get_credentials
credentials = app_flow.run_local_server()

File "C:\Users\Admin\Anaconda3\lib\site-packages\google_auth_oauthlib\flow.py", line 458, in run_local_server
host, port, wsgi_app, handler_class=_WSGIRequestHandler

File "C:\Users\Admin\Anaconda3\lib\wsgiref\simple_server.py", line 153, in make_server
server = server_class((host, port), handler_class)

File "C:\Users\Admin\Anaconda3\lib\socketserver.py", line 452, in init
self.server_bind()

File "C:\Users\Admin\Anaconda3\lib\wsgiref\simple_server.py", line 50, in server_bind
HTTPServer.server_bind(self)

File "C:\Users\Admin\Anaconda3\lib\http\server.py", line 137, in server_bind
socketserver.TCPServer.server_bind(self)

File "C:\Users\Admin\Anaconda3\lib\socketserver.py", line 466, in server_bind
self.socket.bind(self.server_address)

OSError: [WinError 10013] Une tentative d’accès à un socket de manière interdite par ses autorisations d’accès a été tentée