TextTractor 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +6 -0
  2. data/Gemfile +4 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +66 -0
  5. data/Rakefile +6 -0
  6. data/assets/images/blankpad.png +0 -0
  7. data/assets/images/stale.png +0 -0
  8. data/assets/images/translated.png +0 -0
  9. data/assets/images/untranslated.png +0 -0
  10. data/assets/js/application.js +38 -0
  11. data/assets/js/jquery.js +16 -0
  12. data/assets/js/jquery.pjax.js +188 -0
  13. data/config.ru +20 -0
  14. data/lib/text_tractor.rb +31 -0
  15. data/lib/text_tractor/api_server.rb +93 -0
  16. data/lib/text_tractor/base.rb +25 -0
  17. data/lib/text_tractor/config.rb +48 -0
  18. data/lib/text_tractor/phrase.rb +67 -0
  19. data/lib/text_tractor/projects.rb +202 -0
  20. data/lib/text_tractor/ui_server.rb +152 -0
  21. data/lib/text_tractor/users.rb +49 -0
  22. data/lib/text_tractor/users_spec.rb +10 -0
  23. data/lib/text_tractor/version.rb +3 -0
  24. data/spec/api_server_spec.rb +224 -0
  25. data/spec/config_spec.rb +56 -0
  26. data/spec/phrase_spec.rb +71 -0
  27. data/spec/project_spec.rb +292 -0
  28. data/spec/spec_helper.rb +51 -0
  29. data/spec/ui_server/authentication_spec.rb +60 -0
  30. data/spec/ui_server/project_management_spec.rb +103 -0
  31. data/spec/ui_server/project_viewing_spec.rb +137 -0
  32. data/spec/ui_server_spec.rb +6 -0
  33. data/spec/users_spec.rb +123 -0
  34. data/text_tractor.gemspec +33 -0
  35. data/views/blurbs/_blurb.haml +1 -0
  36. data/views/blurbs/edit.haml +5 -0
  37. data/views/blurbs/value.haml +9 -0
  38. data/views/index.haml +13 -0
  39. data/views/layout.haml +26 -0
  40. data/views/projects/getting_started.haml +16 -0
  41. data/views/projects/new.haml +18 -0
  42. data/views/projects/show.haml +23 -0
  43. data/views/styles.scss +218 -0
  44. data/views/users.haml +29 -0
  45. data/watchr.rb +8 -0
  46. metadata +225 -0
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "text_tractor/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "TextTractor"
7
+ s.version = TextTractor::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Jon Wood"]
10
+ s.email = ["jon@blankpad.net"]
11
+ s.homepage = "https://github.com/jellybob/text_tractor"
12
+ s.summary = %q{An implementation of the server side for a certain web service.}
13
+ s.description = %q{TextTractor provides a web interface so that your clients can edit their copy, while you get on with more interesting things.}
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_dependency "haml"
21
+ s.add_dependency "sass"
22
+ s.add_dependency "sinatra"
23
+ s.add_dependency "json"
24
+ s.add_dependency "redis"
25
+ s.add_dependency "redis-namespace"
26
+
27
+ s.add_development_dependency "rake"
28
+ s.add_development_dependency "rspec"
29
+ s.add_development_dependency "rack-test"
30
+ s.add_development_dependency "capybara"
31
+
32
+ s.post_install_message = "If you're updating from 0.0.1 then you need to run TextTractor::Projects.update_datastore. See https://github.com/jellybob/text_tractor/wiki/Updating-Your-Datastore for details."
33
+ end
@@ -0,0 +1 @@
1
+ %dd{ "data-key" => @key }= @value
@@ -0,0 +1,5 @@
1
+ %dt{ class: "state-#{@phrase[@locale].state}" }= @path.split("/").collect { |part| part.gsub("_", " ").capitalize }.join(" / ")
2
+ %dd{ "data-key" => @path.gsub("/", ".") }
3
+ %form{ method: "post", action: "/projects/#{@api_key}/#{@locale}/#{@path}" }
4
+ %textarea{ name: "blurb" }= @phrase[@locale].to_s.strip
5
+ %input{ type: "submit", value: "Save" }
@@ -0,0 +1,9 @@
1
+ %dt{ class: "state-#{phrase.state}" }= key.split(".").collect { |part| part.gsub("_", " ").capitalize }.join(" / ")
2
+ %dd{ "data-key" => key }
3
+ - unless phrase.to_s.empty?
4
+ %p.translation= phrase.to_s
5
+ - else
6
+ %p.translation.empty Click to add a translation
7
+
8
+ - if show_original
9
+ %p.original= original
@@ -0,0 +1,13 @@
1
+ %h1 Projects
2
+
3
+ %section#projects
4
+ - if @projects.size > 0
5
+ %ul
6
+ - @projects.each do |project|
7
+ %li
8
+ %a{ href: "/projects/#{project["api_key"]}" }= project["name"]
9
+ - else
10
+ %p It doesn't look like you've got any projects yet.
11
+
12
+ - if current_user["superuser"]
13
+ %a#new_project{ href: "/projects/new" } Create a Project
@@ -0,0 +1,26 @@
1
+ !!! 5
2
+ %html
3
+ %head
4
+ %title TextTractor
5
+ %link{ rel: "stylesheet", href: "/styles.css"}
6
+ %script{ src: "/js/jquery.js" }
7
+ %script{ src: "/js/jquery.pjax.js" }
8
+ %script{ src: "/js/application.js" }
9
+
10
+ %body
11
+ %header
12
+ %ul#navigation
13
+ - if current_user["superuser"]
14
+ %li
15
+ %a{ href: "/users" } Users
16
+ %li
17
+ %a{ href: "/" } Projects
18
+
19
+ %h1 TextTractor
20
+
21
+ %section#content
22
+ =yield
23
+
24
+ %footer
25
+ %a{ href: "http://blankpad.net", target: "_top" }
26
+ %img{ src: "/images/blankpad.png", alt: "Blank Pad Development", title: "Developed by Blank Pad Development" }
@@ -0,0 +1,16 @@
1
+ %h1= "#{@project["name"]} (#{@project["default_locale"]})"
2
+ %p It doesn't look like you've set up your application to work with TextTractor yet. If you know what you're doing your API key is:
3
+ %p.api_key= @project["api_key"]
4
+
5
+ %p Otherwise, follow the instructions below to configure a Rails 3 application:
6
+
7
+ %p Add Copycopter client to your Gemfile
8
+ %code gem "copycopter_client"
9
+
10
+ %p Then create config/initializers/text_tractor.rb with the following content:
11
+ %code= @project.configuration_block
12
+
13
+ %p And finally, restart your application server. Your appliction will then upload translations and this page will disappear.
14
+ %p
15
+ As you open each page you'll see the translations defined on those pages appear here. Any changes you make from this web interface
16
+ will appear within your development and staging applications shortly afterwards.
@@ -0,0 +1,18 @@
1
+ %h1 New Project
2
+ %form{ action: "/projects", method: "post" }
3
+ %div.field
4
+ %label{ for: "name" } Project Name
5
+ %input{ type: "text", name: "project[name]", id: "name" }
6
+
7
+ %div.field
8
+ %label{ for: "default_locale" } Default Locale
9
+ %input{ type: "text", name: "project[default_locale]", id: "default_locale", value: "en" }
10
+
11
+ %h2 Users
12
+ %p Check the box next to each user who should be granted access to this project.
13
+ - @users.each do |user|
14
+ %div.field
15
+ %label{ for: "user_#{user["username"]}" }= user["name"]
16
+ %input{ type: "checkbox", name: "project[users][]", id: "user_#{user["username"]}" }
17
+
18
+ %input{ type: "submit", value: "Create Project" }
@@ -0,0 +1,23 @@
1
+ %h1= "#{@project["name"]} (#{@locale})"
2
+ %ul#locales
3
+ - @project.locales.each do |locale|
4
+ %li
5
+ - if locale == @locale
6
+ = locale
7
+ - else
8
+ %a{ href: "/projects/#{@project.api_key}/#{locale}" }= locale
9
+
10
+ %form#filter{ method: "get" }
11
+ %label{ for: "state" } Filter:
12
+ %select#state{ name: "state" }
13
+ - { "all" => "All", "needs_work" => "Requires work", "translated" => "Translated", "untranslated" => "Untranslated", "stale" => "Stale" }.each do |key, value|
14
+ - if key == params["state"]
15
+ %option{ selected: "selected", value: key }= value
16
+ - else
17
+ %option{ value: key }= value
18
+
19
+ %p Click on a phrase to edit it.
20
+
21
+ %dl
22
+ - @phrases.sort.each do |key, value|
23
+ = haml :"blurbs/value", :layout => false, :locals => { :phrase => value[@locale], :key => key, :locale => @locale, :original => value[@project.default_locale], :show_original => @project.default_locale != @locale }
@@ -0,0 +1,218 @@
1
+ /* Reset */
2
+ html, body, div, span, applet, object, iframe,
3
+ h1, h2, h3, h4, h5, h6, p, blockquote, pre,
4
+ a, abbr, acronym, address, big, cite, code,
5
+ del, dfn, em, img, ins, kbd, q, s, samp,
6
+ small, strike, strong, sub, sup, tt, var,
7
+ b, u, i, center,
8
+ dl, dt, dd, ol, ul, li,
9
+ fieldset, form, label, legend,
10
+ table, caption, tbody, tfoot, thead, tr, th, td,
11
+ article, aside, canvas, details, embed,
12
+ figure, figcaption, footer, header, hgroup,
13
+ menu, nav, output, ruby, section, summary,
14
+ time, mark, audio, video {
15
+ margin: 0;
16
+ padding: 0;
17
+ border: 0;
18
+ font-size: 100%;
19
+ font: inherit;
20
+ vertical-align: baseline;
21
+ }
22
+ /* HTML5 display-role reset for older browsers */
23
+ article, aside, details, figcaption, figure,
24
+ footer, header, hgroup, menu, nav, section {
25
+ display: block;
26
+ }
27
+ body {
28
+ line-height: 1;
29
+ }
30
+ ol, ul {
31
+ list-style: none;
32
+ }
33
+ blockquote, q {
34
+ quotes: none;
35
+ }
36
+ blockquote:before, blockquote:after,
37
+ q:before, q:after {
38
+ content: '';
39
+ content: none;
40
+ }
41
+ table {
42
+ border-collapse: collapse;
43
+ border-spacing: 0;
44
+ }
45
+
46
+ /* The real deal */
47
+ body {
48
+ background-color: #f5f5f5;
49
+ font-family: "Georgia", serif;
50
+ padding: 0;
51
+ margin: 0;
52
+
53
+ header {
54
+ margin: 0;
55
+ padding: 0.5em 1em;
56
+ background-color: darken(#f5f5f5, 50%);
57
+
58
+ h1 {
59
+ margin-top: 0;
60
+ margin-bottom: 0.2em;
61
+ font-size: 2em;
62
+ font-weight: bold;
63
+ }
64
+
65
+ ul#navigation {
66
+ li {
67
+ float: right;
68
+ font-weight: bold;
69
+ display: inline;
70
+ margin-top: 0.5em;
71
+ margin-left: 1em;
72
+
73
+ a {
74
+ color: black;
75
+ text-decoration: none;
76
+ }
77
+ }
78
+ }
79
+ }
80
+
81
+ section#content {
82
+ padding: 0.5em 1em;
83
+
84
+ h1 {
85
+ font-size: 1.5em;
86
+ margin-bottom: 0.5em;
87
+ }
88
+
89
+ h2 {
90
+ font-size: 1.3em;
91
+ margin-bottom: 0.5em;
92
+ margin-top: 1em;
93
+ }
94
+
95
+ p {
96
+ line-height: 1.4em;
97
+ margin: 0.5em 0;
98
+ }
99
+
100
+ ul {
101
+ margin-top: 1em;
102
+ margin-left: 1.2em;
103
+ list-style: disc;
104
+
105
+ li {
106
+ margin-bottom: 0.5em;
107
+ }
108
+ }
109
+
110
+ ul#locales {
111
+ margin-top: 0;
112
+ margin-bottom: 1em;
113
+ margin-left: 0;
114
+ padding-left: 0;
115
+ font-size: 1.1em;
116
+
117
+ &:before {
118
+ content: "Language:";
119
+ font-weight: bold;
120
+ }
121
+
122
+ li {
123
+ display: inline;
124
+ }
125
+ }
126
+
127
+ label {
128
+ font-weight: bold;
129
+ }
130
+
131
+ p.api_key {
132
+ text-align: center;
133
+ font-size: 1.5em;
134
+ font-weight: bold;
135
+ }
136
+
137
+ code {
138
+ background-color: #333;
139
+ border: 2px solid #999;
140
+ color: white;
141
+ display: block;
142
+ font-family: monospace;
143
+ white-space: pre;
144
+ padding: 0.5em;
145
+ margin-top: 0.5em;
146
+ margin-bottom: 0.5em;
147
+ }
148
+
149
+ form {
150
+ .field {
151
+ margin-bottom: 0.5em;
152
+
153
+ label {
154
+ width: 10em;
155
+ display: block;
156
+ float: left;
157
+ }
158
+
159
+ input[type="text"] {
160
+ min-width: 30em;
161
+ }
162
+
163
+ input[type="submit"] {
164
+ margin-left: 15em;
165
+ }
166
+ }
167
+ }
168
+
169
+ dl {
170
+ margin-bottom: 0.5em;
171
+
172
+ dt {
173
+ font-weight: bold;
174
+ background-position: top left;
175
+ background-repeat: no-repeat;
176
+ padding-left: 20px;
177
+
178
+ &.state-translated {
179
+ background-image: url("/images/translated.png");
180
+ }
181
+
182
+ &.state-untranslated {
183
+ background-image: url("/images/untranslated.png");
184
+ }
185
+
186
+ &.state-stale {
187
+ background-image: url("/images/stale.png");
188
+ }
189
+ }
190
+
191
+ dd {
192
+ margin-top: 0.2em;
193
+ margin-bottom: 0.5em;
194
+
195
+ textarea {
196
+ font-size: 1em;
197
+ font-family: "Georgia", serif;
198
+ padding: 0.3em;
199
+ width: 100%;
200
+ }
201
+
202
+ input[type="submit"] {
203
+ display: block;
204
+ font-size: 1em;
205
+ }
206
+
207
+ p.empty {
208
+ color: #999;
209
+ }
210
+ }
211
+ }
212
+ }
213
+
214
+ footer {
215
+ padding: 0.5em 1em;
216
+ text-align: right;
217
+ }
218
+ }
@@ -0,0 +1,29 @@
1
+ %h1 User Management
2
+ %p Listed below are the currently available users. You can only create users from here. To change their details, you'll have to get dirty in the console.
3
+
4
+ %ul
5
+ - @users.each do |user|
6
+ %li
7
+ = user["name"]
8
+ = "(Superuser)" if user["superuser"]
9
+
10
+ %h2 Create a User
11
+ %form{ method: "post" }
12
+ %div.field
13
+ %label{ for: "name" } Name
14
+ %input{ type: "text", id: "name", name: "user[name]" }
15
+
16
+ %div.field
17
+ %label{ for: "username" } Username
18
+ %input{ type: "text", id: "username", name: "user[username]" }
19
+
20
+ %div.field
21
+ %label{ for: "password" } Password
22
+ %input{ type: "text", id: "password", name: "user[password]" }
23
+
24
+ %div.field
25
+ %label{ for: "superuser" } Superuser
26
+ %input{ type: "checkbox", id: "superuser", name: "user[superuser]", value: "true" }
27
+
28
+ %div.field
29
+ %input{ type: "submit", value: "Create User" }
@@ -0,0 +1,8 @@
1
+ def restart_and_spec
2
+ system("powder restart")
3
+ system("bundle exec rspec spec")
4
+ end
5
+
6
+ watch( 'lib/.*\.rb' ) { |md| restart_and_spec }
7
+ watch( 'views/.*') { |md| restart_and_spec }
8
+ watch( 'spec/.*\.rb' ) { |md| system("bundle exec rspec spec") }
metadata ADDED
@@ -0,0 +1,225 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: TextTractor
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Jon Wood
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-05-31 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: haml
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: sass
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: sinatra
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :runtime
47
+ prerelease: false
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: json
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: redis
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
72
+ name: redis-namespace
73
+ requirement: &id006 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ type: :runtime
80
+ prerelease: false
81
+ version_requirements: *id006
82
+ - !ruby/object:Gem::Dependency
83
+ name: rake
84
+ requirement: &id007 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: *id007
93
+ - !ruby/object:Gem::Dependency
94
+ name: rspec
95
+ requirement: &id008 !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: "0"
101
+ type: :development
102
+ prerelease: false
103
+ version_requirements: *id008
104
+ - !ruby/object:Gem::Dependency
105
+ name: rack-test
106
+ requirement: &id009 !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: "0"
112
+ type: :development
113
+ prerelease: false
114
+ version_requirements: *id009
115
+ - !ruby/object:Gem::Dependency
116
+ name: capybara
117
+ requirement: &id010 !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: "0"
123
+ type: :development
124
+ prerelease: false
125
+ version_requirements: *id010
126
+ description: TextTractor provides a web interface so that your clients can edit their copy, while you get on with more interesting things.
127
+ email:
128
+ - jon@blankpad.net
129
+ executables: []
130
+
131
+ extensions: []
132
+
133
+ extra_rdoc_files: []
134
+
135
+ files:
136
+ - .gitignore
137
+ - Gemfile
138
+ - MIT-LICENSE
139
+ - README.md
140
+ - Rakefile
141
+ - assets/images/blankpad.png
142
+ - assets/images/stale.png
143
+ - assets/images/translated.png
144
+ - assets/images/untranslated.png
145
+ - assets/js/application.js
146
+ - assets/js/jquery.js
147
+ - assets/js/jquery.pjax.js
148
+ - config.ru
149
+ - lib/text_tractor.rb
150
+ - lib/text_tractor/api_server.rb
151
+ - lib/text_tractor/base.rb
152
+ - lib/text_tractor/config.rb
153
+ - lib/text_tractor/phrase.rb
154
+ - lib/text_tractor/projects.rb
155
+ - lib/text_tractor/ui_server.rb
156
+ - lib/text_tractor/users.rb
157
+ - lib/text_tractor/users_spec.rb
158
+ - lib/text_tractor/version.rb
159
+ - spec/api_server_spec.rb
160
+ - spec/config_spec.rb
161
+ - spec/phrase_spec.rb
162
+ - spec/project_spec.rb
163
+ - spec/spec_helper.rb
164
+ - spec/ui_server/authentication_spec.rb
165
+ - spec/ui_server/project_management_spec.rb
166
+ - spec/ui_server/project_viewing_spec.rb
167
+ - spec/ui_server_spec.rb
168
+ - spec/users_spec.rb
169
+ - text_tractor.gemspec
170
+ - views/blurbs/_blurb.haml
171
+ - views/blurbs/edit.haml
172
+ - views/blurbs/value.haml
173
+ - views/index.haml
174
+ - views/layout.haml
175
+ - views/projects/getting_started.haml
176
+ - views/projects/new.haml
177
+ - views/projects/show.haml
178
+ - views/styles.scss
179
+ - views/users.haml
180
+ - watchr.rb
181
+ has_rdoc: true
182
+ homepage: https://github.com/jellybob/text_tractor
183
+ licenses: []
184
+
185
+ post_install_message: If you're updating from 0.0.1 then you need to run TextTractor::Projects.update_datastore. See https://github.com/jellybob/text_tractor/wiki/Updating-Your-Datastore for details.
186
+ rdoc_options: []
187
+
188
+ require_paths:
189
+ - lib
190
+ required_ruby_version: !ruby/object:Gem::Requirement
191
+ none: false
192
+ requirements:
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ hash: 1027683455972089235
196
+ segments:
197
+ - 0
198
+ version: "0"
199
+ required_rubygems_version: !ruby/object:Gem::Requirement
200
+ none: false
201
+ requirements:
202
+ - - ">="
203
+ - !ruby/object:Gem::Version
204
+ hash: 1027683455972089235
205
+ segments:
206
+ - 0
207
+ version: "0"
208
+ requirements: []
209
+
210
+ rubyforge_project:
211
+ rubygems_version: 1.6.2
212
+ signing_key:
213
+ specification_version: 3
214
+ summary: An implementation of the server side for a certain web service.
215
+ test_files:
216
+ - spec/api_server_spec.rb
217
+ - spec/config_spec.rb
218
+ - spec/phrase_spec.rb
219
+ - spec/project_spec.rb
220
+ - spec/spec_helper.rb
221
+ - spec/ui_server/authentication_spec.rb
222
+ - spec/ui_server/project_management_spec.rb
223
+ - spec/ui_server/project_viewing_spec.rb
224
+ - spec/ui_server_spec.rb
225
+ - spec/users_spec.rb