public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "refreshfromgithubyaml")] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("RefreshFromGithubYaml(): Received request");

            using StreamReader reader = new StreamReader(req.Body);
            try
            {
                string requestBody = reader.ReadToEnd();
                var    repo        = JsonConvert.DeserializeObject <RepositoryEntity>(requestBody);

                var yamlData = await GithubExpertsData.GetTutorYamlAsync(repo.Repository);

                await ExpertData.UpsertExpertsAsync(yamlData.Experts, repo.Repository);

                return(new OkResult());
            }
            catch (JsonSerializationException ex)
            {
                log.LogError(string.Format("RefreshFromGithubYaml(): JsonSerializationException occurred {0}:{1}", ex.Message, ex.InnerException));
                return(new BadRequestObjectResult(ex.Message));
            }
            catch (StorageException ex)
            {
                log.LogError(string.Format("RefreshFromGithubYaml(): StorageException occurred {0}:{1}", ex.Message, ex.InnerException));
                return(new BadRequestObjectResult(ex.Message));
            }
            catch (Exception ex)
            {
                log.LogError(string.Format("RefreshFromGithubYaml(): Exception occurred {0}:{1}", ex.Message, ex.InnerException));
                return(new InternalServerErrorResult());
            }
        }
Example #2
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "experts/{repo}")] HttpRequest req,
            string repo,
            ILogger log)
        {
            GithubExperts yamlData = null;

            log.LogInformation("Experts(): Received request");

            var result = await ExpertData.GetExpertsAsync(repo);

            // If no results, we might not have data for this repo yet...try and get it.
            if (result.Count == 0)
            {
                try
                {
                    yamlData = await GithubExpertsData.GetTutorYamlAsync(repo.Replace("+", "/"));

                    if (yamlData != null)
                    {
                        await ExpertData.UpsertExpertsAsync(yamlData.Experts, repo);

                        result = yamlData.Experts;
                    }
                }
                catch (Exception ex)
                {
                    log.LogError(string.Format("Experts(): Exception occurred {0}:{1}", ex.Message, ex.InnerException));
                    return(new InternalServerErrorResult());
                }
            }

            return(new OkObjectResult(result));
        }
Example #3
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "patch", Route = "appointment/{repo}/{id}")] HttpRequest req,
            string repo,
            string id,
            ILogger log)
        {
            log.LogInformation("UpdateAppointment(): Received request");

            using StreamReader reader = new StreamReader(req.Body);
            try
            {
                string            requestBody       = reader.ReadToEnd();
                AppointmentEntity appointmentEntity = JsonConvert.DeserializeObject <AppointmentEntity>(requestBody);

                var table = CosmosTableUtil.GetTableReference("schedule");

                var appointment = await AppointmentData.GetAppointmentAsync(repo, id);

                if (appointment != null)
                {
                    appointment.Status = appointmentEntity.Status;
                    var expert = await ExpertData.GetExpertAsync(appointment.Expert);

                    // Update record
                    var result = await table.ExecuteAsync(TableOperation.InsertOrReplace(appointment));

                    // Send email to expert
                    await EmailUtil.SendEmailAsync(appointment, expert);

                    return(new OkResult());
                }
                else
                {
                    return(new NotFoundResult());
                }
            }
            catch (Exception ex)
            {
                log.LogError(string.Format("UpdateAppointment(): Exception occurred {0}:{1}", ex.Message, ex.InnerException));
                return(new InternalServerErrorResult());
            }
        }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "appointment")] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("CreateAppointment(): Received request");

            using StreamReader reader = new StreamReader(req.Body);
            try
            {
                string            requestBody       = reader.ReadToEnd();
                AppointmentEntity appointmentEntity = JsonConvert.DeserializeObject <AppointmentEntity>(requestBody);

                // Set status for new appointment request
                appointmentEntity.Status   = "requested";
                appointmentEntity.RoomName = await CatNameGenerator.NewCatAsync();

                var table  = CosmosTableUtil.GetTableReference("schedule");
                var result = await table.ExecuteAsync(TableOperation.InsertOrMerge(appointmentEntity));

                var appointment = result.Result as AppointmentEntity;
                var expert      = await ExpertData.GetExpertAsync(appointment.Expert);

                await EmailUtil.SendEmailAsync(appointment, expert);

                return(new OkObjectResult(appointment));
            }
            catch (JsonSerializationException ex)
            {
                log.LogError(string.Format("CreateAppointment(): JsonSerializationException occurred {0}:{1}", ex.Message, ex.InnerException));
                return(new BadRequestObjectResult(ex.Message));
            }
            catch (StorageException ex)
            {
                log.LogError(string.Format("CreateAppointment(): StorageException occurred {0}:{1}", ex.Message, ex.InnerException));
                return(new BadRequestObjectResult(ex.Message));
            }
            catch (Exception ex)
            {
                log.LogError(string.Format("CreateAppointment(): Exception occurred {0}:{1}", ex.Message, ex.InnerException));
                return(new InternalServerErrorResult());
            }
        }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "monthlyavailability/{repo}/{handle}")] HttpRequest req,
            string repo,
            string handle,
            ILogger log)
        {
            DateTime     startDate, endDate;
            StringValues startBuffer, endBuffer;

            log.LogInformation("MonthlyAvailability(): Received request");

            if (req.Query.TryGetValue("startdate", out startBuffer) && req.Query.TryGetValue("enddate", out endBuffer))
            {
                if (!DateTime.TryParse(startBuffer, out startDate) || !DateTime.TryParse(endBuffer, out endDate))
                {
                    log.LogError("MonthlyAvailability(): Badly formed dates in query string");
                    return(new BadRequestResult());
                }
            }
            else
            {
                // Dates were not provided, use default of next 45 days
                startDate = DateTime.Today;
                endDate   = DateTime.Today.AddDays(45);
            }

            // Protect from too large of a range
            if ((endDate - startDate).TotalDays > 100)
            {
                endDate = startDate.AddDays(100);
            }

            var result = await AppointmentData.GetAppointmentsAsync(repo, handle, startDate, endDate);

            var expert = await ExpertData.GetExpertAsync(handle);

            var availabilityByDay = new List <AvailabilityEntity>((int)(endDate - startDate).TotalDays);

            // Compute number of 30 minute time slots for this expert
            var totalSlotsForExpert = (expert.EndTime.TimeOfDay - expert.StartTime.TimeOfDay).TotalHours / 30;
            var dayLoop             = startDate;

            while (dayLoop <= endDate)
            {
                bool hasAvailability = false;

                // Check if day is a "working" day
                if (expert.ExcludeWeekends == false ||
                    (dayLoop.DayOfWeek != DayOfWeek.Saturday && dayLoop.DayOfWeek != DayOfWeek.Sunday))
                {
                    // Look how many time slots were filled and compare against total slots
                    var numAppointments = result.Count(x => x.DateTime.Date == dayLoop.Date);

                    hasAvailability = numAppointments < totalSlotsForExpert;
                }

                availabilityByDay.Add(new AvailabilityEntity
                {
                    StartDate = dayLoop,
                    EndDate   = dayLoop,
                    Available = hasAvailability,
                });

                dayLoop = dayLoop.AddDays(1);
            }

            log.LogInformation("here");

            return(new OkObjectResult(availabilityByDay));
        }
Example #6
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "dailyavailability/{repo}/{handle}")] HttpRequest req,
            string repo,
            string handle,
            ILogger log)
        {
            DateTime     startDate, endDate;
            StringValues startBuffer, endBuffer;

            log.LogInformation("DailyAvailability(): Received request");

            if (req.Query.TryGetValue("startdate", out startBuffer) && req.Query.TryGetValue("enddate", out endBuffer))
            {
                if (!DateTime.TryParse(startBuffer, out startDate) || !DateTime.TryParse(endBuffer, out endDate))
                {
                    log.LogError("DailyAvailability(): Badly formed dates in query string");
                    return(new BadRequestResult());
                }
            }
            else
            {
                // Dates were not provided, use default of next 7 days
                startDate = DateTime.Today;
                endDate   = DateTime.Today.AddDays(7);
            }

            // Protect from too large of a range
            if ((endDate - startDate).TotalDays > 100)
            {
                endDate = startDate.AddDays(100);
            }

            var result = await AppointmentData.GetAppointmentsAsync(repo, handle, startDate, endDate);

            var expert = await ExpertData.GetExpertAsync(handle);

            if (expert == null)
            {
                return(new NotFoundResult());
            }

            var availableTimeslots = new List <AvailabilityEntity>();

            var dayLoop = startDate;

            while (dayLoop <= endDate)
            {
                if (expert.ExcludeWeekends == true &&
                    (dayLoop.DayOfWeek == DayOfWeek.Saturday || dayLoop.DayOfWeek == DayOfWeek.Sunday))
                {
                    dayLoop = dayLoop.AddDays(1);
                    continue;
                }

                // Build slots for this day and mark as available or filled
                var timeSlotLoop = expert.StartTime.TimeOfDay;
                while (timeSlotLoop <= expert.EndTime.TimeOfDay)
                {
                    var starttime   = new DateTime(dayLoop.Year, dayLoop.Month, dayLoop.Day, timeSlotLoop.Hours, timeSlotLoop.Minutes, timeSlotLoop.Seconds);
                    var appointment = result.Where(x => x.DateTime.Date == dayLoop.Date && x.DateTime.TimeOfDay == timeSlotLoop).FirstOrDefault();

                    var availability = new AvailabilityEntity
                    {
                        StartDate = starttime,
                        EndDate   = starttime.AddMinutes(30),
                    };

                    availability.Available = appointment == null;

                    availableTimeslots.Add(availability);

                    // increment by 30 minutes
                    timeSlotLoop = timeSlotLoop.Add(new TimeSpan(0, 30, 0));
                }

                dayLoop = dayLoop.AddDays(1);
            }

            return(new OkObjectResult(availableTimeslots));
        }