watch_tower 0.0.0.1 → 0.0.1.beta1
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.
- data/.todo +3 -0
- data/.travis.yml +4 -0
- data/Gemfile +0 -4
- data/README.md +48 -2
- data/TODO +3 -0
- data/ci/travis.rb +4 -1
- data/lib/watch_tower/appscript.rb +65 -7
- data/lib/watch_tower/cli/install.rb +27 -3
- data/lib/watch_tower/cli/open.rb +2 -0
- data/lib/watch_tower/cli/start.rb +3 -1
- data/lib/watch_tower/cli.rb +2 -0
- data/lib/watch_tower/config.rb +2 -0
- data/lib/watch_tower/core_ext.rb +2 -0
- data/lib/watch_tower/editor/base_appscript.rb +28 -1
- data/lib/watch_tower/editor/base_ps.rb +25 -0
- data/lib/watch_tower/editor/textmate.rb +2 -0
- data/lib/watch_tower/editor/xcode.rb +2 -0
- data/lib/watch_tower/editor.rb +2 -0
- data/lib/watch_tower/errors.rb +2 -0
- data/lib/watch_tower/eye.rb +13 -2
- data/lib/watch_tower/file_tree.rb +78 -0
- data/lib/watch_tower/project/any_based.rb +2 -0
- data/lib/watch_tower/project/git_based.rb +2 -0
- data/lib/watch_tower/project/init.rb +2 -0
- data/lib/watch_tower/project/path_based.rb +2 -0
- data/lib/watch_tower/project.rb +2 -0
- data/lib/watch_tower/server/app.rb +37 -7
- data/lib/watch_tower/server/assets/javascripts/application.js +4 -0
- data/lib/watch_tower/server/assets/javascripts/datepicker.coffee +21 -0
- data/lib/watch_tower/server/assets/javascripts/file_tree.coffee +30 -0
- data/lib/watch_tower/server/assets/javascripts/percentage.coffee +15 -5
- data/lib/watch_tower/server/assets/stylesheets/application.css +1 -0
- data/lib/watch_tower/server/assets/stylesheets/date.sass +17 -0
- data/lib/watch_tower/server/assets/stylesheets/file_tree.sass +42 -0
- data/lib/watch_tower/server/assets/stylesheets/global.sass +7 -4
- data/lib/watch_tower/server/configurations/asset.rb +2 -0
- data/lib/watch_tower/server/configurations.rb +2 -0
- data/lib/watch_tower/server/database.rb +2 -0
- data/lib/watch_tower/server/db/migrate/001_create_projects.rb +2 -0
- data/lib/watch_tower/server/db/migrate/002_create_files.rb +2 -0
- data/lib/watch_tower/server/db/migrate/003_create_time_entries.rb +2 -0
- data/lib/watch_tower/server/db/migrate/004_create_durations.rb +2 -0
- data/lib/watch_tower/server/db/migrate/005_add_hash_to_time_entries.rb +2 -0
- data/lib/watch_tower/server/db/migrate/006_add_hash_to_files.rb +2 -0
- data/lib/watch_tower/server/db/migrate/007_add_editor_to_times_entries.rb +8 -0
- data/lib/watch_tower/server/db/migrate/008_rename_editor_to_editor_name_in_times_entries.rb +5 -0
- data/lib/watch_tower/server/db/migrate/009_remove_editor_index_from_time_entries.rb +7 -0
- data/lib/watch_tower/server/db/migrate/010_add_editor_version_to_times_entries.rb +7 -0
- data/lib/watch_tower/server/helpers/asset.rb +2 -0
- data/lib/watch_tower/server/helpers/improved_partials.rb +2 -0
- data/lib/watch_tower/server/helpers/presenters.rb +33 -0
- data/lib/watch_tower/server/helpers.rb +3 -0
- data/lib/watch_tower/server/models/duration.rb +9 -0
- data/lib/watch_tower/server/models/file.rb +17 -0
- data/lib/watch_tower/server/models/project.rb +30 -0
- data/lib/watch_tower/server/models/time_entry.rb +5 -0
- data/lib/watch_tower/server/presenters/application_presenter.rb +165 -0
- data/lib/watch_tower/server/presenters/file_presenter.rb +10 -0
- data/lib/watch_tower/server/presenters/project_presenter.rb +20 -0
- data/lib/watch_tower/server/presenters.rb +13 -0
- data/lib/watch_tower/server/public/assets/{WatchTower-4d6de11e1bd34165ad91ac46fb711bf3.jpg → WatchTower-58eff0713efffbc6054defddc879e0b1.jpg} +0 -0
- data/lib/watch_tower/server/public/assets/application-4e6971066e06aa53b0c8e52c764044d1.css +389 -0
- data/lib/watch_tower/server/public/assets/application-6a1be75d4fd6a545faceb638e47a2486.js +23778 -0
- data/lib/watch_tower/server/public/assets/calendar-379834cd6e6321a940b662ace47f3032.gif +0 -0
- data/lib/watch_tower/server/public/assets/calendar-blue-d6aa74feef7ee4287532761db99a6c0a.gif +0 -0
- data/lib/watch_tower/server/public/assets/calendar-green-3752fe2996091379c8d321f759039385.gif +0 -0
- data/lib/watch_tower/server/public/assets/jquery.datepick-9c8dfe3a4d40bcafc7b182e194c13836.css +227 -0
- data/lib/watch_tower/server/public/assets/{percentage-d8589e21a5fc85d32a445f531ff8ab95.png → percentage-d0176e99520c95e93eee63738ef5d487.png} +0 -0
- data/lib/watch_tower/server/vendor/assets/images/calendar-blue.gif +0 -0
- data/lib/watch_tower/server/vendor/assets/images/calendar-green.gif +0 -0
- data/lib/watch_tower/server/vendor/assets/images/calendar.gif +0 -0
- data/lib/watch_tower/server/vendor/assets/javascripts/jquery-datepick-ext.js +266 -0
- data/lib/watch_tower/server/vendor/assets/javascripts/jquery-datepick-validation.js +232 -0
- data/lib/watch_tower/server/vendor/assets/javascripts/jquery-datepick.js +2092 -0
- data/lib/watch_tower/server/vendor/assets/stylesheets/jquery.datepick.css +226 -0
- data/lib/watch_tower/server/views/_project.haml +10 -13
- data/lib/watch_tower/server/views/index.haml +9 -6
- data/lib/watch_tower/server/views/layout.haml +7 -4
- data/lib/watch_tower/server/views/project.haml +9 -11
- data/lib/watch_tower/server.rb +8 -1
- data/lib/watch_tower/templates/{watchtower.plist → watchtower.plist.erb} +5 -6
- data/lib/watch_tower/version.rb +12 -3
- data/lib/watch_tower.rb +20 -1
- data/spec/factories.rb +2 -0
- data/spec/watch_tower/appscript_spec.rb +36 -2
- data/spec/watch_tower/editor/base_appscript_spec.rb +83 -0
- data/spec/watch_tower/editor/textmate_spec.rb +37 -0
- data/spec/watch_tower/editor/xcode_spec.rb +6 -0
- data/spec/watch_tower/eye_spec.rb +21 -0
- data/spec/watch_tower/file_tree_spec.rb +156 -0
- data/spec/watch_tower/server/app_spec.rb +64 -20
- data/spec/watch_tower/server/models/file_spec.rb +93 -31
- data/spec/watch_tower/server/models/project_spec.rb +147 -18
- data/spec/watch_tower/server/models/time_entry_spec.rb +10 -0
- data/spec/watch_tower/server/{decorator/project_decorator_spec.rb → presenters/application_presenter_spec.rb} +24 -13
- data/spec/watch_tower/server/presenters/file_presenter_spec.rb +8 -0
- data/spec/watch_tower/server/presenters/project_presenter_spec.rb +130 -0
- data/watch_tower.gemspec +10 -4
- metadata +114 -74
- data/lib/watch_tower/server/decorator/application_decorator.rb +0 -91
- data/lib/watch_tower/server/decorator/file_decorator.rb +0 -38
- data/lib/watch_tower/server/decorator/project_decorator.rb +0 -51
- data/lib/watch_tower/server/decorator.rb +0 -21
- data/lib/watch_tower/server/public/assets/application-7829b53b5ece1a16d22dc3d00f329023.css +0 -107
- data/lib/watch_tower/server/public/assets/application-e0e6b7731aade460f680331e65cf0682.js +0 -9359
- data/lib/watch_tower/server/views/_file.haml +0 -9
@@ -1,91 +0,0 @@
|
|
1
|
-
module WatchTower
|
2
|
-
module Server
|
3
|
-
module Decorator
|
4
|
-
class ApplicationDecorator < Draper::Base
|
5
|
-
|
6
|
-
# Returns a human formatted time
|
7
|
-
#
|
8
|
-
# @return [String] The elapsed time formatted
|
9
|
-
def elapsed
|
10
|
-
if model.respond_to? :elapsed_time
|
11
|
-
humanize_time elapsed_time
|
12
|
-
else
|
13
|
-
""
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
protected
|
18
|
-
def pluralize(num, word)
|
19
|
-
if num > 1
|
20
|
-
"#{num} #{word.pluralize}"
|
21
|
-
else
|
22
|
-
"#{num} #{word}"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
# Humanize time
|
27
|
-
#
|
28
|
-
# @param [Integer] The number of seconds
|
29
|
-
# @return [String]
|
30
|
-
def humanize_time(time)
|
31
|
-
case
|
32
|
-
when time >= 1.day
|
33
|
-
humanize_day(time)
|
34
|
-
when time >= 1.hour
|
35
|
-
humanize_hour(time)
|
36
|
-
when time >= 1.minute
|
37
|
-
humanize_minute(time)
|
38
|
-
else
|
39
|
-
pluralize time, "second"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
[:day, :hour, :minute].each do |t|
|
44
|
-
class_eval <<-END, __FILE__, __LINE__ + 1
|
45
|
-
protected
|
46
|
-
def humanize_#{t}(time)
|
47
|
-
seconds = 1.#{t}
|
48
|
-
num = (time / seconds).to_i
|
49
|
-
rest = time % seconds
|
50
|
-
|
51
|
-
time_str = pluralize num, "#{t}"
|
52
|
-
|
53
|
-
unless rest == 0
|
54
|
-
"\#{time_str}#{t == :minute ? ' and' : ','} \#{humanize_time(rest)}"
|
55
|
-
else
|
56
|
-
time_str
|
57
|
-
end
|
58
|
-
end
|
59
|
-
END
|
60
|
-
end
|
61
|
-
|
62
|
-
# Lazy Helpers
|
63
|
-
# PRO: Call Rails helpers without the h. proxy
|
64
|
-
# ex: number_to_currency(model.price)
|
65
|
-
# CON: Add a bazillion methods into your decorator's namespace
|
66
|
-
# and probably sacrifice performance/memory
|
67
|
-
#
|
68
|
-
# Enable them by uncommenting this line:
|
69
|
-
# lazy_helpers
|
70
|
-
|
71
|
-
# Shared Decorations
|
72
|
-
# Consider defining shared methods common to all your models.
|
73
|
-
#
|
74
|
-
# Example: standardize the formatting of timestamps
|
75
|
-
#
|
76
|
-
# def formatted_timestamp(time)
|
77
|
-
# h.content_tag :span, time.strftime("%a %m/%d/%y"),
|
78
|
-
# :class => 'timestamp'
|
79
|
-
# end
|
80
|
-
#
|
81
|
-
# def created_at
|
82
|
-
# formatted_timestamp(model.created_at)
|
83
|
-
# end
|
84
|
-
#
|
85
|
-
# def updated_at
|
86
|
-
# formatted_timestamp(model.updated_at)
|
87
|
-
# end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
module WatchTower
|
2
|
-
module Server
|
3
|
-
module Decorator
|
4
|
-
class FileDecorator < ApplicationDecorator
|
5
|
-
decorates :file
|
6
|
-
|
7
|
-
# Accessing Helpers
|
8
|
-
# You can access any helper via a proxy
|
9
|
-
#
|
10
|
-
# Normal Usage: helpers.number_to_currency(2)
|
11
|
-
# Abbreviated : h.number_to_currency(2)
|
12
|
-
#
|
13
|
-
# Or, optionally enable "lazy helpers" by calling this method:
|
14
|
-
# lazy_helpers
|
15
|
-
# Then use the helpers with no proxy:
|
16
|
-
# number_to_currency(2)
|
17
|
-
|
18
|
-
# Defining an Interface
|
19
|
-
# Control access to the wrapped subject's methods using one of the following:
|
20
|
-
#
|
21
|
-
# To allow only the listed methods (whitelist):
|
22
|
-
# allows :method1, :method2
|
23
|
-
#
|
24
|
-
# To allow everything except the listed methods (blacklist):
|
25
|
-
# denies :method1, :method2
|
26
|
-
|
27
|
-
# Presentation Methods
|
28
|
-
# Define your own instance methods, even overriding accessors
|
29
|
-
# generated by ActiveRecord:
|
30
|
-
#
|
31
|
-
# def created_at
|
32
|
-
# h.content_tag :span, time.strftime("%a %m/%d/%y"),
|
33
|
-
# :class => 'timestamp'
|
34
|
-
# end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
module WatchTower
|
2
|
-
module Server
|
3
|
-
module Decorator
|
4
|
-
class ProjectDecorator < ApplicationDecorator
|
5
|
-
decorates :project
|
6
|
-
|
7
|
-
# Return an image representing the percentage of this project
|
8
|
-
#
|
9
|
-
# @return [String] image_tag
|
10
|
-
def percentage
|
11
|
-
max_elapsed = Project.order('elapsed_time DESC').first.elapsed_time
|
12
|
-
|
13
|
-
percentage = (elapsed_time * 100 / max_elapsed).to_i
|
14
|
-
|
15
|
-
<<-EHTML
|
16
|
-
<img src="#{asset_path('percentage.png')}" data-width="#{percentage}" />
|
17
|
-
EHTML
|
18
|
-
end
|
19
|
-
|
20
|
-
# Accessing Helpers
|
21
|
-
# You can access any helper via a proxy
|
22
|
-
#
|
23
|
-
# Normal Usage: helpers.number_to_currency(2)
|
24
|
-
# Abbreviated : h.number_to_currency(2)
|
25
|
-
#
|
26
|
-
# Or, optionally enable "lazy helpers" by calling this method:
|
27
|
-
# lazy_helpers
|
28
|
-
# Then use the helpers with no proxy:
|
29
|
-
# number_to_currency(2)
|
30
|
-
|
31
|
-
# Defining an Interface
|
32
|
-
# Control access to the wrapped subject's methods using one of the following:
|
33
|
-
#
|
34
|
-
# To allow only the listed methods (whitelist):
|
35
|
-
# allows :method1, :method2
|
36
|
-
#
|
37
|
-
# To allow everything except the listed methods (blacklist):
|
38
|
-
# denies :method1, :method2
|
39
|
-
|
40
|
-
# Presentation Methods
|
41
|
-
# Define your own instance methods, even overriding accessors
|
42
|
-
# generated by ActiveRecord:
|
43
|
-
#
|
44
|
-
# def created_at
|
45
|
-
# h.content_tag :span, time.strftime("%a %m/%d/%y"),
|
46
|
-
# :class => 'timestamp'
|
47
|
-
# end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'draper'
|
2
|
-
|
3
|
-
module WatchTower
|
4
|
-
module Server
|
5
|
-
module Decorator
|
6
|
-
extend ::ActiveSupport::Autoload
|
7
|
-
|
8
|
-
autoload :ApplicationDecorator
|
9
|
-
autoload :ProjectDecorator
|
10
|
-
autoload :FileDecorator
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# Monkey Patch Draper
|
16
|
-
Draper::Base.class_eval <<-END, __FILE__, __LINE__ + 1
|
17
|
-
def self.decorates(input)
|
18
|
-
self.model_class = "::WatchTower::Server::\#{input.to_s.camelize}".constantize
|
19
|
-
model_class.send :include, Draper::ModelSupport
|
20
|
-
end
|
21
|
-
END
|
@@ -1,107 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* This is a manifest file that'll automatically include all the stylesheets available in this directory
|
3
|
-
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
|
4
|
-
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
5
|
-
*/
|
6
|
-
h1 {
|
7
|
-
font-size: 2em; }
|
8
|
-
|
9
|
-
h2 {
|
10
|
-
font-size: 1em; }
|
11
|
-
|
12
|
-
#logo a {
|
13
|
-
color: black;
|
14
|
-
text-decoration: none;
|
15
|
-
display: block;
|
16
|
-
background: url("WatchTower-4d6de11e1bd34165ad91ac46fb711bf3.jpg") no-repeat;
|
17
|
-
width: 390px;
|
18
|
-
height: 94px; }
|
19
|
-
#logo a:visited, #logo a:hover {
|
20
|
-
text-decoration: none; }
|
21
|
-
#logo h1 {
|
22
|
-
float: left;
|
23
|
-
margin-top: 30px;
|
24
|
-
margin-left: 180px; }
|
25
|
-
|
26
|
-
.clearfix {
|
27
|
-
clear: both; }
|
28
|
-
|
29
|
-
a {
|
30
|
-
color: +#b36c6c;
|
31
|
-
text-decoration: none; }
|
32
|
-
a:hover, a:visited {
|
33
|
-
text-decoration: none; }
|
34
|
-
|
35
|
-
body {
|
36
|
-
background: #f7f7f7;
|
37
|
-
color: black;
|
38
|
-
font-family: Arial, Helvetica, sans-serif; }
|
39
|
-
body #wrapper {
|
40
|
-
width: 960px;
|
41
|
-
margin: 0 auto; }
|
42
|
-
body #wrapper #main {
|
43
|
-
border: 1px solid #cdcdcd;
|
44
|
-
-webkit-border-radius: 5px;
|
45
|
-
-moz-border-radius: 5px;
|
46
|
-
border-radius: 5px;
|
47
|
-
padding: 10px;
|
48
|
-
min-height: 200px;
|
49
|
-
background: white; }
|
50
|
-
body #wrapper #footer {
|
51
|
-
width: 960px;
|
52
|
-
text-align: center;
|
53
|
-
background: #d6afaf;
|
54
|
-
color: black;
|
55
|
-
padding: 5px 0;
|
56
|
-
font-size: 12px; }
|
57
|
-
body #wrapper #footer a {
|
58
|
-
color: black;
|
59
|
-
text-decoration: none; }
|
60
|
-
body #wrapper #footer a:visited, body #wrapper #footer a:hover {
|
61
|
-
text-decoration: none; }
|
62
|
-
#projects header .name {
|
63
|
-
float: left;
|
64
|
-
width: 200px;
|
65
|
-
font-size: 20px;
|
66
|
-
text-decoration: underline; }
|
67
|
-
#projects header .percentage {
|
68
|
-
width: 310px;
|
69
|
-
float: left;
|
70
|
-
font-size: 20px;
|
71
|
-
text-decoration: underline; }
|
72
|
-
#projects header .percentage .percentage_img {
|
73
|
-
height: 20px; }
|
74
|
-
#projects header .elapsed {
|
75
|
-
float: left;
|
76
|
-
font-size: 20px;
|
77
|
-
text-decoration: underline; }
|
78
|
-
#projects .project .name {
|
79
|
-
float: left;
|
80
|
-
width: 200px; }
|
81
|
-
#projects .project .percentage_img_container {
|
82
|
-
width: 310px;
|
83
|
-
float: left; }
|
84
|
-
#projects .project .percentage_img_container .percentage_img {
|
85
|
-
height: 20px; }
|
86
|
-
#projects .project .elapsed {
|
87
|
-
float: left; }
|
88
|
-
|
89
|
-
#project #files header .path {
|
90
|
-
font-size: 20px;
|
91
|
-
text-decoration: underline;
|
92
|
-
float: left;
|
93
|
-
width: 600px; }
|
94
|
-
#project #files header .elapsed {
|
95
|
-
font-size: 20px;
|
96
|
-
text-decoration: underline;
|
97
|
-
float: left; }
|
98
|
-
#project .path {
|
99
|
-
float: left;
|
100
|
-
width: 600px; }
|
101
|
-
#project .elapsed {
|
102
|
-
float: left; }
|
103
|
-
#project .percentage_img_container {
|
104
|
-
width: 310px;
|
105
|
-
float: left; }
|
106
|
-
#project .percentage_img_container .percentage_img {
|
107
|
-
height: 20px; }
|