public ActionResult CreateAlert(JobAlert alert)
        {
            var query = HttpUtility.ParseQueryString(Request.Url.Query);

            if (ModelState.IsValid)
            {
                var converter  = new JobSearchQueryConverter(ConfigurationManager.AppSettings["TranslateObsoleteJobTypes"]?.ToUpperInvariant() == "TRUE");
                var encoder    = new JobAlertIdEncoder(converter);
                var alertsRepo = new AzureTableStorageAlertsRepository(converter, ConfigurationManager.ConnectionStrings["Escc.EastSussexGovUK.Umbraco.AzureStorage"].ConnectionString);
                alert.Query   = converter.ToQuery(query);
                alert.AlertId = encoder.GenerateId(alert);
                alertsRepo.SaveAlert(alert);

                var jobAlertsSettings = new JobAlertsSettingsFromUmbraco(Umbraco).GetJobAlertsSettings(alert.JobsSet);
                if (jobAlertsSettings != null && !String.IsNullOrEmpty(jobAlertsSettings.NewAlertEmailSubject))
                {
                    var emailService = ServiceContainer.LoadService <IEmailSender>(new ConfigurationServiceRegistry(), new HttpContextCacheStrategy());
                    var sender       = new JobAlertsByEmailSender(jobAlertsSettings, new HtmlJobAlertFormatter(jobAlertsSettings, encoder), emailService);

                    sender.SendNewAlertConfirmation(alert);
                }

                query.Add("subscribed", "1");
            }
            return(new RedirectToUmbracoPageResult(CurrentPage, query));
        }
        /// <summary>
        /// Gets the jobs matching the supplied query
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task <JobSearchResult> ReadJobs(JobSearchQuery query)
        {
            if (_jobsCache != null)
            {
                var cached = _jobsCache.ReadJobs(query);
                if (cached != null)
                {
                    return(cached);
                }
            }

            try
            {
                if (_httpClient == null)
                {
                    _httpClient = _httpClientProvider.GetHttpClient();
                }

                var queryString  = new JobSearchQueryConverter(ConfigurationManager.AppSettings["TranslateObsoleteJobTypes"]?.ToUpperInvariant() == "TRUE").ToCollection(query).ToString();
                var responseJson = await _httpClient.GetStringAsync(new Uri($"{_apiBaseUrl.ToString().TrimEnd('/')}/umbraco/api/{_jobsSet}/jobs/?baseUrl={HttpUtility.UrlEncode(_jobAdvertBaseUrl.ToString())}&{queryString}"));

                var result = JsonConvert.DeserializeObject <JobSearchResult>(responseJson, new[] { new IHtmlStringConverter() });
                if (_jobsCache != null)
                {
                    _jobsCache.CacheJobs(query, result);
                }
                return(result);
            }
            catch (HttpRequestException ex)
            {
                ex.ToExceptionless().Submit();
                return(new JobSearchResult());
            }
        }
Esempio n. 3
0
        public void ContractTypeIsPopulatedFromCollection()
        {
            var collection = new NameValueCollection();

            collection["contracttypes"] = "Contract type";
            var converter = new JobSearchQueryConverter(false);

            var query = converter.ToQuery(collection);

            Assert.AreEqual("Contract type", query.ContractTypes[0]);
        }
Esempio n. 4
0
        public void MaximumSalaryRangeIsPopulatedFromQuery()
        {
            var query = new JobSearchQuery();

            query.SalaryRanges.Add("£50000 and over");
            var converter = new JobSearchQueryConverter(false);

            var collection = converter.ToCollection(query);

            Assert.AreEqual("£50000 and over", collection["salaryranges"]);
        }
Esempio n. 5
0
        public void PayGradeIsPopulatedFromCollection()
        {
            var collection = new NameValueCollection();

            collection["paygrades"] = "Single Status";
            var converter = new JobSearchQueryConverter(false);

            var query = converter.ToQuery(collection);

            Assert.AreEqual("Single Status", query.PayGrades[0]);
        }
Esempio n. 6
0
        public void OrganisationIsPopulatedFromQuery()
        {
            var query = new JobSearchQuery();

            query.Organisations.Add("Example organisation");
            var converter = new JobSearchQueryConverter(false);

            var collection = converter.ToCollection(query);

            Assert.AreEqual("Example organisation", collection["org"]);
        }
Esempio n. 7
0
        public void SalaryRangeIsPopulatedFromCollection()
        {
            var collection = new NameValueCollection();

            collection["salaryranges"] = "£10000 to £20000";
            var converter = new JobSearchQueryConverter(false);

            var query = converter.ToQuery(collection);

            Assert.AreEqual("£10,000 to £20,000", query.SalaryRanges[0]);
        }
Esempio n. 8
0
        public void KeywordsArePopulatedFromCollection()
        {
            var collection = new NameValueCollection();

            collection["keywords"] = "this is a test";
            var converter = new JobSearchQueryConverter(false);

            var query = converter.ToQuery(collection);

            Assert.AreEqual("this is a test", query.Keywords);
        }
Esempio n. 9
0
        public void OrganisationIsPopulatedFromCollection()
        {
            var collection = new NameValueCollection();

            collection["org"] = "Example organisation";
            var converter = new JobSearchQueryConverter(false);

            var query = converter.ToQuery(collection);

            Assert.AreEqual("Example organisation", query.Organisations[0]);
        }
Esempio n. 10
0
        public void DepartmentIsPopulatedFromQuery()
        {
            var query = new JobSearchQuery();

            query.Departments.Add("Example department");
            var converter = new JobSearchQueryConverter(false);

            var collection = converter.ToCollection(query);

            Assert.AreEqual("Example department", collection["department"]);
        }
Esempio n. 11
0
        public void DepartmentIsPopulatedFromCollection()
        {
            var collection = new NameValueCollection();

            collection["department"] = "Example department";
            var converter = new JobSearchQueryConverter(false);

            var query = converter.ToQuery(collection);

            Assert.AreEqual("Example department", query.Departments[0]);
        }
        public async Task <ActionResult> CancelAlert()
        {
            var converter   = new JobSearchQueryConverter(ConfigurationManager.AppSettings["TranslateObsoleteJobTypes"]?.ToUpperInvariant() == "TRUE");
            var encoder     = new JobAlertIdEncoder(converter);
            var absoluteUrl = new Uri(Request.Url, Request.RawUrl);
            var alertId     = encoder.ParseIdFromUrl(absoluteUrl);
            var alertsRepo  = new AzureTableStorageAlertsRepository(converter, ConfigurationManager.ConnectionStrings["Escc.EastSussexGovUK.Umbraco.AzureStorage"].ConnectionString);
            var success     = await alertsRepo.CancelAlert(alertId);

            return(new RedirectResult(absoluteUrl.AbsolutePath + "?cancelled=" + (success ? "1" : "0")));
        }
Esempio n. 13
0
        public void WorkingPatternIsPopulatedFromCollection()
        {
            var collection = new NameValueCollection();

            collection["workpatterns"] = "Working pattern";
            var converter = new JobSearchQueryConverter(false);

            var query = converter.ToQuery(collection);

            Assert.AreEqual("Working pattern", query.WorkPatterns[0]);
        }
Esempio n. 14
0
        public void PayGradeIsPopulatedFromQuery()
        {
            var query = new JobSearchQuery();

            query.PayGrades.Add("Single Status");
            var converter = new JobSearchQueryConverter(false);

            var collection = converter.ToCollection(query);

            Assert.AreEqual("Single Status", collection["paygrades"]);
        }
Esempio n. 15
0
        public void ObsoleteJobTypeIsTranslated()
        {
            var collection = new NameValueCollection();

            collection["jobtypes"] = "Personnel and HR";
            var converter = new JobSearchQueryConverter(true);

            var query = converter.ToQuery(collection);

            Assert.AreEqual("Human Resources", query.JobTypes[0]);
        }
Esempio n. 16
0
        public void JobTypeIsPopulatedFromQuery()
        {
            var query = new JobSearchQuery();

            query.JobTypes.Add("Example job type");
            var converter = new JobSearchQueryConverter(false);

            var collection = converter.ToCollection(query);

            Assert.AreEqual("Example job type", collection["jobtypes"]);
        }
Esempio n. 17
0
        public void ContractTypeIsPopulatedFromQuery()
        {
            var query = new JobSearchQuery();

            query.ContractTypes.Add("Contract type");
            var converter = new JobSearchQueryConverter(false);

            var collection = converter.ToCollection(query);

            Assert.AreEqual("Contract type", collection["contracttypes"]);
        }
Esempio n. 18
0
        public void JobTypeIsPopulatedFromCollection()
        {
            var collection = new NameValueCollection();

            collection["jobtypes"] = "Example job type";
            var converter = new JobSearchQueryConverter(false);

            var query = converter.ToQuery(collection);

            Assert.AreEqual("Example job type", query.JobTypes[0]);
        }
Esempio n. 19
0
        public void ReferenceIsPopulatedFromCollection()
        {
            var collection = new NameValueCollection();

            collection["ref"] = "ABC1234";
            var converter = new JobSearchQueryConverter(false);

            var query = converter.ToQuery(collection);

            Assert.AreEqual("ABC1234", query.JobReference);
        }
Esempio n. 20
0
        public void WorkingPatternIsPopulatedFromQuery()
        {
            var query = new JobSearchQuery();

            query.WorkPatterns.Add("Working pattern");
            var converter = new JobSearchQueryConverter(false);

            var collection = converter.ToCollection(query);

            Assert.AreEqual("Working pattern", collection["workpatterns"]);
        }
Esempio n. 21
0
        public void ReferenceIsPopulatedFromQuery()
        {
            var query = new JobSearchQuery()
            {
                JobReference = "ABC1234"
            };
            var converter = new JobSearchQueryConverter(false);

            var collection = converter.ToCollection(query);

            Assert.AreEqual("ABC1234", collection["ref"]);
        }
Esempio n. 22
0
        public void KeywordsArePopulatedFromQuery()
        {
            var query = new JobSearchQuery()
            {
                Keywords = "this is a test"
            };
            var converter = new JobSearchQueryConverter(false);

            var collection = converter.ToCollection(query);

            Assert.AreEqual("this is a test", collection["keywords"]);
        }
Esempio n. 23
0
        /// <summary>
        /// The default action to render the front-end view
        /// </summary>
        /// <param name="model"/>
        /// <returns/>
        public async new Task <ActionResult> Index(RenderModel model)
        {
            var modelBuilder           = new JobsSearchViewModelFromUmbraco(model.Content, new JobAlertsViewModel());
            var viewModel              = (JobAlertsViewModel)modelBuilder.BuildModel();
            var lookupValuesDataSource = new JobsLookupValuesFromApi(new Uri(ConfigurationManager.AppSettings["JobsApiBaseUrl"]), viewModel.JobsSet, new MemoryJobCacheStrategy(MemoryCache.Default, Request.QueryString["ForceCacheRefresh"] == "1"));
            await modelBuilder.AddLookupValuesToModel(lookupValuesDataSource, viewModel);

            var converter = new JobSearchQueryConverter(ConfigurationManager.AppSettings["TranslateObsoleteJobTypes"]?.ToUpperInvariant() == "TRUE");
            var alertId   = new JobAlertIdEncoder(converter).ParseIdFromUrl(Request.Url);

            if (!string.IsNullOrEmpty(alertId))
            {
                if (ConfigurationManager.ConnectionStrings["Escc.EastSussexGovUK.Umbraco.AzureStorage"] == null || String.IsNullOrEmpty(ConfigurationManager.ConnectionStrings["Escc.EastSussexGovUK.Umbraco.AzureStorage"].ConnectionString))
                {
                    var error = new ConfigurationErrorsException("The Escc.EastSussexGovUK.Umbraco.AzureStorage connection string is missing from web.config");
                    LogHelper.Error <JobAlertsController>(error.Message, error);
                    error.ToExceptionless().Submit();
                }
                else
                {
                    var alertsRepo = new AzureTableStorageAlertsRepository(converter, ConfigurationManager.ConnectionStrings["Escc.EastSussexGovUK.Umbraco.AzureStorage"].ConnectionString);
                    viewModel.Alert = alertsRepo.GetAlertById(alertId);
                    viewModel.Query = viewModel.Alert?.Query;

                    if (viewModel.Alert == null && Request.QueryString["cancelled"] != "1" && string.IsNullOrEmpty(Request.QueryString["altTemplate"]))
                    {
                        // Returning HttpNotFoundResult() ends up with a generic browser 404,
                        // so to get our custom one we need to look it up and transfer control to it.
                        var notFoundUrl = new HttpStatusFromConfiguration().GetCustomUrlForStatusCode(404);
                        if (notFoundUrl != null && Server != null)
                        {
                            Server.TransferRequest(notFoundUrl + "?404;" + HttpUtility.UrlEncode(Request.Url.ToString()));
                        }
                    }
                }
            }

            var baseModelBuilder = new BaseViewModelBuilder(new EastSussexGovUKTemplateRequest(Request, webChatSettingsService: new UmbracoWebChatSettingsService(model.Content, new UrlListReader())));
            await baseModelBuilder.PopulateBaseViewModel(viewModel, model.Content, new ContentExperimentSettingsService(),
                                                         new ExpiryDateFromExamine(model.Content.Id, ExamineManager.Instance.SearchProviderCollection["ExternalSearcher"], new ExpiryDateMemoryCache(TimeSpan.FromHours(1))).ExpiryDate,
                                                         UmbracoContext.Current.InPreviewMode);

            baseModelBuilder.PopulateBaseViewModelWithInheritedContent(viewModel,
                                                                       new UmbracoLatestService(model.Content),
                                                                       new UmbracoSocialMediaService(model.Content),
                                                                       null, null);

            return(CurrentTemplate(viewModel));
        }
        public async Task <ActionResult> ReplaceAlert(JobSearchQuery searchQuery)
        {
            if (ModelState.IsValid)
            {
                var converter = new JobSearchQueryConverter(ConfigurationManager.AppSettings["TranslateObsoleteJobTypes"]?.ToUpperInvariant() == "TRUE");
                var encoder   = new JobAlertIdEncoder(converter);
                var alertId   = encoder.ParseIdFromUrl(new Uri(Request.Url, Request.RawUrl));
                var repo      = new AzureTableStorageAlertsRepository(converter, ConfigurationManager.ConnectionStrings["Escc.EastSussexGovUK.Umbraco.AzureStorage"].ConnectionString);
                var oldAlert  = repo.GetAlertById(alertId);

                var newAlert = new JobAlert()
                {
                    Query     = searchQuery,
                    Email     = oldAlert.Email,
                    Frequency = searchQuery.Frequency,
                    JobsSet   = searchQuery.JobsSet
                };
                newAlert.AlertId = encoder.GenerateId(newAlert);

                if (oldAlert.AlertId == newAlert.AlertId)
                {
                    // The alert id didn't change but the frequency may have, so update the existing alert
                    await repo.SaveAlert(newAlert);
                }
                else
                {
                    // The alert id, and therefore the criteria, changed, so save the new alert and delete the old one
                    await repo.SaveAlert(newAlert);

                    await repo.CancelAlert(oldAlert.AlertId);
                }

                var urlWithoutQueryString = new Uri(Request.Url, new Uri(Request.Url, Request.RawUrl).AbsolutePath);
                var urlWithoutAlertId     = encoder.RemoveIdFromUrl(urlWithoutQueryString);
                var urlWithAlertId        = encoder.AddIdToUrl(urlWithoutAlertId, newAlert.AlertId);

                return(new RedirectResult(urlWithAlertId + "?updated=1"));
            }
            else
            {
                return(new RedirectResult(Request.RawUrl));
            }
        }
        private async Task SendAlertsForJobSet(IJobsDataProvider jobsProvider, JobsSet jobsSet, int?frequency, JobAlertSettings alertSettings, bool forceResend)
        {
            // No point sending alerts without links to the jobs
            if (alertSettings.JobAdvertBaseUrl == null)
            {
                _log.Error("JobAdvertBaseUrl not found - aborting");
                return;
            }

            // We need somewhere to get the alerts from...
            var converter = new JobSearchQueryConverter(ConfigurationManager.AppSettings["TranslateObsoleteJobTypes"]?.ToUpperInvariant() == "TRUE");
            var encoder   = new JobAlertIdEncoder(converter);
            IJobAlertsRepository alertsRepo = new AzureTableStorageAlertsRepository(converter, ConfigurationManager.ConnectionStrings["JobAlerts.AzureStorage"].ConnectionString);

            // We need a way to send the alerts...
            var configuration = new ConfigurationServiceRegistry();
            var emailService  = ServiceContainer.LoadService <IEmailSender>(configuration);
            var sender        = new JobAlertsByEmailSender(alertSettings, new HtmlJobAlertFormatter(alertSettings, encoder), emailService);

            // Get them, sort them and send them
            _log.Info($"Requesting jobs matching {jobsSet} with frequency {frequency} from Azure Storage");
            var alerts = await alertsRepo.GetAlerts(new JobAlertsQuery()
            {
                Frequency = frequency, JobsSet = jobsSet
            });

            var alertsGroupedByEmail = GroupAlertsByEmail(alerts);

            _log.Info($"{alerts.Count()} alerts found for {alertsGroupedByEmail.Count()} email addresses");
            foreach (var alertsForAnEmail in alertsGroupedByEmail)
            {
                foreach (var alert in alertsForAnEmail)
                {
                    var jobsSentForThisEmail = forceResend ? new List <int>() : await alertsRepo.GetJobsSentForEmail(alert.JobsSet, alert.Email);
                    await LookupJobsForAlert(jobsProvider, alert, jobsSentForThisEmail);
                }
            }

            _log.Info("Sending alerts");
            await sender.SendGroupedAlerts(alertsGroupedByEmail, alertsRepo);
        }
        public bool TryFindContent(PublishedContentRequest contentRequest)
        {
            try
            {
                if (contentRequest == null)
                {
                    throw new ArgumentNullException(nameof(contentRequest));
                }

                var converter = new JobSearchQueryConverter(ConfigurationManager.AppSettings["TranslateObsoleteJobTypes"]?.ToUpperInvariant() == "TRUE");
                var encoder   = new JobAlertIdEncoder(converter);
                var alertId   = encoder.ParseIdFromUrl(contentRequest.Uri);
                if (String.IsNullOrEmpty(alertId))
                {
                    return(false); // not found
                }

                // if we remove the suffix, does that match a Job Alerts node?
                var contentCache = UmbracoContext.Current.ContentCache;
                var content      = contentCache.GetByRoute(encoder.RemoveIdFromUrl(contentRequest.Uri).AbsolutePath);
                if (content == null)
                {
                    return(false);                 // not found
                }
                if (content.ContentType.Alias != "JobAlerts")
                {
                    return(false);                                          // not found
                }
                // render that node
                contentRequest.PublishedContent = content;
                return(true);
            }
            catch (Exception e)
            {
                e.ToExceptionless().Submit();
                return(false);
            }
        }