wovnrb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 61f0246afc971fcc1a0e23f4d52bcc7eb6308047
4
+ data.tar.gz: 7287c6ccc22deaf0fc375f47b56f1e14a6af8c3e
5
+ SHA512:
6
+ metadata.gz: 7b9ae3b2c55af426048647b12897a035cb72b9644d96522dfaddcf8514bf42401e892492684fbda754bcdde6828057576ac858f71e4639015dfbaab5951b827d
7
+ data.tar.gz: ad3b42dde7eec3635b6560c3d9b4136ba3eda76f146411aa666398adc83f413c1ea04bbb684a1dbd182e566b9ed533be05de251094c929cb7e1d72943e48bbc5
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ /.bundle/
2
+ <<<<<<< HEAD
3
+ /vendor
4
+ =======
5
+ /vendor/bundle/
6
+ >>>>>>> 78ccf8410c19bdee508e96a2386a5273abfad0ba
7
+ /.yardoc
8
+ /Gemfile.lock
9
+ /_yardoc/
10
+ /coverage/
11
+ /doc/
12
+ /pkg/
13
+ /spec/reports/
14
+ /tmp/
15
+ *.bundle
16
+ *.so
17
+ *.o
18
+ *.a
19
+ *.swp
20
+ mkmf.log
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.0.0-p451
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in wovn.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Wovn
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'wovnrb'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install wovnrb
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/wovnrb/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ #require "bundler/gem_tasks"
2
+ #require 'rake/extensiontask'
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << 'test'
7
+ t.test_files = FileList['test/*/*.rb']
8
+ t.options = '-p'
9
+ end
10
+
11
+ desc 'Run tests'
12
+ task :default => :test
13
+
14
+ #Rake::ExtensionTask.new 'dom' do |ext|
15
+ # ext.lib_dir = 'lib/wovnrb'
16
+ #end
17
+
18
+ #gemspec = Gem::Specification.load('wovnrb.gemspec')
19
+ #Rake::ExtensionTask.new do |ext|
20
+ # ext.name = 'dom'
21
+ # ext.source_pattern = "*.{cpp,h}"
22
+ # ext.ext_dir = 'ext/wovnrb'
23
+ # ext.lib_dir = 'lib/wovnrb'
24
+ # ext.gem_spec = gemspec
25
+ #end
26
+ #
27
+ #task :default => [:compile]
28
+
data/lib/wovnrb.rb ADDED
@@ -0,0 +1,116 @@
1
+ require 'wovnrb/store'
2
+ require 'wovnrb/headers'
3
+ require 'wovnrb/lang'
4
+ #require 'dom'
5
+ require 'json'
6
+
7
+ require 'wovnrb/railtie' if defined?(Rails)
8
+
9
+ module Wovnrb
10
+
11
+ STORE = Store.new
12
+
13
+ class Interceptor
14
+ def initialize(app)
15
+ @app = app
16
+ end
17
+
18
+ def call(env)
19
+ @env = env
20
+ STORE.refresh_settings
21
+ headers = Headers.new(env, STORE.settings)
22
+ if ((headers.path_lang != '' && !STORE.settings['supported_langs'].include?(headers.path_lang)) || headers.path_lang == STORE.settings['default_lang'])
23
+ redirect_headers = headers.redirect(STORE.settings['default_lang'])
24
+ redirect_headers['set-cookie'] = "wovn_selected_lang=#{STORE.settings['default_lang']};"
25
+ return [307, redirect_headers, ['']]
26
+ elsif headers.path_lang == '' && (headers.browser_lang != STORE.settings['default_lang'] && STORE.settings['supported_langs'].include?(headers.browser_lang))
27
+ redirect_headers = headers.redirect(headers.browser_lang)
28
+ return [307, redirect_headers, ['']]
29
+ end
30
+ lang = headers.lang
31
+
32
+ # pass to application
33
+ status, res_headers, body = @app.call(headers.request_out)
34
+
35
+ if res_headers["Content-Type"] =~ /html/ && !body[0].nil?
36
+ # Can we make this request beforehand?
37
+ values = STORE.get_values(headers.redis_url)
38
+ url = {
39
+ :protocol => headers.protocol,
40
+ :host => headers.host,
41
+ :pathname => headers.pathname
42
+ }
43
+ switch_lang(body, values, url, lang) unless status.to_s =~ /^1|302/ || lang === STORE.settings['default_lang']
44
+ #d = Dom.new(storage.get_values, body, lang)
45
+ end
46
+
47
+ headers.out(res_headers)
48
+ [status, res_headers, body]
49
+ #[status, res_headers, d.transform()]
50
+ end
51
+
52
+
53
+ def switch_lang(body, values, url, lang=STORE.settings['default_lang'])
54
+ def_lang = 'en'
55
+ text_index = values['text_vals'] || {}
56
+ src_index = values['img_vals'] || {}
57
+ img_src_prefix = values['img_src_prefix'] || ''
58
+ string_index = {}
59
+ body.map! do |b|
60
+ d = Nokogiri::HTML5(b)
61
+ d.xpath('//text()').each do |node|
62
+ node_text = node.content.strip
63
+ if text_index[node_text] && text_index[node_text][lang]
64
+ node.content = node.content.gsub(/^(\s*)[\S\s]*(\s*)$/, '\1' + text_index[node_text][lang][0]['data'] + '\2')
65
+ end
66
+ end
67
+ d.xpath('//img').each do |node|
68
+ # use regular expressions to support case insensitivity (right?)
69
+ if node.to_html =~ /src=['"][^'"]*['"]/i
70
+ src = node.to_html.match(/src=['"]([^&'"]*)['"]/i)[1]
71
+ # THIS SRC CORRECTION DOES NOT HANDLE ONE IMPORTANT CASE
72
+ # 1) "../path/with/ellipse"
73
+ # if this is not an absolute src
74
+ if src !~ /:\/\//
75
+ # if this is a path with a leading slash
76
+ if src =~ /^\//
77
+ src = "#{url[:protocol]}://#{url[:host]}#{src}"
78
+ else
79
+ src = "#{url[:protocol]}://#{url[:host]}#{url[:path]}#{src}"
80
+ end
81
+ end
82
+
83
+ if src_index[src] && src_index[src][lang]
84
+ node.attribute('src').value = "#{img_src_prefix}#{src_index[src][lang][0]['data']}"
85
+ end
86
+ end
87
+ end
88
+ # INSERTS
89
+ #insert_node = Nokogiri::XML::Node.new('script', d)
90
+ #insert_node['type'] = 'text/javascript'
91
+ #insert_node.content = "window.wovn_backend = function() { return {'currentLang': '#{lang}'}; };"
92
+ #parent_node = d.at_css('head') || d.at_css('body') || d.at_css('html')
93
+ #parent_node.add_child(insert_node)
94
+
95
+ # If dev can't be used on production gem
96
+ d.xpath('//script').each do |script_node|
97
+ if script_node['src'] && script_node['src'].include?('//j.wovn.io/')
98
+ script_node.remove
99
+ end
100
+ end
101
+ insert_node = Nokogiri::XML::Node.new('script', d)
102
+ insert_node['src'] = '//j.wovn.io/0'
103
+ insert_node['data-wovnio'] = "key=#{STORE.settings['user_token']}&backend=true&currentLang=#{lang}&urlPattern=#{STORE.settings['url_pattern_name']}"
104
+ # do this so that there will be a closing tag (better compatibility with browsers)
105
+ insert_node.content = ' '
106
+ parent_node = d.at_css('head') || d.at_css('body') || d.at_css('html')
107
+ parent_node.prepend_child(insert_node)
108
+
109
+ d.to_html
110
+ end
111
+ end
112
+
113
+ end
114
+
115
+ end
116
+
@@ -0,0 +1,176 @@
1
+ module Wovnrb
2
+
3
+ class Headers
4
+ attr_reader :unmasked_url
5
+ attr_reader :url
6
+ attr_reader :protocol
7
+ attr_reader :unmasked_host
8
+ attr_reader :host
9
+ attr_reader :unmasked_pathname
10
+ attr_reader :pathname
11
+ attr_reader :redis_url
12
+
13
+ def initialize(env, settings)
14
+ @env = env
15
+ @protocol = @env['rack.url_scheme']
16
+ @unmasked_host = @env['HTTP_HOST']
17
+ @unmasked_pathname = @env['REQUEST_URI'].split('?')[0]
18
+ @unmasked_pathname += '/' unless @unmasked_pathname =~ /\/$/ || @unmasked_pathname =~ /\/[^\/.]+\.[^\/.]+$/
19
+ @unmasked_url = "#{@protocol}://#{@unmasked_host}#{@unmasked_pathname}"
20
+ @host = remove_lang(@env['HTTP_HOST'], self.lang)
21
+ @pathname, @query = @env['REQUEST_URI'].split('?')
22
+ @pathname = remove_lang(@pathname, self.lang)
23
+ @query = @query || ''
24
+ @url = "#{@host}#{@pathname}#{(@query.length > 0 ? '?' : '') + remove_lang(@query, self.lang)}"
25
+ if settings['query'].length > 0
26
+ query_vals = []
27
+ settings['query'].each do |qv|
28
+ rx = Regexp.new("(^|&)(?<query_val>#{qv}[^&]+)(&|$)")
29
+ m = @query.match(rx)
30
+ if m && m[:query_val]
31
+ query_vals.push(m[:query_val])
32
+ end
33
+ end
34
+ if query_vals.length > 0
35
+ @query = "?#{query_vals.sort.join('&')}"
36
+ end
37
+ else
38
+ @query = ''
39
+ end
40
+ @query = remove_lang(@query, self.lang)
41
+ @pathname = @pathname.gsub(/\/$/, '')
42
+ @redis_url = "#{@host}#{@pathname}#{@query}"
43
+ end
44
+
45
+ def lang
46
+ (self.path_lang && self.path_lang.length > 0) ? self.path_lang : STORE.settings['default_lang']
47
+ end
48
+
49
+ def path_lang
50
+ if @path_lang.nil?
51
+ rp = Regexp.new(STORE.settings['url_pattern_reg'])
52
+ match = "#{@env['SERVER_NAME']}#{@env['REQUEST_URI']}".match(rp)
53
+ if match && match[:lang] && Lang::LANG[match[:lang]]
54
+ @path_lang = match[:lang]
55
+ else
56
+ @path_lang = ''
57
+ end
58
+ end
59
+ return @path_lang
60
+ end
61
+
62
+ def browser_lang
63
+ if @browser_lang.nil?
64
+ match = (@env['HTTP_COOKIE'] || '').match(/wovn_selected_lang\s*=\s*(?<lang>[^;\s]+)/)
65
+ if match && match[:lang] && Lang::LANG[match[:lang]]
66
+ @browser_lang = match[:lang]
67
+ else
68
+ # IS THIS RIGHT?
69
+ @browser_lang = ''
70
+ accept_langs = (@env['HTTP_ACCEPT_LANGUAGE'] || '').split(/[,;]/)
71
+ accept_langs.each do |l|
72
+ if Lang::LANG[l]
73
+ @browser_lang = l
74
+ break
75
+ end
76
+ end
77
+ end
78
+ end
79
+ return @browser_lang
80
+ end
81
+
82
+ def redirect(lang=self.browser_lang)
83
+ redirect_headers = {}
84
+ redirect_headers['location'] = self.redirect_location(lang)
85
+ redirect_headers['content-length'] = '0'
86
+ return redirect_headers
87
+ end
88
+
89
+ def redirect_location(lang)
90
+ if lang == STORE.settings['default_lang']
91
+ # IS THIS RIGHT??
92
+ return "#{self.protocol}://#{self.url}"
93
+ #return remove_lang("#{@env['HTTP_HOST']}#{@env['REQUEST_URI']}", lang)
94
+ else
95
+ location = self.url
96
+ case STORE.settings['url_pattern_name']
97
+ when 'query'
98
+ if location !~ /\?/
99
+ location = "#{location}?wovn=#{lang}"
100
+ else @env['REQUEST_URI'] !~ /(\?|&)wovn=/
101
+ location = "#{location}&wovn=#{lang}"
102
+ end
103
+ when 'subdomain'
104
+ location = "#{lang}.#{location}"
105
+ #when 'path'
106
+ else
107
+ location = location.sub(/(\/|$)/, "/#{lang}/");
108
+ end
109
+ return "#{self.protocol}://#{location}"
110
+ end
111
+ end
112
+
113
+ def request_out(def_lang=STORE.settings['default_lang'])
114
+ case STORE.settings['url_pattern_name']
115
+ when 'query'
116
+ @env['REQUEST_URI'] = remove_lang(@env['REQUEST_URI'])
117
+ if @env.has_key?('QUERY_STRING')
118
+ @env['QUERY_STRING'] = remove_lang(@env['QUERY_STRING'])
119
+ end
120
+ if @env.has_key?('ORIGINAL_FULLPATH')
121
+ @env['ORIGINAL_FULLPATH'] = remove_lang(@env['ORIGINAL_FULLPATH'])
122
+ end
123
+ when 'subdomain'
124
+ @env["HTTP_HOST"] = remove_lang(@env["HTTP_HOST"])
125
+ @env["SERVER_NAME"] = remove_lang(@env["SERVER_NAME"])
126
+ if @env.has_key?('HTTP_REFERER')
127
+ @env["HTTP_REFERER"] = remove_lang(@env["HTTP_REFERER"])
128
+ end
129
+ #when 'path'
130
+ else
131
+ @env['REQUEST_URI'] = remove_lang(@env['REQUEST_URI'])
132
+ @env['REQUEST_PATH'] = remove_lang(@env['REQUEST_PATH'])
133
+ @env['PATH_INFO'] = remove_lang(@env['PATH_INFO'])
134
+ if @env.has_key?('ORIGINAL_FULLPATH')
135
+ @env['ORIGINAL_FULLPATH'] = remove_lang(@env['ORIGINAL_FULLPATH'])
136
+ end
137
+ end
138
+ @env
139
+ end
140
+
141
+ def remove_lang(uri, lang=self.path_lang)
142
+ case STORE.settings['url_pattern_name']
143
+ when 'query'
144
+ return uri.sub(/(^|\?|&)wovn=#{lang}(&|$)/, '\1').gsub(/(\?|&)$/, '')
145
+ when 'subdomain'
146
+ rp = Regexp.new('(^|(//))' + lang + '\.')
147
+ return uri.sub(rp, '\1')
148
+ #when 'path'
149
+ else
150
+ return uri.sub(/\/#{lang}(\/|$)/, '/')
151
+ end
152
+ end
153
+
154
+ def out(headers)
155
+ if headers.has_key?("Location")
156
+ case STORE.settings['url_pattern_name']
157
+ when 'query'
158
+ if headers["Location"] =~ /\?/
159
+ headers["Location"] += "&"
160
+ else
161
+ headers["Location"] += "?"
162
+ end
163
+ headers['Location'] += "wovn=#{self.lang}"
164
+ when 'subdomain'
165
+ headers["Location"] = headers["Location"].sub(/\/\/([^.]+)/, '//' + self.lang + '.\1')
166
+ #when 'path'
167
+ else
168
+ headers["Location"] = headers['Location'].sub(/(\/\/[^\/]+)/, '\1/' + self.lang)
169
+ end
170
+ end
171
+ headers
172
+ end
173
+
174
+ end
175
+
176
+ end
@@ -0,0 +1,70 @@
1
+ # -*- encoding: UTF-8 -*-
2
+ module Wovnrb
3
+ class Lang
4
+ LANG = {
5
+ #http://msdn.microsoft.com/en-us/library/hh456380.aspx
6
+ 'ar' => {name: 'العربية', code: 'ar', en: 'Arabic'},
7
+ 'zh-CHS' => {name: '简体中文', code: 'zh-CHS', en: 'Simp Chinese'},
8
+ 'zh-CHT' => {name: '繁體中文', code: 'zh-CHT', en: 'Trad Chinese'},
9
+ 'da' => {name: 'Dansk', code: 'da', en: 'Danish'},
10
+ 'nl' => {name: 'Nederlands', code: 'nl', en: 'Dutch'},
11
+ 'en' => {name: 'English', code: 'en', en: 'English'},
12
+ 'fi' => {name: 'Suomi', code: 'fi', en: 'Finnish'},
13
+ 'fr' => {name: 'Français', code: 'fr', en: 'French'},
14
+ 'de' => {name: 'Deutsch', code: 'de', en: 'German'},
15
+ 'el' => {name: 'Ελληνικά', code: 'el', en: 'Greek'},
16
+ 'he' => {name: 'עברית', code: 'he', en: 'Hebrew'},
17
+ 'id' => {name: 'Bahasa Indonesia', code: 'id', en: 'Indonesian'},
18
+ 'it' => {name: 'Italiano', code: 'it', en: 'Italian'},
19
+ 'ja' => {name: '日本語', code: 'ja', en: 'Japanese'},
20
+ 'ko' => {name: '한국어', code: 'ko', en: 'Korean'},
21
+ 'ms' => {name: 'Bahasa Melayu', code: 'ms', en: 'Malay'},
22
+ 'no' => {name: 'Norsk', code: 'no', en: 'Norwegian'},
23
+ 'pl' => {name: 'Polski', code: 'pl', en: 'Polish'},
24
+ 'pt' => {name: 'Português', code: 'pt', en: 'Portuguese'},
25
+ 'ru' => {name: 'Русский', code: 'ru', en: 'Russian'},
26
+ 'es' => {name: 'Español', code: 'es', en: 'Spanish'},
27
+ 'sv' => {name: 'Svensk', code: 'sv', en: 'Swedish'},
28
+ 'th' => {name: 'ภาษาไทย', code: 'th', en: 'Thai'},
29
+ 'hi' => {name: 'हिन्दी', code: 'hi', en: 'Hindi'},
30
+ 'tr' => {name: 'Türkçe', code: 'tr', en: 'Turkish'},
31
+ 'uk' => {name: 'Українська', code: 'uk', en: 'Ukrainian'},
32
+ 'vi' => {name: 'Tiếng Việt', code: 'vi', en: 'Vietnamese'},
33
+
34
+ =begin
35
+ * denotes no Google support
36
+ *{name: 'Urdu', code: 'ur', en: 'Urdu'},
37
+ {name: 'Català', code: 'ca'},
38
+ {name: 'Čeština', code: 'cs'},
39
+ {name: 'Български', code: 'bg'},
40
+ {name: 'Estonian', code: 'et'},
41
+ *{name: 'Haitian Creoloe', code: 'ht'},
42
+ *{name: 'Hmong Daw', code: 'mww'},
43
+ {name: 'Hungarian', code: 'hu'},
44
+ *{name: 'Klingon', code: 'tlh'},
45
+ *{name: 'Klingon (plqaD)', code: 'tlh-Qaak'},
46
+ {name: 'Latvian', code: 'lv'},
47
+ {name: 'Lithuanian', code: 'lt'},
48
+ {name: 'Maltese', code: 'mt'},
49
+ {name: 'Persian', code: 'fa'},
50
+ {name: 'Romanian', code: 'ro'},
51
+ {name: 'Slovak', code: 'sk'},
52
+ {name: 'Slovenian', code: 'sl'},
53
+ {name: 'Ukranian', code: 'uk'},
54
+ {name: 'Welsh', code: 'cy'},
55
+ =end
56
+ }
57
+
58
+ def self.get_code(lang_name)
59
+ return nil if lang_name.nil?
60
+ return lang_name if LANG[lang_name]
61
+ LANG.each do |k, l|
62
+ if lang_name.downcase == l[:name].downcase || lang_name.downcase == l[:en].downcase
63
+ return l[:code]
64
+ end
65
+ end
66
+ return nil
67
+ end
68
+
69
+ end
70
+ end
@@ -0,0 +1,15 @@
1
+ module Wovnrb
2
+
3
+ class Railtie < Rails::Railtie
4
+ initializer 'wovnrb.configure_rails_initialization' do |app|
5
+ app.middleware.insert_before(0, Wovnrb::Interceptor)
6
+
7
+ #if Rails.env.development? && config.respond_to?(:wovnrb)
8
+ # config.after_initialize do
9
+ # config.wovnrb[:user_token] = User.first.short_token
10
+ # end
11
+ #end
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,104 @@
1
+ require 'redis'
2
+ require 'net/http'
3
+
4
+ module Wovnrb
5
+
6
+ class Store
7
+ attr_reader :settings
8
+
9
+
10
+ def initialize
11
+ @settings =
12
+ {
13
+ 'user_token' => '',
14
+ # 'url_pattern_name' => 'query'
15
+ # 'url_pattern_reg' => "?.*wovn=(?<lang>[^&]+)(&|$)",
16
+ 'url_pattern_name' => 'path',
17
+ 'url_pattern_reg' => "/(?<lang>[^/.?]+)",
18
+ #'url_pattern_name' => 'subdomain',
19
+ #'url_pattern_reg' => "^(?<lang>[^.]+)\.",
20
+ 'query' => [],
21
+ 'backend_host' => 'rs1.wovn.io',
22
+ 'backend_port' => '6379',
23
+ 'default_lang' => 'en',
24
+ 'supported_langs' => ['en'],
25
+ }
26
+ # When Store is initialized, the Rails.configuration object is not yet initialized
27
+ @config_loaded = false
28
+ end
29
+
30
+ def settings
31
+ if !@config_loaded
32
+ if Object.const_defined?('Rails') && Rails.configuration.respond_to?(:wovnrb)
33
+ @settings.merge!(Rails.configuration.wovnrb.stringify_keys)
34
+ end
35
+ refresh_settings
36
+ @config_loaded = true
37
+ end
38
+ @settings
39
+ end
40
+
41
+ def refresh_settings
42
+ # add timer so this only accesses redis once every 5 minutes etc
43
+ user_token = @settings['user_token']
44
+ #user_token = 'lYWQ9'
45
+ redis_key = 'WOVN:BACKEND:SETTING::' + user_token
46
+ cli = Redis.new(host: @settings['backend_host'], port: @settings['backend_port'])
47
+ begin
48
+ vals = cli.hgetall(redis_key) || {}
49
+ rescue
50
+ vals = {}
51
+ end
52
+ if vals.has_key?('query')
53
+ vals['query'] = JSON.parse(vals['query'])
54
+ end
55
+ if vals.has_key?('supported_langs')
56
+ vals['supported_langs'] = JSON.parse(vals['supported_langs'])
57
+ end
58
+ @settings.merge!(vals)
59
+ @settings['backend_port'] = @settings['backend_port'].to_s
60
+ @settings['default_lang'] = Lang.get_code(@settings['default_lang'])
61
+ if !vals.has_key?('supported_langs')
62
+ @settings['supported_langs'] = [@settings['default_lang']]
63
+ end
64
+ if @settings['url_pattern_name'] == 'path'
65
+ @settings['url_pattern_reg'] = "/(?<lang>[^/.?]+)"
66
+ elsif @settings['url_pattern_name'] == 'query'
67
+ @settings['url_pattern_reg'] = '((\?.*&)|\?)wovn=(?<lang>[^&]+)(&|$)'
68
+ end
69
+ @settings
70
+ end
71
+
72
+ def get_values(url)
73
+ #url = 'http://wovn.io'
74
+ user_token = @settings['user_token']
75
+ #user_token = 'lYWQ9'
76
+ redis_key = 'WOVN:BACKEND:STORAGE:' + url.gsub(/\/$/, '') + ':' + user_token
77
+ vals = request_values(redis_key)
78
+ if vals.empty?
79
+ #uri = URI.parse('http://wovn.io/[USER_ID]/[PAGE_ID]')
80
+ #Net::HTTP.get(uri)
81
+ end
82
+ vals
83
+ #f = File.open('./values/values', 'r')
84
+ #return JSON.parse(f.read)
85
+ #f.close
86
+ end
87
+
88
+ def request_values(key)
89
+ Rails.logger.info("*******************************************************")
90
+ Rails.logger.info(key)
91
+ cli = Redis.new(host: @settings['backend_host'], port: @settings['backend_port'])
92
+ Rails.logger.info(@settings['backend_host'])
93
+ Rails.logger.info(@settings['backend_port'])
94
+ begin
95
+ vals = cli.get(key) || '{}'
96
+ vals = JSON.parse(vals)
97
+ rescue
98
+ vals = {}
99
+ end
100
+ end
101
+
102
+ end
103
+
104
+ end
@@ -0,0 +1,3 @@
1
+ module Wovnrb
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,2 @@
1
+ require 'pry'
2
+ require 'Wovnrb'
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Wovnrb do
4
+ it 'does stuff' do
5
+ pending # no code yet
6
+ end
7
+ end
@@ -0,0 +1,96 @@
1
+ require 'wovnrb'
2
+ require 'minitest/autorun'
3
+ require 'pry'
4
+
5
+ class TestHeaders < Minitest::Test
6
+
7
+ def test_initialize
8
+ h = Wovnrb::Headers.new(get_env, get_settings)
9
+ refute_nil(h)
10
+ end
11
+
12
+ def test_initialize_with_simple_url
13
+ h = Wovnrb::Headers.new(get_env('url' => 'https://wovn.io'), get_settings)
14
+ #assert_equal(''
15
+ end
16
+
17
+ def test_keys_exist
18
+ Wovnrb::Lang::LANG.each do |k, l|
19
+ assert(l.has_key?(:name))
20
+ assert(l.has_key?(:code))
21
+ assert(l.has_key?(:en))
22
+ assert_equal(k, l[:code])
23
+ end
24
+ end
25
+
26
+ def test_get_code_with_valid_code
27
+ assert_equal('ms', Wovnrb::Lang.get_code('ms'))
28
+ end
29
+
30
+ def test_get_code_with_valid_english_name
31
+ assert_equal('pt', Wovnrb::Lang.get_code('Portuguese'))
32
+ end
33
+
34
+ def test_get_code_with_valid_native_name
35
+ assert_equal('hi', Wovnrb::Lang.get_code('हिन्दी'))
36
+ end
37
+
38
+ def test_get_code_with_invalid_name
39
+ assert_equal(nil, Wovnrb::Lang.get_code('WOVN4LYFE'))
40
+ end
41
+
42
+ def test_get_code_with_empty_string
43
+ assert_equal(nil, Wovnrb::Lang.get_code(''))
44
+ end
45
+
46
+ def test_get_code_with_nil
47
+ assert_equal(nil, Wovnrb::Lang.get_code(nil))
48
+ end
49
+
50
+ def get_settings(options={})
51
+ settings = {}
52
+ settings['user_token'] = 'OHYx9'
53
+ settings['url_pattern_name'] = 'path'
54
+ settings['url_pattern_reg'] = "/(?<lang>[^/.?]+)"
55
+ settings['query'] = []
56
+ settings['backend_host'] = 'localhost'
57
+ settings['backend_port'] = '6379'
58
+ settings['default_lang'] = 'en'
59
+ settings['supported_langs'] = []
60
+ settings['secret_key'] = ''
61
+
62
+ return settings.merge(options)
63
+ end
64
+
65
+ def get_env(options={})
66
+ env = {}
67
+ env['rack.url_scheme'] = 'http'
68
+ env['HTTP_HOST'] = 'wovn.io'
69
+ env['REQUEST_URI'] = '/dashboard?param=val&hey=you'
70
+ env['SERVER_NAME'] = 'wovn.io'
71
+ env['HTTP_COOKIE'] = "olfsk=olfsk021093478426337242; hblid=KB8AAMzxzu2DSxnB4X7BJ26rBGVeF0yJ; optimizelyEndUserId=oeu1426233718869r0.5398541854228824; __zlcmid=UFeZqrVo6Mv3Yl; wovn_selected_lang=en; optimizelySegments=%7B%7D; optimizelyBuckets=%7B%7D; _equalizer_session=eDFwM3M2QUZJZFhoby9JZlArckcvSUJwNFRINXhUeUxtNnltQXZhV0tqdGhZQjJMZ01URnZTK05ydFVWYmM3U0dtMVN0M0Z0UnNDVG8vdUNDTUtPc21jY0FHREgrZ05CUnBTb0hyUlkvYlBWQVhQR3RZdnhjMWsrRW5rOVp1Z3V3bkgyd3NpSlRZQWU1dlZvNmM1THp6aUZVeE83Y1pWWENRNTBUVFIrV05WeTdDMlFlem1tUzdxaEtndFZBd2dtUjU2ak5EUmJPa3RWWmMyT1pSVWdMTm8zOVZhUWhHdGQ3L1c5bm91RmNSdFRrcC90Tml4N2t3ZWlBaDRya2lLT1I0S0J2TURhUWl6Uk5rOTQ4Y1MwM3VKYnlLMUYraEt5clhRdFd1eGdEWXdZd3pFbWQvdE9vQndhdDVQbXNLcHBURm9CbnZKenU2YnNXRFdqRVl0MVV3bmRyYjhvMDExcGtUVU9tK1lqUGswM3p6M05tbVRnTjE3TUl5cEdpTTZ4a2gray8xK0FvTC9wUDVka1JSeE5GM1prZmRjWDdyVzRhWW5uS2Mxc1BxOEVVTTZFS3N5bTlVN2p5eE5YSjNZWGI2UHd3Vzc0bDM5QjIwL0l5Mm85NmQyWFAwdVQ3ZzJYYk1QOHY2NVJpY2c9LS1KNU96eHVycVJxSDJMbEc4Rm9KVXpBPT0%3D--17e47555d692fb9cde20ef78a09a5eabbf805bb3; mp_a0452663eb7abb7dfa9c94007ebb0090_mixpanel=%7B%22distinct_id%22%3A%20%2253ed9ffa4a65662e37000000%22%2C%22%24initial_referrer%22%3A%20%22http%3A%2F%2Fp.dev-wovn.io%3A8080%2Fhttp%3A%2F%2Fdev-wovn.io%3A3000%22%2C%22%24initial_referring_domain%22%3A%20%22p.dev-wovn.io%3A8080%22%2C%22__mps%22%3A%20%7B%7D%2C%22__mpso%22%3A%20%7B%7D%2C%22__mpa%22%3A%20%7B%7D%2C%22__mpu%22%3A%20%7B%7D%2C%22__mpap%22%3A%20%5B%5D%7D"
72
+ env['HTTP_ACCEPT_LANGUAGE'] = 'ja,en-US;q=0.8,en;q=0.6'
73
+ env['QUERY_STRING'] = 'param=val&hey=you'
74
+ env['ORIGINAL_FULLPATH'] = '/dashboard?param=val&hey=you'
75
+ #env['HTTP_REFERER'] =
76
+ env['REQUEST_PATH'] = '/dashboard'
77
+ env['PATH_INFO'] = '/dashboard'
78
+
79
+ if options['url']
80
+ url = URI.parse(options['url'])
81
+ env['rack.url_scheme'] = url.scheme
82
+ env['HTTP_HOST'] = url.host
83
+ if (url.scheme == 'http' && url.port != 80) || (url.scheme == 'https' && url.port != 443)
84
+ env['HTTP_HOST'] += ":#{url.port}"
85
+ end
86
+ env['SERVER_NAME'] = url.host
87
+ env['REQUEST_URI'] = url.request_uri
88
+ env['ORIGINAL_FULLPATH'] = url.request_uri
89
+ env['QUERY_STRING'] = url.query
90
+ env['REQUEST_PATH'] = url.path
91
+ env['PATH_INFO'] = url.path
92
+ end
93
+
94
+ return env.merge(options)
95
+ end
96
+ end
@@ -0,0 +1,45 @@
1
+ require 'wovnrb'
2
+ #require 'test/unit'
3
+ #require 'test/unit/notify'
4
+ require 'minitest/autorun'
5
+
6
+ class TestLang < Minitest::Test
7
+
8
+ def test_langs_exist
9
+ refute_nil(Wovnrb::Lang::LANG)
10
+ end
11
+
12
+ def test_keys_exist
13
+ Wovnrb::Lang::LANG.each do |k, l|
14
+ assert(l.has_key?(:name))
15
+ assert(l.has_key?(:code))
16
+ assert(l.has_key?(:en))
17
+ assert_equal(k, l[:code])
18
+ end
19
+ end
20
+
21
+ def test_get_code_with_valid_code
22
+ assert_equal('ms', Wovnrb::Lang.get_code('ms'))
23
+ end
24
+
25
+ def test_get_code_with_valid_english_name
26
+ assert_equal('pt', Wovnrb::Lang.get_code('Portuguese'))
27
+ end
28
+
29
+ def test_get_code_with_valid_native_name
30
+ assert_equal('hi', Wovnrb::Lang.get_code('हिन्दी'))
31
+ end
32
+
33
+ def test_get_code_with_invalid_name
34
+ assert_equal(nil, Wovnrb::Lang.get_code('WOVN4LYFE'))
35
+ end
36
+
37
+ def test_get_code_with_empty_string
38
+ assert_equal(nil, Wovnrb::Lang.get_code(''))
39
+ end
40
+
41
+ def test_get_code_with_nil
42
+ assert_equal(nil, Wovnrb::Lang.get_code(nil))
43
+ end
44
+
45
+ end
data/values/values ADDED
@@ -0,0 +1 @@
1
+ [{"_id":{"$oid":"54eab2f84a6566d0ed070000"},"body":"Atteindre le monde","created_at":"2015-02-23T04:56:24.097Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Reach The World","translator_id":null,"updated_at":"2015-02-23T04:56:24.097Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[2]/div[2]/h2/text()"},{"_id":{"$oid":"54eab3054a6566d0ee1b0000"},"body":"価格設定","created_at":"2015-02-23T04:56:37.398Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Pricing","translator_id":null,"updated_at":"2015-02-23T04:56:37.398Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[6]/div/ul/li[4]/a/text()"},{"_id":{"$oid":"54eab3054a6566d0ee190000"},"body":"条件","created_at":"2015-02-23T04:56:37.390Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Terms","translator_id":null,"updated_at":"2015-02-23T04:56:37.390Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[6]/div/ul/li[2]/a/text()"},{"_id":{"$oid":"54eab3054a6566d0ee170000"},"body":"サインアップ","created_at":"2015-02-23T04:56:37.385Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Sign up","translator_id":null,"updated_at":"2015-02-23T04:56:37.385Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[6]/a/text()"},{"_id":{"$oid":"54eab3054a6566d0ee150000"},"body":"今すぐ開始します","created_at":"2015-02-23T04:56:37.379Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Start Now","translator_id":null,"updated_at":"2015-02-23T04:56:37.379Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[6]/h2/text()"},{"_id":{"$oid":"54eab3054a6566d0ee140000"},"body":"サインアップ","created_at":"2015-02-23T04:56:37.377Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Sign up","translator_id":null,"updated_at":"2015-02-23T04:56:37.377Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[5]/div[2]/a/text()"},{"_id":{"$oid":"54eab3054a6566d0ee110000"},"body":"サインアップ","created_at":"2015-02-23T04:56:37.367Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Sign up","translator_id":null,"updated_at":"2015-02-23T04:56:37.367Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[4]/div[2]/a/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed060000"},"body":"Se connecter","created_at":"2015-02-23T04:56:24.095Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Sign in","translator_id":null,"updated_at":"2015-02-23T04:56:24.095Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[1]/div[2]/a/text()"},{"_id":{"$oid":"54eab3054a6566d0ee0b0000"},"body":"サインアップ","created_at":"2015-02-23T04:56:37.196Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Sign up","translator_id":null,"updated_at":"2015-02-23T04:56:37.196Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[2]/div[2]/a/text()"},{"_id":{"$oid":"54eab3054a6566d0ee090000"},"body":"世界リーチ","created_at":"2015-02-23T04:56:37.190Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Reach The World","translator_id":null,"updated_at":"2015-02-23T04:56:37.190Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[2]/div[2]/h2/text()"},{"_id":{"$oid":"54eab3054a6566d0ee080000"},"body":"ログイン","created_at":"2015-02-23T04:56:37.187Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Sign in","translator_id":null,"updated_at":"2015-02-23T04:56:37.187Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[1]/div[2]/a/text()"},{"_id":{"$oid":"54eab3054a6566d0ee070000"},"body":"サインアップ","created_at":"2015-02-23T04:56:37.184Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Sign up","translator_id":null,"updated_at":"2015-02-23T04:56:37.184Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[1]/a[1]/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed030000"},"body":"Localisez votre site.","created_at":"2015-02-23T04:56:24.071Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Localize your website.","translator_id":null,"updated_at":"2015-02-23T04:56:24.071Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[1]/p/text()"},{"_id":{"$oid":"54eab3054a6566d0ee130000"},"body":"ワンクリックでは、自動的にページを翻訳したり、プロの翻訳を注文。編集するか、それを自分で書く。あなたはすべての単語、文字、および句読点を制御します。公開した後、変更内容は、サイト上で瞬時に表示されます。","created_at":"2015-02-23T04:56:37.374Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"In one click, automatically translate your page or order a professional translation. Edit or write it yourself. You control every word, letter, and punctuation mark. After publishing, your changes are instantly visible on your site.","translator_id":null,"updated_at":"2015-02-23T04:56:37.374Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[5]/div[2]/p/text()"},{"_id":{"$oid":"54eab3054a6566d0ee100000"},"body":"あなたのウェブサイトやブログに多言語サポートを追加するのは簡単です。 WOVN.ioが提供するコードの1行は、あなたが始めるために必要なすべてのです。公開された翻訳は、サイト上で瞬時に表示されます。","created_at":"2015-02-23T04:56:37.363Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Adding multilingual support to your website or blog is easy. One line of code, provided by WOVN.io, is all you need to get started. Your published translations will be instantly visible on your site.","translator_id":null,"updated_at":"2015-02-23T04:56:37.363Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[4]/div[2]/p/text()"},{"_id":{"$oid":"54eab3054a6566d0ee0a0000"},"body":"WOVN.ioは世界にあなたのコンテンツをもたらし、あなたのウェブサイトやブログのための多言語サポートを提供します。サイト訪問者はすぐにWOVN.ioウィジェットを使用して言語を切り替えることができます。あなたの翻訳されたコンテンツのすべての編集および管理は、ブラウザの利便性から行うことができます。","created_at":"2015-02-23T04:56:37.194Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"WOVN.io provides multilingual support for your website or blog, bringing your content to the world. Site visitors can quickly toggle between languages using the WOVN.io widget. All editing and management of your translated content can be done from the convenience of your browser.","translator_id":null,"updated_at":"2015-02-23T04:56:37.194Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[2]/div[2]/p/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed110000"},"body":"En un seul clic, de traduire automatiquement votre page ou commander une traduction professionnelle. Modifier ou écrire vous-même. Vous contrôlez chaque mot, lettre et un signe de ponctuation. Après la publication, vos modifications sont immédiatement visibles sur votre site.","created_at":"2015-02-23T04:56:24.228Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"In one click, automatically translate your page or order a professional translation. Edit or write it yourself. You control every word, letter, and punctuation mark. After publishing, your changes are instantly visible on your site.","translator_id":null,"updated_at":"2015-02-23T04:56:24.228Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[5]/div[2]/p/text()"},{"_id":{"$oid":"54eab3054a6566d0ee1c0000"},"body":"©2014ミニマル·テクノロジーズ","created_at":"2015-02-23T04:56:37.402Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"©2014 Minimal Technologies","translator_id":null,"updated_at":"2015-02-23T04:56:37.402Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[6]/div/ul/li[5]/a/text()"},{"_id":{"$oid":"54eab3054a6566d0ee1a0000"},"body":"フィードバック&お問い合わせ","created_at":"2015-02-23T04:56:37.392Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Feedback \u0026 Contact","translator_id":null,"updated_at":"2015-02-23T04:56:37.392Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[6]/div/ul/li[3]/a/text()"},{"_id":{"$oid":"54eab3054a6566d0ee180000"},"body":"個人情報保護方針","created_at":"2015-02-23T04:56:37.387Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Privacy Policy","translator_id":null,"updated_at":"2015-02-23T04:56:37.387Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[6]/div/ul/li[1]/a/text()"},{"_id":{"$oid":"54eab3054a6566d0ee160000"},"body":"世界とあなたのサイトを共有する。瞬時に。","created_at":"2015-02-23T04:56:37.383Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Share your site with the world. Instantly.","translator_id":null,"updated_at":"2015-02-23T04:56:37.383Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[6]/p/text()"},{"_id":{"$oid":"54eab3054a6566d0ee120000"},"body":"コンテンツあなたがコントロールする","created_at":"2015-02-23T04:56:37.370Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Content You Control","translator_id":null,"updated_at":"2015-02-23T04:56:37.370Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[5]/div[2]/h2/text()"},{"_id":{"$oid":"54eab3054a6566d0ee0f0000"},"body":"一列にはじめよう","created_at":"2015-02-23T04:56:37.206Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Get Started In One Line","translator_id":null,"updated_at":"2015-02-23T04:56:37.206Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[4]/div[2]/h2/text()"},{"_id":{"$oid":"54eab3054a6566d0ee0e0000"},"body":"翻訳して公開","created_at":"2015-02-23T04:56:37.204Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Translate and publish","translator_id":null,"updated_at":"2015-02-23T04:56:37.204Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[3]/div[5]/p/text()"},{"_id":{"$oid":"54eab3054a6566d0ee0d0000"},"body":"翻訳するためにページを追加します。","created_at":"2015-02-23T04:56:37.201Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Add a page to translate","translator_id":null,"updated_at":"2015-02-23T04:56:37.201Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[3]/div[3]/p/text()"},{"_id":{"$oid":"54eab3054a6566d0ee0c0000"},"body":"WOVN.ioコードスニペットを挿入します","created_at":"2015-02-23T04:56:37.198Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Insert the WOVN.io code snippet","translator_id":null,"updated_at":"2015-02-23T04:56:37.198Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[3]/div[1]/p/text()"},{"_id":{"$oid":"54eab3054a6566d0ee050000"},"body":"あなたのウェブサイトをローカライズ。","created_at":"2015-02-23T04:56:37.179Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Localize your website.","translator_id":null,"updated_at":"2015-02-23T04:56:37.179Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[1]/p/text()"},{"_id":{"$oid":"54eab3054a6566d0ee040000"},"body":"コー​​ドの1行で世界を歓迎します。","created_at":"2015-02-23T04:56:37.177Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Welcome the world in one line of code.","translator_id":null,"updated_at":"2015-02-23T04:56:37.177Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[1]/h2/text()"},{"_id":{"$oid":"54eab3054a6566d0ee030000"},"body":"Wovn.io |あなたのウェブサイトをローカライズ。","created_at":"2015-02-23T04:56:37.173Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Wovn.io | Localize your website.","translator_id":null,"updated_at":"2015-02-23T04:56:37.173Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/head/title/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed1a0000"},"body":"© 2014 Technologies minimales","created_at":"2015-02-23T04:56:24.255Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"©2014 Minimal Technologies","translator_id":null,"updated_at":"2015-02-23T04:56:24.255Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[6]/div/ul/li[5]/a/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed0e0000"},"body":"Ajout d'un support multilingue à votre site ou blog est facile. Une ligne de code, fourni par WOVN.io, est tout ce que vous avez besoin pour commencer. Vos traductions publiées seront instantanément visibles sur votre site.","created_at":"2015-02-23T04:56:24.122Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Adding multilingual support to your website or blog is easy. One line of code, provided by WOVN.io, is all you need to get started. Your published translations will be instantly visible on your site.","translator_id":null,"updated_at":"2015-02-23T04:56:24.122Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[4]/div[2]/p/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed180000"},"body":"Feedback \u0026 Contact","created_at":"2015-02-23T04:56:24.249Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Feedback \u0026 Contact","translator_id":null,"updated_at":"2015-02-23T04:56:24.249Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[6]/div/ul/li[3]/a/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed160000"},"body":"Politique de confidentialité","created_at":"2015-02-23T04:56:24.245Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Privacy Policy","translator_id":null,"updated_at":"2015-02-23T04:56:24.245Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[6]/div/ul/li[1]/a/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed140000"},"body":"Partager votre site avec le monde. Instantanément.","created_at":"2015-02-23T04:56:24.239Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Share your site with the world. Instantly.","translator_id":null,"updated_at":"2015-02-23T04:56:24.239Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[6]/p/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed100000"},"body":"Contenu You Control","created_at":"2015-02-23T04:56:24.134Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Content You Control","translator_id":null,"updated_at":"2015-02-23T04:56:24.134Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[5]/div[2]/h2/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed0d0000"},"body":"Commencez sur une seule ligne","created_at":"2015-02-23T04:56:24.119Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Get Started In One Line","translator_id":null,"updated_at":"2015-02-23T04:56:24.119Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[4]/div[2]/h2/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed0c0000"},"body":"Traduire et publier","created_at":"2015-02-23T04:56:24.114Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Translate and publish","translator_id":null,"updated_at":"2015-02-23T04:56:24.114Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[3]/div[5]/p/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed020000"},"body":"Bienvenue dans le monde sur une seule ligne de code.","created_at":"2015-02-23T04:56:24.065Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Welcome the world in one line of code.","translator_id":null,"updated_at":"2015-02-23T04:56:24.065Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[1]/h2/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed080000"},"body":"WOVN.io fournit un support multilingue pour votre site ou blog, ce qui porte votre contenu au monde. Les visiteurs du site peuvent rapidement basculer entre les langues utilisant le widget WOVN.io. Tous édition et la gestion de votre contenu traduit peut être fait dans le confort de votre navigateur.","created_at":"2015-02-23T04:56:24.099Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"WOVN.io provides multilingual support for your website or blog, bringing your content to the world. Site visitors can quickly toggle between languages using the WOVN.io widget. All editing and management of your translated content can be done from the convenience of your browser.","translator_id":null,"updated_at":"2015-02-23T04:56:24.099Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[2]/div[2]/p/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed050000"},"body":"Signer","created_at":"2015-02-23T04:56:24.093Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Sign up","translator_id":null,"updated_at":"2015-02-23T04:56:24.093Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[1]/a[1]/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed040000"},"body":"Gratuit","created_at":"2015-02-23T04:56:24.089Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Free","translator_id":null,"updated_at":"2015-02-23T04:56:24.089Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[1]/div[1]/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed0b0000"},"body":"Ajouter une page à traduire","created_at":"2015-02-23T04:56:24.110Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Add a page to translate","translator_id":null,"updated_at":"2015-02-23T04:56:24.110Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[3]/div[3]/p/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed0a0000"},"body":"Insérez l'extrait de code WOVN.io","created_at":"2015-02-23T04:56:24.106Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Insert the WOVN.io code snippet","translator_id":null,"updated_at":"2015-02-23T04:56:24.106Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[3]/div[1]/p/text()"},{"_id":{"$oid":"54eab3054a6566d0ee060000"},"body":"フリー","created_at":"2015-02-23T04:56:37.182Z","ec":null,"ei":null,"en":null,"et":null,"language":"ja","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Free","translator_id":null,"updated_at":"2015-02-23T04:56:37.182Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[1]/div[1]/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed190000"},"body":"Établissement des prix","created_at":"2015-02-23T04:56:24.251Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Pricing","translator_id":null,"updated_at":"2015-02-23T04:56:24.251Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[6]/div/ul/li[4]/a/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed170000"},"body":"Termes","created_at":"2015-02-23T04:56:24.247Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Terms","translator_id":null,"updated_at":"2015-02-23T04:56:24.247Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[6]/div/ul/li[2]/a/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed150000"},"body":"Signer","created_at":"2015-02-23T04:56:24.242Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Sign up","translator_id":null,"updated_at":"2015-02-23T04:56:24.242Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[6]/a/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed130000"},"body":"Démarrer maintenant","created_at":"2015-02-23T04:56:24.236Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Start Now","translator_id":null,"updated_at":"2015-02-23T04:56:24.236Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[6]/h2/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed120000"},"body":"Signer","created_at":"2015-02-23T04:56:24.233Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Sign up","translator_id":null,"updated_at":"2015-02-23T04:56:24.233Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[5]/div[2]/a/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed0f0000"},"body":"Signer","created_at":"2015-02-23T04:56:24.129Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Sign up","translator_id":null,"updated_at":"2015-02-23T04:56:24.129Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[4]/div[2]/a/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed010000"},"body":"Wovn.io | Localisez votre site.","created_at":"2015-02-23T04:56:24.047Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Wovn.io | Localize your website.","translator_id":null,"updated_at":"2015-02-23T04:56:24.047Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/head/title/text()"},{"_id":{"$oid":"54eab2f84a6566d0ed090000"},"body":"Signer","created_at":"2015-02-23T04:56:24.102Z","ec":null,"ei":null,"en":null,"et":null,"language":"fr","page_id":{"$oid":"54cb63a64a65667be0000000"},"publish":true,"src_body":"Sign up","translator_id":null,"updated_at":"2015-02-23T04:56:24.102Z","user_id":{"$oid":"53ed9ffa4a65662e37000000"},"xpath":"/html/body/div[2]/div[2]/a/text()"}]
data/wovnrb.gemspec ADDED
@@ -0,0 +1,49 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'wovnrb/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "wovnrb"
8
+ spec.version = Wovnrb::VERSION
9
+ spec.authors = ["Jeff Sandford", "Antoine David"]
10
+ spec.email = ["jeff@wovn.io"]
11
+ spec.summary = %q{Gem for WOVN.io}
12
+ spec.description = %q{ALPHA VERSION, not in a useable form.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+
17
+ files = `git ls-files -z`.split("\x0")
18
+ files.delete('BEFORE_PUSHING')
19
+ spec.files = files
20
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
22
+ spec.require_paths = ["lib"]
23
+ #spec.require_paths = ["lib", "ext"]
24
+ #spec.extensions = spec.files.grep(%r{/extconf\.rb$})
25
+ #spec.extensions = %w[ext/dom/extconf.rb]
26
+ #spec.extensions = spec.files.grep(%r{/extconf\.rb$})
27
+
28
+ spec.add_dependency "nokogumbo"
29
+ spec.add_dependency "redis"
30
+
31
+ spec.add_development_dependency "bundler", "~> 1.7"
32
+ spec.add_development_dependency "rake", "~> 10.0"
33
+ #spec.add_development_dependency "rspec"
34
+ #spec.add_development_dependency "rspec-nc"
35
+ spec.add_development_dependency "test-unit"
36
+ spec.add_development_dependency "test-unit-notify"
37
+ spec.add_development_dependency "minitest"
38
+ spec.add_development_dependency "terminal-notifier"
39
+ spec.add_development_dependency "guard"
40
+ spec.add_development_dependency "guard-rspec"
41
+ spec.add_development_dependency "pry"
42
+ spec.add_development_dependency "pry-remote"
43
+ spec.add_development_dependency "pry-nav"
44
+ #spec.add_development_dependency "rice"
45
+ spec.add_development_dependency "rake-compiler"
46
+ spec.add_development_dependency "geminabox"
47
+
48
+ end
49
+
metadata ADDED
@@ -0,0 +1,277 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wovnrb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jeff Sandford
8
+ - Antoine David
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-05-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nokogumbo
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '>='
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: redis
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: bundler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ version: '1.7'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: '1.7'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rake
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: '10.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '10.0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: test-unit
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: test-unit-notify
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: minitest
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: terminal-notifier
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: guard
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ - !ruby/object:Gem::Dependency
141
+ name: guard-rspec
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - '>='
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ type: :development
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ - !ruby/object:Gem::Dependency
155
+ name: pry
156
+ requirement: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - '>='
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ type: :development
162
+ prerelease: false
163
+ version_requirements: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - '>='
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ - !ruby/object:Gem::Dependency
169
+ name: pry-remote
170
+ requirement: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - '>='
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ type: :development
176
+ prerelease: false
177
+ version_requirements: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ - !ruby/object:Gem::Dependency
183
+ name: pry-nav
184
+ requirement: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - '>='
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ type: :development
190
+ prerelease: false
191
+ version_requirements: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - '>='
194
+ - !ruby/object:Gem::Version
195
+ version: '0'
196
+ - !ruby/object:Gem::Dependency
197
+ name: rake-compiler
198
+ requirement: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - '>='
201
+ - !ruby/object:Gem::Version
202
+ version: '0'
203
+ type: :development
204
+ prerelease: false
205
+ version_requirements: !ruby/object:Gem::Requirement
206
+ requirements:
207
+ - - '>='
208
+ - !ruby/object:Gem::Version
209
+ version: '0'
210
+ - !ruby/object:Gem::Dependency
211
+ name: geminabox
212
+ requirement: !ruby/object:Gem::Requirement
213
+ requirements:
214
+ - - '>='
215
+ - !ruby/object:Gem::Version
216
+ version: '0'
217
+ type: :development
218
+ prerelease: false
219
+ version_requirements: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - '>='
222
+ - !ruby/object:Gem::Version
223
+ version: '0'
224
+ description: ALPHA VERSION, not in a useable form.
225
+ email:
226
+ - jeff@wovn.io
227
+ executables: []
228
+ extensions: []
229
+ extra_rdoc_files: []
230
+ files:
231
+ - .gitignore
232
+ - .ruby-version
233
+ - Gemfile
234
+ - LICENSE.txt
235
+ - README.md
236
+ - Rakefile
237
+ - lib/wovnrb.rb
238
+ - lib/wovnrb/headers.rb
239
+ - lib/wovnrb/lang.rb
240
+ - lib/wovnrb/railtie.rb
241
+ - lib/wovnrb/store.rb
242
+ - lib/wovnrb/version.rb
243
+ - spec/spec_helper.rb
244
+ - spec/wovnrb_spec.rb
245
+ - test/lib/test_headers.rb
246
+ - test/lib/test_lang.rb
247
+ - values/values
248
+ - wovnrb.gemspec
249
+ homepage: ''
250
+ licenses:
251
+ - MIT
252
+ metadata: {}
253
+ post_install_message:
254
+ rdoc_options: []
255
+ require_paths:
256
+ - lib
257
+ required_ruby_version: !ruby/object:Gem::Requirement
258
+ requirements:
259
+ - - '>='
260
+ - !ruby/object:Gem::Version
261
+ version: '0'
262
+ required_rubygems_version: !ruby/object:Gem::Requirement
263
+ requirements:
264
+ - - '>='
265
+ - !ruby/object:Gem::Version
266
+ version: '0'
267
+ requirements: []
268
+ rubyforge_project:
269
+ rubygems_version: 2.0.14
270
+ signing_key:
271
+ specification_version: 4
272
+ summary: Gem for WOVN.io
273
+ test_files:
274
+ - spec/spec_helper.rb
275
+ - spec/wovnrb_spec.rb
276
+ - test/lib/test_headers.rb
277
+ - test/lib/test_lang.rb