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.
@@ -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
+