Example #1
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "DeleteInReachFeedFromCosmos/{userWebId}/{trackId}")] HttpRequest req,
            [CosmosDB(
                 databaseName: "FreeCosmosDB",
                 collectionName: "TrackMe",
                 ConnectionStringSetting = "CosmosDBForFree",
                 PartitionKey = "{userWebId}",
                 Id = "{trackId}"
                 )] KMLInfo kMLInfo,
            [CosmosDB(
                 databaseName: "FreeCosmosDB",
                 collectionName: "TrackMe",
                 ConnectionStringSetting = "CosmosDBForFree",
                 SqlQuery = "SELECT * FROM c WHERE c.groupid = 'user'"
                 )] IEnumerable <InReachUser> inReachUsers,
            [CosmosDB(
                 databaseName: "FreeCosmosDB",
                 collectionName: "TrackMe",
                 ConnectionStringSetting = "CosmosDBForFree"
                 )] DocumentClient documentClient,
            ExecutionContext context)
        {
            var config = new ConfigurationBuilder()
                         .SetBasePath(context.FunctionAppDirectory)
                         .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                         .AddEnvironmentVariables()
                         .Build();
            var StorageContainerConnectionString = config["StorageContainerConnectionString"];
            CloudStorageAccount storageAccount   = CloudStorageAccount.Parse(StorageContainerConnectionString);
            CloudBlobClient     blobClient       = storageAccount.CreateCloudBlobClient();

            HelperKMLParse  helperKMLParse  = new HelperKMLParse();
            ClaimsPrincipal Identities      = req.HttpContext.User;
            var             checkUser       = new HelperCheckUser();
            var             LoggedInUser    = checkUser.LoggedInUser(inReachUsers, Identities);
            var             IsAuthenticated = false;

            if (LoggedInUser.status == Status.ExistingUser)
            {
                IsAuthenticated = true;
            }

            if (IsAuthenticated)
            {
                //selfLink is like this: "dbs/auo6AA==/colls/auo6AOdfluE=/docs/auo6AOdfluEnFwIAAAAAAA==/";
                await documentClient.DeleteDocumentAsync(kMLInfo._self, new RequestOptions { PartitionKey = new PartitionKey(LoggedInUser.userWebId) });

                //delete blobs
                foreach (var blob in helperKMLParse.Blobs)
                {
                    var blobName = $"{kMLInfo.groupid}/{kMLInfo.id}/{blob.BlobName}.kml";
                    await helperKMLParse.RemoveBlobAsync(blobName, blobClient);
                }
            }
            return(new OkObjectResult(IsAuthenticated));
        }
        public static async Task Run([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer,
                                     [CosmosDB(
                                          databaseName: "FreeCosmosDB",
                                          collectionName: "TrackMe",
                                          ConnectionStringSetting = "CosmosDBForFree"
                                          )]
                                     IAsyncCollector <KMLInfo> asyncCollectorKMLInfo,
                                     [CosmosDB(
                                          databaseName: "FreeCosmosDB",
                                          collectionName: "TrackMe",
                                          ConnectionStringSetting = "CosmosDBForFree"
                                          )] DocumentClient documentClient,
                                     [CosmosDB(
                                          databaseName: "FreeCosmosDB",
                                          collectionName: "TrackMe",
                                          ConnectionStringSetting = "CosmosDBForFree",
                                          SqlQuery = "SELECT * FROM c WHERE c.groupid = 'user'"
                                          )] IEnumerable <InReachUser> inReachUsers,
                                     ExecutionContext context)
        {
            var config = new ConfigurationBuilder()
                         .SetBasePath(context.FunctionAppDirectory)
                         .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                         .AddEnvironmentVariables()
                         .Build();
            var SendEmailFunctionKey             = config["SendEmailInReachFunctionKey"];
            var SendEmailFunctionUrl             = config["SendEmailFunctionUrl"];
            var WebSiteUrl                       = config["WebSiteUrl"];
            var TodayTrackId                     = config["TodayTrackId"];
            var StorageContainerConnectionString = config["StorageContainerConnectionString"];

            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(StorageContainerConnectionString);
            CloudBlobClient     blobClient     = storageAccount.CreateCloudBlobClient();

            Uri           collectionUri = UriFactory.CreateDocumentCollectionUri("FreeCosmosDB", "TrackMe");
            List <Emails> emails        = new List <Emails>();

            DateTime dateTimeUTC = DateTime.UtcNow.ToUniversalTime();

            //getting active tracks from CosmosDB
            var query = new SqlQuerySpec("SELECT * FROM c WHERE (c.d1 < @dateTimeUTC and c.d2 > @dateTimeUTC) or c.id = @TodayTrack",
                                         new SqlParameterCollection(new SqlParameter[] { new SqlParameter {
                                                                                             Name = "@dateTimeUTC", Value = dateTimeUTC
                                                                                         }, new SqlParameter {
                                                                                             Name = "@TodayTrack", Value = TodayTrackId
                                                                                         } }));
            IEnumerable <KMLInfo> kMLInfos = documentClient.CreateDocumentQuery <KMLInfo>(collectionUri, query, new FeedOptions {
                EnableCrossPartitionQuery = true
            }).AsEnumerable();

            //remove all duplicates by LastPointTimestamp and groupid field to make only one query to Garmin per user (if user has multiple Live tracks in same time)
            IEnumerable <KMLInfo> kMLInfoDeDups = kMLInfos.GroupBy(x => new { x.LastPointTimestamp, x.groupid }).Select(x => x.First()).ToList();

            //getting feed from garmin, one feed for each user if LastpointTimestamp is same
            foreach (var kMLInfoDeDup in kMLInfoDeDups)
            {
                DateTime lastd1 = DateTime.SpecifyKind(DateTime.Parse(kMLInfoDeDup.d1, CultureInfo.InvariantCulture), DateTimeKind.Utc);
                DateTime today  = DateTime.UtcNow.ToUniversalTime().AddDays(-1);

                //set d1 to LastPointTimestamp + 1 second (if LastTimestamp exist) to download the feed from that point forward from Garmin
                if (!string.IsNullOrEmpty(kMLInfoDeDup.LastPointTimestamp))
                {
                    kMLInfoDeDup.d1 = DateTime.Parse(kMLInfoDeDup.LastPointTimestamp, CultureInfo.InvariantCulture).AddSeconds(1).ToString("yyyy-MM-ddTHH:mm:ssZ");
                }
                else
                {
                    kMLInfoDeDup.d1 = DateTime.Parse(kMLInfoDeDup.d1, CultureInfo.InvariantCulture).ToString("yyyy-MM-ddTHH:mm:ssZ");
                }

                //resetting Today's track, once at night according to user Timezone
                if (lastd1 < today && kMLInfoDeDup.id == TodayTrackId)
                {
                    var dated1     = DateTime.UtcNow.ToUniversalTime().AddHours(kMLInfoDeDup.UserTimezone).ToString("yyyy-MM-dd");
                    var dateTimed1 = DateTime.Parse(dated1).AddHours(-kMLInfoDeDup.UserTimezone).ToString("yyyy-MM-ddTHH:mm:ssZ");
                    var dateTimed2 = DateTime.Parse(dated1).AddDays(1).AddHours(-kMLInfoDeDup.UserTimezone).ToString("yyyy-MM-ddTHH:mm:ssZ");
                    kMLInfoDeDup.d1 = dateTimed1;
                    kMLInfoDeDup.d2 = dateTimed2;
                    kMLInfoDeDup.LastPointTimestamp = "";
                    kMLInfoDeDup.LastLatitude       = 0;
                    kMLInfoDeDup.LastLongitude      = 0;
                    kMLInfoDeDup.LastTotalDistance  = 0;
                    kMLInfoDeDup.LastTotalTime      = "";
                    kMLInfoDeDup.TrackStartTime     = "";
                    await asyncCollectorKMLInfo.AddAsync(kMLInfoDeDup);

                    //delete Today's blobs
                    foreach (var blob in helperKMLParse.Blobs)
                    {
                        var blobName = $"{kMLInfoDeDup.groupid}/{kMLInfoDeDup.id}/{blob.BlobName}.kml";
                        await helperKMLParse.RemoveBlobAsync(blobName, blobClient);
                    }
                }
                //getting always only last point from garmin (except if new day with active tracking has started)
                HelperGetKMLFromGarmin GetKMLFromGarmin = new HelperGetKMLFromGarmin();
                var kmlFeedresult = await GetKMLFromGarmin.GetKMLAsync(kMLInfoDeDup);

                kMLInfoDeDup.LastPoint = kmlFeedresult;
            }

            foreach (var kMLInfo in kMLInfos)
            {
                var kmlFeedresult = kMLInfoDeDups.First(x => x.groupid == kMLInfo.groupid).LastPoint;
                //if there are new points, then load whole track from database and add the point
                if (helperKMLParse.IsThereNewPoints(kmlFeedresult, kMLInfo))
                {
                    var user = new InReachUser();
                    foreach (var usr in inReachUsers)
                    {
                        if (usr.userWebId == kMLInfo.groupid)
                        {
                            user = usr;
                            break;
                        }
                    }
                    //open KML feeds from Blobstorage
                    var blobs = helperKMLParse.Blobs;
                    foreach (var blob in blobs)
                    {
                        var blobName = $"{kMLInfo.groupid}/{kMLInfo.id}/{blob.BlobName}.kml";
                        blob.BlobValue = await helperKMLParse.GetFromBlobAsync(blobName, blobClient);
                    }

                    //process the full track
                    helperKMLParse.ParseKMLFile(kmlFeedresult, kMLInfo, blobs, emails, user, WebSiteUrl);

                    kMLInfo.d1 = DateTime.Parse(kMLInfo.d1, CultureInfo.InvariantCulture).ToString("yyyy-MM-ddTHH:mm:ssZ");
                    kMLInfo.d2 = DateTime.Parse(kMLInfo.d2, CultureInfo.InvariantCulture).ToString("yyyy-MM-ddTHH:mm:ssZ");

                    await asyncCollectorKMLInfo.AddAsync(kMLInfo);

                    //save blobs
                    foreach (var blob in blobs)
                    {
                        var blobName = $"{kMLInfo.groupid}/{kMLInfo.id}/{blob.BlobName}.kml";
                        await helperKMLParse.AddToBlobAsync(blobName, blob.BlobValue, blobClient);
                    }
                }
            }

            //remove all duplicates by DateTime field and sending the list to SendEmailFunction
            if (emails.Any())
            {
                List <Emails> emailList            = emails.GroupBy(x => x.DateTime).Select(x => x.First()).ToList();
                HttpClient    client               = new HttpClient();
                Uri           SendEmailFunctionUri = new Uri($"{SendEmailFunctionUrl}?code={SendEmailFunctionKey}");
                var           returnMessage        = await client.PostAsJsonAsync(SendEmailFunctionUri, emailList);
            }
        }
        static async Task ManageTodayTrack(InReachUser LoggedInUser, IAsyncCollector <KMLInfo> addDocuments, DocumentClient client, Uri collectionUri, string TodayTrackId, string SendEmailFunctionUrl, string SendEmailFunctionKey, string WebSiteUrl, CloudBlobClient blobClient)
        {
            var dated1     = DateTime.UtcNow.ToUniversalTime().ToString("yyyy-MM-dd");
            var dated2     = DateTime.UtcNow.ToUniversalTime().ToString("yyyy-MM-dd");
            var dateTimed1 = DateTime.Parse(dated1).AddHours(-LoggedInUser.UserTimezone).ToString("yyyy-MM-ddTHH:mm:ssZ");
            var dateTimed2 = DateTime.Parse(dated2).AddDays(1).AddHours(-LoggedInUser.UserTimezone).ToString("yyyy-MM-ddTHH:mm:ssZ");

            KMLInfo kMLInfo = new KMLInfo()
            {
                id                 = TodayTrackId,
                Title              = "Today's Live Track",
                d1                 = dateTimed1,
                d2                 = dateTimed2,
                groupid            = LoggedInUser.userWebId,
                InReachWebAddress  = LoggedInUser.InReachWebAddress,
                InReachWebPassword = LoggedInUser.InReachWebPassword,
                UserTimezone       = LoggedInUser.UserTimezone,
                IsLongTrack        = false
            };

            //create Today's track
            if (LoggedInUser.Active)
            {
                HelperGetKMLFromGarmin helperGetKMLFromGarmin = new HelperGetKMLFromGarmin();

                var emails = new List <Emails>();
                //get feed grom garmin
                var kmlFeedresult = await helperGetKMLFromGarmin.GetKMLAsync(kMLInfo);

                var blobs = helperKMLParse.Blobs;
                //parse and transform the feed and save to database
                helperKMLParse.ParseKMLFile(kmlFeedresult, kMLInfo, blobs, emails, LoggedInUser, WebSiteUrl);
                await addDocuments.AddAsync(kMLInfo);

                //save blobs
                foreach (var blob in blobs)
                {
                    var blobName = $"{kMLInfo.groupid}/{kMLInfo.id}/{blob.BlobName}.kml";
                    await helperKMLParse.AddToBlobAsync(blobName, blob.BlobValue, blobClient);
                }

                //sending out emails
                if (emails.Any())
                {
                    HttpClient httpClient           = new HttpClient();
                    Uri        SendEmailFunctionUri = new Uri($"{SendEmailFunctionUrl}?code={SendEmailFunctionKey}");
                    var        returnMessage        = await httpClient.PostAsJsonAsync(SendEmailFunctionUri, emails);
                }
            }
            //delete Today's track
            if (!LoggedInUser.Active)
            {
                //select and delete document
                var queryOne = new SqlQuerySpec("SELECT c._self, c.groupid, c.id FROM c WHERE c.id = @id",
                                                new SqlParameterCollection(new SqlParameter[] { new SqlParameter {
                                                                                                    Name = "@id", Value = kMLInfo.id
                                                                                                } }));
                KMLInfo kML = client.CreateDocumentQuery(collectionUri, queryOne, new FeedOptions {
                    PartitionKey = new PartitionKey(kMLInfo.groupid)
                }).AsEnumerable().FirstOrDefault();
                if (!(kML is null))
                {
                    //delete metadata
                    await client.DeleteDocumentAsync(kML._self, new RequestOptions { PartitionKey = new PartitionKey(kML.groupid) });

                    //delete blobs
                    foreach (var blob in helperKMLParse.Blobs)
                    {
                        var blobName = $"{kML.groupid}/{kML.id}/{blob.BlobName}.kml";
                        await helperKMLParse.RemoveBlobAsync(blobName, blobClient);
                    }
                }
            }
        }