shiftnote 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a2b6656f26dac7e804d5913fc203623998e548e8af5ef23defc3ee2447d02e2a
4
+ data.tar.gz: 3b3e588761717222c407be99ee76219d9cfa7ed18383a81145eae5fe34205d54
5
+ SHA512:
6
+ metadata.gz: e0f3b24ac76fd45f84f2a65817c2b4b57afb2d7d81d292f69231dba98fe27083bf2068e95212e6c5bf5e688147487551a30b90b5fcbe11f5d45f68bb8baa4b82
7
+ data.tar.gz: fc572be0e9db37eb992a7f7615332ecc29d12bcc284a3d4ecb330a9a0b751e136a6b198438e5973f688ce5267092e3eeafc846ec8a8ccc8aca42344047309ec2
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Gems needed to do a good job
4
+ require 'rest-client'
5
+ require 'nokogiri'
6
+ require 'json'
7
+ require 'rails'
8
+
9
+ # All ShiftNote functionality, whether extended or just here.
10
+ class ShiftNote
11
+ # Initialize a new ShiftNote variable, via a cookie.
12
+ # @param cookie [String] Cookie of an authenticated user.
13
+ def initialize(credentials = {})
14
+ @credentials = credentials
15
+ generate_cookie(credentials[:username], credentials[:password])
16
+ end
17
+
18
+ def generate_cookie(username, password)
19
+ uri = URI.parse('https://ww1.shiftnote.com/login')
20
+ request = Net::HTTP::Post.new(uri)
21
+ request.content_type = 'application/x-www-form-urlencoded'
22
+ request.set_form_data(
23
+ 'FullSite' => 'False',
24
+ 'ReturnUrl' => '',
25
+ 'username' => username,
26
+ 'Password' => password,
27
+ 'Submit' => 'Submit',
28
+ 'remember' => 'true'
29
+ )
30
+
31
+ req_options = {
32
+ use_ssl: uri.scheme == 'https'
33
+ }
34
+
35
+ response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
36
+ http.request(request)
37
+ end
38
+ # response.code
39
+ raise Errors::InvalidCredentials, 'The provided credentials are invalid, please try again.' if response.body.include?("There was no match for the username and password provided, please try again!")
40
+
41
+ @cookie = response.header['Set-Cookie']
42
+ end
43
+
44
+ # Initialize the Employee
45
+ # @return [ShiftNote::EmployeeOverviewViewModel] the employee
46
+ def employee
47
+ shiftnote = RestClient.get('https://ww1.shiftnote.com/BulletinBoard/', Cookie: @cookie)
48
+
49
+ doc = Nokogiri::HTML.parse(shiftnote.body)
50
+
51
+ begin
52
+ data = doc.search('div#MyScheduleDiv').at('script').text
53
+ rescue NoMethodError
54
+ generate_cookie(@credentials[:username], @credentials[:password])
55
+ retry
56
+ end
57
+
58
+ data = data.gsub('<script>', '').delete(';').gsub('</script>', '').gsub('window.scheduleMinebindings = ShiftNote.Bind(window.scheduleMinemodel)', '').gsub('window.scheduleMinemodel = ', '')
59
+
60
+ @employee = EmployeeOverviewViewModel.new(JSON.parse(data))
61
+ end
62
+
63
+ # @param weeks [Integer]
64
+ def get_all_upcoming_shifts(_weeks = 0)
65
+ employee if @employee = nil?
66
+ week2 = RestClient.get("https://ww1.shiftnote.com/Schedules/ScheduleMine/?startDate=#{nextmonday.month}%2F#{nextmonday.day}%2F#{nextmonday.year}&noContainer=true&_=1559999273196", Cookie: @cookie)
67
+
68
+ week2doc = Nokogiri::HTML.parse(week2.body)
69
+ dataweek2 = JSON.parse(scrapejunk(week2doc.at('script').text))
70
+ me2 = EmployeeOverviewViewModel.new(dataweek2)
71
+ end
72
+ end
73
+
74
+ # Require files.
75
+ require_relative 'shiftnote/days_of_week_shift'
76
+ require_relative 'shiftnote/days_of_week_shifts'
77
+ require_relative 'shiftnote/employee_overview_view_model'
78
+ require_relative 'shiftnote/errors'
79
+ require_relative 'shiftnote/schedule_this_week_view_model'
80
+ require_relative 'shiftnote/shift_view_model'
@@ -0,0 +1,27 @@
1
+ class ShiftNote::DaysOfWeekShift
2
+ def initialize(data)
3
+ @raw = data
4
+ @date = Time.parse(data['ShiftDate'])
5
+ @raw_shifts = data['Shifts']
6
+ end
7
+
8
+ attr_reader :date
9
+
10
+ def shifts
11
+ shifts = []
12
+ @raw_shifts.each do |e|
13
+ shifts.push ShiftNote::ShiftViewModel.new(e)
14
+ end
15
+ shifts
16
+ end
17
+
18
+ def amount_of_shifts
19
+ @raw_shifts.length
20
+ end
21
+
22
+ def first_shift
23
+ ShiftNote::ShiftViewModel.new(@raw_shifts.first)
24
+ end
25
+
26
+ attr_reader :raw
27
+ end
@@ -0,0 +1,25 @@
1
+ class ShiftNote::DaysOfWeekShifts
2
+ def initialize(data)
3
+ @data = data
4
+ end
5
+
6
+ def days
7
+ dayz = []
8
+ @data.each do |e|
9
+ dayz.push ShiftNote::DaysOfWeekShift.new(e)
10
+ end
11
+ dayz
12
+ end
13
+
14
+ def working_days
15
+ dayz = []
16
+ @data.each do |e|
17
+ dayz.push ShiftNote::DaysOfWeekShift.new(e) unless e['Shifts'].empty?
18
+ end
19
+ dayz
20
+ end
21
+
22
+ def raw
23
+ @data
24
+ end
25
+ end
@@ -0,0 +1,47 @@
1
+ class ShiftNote::EmployeeOverviewViewModel
2
+ def initialize(data)
3
+ @raw = data
4
+ @id = data['EmployeeId']
5
+ @name = data['EmployeeName']
6
+ @phones = {
7
+ 'home' => data['HomePhone'],
8
+ 'mobile' => data['MobilePhone']
9
+ }
10
+ @email = data['Email']
11
+ @birthday = Time.parse(data['BirthDate'])
12
+ @schedule_this_week = ShiftNote::ScheduleThisWeekViewModel.new(data['ScheduleThisWeekViewModel'])
13
+ @trade_shifts = data['TradeShifts']
14
+ @trade_shifts_current_day = data['TradeShiftsCurrentDay']
15
+ @positions = data['ThisEmployeePositions']
16
+ @last_day = data['LastDay'] ? Time.parse(data['LastDay']) : nil
17
+ @hire_day = data['HireDate'] ? Time.parse(data['HireDate']) : nil
18
+ end
19
+
20
+ # This is the employee's ID. Really has no use outside of Shiftnote internal data
21
+ # @return [Integer] the employee's internal ID
22
+ attr_reader :id
23
+
24
+ # The employee's (legal) name.
25
+ # @return [String] the employee's name
26
+ attr_reader :name
27
+
28
+ # An array containing the user's home and mobile phone numbers
29
+ # @return [Array<String>] the user's phone numbers.
30
+ attr_reader :phones
31
+
32
+ # @return [String] the user's email.
33
+ attr_reader :email
34
+
35
+ # @return [Time] the user's birthday
36
+ attr_reader :birthday
37
+
38
+ # The user's "Schedule This Week," consider the return type for info
39
+ # @return [ShiftNote::ScheduleThisWeekViewModel]
40
+ attr_reader :schedule_this_week
41
+ attr_reader :raw
42
+ attr_reader :trade_shifts
43
+ attr_reader :trade_shifts_current_day
44
+ attr_reader :positions
45
+ attr_reader :last_day
46
+ attr_reader :hire_day
47
+ end
@@ -0,0 +1,5 @@
1
+ # Errors are cool.
2
+ module ShiftNote::Errors
3
+ # Raised if the ShiftNote credentials are invalid.
4
+ class InvalidCredentials < ArgumentError; end
5
+ end
@@ -0,0 +1,19 @@
1
+ class ShiftNote::ScheduleThisWeekViewModel
2
+ def initialize(data)
3
+ @raw = data
4
+ @start_date = Time.parse(data['StartDate'])
5
+ @end_date = Time.parse(data['EndDate'])
6
+ @hours = data['Hours']
7
+ @cost = data['Cost']
8
+ @shifts = data['Shifts']
9
+ @schedule = ShiftNote::DaysOfWeekShifts.new(data['DaysOfWeekShifts'])
10
+ end
11
+
12
+ attr_reader :start_date
13
+ attr_reader :end_date
14
+ attr_reader :hours
15
+ attr_reader :cost
16
+ attr_reader :shifts
17
+ attr_reader :schedule
18
+ attr_reader :raw
19
+ end
@@ -0,0 +1,60 @@
1
+ class ShiftNote::ShiftViewModel
2
+ def initialize(data)
3
+ @raw = data
4
+ @schedule_id = data['ScheduleId']
5
+ @schedule_name = data['ScheduleName']
6
+ @schedule_status_id = data['ScheduleStatusId']
7
+ @shift_id = data['ShiftId']
8
+ @employee_id = data['EmployeeId']
9
+ @employee = data['Employee']
10
+ @shift_date = Time.parse(data['ShiftDate'])
11
+ @time_in = Time.parse(data['TimeIn'])
12
+ @time_out = Time.parse(data['TimeOut'])
13
+ @position = data['Position']
14
+ @position_color = data['PositionColor']
15
+ @internal_location = data['InternalLocation']
16
+ @open = data['Open']
17
+ @close = data['Close']
18
+ @on_call = data['OnCall']
19
+ @volume = data['Volume']
20
+ @note = data['Note']
21
+ @hours = data['Hours']
22
+ @cost = data['Cost']
23
+ @is_pending_pickup = data['IsPendingPickUp']
24
+ @is_pending_manager_approval = data['IsPendingManagerApproval']
25
+ @is_pending_swap = data['IsPendingSwap']
26
+ @is_pending_swap_manager_approval = data['IsPendingSwapManagerApproval']
27
+ @hide_end_times = data['HideEndTimes']
28
+ end
29
+
30
+ attr_reader :schedule_id
31
+ attr_reader :schedule_name
32
+ attr_reader :schedule_status_id
33
+ attr_reader :shift_id
34
+ attr_reader :employee_id
35
+ attr_reader :employee
36
+ attr_reader :shift_date
37
+ attr_reader :time_in
38
+ attr_reader :time_out
39
+ attr_reader :position
40
+ attr_reader :position_color
41
+ attr_reader :internal_location
42
+ attr_reader :open
43
+ attr_reader :close
44
+ attr_reader :on_call
45
+ attr_reader :volume
46
+ attr_reader :note
47
+ attr_reader :hours
48
+ attr_reader :cost
49
+ attr_reader :is_pending_pickup
50
+ attr_reader :is_pending_manager_approval
51
+ attr_reader :is_pending_swap
52
+ attr_reader :is_pending_swap_manager_approval
53
+ attr_reader :hide_end_times
54
+ attr_reader :raw
55
+
56
+ # Releases the shift
57
+ def release(employee = 0)
58
+
59
+ end
60
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shiftnote
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Chew
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-06-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.10.3
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.10.3
41
+ - !ruby/object:Gem::Dependency
42
+ name: rest-client
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.1.0.rc1
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.1.0.rc1
55
+ description: ShiftNote, an employee shift management system, but for Ruby
56
+ email: chew@chew.pw
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - lib/shiftnote.rb
62
+ - lib/shiftnote/days_of_week_shift.rb
63
+ - lib/shiftnote/days_of_week_shifts.rb
64
+ - lib/shiftnote/employee_overview_view_model.rb
65
+ - lib/shiftnote/errors.rb
66
+ - lib/shiftnote/schedule_this_week_view_model.rb
67
+ - lib/shiftnote/shift_view_model.rb
68
+ homepage: https://github.com/Chew/ShiftNoteRB
69
+ licenses:
70
+ - MIT
71
+ metadata:
72
+ bug_tracker_uri: https://github.com/Chew/ShiftNoteRB/issues
73
+ changelog_uri: https://github.com/Chew/ShiftNoteRB/releases
74
+ homepage_uri: http://github.com/Chew/ShiftNoteRB
75
+ source_code_uri: http://github.com/Chew/ShiftNoteRB
76
+ wiki_uri: http://github.com/Chew/ShiftNoteRB/wiki
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: 2.2.4
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubygems_version: 3.0.2
93
+ signing_key:
94
+ specification_version: 4
95
+ summary: ShiftNote, an employee shift management system, but for Ruby.
96
+ test_files: []