J'ai repris le script de FTG (merci bcp à lui, j'ai pas changé grand chose) et j'ai ajouté une interface avec zenity (grâce au code de PyZenity de Brian Ramos). J'ai jamais fait de Python alors soyez indulgent.
L'essentiel du code est à la fin.
# -*- coding: utf-8 -*-
# Envoi de photos sur picasaweb
# Dépend de :
# gdata [ à télécharger sur http://code.google.com/p/gdata-python-client/downloads/list et installer - cf. INSTALL.TXT - ]
# nautilus-actions
# zenity
# Dans Nautilus Action rentrer
# Chemin : /usr/bin/python </chemni/vers/script>
# Parametres : %M
# Conditions :
# Types Mime : image/*
# Cocher : Apparaît si la selection contient plusieurs fichiers ou dossiers
#
######-PyZenity-##########
#Afin de ne pas avoir à télécharger et installer le code de PyZenity, je l'ai reproduis en partie ici.
######################################################################################################
# Name: iPyZenity.py
# Author: Brian Ramos
# Created: 10/17/2005
# Revision Information:
# $Date: $
# $Revision: $
# $Author: bramos $
#
# Licence: MIT Licence
#
# Copyright (c) 2005 Brian Ramos
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
################################################################################
from datetime import date
from subprocess import Popen, PIPE
from itertools import chain
from os import path
__all__ = ['GetText','Question', 'Warning', 'ErrorMessage', 'Progress','List' ]
zen_exec = 'zenity'
def run_zenity(type, *args):
return Popen([zen_exec, type] + list(args), stdin=PIPE, stdout=PIPE)
def List(column_names, title=None, boolstyle=None, editable=False,
select_col=None, sep='|', data=[]):
"""Present a list of items to select.
This will raise a Zenity List Dialog populated with the colomns and rows
specified and return either the cell or row that was selected or None if
the user hit cancel.
column_names - A tuple or list containing the names of the columns.
title - The title of the dialog box.
boolstyle - Whether the first columns should be a bool option ("checklist",
"radiolist") or None if it should be a text field.
editable - True if the user can edit the cells.
select_col - The column number of the selected cell to return or "ALL" to
return the entire row.
sep - Token to use as the row separator when parsing Zenity's return.
Cells should not contain this token.
data - A list or tuple of tuples that contain the cells in the row. The
size of the row's tuple must be equal to the number of columns."""
args = []
for column in column_names:
args.append('--column=%s' % column)
if title:
args.append('--title=%s' % title)
if boolstyle:
if not (boolstyle == 'checklist' or boolstyle == 'radiolist'):
raise ValueError('"%s" is not a proper boolean column style.'
% boolstyle)
args.append('--' + boolstyle)
if editable:
args.append('--editable')
if select_col:
args.append('--print-column=%s' % select_col)
if sep != '|':
args.append('--separator=%s' % sep)
for datum in chain(*data):
args.append(str(datum))
p = run_zenity('--list', *args)
if p.wait() == 0:
return p.stdout.read().strip().split(sep)
def ErrorMessage(text):
"""Show an error message dialog to the user.
This will raise a Zenity Error Dialog with a description of the error.
text - A description of the error."""
run_zenity('--error', '--text=%s' % text).wait()
def Question(text):
"""Ask the user a question.
This will raise a Zenity Question Dialog that will present the user with an
OK/Cancel dialog box. It returns True if the user clicked OK; False on
Cancel.
text - The question to ask."""
return run_zenity('--question', '--text=%s' % text).wait() == 0
def Warning(text):
"""Show a warning message dialog to the user.
This will raise a Zenity Warning Dialog with a description of the warning.
It returns True if the user clicked OK; False on cancel.
text - A description of the warning."""
return run_zenity('--warning', '--text=%s' % text).wait() == 0
def Progress(text='', percentage=0, auto_close=False, pulsate=False):
"""Show a progress dialog to the user.
This will raise a Zenity Progress Dialog. It returns a callback that
accepts two arguments. The first is a numeric value of the percent
complete. The second is a message about the progress.
NOTE: This function sends the SIGHUP signal if the user hits the cancel
button. You must connect to this signal if you do not want your
application to exit.
text - The initial message about the progress.
percentage - The initial percentage to set the progress bar to.
auto_close - True if the dialog should close automatically if it reaches
100%.
pulsate - True is the status should pulsate instead of progress."""
args = []
if text:
args.append('--text=%s' % text)
if percentage:
args.append('--percentage=%s' % percentage)
if auto_close:
args.append('--auto-close=%s' % auto_close)
if pulsate:
args.append('--pulsate=%s' % pulsate)
p = Popen([zen_exec, '--progress'] + args, stdin=PIPE, stdout=PIPE)
def update(percent, message=''):
if type(percent) == float:
percent = int(percent * 100)
p.stdin.write(str(percent) + '\n')
if message:
p.stdin.write('# %s\n' % message)
return p.returncode
return update
def GetText(text='', entry_text='', password=False):
"""Get some text from the user.
This will raise a Zenity Text Entry Dialog. It returns the text the user
entered or None if the user hit cancel.
text - A description of the text to enter.
entry_text - The initial value of the text entry box.
password - True if text entered should be hidden by stars."""
args = []
if text:
args.append('--text=%s' % text)
if entry_text:
args.append('--entry-text=%s' % entry_text)
if password:
args.append('--hide-text')
p = run_zenity('--entry', *args)
if p.wait() == 0:
return p.stdout.read()[:-1]
########################################################
#####-END of PyZenity-######
import sys
import gdata.photos.service
#import PyZenity
#import bz2
#Paramètres : possibilité de les rentrer en dur
email=GetText(text='Email', entry_text='@gmail.com', password=False)
password=GetText(text='Mot de passe', entry_text='Picasa', password=True)
#key=...
########-Fonction d'envoi des photos-########
def send_photo(album):
album_url = '/data/feed/api/user/%s/album/%s' % ('default', album)
update=Progress(text='Envoi des photos ...', percentage=0, auto_close=False, pulsate=False)
percent=0
for i in range(len(sys.argv)-1):
text='Envoi des photos ... ('+str(i+1)+'/'+str(len(sys.argv)-1)+')'
print str(percent)
update(percent,text)
entry = gd_client.InsertPhotoSimple(album_url, 'New Photo','', sys.argv[i+1], content_type='image/jpeg')
percent=int(float(i+1)/(len(sys.argv)-1)*100)
#############################################
#Connection à picasaweb
gd_client = gdata.photos.service.PhotosService()
gd_client.email = email
#gd_client.password = bz2.decompress(key)
gd_client.password = password
gd_client.source = 'exampleCo-exampleApp-1'
try:
gd_client.ProgrammaticLogin()
except gdata.service.CaptchaRequired:
# print('Required Captcha')
ErrorMessage('Required Captcha')
except gdata.service.BadAuthentication:
# print('Mauvaise authentification')
ErrorMessage('Mauvaise authentification')
except gdata_client.Error:
# print('Probleme de Login')
ErrorMessage('Probleme de Login')
else:
nouvelalbum=Question("Creer un nouvel album ?")
if nouvelalbum==True :
nom_album=GetText(text='Nom de l\'album (sans espaces): ', entry_text='Nouvel_album', password=False)
# Verification si l'album existe deja
feed = gd_client.GetUserFeed(user="default")
for entry in feed.entry:
while nom_album.lower()==str(entry.title.text).lower():
Warning("Cet album existe deja, veuillez entrer un autre nom !")
nom_album=GetText(text='Nom de l\'album (sans espaces): ', entry_text='Nouvel_album_2', password=False)
#Permissions sur l'album
acces="private"
#Crée l'album
entry = gd_client.InsertAlbum(nom_album, summary='This is an album', access=acces)
#Envoi des photos
send_photo(nom_album)
else:
# Choisir un album
feed = gd_client.GetUserFeed(user="default")
i=0
liste=()
for entry in feed.entry:
i=i+1
liste = liste + (entry.title.text,)
nom_album=(List(('Album',), title=None, boolstyle=None, editable=False, select_col=None, sep='|', data=[liste]))[0]
#Envoi des photos
send_photo(nom_album)