rack-webtranslateit 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|