281 lines
10 KiB
C#
281 lines
10 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using System;
|
|
using Newtonsoft.Json;
|
|
using RothenburgAR.Common;
|
|
using System.IO;
|
|
|
|
namespace RothenburgAR.Updater
|
|
{
|
|
public class UpdaterBehaviour : MonoBehaviour
|
|
{
|
|
public UnityEngine.UI.Slider ProgressBar;
|
|
|
|
public VersioncheckAnswer VersionAnswer { get; set; }
|
|
private List<HttpHandler> httpHandlers = new List<HttpHandler>();
|
|
|
|
void Start()
|
|
{
|
|
/* TODO: allg. fragen
|
|
punkt zum eintragen der credentials? user will ja nur seine/nur bestimmte exhibitions haben schätz ich
|
|
oder beim update auswählen lassen, welche kommen sollen
|
|
*/
|
|
|
|
FindObjectsOfType<Camera>().First().enabled = true;
|
|
|
|
if (Application.internetReachability == NetworkReachability.NotReachable)
|
|
{
|
|
// just continue to app
|
|
LoadMainScene();
|
|
return;
|
|
}
|
|
|
|
CheckForUpdates();
|
|
}
|
|
|
|
private void CheckForUpdates()
|
|
{
|
|
// check for updates and ask for permission to download if there are any
|
|
|
|
string versionMap = GenerateVersionMap();
|
|
HttpHandler http = new HttpRequest(ApiInfo.VersionCheckEndpoint, HttpVerb.POST, versionMap).send();
|
|
httpHandlers.Add(http);
|
|
|
|
http.operation.completed += ar =>
|
|
{
|
|
if (CheckNetworkErrors(http))
|
|
{
|
|
return;
|
|
}
|
|
|
|
Debug.Log(http.download.text);
|
|
|
|
//VersionAnswer = JsonConvert.DeserializeObject<VersioncheckAnswer>(http.download.text);
|
|
VersionAnswer = JsonConvert.DeserializeObject<VersioncheckAnswer>(@"{""languages"":[""de"",""en""],""data"":[{""id"":""006e164c-5e31-4ddf-adf5-df7016c8b3a8"",""meta"":{""status"":""ok"",""updateUrl"":""https://lambdalike.pa.kaim.network/meta/006e164c-5e31-4ddf-adf5-df7016c8b3a7/{lang}""},""tracker"":{""status"":""ok"",""updateUrl"":""https://lambdalike.pa.kaim.network/meta/006e164c-5e31-4ddf-adf5-df7016c8b3a7/{lang}""}},{""id"":""006e164c-5e31-4ddf-adf5-df7016c8b3a7"",""meta"":{""status"":""updated"",""updateUrl"":""https://lambdalike.pa.kaim.network/meta/006e164c-5e31-4ddf-adf5-df7016c8b3a7/{lang}""},""tracker"":{""status"":""ok"",""updateUrl"":""https://lambdalike.pa.kaim.network/meta/006e164c-5e31-4ddf-adf5-df7016c8b3a7/{lang}""}}]}");
|
|
|
|
if (VersionAnswer.data.TrueForAll(d => d.Meta.Status == VersionStatus.ok && d.Tracker.Status == VersionStatus.ok))
|
|
{
|
|
// no updates required, continue to app
|
|
LoadMainScene();
|
|
return;
|
|
}
|
|
|
|
if (Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork)
|
|
{
|
|
TriggerUpdate();
|
|
}
|
|
else
|
|
{
|
|
// TODO ask for user permission to perform update
|
|
}
|
|
};
|
|
}
|
|
|
|
private string GenerateVersionMap()
|
|
{
|
|
string result = "{";
|
|
|
|
var rootDir = new DirectoryInfo(PathHelper.ExhibitionPath);
|
|
var exhibitionDirs = rootDir.GetDirectories().ToList();
|
|
exhibitionDirs.ForEach(dir =>
|
|
{
|
|
var subdir = dir.GetDirectories().ToList().First();
|
|
if (subdir == null) return;
|
|
|
|
var metaFilePath = Path.Combine(subdir.FullName, "meta.json");
|
|
if (!File.Exists(metaFilePath)) return;
|
|
|
|
var exhibits = JsonConvert.DeserializeObject<List<Exhibit>>(File.ReadAllText(metaFilePath));
|
|
foreach (var exhibit in exhibits)
|
|
{
|
|
result += @"""{id}"":""{version}"",".Replace("{id}", exhibit.Id).Replace("{version}", exhibit.UpdatedTime.ToString());
|
|
}
|
|
});
|
|
|
|
result = result.Substring(0, result.Length - 1);
|
|
result += "}";
|
|
return result;
|
|
}
|
|
|
|
private void TriggerUpdate()
|
|
{
|
|
// TODO create centralized network error feedback hub thing
|
|
/*
|
|
* dir structure:
|
|
* data
|
|
* exhibitions
|
|
* id
|
|
* tracker.dat
|
|
* tracker.xml
|
|
* de
|
|
* meta.json
|
|
* en
|
|
* meta.json
|
|
* id
|
|
* ...
|
|
* poi
|
|
* ...
|
|
* media
|
|
* ...
|
|
*/
|
|
|
|
//TODO write languages to file the app can read
|
|
|
|
var updatedMeta = VersionAnswer.data.Where(d => d.Meta.Status == VersionStatus.updated).ToList();
|
|
var updatedTracker = VersionAnswer.data.Where(d => d.Tracker.Status == VersionStatus.updated).ToList();
|
|
updatedMeta.Union(updatedTracker).ToList().ForEach(updatedExhibition =>
|
|
{
|
|
// create exhibition directories
|
|
var path = Path.Combine(PathHelper.ExhibitionPath, updatedExhibition.Id);
|
|
if (!Directory.Exists(path))
|
|
{
|
|
Directory.CreateDirectory(path);
|
|
}
|
|
});
|
|
|
|
updatedMeta.ForEach(d => UpdateMeta(d));
|
|
updatedTracker.ForEach(d => UpdateTracker(d));
|
|
|
|
var deletedMeta = VersionAnswer.data.Where(d => d.Meta.Status == VersionStatus.deleted).ToList();
|
|
var deletedTracker = VersionAnswer.data.Where(d => d.Tracker.Status == VersionStatus.deleted).ToList();
|
|
//TODO figure out if you can delete a tracker but not the meta (or vice versa)
|
|
}
|
|
|
|
private void UpdateMeta(ExhibitionVersion exhibition)
|
|
{
|
|
foreach (var lang in VersionAnswer.languages)
|
|
{
|
|
var path = PathHelper.CombinePaths(PathHelper.ExhibitionPath, exhibition.Id, lang);
|
|
var url = exhibition.Meta.UpdateUrl.Replace("{lang}", lang);
|
|
var http = new HttpRequest(url, HttpVerb.GET).send();
|
|
httpHandlers.Add(http);
|
|
|
|
http.operation.completed += ar =>
|
|
{
|
|
if (CheckNetworkErrors(http))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!Directory.Exists(path))
|
|
{
|
|
Directory.CreateDirectory(path);
|
|
}
|
|
|
|
File.WriteAllText(Path.Combine(path, "meta.json"), http.download.text, System.Text.Encoding.UTF8);
|
|
|
|
var exhibits = JsonConvert.DeserializeObject<List<Exhibit>>(http.download.text);
|
|
foreach (var exhibit in exhibits)
|
|
{
|
|
UpdateMedia(exhibit);
|
|
}
|
|
};
|
|
}
|
|
|
|
}
|
|
|
|
private void UpdateMedia(Exhibit exhibit)
|
|
{
|
|
//TODO implement feedback: which id is the right one?
|
|
// ImageId is apparently just the ExhibitId
|
|
// Exhibit doesn't have media, POI does. so the Exhibit.MediaId doesn't make sense
|
|
//exhibit.MediaId;
|
|
//exhibit.Pois[0].ImageId;
|
|
|
|
//TODO check existing file for creation/alteration date to see if download is necessary
|
|
|
|
var mediaIDs = new List<string> { exhibit.MediaId };
|
|
//var mediaIDs = exhibit.Pois.Select(p => p.ImageId).ToList();
|
|
|
|
foreach (var mediaId in mediaIDs)
|
|
{
|
|
var path = PathHelper.CombinePaths(PathHelper.MediaPath, mediaId);
|
|
var url = ApiInfo.FileEndpoint.Replace("{id}", mediaId);
|
|
var http = new HttpRequest(url, HttpVerb.GET).send();
|
|
httpHandlers.Add(http);
|
|
|
|
http.operation.completed += ar =>
|
|
{
|
|
if (CheckNetworkErrors(http))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!Directory.Exists(path))
|
|
{
|
|
Directory.CreateDirectory(path);
|
|
}
|
|
|
|
//TODO find out media type
|
|
var type = http.request.GetResponseHeader("Content-Type");
|
|
File.WriteAllBytes(Path.Combine(path, "media.dat"), http.download.data);
|
|
};
|
|
}
|
|
}
|
|
|
|
private bool CheckNetworkErrors(HttpHandler http)
|
|
{
|
|
if (http.request.isNetworkError || http.request.isHttpError)
|
|
{
|
|
//TODO notify user about error (decide on level of detail)
|
|
Debug.LogError(String.Format("Error while downloading\nurl: {0}\nNetwork Error: {1}\nHttp Error: {2}\nHttp Response Code: {3}",
|
|
http.request.url,
|
|
http.request.isNetworkError,
|
|
http.request.isHttpError,
|
|
http.request.responseCode));
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private void UpdateTracker(ExhibitionVersion exhibition)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
private static void LoadMainScene()
|
|
{
|
|
UnityEngine.SceneManagement.SceneManager.LoadScene("mainScene");
|
|
}
|
|
|
|
private DateTime downloadEndedTime = DateTime.Now.AddSeconds(1);
|
|
private float afterDownloadWaitTime = 3f;
|
|
|
|
void Update()
|
|
{
|
|
if (httpHandlers.Count > 0)
|
|
{
|
|
float downloadProgress = 0f;
|
|
httpHandlers.ForEach(h =>
|
|
{
|
|
downloadProgress += h.operation.progress;
|
|
});
|
|
|
|
downloadProgress /= httpHandlers.Count;
|
|
|
|
ProgressBar.value = downloadProgress;
|
|
}
|
|
|
|
// Continue to Main Scene after all downloads are done and 3 seconds have passed without any new downloads triggering.
|
|
if (httpHandlers.All(h => h.IsDone))
|
|
{
|
|
if (downloadEndedTime > DateTime.Now)
|
|
{
|
|
downloadEndedTime = DateTime.Now;
|
|
}
|
|
if (downloadEndedTime.AddSeconds(afterDownloadWaitTime) < DateTime.Now)
|
|
{
|
|
Debug.Log("Done Updating");
|
|
LoadMainScene();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
downloadEndedTime = DateTime.Now.AddSeconds(1);
|
|
}
|
|
}
|
|
}
|
|
} |