rack-webtranslateit 0.1.0

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