2017-10-15 13:37:45 +02:00
/ * *
* cemu_UI
*
2018-04-28 12:17:12 +02:00
* Copyright 2017 - 2018 < @Seil0 >
2017-10-15 13:37:45 +02:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston ,
* MA 02110 - 1301 , USA .
* /
2017-11-13 16:44:39 +01:00
package com.cemu_UI.vendorCloudController ;
2017-04-17 00:58:49 +02:00
2017-04-17 23:37:06 +02:00
import java.io.FileOutputStream ;
import java.io.IOException ;
import java.io.InputStream ;
import java.io.InputStreamReader ;
import java.io.OutputStream ;
import java.util.Collections ;
2017-09-12 15:04:21 +02:00
import org.apache.logging.log4j.LogManager ;
import org.apache.logging.log4j.Logger ;
2017-04-17 23:37:06 +02:00
2017-04-17 00:58:49 +02:00
import com.google.api.client.auth.oauth2.Credential ;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp ;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver ;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow ;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets ;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport ;
import com.google.api.client.http.FileContent ;
import com.google.api.client.http.HttpTransport ;
import com.google.api.client.json.JsonFactory ;
2017-04-17 23:37:06 +02:00
import com.google.api.client.json.jackson2.JacksonFactory ;
2017-04-17 00:58:49 +02:00
import com.google.api.client.util.DateTime ;
import com.google.api.client.util.store.FileDataStoreFactory ;
import com.google.api.services.drive.Drive ;
import com.google.api.services.drive.Drive.Files ;
2017-04-17 23:37:06 +02:00
import com.google.api.services.drive.DriveScopes ;
import com.google.api.services.drive.model.File ;
import com.google.api.services.drive.model.FileList ;
2017-04-17 00:58:49 +02:00
public class GoogleDriveController {
Drive service ;
private String folderID ;
2017-12-12 23:52:54 +01:00
private File downloadFile ;
2017-09-12 15:04:21 +02:00
private static final Logger LOGGER = LogManager . getLogger ( GoogleDriveController . class . getName ( ) ) ;
2017-04-17 00:58:49 +02:00
2017-12-12 23:52:54 +01:00
private final String APPLICATION_NAME = " cemu_Ui Google Drive API Controller " ;
2017-04-17 00:58:49 +02:00
2017-04-25 22:16:30 +02:00
//Directory to store user credentials for this application
2017-04-17 00:58:49 +02:00
private final java . io . File DATA_STORE_DIR = new java . io . File ( System . getProperty ( " user.home " ) , " .credentials/cemu_UI_credential " ) ;
2017-04-25 22:16:30 +02:00
//Global instance of the {@link FileDataStoreFactory}
2017-04-17 00:58:49 +02:00
private FileDataStoreFactory DATA_STORE_FACTORY ;
2017-04-25 22:16:30 +02:00
//Global instance of the JSON factory
2017-04-17 00:58:49 +02:00
private final JsonFactory JSON_FACTORY = JacksonFactory . getDefaultInstance ( ) ;
2017-04-25 22:16:30 +02:00
//Global instance of the HTTP transport
2017-04-17 00:58:49 +02:00
private HttpTransport HTTP_TRANSPORT ;
2017-04-25 22:16:30 +02:00
/ * * If modifying these scopes , delete your previously saved credentials
2017-04-17 00:58:49 +02:00
* at ~ / . credentials / cemu_UI_credential
* /
private final java . util . Collection < String > SCOPES = DriveScopes . all ( ) ;
public GoogleDriveController ( ) {
try {
HTTP_TRANSPORT = GoogleNetHttpTransport . newTrustedTransport ( ) ;
DATA_STORE_FACTORY = new FileDataStoreFactory ( DATA_STORE_DIR ) ;
folderID = " " ;
} catch ( Throwable t ) {
2017-09-12 15:04:21 +02:00
LOGGER . error ( " error " , t ) ;
2017-04-17 00:58:49 +02:00
System . exit ( 1 ) ;
}
}
/ * *
* Creates an authorized Credential object .
* @return an authorized Credential object .
* @throws IOException
* /
public Credential authorize ( ) throws IOException {
// Load client secrets.
2017-11-13 16:44:39 +01:00
InputStream in = getClass ( ) . getClassLoader ( ) . getResourceAsStream ( " client_secret.json " ) ;
2017-12-07 22:52:32 +01:00
GoogleClientSecrets clientSecrets = GoogleClientSecrets . load ( JSON_FACTORY , new InputStreamReader ( in ) ) ;
2017-10-29 23:27:36 +01:00
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow . Builder ( HTTP_TRANSPORT , JSON_FACTORY , clientSecrets , SCOPES )
. setDataStoreFactory ( DATA_STORE_FACTORY )
2017-04-17 00:58:49 +02:00
. setAccessType ( " offline " )
. build ( ) ;
2017-11-28 13:55:07 +01:00
2017-04-17 00:58:49 +02:00
Credential credential = new AuthorizationCodeInstalledApp ( flow , new LocalServerReceiver ( ) ) . authorize ( " user " ) ;
2017-09-12 15:04:21 +02:00
LOGGER . info ( " Credentials saved to " + DATA_STORE_DIR . getAbsolutePath ( ) ) ;
2017-04-17 00:58:49 +02:00
return credential ;
}
/ * *
* Build and return an authorized Drive client service .
* @return an authorized Drive client service
* @throws IOException
* /
2017-04-25 22:16:30 +02:00
public Drive getDriveService ( ) throws IOException {
2017-04-17 00:58:49 +02:00
Credential credential = authorize ( ) ;
return new Drive . Builder ( HTTP_TRANSPORT , JSON_FACTORY , credential )
. setApplicationName ( APPLICATION_NAME )
. build ( ) ;
}
2017-12-13 00:07:20 +01:00
public void main ( String cemuDirectory ) throws IOException {
service = getDriveService ( ) ;
if ( getFolderID ( ) = = " " | | getFolderID ( ) = = null ) {
getSavegamesFolderID ( ) ;
}
}
2017-04-25 22:16:30 +02:00
2017-12-12 23:52:54 +01:00
// create a folder in google drive
2017-05-04 22:07:50 +02:00
public void creatFolder ( ) throws IOException {
2017-09-12 15:04:21 +02:00
LOGGER . info ( " creating new folder " ) ;
2017-04-17 00:58:49 +02:00
File fileMetadata = new File ( ) ;
fileMetadata . setName ( " cemu_savegames " ) ;
fileMetadata . setMimeType ( " application/vnd.google-apps.folder " ) ;
2017-04-25 22:16:30 +02:00
File file = service . files ( ) . create ( fileMetadata ) . setFields ( " id " ) . execute ( ) ;
2017-09-12 15:04:21 +02:00
LOGGER . info ( " Folder ID: " + file . getId ( ) ) ;
2017-04-17 00:58:49 +02:00
folderID = file . getId ( ) ;
2017-04-25 22:16:30 +02:00
}
2017-12-12 23:52:54 +01:00
// check if folder already exist
public boolean checkFolder ( ) {
2017-04-17 00:58:49 +02:00
try {
Files . List request = service . files ( ) . list ( ) . setQ ( " mimeType = 'application/vnd.google-apps.folder' and name = 'cemu_savegames' " ) ;
FileList files = request . execute ( ) ;
if ( files . getFiles ( ) . size ( ) = = 0 ) {
return false ;
} else {
return true ;
}
} catch ( IOException e ) {
e . printStackTrace ( ) ;
return false ;
}
2017-04-25 22:16:30 +02:00
}
2017-12-12 23:52:54 +01:00
// FIXME it seams like there is a bug in this method
// get the name of the zip in the semu_savegames folder, which is the last upload Unix time
public long getLastCloudSync ( ) throws IOException {
LOGGER . info ( " getting last cloud sync " ) ;
long lastCloudSync = 0 ;
2017-05-30 21:36:56 +02:00
Files . List request = service . files ( ) . list ( ) . setQ ( " ' " + folderID + " ' in parents " ) . setFields ( " nextPageToken, files(id, name, size, modifiedTime, createdTime, md5Checksum) " ) ;
2017-04-25 22:16:30 +02:00
FileList files = request . execute ( ) ;
2017-04-17 00:58:49 +02:00
2017-04-25 22:16:30 +02:00
for ( File file : files . getFiles ( ) ) {
2017-12-12 23:52:54 +01:00
downloadFile = file ;
lastCloudSync = Long . parseLong ( file . getName ( ) . substring ( 0 , file . getName ( ) . length ( ) - 4 ) ) ;
}
return lastCloudSync ;
2017-05-25 19:07:16 +02:00
}
2017-12-12 23:52:54 +01:00
/ * *
* delete all existing files in cemu_savegames at first
* upload the new savegames zip file
* @param uploadFile savegames zip file
* @throws IOException
* /
public void uploadZipFile ( java . io . File uploadFile ) throws IOException {
LOGGER . info ( " deleting old savegames ... " ) ;
Files . List request = service . files ( ) . list ( ) . setQ ( " ' " + folderID + " ' in parents " ) . setFields ( " nextPageToken, files(id, name, size, modifiedTime, createdTime, md5Checksum) " ) ;
2017-05-25 19:07:16 +02:00
FileList files = request . execute ( ) ;
2017-12-12 23:52:54 +01:00
for ( File file : files . getFiles ( ) ) {
service . files ( ) . delete ( file . getId ( ) ) . execute ( ) ; // deleting old file
2017-05-25 19:07:16 +02:00
}
2017-09-12 15:04:21 +02:00
LOGGER . info ( " uploading " + uploadFile . getName ( ) + " ... " ) ;
2017-04-17 00:58:49 +02:00
File fileMetadata = new File ( ) ;
2017-12-12 23:52:54 +01:00
fileMetadata . setName ( uploadFile . getName ( ) ) ;
2017-04-17 00:58:49 +02:00
fileMetadata . setParents ( Collections . singletonList ( folderID ) ) ;
fileMetadata . setModifiedTime ( new DateTime ( uploadFile . lastModified ( ) ) ) ;
FileContent mediaContent = new FileContent ( " " , uploadFile ) ;
File file = service . files ( ) . create ( fileMetadata , mediaContent ) . setFields ( " id, parents " ) . execute ( ) ;
2017-09-12 15:04:21 +02:00
LOGGER . info ( " upload successfull, File ID: " + file . getId ( ) ) ;
2017-04-25 22:16:30 +02:00
}
2017-04-17 00:58:49 +02:00
2017-12-12 23:52:54 +01:00
// download zip file from the cloud and unzip it
public java . io . File downloadZipFile ( String cemu_UIDirectory ) throws IOException {
2017-09-12 15:04:21 +02:00
LOGGER . info ( " downloading " + downloadFile . getName ( ) + " ... " ) ;
2017-12-12 23:52:54 +01:00
java . io . File outputFile = new java . io . File ( cemu_UIDirectory + " / " + downloadFile . getName ( ) ) ;
2017-04-17 00:58:49 +02:00
2017-12-12 23:52:54 +01:00
OutputStream outputStream = new FileOutputStream ( outputFile ) ;
2017-10-28 16:43:04 +02:00
service . files ( ) . get ( downloadFile . getId ( ) ) . executeMediaAndDownloadTo ( outputStream ) ;
outputStream . close ( ) ;
2017-12-12 23:52:54 +01:00
LOGGER . info ( " download successfull: " + downloadFile . getName ( ) ) ;
return outputFile ;
2017-04-25 22:16:30 +02:00
}
2017-12-13 00:07:20 +01:00
private void getSavegamesFolderID ( ) throws IOException {
Files . List request = service . files ( ) . list ( ) . setQ ( " mimeType = 'application/vnd.google-apps.folder' and name = 'cemu_savegames' " ) ;
FileList files = request . execute ( ) ;
try {
LOGGER . info ( " FolderID: " + files . getFiles ( ) . get ( 0 ) . getId ( ) ) ;
setFolderID ( files . getFiles ( ) . get ( 0 ) . getId ( ) ) ;
} catch ( Exception e ) {
LOGGER . error ( " Oops, something went wrong! It seems that you have more than one folder called 'cemu_savegames'! " , e ) ;
}
}
public String getFolderID ( ) {
return folderID ;
}
public void setFolderID ( String folderID ) {
this . folderID = folderID ;
}
2017-04-17 00:58:49 +02:00
}