diff --git a/Assets/Editor/Tests/TestDownloadingCache.cs b/Assets/Editor/Tests/TestDownloadingCache.cs new file mode 100644 index 0000000000..196ccf4f91 --- /dev/null +++ b/Assets/Editor/Tests/TestDownloadingCache.cs @@ -0,0 +1,76 @@ +using System.IO; +using System.Linq; +using Assets.Oculus.VR.Editor; +using NUnit.Framework; +namespace TiltBrush +{ + [TestFixture] + public class TestDownloadingCache + { + private DownloadingCache m_dlCache; + private FileCache m_Cache; + private string m_Path; + + private const string kLocalFile = "file://TestData/main_1.png"; + private const string kRemoteFile = "http://openbrush.app/assets/icon.png"; + + [SetUp] + public void Setup() + { + m_Path = Path.Combine(Path.GetTempPath(), "FileCacheTest"); + if (File.Exists(m_Path)) + { + File.Delete(m_Path); + } + if (Directory.Exists(m_Path)) + { + Directory.Delete(m_Path, recursive: true); + } + m_Cache = new FileCache(m_Path, 1); + m_dlCache = new DownloadingCache(m_Cache); + } + + [TearDown] + public void Teardown() + { + if (Directory.Exists(m_Path)) + { + Directory.Delete(m_Path, recursive: true); + } + } + + [Test] + public async void LocalFileLoads() + { + var bytes = await m_dlCache.Read("test", "logo1", kLocalFile); + Assert.That(bytes != null); + Assert.That(bytes.Length == 32983); + } + + [Test] + public async void RemoteFileLoads() + { + var bytes = await m_dlCache.Read("test", "logo1", kRemoteFile); + Assert.That(bytes != null); + Assert.That(bytes.Length == 32983); + } + + [Test] + public async void RemoteFileIsStoredInCache() + { + var bytes = await m_dlCache.Read("test", "logo1", kRemoteFile); + Assert.That(m_Cache.CacheSize == 32983); + } + + [Test] + public async void RemoteFileCanBeLoadedFromCache() + { + var bytes = await m_dlCache.Read("test", "logo1", kRemoteFile); + var bytes2 = m_Cache.Read("test", "logo1"); + Assert.That(Enumerable.SequenceEqual(bytes, bytes2)); + var bytes3 = await m_dlCache.Read("test", "logo1", kRemoteFile); + Assert.That(Enumerable.SequenceEqual(bytes, bytes3)); + } + + } +} diff --git a/Assets/Editor/Tests/TestDownloadingCache.cs.meta b/Assets/Editor/Tests/TestDownloadingCache.cs.meta new file mode 100644 index 0000000000..63b74e0f24 --- /dev/null +++ b/Assets/Editor/Tests/TestDownloadingCache.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a804d95b31bd499e9e08354bc616fc98 +timeCreated: 1675906363 \ No newline at end of file diff --git a/Assets/Scripts/App.cs b/Assets/Scripts/App.cs index b7eab2a4cf..f2cfe7ba64 100644 --- a/Assets/Scripts/App.cs +++ b/Assets/Scripts/App.cs @@ -18,6 +18,7 @@ using System.IO; using System.Linq; using System.Net; +using System.Net.Http; using System.Reflection; using System.Runtime.CompilerServices; using UnityEngine; @@ -75,6 +76,8 @@ public partial class App : MonoBehaviour "All your " + kAppDisplayName + " files have been moved to\n" + "/sdcard/" + kAppFolderName + ".\n"; + public static HttpClient HttpClient = new HttpClient(); + public enum AppState { Error, diff --git a/Assets/Scripts/Sharing/DownloadingCache.cs b/Assets/Scripts/Sharing/DownloadingCache.cs new file mode 100644 index 0000000000..be00365a41 --- /dev/null +++ b/Assets/Scripts/Sharing/DownloadingCache.cs @@ -0,0 +1,56 @@ +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +namespace TiltBrush +{ + /// + /// Cache where remote or local files can be requested, and remote files will be cached. + /// Local files will just be read directly. + /// + public class DownloadingCache + { + /// + /// Constructor + /// + /// File cache + public DownloadingCache(FileCache cache) + { + m_Cache = cache; + } + + // TODO: I think this needs to store metadata about where the file came from. + // and do something about files that have changed etc + + /// + /// Read a file from a location. If the file does not exist, it will be cached + /// at the given fileset and filename. + /// + /// Fileset to store/retrieve + /// Filename + /// Location to load - should be http(s):// or file:// + /// Task that returns the bytes for a file. + public async Task Read(string fileset, string filename, string url) + { + const string fileStart = "file://"; + const string httpStart = "http"; + if (m_Cache.FileExists(fileset, filename)) + { + return m_Cache.Read(fileset, filename); + } + if (url.StartsWith(fileStart)) + { + return File.ReadAllBytes(url.Skip(fileStart.Length).ToString()); + } + else if (url.StartsWith(httpStart)) + { + byte[] bytes = await App.HttpClient.GetByteArrayAsync(url); + m_Cache.Write(fileset, filename, bytes); + return bytes; + } + return null; + } + + private FileCache m_Cache; + } +} diff --git a/Assets/Scripts/Sharing/DownloadingCache.cs.meta b/Assets/Scripts/Sharing/DownloadingCache.cs.meta new file mode 100644 index 0000000000..65d7ea987e --- /dev/null +++ b/Assets/Scripts/Sharing/DownloadingCache.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e57a79bd52ee446cbfa9d68ed33124d1 +timeCreated: 1675749698 \ No newline at end of file