예제 #1
0
        public Dictionary<string, List<AlumniPost>> GetAlumni(FilterBag filters)
        {
            Dictionary<string, List<AlumniPost>> alumni = new Dictionary<string, List<AlumniPost>>();

            if (filters.IsEmpty())
            {
                return alumni;
            }

            // Use a dictionary of module to bool so each module can mark when it's complete,
            // this is used incase of a timeout so it can be determined which module did not complete.
            Dictionary<IAlumniModule, bool> moduleCompleted = new Dictionary<IAlumniModule, bool>();
            foreach(IAlumniModule module in modules)
            {
                moduleCompleted.Add(module, false);
            }

            object lockObject = new Object();

            var timeout = 5000; // 5 seconds
            var cts = new CancellationTokenSource();
            var t = new Timer(_ => cts.Cancel(), null, timeout, -1);

            try
            {
                Parallel.ForEach(modules,
                    new ParallelOptions { CancellationToken = cts.Token },
                    (module) =>
                    {
                        try
                        {
                            Dictionary<string, List<AlumniPost>> partialJobs = module.GetAlumni(filters);
                            lock (lockObject)
                            {
                                moduleCompleted[module] = true;
                                alumni = alumni.Concat(partialJobs).ToDictionary(e => e.Key, e => e.Value);
                            }
                        }
                        catch (Exception e)
                        {
                            Debug.WriteLine(e.ToString());
                            // The module failed. Not a system failure but the user should be notified
                            // we need to create a mechanism to actually notify them and call it here
                        }

                    }
                );
            }
            catch(OperationCanceledException)
            {
                // This is where we should notify the user that a source timed out
                // The source can be determined by looking at the dictionary moduleCompleted
            }
            return PostProcessAlumni(alumni);
        }
예제 #2
0
파일: JobShepard.cs 프로젝트: cray1/jobsalt
        public List<JobPost> GetJobs(FilterBag filters, int page, int resultsPerModule)
        {
            if (filters.IsEmpty())
            {
                return new List<JobPost>();
            }

            List<Task> tasks = new List<Task>();
            List<List<JobPost>> jobs = new List<List<JobPost>>();
            object lockObject = new object();

            foreach(IJobModule module in modules)
            {
                Task task = new Task(() =>
            {
                        try
                        {
                            List<JobPost> moduleJobs = module.GetJobs(filters, page, resultsPerModule);
                            lock (lockObject)
                            {
                                jobs.Add(moduleJobs);
                            }
                        }
                        catch (Exception)
                        {
                            // The module failed. Not a system failure but the user should be notified
                            // we need to create a mechanism to actually notify them and call it here
                        }

                    });
                tasks.Add(task);
                task.Start();
                    }
            Task.WaitAll(tasks.ToArray(), MaxWaitTime * 1000);

            // Create a copy of jobs incase a module finishes late and tries to modifiy the
            // collection while we're still using it.
            List<List<JobPost>> duplicatedJobs = new List<List<JobPost>>(jobs);

            if (ConfigLoader.JobConfig.RemoveDuplicatePosts)
                    {
                RemoveDuplicateJobs(duplicatedJobs, page);
            }

            return PostProcessJobs(duplicatedJobs); ;
        }
예제 #3
0
        public List<JobPost> GetJobs( FilterBag filters , int page , int resultsPerPage )
        {
            List<JobPost> jobsToReturn = new List<JobPost>( );

            if (filters.IsEmpty())
            {
                return jobsToReturn;
            }

            string request = builder.BuildQuery( filters , page , resultsPerPage );

            XDocument doc = XDocument.Load( request );
            IEnumerable<XElement> results = doc.Descendants( "ResponseJobSearch" ).Single( ).Descendants( "Results" ).Single( ).Descendants( "JobSearchResult" );

            foreach ( var jobPost in results )
                {
                JobPost post = new JobPost( );

                post.URL = jobPost.Element( "JobDetailsURL" ).Value;
                post.SourceModule =source;
                post.DatePosted = DateTime.Parse( jobPost.Element( "PostedDate" ).Value );
                post.JobTitle = jobPost.Element( "JobTitle" ).Value;

                //this field is returned as "MN - Plymouth", so split by values
                string[] location = jobPost.Element( "Location" ).Value.Split( new char[] { '-' } );
                post.Location = new Location
                {
                    State= location[0].Trim( ) ,
                    City= location[1].Trim( ) ,
                    ZipCode=null
                };
                //if the company name is empty, fill with city and state (there are some posts with an empty company name)
                post.Company = jobPost.Element( "Company" ).Value==""?location[1]+" , "+location[0]:jobPost.Element( "Company" ).Value;
                post.Description =  jobPost.Element( "DescriptionTeaser" ).Value;
                post.FieldOfStudy = null;
                post.Salary =  jobPost.Element( "Pay" ).Value;
                jobsToReturn.Add( post );

                }
            return jobsToReturn;
        }
예제 #4
0
        public List<JobPost> GetJobs(FilterBag filterbag, int page, int resultsPerPage)
        {
            // Short circuit if there are no filters specified
            if (  filterbag.IsEmpty()  ) {  return new List<JobPost>();   }

            // Will try and build an Indeed API request from the given set of filters. Catches and logs any problems
            string request = "";
            try
            {
                // Build the request based on filters
                request = builder.buildQuery(filterbag, page, resultsPerPage);

                // If the request comes back empty, something bad happened
                if (String.IsNullOrEmpty(request)) { throw new ArgumentException(); }

            }

            // The built request is, for some reason, empty or null. Return empty results list
            catch (ArgumentException argex)
            {
                Logging.JobSaltLogger.Instance.log("(Indeed) Error in IndeedQueryBuilder caused API request string to be empty or null.");
                Logging.JobSaltLogger.Instance.log(filterbag.ToString() + "\n Page=" + page + "\n resultsPerPage=" + resultsPerPage);
                return new List<JobPost>();
            }

            // An unknown exception was thrown when trying to build the request. The request string
            // is empty now, so there's no point trying to continue (since it will return an empty list anyway)
            catch (Exception e)
            {
                Logging.JobSaltLogger.Instance.log("(Indeed) Exception caught while building Indeed Query: " + e.Message);
                Logging.JobSaltLogger.Instance.log(filterbag.ToString() + "\n Page=" + page + "\n resultsPerPage=" + resultsPerPage);
                return new List<JobPost>();
            }

            IndeedResult iResult;   // Raw Indeed results
            using (var client = new WebClient())
            {
                string json = client.DownloadString(request);   // Issues a Get to the Indeed API with the request string

                try
                {

                    var serializer = new JavaScriptSerializer();
                    iResult = serializer.Deserialize<IndeedResult>(json);   // Parses JSON result into C# Indeed data object

                    // The raw Indeed results are null... something very bad happened!
                    if (null == iResult) { throw new ArgumentException();}

                    // This is used to make sure that if a higher page is requested than Indeed has,
                    // then the last several posts don't keep getting returned (fixed bug)
                    int startpost = resultsPerPage * page;

                    return IndeedResultToJobPosts(iResult, startpost); // Parses C# Indeed data object into a list of JobPosts

                }

                // iResult is null, which means something went very wrong. Return an empty job list
                catch (ArgumentException argex)
                {
                    Logging.JobSaltLogger.Instance.log("(Indeed) An error occured when parsing Indeed JSON into iResult, resulting in iResult being null: " + argex.Message);
                    Logging.JobSaltLogger.Instance.log("(Indeed) JSON: \n" + json);
                    return new List<JobPost>();
                }

                // An unknown exception occured
                catch (Exception e)
                {
                    Logging.JobSaltLogger.Instance.log("(Indeed) An exception occured when parsing Indeed JSON into iResult: " + e.Message);
                    Logging.JobSaltLogger.Instance.log("(Indeed) JSON: \n" + json);
                    return new List<JobPost>();
                }
            }
        }