shiftnote 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []