// ReSharper disable once UnusedMethodReturnValue.Local private bool UploadApk(string apkFileName, string expansionFileName, string track, List <UpdateInfo> apkChanges) { if (_serviceThread != null) { return(false); } if (!File.Exists(apkFileName)) { UpdateStatus("Apk file not existing"); return(false); } if (!string.IsNullOrEmpty(expansionFileName) && !File.Exists(expansionFileName)) { UpdateStatus("Expansion file not existing"); return(false); } UpdateStatus(string.Empty); _cts = new CancellationTokenSource(); _serviceThread = new Thread(async() => { UpdateStatus(string.Empty); StringBuilder sb = new StringBuilder(); try { if (apkChanges != null) { sb.Append("Changes info for languages: "); foreach (UpdateInfo updateInfo in apkChanges) { sb.Append($"{updateInfo.Language} "); } sb.AppendLine(); UpdateStatus(sb.ToString()); } UserCredential credential = await GetCredatials(); using (AndroidPublisherService service = new AndroidPublisherService(GetInitializer(credential))) { EditsResource edits = service.Edits; EditsResource.InsertRequest editRequest = edits.Insert(null, PackageName); AppEdit appEdit = await editRequest.ExecuteAsync(_cts.Token); bool reuseExpansion = false; ExpansionInfo expansionInfo = await GetNewestExpansionFile(edits, appEdit); if (expansionInfo != null) { sb.AppendLine($"Latest expansion: apk version={expansionInfo.ApkVersion}, expansion version={expansionInfo.ExpansionVersion}, size={expansionInfo.FileSize}"); if (!string.IsNullOrEmpty(expansionFileName)) { FileInfo fileInfo = new FileInfo(expansionFileName); if (fileInfo.Exists && fileInfo.Length == expansionInfo.FileSize) { sb.AppendLine("Size unchanged, reusing old expansion file"); reuseExpansion = true; } } } Apk apkUploaded = null; using (FileStream apkStream = new FileStream(apkFileName, FileMode.Open, FileAccess.Read)) { long fileLength = (apkStream.Length > 0) ? apkStream.Length : 1; EditsResource.ApksResource.UploadMediaUpload upload = edits.Apks.Upload(PackageName, appEdit.Id, apkStream, "application/vnd.android.package-archive"); upload.ChunkSize = ResumableUpload.MinimumChunkSize; upload.ProgressChanged += progress => { UpdateStatus(sb.ToString() + $"Apk progress: {100 * progress.BytesSent / fileLength}%"); }; upload.ResponseReceived += apk => { apkUploaded = apk; }; IUploadProgress uploadProgress = await upload.UploadAsync(_cts.Token); sb.AppendLine($"Upload status: {uploadProgress.Status.ToString()}"); UpdateStatus(sb.ToString()); if (uploadProgress.Exception != null) { throw uploadProgress.Exception; } } int?versionCode = apkUploaded?.VersionCode; if (!versionCode.HasValue) { throw new Exception("No apk version code"); } sb.AppendLine($"Version code uploaded: {versionCode.Value}"); UpdateStatus(sb.ToString()); if (!string.IsNullOrEmpty(expansionFileName) && !reuseExpansion) { using (FileStream expansionStream = new FileStream(expansionFileName, FileMode.Open, FileAccess.Read)) { long fileLength = (expansionStream.Length > 0) ? expansionStream.Length : 1; EditsResource.ExpansionfilesResource.UploadMediaUpload upload = edits.Expansionfiles.Upload(PackageName, appEdit.Id, versionCode.Value, EditsResource.ExpansionfilesResource.UploadMediaUpload.ExpansionFileTypeEnum.Main, expansionStream, "application/octet-stream"); upload.ChunkSize = ResumableUpload.MinimumChunkSize; upload.ProgressChanged += progress => { UpdateStatus(sb.ToString() + $"Expansion progress: {100 * progress.BytesSent / fileLength}%"); }; IUploadProgress uploadProgress = await upload.UploadAsync(_cts.Token); sb.AppendLine($"Upload status: {uploadProgress.Status.ToString()}"); UpdateStatus(sb.ToString()); if (uploadProgress.Exception != null) { throw uploadProgress.Exception; } } } else { if (expansionInfo != null) { ExpansionFile expansionRef = new ExpansionFile { ReferencesVersion = expansionInfo.ExpansionVersion }; await edits.Expansionfiles.Update(expansionRef, PackageName, appEdit.Id, versionCode.Value, EditsResource.ExpansionfilesResource.UpdateRequest.ExpansionFileTypeEnum.Main).ExecuteAsync(_cts.Token); sb.AppendLine($"Expansion version {expansionInfo.ExpansionVersion} assigned"); } else { sb.AppendLine("No existing expansion found!"); } } Track updateTrack = new Track { VersionCodes = new List <int?> { versionCode.Value } }; EditsResource.TracksResource.UpdateRequest updateRequest = edits.Tracks.Update(updateTrack, PackageName, appEdit.Id, track); Track updatedTrack = await updateRequest.ExecuteAsync(_cts.Token); sb.AppendLine($"Track updated: {updatedTrack.TrackValue}"); UpdateStatus(sb.ToString()); if (apkChanges != null) { foreach (UpdateInfo updateInfo in apkChanges) { ApkListing apkListing = new ApkListing { RecentChanges = updateInfo.Changes }; await edits.Apklistings.Update(apkListing, PackageName, appEdit.Id, versionCode.Value, updateInfo.Language).ExecuteAsync(_cts.Token); sb.AppendLine($"Changes for language {updateInfo.Language} updated"); UpdateStatus(sb.ToString()); } } EditsResource.CommitRequest commitRequest = edits.Commit(PackageName, appEdit.Id); AppEdit appEditCommit = await commitRequest.ExecuteAsync(_cts.Token); sb.AppendLine($"App edit committed: {appEditCommit.Id}"); UpdateStatus(sb.ToString()); } } catch (Exception e) { sb.AppendLine($"Exception: {e.Message}"); } finally { _serviceThread = null; _cts.Dispose(); UpdateStatus(sb.ToString()); } }); _serviceThread.Start(); return(true); }
// ReSharper disable once UnusedMethodReturnValue.Local private bool AssignTrack(string track, int?versionAssign) { if (_serviceThread != null) { return(false); } UpdateStatus(string.Empty); _cts = new CancellationTokenSource(); _serviceThread = new Thread(async() => { UpdateStatus(string.Empty); StringBuilder sb = new StringBuilder(); try { UserCredential credential = await GetCredatials(); using (AndroidPublisherService service = new AndroidPublisherService(GetInitializer(credential))) { EditsResource edits = service.Edits; EditsResource.InsertRequest editRequest = edits.Insert(null, PackageName); AppEdit appEdit = await editRequest.ExecuteAsync(_cts.Token); try { Track trackResponse = await edits.Tracks.Get(PackageName, appEdit.Id, track).ExecuteAsync(_cts.Token); sb.AppendLine($"Track: {track}"); foreach (int?version in trackResponse.VersionCodes) { if (version != null) { sb.AppendLine($"Version: {version.Value}"); } } } catch (Exception) { sb.AppendLine($"No version for track: {track}"); } Track assignTrack = new Track { VersionCodes = new List <int?>() }; if (versionAssign.HasValue) { assignTrack.VersionCodes.Add(versionAssign); sb.AppendLine($"Assign version: {versionAssign}"); } else { sb.AppendLine("Unassign version"); } UpdateStatus(sb.ToString()); await edits.Tracks.Update(assignTrack, PackageName, appEdit.Id, track).ExecuteAsync(); sb.AppendLine("Track updated"); UpdateStatus(sb.ToString()); EditsResource.CommitRequest commitRequest = edits.Commit(PackageName, appEdit.Id); AppEdit appEditCommit = await commitRequest.ExecuteAsync(_cts.Token); sb.AppendLine($"App edit committed: {appEditCommit.Id}"); UpdateStatus(sb.ToString()); } } catch (Exception e) { sb.AppendLine($"Exception: {e.Message}"); } finally { _serviceThread = null; _cts.Dispose(); UpdateStatus(sb.ToString()); } }); _serviceThread.Start(); return(true); }
// ReSharper disable once UnusedMethodReturnValue.Local private bool UpdateChanges(string track, List <UpdateInfo> apkChanges) { if (_serviceThread != null) { return(false); } if (apkChanges == null) { UpdateStatus("No language changes info"); return(false); } UpdateStatus(string.Empty); _cts = new CancellationTokenSource(); _serviceThread = new Thread(async() => { UpdateStatus(string.Empty); StringBuilder sb = new StringBuilder(); try { UserCredential credential = await GetCredatials(); using (AndroidPublisherService service = new AndroidPublisherService(GetInitializer(credential))) { EditsResource edits = service.Edits; EditsResource.InsertRequest editRequest = edits.Insert(null, PackageName); AppEdit appEdit = await editRequest.ExecuteAsync(_cts.Token); Track trackResponse = await edits.Tracks.Get(PackageName, appEdit.Id, track).ExecuteAsync(_cts.Token); sb.AppendLine($"Track: {track}"); if (trackResponse.VersionCodes.Count != 1 || !trackResponse.VersionCodes[0].HasValue) { sb.AppendLine($"Invalid version count: {trackResponse.VersionCodes.Count}"); UpdateStatus(sb.ToString()); throw new Exception("Invalid version count"); } int currentVersion = trackResponse.VersionCodes[0].Value; sb.AppendLine($"Version: {currentVersion}"); UpdateStatus(sb.ToString()); await edits.Apklistings.Deleteall(PackageName, appEdit.Id, currentVersion).ExecuteAsync(_cts.Token); sb.AppendLine("All changes cleared"); UpdateStatus(sb.ToString()); foreach (UpdateInfo updateInfo in apkChanges) { ApkListing apkListing = new ApkListing { RecentChanges = updateInfo.Changes }; await edits.Apklistings.Update(apkListing, PackageName, appEdit.Id, currentVersion, updateInfo.Language).ExecuteAsync(_cts.Token); sb.AppendLine($"Changes for language {updateInfo.Language} updated"); UpdateStatus(sb.ToString()); } EditsResource.CommitRequest commitRequest = edits.Commit(PackageName, appEdit.Id); AppEdit appEditCommit = await commitRequest.ExecuteAsync(_cts.Token); sb.AppendLine($"App edit committed: {appEditCommit.Id}"); UpdateStatus(sb.ToString()); } } catch (Exception e) { sb.AppendLine($"Exception: {e.Message}"); } finally { _serviceThread = null; _cts.Dispose(); UpdateStatus(sb.ToString()); } }); _serviceThread.Start(); return(true); }
// ReSharper disable once UnusedMethodReturnValue.Local private bool ChangeTrack(string fromTrack, string toTrack) { if (_serviceThread != null) { return(false); } UpdateStatus(string.Empty); if (string.Compare(fromTrack, toTrack, StringComparison.OrdinalIgnoreCase) == 0) { UpdateStatus("Both tracks identical"); return(false); } _cts = new CancellationTokenSource(); _serviceThread = new Thread(async() => { UpdateStatus(string.Empty); StringBuilder sb = new StringBuilder(); try { UserCredential credential = await GetCredatials(); using (AndroidPublisherService service = new AndroidPublisherService(GetInitializer(credential))) { EditsResource edits = service.Edits; EditsResource.InsertRequest editRequest = edits.Insert(null, PackageName); AppEdit appEdit = await editRequest.ExecuteAsync(_cts.Token); Track trackResponse = await edits.Tracks.Get(PackageName, appEdit.Id, fromTrack).ExecuteAsync(_cts.Token); sb.AppendLine($"From track: {fromTrack}"); if (trackResponse.VersionCodes.Count != 1 || !trackResponse.VersionCodes[0].HasValue) { sb.AppendLine($"Invalid version count: {trackResponse.VersionCodes.Count}"); UpdateStatus(sb.ToString()); throw new Exception("Invalid version count"); } int currentVersion = trackResponse.VersionCodes[0].Value; sb.AppendLine($"Version: {currentVersion}"); UpdateStatus(sb.ToString()); Track assignTrack = new Track { VersionCodes = new List <int?> { currentVersion } }; await edits.Tracks.Update(assignTrack, PackageName, appEdit.Id, toTrack).ExecuteAsync(); sb.AppendLine($"Assigned to track: {toTrack}"); UpdateStatus(sb.ToString()); Track unassignTrack = new Track { VersionCodes = new List <int?>() }; await edits.Tracks.Update(unassignTrack, PackageName, appEdit.Id, fromTrack).ExecuteAsync(); sb.AppendLine($"Unassigned from track: {fromTrack}"); UpdateStatus(sb.ToString()); ApkListingsListResponse listingsResponse = await edits.Apklistings.List(PackageName, appEdit.Id, currentVersion).ExecuteAsync(_cts.Token); if (listingsResponse.Listings != null) { foreach (ApkListing listing in listingsResponse.Listings) { if (listing.RecentChanges != null) { await edits.Apklistings.Update(listing, PackageName, appEdit.Id, currentVersion, listing.Language).ExecuteAsync(_cts.Token); sb.AppendLine($"Changes for language {listing.Language} updated"); UpdateStatus(sb.ToString()); } } } EditsResource.CommitRequest commitRequest = edits.Commit(PackageName, appEdit.Id); AppEdit appEditCommit = await commitRequest.ExecuteAsync(_cts.Token); sb.AppendLine($"App edit committed: {appEditCommit.Id}"); UpdateStatus(sb.ToString()); } } catch (Exception e) { sb.AppendLine($"Exception: {e.Message}"); } finally { _serviceThread = null; _cts.Dispose(); UpdateStatus(sb.ToString()); } }); _serviceThread.Start(); return(true); }