łatka do pobrania

Google OAuth 2.0 + Google Photo Library API

Google Photo Library API udostępnia Twojej aplikacji możliwość czytania, zapisywania i udostępnia zdjęć i filmów w galerii Google.

API wykorzystuje OAuth 2.0 do obsługi uwierzytelniania i autoryzacji. Twoja aplikacja może poprosić o dostęp do biblioteki Zdjęć Google użytkownika za pośrednictwem różnych zakresów autoryzacji udostępnianych przez interfejs API.

Pierwszym krokiem przy integracji jest założenie konta developerskiego wraz z projektem dla swojej aplikacji do której dodajemy API z których będziemy korzystać w celu wygenerowania klucza klienta i identyfikatora klienta, które umieszczamy w kodzie w miejsca PLACE HERE.


...
gapi.client.init({
        'apiKey': 'PLACE HERE YOUR APIKEY',
        'discoveryDocs': [discoveryUrl],
        'clientId': 'PLACE HERE YOUR CLIENTID',
        'scope': SCOPE
    }).then(function () {
...


Dzięki czemu mamy możliwość autoryzacji użytkowników przez protokół OAuth.

Jeżeli jesteśmy w fazie testów a nasza aplikacja nie przeszła jeszcze weryfikacji przez serwis Google podczas autoryzacji należy zastosować się do zdjęcia poniżej.

Funkcjonalności :

  • autoryzacja użytkownika z Google
  • wyświetlanie zdjęć z galerii użytkownika
  • możliwość wyświetlania zdjęć w trybie osi czasu
  • wyświetlanie zdjęć z wybranego albumu
  • filtrowanie po dacie
  • ograniczenie ilości wyświetlanych zdjęć


Załącznik zawiera przykład wykorzystania pokazany niżej oraz bibliotekę.
Prosty przykład wykorzystania przygotowanej biblioteki dla Google Photo Libery API.

 

Przygotowana biblioteka dla Google Photos Library API



class GooglePhotosLibraryAPI {
$/*
funkjca listuje zdjecia użytkownika (oś czasu)
parametr pageSize to maksymalna liczba zdjęć zwaracana w odpowiedzi
nextPageToken przyjmuje pusty string kiedy 1 strona
nextPageToken przyjmuje nextPageToken z odpowiedzi aby przejść do kolejnej strony
$*/
listPhotoGoogleApiTimeline (pageSize, nextPageToken, callbackFunction) {
gapi.client.request({
'path': 'https://photoslibrary.googleapis.com/v1/mediaItems',
'params': {
'pageSize': pageSize,
'pageToken': nextPageToken
},
'method': 'GET',
'body':{
'filters': {
'mediaTypeFilter': {
'mediaTypes': ['PHOTO']
}
}
}
}).then(function (resp) {
callbackFunction(resp);
}, function (reason) {
return reason;
});
}

$/*
funkcja listuje albumy użytkownika
parametr pageSize to maksymalna liczba albumów zwaracana w odpowiedzi
$*/
listAlbumsGoogleApi(pageSize, callbackFunction) {
gapi.client.request({
'path': 'https://photoslibrary.googleapis.com/v1/albums',
'params': {
'pageSize': pageSize
},
'method': 'GET'
}).then(function (resp) {
callbackFunction(resp);
}, function (reason) {
return reason;
});
}

$/*
funkjca listuje zdjecia z albumu
parametr pageSize to maksymalna liczba zdjęć zwaracana w odpowiedzi
parametr selectedToken to id albumu który chcemy wylistować
nextPageToken przyjmuje pusty string kiedy 1 strona
nextPageToken przyjmuje nextPageToken z odpowiedzi aby przejść do kolejnej strony
$*/
getSelectedValueListAlbumsGoogleApi (selectedToken, pageSize, nextPageToken, callbackFunction) {
gapi.client.request({
'path': 'https://photoslibrary.googleapis.com/v1/mediaItems:search',
'params': {
'albumId' : selectedToken,
'pageToken': nextPageToken,
'pageSize': pageSize
},
'method': 'POST'
}).then(function (resp) {
callbackFunction(resp);
}, function (reason) {
return reason;
});
}

$/*
funkjca filtruje galerię użytkownika
parametr pageSize to maksymalna liczba zdjęć zwaracana w odpowiedzi
startDay,startMonth,startYear - filtrowanie od
endDay,endMonth,endYear - filtrowanie do
nextPageToken przyjmuje pusty string kiedy 1 strona
nextPageToken przyjmuje nextPageToken z odpowiedzi aby przejść do kolejnej strony
$*/
searchPhotoGoogleApiFromAlbum (startDay, startMonth, startYear, endDay, endMonth, endYear, pageSize, nextPageToken, callbackFunction) {
gapi.client.request({
"path": "https://photoslibrary.googleapis.com/v1/mediaItems:search",
"method": "POST",
"params": {
"pageSize": pageSize,
"pageToken": nextPageToken
},
"body":{
"filters": {
"mediaTypeFilter": {
"mediaTypes": ["PHOTO"]
},
"dateFilter": {
"ranges": [
{
"startDate": {
"day": startDay,
"month": startMonth,
"year": startYear
},
"endDate": {
"day": endDay,
"month": endMonth,
"year": endYear
}
}
]
}
}
}
}).then(function (resp) {
callbackFunction(resp);
}, function (reason) {
return reason;
});
}

}

JavaScript OAuth 2.0



function handleClientLoad() {
// Load the API's client and auth2 modules.
// Call the initClient function after the modules load.
gapi.load('client:auth2', initClient);
}

function initClient() {
// Retrieve the discovery document for version 3 of Google Drive API.
// In practice, your app can retrieve one or more discovery documents.
var discoveryUrl = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';

// Initialize the gapi.client object, which app uses to make API requests.
// Get API key and client ID from API Console.
// 'scope' field specifies space-delimited list of access scopes.
gapi.client.init({
'apiKey': 'PLACE HERE YOUR APIKEY',
'discoveryDocs': [discoveryUrl],
'clientId': 'PLACE HERE YOUR CLIENTID',
'scope': SCOPE
}).then(function () {
GoogleAuth = gapi.auth2.getAuthInstance();
// Listen for sign-in state changes.
GoogleAuth.isSignedIn.listen(updateSigninStatus);
// Handle initial sign-in state. (Determine if user is already signed in.)
var user = GoogleAuth.currentUser.get();
setSigninStatus();
// Call handleAuthClick function when user clicks on
// "Sign In/Authorize" button.
jq('#sign-in-or-out-button').click(function() {
handleAuthClick();
});
jq('#revoke-access-button').click(function() {
revokeAccess();
});
});
}

function handleAuthClick() {
if (GoogleAuth.isSignedIn.get()) {
// User is authorized and has clicked 'Sign out' button.
GoogleAuth.signOut();
} else {
// User is not signed in. Start Google auth flow.
GoogleAuth.signIn();
}
}
function revokeAccess() {
GoogleAuth.disconnect();
}
function setSigninStatus(isSignedIn) {
var user = GoogleAuth.currentUser.get();
var isAuthorized = user.hasGrantedScopes(SCOPE);
if (isAuthorized) {
jq('#sign-in-or-out-button').html('Sign out');
jq('#revoke-access-button').css('display', 'inline-block');
jq('#auth-status').html('You are currently signed in and have granted ' +
'access to this app.');
googlePhotosLibrary.listAlbumsGoogleApi(20,drawMyAlbumDroplist)
googlePhotosLibrary.listPhotoGoogleApiTimeline(10,'', drawMyPicturesTimeline)
} else {
jq('#sign-in-or-out-button').html('Sign In/Authorize');
jq('#revoke-access-button').css('display', 'none');
jq('#auth-status').html('You have not authorized this app or you are ' +
'signed out.');
}
}
function updateSigninStatus(isSignedIn) {
setSigninStatus();
}

JavaScript API



$/*
funkcja obrabia odpowiedź i wyświetla zdjęcia na osi czasu
$*/
function drawMyPicturesTimeline(resp){
if(resp.result.nextPageToken){
jq('#nextPagePhotoGoogle').show()
nextPageToken = resp.result.nextPageToken
}else{
jq('#nextPagePhotoGoogle').hide()
nextPageToken = '';
}
for (i=0; i<resp.result.mediaItems.length; i++) {
baseUrl = resp.result.mediaItems[i].baseUrl
filename = resp.result.mediaItems[i].filename
var img = document.createElement('img');
img.height = 250;
img.style = "padding:10px";
img.title = filename;
img.src = baseUrl;
document.getElementById('imagediv').appendChild(img);
}
}
$/*
funkcja obrabia odpowiedź i tworzy dropliste albumów użytkownika
$*/
function drawMyAlbumDroplist(resp){
var div = document.querySelector("#dropListAlbumContainer"),
frag = document.createDocumentFragment(),
select = document.createElement("select");
select.options.add( new Option("Oś czasu",-1) );
for (i=0; i<resp.result.albums.length; i++) {
title = resp.result.albums[i].title;
productUrl = resp.result.albums[i].productUrl;
token = resp.result.albums[i].id;
select.options.add( new Option(title,token) );
}
frag.appendChild(select);
div.appendChild(frag);
}
$/*
funkcja na podstawie input hidden wybiera funkcję,
której ma użyć do wyświetlenia kolejnych zdjęć
$*/
function drawMoreMyPicturesManager(){
if( jq('#status').val() == 0 ) {
googlePhotosLibrary.listPhotoGoogleApiTimeline(10, nextPageToken, drawMyPicturesTimeline)
}else if ( jq('#status').val() == 1) {
googlePhotosLibrary.getSelectedValueListAlbumsGoogleApi(selectedToken, 10, nextPageToken, drawMyPicturesFromAlbum)
}else if ( jq('#status').val() == 2){
googlePhotosLibrary.searchPhotoGoogleApiFromAlbum(startDay, startMonth, startYear, endDay, endMonth, endYear, 10, nextPageToken, drawMyPicturesFromSearchDate)
}
}
$/*
funkcja na podstawie input hidden wybiera funkcję,
której ma użyć do wyświetlenia zdjęć z wybranego albumu
$*/
function drawMyPicturesFromDroplist(){
jq("#imagediv").empty();
nextPageToken='';
selectedToken = jq('#dropListAlbumContainer').find( "select" ).val();
if( selectedToken == -1 ) {
jq('#status').val(0)
googlePhotosLibrary.listPhotoGoogleApiTimeline(10, '', drawMyPicturesTimeline)
}else{
jq('#status').val(1)
googlePhotosLibrary.getSelectedValueListAlbumsGoogleApi(selectedToken, 10, '', drawMyPicturesFromAlbum)
}
}
$/*
funkcja na listuje zdjęcia z wybranego albumu
$*/
function drawMyPicturesFromAlbum(resp){
if(resp.result.nextPageToken){
jq('#nextPagePhotoGoogle').show()
nextPageToken = resp.result.nextPageToken
}else{
jq('#nextPagePhotoGoogle').hide()
nextPageToken = '';
}
for (i=0; i<resp.result.mediaItems.length; i++) {
baseUrl = resp.result.mediaItems[i].baseUrl
filename = resp.result.mediaItems[i].filename
var img = document.createElement('img');
img.height = 250;
img.style = "padding:10px";
img.title = filename;
img.src = baseUrl;
document.getElementById('imagediv').appendChild(img);
}
}
$/*
funkcja na listuje zdjęcia z filtru daty
$*/
function drawMyPicturesFromSearchDate(resp) {
if(!resp.result.mediaItems){
alert("Brak wyników.")
}else{
if(resp.result.nextPageToken){
nextPageToken = resp.result.nextPageToken
jq('#nextPagePhotoGoogle').show()
}else{
nextPageToken = '';
jq('#nextPagePhotoGoogle').hide()
}
for (i=0; i<resp.result.mediaItems.length; i++) {
baseUrl = resp.result.mediaItems[i].baseUrl
filename = resp.result.mediaItems[i].filename
var img = document.createElement('img');
img.height = 250;
img.style = "padding:10px";
img.title = filename;
img.src = baseUrl;
document.getElementById('imagediv').appendChild(img);
}
}
}
$/*
Pobiera dane ustawionej daty do filtrowania,
następnie przekazuje do funkcji wysyłającej zapytanie
$*/
function searchDateManager(){
jq('#status').val(2);
var date = new Date(jq('#startFilterDate').val());
startDay = date.getDate();
startMonth = date.getMonth() + 1;
startYear = date.getFullYear();
date = new Date(jq('#endFilterDate').val());
endDay = date.getDate();
endMonth = date.getMonth() + 1;
endYear = date.getFullYear();
googlePhotosLibrary.searchPhotoGoogleApiFromAlbum(startDay, startMonth, startYear, endDay, endMonth, endYear, 10, '', drawMyPicturesFromSearchDate)
}

HTML



<input type="hidden" id="status" value="0"/>
<button id="sign-in-or-out-button" style="margin-left: 25px">Sign In/Authorize</button>
<button id="revoke-access-button" style="display: none; margin-left: 25px">Revoke access</button>
$//container na status OAuth
<div id="auth-status" style="display: inline; padding-left: 25px"></div>
$//container na droplista z albumi
<div id="dropListAlbumContainer" style="display: inline; padding-left: 25px">
<input type="button" id="selectedAlbum" value="Wybierz" onclick="drawMyPicturesFromDroplist()" />
</div>
od:
<input type="date" id="startFilterDate"/>
do:
<input type="date" id="endFilterDate"/>
<input type="button" id="submitDateFilterButton" value="Szukaj" onclick="searchDateManager()">
$//container na zdjeca
<div id="imagediv"></div>
<input type="button" id="nextPagePhotoGoogle" value="Więcej" onclick="drawMoreMyPicturesManager()">
 



Powrót