mypage_tools 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +42 -0
- data/Rakefile +1 -0
- data/bin/mypage +5 -0
- data/lib/capybara_with_phantom_js.rb +25 -0
- data/lib/mypage_tools.rb +48 -0
- data/lib/mypage_tools/cli.rb +56 -0
- data/lib/mypage_tools/schedule_page.rb +74 -0
- data/lib/mypage_tools/schedule_scraper.rb +103 -0
- data/lib/mypage_tools/shift.rb +40 -0
- data/lib/mypage_tools/version.rb +3 -0
- data/lib/mypage_tools/weekly_schedule.rb +27 -0
- data/mypage_tools.gemspec +29 -0
- metadata +158 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 22802225cc96365c393cd16775b504bf8e49d37c
|
4
|
+
data.tar.gz: 3d585f0cc41fcee1a98a27c6d4b7c87b17e96c61
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 756f3a6075e5d983063c5a4b9c15ba85061dd075450e09c29fc8c109e2833e973d6545d7875ecfa3d539cd31f3c260b8342ce241953bde8b7416f12fa4a12477
|
7
|
+
data.tar.gz: ff404bc6df53c0d386efd83d7a8681bce39beca95488dba96174eaa107c6d5a01211722ed95bb189aa8db0f49103e0bd06e513b15fc721c1586d5d66af16c702
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Brown Mike
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# MypageTools
|
2
|
+
|
3
|
+
A work in progress. Very primitive right now.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'mypage_tools'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install mypage_tools
|
18
|
+
|
19
|
+
## Requirements
|
20
|
+
|
21
|
+
For now you need [PhantomJS](http://phantomjs.org) and [Ruby 2.0](http://www.ruby-lang.org/en/downloads/) or greater installed.
|
22
|
+
|
23
|
+
If you have [Homebrew](http://brew.sh) installed you can just
|
24
|
+
|
25
|
+
$ brew install phantomjs
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
$ mypage
|
30
|
+
|
31
|
+
## TODO:
|
32
|
+
+ Automagically handle PhantomJS dependency
|
33
|
+
+ Output to one .ics file starting from the first day you don't have a schedule for
|
34
|
+
+ Write tests! :-X
|
35
|
+
|
36
|
+
## Contributing
|
37
|
+
|
38
|
+
1. Fork it
|
39
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
40
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
41
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
42
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/mypage
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Voodoo to make Capybara do what I want.
|
2
|
+
# Ripped off nearly wholesale from a random blog after hours of Googling.
|
3
|
+
module CapybaraWithPhantomJs
|
4
|
+
include Capybara::DSL
|
5
|
+
|
6
|
+
def new_session
|
7
|
+
Capybara.register_driver :poltergeist do |app|
|
8
|
+
Capybara::Poltergeist::Driver.new(app)
|
9
|
+
end
|
10
|
+
|
11
|
+
Capybara.configure do |config|
|
12
|
+
config.run_server = false # Aparrently I have to do this if I'm not locally testing
|
13
|
+
config.default_driver = :poltergeist
|
14
|
+
config.default_selector = :xpath
|
15
|
+
config.ignore_hidden_elements = true
|
16
|
+
config.app_host = "https://mypage.apple.com"
|
17
|
+
end
|
18
|
+
|
19
|
+
@session = Capybara::Session.new(:poltergeist)
|
20
|
+
|
21
|
+
@session.driver.headers = { "User-Agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X" }
|
22
|
+
|
23
|
+
@session
|
24
|
+
end
|
25
|
+
end
|
data/lib/mypage_tools.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
2
|
+
# #
|
3
|
+
# USELESS COMMENT BOX BY: #
|
4
|
+
# #
|
5
|
+
# ___ ___ _ _ #
|
6
|
+
# | \ / | o | | / /____ #
|
7
|
+
# | |\ \/ /| | _ | |/ // __ \ #
|
8
|
+
# | | \__/ | || || (/ ____\ #
|
9
|
+
# | | | || || |\ \ \___ #
|
10
|
+
# |_| |_||_||_| \_\_____\ #
|
11
|
+
# ____ #
|
12
|
+
# | \ #
|
13
|
+
# | - ) _____ ___ __ __ __ #
|
14
|
+
# | __/ | ___\ / _ \\ \ __ / // \ #
|
15
|
+
# | \ | | | | | |\ \ / \ / /| /\ | #
|
16
|
+
# | - )| | | |_| | \ \/ /\ \/ / | | | | #
|
17
|
+
# |____/ |_| \ ___ / \__/ \__/ |_| |_| #
|
18
|
+
# #
|
19
|
+
# #
|
20
|
+
# TODO: Compare gathered data to existing .ics files #
|
21
|
+
# and inform of any changes to schedule #
|
22
|
+
# #
|
23
|
+
# TODO: Add ability to automagically import to #
|
24
|
+
# Calendar application #
|
25
|
+
# #
|
26
|
+
# TODO: GUI? Bah. Probably not. #
|
27
|
+
# #
|
28
|
+
# TODO: Check timecard against schedule for possible #
|
29
|
+
# missing punches? #
|
30
|
+
# #
|
31
|
+
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
32
|
+
|
33
|
+
require "capybara/dsl"
|
34
|
+
require "capybara/poltergeist"
|
35
|
+
require "icalendar"
|
36
|
+
require "io/console"
|
37
|
+
require "active_support/core_ext"
|
38
|
+
require "mypage_tools/version"
|
39
|
+
require "capybara_with_phantom_js"
|
40
|
+
require "mypage_tools/shift"
|
41
|
+
require "mypage_tools/weekly_schedule"
|
42
|
+
require "mypage_tools/schedule_scraper"
|
43
|
+
require "mypage_tools/schedule_page"
|
44
|
+
require "mypage_tools/cli"
|
45
|
+
|
46
|
+
module MypageTools
|
47
|
+
SCHEDULE_DIR = File.join(Dir.home, "myPage Schedule")
|
48
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module MypageTools
|
2
|
+
class CLI
|
3
|
+
def self.parse_options args=ARGV
|
4
|
+
case args[0]
|
5
|
+
when "schedule"
|
6
|
+
schedule
|
7
|
+
when "help"
|
8
|
+
self.help
|
9
|
+
else
|
10
|
+
puts "\nUnkown Argument\n"
|
11
|
+
self.help
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.schedule
|
16
|
+
print `clear`
|
17
|
+
puts "In order to get your work schedule you need to provide your login and password for myPage."
|
18
|
+
print "Login: "
|
19
|
+
ARGV.clear
|
20
|
+
login = gets.chomp
|
21
|
+
password = get_password
|
22
|
+
puts "\n"
|
23
|
+
scrape_session = ScheduleScraper.new login, password
|
24
|
+
scrape_session.schedule_page
|
25
|
+
while scrape_session.schedule_available?
|
26
|
+
scrape_session.generate_schedule
|
27
|
+
scrape_session.next_week
|
28
|
+
break if scrape_session.no_schedule_available? # Loop not breaking w/out this line. Need to investigate.
|
29
|
+
end
|
30
|
+
puts "\nNo further schedules available."
|
31
|
+
print `open #{Dir.home}/myPage\\ Schedule`
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.help # hahaha
|
35
|
+
puts ""
|
36
|
+
puts "The only implemented feature currently is getting your schedule"
|
37
|
+
puts ""
|
38
|
+
puts "USAGE:"
|
39
|
+
puts "\tmypage schedule"
|
40
|
+
puts ""
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
if STDIN.respond_to?(:noecho)
|
45
|
+
def self.get_password
|
46
|
+
print "Password: "
|
47
|
+
STDIN.noecho(&:gets).chomp
|
48
|
+
end
|
49
|
+
else
|
50
|
+
# Legacy support for Ruby < 1.9
|
51
|
+
def self.get_password
|
52
|
+
`read -s -p "Password: " password; echo $password`.chomp
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module MypageTools
|
2
|
+
class SchedulePage
|
3
|
+
# Expects the myPage schedule page as a Nokogiri HTML object
|
4
|
+
def initialize page
|
5
|
+
@page = page
|
6
|
+
end
|
7
|
+
|
8
|
+
# Return string containing the date the week begins, i.e. "Sep 14, 2013"
|
9
|
+
# Matches from the raw_schedule_text using a regex
|
10
|
+
# http://rubular.com/r/OjRZ0q6cko
|
11
|
+
def week_begins
|
12
|
+
unless @week_begins
|
13
|
+
@week_begins = raw_schedule_text.scan(/\w+\s\d{1,2},\s\d{4}/)[0]
|
14
|
+
end
|
15
|
+
@week_begins
|
16
|
+
end
|
17
|
+
|
18
|
+
# Gross & Ugly.
|
19
|
+
# Returns an array where every item is a Shift object
|
20
|
+
def shift_array
|
21
|
+
unless @shift_array
|
22
|
+
@shift_array = []
|
23
|
+
days_of_week = %w[Saturday Sunday Monday Tuesday Wednesday Thursday Friday]
|
24
|
+
|
25
|
+
# Establishing variable scope
|
26
|
+
current_day = nil
|
27
|
+
current_date = nil
|
28
|
+
index_counter = 0
|
29
|
+
shift = nil
|
30
|
+
|
31
|
+
# Finds a day then creates shifts for that day from each following pair of times
|
32
|
+
raw_schedule_array.each do |item|
|
33
|
+
if days_of_week.member?(item)
|
34
|
+
current_day = item
|
35
|
+
# Figure out the date of the shift based on the day of the week & start date of the week
|
36
|
+
current_date = Date.parse(week_begins) + days_of_week.index(item)
|
37
|
+
index_counter = 0
|
38
|
+
elsif index_counter == 0
|
39
|
+
shift = Shift.new
|
40
|
+
shift.day_of_week = current_day
|
41
|
+
shift.date = current_date
|
42
|
+
shift.start = item
|
43
|
+
index_counter += 1
|
44
|
+
elsif index_counter == 1
|
45
|
+
shift.stop = item
|
46
|
+
index_counter = 0
|
47
|
+
@shift_array << shift
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
@shift_array
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
# Returns a string with all the necessary information to extract that week's schedule
|
56
|
+
def raw_schedule_text
|
57
|
+
unless @raw_schedule_text
|
58
|
+
xpath_to_schedule = "//div[@id = 'contentTimecard']/div/table/tbody/tr/td/table/tbody"
|
59
|
+
@raw_schedule_text = @page.search(xpath_to_schedule).text
|
60
|
+
end
|
61
|
+
@raw_schedule_text
|
62
|
+
end
|
63
|
+
|
64
|
+
# Data structure for schedule: [Day, Start, End, Day, Start, End, (Start), (End), etc...]
|
65
|
+
# Matched from the raw_schedule_text with a regex
|
66
|
+
# http://rubular.com/r/xOOFBOKFMM
|
67
|
+
def raw_schedule_array
|
68
|
+
unless @raw_schedule_array
|
69
|
+
@raw_schedule_array = raw_schedule_text.scan /[SMTWF]\w{2,5}day|\d{1,2}:\d{2}[A|P]M/
|
70
|
+
end
|
71
|
+
@raw_schedule_array
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module MypageTools
|
2
|
+
class ScheduleScraper
|
3
|
+
include CapybaraWithPhantomJs
|
4
|
+
|
5
|
+
def initialize username, password
|
6
|
+
@username = username
|
7
|
+
@password = password
|
8
|
+
end
|
9
|
+
|
10
|
+
def schedule_page
|
11
|
+
unless @schedule_page
|
12
|
+
new_session
|
13
|
+
visit "/"
|
14
|
+
wait_for(:wait_message => "Loading Login Page") { page.has_content? "Account Name" }
|
15
|
+
login
|
16
|
+
click_link "myTime"
|
17
|
+
wait_for(:wait_message => "Loading Timecard") { page.has_content? "Current Timecard" }
|
18
|
+
click_link "Schedule"
|
19
|
+
wait_for(:wait_message => "Checking for available schedule") { schedule_available? }
|
20
|
+
@schedule_page = SchedulePage.new(Nokogiri::HTML.parse(page.html))
|
21
|
+
end
|
22
|
+
@schedule_page
|
23
|
+
end
|
24
|
+
|
25
|
+
def schedule_available?
|
26
|
+
page.has_text? /Schedule\sbegins\s\w+\s\d{1,2},\s\d{4}/
|
27
|
+
end
|
28
|
+
|
29
|
+
def no_schedule_available?
|
30
|
+
page.has_text? "Schedule is not available for the selected week"
|
31
|
+
end
|
32
|
+
|
33
|
+
def generate_schedule
|
34
|
+
schedule = WeeklySchedule.new @schedule_page.week_begins, @schedule_page.shift_array
|
35
|
+
schedule.to_ics
|
36
|
+
end
|
37
|
+
|
38
|
+
def next_week
|
39
|
+
next_week_begins_date = Date.parse(@schedule_page.week_begins) + 7
|
40
|
+
if date_in_current_month? next_week_begins_date
|
41
|
+
click_calendar_day(next_week_begins_date)
|
42
|
+
@schedule_page = SchedulePage.new(Nokogiri::HTML.parse(page.html))
|
43
|
+
else
|
44
|
+
click_next_month next_week_begins_date
|
45
|
+
click_calendar_day(next_week_begins_date)
|
46
|
+
@schedule_page = SchedulePage.new(Nokogiri::HTML.parse(page.html))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
def login
|
52
|
+
fill_in "appleId", with: @username
|
53
|
+
fill_in "accountPassword", with: @password
|
54
|
+
click_on "submitButton2"
|
55
|
+
wait_for(:wait_message => "Logging in") { page.has_button? "Sign Out" }
|
56
|
+
end
|
57
|
+
|
58
|
+
def date_in_current_month? date
|
59
|
+
Date.parse(@schedule_page.week_begins).month == date.month
|
60
|
+
end
|
61
|
+
|
62
|
+
def click_calendar_day date
|
63
|
+
day_number = date.day.to_s
|
64
|
+
within("//div[@id = 'calendar-#{date.year}-#{date.month - 1}']") do
|
65
|
+
# BUG FIX -> capybara finding multiple elements, use regex to exact match date
|
66
|
+
find("//td[@class = 'weekend']", text: /\A#{day_number}\z/).click
|
67
|
+
end
|
68
|
+
wait_for(:wait_message => "Loading next week") do
|
69
|
+
page.has_content?("Schedule begins #{date.strftime("%b %d, %Y")}") || no_schedule_available?
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Clicks on the little arrow on the calendar to load the next month
|
74
|
+
def click_next_month date
|
75
|
+
find("//img[@id = 'right' and @class = 'arrow']").click
|
76
|
+
wait_for { page.has_content? "#{date.strftime("%B %Y")}" }
|
77
|
+
end
|
78
|
+
|
79
|
+
# Helper method to allow waiting for a specific thing on the page to load
|
80
|
+
# Times out after 10 seconds (1+2+3+4)
|
81
|
+
# Expects a block that returns a boolean value
|
82
|
+
def wait_for options={}
|
83
|
+
options.reverse_merge!({fail_message: "Request Timed Out"})
|
84
|
+
wait_message = options[:wait_message]
|
85
|
+
latency = 0
|
86
|
+
print "\n" << wait_message << "..." if wait_message
|
87
|
+
while latency < 6
|
88
|
+
latency.times { print "." } if wait_message
|
89
|
+
sleep latency
|
90
|
+
if yield
|
91
|
+
print "\n" if wait_message
|
92
|
+
return true
|
93
|
+
end
|
94
|
+
latency += 1
|
95
|
+
end
|
96
|
+
abort format_failure(options[:fail_message])
|
97
|
+
end
|
98
|
+
|
99
|
+
def format_failure message
|
100
|
+
"\n" + ("#" * message.length) + "\n\n#{message}\n\n" + ("#" * message.length) + "\n\n"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module MypageTools
|
2
|
+
# Data structure to represent a single shift on a single day
|
3
|
+
class Shift
|
4
|
+
include Icalendar
|
5
|
+
attr_accessor :day_of_week, :date, :start, :stop
|
6
|
+
|
7
|
+
def initialize day_of_week=nil, date=nil, start=nil, stop=nil
|
8
|
+
@day_of_week = day_of_week
|
9
|
+
@date = date
|
10
|
+
@start = start
|
11
|
+
@stop = stop
|
12
|
+
end
|
13
|
+
|
14
|
+
def date
|
15
|
+
@date.strftime("%b %d, %Y")
|
16
|
+
end
|
17
|
+
|
18
|
+
def start
|
19
|
+
Time.parse(@start).strftime("%H:%M")
|
20
|
+
end
|
21
|
+
|
22
|
+
def stop
|
23
|
+
Time.parse(@stop).strftime("%H:%M")
|
24
|
+
end
|
25
|
+
|
26
|
+
def not_scheduled?
|
27
|
+
@start == "00:00AM" && @stop == "00:00AM"
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_ical_event
|
31
|
+
event = Event.new
|
32
|
+
event.start = DateTime.parse(self.date + " " + self.start + " PST")
|
33
|
+
event.end = DateTime.parse(self.date + " " + self.stop + " PST")
|
34
|
+
event.description = "Work at Apple"
|
35
|
+
event.summary = "Work (Apple)"
|
36
|
+
event.location = "Apple Store University Village, 2656 Northeast University Village Street, Seattle, WA, US"
|
37
|
+
event
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module MypageTools
|
2
|
+
# Data structure to represent 1 week's Shifts
|
3
|
+
class WeeklySchedule
|
4
|
+
include Icalendar
|
5
|
+
attr_reader :week_begins
|
6
|
+
|
7
|
+
def initialize week_begins, shift_array
|
8
|
+
@week_begins = week_begins
|
9
|
+
@shift_array = shift_array
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_ics
|
13
|
+
cal = Calendar.new
|
14
|
+
@shift_array.each do |shift|
|
15
|
+
cal.add_event shift.to_ical_event unless shift.not_scheduled?
|
16
|
+
end
|
17
|
+
cal.publish
|
18
|
+
cal_string = cal.to_ical
|
19
|
+
|
20
|
+
# TODO: Extract this elsewhere
|
21
|
+
FileUtils.mkdir(SCHEDULE_DIR) unless File.directory?(SCHEDULE_DIR)
|
22
|
+
file_name = File.join(SCHEDULE_DIR, "Schedule from #{@week_begins}.ics")
|
23
|
+
File.open(file_name, "w") { |io| io.write cal_string }
|
24
|
+
print "\nSaving schedule to:\n#{file_name}\n"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'mypage_tools/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "mypage_tools"
|
8
|
+
spec.version = MypageTools::VERSION
|
9
|
+
spec.authors = ["Brown Mike"]
|
10
|
+
spec.email = ["thebrownmike@me.com"]
|
11
|
+
spec.description = %q{myPage tools for Apple Retail employees}
|
12
|
+
spec.summary = %q{myPage tools for Apple Retail employees}
|
13
|
+
spec.homepage = "https://www.github.com/brownmike/mypage_tools"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency "capybara", "~> 2.2.1"
|
22
|
+
spec.add_runtime_dependency "poltergeist", "~> 1.5.0"
|
23
|
+
spec.add_runtime_dependency "icalendar", "~> 1.5.0"
|
24
|
+
spec.add_runtime_dependency "active_support", "~> 3.0.0"
|
25
|
+
spec.add_runtime_dependency "i18n"
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
28
|
+
spec.add_development_dependency "rake"
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mypage_tools
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brown Mike
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: capybara
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.2.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.2.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: poltergeist
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.5.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.5.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: icalendar
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.5.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.5.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: active_support
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.0.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 3.0.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: i18n
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: bundler
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.3'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.3'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: myPage tools for Apple Retail employees
|
112
|
+
email:
|
113
|
+
- thebrownmike@me.com
|
114
|
+
executables:
|
115
|
+
- mypage
|
116
|
+
extensions: []
|
117
|
+
extra_rdoc_files: []
|
118
|
+
files:
|
119
|
+
- ".gitignore"
|
120
|
+
- Gemfile
|
121
|
+
- LICENSE.txt
|
122
|
+
- README.md
|
123
|
+
- Rakefile
|
124
|
+
- bin/mypage
|
125
|
+
- lib/capybara_with_phantom_js.rb
|
126
|
+
- lib/mypage_tools.rb
|
127
|
+
- lib/mypage_tools/cli.rb
|
128
|
+
- lib/mypage_tools/schedule_page.rb
|
129
|
+
- lib/mypage_tools/schedule_scraper.rb
|
130
|
+
- lib/mypage_tools/shift.rb
|
131
|
+
- lib/mypage_tools/version.rb
|
132
|
+
- lib/mypage_tools/weekly_schedule.rb
|
133
|
+
- mypage_tools.gemspec
|
134
|
+
homepage: https://www.github.com/brownmike/mypage_tools
|
135
|
+
licenses:
|
136
|
+
- MIT
|
137
|
+
metadata: {}
|
138
|
+
post_install_message:
|
139
|
+
rdoc_options: []
|
140
|
+
require_paths:
|
141
|
+
- lib
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
requirements: []
|
153
|
+
rubyforge_project:
|
154
|
+
rubygems_version: 2.0.3
|
155
|
+
signing_key:
|
156
|
+
specification_version: 4
|
157
|
+
summary: myPage tools for Apple Retail employees
|
158
|
+
test_files: []
|