rack-webtranslateit 0.1.0
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/README.markdown +33 -0
- data/lib/rack/webtranslateit.rb +21 -0
- data/lib/rack/webtranslateit/configuration.rb +37 -0
- data/lib/rack/webtranslateit/translation_file.rb +81 -0
- data/lib/rack/webtranslateit/ui.rb +51 -0
- data/public/static/main.css +73 -0
- data/public/static/stripe5.png +0 -0
- data/templates/index.erb +52 -0
- metadata +72 -0
data/README.markdown
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#Usage:
|
2
|
+
|
3
|
+
* Sign up for a webtranslateit.com premium account.
|
4
|
+
* Create a config/translation.yml file:
|
5
|
+
|
6
|
+
# The Project API Token from Web Translate It
|
7
|
+
api_key: ffffffffffffffffffffffffffffffffffffffff
|
8
|
+
|
9
|
+
# The locales not to sync with Web Translate It.
|
10
|
+
# Pass an array of string, or an array of symbols, a string or a symbol.
|
11
|
+
# eg. [:en, :fr] or just 'en'
|
12
|
+
ignore_locales: :en
|
13
|
+
|
14
|
+
# A list of files to translate
|
15
|
+
# You can name your language files as you want, as long as the locale name match the
|
16
|
+
# locale name you set in Web Translate It, and that the different language files names are
|
17
|
+
# differenciated by their locale name.
|
18
|
+
# For example, if you set to translate a project in en_US in WTI, you should use the locale en_US in your app
|
19
|
+
#
|
20
|
+
# wti_id is the file id from Web Translate It.
|
21
|
+
files:
|
22
|
+
1234: config/locales/[locale].yml
|
23
|
+
|
24
|
+
# Optional password to access the web interface
|
25
|
+
password: password
|
26
|
+
|
27
|
+
* Add the middleware:
|
28
|
+
|
29
|
+
config.gem 'rack-webtranslateit', :lib => false
|
30
|
+
config.middleware.use "Rack::Webtranslateit", "/translations/"
|
31
|
+
|
32
|
+
* Go to http://yourapp/translations.
|
33
|
+
* Click update translations.
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "rack"
|
2
|
+
|
3
|
+
module Rack::Webtranslateit
|
4
|
+
def new(app, mount_point = "/translations/")
|
5
|
+
builder = Rack::Builder.new
|
6
|
+
builder.use Rack::Auth::Basic, &method(:authenticator) if Configuration.password
|
7
|
+
builder.map(mount_point){ run Ui.new }
|
8
|
+
builder.map("/"){ run app }
|
9
|
+
builder.to_app
|
10
|
+
end
|
11
|
+
|
12
|
+
def authenticator(username, password)
|
13
|
+
username == "admin" and password == Configuration.password
|
14
|
+
end
|
15
|
+
|
16
|
+
autoload :Configuration, "rack/webtranslateit/configuration"
|
17
|
+
autoload :Ui, "rack/webtranslateit/ui"
|
18
|
+
autoload :TranslationFile, "rack/webtranslateit/translation_file"
|
19
|
+
|
20
|
+
extend self
|
21
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
class Rack::Webtranslateit::Configuration
|
4
|
+
attr_accessor :api_key, :autofetch, :files, :ignore_locales, :password
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
file = File.join(RAILS_ROOT, 'config', 'translation.yml')
|
8
|
+
configuration = YAML.load_file(file)
|
9
|
+
self.api_key = configuration['api_key']
|
10
|
+
self.autofetch = configuration[RAILS_ENV]['autofetch']
|
11
|
+
self.password = configuration['password']
|
12
|
+
self.files = []
|
13
|
+
self.ignore_locales = [configuration['ignore_locales']].flatten.map{ |l| l.to_s }
|
14
|
+
configuration['files'].each do |file_id, file_path|
|
15
|
+
self.files.push(Rack::Webtranslateit::TranslationFile.new(file_id, file_path, api_key))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def locales
|
20
|
+
http = Net::HTTP.new('webtranslateit.com', 443)
|
21
|
+
http.use_ssl = true
|
22
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
23
|
+
http.read_timeout = 10
|
24
|
+
request = Net::HTTP::Get.new("/api/projects/#{api_key}/locales")
|
25
|
+
response = http.request(request)
|
26
|
+
if response.code.to_i == 200
|
27
|
+
response.body.split
|
28
|
+
else
|
29
|
+
[]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.method_missing(name, *args)
|
34
|
+
@configuration ||= new
|
35
|
+
@configuration.send(name, *args)
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'net/https'
|
2
|
+
require 'ftools'
|
3
|
+
class Rack::Webtranslateit::TranslationFile
|
4
|
+
attr_accessor :id, :file_path, :api_key
|
5
|
+
|
6
|
+
def initialize(id, file_path, api_key)
|
7
|
+
self.id = id
|
8
|
+
self.file_path = file_path
|
9
|
+
self.api_key = api_key
|
10
|
+
end
|
11
|
+
|
12
|
+
def for(locale)
|
13
|
+
ForLocale.new(self, locale)
|
14
|
+
end
|
15
|
+
|
16
|
+
class ForLocale
|
17
|
+
attr_reader :file, :locale
|
18
|
+
def initialize(file, locale)
|
19
|
+
@file, @locale = file, locale
|
20
|
+
end
|
21
|
+
|
22
|
+
def exists?
|
23
|
+
File.exists?(file_path)
|
24
|
+
end
|
25
|
+
|
26
|
+
def committed?
|
27
|
+
Dir.chdir(File.dirname(file_path)) do
|
28
|
+
system "git status | grep 'modified: #{File.basename(file_path)}' > /dev/null"
|
29
|
+
end
|
30
|
+
! $?.success?
|
31
|
+
end
|
32
|
+
|
33
|
+
def modified_remotely?
|
34
|
+
get_translations.code.to_i == 200
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_translations(respect_modified_since = true)
|
38
|
+
http_connection do |http|
|
39
|
+
request = Net::HTTP::Get.new(api_url)
|
40
|
+
request.add_field('If-Modified-Since', File.mtime(File.new(file_path, 'r')).rfc2822) if File.exist?(file_path) and respect_modified_since
|
41
|
+
return http.request(request)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def fetch
|
46
|
+
response = get_translations
|
47
|
+
File.open(file_path, 'w'){|f| f << response.body } if response.code.to_i == 200 and not response.body.blank?
|
48
|
+
end
|
49
|
+
|
50
|
+
def fetch!
|
51
|
+
response = get_translations(false)
|
52
|
+
File.open(file_path, 'w'){|f| f << response.body } if response.code.to_i == 200 and not response.body.blank?
|
53
|
+
end
|
54
|
+
|
55
|
+
def send
|
56
|
+
File.open(file_path) do |file|
|
57
|
+
http_connection do |http|
|
58
|
+
request = Net::HTTP::Put::Multipart.new(api_url, "file" => UploadIO.new(file, "text/plain", file.path))
|
59
|
+
response = http.request(request)
|
60
|
+
return response.code.to_i
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def file_path
|
66
|
+
@file_path ||= File.expand_path(file.file_path.gsub("[locale]", locale))
|
67
|
+
end
|
68
|
+
|
69
|
+
def http_connection
|
70
|
+
http = Net::HTTP.new('webtranslateit.com', 443)
|
71
|
+
http.use_ssl = true
|
72
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
73
|
+
http.read_timeout = 10
|
74
|
+
yield http
|
75
|
+
end
|
76
|
+
|
77
|
+
def api_url
|
78
|
+
"/api/projects/#{file.api_key}/files/#{file.id}/locales/#{locale}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
class Rack::Webtranslateit::Ui < Sinatra::Base
|
4
|
+
set :views => File.join(File.dirname(__FILE__), *%w[.. .. .. templates])
|
5
|
+
|
6
|
+
use Rack::ShowExceptions
|
7
|
+
use Rack::Lint
|
8
|
+
use Rack::Static, :urls => ["/static"], :root => File.join(File.dirname(__FILE__), *%w[.. .. .. public])
|
9
|
+
|
10
|
+
get(''){redirect "/"}
|
11
|
+
|
12
|
+
get '/' do
|
13
|
+
content_type 'text/html', :charset => 'utf-8'
|
14
|
+
erb :index, :locals => {:files => config.files, :locales => config.locales}
|
15
|
+
end
|
16
|
+
|
17
|
+
post '/update' do
|
18
|
+
fetch_translations
|
19
|
+
redirect "/"
|
20
|
+
end
|
21
|
+
|
22
|
+
helpers do
|
23
|
+
def highlight_unless_equal(value, expected)
|
24
|
+
value == expected ? value : "<em>#{value}</em>"
|
25
|
+
end
|
26
|
+
|
27
|
+
def base_path
|
28
|
+
request.script_name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
def redirect(path, *args)
|
35
|
+
super(base_path + path, *args)
|
36
|
+
end
|
37
|
+
|
38
|
+
def config
|
39
|
+
@config ||= Rack::Webtranslateit::Configuration
|
40
|
+
end
|
41
|
+
|
42
|
+
def fetch_translations
|
43
|
+
config.files.each do |file|
|
44
|
+
config.locales.each do |locale|
|
45
|
+
next if config.ignore_locales.include?(locale)
|
46
|
+
response_code = file.for(locale).fetch!
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
body {
|
2
|
+
font-family: 'Lucida Grande', Arial, Helvetica, Verdana, sans-serif;
|
3
|
+
background: url("stripe5.png");
|
4
|
+
color: #444;
|
5
|
+
}
|
6
|
+
|
7
|
+
h1{
|
8
|
+
background: #CFDBBA;
|
9
|
+
margin: 0 0 1em 0;
|
10
|
+
padding: .5em;
|
11
|
+
font-size: 1.6em;
|
12
|
+
border-bottom: 1px solid #8C9574;
|
13
|
+
text-shadow: #EEE 0px 1px 1px;
|
14
|
+
}
|
15
|
+
|
16
|
+
em {
|
17
|
+
background-color: rgb(255, 227, 0);
|
18
|
+
padding: 2px;
|
19
|
+
}
|
20
|
+
|
21
|
+
#content {
|
22
|
+
background: #fff;
|
23
|
+
border: 1px solid #8C9574;
|
24
|
+
width: 700px;
|
25
|
+
margin-left: -351px;
|
26
|
+
position: absolute;
|
27
|
+
left: 50%;
|
28
|
+
top: 5em;
|
29
|
+
}
|
30
|
+
|
31
|
+
#content > div {
|
32
|
+
margin: .5em;
|
33
|
+
}
|
34
|
+
|
35
|
+
table {
|
36
|
+
margin: 1em auto;
|
37
|
+
border-collapse: collapse;
|
38
|
+
}
|
39
|
+
table caption{
|
40
|
+
font-size: 1.3em;
|
41
|
+
font-weight: bold;
|
42
|
+
text-shadow: #EEE 0px 1px 1px;
|
43
|
+
margin: .3em;
|
44
|
+
}
|
45
|
+
table td, table th {
|
46
|
+
border: 1px solid #8C9574;
|
47
|
+
padding: .2em;
|
48
|
+
width: 50%;
|
49
|
+
}
|
50
|
+
|
51
|
+
form {
|
52
|
+
text-align: center;
|
53
|
+
}
|
54
|
+
|
55
|
+
#footer {
|
56
|
+
position: absolute;
|
57
|
+
bottom: 0;
|
58
|
+
left: 0;
|
59
|
+
width: 100%;
|
60
|
+
background: rgba(50,50,50,.5);
|
61
|
+
margin:0;
|
62
|
+
}
|
63
|
+
|
64
|
+
#footer p {
|
65
|
+
margin: 1em 3em;
|
66
|
+
font-size: 0.5em;
|
67
|
+
text-align: right;
|
68
|
+
color: #ccc;
|
69
|
+
}
|
70
|
+
|
71
|
+
#footer p a {
|
72
|
+
color: #fff;
|
73
|
+
}
|
Binary file
|
data/templates/index.erb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>WebTranslateIt – Admin</title>
|
5
|
+
<link rel="stylesheet" href="<%= base_path %>/static/main.css" type="text/css" media="screen" charset="utf-8">
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<div id="content">
|
9
|
+
<h1>WebTranslateIt – Admin</h1>
|
10
|
+
<div>
|
11
|
+
<p>
|
12
|
+
Manage your translations on <a href="https://webtranslateit.com">webtranslateit.com</a>
|
13
|
+
and use the interface below to update the local version.
|
14
|
+
Once you are finished, any uncommitted files will need to be updated and committed by a developer.
|
15
|
+
</p>
|
16
|
+
|
17
|
+
<% files.each do |file| %>
|
18
|
+
<table>
|
19
|
+
<caption> <%= file.file_path %> </caption>
|
20
|
+
<thead>
|
21
|
+
<tr>
|
22
|
+
<th>Locale</th>
|
23
|
+
<td>Path</td>
|
24
|
+
<td>Exists</td>
|
25
|
+
<td>Committed</td>
|
26
|
+
<td>New Version Available</td>
|
27
|
+
</tr>
|
28
|
+
</thead>
|
29
|
+
<tbody>
|
30
|
+
<% locales.each do |locale| locale_file = file.for(locale) %>
|
31
|
+
<tr>
|
32
|
+
<th style="width: 5px;"><%= locale %></th>
|
33
|
+
<td><abbr title="<%= locale_file.file_path %>"><%= File.basename(locale_file.file_path) %></abbr></td>
|
34
|
+
<td><%= highlight_unless_equal(locale_file.exists?, true) %></td>
|
35
|
+
<td><%= highlight_unless_equal(locale_file.committed?, true) %></td>
|
36
|
+
<td><%= highlight_unless_equal(locale_file.modified_remotely?, false) %></td>
|
37
|
+
</tr>
|
38
|
+
<% end %>
|
39
|
+
</tbody>
|
40
|
+
</table>
|
41
|
+
<% end %>
|
42
|
+
|
43
|
+
<form method="post" action="<%= base_path %>/update">
|
44
|
+
<input type="submit" value="Update All Translations" />
|
45
|
+
</form>
|
46
|
+
</div>
|
47
|
+
</div>
|
48
|
+
<div id="footer">
|
49
|
+
<p>This page was generated by <a href="">webtranslateit-admin</a>, developed by <a href="http://tomlea.co.uk">Tom Lea</a> at <a href="http://www.reevoo.com/">reevoo.com</a>.</p>
|
50
|
+
</div>
|
51
|
+
</body>
|
52
|
+
</html>
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-webtranslateit
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tom Lea
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-01-05 00:00:00 +00:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: sinatra
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description:
|
26
|
+
email: contrib@tomlea.co.uk
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.markdown
|
33
|
+
files:
|
34
|
+
- README.markdown
|
35
|
+
- lib/rack/webtranslateit/configuration.rb
|
36
|
+
- lib/rack/webtranslateit/translation_file.rb
|
37
|
+
- lib/rack/webtranslateit/ui.rb
|
38
|
+
- lib/rack/webtranslateit.rb
|
39
|
+
- public/static/main.css
|
40
|
+
- public/static/stripe5.png
|
41
|
+
- templates/index.erb
|
42
|
+
has_rdoc: true
|
43
|
+
homepage: http://tomlea.co.uk
|
44
|
+
licenses: []
|
45
|
+
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options:
|
48
|
+
- --main
|
49
|
+
- README.markdown
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
requirements: []
|
65
|
+
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.3.5
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: Provide a web interface for updating your WebTranslateIt.com translations.
|
71
|
+
test_files: []
|
72
|
+
|