ghours 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ == 0.0.1 2009-05-17
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
5
+
@@ -0,0 +1,15 @@
1
+ bin/ghours
2
+ History.txt
3
+ Manifest.txt
4
+ README.rdoc
5
+ Rakefile
6
+ lib/ghours.rb
7
+ lib/ghours/stuff.rb
8
+ script/console
9
+ script/destroy
10
+ script/generate
11
+ spec/ghours_spec.rb
12
+ spec/spec.opts
13
+ spec/spec_helper.rb
14
+ tasks/rspec.rake
15
+
@@ -0,0 +1,62 @@
1
+ = ghours
2
+
3
+ Simple ruby application which enables you to count hours in google calendar
4
+ events this month and week. (http://github.com/kazjote/GHours/tree/master)
5
+
6
+ == DESCRIPTION:
7
+
8
+ Simple ruby application which enables you to count hours in google calendar
9
+ events this month and week.
10
+
11
+ It sums all hours spent by events.
12
+
13
+ It stores your email used to sign in to google in $HOME/.ghours. If you want
14
+ to change this email simply delete this file.
15
+
16
+ == SYNOPSIS:
17
+
18
+ USAGE:
19
+ $ ghours Robota my_calendar
20
+
21
+ after password prompt it prints following output:
22
+
23
+ In this week : 4.0
24
+ month: 28.0
25
+
26
+ That's all... It is really simple ;)
27
+
28
+ == REQUIREMENTS:
29
+
30
+ * activesupport (>=2.0.2)
31
+ * highline (>=1.4.0)
32
+ * googlecalendar (>=1.1.0)
33
+
34
+ == INSTALL:
35
+
36
+ $ sudo gem install ghours
37
+
38
+ == LICENSE:
39
+
40
+ (The MIT License)
41
+
42
+ Copyright (c) 2009 FIXME full name
43
+
44
+ Permission is hereby granted, free of charge, to any person obtaining
45
+ a copy of this software and associated documentation files (the
46
+ 'Software'), to deal in the Software without restriction, including
47
+ without limitation the rights to use, copy, modify, merge, publish,
48
+ distribute, sublicense, and/or sell copies of the Software, and to
49
+ permit persons to whom the Software is furnished to do so, subject to
50
+ the following conditions:
51
+
52
+ The above copyright notice and this permission notice shall be
53
+ included in all copies or substantial portions of the Software.
54
+
55
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
56
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
57
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
58
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
59
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
60
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
61
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
62
+
@@ -0,0 +1,30 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/ghours'
3
+
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('ghours', GHours::VERSION) do |p|
7
+ p.developer('Kacper Bielecki', 'kazjote@gmail.com')
8
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
+ p.rubyforge_name = p.name # TODO this is default value
10
+ p.extra_deps = [
11
+ ['activesupport','>= 2.0.2'],
12
+ ['highline', '>= 1.4.0'],
13
+ ['googlecalendar', '>=1.1.0']
14
+ ]
15
+ p.extra_dev_deps = [
16
+ ['newgem', ">= #{::Newgem::VERSION}"]
17
+ ]
18
+
19
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
20
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
21
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
22
+ p.rsync_args = '-av --delete --ignore-errors'
23
+ end
24
+
25
+ require 'newgem/tasks' # load /tasks/*.rake
26
+ Dir['tasks/**/*.rake'].each { |t| load t }
27
+
28
+ # TODO - want other tests/tasks run by default? Add them to the list
29
+ # task :default => [:spec, :features]
30
+
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + File.join("/../lib/ghours"))
4
+
5
+ GHours.process(ARGV)
6
+
@@ -0,0 +1,47 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require "ghours/stuff"
5
+
6
+ require 'rubygems'
7
+ require 'googlecalendar'
8
+ require 'activesupport'
9
+ require 'rexml/document'
10
+
11
+ module GHours
12
+ VERSION = '0.0.1'
13
+
14
+ def self.process(argv)
15
+ if(argv.empty?)
16
+ raise ExitReason.new("USAGE: ghours <calendar_name>")
17
+ end
18
+
19
+ config = Configuration.new
20
+ config.init_new unless config.found?
21
+
22
+ email, pass = config.credentials
23
+
24
+ connection = Connection.new(email, pass)
25
+ in_week, in_month = count_hours(connection.events(argv[0]))
26
+ UI.print_hours(in_week, in_month)
27
+ rescue GHours::ExitReason => ex
28
+ puts ex.message
29
+ exit 1
30
+ end
31
+
32
+ def self.count_hours events
33
+ doc = REXML::Document.new(events)
34
+
35
+ done = Hash.new(0.0)
36
+ doc.elements.each("*/entry/gd:when") do |time_elem|
37
+ diff = (start = time_elem.attributes["endTime"].to_time) -
38
+ time_elem.attributes["startTime"].to_time
39
+ diff = diff / 60.0 / 60.0
40
+ done[:week] += diff if start.this_week?
41
+ done[:month] += diff
42
+ end
43
+
44
+ [done[:week], done[:month]]
45
+ end
46
+ end
47
+
@@ -0,0 +1,103 @@
1
+ require 'net/http'
2
+
3
+ require 'rubygems'
4
+ require 'highline/import'
5
+ require 'activesupport'
6
+
7
+ class String
8
+ def to_time
9
+ matches = /([\d]{4})-([\d]{2})-([\d]{2})T([\d]{2}):([\d]{2}):([\d]{2}).*/.match(to_s)
10
+ Time.mktime(*matches[1..6])
11
+ end
12
+ end
13
+
14
+ class Time
15
+ def this_week?
16
+ self > Time.now.monday
17
+ end
18
+ end
19
+
20
+ module Net
21
+ class HTTP
22
+ def fetch(path, headers, limit = 10)
23
+ # You should choose better exception.
24
+ raise ArgumentError, 'HTTP redirect too deep' if limit == 0
25
+
26
+ response, body = get(path, headers)
27
+ case response
28
+ when Net::HTTPSuccess
29
+ body
30
+ when Net::HTTPRedirection
31
+ fetch(response['location'], headers, limit - 1)
32
+ else
33
+ response.error!
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+
40
+ module GHours
41
+
42
+ class ExitReason < Exception
43
+ end
44
+
45
+ class Configuration
46
+
47
+ def found?
48
+ File.exists?(config_path)
49
+ end
50
+
51
+ def init_new
52
+ file = File.new(config_path, "w")
53
+ file.write(UI.ask_for_email)
54
+ file.close
55
+ end
56
+
57
+ def credentials
58
+ file = File.new(config_path, "r")
59
+ [file.readlines.first, UI.password]
60
+ end
61
+
62
+ def config_path
63
+ File.join(ENV["HOME"], ".ghours")
64
+ end
65
+
66
+ end
67
+
68
+ class Connection
69
+
70
+ def initialize(email, pass)
71
+ @gdata = Googlecalendar::GData.new
72
+ @token = @gdata.login(email, pass)
73
+ end
74
+
75
+ def events calendar_name
76
+ @gdata.get_calendars
77
+ headers = {"Authorization" => "GoogleLogin auth=#{@token}"}
78
+ calendar = @gdata.find_calendar(calendar_name)
79
+ raise ExitReason.new("Calendar not found :(") unless calendar
80
+
81
+ time_format = "%Y-%m-%dT00:00:00"
82
+ query = ["start-min=", Time.now.utc.beginning_of_month.strftime(time_format)].join
83
+ Net::HTTP.new("www.google.com").fetch([calendar.url, query].join("?"), headers)
84
+ end
85
+
86
+ end
87
+
88
+ module UI
89
+ def self.print_hours(in_week, in_month)
90
+ puts "In this week : #{in_week}"
91
+ puts " month: #{in_month}"
92
+ end
93
+
94
+ def self.ask_for_email
95
+ ask("Enter your email address used to login to your calendar:")
96
+ end
97
+
98
+ def self.password
99
+ ask("Enter your password:") { |q| q.echo = false }
100
+ end
101
+ end
102
+ end
103
+
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/ghours.rb'}"
9
+ puts "Loading ghours gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,69 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe "GHours" do
4
+
5
+ it "should throw usage info when no arguments" do
6
+ lambda { GHours.process([]) }.should raise_error(SystemExit)
7
+ end
8
+
9
+ describe "when properly invoked" do
10
+
11
+ before do
12
+ @config = mock("config")
13
+ GHours::Configuration.should_receive(:new).and_return(@config)
14
+ @connection = mock("connection")
15
+ @connection.stub!(:events)
16
+ GHours::Connection.stub!(:new).and_return(@connection)
17
+ end
18
+
19
+ it "should init new configuration when one not found" do
20
+ @config.should_receive(:found?).and_return(false)
21
+ @config.should_receive(:init_new)
22
+
23
+ @config.stub!(:credentials)
24
+
25
+ GHours.process ["blah"]
26
+ end
27
+
28
+ it "should create connection with received credentials" do
29
+ @config.stub!(:found?)
30
+ @config.stub!(:init_new)
31
+ @config.should_receive(:credentials).and_return(["gosia@example.com", "gosia_pass"])
32
+ GHours::Connection.should_receive(:new).with("gosia@example.com", "gosia_pass")
33
+
34
+ GHours.process ["blah"]
35
+ end
36
+ end
37
+
38
+ describe "Connection" do
39
+
40
+ before do
41
+ @gdata = mock("gdata")
42
+ Googlecalendar::GData.should_receive(:new).and_return(@gdata)
43
+ end
44
+
45
+ it "should login when initialized" do
46
+ @gdata.should_receive(:login).with("tom@example.com", "secret")
47
+ GHours::Connection.new("tom@example.com", "secret")
48
+ end
49
+
50
+ describe "while successfully logged in " do
51
+ before do
52
+ @gdata.stub!(:login)
53
+ @gdata.stub!(:get_calendars)
54
+ @connection = GHours::Connection.new("tom@example.com", "secret")
55
+ end
56
+
57
+ it "should throw exception when calendar not found" do
58
+ @gdata.should_receive(:find_calendar).with("calendar_name").and_return(nil)
59
+
60
+ lambda { @connection.events("calendar_name") }.should raise_error(GHours::ExitReason)
61
+ end
62
+ end
63
+ end
64
+
65
+ describe "Configuration" do
66
+ end
67
+
68
+ end
69
+
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,12 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
10
+
11
+ require 'ghours'
12
+
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'spec'
6
+ end
7
+ begin
8
+ require 'spec/rake/spectask'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ desc "Run the specs under spec/models"
18
+ Spec::Rake::SpecTask.new do |t|
19
+ t.spec_opts = ['--options', "spec/spec.opts"]
20
+ t.spec_files = FileList['spec/**/*_spec.rb']
21
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ghours
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Kacper Bielecki
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-18 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.0.2
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: highline
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.4.0
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: googlecalendar
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.1.0
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: newgem
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.2.3
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: hoe
57
+ type: :development
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 1.8.0
64
+ version:
65
+ description: Simple ruby application which enables you to count hours in google calendar events this month and week. It sums all hours spent by events. It stores your email used to sign in to google in $HOME/.ghours. If you want to change this email simply delete this file.
66
+ email:
67
+ - kazjote@gmail.com
68
+ executables:
69
+ - ghours
70
+ extensions: []
71
+
72
+ extra_rdoc_files:
73
+ - History.txt
74
+ - Manifest.txt
75
+ - README.rdoc
76
+ files:
77
+ - bin/ghours
78
+ - History.txt
79
+ - Manifest.txt
80
+ - README.rdoc
81
+ - Rakefile
82
+ - lib/ghours.rb
83
+ - lib/ghours/stuff.rb
84
+ - script/console
85
+ - script/destroy
86
+ - script/generate
87
+ - spec/ghours_spec.rb
88
+ - spec/spec.opts
89
+ - spec/spec_helper.rb
90
+ - tasks/rspec.rake
91
+ has_rdoc: true
92
+ homepage: Simple ruby application which enables you to count hours in google calendar
93
+ post_install_message:
94
+ rdoc_options:
95
+ - --main
96
+ - README.rdoc
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: "0"
104
+ version:
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: "0"
110
+ version:
111
+ requirements: []
112
+
113
+ rubyforge_project: ghours
114
+ rubygems_version: 1.3.1
115
+ signing_key:
116
+ specification_version: 2
117
+ summary: Simple ruby application which enables you to count hours in google calendar events this month and week
118
+ test_files: []
119
+