harvest_wheelman 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 08f7c6b51b6bb944171bb219bb8076928933cd22
4
+ data.tar.gz: 9d3f26cbb92f6066e3b8b184d3720a2ea9a59a95
5
+ SHA512:
6
+ metadata.gz: 65bcb571eb81cfe6f22ee7a1a0327ee0c14a1e314c5de68d1e22eb817b6e9d79c3bf449b401082f6eec5207e0f52023428a959282d11cb6a7144da1fdb5736ba
7
+ data.tar.gz: 00fa3e3ba4eda7da8065a9c6c88c049c78f74f0dbfe354b487206fd158091991913995daaa09abdcf623828ff8623f2600b02909d0dc26394fad193fc487591e
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in harvest_wheelman.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Keyvan Fatehi
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,50 @@
1
+ # HarvestWheelman
2
+
3
+ I use this tool every 2 weeks to generate a PDF timesheet report from Harvest the way my company wants them.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'harvest_wheelman'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install harvest_wheelman
18
+
19
+ ## Usage
20
+
21
+ `harvest_wheelman`
22
+
23
+ Optionally you can pass in a settings file like this:
24
+
25
+ `harvest_wheelman ~/MyStuff/harvest_Wheelman.json`
26
+
27
+ ## Example Settings File
28
+
29
+ ```json
30
+ {
31
+ "harvest":{
32
+ "site":"---",
33
+ "user":"---",
34
+ "pass":"---"
35
+ },
36
+ "pay_period":{
37
+ "weeks":2, # weeks in a pay period; used when only 1 date given (optional and defaults to 2)
38
+ "from":"09/03/2012", # start of pay period (optional if 'to' exists)
39
+ "to":"09/16/2012" # end of pay period (optional if 'from' exists)
40
+ }
41
+ }
42
+ ```
43
+
44
+ ## Contributing
45
+
46
+ 1. Fork it
47
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
48
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
49
+ 4. Push to the branch (`git push origin my-new-feature`)
50
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+ require 'harvest_wheelman'
3
+
4
+ SETTINGS_FILE = File.expand_path(ENV['SETTINGS_FILE_PATH'] || ARGV[0] || 'settings.json')
5
+
6
+ begin
7
+ hs = HarvestWheelman::HarvestSubmit.new(SETTINGS_FILE)
8
+ puts %{
9
+ Pay period is set from: #{hs.from}
10
+ to: #{hs.to}
11
+ Press enter to open firefox and generate the PDF using these dates.
12
+ Ctrl-C to quit.
13
+ }
14
+ puts hs.drive_to_pdf if STDIN.gets
15
+ rescue => ex
16
+ puts %{
17
+ Could not start, check your settings file.
18
+ Settings file: #{SETTINGS_FILE}
19
+
20
+ Example:
21
+ {
22
+ "harvest":{
23
+ "site":"---",
24
+ "user":"---",
25
+ "pass":"---"
26
+ },
27
+ "pay_period":{
28
+ "weeks":2, # weeks in a pay period (defaults to 2), used when only 1 date given
29
+ "from":"09/03/2012", # start of pay period
30
+ "to":"09/16/2012" # end of pay period
31
+ }
32
+ }
33
+ }
34
+ puts "There was a problem!\n#{ex.backtrace.join("\n")}\n\n#{ex.message}"
35
+ 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 'harvest_wheelman/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "harvest_wheelman"
8
+ spec.version = HarvestWheelman::VERSION
9
+ spec.authors = ["Keyvan Fatehi"]
10
+ spec.email = ["keyvanfatehi@gmail.com"]
11
+ spec.description = %q{Logs into Harvest and generates a PDF report the way my company likes it}
12
+ spec.summary = %q{Logs into Harvest and generates a PDF report}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.bindir = 'bin'
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "pry"
25
+
26
+ spec.add_runtime_dependency 'selenium-webdriver', '>=2.31.0'
27
+ spec.add_runtime_dependency 'timerizer'
28
+ spec.add_runtime_dependency 'json'
29
+ end
@@ -0,0 +1,143 @@
1
+ require 'json'
2
+ require 'selenium-webdriver'
3
+ require 'timerizer'
4
+
5
+ ##
6
+ # Puts +str+ into the pasteboard (Mac only)
7
+ def pbcopy(str)
8
+ return unless RUBY_PLATFORM =~ /darwin/
9
+ `echo "#{str}" | pbcopy`
10
+ end
11
+
12
+ module HarvestWheelman
13
+ class HarvestSubmit
14
+ class UnknownTimeIntervalError < StandardError ; end
15
+ DATEFORMAT = "%m/%d/%Y"
16
+ attr_reader :harvest
17
+ attr_writer :from, :to
18
+
19
+ def initialize(settings_file)
20
+ File.open(settings_file) do |f|
21
+ @settings = JSON.parse(f.read)
22
+ end
23
+ determine_time_interval!
24
+ end
25
+
26
+ ##
27
+ # Pay period weeks
28
+ def ppw
29
+ @ppw ||= @settings['pay_period']['weeks'] || 2
30
+ end
31
+
32
+ def determine_time_interval!
33
+ if date_valid? from
34
+ if date_valid? to
35
+ else
36
+ puts "Setting TO via the FROM based on a #{ppw} week pay period"
37
+ @to = date_to_string(1.day.before(ppw.weeks.after(string_to_date(from))))
38
+ end
39
+ elsif date_valid? to
40
+ puts "Setting FROM via the TO based on a ppw week pay period"
41
+ @from = date_to_string(1.day.after(ppw.weeks.before(string_to_date(to))))
42
+ else
43
+ raise UnknownTimeIntervalError
44
+ end
45
+ end
46
+
47
+ def string_to_date(input)
48
+ Date.strptime(input, DATEFORMAT)
49
+ end
50
+
51
+ def date_to_string(input)
52
+ input.strftime(DATEFORMAT)
53
+ end
54
+
55
+ def date_valid?(input)
56
+ return false unless input
57
+ begin
58
+ string_to_date input
59
+ rescue ArgumentError
60
+ false
61
+ end
62
+ end
63
+
64
+ def from
65
+ @from ||= @settings['pay_period']['from']
66
+ end
67
+
68
+ def to
69
+ @to ||= @settings['pay_period']['to']
70
+ end
71
+
72
+ def site
73
+ @settings["harvest"]["site"]
74
+ end
75
+
76
+ def user
77
+ @settings['harvest']['user']
78
+ end
79
+
80
+ def pass
81
+ @settings['harvest']['pass']
82
+ end
83
+
84
+ def whoami
85
+ `whoami`.strip
86
+ end
87
+
88
+ def pdf_name
89
+ "#{subject}.pdf"
90
+ end
91
+
92
+ def subject
93
+ "#{whoami}'s Timesheet #{from} - #{to}"
94
+ end
95
+
96
+ def body
97
+ %{Hello,
98
+ Attached is my timesheet for pay period #{from} - #{to}
99
+ Thank you,
100
+ #{whoami}}
101
+ end
102
+
103
+ def drive_to_pdf
104
+ begin
105
+ @driver = Selenium::WebDriver.for :firefox
106
+ @base_url = "https://#{site}.harvestapp.com/"
107
+ @driver.manage.timeouts.implicit_wait = 30
108
+ @verification_errors = []
109
+ @driver.get(@base_url + "/account/login")
110
+ @driver.find_element(:id, "email").clear
111
+ @driver.find_element(:id, "email").send_keys user
112
+ @driver.find_element(:id, "user_password").clear
113
+ @driver.find_element(:id, "user_password").send_keys pass
114
+ @driver.find_element(:id, "sign-in-button").click
115
+ @driver.find_element(:link, "Reports").click
116
+ @driver.find_element(:css, "span.btn-dropdown").click
117
+ @driver.find_element(:link, "Custom").click
118
+
119
+ @driver.find_element(:id, "start_date").clear
120
+ @driver.find_element(:id, "start_date").send_keys from
121
+ @driver.find_element(:id, "end_date").clear
122
+ @driver.find_element(:id, "end_date").send_keys to
123
+
124
+ @driver.find_element(:link, "Update Report").click
125
+ @driver.find_element(:link, "Detailed Report").click
126
+ @driver.find_elements(:tag_name => 'option').find{|i| i.text == 'Task'}.click
127
+
128
+ puts "Print as PDF. Filename:\n#{pdf_name}"
129
+ pbcopy pdf_name
130
+ @driver.execute_script('window.print()')
131
+ @driver.find_element(:xpath, "//nav[@id='nav']/div/ul/li[4]/a").click
132
+ @driver.find_element(:link, "Sign Out").click
133
+ @driver.quit
134
+ puts "Email your PDF."
135
+ puts "Subject:\n#{subject}"
136
+ puts "Body:\n#{body}"
137
+ pbcopy "#{subject}\n#{body}"
138
+ rescue Exception => ex
139
+ "There was a problem!\n#{ex.backtrace}\n\n#{ex.message}\nExit!"
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,3 @@
1
+ module HarvestWheelman
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,5 @@
1
+ require "harvest_wheelman/version"
2
+ require 'harvest_submit'
3
+
4
+ module HarvestWheelman
5
+ end
metadata ADDED
@@ -0,0 +1,140 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: harvest_wheelman
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Keyvan Fatehi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-05-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: selenium-webdriver
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 2.31.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: 2.31.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: timerizer
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: json
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Logs into Harvest and generates a PDF report the way my company likes
98
+ it
99
+ email:
100
+ - keyvanfatehi@gmail.com
101
+ executables:
102
+ - harvest_wheelman
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - .gitignore
107
+ - Gemfile
108
+ - LICENSE.txt
109
+ - README.md
110
+ - Rakefile
111
+ - bin/harvest_wheelman
112
+ - harvest_wheelman.gemspec
113
+ - lib/harvest_submit.rb
114
+ - lib/harvest_wheelman.rb
115
+ - lib/harvest_wheelman/version.rb
116
+ homepage: ''
117
+ licenses:
118
+ - MIT
119
+ metadata: {}
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements: []
135
+ rubyforge_project:
136
+ rubygems_version: 2.0.3
137
+ signing_key:
138
+ specification_version: 4
139
+ summary: Logs into Harvest and generates a PDF report
140
+ test_files: []