time_tracker 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.DS_Store ADDED
Binary file
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *.pdf
6
+ config.json
data/.rvmrc ADDED
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
7
+ environment_id="ruby-1.9.2-p180@time_tracker"
8
+
9
+ #
10
+ # First we attempt to load the desired environment directly from the environment
11
+ # file. This is very fast and efficicent compared to running through the entire
12
+ # CLI and selector. If you want feedback on which environment was used then
13
+ # insert the word 'use' after --create as this triggers verbose mode.
14
+ #
15
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
16
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]] ; then
17
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
18
+ else
19
+ # If the environment file has not yet been created, use the RVM CLI to select.
20
+ rvm --create "$environment_id"
21
+ fi
22
+
23
+ #
24
+ # If you use an RVM gemset file to install a list of gems (*.gems), you can have
25
+ # it be automatically loaded. Uncomment the following and adjust the filename if
26
+ # necessary.
27
+ #
28
+ # filename=".gems"
29
+ # if [[ -s "$filename" ]] ; then
30
+ # rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
31
+ # fi
32
+
33
+ #
34
+ # If you use bundler and would like to run bundle each time you enter the
35
+ # directory, you can uncomment the following code.
36
+ #
37
+ # # Ensure that Bundler is installed. Install it if it is not.
38
+ # if ! command -v bundle >/dev/null; then
39
+ # printf "The rubygem 'bundler' is not installed. Installing it now.\n"
40
+ # gem install bundler
41
+ # fi
42
+ #
43
+ # # Bundle while reducing excess noise.
44
+ # printf "Bundling your gems. This may take a few minutes on a fresh clone.\n"
45
+ # bundle | grep -v '^Using ' | grep -v ' is complete' | sed '/^$/d'
46
+ #
47
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in time_tracker.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/Readme.md ADDED
@@ -0,0 +1,71 @@
1
+
2
+ # TimeTracker
3
+ ## About
4
+ In some companies you need to track your working time with the help of excel. For that purpose you have to create sheets and put each entry into the file by hand. TimeTracker.rb
5
+ simplifies this workflow by adding your working time into a public iCal feed after calling timetracker a PDF for each month wil be generated. The configuration is very easy with the
6
+ help of a JSON file.
7
+
8
+ # Installation & Running
9
+ TimeTracker is tested with Ruby 1.9.2, simply install it by calling:
10
+ gem install timetracker.rb
11
+
12
+ Goto the directory where you want to create your sheets and create a config file. TimeTracker is highly configurable because of localization issues, different working times etc.
13
+
14
+ {
15
+ "url" : "your url",
16
+
17
+ "name" : "Your Name",
18
+ "department" : "Your Department",
19
+ "year" : 2011,
20
+ "offset" : 0,
21
+
22
+ "working_time" : {
23
+ "january" : 160,
24
+ "february" : 120,
25
+ "march" : 0,
26
+ "april" : 0,
27
+ "may" : 50,
28
+ "june" : 70,
29
+ "july" : 50,
30
+ "august" : 90,
31
+ "september" : 160,
32
+ "october" : 120,
33
+ "november" : 100,
34
+ "december" : 1ß
35
+ },
36
+
37
+ "time_sheet" : {
38
+ "title" : "Zeiterfassungsbogen",
39
+
40
+ "name" : "name",
41
+ "month" : "Monat",
42
+ "monthly_working_time" : "monatliche Arbeitszeit",
43
+ "department" : "Abteilung",
44
+ "date" : "Datum",
45
+ "begin" : "Begin",
46
+ "end" : "Ende",
47
+ "description" : "Beschreibung",
48
+ "hours_without_break" : "Stunden ohne Pause",
49
+ "break_time" : "Pausenzeit",
50
+ "sum" : "Summe",
51
+ "carry" : "Übertrag",
52
+ "correctness" : "Für die Richtigkeit der Eintragung",
53
+ "signature" : "Zur Kenntniss genommen",
54
+
55
+ "January" : "Januar",
56
+ "February" : "February",
57
+ "March" : "März",
58
+ "April" : "April",
59
+ "May" : "Mai",
60
+ "June" : "Juni",
61
+ "July" : "Juli",
62
+ "August" : "Augut",
63
+ "September" : "September",
64
+ "October" : "Oktober",
65
+ "November" : "November",
66
+ "December" : "Dezember"
67
+ }
68
+ }
69
+
70
+ ## Contributions
71
+ Please contribute!
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'time_tracker'
4
+
5
+ tracker = TimeTracker::Creator.new
6
+ tracker.start_tracking
@@ -0,0 +1,55 @@
1
+ {
2
+ "url" : "your url",
3
+
4
+ "name" : "Your Name",
5
+ "department" : "Your Department",
6
+ "year" : 2011,
7
+ "offset" : 0,
8
+
9
+ "working_time" : {
10
+ "january" : 160,
11
+ "february" : 120,
12
+ "march" : 0,
13
+ "april" : 0,
14
+ "may" : 50,
15
+ "june" : 70,
16
+ "july" : 50,
17
+ "august" : 90,
18
+ "september" : 160,
19
+ "october" : 120,
20
+ "november" : 100,
21
+ "december" : 1ß
22
+ },
23
+
24
+ "time_sheet" : {
25
+ "title" : "Zeiterfassungsbogen",
26
+
27
+ "name" : "name",
28
+ "month" : "Monat",
29
+ "monthly_working_time" : "monatliche Arbeitszeit",
30
+ "department" : "Abteilung",
31
+ "date" : "Datum",
32
+ "begin" : "Begin",
33
+ "end" : "Ende",
34
+ "description" : "Beschreibung",
35
+ "hours_without_break" : "Stunden ohne Pause",
36
+ "break_time" : "Pausenzeit",
37
+ "sum" : "Summe",
38
+ "carry" : "Übertrag",
39
+ "correctness" : "Für die Richtigkeit der Eintragung",
40
+ "signature" : "Zur Kenntniss genommen",
41
+
42
+ "January" : "Januar",
43
+ "February" : "February",
44
+ "March" : "März",
45
+ "April" : "April",
46
+ "May" : "Mai",
47
+ "June" : "Juni",
48
+ "July" : "Juli",
49
+ "August" : "Augut",
50
+ "September" : "September",
51
+ "October" : "Oktober",
52
+ "November" : "November",
53
+ "December" : "Dezember"
54
+ }
55
+ }
@@ -0,0 +1,3 @@
1
+ module TimeTracker
2
+ VERSION = "0.1"
3
+ end
@@ -0,0 +1,247 @@
1
+ require "time_tracker/version"
2
+
3
+
4
+ require 'iCalendar'
5
+ require 'date'
6
+ require 'prawn'
7
+ require 'json'
8
+ require 'httpclient'
9
+
10
+ module TimeTracker
11
+
12
+
13
+ class TimeTracker::Month
14
+
15
+ attr_reader :monthly_working_time, :entries
16
+ # offset means +/- hours within this month
17
+ # global_offset within the whole year as a sum
18
+ attr_accessor :offset, :global_offset, :fixed_monthly_working_time
19
+
20
+ def initialize
21
+ @entries = Array.new
22
+ #@fixed_monthly_working_time
23
+ end
24
+
25
+ def add_event event
26
+ @entries.push(Entry.new(event))
27
+ end
28
+
29
+ def sort_entries!
30
+ @entries.sort! { |a,b| a.start_time <=> b.start_time }
31
+ end
32
+
33
+ def calulate_working_time
34
+ @monthly_working_time = 0
35
+ @entries.each do |entry|
36
+ @monthly_working_time += entry.duration
37
+ end
38
+ @offset = @monthly_working_time - @fixed_monthly_working_time
39
+ @global_offset += @offset
40
+ end
41
+
42
+ def to_s
43
+ entries = "Entries: \n"
44
+ @entries.each do |entry|
45
+ entries += "#{entry} \n"
46
+ end
47
+ entries
48
+ end
49
+
50
+ private
51
+ def add_entry entry
52
+ @entries.push entry
53
+ end
54
+
55
+ end
56
+
57
+ class TimeTracker::Entry
58
+ attr_accessor :start_time, :end_time, :summary, :duration
59
+ attr_reader :break_time
60
+
61
+ def initialize event
62
+ @start_time = event.dtstart
63
+ @end_time = event.dtend
64
+ @summary = event.summary
65
+ @duration = calculate_duration
66
+ end
67
+
68
+ private
69
+ def calculate_duration
70
+ # duration in hours
71
+ duration = (@end_time.hour - @start_time.hour).to_f
72
+
73
+ # break_one
74
+ if duration >= 6 then
75
+ duration -= 0.5
76
+ @break_time = 0.5
77
+ # break_two
78
+ elsif duration >= 9 then
79
+ duration -= 0.75
80
+ @break_time = 0.75
81
+ else
82
+ @break_time = 0
83
+ end
84
+ duration
85
+ end
86
+
87
+
88
+ # just for debugging
89
+ def to_s
90
+ "start: #{@start_time}, end: #{@end_time}, summary: #{@summary}"
91
+ end
92
+
93
+ end
94
+
95
+ class TimeTracker::TimeSheet
96
+ def initialize month, config
97
+ @month = month
98
+ @config = config
99
+ end
100
+
101
+ def print
102
+ # you worked this month
103
+ if @month.entries.length > 0 then
104
+ # get localized month name
105
+ config = @config
106
+ temp_name = @month.entries[0].start_time.strftime("%B")
107
+ month_name = config["time_sheet"][temp_name]
108
+ # why namespace clashing here?
109
+ entries = @month.entries
110
+ month = @month
111
+ Prawn::Document.generate("#{month_name}.pdf") do
112
+ #heading
113
+ font_size 16
114
+ text "#{config["time_sheet"]["title"]}", :style => :bold, :align => :center
115
+ font_size 12
116
+ move_down 5
117
+ text "#{config["time_sheet"]["name"]}: #{config["name"]}"
118
+ text "#{config["time_sheet"]["month"]}: #{month_name}"
119
+ text "#{config["time_sheet"]["monthly_working_time"]}: #{month.fixed_monthly_working_time}"
120
+ text "#{config["time_sheet"]["department"]}: #{config["department"]}"
121
+ table_data = Array.new
122
+ # fill table header
123
+ table_data.push [#{config["time_sheet"]["date"]},
124
+ #{config["time_sheet"]["begin"]},
125
+ #{config["time_sheet"]["end"]},
126
+ #{config["time_sheet"]["description"]},
127
+ #{config["time_sheet"]["hours_without_break"]},
128
+ #{config["time_sheet"]["break_time"]}
129
+ ]
130
+
131
+ entries.each do |entry|
132
+ row_data = Array.new
133
+ row_data.push "#{entry.start_time.strftime("%d")}."
134
+ row_data.push "#{entry.start_time.strftime("%H")}:#{entry.start_time.strftime("%M")}"
135
+ row_data.push "#{entry.end_time.strftime("%H")}:#{entry.end_time.strftime("%M")}"
136
+ row_data.push entry.summary
137
+ row_data.push entry.duration
138
+ row_data.push entry.break_time
139
+ table_data.push row_data
140
+ end
141
+ move_down 5
142
+ table table_data
143
+ move_down 5
144
+ text "#{config["time_sheet"]["sum"]}: #{month.monthly_working_time}"
145
+ move_down 5
146
+ text "#{config["time_sheet"]["carry"]}: #{month.global_offset}"
147
+ move_down 50
148
+ text "__________________________"
149
+ text "#{config["time_sheet"]["correctness"]}"
150
+ move_down 50
151
+ text "__________________________"
152
+ text "#{config["time_sheet"]["signature"]}"
153
+ end
154
+ end
155
+ end
156
+
157
+ end
158
+
159
+ class TimeTracker::Creator
160
+
161
+ def initialize
162
+
163
+ # configuration stuff
164
+ begin
165
+ config_file = File.read "config.json"
166
+ rescue
167
+ puts "Can't read configuration file"
168
+ end
169
+ @config = JSON.parse config_file
170
+
171
+ # Open a file or pass a string to the parser
172
+ client = HTTPClient.new
173
+ cal_file = client.get_content @config["url"]
174
+
175
+ # Parser returns an array of calendars because a single file
176
+ # can have multiple calendars.
177
+ cals = Icalendar.parse cal_file
178
+ cal = cals.first
179
+
180
+ # initialize months, yep 1 to 13 cause we can use month 1..12
181
+ # a little bit unclean but the use is more intuitive
182
+ @months = Array.new
183
+ 13.times do
184
+ @months.push Month.new
185
+ end
186
+
187
+
188
+ # sort each event into the right month
189
+ cal.events.each do |event|
190
+ if event.start.year == @config["year"] then
191
+ @months[event.start.month].add_event event
192
+ end
193
+ end
194
+ end
195
+
196
+ def index_to_month i
197
+ result = ""
198
+ case i
199
+ when 1
200
+ result = "january"
201
+ when 2
202
+ result = "february"
203
+ when 3
204
+ result = "march"
205
+ when 4
206
+ result = "april"
207
+ when 5
208
+ result = "may"
209
+ when 6
210
+ result = "june"
211
+ when 7
212
+ result = "july"
213
+ when 8
214
+ result = "august"
215
+ when 9
216
+ result = "september"
217
+ when 10
218
+ result = "october"
219
+ when 11
220
+ result = "november"
221
+ when 12
222
+ result = "december"
223
+ else
224
+ result = "error"
225
+ end
226
+ result
227
+ end
228
+
229
+ def start_tracking
230
+ # sort events within the month and calculate +/- hours
231
+ temp_offset = @config["offset"];
232
+ config = @config
233
+ @months.each_with_index do |month, i|
234
+ if i > 0 then
235
+ month.sort_entries!
236
+ month.global_offset = temp_offset
237
+ # reading monthly working time with some dirty conversion for a more beautiful configuration file
238
+ month.fixed_monthly_working_time = @config["working_time"][(index_to_month i)]
239
+ month.calulate_working_time # monthly_working_time
240
+ temp_offset = month.global_offset
241
+ sheet = TimeSheet.new month, config
242
+ sheet.print
243
+ end
244
+ end
245
+ end
246
+ end
247
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "time_tracker/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "time_tracker"
7
+ s.version = TimeTracker::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Horst Mumpitz"]
10
+ s.email = ["d-staar@gmx.de"]
11
+ s.homepage = ""
12
+ s.summary = "Create time sheets with the help of a public iCal file"
13
+ s.description = "In some companies you need to track your working time with the help of excel. For that purpose you have to create sheets and put each entry into the file by hand. TimeTracker.rb
14
+ simplifies this workflow by adding your working time into a public iCal feed after calling timetracker a PDF for each month wil be generated. The configuration is very easy with the
15
+ help of a JSON file."
16
+
17
+ s.rubyforge_project = "time_tracker"
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+
24
+ s.add_runtime_dependency "icalendar"
25
+ s.add_runtime_dependency "prawn"
26
+ s.add_runtime_dependency "json"
27
+ s.add_runtime_dependency "httpclient"
28
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: time_tracker
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Horst Mumpitz
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-30 00:00:00.000000000 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: icalendar
17
+ requirement: &2156794660 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *2156794660
26
+ - !ruby/object:Gem::Dependency
27
+ name: prawn
28
+ requirement: &2156794240 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *2156794240
37
+ - !ruby/object:Gem::Dependency
38
+ name: json
39
+ requirement: &2156793820 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *2156793820
48
+ - !ruby/object:Gem::Dependency
49
+ name: httpclient
50
+ requirement: &2156793400 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *2156793400
59
+ description: ! "In some companies you need to track your working time with the help
60
+ of excel. For that purpose you have to create sheets and put each entry into the
61
+ file by hand. TimeTracker.rb \n \t\t\t\t\t\t\t\t simplifies this workflow by adding
62
+ your working time into a public iCal feed after calling timetracker a PDF for each
63
+ month wil be generated. The configuration is very easy with the\n \t\t\t\t\t\t\t\t
64
+ help of a JSON file."
65
+ email:
66
+ - d-staar@gmx.de
67
+ executables:
68
+ - timetracker.rb
69
+ extensions: []
70
+ extra_rdoc_files: []
71
+ files:
72
+ - .DS_Store
73
+ - .gitignore
74
+ - .rvmrc
75
+ - Gemfile
76
+ - Rakefile
77
+ - Readme.md
78
+ - bin/timetracker.rb
79
+ - example_config.json
80
+ - lib/time_tracker.rb
81
+ - lib/time_tracker/version.rb
82
+ - time_tracker.gemspec
83
+ has_rdoc: true
84
+ homepage: ''
85
+ licenses: []
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project: time_tracker
104
+ rubygems_version: 1.5.2
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: Create time sheets with the help of a public iCal file
108
+ test_files: []