Beispiel #1
0
        public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = nameof(GetGameByEntryCode))]
                                              HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(GetGameByEntryCode)
            }))
            {
                try
                {
                    var kvps      = req.GetQueryNameValuePairs();
                    var email     = kvps.FirstOrDefault(kvp => kvp.Key == "email").Value;
                    var entryCode = kvps.FirstOrDefault(kvp => kvp.Key == "entryCode").Value;

                    var existingGame = CosmosDataService.Instance.GetOngoingGame(email);

                    if (existingGame != null)
                    {
                        return(req.CreateErrorResponse(HttpStatusCode.Conflict, "User already has an ongoing game"));
                    }

                    var openGame = CosmosDataService.Instance.GetGameByEntryCode(entryCode);

                    return(req.CreateResponse(HttpStatusCode.OK, openGame));
                }
                catch (Exception e)
                {
                    // track exceptions that occur
                    analytic.TrackException(e);
                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, e.Message, e));
                }
            }
        }
Beispiel #2
0
        public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = nameof(RegisterDevice))]
                                              HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(AnalyseText)
            }))
            {
                try
                {
                    var json         = req.Content.ReadAsStringAsync().Result;
                    var registration = JsonConvert.DeserializeObject <DeviceRegistration>(json);

                    var instance = registration.AppMode == AppMode.Dev ? PushService.Dev : PushService.Production;
                    var result   = instance.Register(registration).Result;

                    return(req.CreateResponse(HttpStatusCode.OK, result));
                }
                catch (Exception e)
                {
                    analytic.TrackException(e.GetBaseException());
                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, e.GetBaseException()));
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Not used right now
        /// </summary>
        /// <param name="game"></param>
        static void CreateAudiences(Game game, AnalyticService analytic)
        {
            //Configure the proper Push Audiences in Mobile Center so notifications can be sent to all in a game or team
            var p       = new PushService();
            var success = p.CreateAudience(HuntAudience.GameId, game.Id).Result;

            if (success)
            {
                foreach (var team in game.Teams)
                {
                    var good = p.CreateAudience(HuntAudience.TeamId, team.Id).Result;

                    if (!good)
                    {
                        throw new Exception("Unable to properly configure push notifications");
                    }
                }
            }
            else
            {
                var e = new Exception("Unable to properly configure push notifications");

                // track exceptions that occur
                analytic.TrackException(e);

                throw e;
            }
        }
Beispiel #4
0
        public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = nameof(GetGame))]
                                              HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(GetGame)
            }))
            {
                try
                {
                    var gameId = req.GetQueryNameValuePairs().FirstOrDefault(kvp => kvp.Key == "id").Value;

                    using (var client = new CosmosDataService())
                    {
                        var game = client.GetItemAsync <Game>(gameId).Result;

                        return(req.CreateResponse(HttpStatusCode.OK, game));
                    }
                }
                catch (Exception e)
                {
                    analytic.TrackException(e);

                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, e));
                }
            }
        }
Beispiel #5
0
        async public static Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = nameof(RegisterDevice))]
                                                           HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(AnalyseText)
            }))
            {
                try
                {
                    var json         = req.Content.ReadAsStringAsync().Result;
                    var registration = JsonConvert.DeserializeObject <DeviceRegistration>(json);

                    var instance = registration.AppMode == AppMode.Dev ? PushService.Dev : PushService.Production;
                    var result   = instance.Register(registration).Result;

                    var data = new Event("Registering device");
                    data.Add("mode", registration.AppMode).Add("OS", registration.Platform).Add("handle", registration.Handle).Add("tags", string.Join(", ", registration.Tags).Trim());
                    await EventHubService.Instance.SendEvent(data);

                    return(req.CreateResponse(HttpStatusCode.OK, result));
                }
                catch (Exception e)
                {
                    analytic.TrackException(e.GetBaseException());
                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, e.GetBaseException()));
                }
            }
        }
Beispiel #6
0
        public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "post",
                                                           Route = nameof(PostMessageToQueue))]
                                              HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(PostMessageToQueue)
            }))
            {
                var image = req.GetObject <byte[]>();

                try
                {
                    using (var client = new QueueService("imageprocess"))
                    {
                        client.SendBrokeredMessageAsync(image).Wait();

                        return(req.CreateResponse(HttpStatusCode.OK));
                    }
                }
                catch (Exception e)
                {
                    // track exceptions that occur
                    analytic.TrackException(e);

                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, e));
                }
            }
        }
Beispiel #7
0
        public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = nameof(GetOngoingGame))]
                                              HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(GetOngoingGame)
            }))
            {
                try
                {
                    var email = req.GetQueryNameValuePairs().FirstOrDefault(kvp => kvp.Key == "email").Value;

                    if (string.IsNullOrWhiteSpace(email))
                    {
                        return(req.CreateErrorResponse(HttpStatusCode.BadRequest, "email address required"));
                    }

                    using (var client = new CosmosDataService())
                    {
                        var game = client.GetOngoingGame(email);

                        return(req.CreateResponse(HttpStatusCode.OK, game as Object));
                    }
                }
                catch (Exception e)
                {
                    // track exceptions that occur
                    analytic.TrackException(e);

                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, e));
                }
            }
        }
Beispiel #8
0
        async public static Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = nameof(AnalyseImage))]
                                                           HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(AnalyseImage)
            }))
            {
                try
                {
                    var allTags   = new List <string>();
                    var json      = req.Content.ReadAsStringAsync().Result;
                    var photoUrls = JsonConvert.DeserializeObject <string[]>(json);

                    foreach (var url in photoUrls)
                    {
                        var result = VisionService.Instance.GetImageDescriptionAsync(url).Result;
                        allTags.AddRange(result.Tags.Select(t => t.Name).ToArray());
                        allTags.AddRange(result.Description.Tags);
                    }

                    var attributes = new Dictionary <string, int>();
                    foreach (var tag in allTags)
                    {
                        if (tag.Equals("indoor", StringComparison.InvariantCultureIgnoreCase) ||
                            tag.Equals("outdoor", StringComparison.InvariantCultureIgnoreCase))
                        {
                            continue;
                        }

                        if (attributes.ContainsKey(tag))
                        {
                            attributes[tag]++;
                        }
                        else
                        {
                            attributes.Add(tag, 1);
                        }
                    }

                    var topAttributes = attributes.OrderByDescending(k => k.Value);
                    var toReturn      = topAttributes.Select(k => k.Key).Take(10).ToArray();

                    var data = new Event("Generic image analyzed for tags");
                    data.Add("image", photoUrls.First()).Add("tags", string.Join(", ", toReturn).Trim());
                    await EventHubService.Instance.SendEvent(data);

                    return(req.CreateResponse(HttpStatusCode.OK, toReturn));
                }
                catch (Exception e)
                {
                    analytic.TrackException(e);

                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, e));
                }
            }
        }
Beispiel #9
0
 public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = nameof(WakeUp))]
                                       HttpRequestMessage req, TraceWriter log)
 {
     using (var analytic = new AnalyticService(new RequestTelemetry
     {
         Name = nameof(WakeUp)
     }))
     {
         return(req.CreateResponse(HttpStatusCode.OK));
     }
 }
Beispiel #10
0
 static void SetEndGameTimer(Game game, AnalyticService analytic)
 {
     try
     {
         var client = new QueueService(Keys.ServiceBus.EndGameBusName);
         client.SendBrokeredMessageAsync(game.DurationInMinutes, game.Id, "endgametime", (int)game.DurationInMinutes).Wait();
     }
     catch (Exception e)
     {
         analytic.TrackException(e);
     }
 }
Beispiel #11
0
        async public static Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = nameof(WakeUp))]
                                                           HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(WakeUp)
            }))
            {
                await EventHubService.Instance.SendEvent(new Event("Wake request received"));

                return(req.CreateResponse(HttpStatusCode.OK));
            }
        }
Beispiel #12
0
        async public static Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = nameof(AnalyseText))]
                                                           HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(AnalyseText)
            }))
            {
                try
                {
                    var text = req.GetQueryNameValuePairs().FirstOrDefault(kvp => kvp.Key == "text").Value;

                    using (var client = new HttpClient())
                    {
                        var queryString = HttpUtility.ParseQueryString(string.Empty);

                        client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", ConfigManager.Instance.ContentModeratorKey);

                        queryString["autocorrect"] = "{boolean}";
                        queryString["PII"]         = "{boolean}";
                        queryString["listId"]      = "{string}";

                        var uri = ConfigManager.Instance.ContentModeratorUrl + queryString;
                        HttpResponseMessage response;
                        byte[] byteData = Encoding.UTF8.GetBytes(text);

                        using (var content = new ByteArrayContent(byteData))
                        {
                            content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
                            response = client.PostAsync(uri, content).Result;

                            var json           = response.Content.ReadAsStringAsync().Result;
                            var textModeration = JsonConvert.DeserializeObject <TextModeration>(json);

                            var terms = textModeration.Terms == null ? "NONE" : string.Join(", ", textModeration.Terms.Select(t => t.TermString).ToArray()).Trim();
                            var data  = new Event("Analyzing text for appropriate content");
                            data.Add("text", text).Add("terms", terms);
                            await EventHubService.Instance.SendEvent(data);

                            return(req.CreateResponse(HttpStatusCode.OK, textModeration.Terms == null));
                        }
                    }
                }
                catch (Exception e)
                {
                    analytic.TrackException(e);

                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, e));
                }
            }
        }
Beispiel #13
0
        public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = nameof(GetStorageToken))]
                                                           HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(GetStorageToken)
            }))
            {
                try
                {
                    var kvps     = req.GetQueryNameValuePairs();
                    var blobName = kvps.FirstOrDefault(kvp => kvp.Key == "blobName").Value;

                    if (string.IsNullOrWhiteSpace(blobName))
                    {
                        var e = new ArgumentNullException(nameof(blobName));

                        // track exceptions that occur
                        analytic.TrackException(e);

                        throw e;
                    }

                    if (_storageAccount == null)
                    {
                        _storageAccount = CloudStorageAccount.Parse(ConfigManager.Instance.BlobSharedStorageKey);
                    }

                    if (_blobClient == null)
                    {
                        _blobClient = _storageAccount.CreateCloudBlobClient();
                    }

                    _container = _blobClient.GetContainerReference(ConfigManager.BlobImageContainer);
                    await _container.CreateIfNotExistsAsync();

                    var sasUri = await GetSASToken(blobName);

                    var token = new StorageToken(blobName, sasUri);

                    return(req.CreateResponse(HttpStatusCode.OK, token));
                }
                catch (Exception e)
                {
                    // track exceptions that occur
                    analytic.TrackException(e);

                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, e.Message, e));
                }
            }
        }
Beispiel #14
0
        async public static Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = nameof(GetGameByEntryCode))]
                                                           HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(GetGameByEntryCode)
            }))
            {
                try
                {
                    var kvps      = req.GetQueryNameValuePairs();
                    var email     = kvps.FirstOrDefault(kvp => kvp.Key == "email").Value;
                    var entryCode = kvps.FirstOrDefault(kvp => kvp.Key == "entryCode").Value;

                    var existingGame = CosmosDataService.Instance.GetOngoingGame(email);

                    if (existingGame != null)
                    {
                        var data = new Event("Attempt to lookup game by entry code failed due to ongoing game");
                        data.Add("code", entryCode).Add("email", email);
                        await EventHubService.Instance.SendEvent(data);

                        return(req.CreateErrorResponse(HttpStatusCode.Conflict, "User already has an ongoing game"));
                    }

                    var openGame = CosmosDataService.Instance.GetGameByEntryCode(entryCode);
                    var outcome  = openGame == null ? "failed" : "succeeded";

                    {
                        var data = new Event($"Attempt to lookup game by entry code {outcome}");
                        data.Add("code", entryCode).Add("email", email);
                        await EventHubService.Instance.SendEvent(data, openGame);
                    }

                    return(req.CreateResponse(HttpStatusCode.OK, openGame));
                }
                catch (Exception e)
                {
                    // track exceptions that occur
                    analytic.TrackException(e);
                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, e.Message, e));
                }
            }
        }
Beispiel #15
0
        async public static Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = nameof(GetOngoingGame))]
                                                           HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(GetOngoingGame)
            }))
            {
                try
                {
                    var email = req.GetQueryNameValuePairs().FirstOrDefault(kvp => kvp.Key == "email").Value;

                    if (string.IsNullOrWhiteSpace(email))
                    {
                        return(req.CreateErrorResponse(HttpStatusCode.BadRequest, "email address required"));
                    }

                    var json    = CosmosDataService.Instance.GetOngoingGame(email);
                    var game    = json == null ? null : JsonConvert.DeserializeObject <Game>(json.ToString()) as Game;
                    var outcome = json == null ? "no games found" : "a game found";

                    var data = new Event($"Looking for an ongoing game resulted in {outcome}");
                    data.Add("email", email);

                    await EventHubService.Instance.SendEvent(data, game);

                    return(req.CreateResponse(HttpStatusCode.OK, game));
                }
                catch (Exception e)
                {
                    // track exceptions that occur
                    analytic.TrackException(e.GetBaseException());
                    var msg = e.GetBaseException().Message;
                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, e.GetBaseException().Message));
                }
            }
        }
Beispiel #16
0
        async public static Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = nameof(TrainClassifier))]
                                                           HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(TrainClassifier)
            }))
            {
                try
                {
                    var allTags   = new List <string>();
                    var json      = req.Content.ReadAsStringAsync().Result;
                    var j         = JObject.Parse(json);
                    var gameId    = (string)j["gameId"];
                    var imageUrls = j["imageUrls"].ToObject <List <string> >();
                    var tags      = (JArray)j["tags"];

                    var         game = CosmosDataService.Instance.GetItemAsync <Game>(gameId).Result;
                    TrainingApi api  = new TrainingApi {
                        ApiKey = ConfigManager.Instance.CustomVisionTrainingKey
                    };
                    Project project = null;

                    //Get the existing project for this game if there is one
                    if (!string.IsNullOrEmpty(game.CustomVisionProjectId))
                    {
                        try     { project = api.GetProject(Guid.Parse(game.CustomVisionProjectId)); }
                        catch (Exception) { }
                    }

                    //Otherwise create a new project and associate it with the game
                    if (project == null)
                    {
                        project = api.CreateProject($"{game.Name}_{DateTime.Now.ToString()}_{Guid.NewGuid().ToString()}", game.Id);
                        game.CustomVisionProjectId = project.Id.ToString();
                        CosmosDataService.Instance.UpdateItemAsync <Game>(game).Wait();
                    }

                    var tagItems = tags.Select(t => api.CreateTag(project.Id, t.ToString().Trim()));
                    var entries  = imageUrls.Select(u => new ImageUrlCreateEntry(u)).ToList();

                    //Batch the image urls that were sent up from Azure Storage (blob)
                    var batch   = new ImageUrlCreateBatch(entries, tagItems.Select(t => t.Id).ToList());
                    var summary = api.CreateImagesFromUrls(project.Id, batch);

                    //if(!summary.IsBatchSuccessful)
                    //	return req.CreateErrorResponse(HttpStatusCode.BadRequest, "Image batch was unsuccessful");

                    //Traing the classifier and generate a new iteration, that we'll set as the default
                    var iteration = api.TrainProject(project.Id);

                    while (iteration.Status == "Training")
                    {
                        Thread.Sleep(1000);
                        iteration = api.GetIteration(project.Id, iteration.Id);
                    }

                    iteration.IsDefault = true;
                    api.UpdateIteration(project.Id, iteration.Id, iteration);

                    var data = new Event("Training classifier");
                    data.Add("project", project.Name);
                    data.Add("iteration", iteration.Id);
                    await EventHubService.Instance.SendEvent(data);

                    return(req.CreateResponse(HttpStatusCode.OK, true));
                }
                catch (Exception e)
                {
                    analytic.TrackException(e);

                    var baseException      = e.GetBaseException();
                    var operationException = baseException as HttpOperationException;
                    var reason             = baseException.Message;

                    if (operationException != null)
                    {
                        var jobj = JObject.Parse(operationException.Response.Content);
                        var code = jobj.GetValue("Code");

                        if (code != null && !string.IsNullOrWhiteSpace(code.ToString()))
                        {
                            reason = code.ToString();
                        }
                    }

                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, reason));
                }
            }
        }
Beispiel #17
0
        public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = nameof(SaveGame))]
                                              HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(SaveGame)
            }))
            {
                var json    = req.Content.ReadAsStringAsync().Result;
                var jobject = JsonConvert.DeserializeObject <JObject>(json);

                var action    = jobject["action"].ToString();
                var arguments = jobject["arguments"].ToObject <Dictionary <string, string> >();
                var game      = jobject["game"].ToObject <Game>();
                arguments = arguments ?? new Dictionary <string, string>();

                //Need to validate this player is not already part of another ongoing game or the coordinator of this game
                if (game.EntryCode == null)
                {
                    //Let's hope this is generally random. Best to confirm the code is not already in used but I'm lazy
                    game.EntryCode = Math.Abs(game.Id.GetHashCode()).ToString().Substring(0, 6);
                }

                Game savedGame   = null;
                bool isEndOfgame = false;
                try
                {
                    if (!game.IsPersisted)
                    {
                        CosmosDataService.Instance.InsertItemAsync(game).Wait();
                    }
                    else
                    {
                        var existingGame = CosmosDataService.Instance.GetItemAsync <Game>(game.Id).Result;
                        if (existingGame.TS != game.TS)
                        {
                            return(req.CreateErrorResponse(HttpStatusCode.Conflict, "Unable to save game - version conflict. Please pull the latest version and reapply your changes."));
                        }

                        if (action == GameUpdateAction.EndGame && existingGame.HasEnded)
                        {
                            return(req.CreateResponse(HttpStatusCode.OK));
                        }

                        if (action == GameUpdateAction.StartGame)
                        {
                            game.StartDate = DateTime.UtcNow;
                        }

                        if (action == GameUpdateAction.EndGame)
                        {
                            isEndOfgame = true;
                        }

                        bool isWinningAcquisition = false;
                        if (action == GameUpdateAction.AcquireTreasure)
                        {
                            //Need to evaluate the game first before we save as there might be a winner
                            var teamId = arguments["teamId"];
                            isWinningAcquisition = game.EvaluateGameForWinner(teamId);

                            if (isWinningAcquisition)
                            {
                                isEndOfgame = true;
                            }
                        }

                        if (isEndOfgame)
                        {
                            game.EndDate = DateTime.UtcNow;
                            var teams = game.Teams.OrderByDescending(t => t.TotalPoints).ToArray();

                            if (teams[0].TotalPoints == teams[1].TotalPoints)
                            {
                                game.WinnningTeamId = null;                                 //Draw
                            }
                            else
                            {
                                game.WinnningTeamId = teams[0].Id;
                            }
                        }

                        CosmosDataService.Instance.UpdateItemAsync(game).Wait();

                        if (action == GameUpdateAction.StartGame)
                        {
                            SetEndGameTimer(game, analytic);
                        }

                        if (isEndOfgame)
                        {
                            SendTargetedNotifications(game, GameUpdateAction.EndGame, arguments);
                        }
                        else
                        {
                            SendTargetedNotifications(game, action, arguments);
                        }
                    }

                    savedGame = CosmosDataService.Instance.GetItemAsync <Game>(game.Id).Result;                    //Comment out at some point if not needed

                    return(req.CreateResponse(HttpStatusCode.OK, savedGame));
                }
                catch (Exception e)
                {
                    // track exceptions that occur
                    analytic.TrackException(e);
                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, e.Message, e));
                }
            }
        }
Beispiel #18
0
        async public static Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = nameof(AnalyseCustomImage))]
                                                           HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(AnalyseCustomImage)
            }))
            {
                try
                {
                    var allTags    = new List <string>();
                    var j          = JObject.Parse(req.Content.ReadAsStringAsync().Result);
                    var imageUrl   = (string)j["imageUrl"];
                    var treasureId = (string)j["treasureId"];
                    var gameId     = (string)j["gameId"];

                    var game = CosmosDataService.Instance.GetItemAsync <Game>(gameId).Result;
                    if (game == null)
                    {
                        return(req.CreateErrorResponse(HttpStatusCode.NotFound, "Game not found"));
                    }

                    var treasure = game.Treasures.SingleOrDefault(t => t.Id == treasureId);
                    if (treasure == null)
                    {
                        var data = new Event("Custom image analyzed for treasure failed");
                        data.Add("hint", treasure.Hint).Add("source", treasure.ImageSource).Add("sent", imageUrl);
                        await EventHubService.Instance.SendEvent(data);

                        return(req.CreateErrorResponse(HttpStatusCode.NotFound, "Treasure not found"));
                    }

                    var endpoint = new PredictionEndpoint {
                        ApiKey = ConfigManager.Instance.CustomVisionPredictionKey
                    };

                    //This is where we run our prediction against the default iteration
                    var result = endpoint.PredictImageUrl(new Guid(game.CustomVisionProjectId), new ImageUrl(imageUrl));


                    ImageTagPredictionModel goodTag = null;
                    // Loop over each prediction and write out the results

                    foreach (var prediction in result.Predictions)
                    {
                        if (treasure.Attributes.Any(a => a.Name.Equals(prediction.Tag, StringComparison.InvariantCultureIgnoreCase)))
                        {
                            if (prediction.Probability >= ConfigManager.Instance.CustomVisionMinimumPredictionProbability)
                            {
                                goodTag = prediction;
                                break;
                            }
                        }
                    }

                    {
                        var outcome = goodTag == null ? "failed" : "succeeded";
                        var data    = new Event($"Custom image analyzed for treasure {outcome}");

                        if (goodTag != null)
                        {
                            data.Add("tags", goodTag.Tag).Add("probability", goodTag.Probability.ToString("P"));
                        }

                        data.Add("hint", treasure.Hint).Add("source", treasure.ImageSource).Add("sent", imageUrl);

                        await EventHubService.Instance.SendEvent(data);
                    }

                    return(req.CreateResponse(HttpStatusCode.OK, goodTag != null));
                }
                catch (Exception e)
                {
                    analytic.TrackException(e);

                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, e));
                }
            }
        }
Beispiel #19
0
        public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = nameof(AnalyseCustomImage))]
                                              HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(AnalyseCustomImage)
            }))
            {
                try
                {
                    var allTags    = new List <string>();
                    var j          = JObject.Parse(req.Content.ReadAsStringAsync().Result);
                    var imageUrl   = (string)j["imageUrl"];
                    var treasureId = (string)j["treasureId"];
                    var gameId     = (string)j["gameId"];

                    var game = CosmosDataService.Instance.GetItemAsync <Game>(gameId).Result;
                    if (game == null)
                    {
                        return(req.CreateErrorResponse(HttpStatusCode.NotFound, "Game not found"));
                    }

                    var treasure = game.Treasures.SingleOrDefault(t => t.Id == treasureId);
                    if (treasure == null)
                    {
                        return(req.CreateErrorResponse(HttpStatusCode.NotFound, "Treasure not found"));
                    }

                    var api           = new TrainingApi(new TrainingApiCredentials(ConfigManager.Instance.CustomVisionTrainingKey));
                    var account       = api.GetAccountInfo();
                    var predictionKey = account.Keys.PredictionKeys.PrimaryKey;

                    var creds    = new PredictionEndpointCredentials(predictionKey);
                    var endpoint = new PredictionEndpoint(creds);

                    //This is where we run our prediction against the default iteration
                    var result = endpoint.PredictImageUrl(new Guid(game.CustomVisionProjectId), new ImageUrl(imageUrl));

                    bool toReturn = false;
                    // Loop over each prediction and write out the results
                    foreach (var outcome in result.Predictions)
                    {
                        if (treasure.Attributes.Any(a => a.Name.Equals(outcome.Tag, StringComparison.InvariantCultureIgnoreCase)))
                        {
                            if (outcome.Probability >= ConfigManager.Instance.CustomVisionMinimumPredictionProbability)
                            {
                                toReturn = true;
                                break;
                            }
                        }
                    }

                    return(req.CreateResponse(HttpStatusCode.OK, toReturn));
                }
                catch (Exception e)
                {
                    analytic.TrackException(e);

                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, e));
                }
            }
        }
Beispiel #20
0
        public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = nameof(TrainClassifier))]
                                              HttpRequestMessage req, TraceWriter log)
        {
            using (var analytic = new AnalyticService(new RequestTelemetry
            {
                Name = nameof(TrainClassifier)
            }))
            {
                try
                {
                    var allTags   = new List <string>();
                    var json      = req.Content.ReadAsStringAsync().Result;
                    var j         = JObject.Parse(json);
                    var gameId    = (string)j["gameId"];
                    var imageUrls = j["imageUrls"].ToObject <List <string> >();
                    var tags      = (JArray)j["tags"];

                    var game = CosmosDataService.Instance.GetItemAsync <Game>(gameId).Result;

                    var          api     = new TrainingApi(new TrainingApiCredentials(ConfigManager.Instance.CustomVisionTrainingKey));
                    ProjectModel project = null;

                    //Get the existing project for this game if there is one
                    if (!string.IsNullOrEmpty(game.CustomVisionProjectId))
                    {
                        try
                        {
                            project = api.GetProject(Guid.Parse(game.CustomVisionProjectId));
                        }
                        catch (Exception) { }
                    }

                    //Otherwise create a new project and associate it with the game
                    if (project == null)
                    {
                        project = api.CreateProject(game.Name, game.Id);
                        game.CustomVisionProjectId = project.Id.ToString();
                        CosmosDataService.Instance.UpdateItemAsync <Game>(game).Wait();
                    }

                    //Generate tag models for training
                    var tagModels = new List <ImageTagModel>();
                    foreach (string tag in tags)
                    {
                        var model = api.CreateTag(project.Id, tag.Trim());
                        tagModels.Add(model);
                    }

                    //Batch the image urls that were sent up from Azure Storage (blob)
                    var batch   = new ImageUrlCreateBatch(tagModels.Select(m => m.Id).ToList(), imageUrls);
                    var summary = api.CreateImagesFromUrls(project.Id, batch);

                    if (!summary.IsBatchSuccessful)
                    {
                        return(req.CreateErrorResponse(HttpStatusCode.BadRequest, "Image batch was unsuccessful"));
                    }

                    //Traing the classifier and generate a new iteration, that we'll set as the default
                    var iteration = api.TrainProject(project.Id);

                    while (iteration.Status == "Training")
                    {
                        Thread.Sleep(1000);
                        iteration = api.GetIteration(project.Id, iteration.Id);
                    }

                    iteration.IsDefault = true;
                    api.UpdateIteration(project.Id, iteration.Id, iteration);

                    return(req.CreateResponse(HttpStatusCode.OK, true));
                }
                catch (Exception e)
                {
                    analytic.TrackException(e);

                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, e));
                }
            }
        }