help_desk_dashboard 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (24) hide show
  1. data/bin/help_desk_dashboard.rb +19 -0
  2. data/lib/help-desk-dashboard/provider_factory.rb +9 -0
  3. data/lib/help-desk-dashboard/providers/service-desk-plus/8.1/provider.rb +11 -0
  4. data/lib/help-desk-dashboard/providers/track-it/2003.10.1/navigator.rb +13 -0
  5. data/lib/help-desk-dashboard/providers/track-it/2003.10.1/parallel_request_scraper.rb +42 -0
  6. data/lib/help-desk-dashboard/providers/track-it/2003.10.1/provider.rb +27 -0
  7. data/lib/help-desk-dashboard/providers/track-it/2003.10.1/request_scraper.rb +48 -0
  8. data/lib/help-desk-dashboard/providers/track-it/2003.10.1/user_operations.rb +40 -0
  9. data/lib/help-desk-dashboard/providers/track-it/2003.10.1/user_request_scraper.rb +33 -0
  10. data/lib/help-desk-dashboard/web/config.ru +16 -0
  11. data/lib/help-desk-dashboard/web/public/bootstrap/css/bootstrap-responsive.css +1109 -0
  12. data/lib/help-desk-dashboard/web/public/bootstrap/css/bootstrap-responsive.min.css +9 -0
  13. data/lib/help-desk-dashboard/web/public/bootstrap/css/bootstrap.css +6158 -0
  14. data/lib/help-desk-dashboard/web/public/bootstrap/css/bootstrap.min.css +9 -0
  15. data/lib/help-desk-dashboard/web/public/bootstrap/img/glyphicons-halflings-white.png +0 -0
  16. data/lib/help-desk-dashboard/web/public/bootstrap/img/glyphicons-halflings.png +0 -0
  17. data/lib/help-desk-dashboard/web/public/bootstrap/js/bootstrap.js +2268 -0
  18. data/lib/help-desk-dashboard/web/public/bootstrap/js/bootstrap.min.js +6 -0
  19. data/lib/help-desk-dashboard/web/public/css/app.css +64 -0
  20. data/lib/help-desk-dashboard/web/public/index.html +16 -0
  21. data/lib/help-desk-dashboard/web/public/js/app.js +107 -0
  22. data/lib/help-desk-dashboard/web/public/js/jquery-1.10.1.min.js +6 -0
  23. data/lib/help-desk-dashboard/web/public/js/moment.min.js +6 -0
  24. metadata +102 -0
@@ -0,0 +1,19 @@
1
+ $stdout.sync = true
2
+
3
+ require_relative '../lib/help-desk-dashboard/provider_factory'
4
+
5
+ ENV['HTTP_PROXY'] = nil
6
+ ENV['CONFIG_FILE'] ||= 'config.json'
7
+
8
+ config = JSON.parse File.read(ENV['CONFIG_FILE'])
9
+ config['thread_limit'] = ENV['THREAD_LIMIT'] ||= '5'
10
+ provider_factory = ProviderFactory.new
11
+ provider = provider_factory.create config
12
+ requests = provider.get_requests
13
+
14
+ public_web_dir = File.join File.dirname(__FILE__) + '/../lib/help-desk-dashboard/web/public'
15
+ data_file = File.join public_web_dir, 'data.json'
16
+ File.write data_file, requests.to_json
17
+ FileUtils.cp_r "#{public_web_dir}/.", config['output_dir']
18
+
19
+ puts 'Done.'
@@ -0,0 +1,9 @@
1
+ class ProviderFactory
2
+
3
+ def create(config)
4
+ path = File.join File.dirname(__FILE__), 'providers', config['provider'], config['version'], 'provider.rb'
5
+ load path
6
+ Provider.new config
7
+ end
8
+
9
+ end
@@ -0,0 +1,11 @@
1
+ class Provider
2
+
3
+ def initialize(config)
4
+
5
+ end
6
+
7
+ def get_requests
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,13 @@
1
+ class Navigator
2
+
3
+ def initialize(b, base_url)
4
+ @b = b
5
+ @base_url = base_url
6
+ end
7
+
8
+ def goto(relative_url)
9
+ url = File.join @base_url, relative_url
10
+ @b.goto url
11
+ end
12
+
13
+ end
@@ -0,0 +1,42 @@
1
+ require 'thread'
2
+ require 'watir-webdriver'
3
+ require_relative 'request_scraper'
4
+ require_relative 'user_operations'
5
+
6
+ class ParallelRequestScraper
7
+
8
+ def initialize(url, user, thread_limit)
9
+ @url = url
10
+ @user = user
11
+ @thread_limit = thread_limit
12
+ end
13
+
14
+ def scrape(request_ids)
15
+ queue = request_ids.clone
16
+ threads = []
17
+ requests = []
18
+ mutex = Mutex.new
19
+
20
+ @thread_limit.times do
21
+ threads << Thread.new do
22
+ b = Watir::Browser.new
23
+ navigator = Navigator.new b, @url
24
+ user_operations = UserOperations.new b, navigator
25
+ user_operations.login @user
26
+ request_scraper = RequestScraper.new b, navigator
27
+ until queue.empty?
28
+ id = nil
29
+ mutex.synchronize do
30
+ id = queue.pop
31
+ end
32
+ break unless id
33
+ requests << request_scraper.scrape(id)
34
+ end
35
+ b.close
36
+ end
37
+ end
38
+ threads.each { |t| t.join }
39
+ requests
40
+ end
41
+
42
+ end
@@ -0,0 +1,27 @@
1
+ require 'watir-webdriver'
2
+ require_relative 'navigator'
3
+ require_relative 'parallel_request_scraper'
4
+ require_relative 'user_operations'
5
+
6
+ class Provider
7
+
8
+ def initialize(config)
9
+ @config = config
10
+ end
11
+
12
+ def get_requests
13
+ url = @config['url']
14
+ users = @config['users']
15
+
16
+ b = Watir::Browser.new
17
+ navigator = Navigator.new b, url
18
+ user_operations = UserOperations.new b, navigator
19
+ request_ids = user_operations.get_request_ids users
20
+ b.close
21
+
22
+ user = users.first
23
+ parallel_request_scraper = ParallelRequestScraper.new url, user, @config['thread_limit'].to_i
24
+ parallel_request_scraper.scrape request_ids
25
+ end
26
+
27
+ end
@@ -0,0 +1,48 @@
1
+ require 'time'
2
+
3
+ class RequestScraper
4
+
5
+ def initialize(b, navigator)
6
+ @b = b
7
+ @navigator = navigator
8
+ end
9
+
10
+ def scrape(id)
11
+ @navigator.goto "hd/ticket/euTicketView.ssp?ticket_id=#{id}&log=show"
12
+ cells = @b.tables[1].tds.to_a
13
+ {
14
+ id: @b.text.match(/Request #(\d+)/)[1],
15
+ title: cells[0].text,
16
+ status: cells[2].text,
17
+ service: cells[3].text,
18
+ request_type: cells[4].text,
19
+ time_spent: cells[6].text,
20
+ priority: cells[7].text,
21
+ deadline: Time.parse(cells[8].text),
22
+ submitted_to: cells[10].text,
23
+ submitted_by: cells[11].text.upcase,
24
+ submitted_on: Time.parse(cells[12].text),
25
+ assigned_to: cells[15].text.upcase,
26
+ assigned_by: cells[16].text,
27
+ assigned_on: Time.parse(cells[17].text),
28
+ department_id: cells[19].text,
29
+ closed_by: cells[20].text,
30
+ closed_on: cells[21].text == 'None' ? 'None' : Time.parse(cells[21].text)
31
+ }.merge scrape_resolved_data_from_audit_log
32
+ end
33
+
34
+ private
35
+
36
+ def scrape_resolved_data_from_audit_log
37
+ rows = @b.tables[3].trs.to_a
38
+ index = rows.index { |r| r.text =~ /Resolved by/ }
39
+ return {} unless index
40
+ text = rows[index-1].text
41
+ matches = text.match /(.+) by (.+)/
42
+ {
43
+ resolved_on: Time.parse(matches[1]),
44
+ resolved_by: matches[2].upcase
45
+ }
46
+ end
47
+
48
+ end
@@ -0,0 +1,40 @@
1
+ class UserOperations
2
+
3
+ def initialize(b, navigator)
4
+ @b = b
5
+ @navigator = navigator
6
+ end
7
+
8
+ def login(user)
9
+ @navigator.goto 'hd/index.ssp'
10
+ @b.text_field(name: 'user_id').set user['username']
11
+ @b.text_field(name: 'user_pwd').set user['password']
12
+ @b.button(value: 'Log on').click
13
+ end
14
+
15
+ def get_request_ids(users)
16
+ users = [users].flatten
17
+ request_ids = users.map do |user|
18
+ login user
19
+ @navigator.goto 'hd/ticket/euTicketFind.ssp'
20
+ @b.button(value: 'Find').click
21
+ request_locations = get_request_locations
22
+ request_locations.map { |l| l.match(/ticket_id=(\d+)/)[1].to_i }
23
+ end
24
+ request_ids.flatten
25
+ end
26
+
27
+ private
28
+
29
+ def get_request_locations
30
+ links = []
31
+ 5.times do
32
+ links = @b.links(href: /euTicketView\.ssp\?ticket_id=/).to_a
33
+ break unless links.empty?
34
+ sleep 2
35
+ end
36
+ puts "No requests found.\n\n#{@b.html}" if links.empty?
37
+ links.map { |link| link.href }.reverse
38
+ end
39
+
40
+ end
@@ -0,0 +1,33 @@
1
+ require 'time'
2
+ require 'watir-webdriver'
3
+ require_relative 'request_scraper'
4
+
5
+ class UserRequestScraper
6
+
7
+ def initialize(b)
8
+ @b = b
9
+ end
10
+
11
+ def scrape
12
+ @b.goto 'hd/ticket/euTicketFind.ssp'
13
+ @b.button(value: 'Find').click
14
+ request_locations = get_request_locations
15
+ request_ids = request_locations.map { |l| l.match(/ticket_id=(\d+)/)[1].to_i }
16
+ request_scraper = RequestScraper.new @b
17
+ request_scraper.scrape_range request_ids
18
+ end
19
+
20
+ private
21
+
22
+ def get_request_locations
23
+ links = []
24
+ 5.times do
25
+ links = @b.links(href: /euTicketView\.ssp\?ticket_id=/).to_a
26
+ break unless links.empty?
27
+ sleep 2
28
+ end
29
+ puts "No requests found.\n\n#{@b.html}" if links.empty?
30
+ links.map { |link| link.href }.reverse
31
+ end
32
+
33
+ end
@@ -0,0 +1,16 @@
1
+ require 'rack'
2
+
3
+ use Rack::Static,
4
+ :urls => %w(/bootstrap /css /js /data.json),
5
+ :root => 'public'
6
+
7
+ run lambda { |env|
8
+ [
9
+ 200,
10
+ {
11
+ 'Content-Type' => 'text/html',
12
+ 'Cache-Control' => 'public, max-age=86400'
13
+ },
14
+ File.open('public/index.html', File::RDONLY)
15
+ ]
16
+ }