class ScrapeTogglJob < ApplicationJob queue_as :default def perform(course_ids) courses = Course.where(id: course_ids) courses.each do |course| self.scrape_course(course) end end # @param [Course] course def scrape_course(course) toggl_project_id = course.toggl_project lectures = course.lectures.order(:start_time).includes(:tracked_time_entries) return if lectures.empty? entries_data = Toggl::entries_for_project( toggl_project_id, # TODO: Work out better limits start_time: course.semester_start_date - 2.months, end_time: course.semester_start_date + 15.weeks + 2.months, ) puts("Entries data for #{course.title}: #{entries_data}") return if entries_data.empty? entries_data.each do |entry| entry_title = entry['description'] # Skip if we've already seen this entry, NOTE: we assume that there is only one inner_entry per time entry next if TrackedTimeEntry.exists?(associated_toggl_entry_id: entry['time_entries'][0]['id']) if (lecture = lectures.find_by(title: entry_title)) is_concurrent = entry['time_entries'].any? do |inner_entry| (Time.new(inner_entry['start']) - lecture.start_time).abs < 10.minutes end kind = if is_concurrent :concurrent else :catchup end lecture.tracked_time_entries.create!( toggl_data: entry, associated_toggl_entry_id: entry['time_entries'][0]['id'], # TODO: What should happen if the time entry is materially before the lecture? kind: ) and next elsif (work_item = course.work_items.find_by(title: entry_title)) work_item.tracked_time_entries.create!( toggl_data: entry, associated_toggl_entry_id: entry['time_entries'][0]['id'], kind: :generic ) and next end concurrent_unlabeled = entry['time_entries'].any? do |inner_entry| lecture = lectures.find do |lecture| (Time.new(inner_entry['start']) - lecture.start_time).abs < 10.minutes end if lecture.present? lecture.tracked_time_entries.create!( kind: :concurrent, toggl_data: entry, associated_toggl_entry_id: inner_entry['id'] ) end lecture.present? end next if concurrent_unlabeled preparation_regex = /^(.+): ?(?:Prep|Preparation)?$/ review_regex = /^(.+): ?(?:Review|Recap)/ catchup_regex = /^(.+): ?(?:Catch-up|Catch up|Catch Up)/ if (lecture_title_match = entry_title.match(preparation_regex)) and (lecture = lectures.find_by(title: lecture_title_match[1])) lecture.tracked_time_entries.create!( kind: :preparation, toggl_data: entry, associated_toggl_entry_id: entry['time_entries'][0]['id'], ) # broadcast_update_to lecture, :lectures elsif (lecture_title_match = entry_title.match(review_regex)) and (lecture = lectures.find_by(title: lecture_title_match[1])) lecture.tracked_time_entries.create!( kind: :review, toggl_data: entry, associated_toggl_entry_id: entry['time_entries'][0]['id'], ) # broadcast_update_to lecture, :lectures elsif (lecture_title_match = entry_title.match(catchup_regex)) and (lecture = lectures.find_by(title: lecture_title_match[1])) lecture.tracked_time_entries.create!( kind: :catchup, toggl_data: entry, associated_toggl_entry_id: entry['time_entries'][0]['id'], ) # broadcast_update_to lecture, :lectures end end end end