Beispiel #1
0
        /// <summary>
        /// Records that an alert has been sent to a given email address.
        /// </summary>
        /// <param name="jobsSet">The jobs set.</param>
        /// <param name="jobId">The job identifier.</param>
        /// <param name="emailAddress">The email address.</param>
        public async Task MarkAlertAsSent(JobsSet jobsSet, int jobId, string emailAddress)
        {
            var table = _tableClient.GetTableReference(_alertsSentTable);
            await table.CreateIfNotExistsAsync();

            var entity = new JobAlertSentTableEntity()
            {
                PartitionKey = ToAzureKeyString(emailAddress),
                RowKey       = jobId.ToString(),
                JobsSet      = jobsSet.ToString()
            };

            try
            {
                var result = table.Execute(TableOperation.InsertOrReplace(entity));
            }
            catch (StorageException ex)
            {
                if (ex.Message.Contains("(400) Bad Request"))
                {
                    LogHelper.Error <AzureTableStorageAlertsRepository>($"Mark job alert for job {jobId} as sent to {emailAddress} returned {ex.RequestInformation.ExtendedErrorInformation.ErrorMessage}", ex);
                    ex.ToExceptionless().Submit();
                }
                else
                {
                    throw;
                }
            }
        }
 public void MarkAlertAsSent(JobsSet jobsSet, int jobId, string emailAddress)
 {
     if (!_jobsSent.Contains(jobId))
     {
         _jobsSent.Add(jobId);
         UniqueJobCount++;
     }
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="JobsDataFromApi" /> class.
 /// </summary>
 /// <param name="apiBaseUrl">The API base URL.</param>
 /// <param name="jobsSet">The jobs set.</param>
 /// <param name="jobAdvertBaseUrl">The job advert base URL.</param>
 /// <param name="httpClientProvider">A method of getting an <see cref="HttpClient"/> to use for the web API requests</param>
 /// <param name="jobsCache">A method of caching the API results.</param>
 /// <exception cref="ArgumentNullException">apiBaseUrl</exception>
 public JobsDataFromApi(Uri apiBaseUrl, JobsSet jobsSet, Uri jobAdvertBaseUrl, IHttpClientProvider httpClientProvider, IJobCacheStrategy jobsCache)
 {
     _apiBaseUrl         = apiBaseUrl ?? throw new ArgumentNullException(nameof(apiBaseUrl));
     _jobsSet            = jobsSet;
     _jobAdvertBaseUrl   = jobAdvertBaseUrl ?? throw new ArgumentNullException(nameof(jobAdvertBaseUrl));
     _httpClientProvider = httpClientProvider;
     _jobsCache          = jobsCache;
 }
Beispiel #4
0
 public Task MarkAlertAsSent(JobsSet jobsSet, int jobId, string emailAddress)
 {
     if (!_jobsSent.Contains(jobId))
     {
         _jobsSent.Add(jobId);
         UniqueJobCount++;
     }
     return(Task.CompletedTask);
 }
        /// <summary>
        /// Reads full details of an individual job from the specified jobs set.
        /// </summary>
        /// <param name="jobsSet">The jobs set.</param>
        /// <param name="jobId">The job identifier.</param>
        /// <param name="baseUrl">The base URL.</param>
        /// <returns></returns>
        protected async Task <Job> Job(JobsSet jobsSet, string jobId, Uri baseUrl)
        {
            var jobsProvider = new JobsDataFromExamine(ExamineManager.Instance.SearchProviderCollection[jobsSet + "Searcher"],
                                                       new QueryBuilder(new LuceneTokenisedQueryBuilder(), new KeywordsTokeniser(), new LuceneStopWordsRemover(), new WildcardSuffixFilter()),
                                                       null,
                                                       new RelativeJobUrlGenerator(baseUrl));

            return(await jobsProvider.ReadJob(jobId));
        }
Beispiel #6
0
        /// <summary>
        /// Gets the job alert settings for a <see cref="JobsSet" />
        /// </summary>
        /// <returns></returns>
        public JobAlertSettings GetJobAlertsSettings(JobsSet jobsSet)
        {
            JobAlertSettings settings = null;

            var jobAlertsSettingsPages = _umbraco.TypedContentAtXPath("//JobAlerts");

            foreach (var jobAlertSettingsPage in jobAlertsSettingsPages)
            {
                // Get the jobs set selected in the Umbraco page
                var selectedJobsSet = umbraco.library.GetPreValueAsString(jobAlertSettingsPage.GetPropertyValue <int>("PublicOrRedeployment_Content"));
                selectedJobsSet = Regex.Replace(selectedJobsSet.ToUpperInvariant(), "[^A-Z]", String.Empty);
                var jobsSetForPage = (JobsSet)Enum.Parse(typeof(JobsSet), selectedJobsSet, true);
                if (jobsSetForPage != jobsSet)
                {
                    continue;
                }

                // Create settings from the page
                settings = new JobAlertSettings();

                settings.NewAlertEmailSubject  = jobAlertSettingsPage.GetPropertyValue <string>("NewAlertEmailSubject_Alert_settings");
                settings.NewAlertEmailBodyHtml = jobAlertSettingsPage.GetPropertyValue <string>("NewAlertEmailBody_Alert_settings");
                settings.AlertEmailSubject     = jobAlertSettingsPage.GetPropertyValue <string>("AlertEmailSubject_Alert_settings");
                settings.AlertEmailBodyHtml    = jobAlertSettingsPage.GetPropertyValue <string>("AlertEmailBody_Alert_settings");

                var baseUrl = jobAlertSettingsPage.GetPropertyValue <string>("BaseUrl_Alert_settings");
                if (!String.IsNullOrEmpty(baseUrl))
                {
                    settings.ChangeAlertBaseUrl = new Uri(new Uri(baseUrl), jobAlertSettingsPage.Url());
                }
                else
                {
                    settings.ChangeAlertBaseUrl = new Uri(jobAlertSettingsPage.UrlAbsolute());
                }

                var jobAdvertPage = jobAlertSettingsPage.GetPropertyValue <IPublishedContent>("JobAdvertPage_Alert_settings");
                if (jobAdvertPage != null)
                {
                    if (!String.IsNullOrEmpty(baseUrl))
                    {
                        settings.JobAdvertBaseUrl = new Uri(new Uri(baseUrl), jobAdvertPage.Url());
                    }
                    else
                    {
                        settings.JobAdvertBaseUrl = new Uri(jobAdvertPage.UrlAbsolute());
                    }
                }
            }

            return(settings);
        }
Beispiel #7
0
        /// <summary>
        /// Gets the ids of the jobs already sent to a given email address.
        /// </summary>
        /// <param name="jobsSet">The jobs set.</param>
        /// <param name="emailAddress">The email address.</param>
        /// <returns></returns>
        public async Task <IList <int> > GetJobsSentForEmail(JobsSet jobsSet, string emailAddress)
        {
            // Create the table query.
            var table = _tableClient.GetTableReference(_alertsSentTable);

            // Initialize a default TableQuery to retrieve all the entities in the table.
            var tableQuery = new TableQuery <TableEntity>().Where(TableQuery.CombineFilters(
                                                                      TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, emailAddress),
                                                                      TableOperators.And,
                                                                      TableQuery.GenerateFilterCondition("JobsSet", QueryComparisons.Equal, jobsSet.ToString()))
                                                                  );

            return(await ReadAllResults <int>(table, tableQuery, entity => Int32.Parse(entity.RowKey)));
        }
        /// <summary>
        /// Gets the job alert settings for a <see cref="JobsSet" />
        /// </summary>
        /// <returns></returns>
        public JobAlertSettings JobAlertSettings(Uri apiBaseUrl, JobsSet jobsSet)
        {
            var request = WebRequest.Create(new Uri($"{apiBaseUrl.ToString().TrimEnd('/')}/umbraco/api/{jobsSet}/jobalertsettings/"));

            _log.Info($"Requesting job alert settings from {request.RequestUri}");
            using (var response = request.GetResponse())
            {
                using (var responseReader = new StreamReader(response.GetResponseStream()))
                {
                    var responseJson = responseReader.ReadToEnd();
                    return(JsonConvert.DeserializeObject <JobAlertSettings>(responseJson, new[] { new IHtmlStringConverter() }));
                }
            }
        }
        /// <summary>
        /// Reads jobs matching the specified search query
        /// </summary>
        /// <param name="jobsSet">The jobs set.</param>
        /// <param name="query">The query.</param>
        /// <param name="baseUrl">The base URL.</param>
        /// <returns></returns>
        protected async Task <JobSearchResult> Jobs(JobsSet jobsSet, JobSearchQuery query, Uri baseUrl)
        {
            var jobsProvider = new JobsDataFromExamine(ExamineManager.Instance.SearchProviderCollection[jobsSet + "Searcher"],
                                                       new QueryBuilder(new LuceneTokenisedQueryBuilder(), new KeywordsTokeniser(), new LuceneStopWordsRemover(), new WildcardSuffixFilter()),
                                                       new SalaryRangeLuceneQueryBuilder(),
                                                       new RelativeJobUrlGenerator(baseUrl));

            var jobs = await jobsProvider.ReadJobs(query);

            foreach (var job in jobs.Jobs)
            {
                // Remove these unnecessary and large fields to significantly reduce the amount that's serialised and sent to the client
                job.AdvertHtml = null;
                job.AdditionalInformationHtml = null;
                job.EqualOpportunitiesHtml    = null;
            }
            return(jobs);
        }
Beispiel #10
0
        private async Task DeleteRecordOfAlertsSent(JobsSet jobsSet, string emailAddress)
        {
            // Only remove data if there are no more alerts set up for this email, otherwise we may still send jobs they've already seen
            var alertsForThisEmail = await GetAlerts(new JobAlertsQuery { JobsSet = jobsSet, EmailAddress = emailAddress });

            if (alertsForThisEmail.Any())
            {
                return;
            }

            // Delete the record of alerts sent
            var table = _tableClient.GetTableReference(_alertsSentTable);

            table.CreateIfNotExistsAsync().Wait();

            var tableQuery = new TableQuery <TableEntity>().Where(TableQuery.CombineFilters(
                                                                      TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, emailAddress),
                                                                      TableOperators.And,
                                                                      TableQuery.GenerateFilterCondition("JobsSet", QueryComparisons.Equal, jobsSet.ToString())));

            var alertsSentEntities = table.ExecuteQuery(tableQuery);

            foreach (var entity in alertsSentEntities)
            {
                try
                {
                    table.Execute(TableOperation.Delete(entity));
                }
                catch (StorageException ex)
                {
                    if (ex.Message.Contains("(400) Bad Request"))
                    {
                        LogHelper.Error <AzureTableStorageAlertsRepository>($"Delete job alert sent record for job {entity.RowKey} and alert {emailAddress} returned {ex.RequestInformation.ExtendedErrorInformation.ErrorMessage}", ex);
                        ex.ToExceptionless().Submit();
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }
        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 Task <IList <int> > GetJobsSentForEmail(JobsSet jobsSet, string emailAddress)
 {
     throw new NotImplementedException();
 }
Beispiel #13
0
 /// <summary>
 /// Jobses the lookup values from API.
 /// </summary>
 /// <param name="apiBaseUrl">The API base URL.</param>
 /// <param name="jobsSet">The jobs set.</param>
 /// <param name="jobsCache">A method of caching the API results.</param>
 /// <exception cref="ArgumentNullException">apiBaseUrl</exception>
 public JobsLookupValuesFromApi(Uri apiBaseUrl, JobsSet jobsSet, IJobCacheStrategy jobsCache)
 {
     this._apiBaseUrl = apiBaseUrl ?? throw new ArgumentNullException(nameof(apiBaseUrl));
     this._jobsSet    = jobsSet;
     this._jobsCache  = jobsCache;
 }
        /// <summary>
        /// Reads the job types.
        /// </summary>
        /// <param name="jobsSet">The jobs set.</param>
        /// <returns></returns>
        protected async Task <IList <JobsLookupValue> > ReadJobTypes(JobsSet jobsSet)
        {
            var dataSource = new JobsLookupValuesFromExamine(ExamineManager.Instance.SearchProviderCollection[jobsSet + "LookupValuesSearcher"]);

            return(await dataSource.ReadJobTypes());
        }
 /// <summary>
 /// Gets the job alert settings for a <see cref="JobsSet" />
 /// </summary>
 /// <param name="jobsSet">The jobs set.</param>
 protected JobAlertSettings JobAlertSettings(JobsSet jobsSet)
 {
     return(new JobAlertsSettingsFromUmbraco(Umbraco).GetJobAlertsSettings(jobsSet));
 }