Class: Scry::Course

Inherits:
Object
  • Object
show all
Includes:
Helpers
Defined in:
lib/scry/course.rb

Overview

This class represents a course for which we are extracting data

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Helpers

#click_link, #write_log

Constructor Details

#initialize(agent, course_link) ⇒ Course

A new course accepts a Mechanize Agent and a Mechanize::Page::Link object for a course link



19
20
21
22
# File 'lib/scry/course.rb', line 19

def initialize(agent, course_link)
  @agent = agent
  @course_link = course_link
end

Class Method Details

.from_cookies(cookie_crumbs, course_url) ⇒ Object

Creates a new instance of a course from given cookies so the user is signed in



28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/scry/course.rb', line 28

def self.from_cookies(cookie_crumbs, course_url)
  agent = Mechanize.new
  agent.cookie_jar = YAML::load(cookie_crumbs)
  course_link = Mechanize::Page::Link.new(
    {
      "href" => course_url,
    },
    agent,
    nil,
  )
  Course.new(agent, course_link)
end

Instance Method Details

#_delete_existing_exports(page, course_id, links) ⇒ Object

:nodoc: Deletes all existing exports from a page.



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/scry/course.rb', line 177

def _delete_existing_exports(page, course_id, links)
  links ||= page.links_with(text: "Delete")
  puts "#{course_id} Deleting exports... #{links.count} remaining"
  if links.any?
    filename = links.last.href[/'(.*)'\,/, 1]

    page = page.form_with(name: "selectFileToDelete") do |form|
      form.field_with(name: "filename").value = filename
    end.submit

    links = page.links_with(text: "Delete")
    if links.any?
      _delete_existing_exports(page, course_id, links)
    end
  end
end

#_process_export_form(export_page) ⇒ Object

:nodoc: Fills out the export form and submits it.



132
133
134
135
136
137
138
139
140
141
142
# File 'lib/scry/course.rb', line 132

def _process_export_form(export_page)
  export_page.form_with(name: "selectCourse") do |export_form|
    export_form.radiobutton_with(
      id: "copyLinkToCourseFilesAndCopiesOfContent",
    ).check
    export_form.radiobutton_with(
      id: "copyLinkToExternalCourseFilesAndCopiesOfContent",
    ).check
    export_form.checkboxes.each(&:check)
  end.submit
end

#_wait_for_export(exports, utilities_page, exports_page, course_id) ⇒ Object

:nodoc: Waits a specified amount of time for an export to show up on the exports page.



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/scry/course.rb', line 149

def _wait_for_export(exports, utilities_page, exports_page, course_id)
  time = Time.now
  elapsed = 0
  puts "Begin waiting for export link for #{course_id}"
  while exports.count.zero? && elapsed < TWO_HOURS
    sleep 30
    exports_page = click_link(
      agent: @agent,
      page: utilities_page,
      text: /Export\/Archive Course/,
    )
    exports = exports_page.links_with(
      text: "View Basic Log",
    )
    elapsed = Time.now - time
    puts "#{course_id} waited #{elapsed.to_i} seconds for link"
  end
  if elapsed >= TWO_HOURS
    raise Scry::ExportFailed, "Export timeout for #{course_id}"
  end
  puts "#{course_id} done after #{(Time.now - time).to_i} seconds"
  exports_page
end

#create_exportObject

Creates an export file for the course

Navigates from the course page to the export course page and creates an export for the course.

First it all existing exports, then attempts to create a new export.

It will wait a specified amount of time for the export to be created.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/scry/course.rb', line 51

def create_export
  course_page = @agent.click(@course_link)
  package_links = course_page.links_with(
    text: /Packages & Utilities Overview Page/,
  )
  if package_links.any?
    utilities_page = click_link(
      agent: @agent,
      page: course_page,
      text: /Packages & Utilities Overview Page/,
    )
    exports_page = click_link(
      agent: @agent,
      page: utilities_page,
      text: /Export\/Archive Course/,
    )
    export_button_link = exports_page.links_with(
      text: /Export Package/,
    )
    if export_button_link.any?
      course_id =
        exports_page.form_with(name: "selectFileToDelete")["courseId"]
      _delete_existing_exports(exports_page, course_id, nil)
      export_page = click_link(
        agent: @agent,
        page: exports_page,
        text: /Export Package/,
      )
      exports_page = _process_export_form(export_page)
      exports = exports_page.links_with(
        text: "View Basic Log",
      )
      _wait_for_export(exports, utilities_page, exports_page, course_id)
    else
      write_log(
        Scry.export_generation_no_export_button,
        @course_link.href.strip,
      )
    end
  end
end

#download_export(url) ⇒ Object

Downloads the export into the given directory.



118
119
120
121
122
123
124
125
126
# File 'lib/scry/course.rb', line 118

def download_export(url)
  puts "Start downloading #{url}"
  time = Time.now
  @agent.pluggable_parser["application/zip"] = Mechanize::Download
  filename = File.basename(URI.parse(url).path)
  @agent.get(url).save(File.join(Scry.default_dir, filename))
  elapsed = Time.now - time
  puts "Done downloading #{url} took #{elapsed} seconds"
end

#download_url(page) ⇒ Object

Extracts the download URL for an export



110
111
112
113
# File 'lib/scry/course.rb', line 110

def download_url(page)
  download_link = page.links_with(text: "Open").last
  download_link.href
end

#validate_export(exports_page) ⇒ Object

Opens the log for an export and checks if it was successful.



96
97
98
99
100
101
102
103
104
105
# File 'lib/scry/course.rb', line 96

def validate_export(exports_page)
  links = exports_page.links_with(text: "View Basic Log")
  if links.empty?
    raise Scry::ExportFailed, "Links empty #{exports_page.uri}"
  end
  url = links.last.attributes["onclick"][/'(.*)'/, 1]
  log_page = @agent.get(url)
  text = Nokogiri::HTML(log_page.body).css("div#containerdiv").text
  !text.match(/error/i)
end