Showing
9 changed files
with
376 additions
and
167 deletions
No preview for this file type
No preview for this file type
No preview for this file type
| 1 | +using Contentful.Core; | ||
| 2 | +using Contentful.Core.Configuration; | ||
| 3 | +using Contentful.Core.Models; | ||
| 4 | +using Contentful.Core.Search; | ||
| 5 | +using System; | ||
| 6 | +using System.Collections; | ||
| 7 | +using System.Collections.Generic; | ||
| 8 | +using System.Linq; | ||
| 9 | +using System.Net.Http; | ||
| 10 | +using UnityEngine; | ||
| 11 | +using UnityEngine.Networking; | ||
| 12 | + | ||
| 13 | +namespace Contentful.Globacore | ||
| 14 | +{ | ||
| 15 | + public enum RequestType | ||
| 16 | + { | ||
| 17 | + FETCH, | ||
| 18 | + CREATE | ||
| 19 | + }; | ||
| 20 | + | ||
| 21 | + public class Request | ||
| 22 | + { | ||
| 23 | + public Action<Response> onComplete { get; set; } | ||
| 24 | + | ||
| 25 | + public object data { get; set; } | ||
| 26 | + | ||
| 27 | + public string contentType { get; set; } | ||
| 28 | + | ||
| 29 | + public RequestType requestType { get; set; } = RequestType.FETCH; | ||
| 30 | + | ||
| 31 | + public string searchField { get; set; } | ||
| 32 | + | ||
| 33 | + public string query { get; set; } | ||
| 34 | + | ||
| 35 | + /// <summary> | ||
| 36 | + /// Send request to Contentful DB. Make sure to pass to initialization data to the request object manually before calling this | ||
| 37 | + /// </summary> | ||
| 38 | + public void Send() | ||
| 39 | + { | ||
| 40 | + ContentfulManager.Instance.Create(this); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + /// <summary> | ||
| 44 | + /// Send request to Contentful DB. Asusumes the Contentful ContentType name is the same as the name of the class being passed | ||
| 45 | + /// </summary> | ||
| 46 | + /// <typeparam name="T"></typeparam> | ||
| 47 | + public void Send<T>() | ||
| 48 | + { | ||
| 49 | + contentType = FormatContentType(typeof(T).ToString()); | ||
| 50 | + ContentfulManager.Instance.Create(this); | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + public void Send<T>(string contentType) | ||
| 54 | + { | ||
| 55 | + this.contentType = contentType; | ||
| 56 | + ContentfulManager.Instance.Create(this); | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + /// <summary> | ||
| 60 | + /// Send request to post content to Contentful DB | ||
| 61 | + /// </summary> | ||
| 62 | + /// <typeparam name="T"></typeparam> | ||
| 63 | + /// <param name="obj"></param> | ||
| 64 | + /// <param name="contentType"></param> | ||
| 65 | + public void Send<T>(T obj, string contentType) | ||
| 66 | + { | ||
| 67 | + requestType = RequestType.CREATE; | ||
| 68 | + data = obj; | ||
| 69 | + this.contentType = contentType; | ||
| 70 | + ContentfulManager.Instance.Create(this); | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + /// <summary> | ||
| 74 | + /// Send request to post content to Contentful DB. Asusumes the Contentful ContentType name is the same as the name of the class being passed | ||
| 75 | + /// </summary> | ||
| 76 | + /// <typeparam name="T"></typeparam> | ||
| 77 | + /// <param name="obj"></param> | ||
| 78 | + /// <param name="contentType"></param> | ||
| 79 | + public void Send<T>(T obj) | ||
| 80 | + { | ||
| 81 | + contentType = FormatContentType(typeof(T).ToString()); | ||
| 82 | + | ||
| 83 | + requestType = RequestType.CREATE; | ||
| 84 | + data = obj; | ||
| 85 | + | ||
| 86 | + ContentfulManager.Instance.Create(this); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + public void Send<T>(string searchField, string query) | ||
| 90 | + { | ||
| 91 | + contentType = FormatContentType(typeof(T).ToString()); | ||
| 92 | + | ||
| 93 | + this.searchField = searchField; | ||
| 94 | + this.query = query; | ||
| 95 | + | ||
| 96 | + ContentfulManager.Instance.Create(this); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + private string FormatContentType(string txt) | ||
| 100 | + { | ||
| 101 | + return (System.Char.ToLowerInvariant(txt[0]) + txt.Substring(1)); | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + public class Response | ||
| 106 | + { | ||
| 107 | + public Request request { get; set; } | ||
| 108 | + | ||
| 109 | + public ContentfulCollection<object> rawResponse { get; set; } | ||
| 110 | + | ||
| 111 | + /// <summary> | ||
| 112 | + /// Cast response from Contentful as type List<T> | ||
| 113 | + /// </summary> | ||
| 114 | + /// <typeparam name="T"></typeparam> | ||
| 115 | + /// <returns></returns> | ||
| 116 | + public List<T> GetAll<T>() | ||
| 117 | + { | ||
| 118 | + var result = new List<T>(); | ||
| 119 | + foreach(var item in rawResponse) | ||
| 120 | + { | ||
| 121 | + var obj = (Newtonsoft.Json.Linq.JObject)item; | ||
| 122 | + result.Add(obj.ToObject<T>()); | ||
| 123 | + } | ||
| 124 | + return result; | ||
| 125 | + } | ||
| 126 | + | ||
| 127 | + /// <summary> | ||
| 128 | + /// Get first result from Contentful response as type T | ||
| 129 | + /// </summary> | ||
| 130 | + /// <typeparam name="T"></typeparam> | ||
| 131 | + /// <returns></returns> | ||
| 132 | + public T GetFirst<T>() | ||
| 133 | + { | ||
| 134 | + var first = (Newtonsoft.Json.Linq.JObject) rawResponse.FirstOrDefault(); | ||
| 135 | + var obj = first.ToObject<T>(); | ||
| 136 | + | ||
| 137 | + return obj; | ||
| 138 | + } | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + public class ContentfulManager : Singleton<ContentfulManager> | ||
| 142 | + { | ||
| 143 | + #region Init | ||
| 144 | + | ||
| 145 | + [SerializeField] | ||
| 146 | + private string _spaceId, _deliveryToken, _managementToken; | ||
| 147 | + | ||
| 148 | + private ContentfulClient _client; | ||
| 149 | + private ContentfulManagementClient _mClient; | ||
| 150 | + | ||
| 151 | + private void Awake() | ||
| 152 | + { | ||
| 153 | + ContentfulOptions options = new ContentfulOptions() | ||
| 154 | + { | ||
| 155 | + ManagementApiKey = _managementToken, | ||
| 156 | + DeliveryApiKey = _deliveryToken, | ||
| 157 | + SpaceId = _spaceId | ||
| 158 | + }; | ||
| 159 | + | ||
| 160 | + _client = new ContentfulClient(new HttpClient(), options); | ||
| 161 | + _mClient = new ContentfulManagementClient(new HttpClient(), options); | ||
| 162 | + | ||
| 163 | + StartCoroutine(JobQueue()); | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | + public void Create(Request request) | ||
| 167 | + { | ||
| 168 | + _activeRequests.Enqueue(request); | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + private Queue<Request> _activeRequests = new Queue<Request>(); | ||
| 172 | + | ||
| 173 | + private IEnumerator JobQueue() | ||
| 174 | + { | ||
| 175 | + while (true) | ||
| 176 | + { | ||
| 177 | + while (_activeRequests.Count == 0) yield return null; | ||
| 178 | + | ||
| 179 | + var thisReq = _activeRequests.Dequeue(); | ||
| 180 | + | ||
| 181 | + Coroutine reqCoroutine = null; | ||
| 182 | + | ||
| 183 | + switch (thisReq.requestType) | ||
| 184 | + { | ||
| 185 | + case RequestType.FETCH: | ||
| 186 | + reqCoroutine = StartCoroutine(FetchRequest(thisReq)); | ||
| 187 | + break; | ||
| 188 | + case RequestType.CREATE: | ||
| 189 | + reqCoroutine = StartCoroutine(CreateRequest(thisReq)); | ||
| 190 | + break; | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + yield return reqCoroutine; | ||
| 194 | + } | ||
| 195 | + } | ||
| 196 | + | ||
| 197 | + #endregion | ||
| 198 | + | ||
| 199 | + private IEnumerator FetchRequest(Request req) | ||
| 200 | + { | ||
| 201 | + string search = "fields." + req.searchField; | ||
| 202 | + | ||
| 203 | + var queryBuilder = new QueryBuilder<object>().ContentTypeIs(req.contentType).FieldEquals(search, req.query).Include(10); | ||
| 204 | + var fetchReq = _client.GetEntries(queryBuilder); | ||
| 205 | + | ||
| 206 | + while (!fetchReq.IsCompleted) yield return null; | ||
| 207 | + | ||
| 208 | + Response thisResp = new Response() | ||
| 209 | + { | ||
| 210 | + request = req, | ||
| 211 | + rawResponse = fetchReq.Result | ||
| 212 | + }; | ||
| 213 | + | ||
| 214 | + req.onComplete?.Invoke(thisResp); | ||
| 215 | + } | ||
| 216 | + | ||
| 217 | + private IEnumerator CreateRequest(Request req) | ||
| 218 | + { | ||
| 219 | + var entry = GenerateEntry(req.data, req.GetType().ToString()); | ||
| 220 | + | ||
| 221 | + var createEntry = _mClient.CreateEntry(entry, contentTypeId: req.contentType); | ||
| 222 | + while (!createEntry.IsCompleted) yield return null; | ||
| 223 | + | ||
| 224 | + print(createEntry.Result.GetType()); | ||
| 225 | + print(Newtonsoft.Json.JsonConvert.SerializeObject(createEntry)); | ||
| 226 | + var createdEntry = createEntry.Result; | ||
| 227 | + | ||
| 228 | + var publishEntry = _mClient.PublishEntry(createdEntry.SystemProperties.Id, 1); | ||
| 229 | + while (!publishEntry.IsCompleted) yield return null; | ||
| 230 | + | ||
| 231 | + Debug.Log(publishEntry.Result.ToString()); | ||
| 232 | + Response thisResp = new Response() | ||
| 233 | + { | ||
| 234 | + request = req, | ||
| 235 | + //rawResponse = publishEntry.Result | ||
| 236 | + }; | ||
| 237 | + | ||
| 238 | + req.onComplete?.Invoke(thisResp); | ||
| 239 | + } | ||
| 240 | + | ||
| 241 | + private Entry<dynamic> GenerateEntry<T>(T obj, string contentType) | ||
| 242 | + { | ||
| 243 | + Type type = obj.GetType(); | ||
| 244 | + | ||
| 245 | + var entry = new Entry<dynamic>(); | ||
| 246 | + entry.SystemProperties = new SystemProperties(); | ||
| 247 | + entry.SystemProperties.Id = contentType; | ||
| 248 | + | ||
| 249 | + var dict = new Dictionary<string, object>(); | ||
| 250 | + | ||
| 251 | + foreach (var prop in type.GetProperties()) | ||
| 252 | + { | ||
| 253 | + if (prop.PropertyType == typeof(SystemProperties)) continue; | ||
| 254 | + | ||
| 255 | + // ignore what ought be ignored | ||
| 256 | + if (Attribute.IsDefined(prop, typeof(Newtonsoft.Json.JsonIgnoreAttribute))) continue; | ||
| 257 | + | ||
| 258 | + dict.Add(prop.Name, new Dictionary<string, object>() | ||
| 259 | + { | ||
| 260 | + { "en-US", prop.GetValue(obj) } | ||
| 261 | + }); | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + foreach (var prop in type.GetFields()) | ||
| 265 | + { | ||
| 266 | + if (prop.FieldType == typeof(SystemProperties)) continue; | ||
| 267 | + | ||
| 268 | + // ignore what ought be ignored | ||
| 269 | + if (Attribute.IsDefined(prop, typeof(Newtonsoft.Json.JsonIgnoreAttribute))) continue; | ||
| 270 | + | ||
| 271 | + dict.Add(prop.Name, new Dictionary<string, object>() | ||
| 272 | + { | ||
| 273 | + { "en-US", prop.GetValue(obj) } | ||
| 274 | + }); | ||
| 275 | + } | ||
| 276 | + | ||
| 277 | + entry.Fields = dict; | ||
| 278 | + | ||
| 279 | + return entry; | ||
| 280 | + } | ||
| 281 | + | ||
| 282 | + public void GetAsset(string id, string url, Action<byte[]> onComplete) | ||
| 283 | + { | ||
| 284 | + StartCoroutine(GetAssetCoroutine(id, url, onComplete)); | ||
| 285 | + } | ||
| 286 | + | ||
| 287 | + private IEnumerator GetAssetCoroutine(string id, string url, Action<byte[]> onComplete) | ||
| 288 | + { | ||
| 289 | + Debug.Log(url); | ||
| 290 | + var www = UnityWebRequest.Get(url); | ||
| 291 | + | ||
| 292 | + yield return www.SendWebRequest(); | ||
| 293 | + | ||
| 294 | + onComplete?.Invoke(www.downloadHandler.data); | ||
| 295 | + } | ||
| 296 | + } | ||
| 297 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | -using Contentful.Core; | ||
| 2 | -using Contentful.Core.Configuration; | ||
| 3 | -using Contentful.Core.Models; | ||
| 4 | -using Contentful.Core.Search; | ||
| 5 | -using Newtonsoft.Json; | ||
| 6 | -using Newtonsoft.Json.Linq; | ||
| 7 | -using System.Collections; | ||
| 8 | -using System.Collections.Generic; | ||
| 9 | -using System.Linq; | ||
| 10 | -using System.Net.Http; | ||
| 11 | -using UnityEngine; | ||
| 12 | -using WebKit; | ||
| 13 | -using Sirenix.OdinInspector; | ||
| 14 | - | ||
| 15 | -[System.Serializable] | ||
| 16 | -public class User | ||
| 17 | -{ | ||
| 18 | - [JsonProperty("sys")] | ||
| 19 | - public SystemProperties sys { get; set; } | ||
| 20 | - | ||
| 21 | - public string firstName; | ||
| 22 | - public string lastName; | ||
| 23 | - public string email; | ||
| 24 | -} | ||
| 25 | - | ||
| 26 | -[System.Serializable] | ||
| 27 | -public class Race | ||
| 28 | -{ | ||
| 29 | - [JsonProperty("sys")] | ||
| 30 | - public SystemProperties sys { get; set; } | ||
| 31 | - | ||
| 32 | - public string time; | ||
| 33 | - public string fuckinIdk; | ||
| 34 | -} | ||
| 35 | - | ||
| 36 | - | ||
| 37 | -public class DatabaseManager : MonoBehaviour | ||
| 38 | -{ | ||
| 39 | - [FoldoutGroup("Contentful Initializer")] | ||
| 40 | - [SerializeField] | ||
| 41 | - private string _spaceId, _deliveryToken, _managementToken; | ||
| 42 | - | ||
| 43 | - private ContentfulClient _client; | ||
| 44 | - private ContentfulManagementClient _mClient; | ||
| 45 | - | ||
| 46 | - void Start() | ||
| 47 | - { | ||
| 48 | - ContentfulOptions options = new ContentfulOptions() | ||
| 49 | - { | ||
| 50 | - ManagementApiKey = _managementToken, | ||
| 51 | - DeliveryApiKey = _deliveryToken, | ||
| 52 | - SpaceId = _spaceId | ||
| 53 | - }; | ||
| 54 | - | ||
| 55 | - _client = new ContentfulClient(new HttpClient(), options); | ||
| 56 | - _mClient = new ContentfulManagementClient(new HttpClient(), options); | ||
| 57 | - } | ||
| 58 | - | ||
| 59 | - | ||
| 60 | - | ||
| 61 | - | ||
| 62 | - #region GetSingle | ||
| 63 | - | ||
| 64 | - [FoldoutGroup("Get Single User")] | ||
| 65 | - [Button("Get Just Dave")] | ||
| 66 | - public void FetchUser() | ||
| 67 | - { | ||
| 68 | - StartCoroutine(GetSpecificUserCoroutine("dave@globacore.com")); | ||
| 69 | - } | ||
| 70 | - | ||
| 71 | - private IEnumerator GetSpecificUserCoroutine(string email) | ||
| 72 | - { | ||
| 73 | - var query = new QueryBuilder<User>().ContentTypeIs("user").FieldEquals(userLambda => userLambda.email, email); | ||
| 74 | - var fetchUserRequest = _client.GetEntries(query); | ||
| 75 | - | ||
| 76 | - while (!fetchUserRequest.IsCompleted) yield return null; | ||
| 77 | - | ||
| 78 | - fetchedUser = fetchUserRequest.Result.First(); | ||
| 79 | - } | ||
| 80 | - | ||
| 81 | - [FoldoutGroup("Get Single User")] | ||
| 82 | - [SerializeField] | ||
| 83 | - private User fetchedUser; | ||
| 84 | - | ||
| 85 | - #endregion | ||
| 86 | - | ||
| 87 | - | ||
| 88 | - | ||
| 89 | - #region GetAll | ||
| 90 | - | ||
| 91 | - [FoldoutGroup("Get All Users")] | ||
| 92 | - [Button("Get All Users As List")] | ||
| 93 | - public void GetAllUsers() | ||
| 94 | - { | ||
| 95 | - StartCoroutine(GetAllUserCoroutine()); | ||
| 96 | - } | ||
| 97 | - | ||
| 98 | - private IEnumerator GetAllUserCoroutine() | ||
| 99 | - { | ||
| 100 | - var query = new QueryBuilder<User>().ContentTypeIs("user"); | ||
| 101 | - var fetchUsersRequest = _client.GetEntries(query); | ||
| 102 | - | ||
| 103 | - while (!fetchUsersRequest.IsCompleted) yield return null; | ||
| 104 | - | ||
| 105 | - allUsers = fetchUsersRequest.Result.ToList(); | ||
| 106 | - } | ||
| 107 | - | ||
| 108 | - [FoldoutGroup("Get All Users")] | ||
| 109 | - [SerializeField] | ||
| 110 | - private List<User> allUsers; | ||
| 111 | - | ||
| 112 | - #endregion | ||
| 113 | - | ||
| 114 | - | ||
| 115 | - | ||
| 116 | - | ||
| 117 | - #region Create | ||
| 118 | - | ||
| 119 | - [FoldoutGroup("Create New User")] | ||
| 120 | - [SerializeField] | ||
| 121 | - public User userToCreate = new User(); | ||
| 122 | - | ||
| 123 | - [FoldoutGroup("Create New User")] | ||
| 124 | - [Button("Create User")] | ||
| 125 | - public void CreateUser() | ||
| 126 | - { | ||
| 127 | - StartCoroutine(CreateUserCoroutine()); | ||
| 128 | - } | ||
| 129 | - | ||
| 130 | - private IEnumerator CreateUserCoroutine() | ||
| 131 | - { | ||
| 132 | - var userEntry = new Entry<dynamic>(); | ||
| 133 | - userEntry.SystemProperties = new SystemProperties(); | ||
| 134 | - userEntry.SystemProperties.Id = "User"; | ||
| 135 | - | ||
| 136 | - userEntry.Fields = new | ||
| 137 | - { | ||
| 138 | - firstName = new Dictionary<string, string>() | ||
| 139 | - { | ||
| 140 | - {"en-US", userToCreate.firstName } | ||
| 141 | - }, | ||
| 142 | - lastName = new Dictionary<string, string>() | ||
| 143 | - { | ||
| 144 | - {"en-US", userToCreate.lastName } | ||
| 145 | - }, | ||
| 146 | - email = new Dictionary<string, string>() | ||
| 147 | - { | ||
| 148 | - {"en-US", userToCreate.email } | ||
| 149 | - }, | ||
| 150 | - }; | ||
| 151 | - | ||
| 152 | - var createEntry = _mClient.CreateEntry(userEntry, "user"); | ||
| 153 | - while (!createEntry.IsCompleted) yield return null; | ||
| 154 | - | ||
| 155 | - var createdEntry = createEntry.Result; | ||
| 156 | - | ||
| 157 | - var publishEntry = _mClient.PublishEntry(createdEntry.SystemProperties.Id, 1); | ||
| 158 | - while (!publishEntry.IsCompleted) yield return null; | ||
| 159 | - | ||
| 160 | - print("dun did it"); | ||
| 161 | - } | ||
| 162 | - | ||
| 163 | - #endregion | ||
| 164 | -} |
ContentfulExample/Assets/Example.cs
0 → 100644
| 1 | +using System.Collections; | ||
| 2 | +using System.Collections.Generic; | ||
| 3 | +using UnityEngine; | ||
| 4 | +using Sirenix.OdinInspector; | ||
| 5 | +using Contentful.Globacore; | ||
| 6 | + | ||
| 7 | +[System.Serializable] | ||
| 8 | +public class User | ||
| 9 | +{ | ||
| 10 | + public string firstName, lastName, email; | ||
| 11 | + public Race race; | ||
| 12 | +} | ||
| 13 | + | ||
| 14 | +[System.Serializable] | ||
| 15 | +public class Race | ||
| 16 | +{ | ||
| 17 | + public float raceTime; | ||
| 18 | + public string fuckinIdk; | ||
| 19 | +} | ||
| 20 | + | ||
| 21 | +public class Example : MonoBehaviour | ||
| 22 | +{ | ||
| 23 | + public User fetchedUser = new User(); | ||
| 24 | + public string searchEmail; | ||
| 25 | + | ||
| 26 | + [Button("Get Single User")] | ||
| 27 | + public void GetUser() | ||
| 28 | + { | ||
| 29 | + Request req = new Request(); | ||
| 30 | + req.onComplete = UserFetched; | ||
| 31 | + req.Send<User>("email", searchEmail); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + private void UserFetched(Response resp) | ||
| 35 | + { | ||
| 36 | + fetchedUser = resp.GetFirst<User>(); | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + [Button("Get All Races")] | ||
| 40 | + public void GetRaces() | ||
| 41 | + { | ||
| 42 | + Request req = new Request(); | ||
| 43 | + req.onComplete = RacesFetched; | ||
| 44 | + req.Send<Race>(); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + [TableList] | ||
| 48 | + public List<Race> races = new List<Race>(); | ||
| 49 | + | ||
| 50 | + private void RacesFetched(Response resp) | ||
| 51 | + { | ||
| 52 | + races = resp.GetAll<Race>(); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + void Start() | ||
| 56 | + { | ||
| 57 | + | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + // Update is called once per frame | ||
| 61 | + void Update() | ||
| 62 | + { | ||
| 63 | + | ||
| 64 | + } | ||
| 65 | +} |
ContentfulExample/Assets/Example.cs.meta
0 → 100644
| ... | @@ -301,9 +301,9 @@ MonoBehaviour: | ... | @@ -301,9 +301,9 @@ MonoBehaviour: |
| 301 | email: | 301 | email: |
| 302 | allUsers: [] | 302 | allUsers: [] |
| 303 | userToCreate: | 303 | userToCreate: |
| 304 | - firstName: | 304 | + firstName: dave |
| 305 | - lastName: | 305 | + lastName: boyle |
| 306 | - email: | 306 | + email: tester@globacore.com |
| 307 | --- !u!4 &1143836155 | 307 | --- !u!4 &1143836155 |
| 308 | Transform: | 308 | Transform: |
| 309 | m_ObjectHideFlags: 0 | 309 | m_ObjectHideFlags: 0 | ... | ... |
-
Please register or sign in to post a comment