Google Drive: Fixed a crash that occurred on the first sync when enabling google drive integration

This commit is contained in:
Souryo 2016-09-07 17:05:08 -04:00
parent 9abebbb688
commit 5fbec9e87e
2 changed files with 45 additions and 23 deletions

View file

@ -38,7 +38,8 @@ namespace Mesen.GUI.GoogleDriveIntegration
try {
InteropEmu.DisplayMessage("GoogleDrive", "SynchronizationStarted");
using(_accessor = new GoogleDriveAccessor()) {
if(!CloudSyncHelper.DownloadData()) {
FileDownloadResult result = CloudSyncHelper.DownloadData();
if(result == FileDownloadResult.Error) {
InteropEmu.DisplayMessage("GoogleDrive", "SynchronizationFailed");
return false;
}
@ -86,31 +87,39 @@ namespace Mesen.GUI.GoogleDriveIntegration
}
}
private static bool DownloadData()
private static FileDownloadResult DownloadData()
{
using(MemoryStream stream = new MemoryStream()) {
bool result = _accessor.DownloadFile(stream, "MesenData.zip");
FileDownloadResult result = _accessor.DownloadFile(stream, "MesenData.zip");
if(result) {
stream.Position = 0;
if(result == FileDownloadResult.OK) {
try {
stream.Position = 0;
string homeFolder = ConfigManager.HomeFolder;
string homeFolder = ConfigManager.HomeFolder;
//Make sure the folders exist
string saveFolder = ConfigManager.SaveFolder;
string saveStateFolder = ConfigManager.SaveStateFolder;
//Make sure the folders exist
string saveFolder = ConfigManager.SaveFolder;
string saveStateFolder = ConfigManager.SaveStateFolder;
using(ZipArchive archive = new ZipArchive(stream)) {
foreach(ZipArchiveEntry entry in archive.Entries) {
if(!string.IsNullOrWhiteSpace(entry.Name)) {
string[] fileAndFolder = entry.FullName.Split('/');
string fileName = Path.Combine(homeFolder, fileAndFolder[0], fileAndFolder[1]);
if(!File.Exists(fileName) || File.GetLastWriteTime(fileName) < entry.LastWriteTime.ToLocalTime()) {
//File on server is more recent, or doesn't exist on local computer, extract it
entry.ExtractToFile(fileName, true);
using(ZipArchive archive = new ZipArchive(stream)) {
foreach(ZipArchiveEntry entry in archive.Entries) {
if(!string.IsNullOrWhiteSpace(entry.Name)) {
string[] fileAndFolder = entry.FullName.Split('/');
string fileName = Path.Combine(homeFolder, fileAndFolder[0], fileAndFolder[1]);
if(!File.Exists(fileName) || File.GetLastWriteTime(fileName) < entry.LastWriteTime.ToLocalTime()) {
//File on server is more recent, or doesn't exist on local computer, extract it
try {
entry.ExtractToFile(fileName, true);
} catch {
//Files might be opened by another program or not read-only, etc.
}
}
}
}
}
} catch {
result = FileDownloadResult.FileCorrupted;
}
} else if(_accessor.Revoked) {
ConfigManager.Config.PreferenceInfo.CloudSaveIntegration = false;

View file

@ -12,6 +12,14 @@ using Google.Apis.Upload;
namespace Mesen.GUI.GoogleDriveIntegration
{
public enum FileDownloadResult
{
OK = 0,
FileNotFound = 1,
Error = 2,
FileCorrupted = 3,
};
public class GoogleDriveAccessor : IDisposable
{
private const string _contentType = @"application/zip";
@ -46,13 +54,13 @@ namespace Mesen.GUI.GoogleDriveIntegration
return _connected;
}
public bool DownloadFile(System.IO.MemoryStream fileStream, string filename)
public FileDownloadResult DownloadFile(System.IO.MemoryStream fileStream, string filename)
{
try {
this.Connect().GetAwaiter().GetResult();
if(_connected) {
this.DownloadFileAsync(fileStream, filename).GetAwaiter().GetResult();
return this.DownloadFileAsync(fileStream, filename).GetAwaiter().GetResult();
}
} catch(TokenResponseException) {
_revoked = true;
@ -64,7 +72,7 @@ namespace Mesen.GUI.GoogleDriveIntegration
_credentials = null;
_service = null;
}
return _connected;
return FileDownloadResult.Error;
}
public bool AcquireToken()
@ -168,7 +176,7 @@ namespace Mesen.GUI.GoogleDriveIntegration
return task;
}
private async Task DownloadFileAsync(System.IO.MemoryStream outStream, string filename)
private async Task<FileDownloadResult> DownloadFileAsync(System.IO.MemoryStream outStream, string filename)
{
File driveFile = this.GetFileMatchingName(filename);
@ -177,15 +185,20 @@ namespace Mesen.GUI.GoogleDriveIntegration
var progress = await request.DownloadAsync(outStream).ConfigureAwait(false);
if(progress.Status == DownloadStatus.Completed) {
_driveFile = driveFile;
return FileDownloadResult.OK;
} else {
_driveFile = null;
return FileDownloadResult.Error;
}
}
return FileDownloadResult.FileNotFound;
}
private async Task DeleteFile(File file)
public async Task DeleteFile(string filename)
{
await _service.Files.Delete(file.Id).ExecuteAsync().ConfigureAwait(false);
this.Connect().GetAwaiter().GetResult();
File driveFile = this.GetFileMatchingName(filename);
await _service.Files.Delete(driveFile.Id).ExecuteAsync().ConfigureAwait(false);
}
void Upload_ResponseReceived(File file)