ruby-rescuetime 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.
Files changed (51) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +16 -0
  3. data/Rakefile +37 -0
  4. data/bin/ruby-rescuetime +6 -0
  5. data/lib/rescuetime.rb +16 -0
  6. data/lib/rescuetime/application.rb +152 -0
  7. data/lib/rescuetime/commands.rb +50 -0
  8. data/lib/rescuetime/config.rb +83 -0
  9. data/lib/rescuetime/debug.rb +18 -0
  10. data/lib/rescuetime/extension.rb +29 -0
  11. data/lib/rescuetime/extensions/chromium.rb +32 -0
  12. data/lib/rescuetime/extensions/gedit.rb +13 -0
  13. data/lib/rescuetime/loop.rb +97 -0
  14. data/lib/rescuetime/uploader.rb +79 -0
  15. data/lib/rescuetime/version.rb +3 -0
  16. data/lib/tasks/ruby-rescuetime_tasks.rake +4 -0
  17. data/test/application_test.rb +12 -0
  18. data/test/dummy/Rakefile +7 -0
  19. data/test/dummy/app/assets/javascripts/application.js +9 -0
  20. data/test/dummy/app/assets/stylesheets/application.css +7 -0
  21. data/test/dummy/app/controllers/application_controller.rb +3 -0
  22. data/test/dummy/app/helpers/application_helper.rb +2 -0
  23. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  24. data/test/dummy/config.ru +4 -0
  25. data/test/dummy/config/application.rb +45 -0
  26. data/test/dummy/config/boot.rb +10 -0
  27. data/test/dummy/config/database.yml +25 -0
  28. data/test/dummy/config/environment.rb +5 -0
  29. data/test/dummy/config/environments/development.rb +30 -0
  30. data/test/dummy/config/environments/production.rb +60 -0
  31. data/test/dummy/config/environments/test.rb +39 -0
  32. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  33. data/test/dummy/config/initializers/inflections.rb +10 -0
  34. data/test/dummy/config/initializers/mime_types.rb +5 -0
  35. data/test/dummy/config/initializers/secret_token.rb +7 -0
  36. data/test/dummy/config/initializers/session_store.rb +8 -0
  37. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  38. data/test/dummy/config/locales/en.yml +5 -0
  39. data/test/dummy/config/routes.rb +58 -0
  40. data/test/dummy/db/test.sqlite3 +0 -0
  41. data/test/dummy/log/development.log +0 -0
  42. data/test/dummy/log/test.log +0 -0
  43. data/test/dummy/public/404.html +26 -0
  44. data/test/dummy/public/422.html +26 -0
  45. data/test/dummy/public/500.html +26 -0
  46. data/test/dummy/public/favicon.ico +0 -0
  47. data/test/dummy/script/rails +6 -0
  48. data/test/loop_test.rb +16 -0
  49. data/test/rescuetime_test.rb +8 -0
  50. data/test/test_helper.rb +10 -0
  51. metadata +180 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,16 @@
1
+ = RubyRescuetime
2
+
3
+ == Ruby port of: https://launchpad.net/rescuetime-linux-uploader
4
+ So, it's basically a inofficial uploader for:
5
+ https://www.rescuetime.com/
6
+
7
+ _It's probably running only on Ubuntu machines. (Feel free to test)_
8
+
9
+ == Installation:
10
+ gem install ruby-rescuetime
11
+
12
+ == Usage:
13
+ ruby-rescuetime --help
14
+
15
+ This project rocks and uses MIT-LICENSE.
16
+
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'RubyRescuetime'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+
24
+
25
+ Bundler::GemHelper.install_tasks
26
+
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'lib'
31
+ t.libs << 'test'
32
+ t.pattern = 'test/**/*_test.rb'
33
+ t.verbose = false
34
+ end
35
+
36
+
37
+ task :default => :test
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # TODO: description
4
+
5
+ require 'rescuetime/commands'
6
+
data/lib/rescuetime.rb ADDED
@@ -0,0 +1,16 @@
1
+ module Rescuetime
2
+ require 'rescuetime/debug'
3
+ require 'rescuetime/extension'
4
+
5
+ require 'rescuetime/application'
6
+ require 'rescuetime/config'
7
+ require 'rescuetime/loop'
8
+ require 'rescuetime/uploader'
9
+
10
+ # Load Extensions
11
+ Dir["#{File.dirname(__FILE__)}/rescuetime/extensions/**/*.rb"].each { |f| require f }
12
+
13
+ # Load Extensions defined in users home directory
14
+ Dir["#{Dir.home}/.ruby-rescuetime/extensions/**/*.rb"].each { |f| require f }
15
+ end
16
+
@@ -0,0 +1,152 @@
1
+ module Rescuetime
2
+ class Application
3
+ include Rescuetime::Debug
4
+
5
+ def self.current_application_name
6
+ cmd = <<-CMD
7
+ xprop -id `xprop -root |
8
+ awk '/_NET_ACTIVE_WINDOW/ {print $5; exit;}'` |
9
+ awk -F = '/WM_CLASS/ {print $2; exit;}'|
10
+ awk '{print $2}' |
11
+ sed 's/^"//g' |
12
+ sed 's/"$//g'
13
+ CMD
14
+ `#{cmd}`.strip
15
+ end
16
+
17
+ def self.current_window_title
18
+ cmd = <<-CMD
19
+ xprop -id `xprop -root |
20
+ awk '/_NET_ACTIVE_WINDOW/ {print $5; exit;}'` |
21
+ awk -F = '/^WM_NAME/ {print $2; exit;}' |
22
+ sed -e's/^ *"//g' |
23
+ sed -e's/\\"$//g'
24
+ CMD
25
+ `#{cmd}`.strip
26
+ end
27
+
28
+ attr_reader :name, :title, :created_at, :finished_at
29
+ #protected_class_method :new
30
+
31
+ # TODO
32
+ def self.create(options = {})
33
+ name = options[:name] || self.current_application_name
34
+ klass = Rescuetime::Extension.get(name) || self
35
+ klass.new(options)
36
+ end
37
+
38
+
39
+
40
+ # Constructor: Call with {:debug => true} to get debug messages
41
+ def initialize(options = {})
42
+ @debug = options[:debug]
43
+ @name = options[:name] || current_application_name
44
+ @title = options[:title] || current_window_title
45
+
46
+ @created_at = Time.now
47
+ @finished_at = nil
48
+ @active = true
49
+ end
50
+
51
+ def name
52
+ @name.gsub("\000", "").gsub("'", "`")
53
+ end
54
+
55
+ def title
56
+ @title.gsub("\000", "").gsub("'", "`")
57
+ end
58
+
59
+ # Returns: Time of where app where detected to not be active anymore, or
60
+ # Time now if not finished yet
61
+ def finished_at
62
+ (@finished_at || Time.now).to_s[0..-7] # HACK: to remove offset (e.g. + 01:00)
63
+ end
64
+
65
+ def created_at
66
+ (@created_at || Time.now).to_s[0..-7] # HACK: to remove offset (e.g. + 01:00)
67
+ end
68
+
69
+ # Returns: boolean, if application is still active window
70
+ def active?
71
+ return @active unless @active
72
+
73
+ @active = @name == current_application_name &&
74
+ @title == current_window_title
75
+ finish! unless @active
76
+
77
+ return @active
78
+ end
79
+
80
+ def finished?
81
+ !active?
82
+ end
83
+
84
+ # Returns difference between StartTime and now if still active, or
85
+ # StartTime and FinishedTime if not ative anymore
86
+ def active_time
87
+ (active?) ? (Time.now - @created_at) : (@finished_at - @created_at)
88
+ end
89
+
90
+ def to_s
91
+ "#{name}:#{title}:#{extended_info}"
92
+ end
93
+
94
+ def extended_info
95
+ (@extended_info || "").gsub("\000", "").gsub("'", "`")
96
+ end
97
+
98
+ def os_username
99
+ @os_username ||= `uname -n`.strip + "\\" + `id -un`.strip
100
+ end
101
+
102
+ # TODO
103
+ def to_upload_data
104
+ return "" if name.empty?
105
+
106
+ out = "- os_username: '#{os_username}'\n"
107
+ out += " app_name: '#{name}'\n"
108
+ out += " window_title: '#{title}'\n"
109
+ out += " extended_info: '#{extended_info}'\n"
110
+ out += " start_time: #{created_at}\n"
111
+ out += " end_time: #{finished_at}\n"
112
+
113
+ return out
114
+ end
115
+
116
+
117
+
118
+ private
119
+ def finish!
120
+ @active = false
121
+ @finished_at = Time.now
122
+ end
123
+
124
+ def current_application_name
125
+ application_name(self.class.current_application_name)
126
+ end
127
+
128
+ def current_window_title
129
+ window_title(self.class.current_window_title)
130
+ end
131
+
132
+ # To be overwritten
133
+ def application_name(name)
134
+ name
135
+ end
136
+
137
+ # To be overwritten
138
+ def window_title(title)
139
+ title
140
+ end
141
+ end
142
+ end
143
+
144
+
145
+
146
+ #- os_username: 'werbeboten-HP-Pavilion-g6-Notebook-PC\werbeboten'
147
+ # app_name: 'werbeboten@werbeboten-HP-Pavilion-g6-Notebook-PC: ~/Dev/Rails3/BuecherdeParser'
148
+ # window_title: 'werbeboten@werbeboten-HP-Pavilion-g6-Notebook-PC: ~/Dev/Rails3/BuecherdeParser'
149
+ # extended_info: ''
150
+ # start_time: 2012-02-10 11:56:52
151
+ # end_time: 2012-02-10 11:56:57
152
+
@@ -0,0 +1,50 @@
1
+ require 'rescuetime'
2
+ require 'optparse'
3
+
4
+ # This hash will hold all of the options
5
+ # parsed from the command-line by OptionParser.
6
+ options = {}
7
+
8
+ optparse = OptionParser.new do|opts|
9
+ # Set a banner, displayed at the top of the help screen.
10
+ opts.banner = "Usage: ruby-rescuetime [options]"
11
+
12
+ # Define the options, and what they do
13
+ opts.on( '-d', '--debug', 'View debug messages' ) do
14
+ options[:debug] = true
15
+ end
16
+
17
+ opts.on( '-u', '--email EMAIL', 'Your email login used.' ) do |email|
18
+ options[:email] = email
19
+ end
20
+
21
+ opts.on( '-p', '--password PASSWORD', 'Your password used.' ) do |password|
22
+ options[:password] = password
23
+ end
24
+
25
+ options[:config] = File.join(Dir.home, ".ruby-rescuetime", "config.yml")
26
+ opts.on( '-c', '--config FILE', 'Path to your config-file. (Default: ~/.ruby-rescuetime/config.yml)' ) do |config|
27
+ options[:config] = config
28
+ end
29
+
30
+ options[:path] = File.join(Dir.home, ".ruby-rescuetime")
31
+ opts.on('--path PATH', 'Path to your config directory. (Default: ~/.ruby-rescuetime/)' ) do |path|
32
+ options[:path] = path
33
+ end
34
+
35
+ # This displays the help screen, all programs are assumed to have this option.
36
+ opts.on( '-h', '--help', 'Display this screen' ) do
37
+ puts opts
38
+ exit
39
+ end
40
+ end
41
+
42
+ # Parse the command-line. Remember there are two forms
43
+ # of the parse method. The 'parse' method simply parses
44
+ # ARGV, while the 'parse!' method parses ARGV and removes
45
+ # any options found there, as well as any parameters for
46
+ # the options. What's left is the list of files to resize.
47
+ optparse.parse!
48
+
49
+ Rescuetime::Loop.new(options)
50
+
@@ -0,0 +1,83 @@
1
+ module Rescuetime
2
+ class Config
3
+ include Rescuetime::Debug
4
+ require 'fileutils'
5
+ require 'yaml'
6
+
7
+ DEFAULT_PATH = File.join(Dir.home, ".ruby-rescuetime")
8
+ DEFAULT_FILE = "config.yml"
9
+
10
+ DEFAULT_CONFIG = {
11
+ :email => "foo@example.com",
12
+ :password => ""
13
+ }
14
+
15
+ # Constructor
16
+ def initialize(options = {})
17
+ options = {
18
+ :debug => false,
19
+ :email => nil,
20
+ :password => nil,
21
+ :config => File.join(DEFAULT_PATH, DEFAULT_FILE),
22
+ :path => nil
23
+ }.merge(options)
24
+
25
+ @debug = options[:debug]
26
+ @config_path = options[:config] || File.join(options[:path] || DEFAULT_PATH, DEFAULT_FILE)
27
+ config = read_config(@config_path)
28
+
29
+ @config = {
30
+ :email => options[:email] || config[:email],
31
+ :password => options[:password] || config[:password],
32
+ :path => DEFAULT_PATH || config[:path]
33
+ }
34
+ update if @config != config
35
+ end
36
+
37
+ def email
38
+ @config[:email]
39
+ end
40
+
41
+ def password
42
+ @config[:password]
43
+ end
44
+
45
+ # Path where to store data
46
+ def path
47
+ @config[:path]
48
+ end
49
+
50
+ def location
51
+ @config_path
52
+ end
53
+
54
+ # Write current config to disc
55
+ def update
56
+ update_config(@config, @config_path)
57
+ end
58
+
59
+
60
+
61
+ private
62
+ def read_config(path)
63
+ create_config_file(path) unless File.exist?(path)
64
+ YAML::load(File.open(path))
65
+ end
66
+
67
+ def create_config_file(path)
68
+ write_config_file(DEFAULT_CONFIG, path)
69
+ end
70
+
71
+ def update_config(config, path)
72
+ write_config_file(config, path)
73
+ end
74
+
75
+ def write_config_file(config, path)
76
+ FileUtils.mkdir_p(File.dirname(path))
77
+ File.open(path, 'w') do |f|
78
+ f.write(YAML::dump(config))
79
+ end
80
+ end
81
+ end
82
+ end
83
+
@@ -0,0 +1,18 @@
1
+ module Rescuetime
2
+ module Debug
3
+ # Debug-mode turned on?
4
+ def debug?
5
+ @debug == true
6
+ end
7
+
8
+ private
9
+ # Debug-Wrapper
10
+ def debug(msg = nil, &block)
11
+ return unless debug?
12
+
13
+ puts msg if msg
14
+ yield if block_given?
15
+ end
16
+ end
17
+ end
18
+
@@ -0,0 +1,29 @@
1
+ module Rescuetime
2
+ module Extension
3
+ @extensions = {}
4
+
5
+ def self.included(klass)
6
+ # TODO: raise "No APPLICATION constant defined."
7
+
8
+ app = klass::APPLICATION.to_s
9
+ if @extensions[app]
10
+ warn <<-WARN
11
+ Extension for given APPLICATION (#{app}) allready exists.
12
+ Class: #{klass}
13
+ Trace: #{caller.first.inspect}
14
+ WARN
15
+ end
16
+
17
+ @extensions[app] = klass
18
+ end
19
+
20
+ def self.extensions
21
+ @extensions
22
+ end
23
+
24
+ def self.get(key)
25
+ @extensions[key.to_s]
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,32 @@
1
+ class Rescuetime::Chromium < Rescuetime::Application
2
+ APPLICATION = "Chromium-browser"
3
+ include Rescuetime::Extension
4
+ include Rescuetime::Debug
5
+
6
+ def window_title(given_title)
7
+ title = given_title.gsub(/- Chromium$/, '').strip
8
+ t = title.downcase
9
+ if t["google mail"]
10
+ return "http://www.mail.google.com"
11
+ elsif t["twitter"]
12
+ return "http://www.twitter.com"
13
+ elsif t["facebook"]
14
+ return "http://www.facebook.com"
15
+ else
16
+ return t
17
+ end
18
+ end
19
+
20
+ alias :old_name :name
21
+ def name
22
+ ["google mail", "twitter", "facebook"].each do |e|
23
+ return "#{e} - chromium" if title[e]
24
+ end
25
+ "#{title} - chromium"
26
+ end
27
+
28
+ # def extended_info
29
+ # title
30
+ # end
31
+ end
32
+