mugen 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/.travis.yml +5 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +5 -0
- data/LICENSE +20 -0
- data/README.md +65 -0
- data/Rakefile +31 -0
- data/autotest/discover.rb +1 -0
- data/generators/README +3 -0
- data/generators/USAGE +34 -0
- data/generators/mugen_generator.rb +63 -0
- data/generators/templates/app/controllers/mygengo/account_controller.rb +10 -0
- data/generators/templates/app/controllers/mygengo/comments_controller.rb +6 -0
- data/generators/templates/app/controllers/mygengo/jobs_controller.rb +153 -0
- data/generators/templates/app/helpers/mugen_helper.rb +11 -0
- data/generators/templates/app/views/layouts/mygengo.html.erb +52 -0
- data/generators/templates/app/views/mygengo/account/_balance.haml +5 -0
- data/generators/templates/app/views/mygengo/account/_stats.haml +9 -0
- data/generators/templates/app/views/mygengo/account/index.haml +3 -0
- data/generators/templates/app/views/mygengo/comments/_comment.haml +7 -0
- data/generators/templates/app/views/mygengo/comments/_form.haml +10 -0
- data/generators/templates/app/views/mygengo/jobs/_comments.haml +8 -0
- data/generators/templates/app/views/mygengo/jobs/_feedback.haml +8 -0
- data/generators/templates/app/views/mygengo/jobs/_job.haml +36 -0
- data/generators/templates/app/views/mygengo/jobs/_revision.haml +2 -0
- data/generators/templates/app/views/mygengo/jobs/index.haml +8 -0
- data/generators/templates/app/views/mygengo/jobs/new.haml +53 -0
- data/generators/templates/app/views/mygengo/jobs/reject_form.haml +36 -0
- data/generators/templates/app/views/mygengo/jobs/review_form.haml +54 -0
- data/generators/templates/app/views/mygengo/jobs/revise_form.haml +7 -0
- data/generators/templates/app/views/mygengo/jobs/revision.haml +8 -0
- data/generators/templates/app/views/mygengo/jobs/show.haml +38 -0
- data/generators/templates/config/initializers/mugen.rb +2 -0
- data/generators/templates/config/routes.rb +16 -0
- data/generators/templates/public/stylesheets/mygengo/base.css +397 -0
- data/generators/templates/public/stylesheets/mygengo/mugen.css +117 -0
- data/generators/templates/public/stylesheets/mygengo/override.css +1 -0
- data/generators/templates/public/stylesheets/mygengo/scaffold.css +56 -0
- data/generators/templates/public/stylesheets/mygengo/style.css +373 -0
- data/lib/generators/mugen/README +3 -0
- data/lib/generators/mugen/USAGE +35 -0
- data/lib/generators/mugen/mugen_generator.rb +50 -0
- data/lib/generators/mugen/templates/app/controllers/mygengo/account_controller.rb +10 -0
- data/lib/generators/mugen/templates/app/controllers/mygengo/comments_controller.rb +6 -0
- data/lib/generators/mugen/templates/app/controllers/mygengo/jobs_controller.rb +153 -0
- data/lib/generators/mugen/templates/app/controllers/mygengo/mygengo_controller.rb +18 -0
- data/lib/generators/mugen/templates/app/helpers/mugen_helper.rb +11 -0
- data/lib/generators/mugen/templates/app/views/layouts/mygengo.html.erb +52 -0
- data/lib/generators/mugen/templates/app/views/mygengo/account/_balance.haml +5 -0
- data/lib/generators/mugen/templates/app/views/mygengo/account/_stats.haml +9 -0
- data/lib/generators/mugen/templates/app/views/mygengo/account/index.haml +3 -0
- data/lib/generators/mugen/templates/app/views/mygengo/comments/_comment.haml +7 -0
- data/lib/generators/mugen/templates/app/views/mygengo/comments/_form.haml +10 -0
- data/lib/generators/mugen/templates/app/views/mygengo/jobs/_comments.haml +8 -0
- data/lib/generators/mugen/templates/app/views/mygengo/jobs/_feedback.haml +8 -0
- data/lib/generators/mugen/templates/app/views/mygengo/jobs/_job.haml +36 -0
- data/lib/generators/mugen/templates/app/views/mygengo/jobs/_revision.haml +2 -0
- data/lib/generators/mugen/templates/app/views/mygengo/jobs/index.haml +8 -0
- data/lib/generators/mugen/templates/app/views/mygengo/jobs/new.haml +53 -0
- data/lib/generators/mugen/templates/app/views/mygengo/jobs/reject_form.haml +36 -0
- data/lib/generators/mugen/templates/app/views/mygengo/jobs/review_form.haml +54 -0
- data/lib/generators/mugen/templates/app/views/mygengo/jobs/revise_form.haml +7 -0
- data/lib/generators/mugen/templates/app/views/mygengo/jobs/revision.haml +8 -0
- data/lib/generators/mugen/templates/app/views/mygengo/jobs/show.haml +38 -0
- data/lib/generators/mugen/templates/config/initializers/mugen.rb +2 -0
- data/lib/generators/mugen/templates/config/routes2.rb +16 -0
- data/lib/generators/mugen/templates/config/routes3.rb +17 -0
- data/lib/generators/mugen/templates/public/images/mygengo/blank +0 -0
- data/lib/generators/mugen/templates/public/stylesheets/mygengo/base.css +397 -0
- data/lib/generators/mugen/templates/public/stylesheets/mygengo/mugen.css +117 -0
- data/lib/generators/mugen/templates/public/stylesheets/mygengo/override.css +1 -0
- data/lib/generators/mugen/templates/public/stylesheets/mygengo/scaffold.css +56 -0
- data/lib/generators/mugen/templates/public/stylesheets/mygengo/style.css +373 -0
- data/lib/mugen.rb +73 -0
- data/lib/mugen/account.rb +27 -0
- data/lib/mugen/client.rb +33 -0
- data/lib/mugen/core_extensions.rb +32 -0
- data/lib/mugen/httparty_extensions.rb +26 -0
- data/lib/mugen/job.rb +169 -0
- data/lib/mugen/jobs.rb +42 -0
- data/lib/mugen/service.rb +30 -0
- data/lib/mugen/version.rb +3 -0
- data/lib/tasks/mugen.rake +5 -0
- data/mugen.gemspec +33 -0
- data/rails/init.rb +1 -0
- data/spec/account_spec.rb +22 -0
- data/spec/job_spec.rb +40 -0
- data/spec/jobs_spec.rb +33 -0
- data/spec/mugen_spec.rb +33 -0
- data/spec/service_spec.rb +21 -0
- data/spec/spec_helper.rb +4 -0
- metadata +191 -0
data/lib/mugen.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'cgi'
|
3
|
+
require 'hmac-sha1'
|
4
|
+
require 'httparty'
|
5
|
+
require 'mugen/core_extensions'
|
6
|
+
require 'mugen/httparty_extensions'
|
7
|
+
|
8
|
+
module Mugen
|
9
|
+
extend self
|
10
|
+
|
11
|
+
autoload :Client, 'mugen/client'
|
12
|
+
autoload :Account, 'mugen/account'
|
13
|
+
autoload :Service, 'mugen/service'
|
14
|
+
autoload :Jobs, 'mugen/jobs'
|
15
|
+
autoload :Job, 'mugen/job'
|
16
|
+
|
17
|
+
@@errors = []
|
18
|
+
|
19
|
+
def api_url=(url)
|
20
|
+
@api_url = url
|
21
|
+
end
|
22
|
+
|
23
|
+
def api_url
|
24
|
+
@api_url || 'http://api.sandbox.mygengo.com/v1/'
|
25
|
+
end
|
26
|
+
|
27
|
+
def api_key=(key)
|
28
|
+
@api_key = key
|
29
|
+
end
|
30
|
+
|
31
|
+
def api_key
|
32
|
+
@api_key or raise "API_KEY is not specified"
|
33
|
+
end
|
34
|
+
|
35
|
+
def private_key=(key)
|
36
|
+
@private_key = key
|
37
|
+
end
|
38
|
+
|
39
|
+
def private_key
|
40
|
+
@private_key or raise "PRIVATE_KEY is not specified"
|
41
|
+
end
|
42
|
+
|
43
|
+
def errors
|
44
|
+
@@errors || []
|
45
|
+
end
|
46
|
+
|
47
|
+
def sign(private_key, data)
|
48
|
+
if Hash === data
|
49
|
+
sorted_keys = data.keys.sort
|
50
|
+
data = sorted_keys.zip(data.values_at(*sorted_keys)).map {|k, v|
|
51
|
+
"#{k}=#{CGI::escape(v.to_s)}"
|
52
|
+
} * '&'
|
53
|
+
end
|
54
|
+
|
55
|
+
HMAC::SHA1.hexdigest private_key, data
|
56
|
+
end
|
57
|
+
|
58
|
+
def set_params(options = {}, method = :get)
|
59
|
+
params = ActiveSupport::OrderedHash.new
|
60
|
+
params.merge! '_method' => 'post' if method == :post
|
61
|
+
params.merge! 'api_key' => Mugen.api_key
|
62
|
+
params.merge! 'data' => options.to_json unless options.empty?
|
63
|
+
params.merge! 'ts' => Time.now.gmtime.to_i.to_s
|
64
|
+
if method == :get
|
65
|
+
params.merge! 'api_sig' => sign(Mugen.private_key, params)
|
66
|
+
else
|
67
|
+
params.merge! 'api_sig' => sign(Mugen.private_key, params.to_json.gsub('/', '\/'))
|
68
|
+
end
|
69
|
+
|
70
|
+
params
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Mugen
|
2
|
+
class Account < Client
|
3
|
+
class << self
|
4
|
+
|
5
|
+
#
|
6
|
+
# /account/stats (GET)
|
7
|
+
# Retrieves account stats, such as orders made.
|
8
|
+
#
|
9
|
+
def stats(options={})
|
10
|
+
res = self.get "/account/stats", :query => options
|
11
|
+
check_for_errors(res)
|
12
|
+
res['response']
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# /account/balance (GET)
|
17
|
+
# Retrieves account balance in credits
|
18
|
+
#
|
19
|
+
def balance(options={})
|
20
|
+
res = self.get "/account/balance", :query => options
|
21
|
+
check_for_errors(res)
|
22
|
+
res['response']
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/mugen/client.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
module Mugen
|
2
|
+
class Client
|
3
|
+
include HTTParty
|
4
|
+
base_uri Mugen.api_url || 'http://api.sandbox.mygengo.com/v1/'
|
5
|
+
headers = {
|
6
|
+
'Accept' => 'application/json',
|
7
|
+
'User-Agent' => 'myGengo Mugen Rails API Wrapper; Version 0.0.1; http://github.com/shell/mugen'
|
8
|
+
}
|
9
|
+
|
10
|
+
# debug_output $stderr
|
11
|
+
|
12
|
+
def self.before_get(path, options)
|
13
|
+
options[:query] = Mugen.set_params(options[:query]) if options.has_key? :query
|
14
|
+
[path, options]
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.before_post(path, options)
|
18
|
+
options[:body] = Mugen.set_params(options[:body], :post) if options.has_key? :body
|
19
|
+
[path, options]
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.before_put(path, options)
|
23
|
+
options[:body] = Mugen.set_params(options[:body], :post) if options.has_key? :body
|
24
|
+
[path, options]
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.check_for_errors(res)
|
28
|
+
if res['opstat'] != 'ok' && res['err']
|
29
|
+
Mugen.errors << res['err']['msg']
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
def sorted_hash
|
4
|
+
self.keys.sort
|
5
|
+
end
|
6
|
+
|
7
|
+
# This hack to enables CGI::escape instead of URI.encode in to_params
|
8
|
+
def normalize_param(key, value)
|
9
|
+
param = ''
|
10
|
+
stack = []
|
11
|
+
|
12
|
+
if value.is_a?(Array)
|
13
|
+
param << value.map { |element| normalize_param("#{key}[]", element) }.join
|
14
|
+
elsif value.is_a?(Hash)
|
15
|
+
stack << [key,value]
|
16
|
+
else
|
17
|
+
param << "#{key}=#{CGI::escape(value.to_s)}&"
|
18
|
+
end
|
19
|
+
|
20
|
+
stack.each do |parent, hash|
|
21
|
+
hash.each do |key, value|
|
22
|
+
if value.is_a?(Hash)
|
23
|
+
stack << ["#{parent}[#{key}]", value]
|
24
|
+
else
|
25
|
+
param << normalize_param("#{parent}[#{key}]", value)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
param
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module HTTParty
|
2
|
+
module ClassMethods
|
3
|
+
alias :original_get :get
|
4
|
+
alias :original_post :post
|
5
|
+
alias :original_put :put
|
6
|
+
|
7
|
+
# Inject pre GET hook
|
8
|
+
def get(path, options={})
|
9
|
+
path, options = before_get(path, options) if respond_to?(:before_get)
|
10
|
+
original_get(path, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Inject pre POST hook
|
14
|
+
def post(path, options={})
|
15
|
+
path, options = before_post(path, options) if respond_to?(:before_post)
|
16
|
+
original_post(path, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Inject pre PUT hook
|
20
|
+
def put(path, options={})
|
21
|
+
path, options = before_put(path, options) if respond_to?(:before_put)
|
22
|
+
original_put(path, options)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
data/lib/mugen/job.rb
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
module Mugen
|
3
|
+
class Job < Client
|
4
|
+
class << self
|
5
|
+
|
6
|
+
attr_accessor :job_id, :slug, :body_src, :body_tgt, :lc_src, :lc_tgt,
|
7
|
+
:unit_count, :tier, :credits, :status, :capcha_url,
|
8
|
+
:eta, :callback_url, :auto_approve, :ctime, :custom_data,
|
9
|
+
:mt, :comment, :as_group
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
#
|
14
|
+
# translate/job/{id} (GET)
|
15
|
+
#
|
16
|
+
# Retrieves a specific job
|
17
|
+
#
|
18
|
+
def find(id, options={})
|
19
|
+
res = self.get "/translate/job/#{id}", :query => options
|
20
|
+
check_for_errors(res)
|
21
|
+
res['response']['job']
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# translate/job (POST)
|
26
|
+
#
|
27
|
+
# Post a new job for translation
|
28
|
+
#
|
29
|
+
def create(options = {})
|
30
|
+
if options.nil? || options.empty?
|
31
|
+
raise Exception, '"options" missing required parameters'
|
32
|
+
end
|
33
|
+
job = { 'job' => options }
|
34
|
+
res = self.post "/translate/job", :body => job
|
35
|
+
check_for_errors(res)
|
36
|
+
res['response']
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# translate/job/{id} (PUT)
|
41
|
+
#
|
42
|
+
# Updates a job to translate.
|
43
|
+
#
|
44
|
+
def update(job_id, action, options = {})
|
45
|
+
# if options.nil? || options.empty?
|
46
|
+
# raise Exception, '"options" missing required parameters'
|
47
|
+
# end
|
48
|
+
options.merge! :action => action
|
49
|
+
job = options
|
50
|
+
res = self.put "/translate/job/#{job_id}", :body => job
|
51
|
+
check_for_errors(res)
|
52
|
+
res['response']
|
53
|
+
end
|
54
|
+
|
55
|
+
def purchase(job_id, options = {})
|
56
|
+
update(job_id, 'purchase', options)
|
57
|
+
end
|
58
|
+
|
59
|
+
def revise(job_id, options = {})
|
60
|
+
update(job_id, 'revise', options)
|
61
|
+
end
|
62
|
+
|
63
|
+
def approve(job_id, options = {})
|
64
|
+
update(job_id, 'approve', options)
|
65
|
+
end
|
66
|
+
|
67
|
+
def reject(job_id, options = {})
|
68
|
+
update(job_id, 'reject', options)
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# translate/job/{id} (DELETE)
|
73
|
+
#
|
74
|
+
# Cancels the job. You can only cancel a job if it has not been
|
75
|
+
# started already by a translator.
|
76
|
+
#
|
77
|
+
def delete(id, options = {})
|
78
|
+
options.merge!('_method' => 'delete')
|
79
|
+
res = self.delete "/translate/job/#{id}", :query => options
|
80
|
+
check_for_errors(res)
|
81
|
+
res['response']
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# translate/job/{id}/preview (GET)
|
86
|
+
#
|
87
|
+
# Renders a JPEG preview of the translated text
|
88
|
+
# N.B. - if the request is valid, a raw JPEG stream is returned.
|
89
|
+
#
|
90
|
+
def preview(id, options = {})
|
91
|
+
name = "#{Time.now.gmtime.to_i}.jpg"
|
92
|
+
res = self.get "/translate/job/#{id}/preview", :query => options
|
93
|
+
check_for_errors(res)
|
94
|
+
fn = if defined?(Rails)
|
95
|
+
Rails.root.join('public', 'images', 'mygengo', name)
|
96
|
+
else
|
97
|
+
Tempfile.new(name)
|
98
|
+
end
|
99
|
+
if !File.exists?(fn)
|
100
|
+
tempfile = File.new(fn, "w+")
|
101
|
+
tempfile << res
|
102
|
+
tempfile.close
|
103
|
+
"mygengo/#{name}"
|
104
|
+
else
|
105
|
+
nil
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
#
|
110
|
+
# translate/job/{id}/comment (POST)
|
111
|
+
#
|
112
|
+
# Submits a new comment to the job's comment thread.
|
113
|
+
#
|
114
|
+
def create_comment(job_id, comment)
|
115
|
+
if comment.nil? || comment.empty?
|
116
|
+
raise Exception, '"options" missing required parameters'
|
117
|
+
end
|
118
|
+
res = self.post "/translate/job/#{job_id}/comment", :body => comment
|
119
|
+
check_for_errors(res)
|
120
|
+
res['response']
|
121
|
+
end
|
122
|
+
|
123
|
+
#
|
124
|
+
# translate/job/{id}/comments (GET)
|
125
|
+
#
|
126
|
+
# Retrieves the comment thread for a job
|
127
|
+
#
|
128
|
+
def comments(id, options = {})
|
129
|
+
res = self.get "/translate/job/#{id}/comments", :query => options
|
130
|
+
check_for_errors(res)
|
131
|
+
res['response']['thread']
|
132
|
+
end
|
133
|
+
|
134
|
+
#
|
135
|
+
# translate/job/{id}/feedback (GET)
|
136
|
+
#
|
137
|
+
# Retrieves the feedback
|
138
|
+
#
|
139
|
+
def feedback(id, options = {})
|
140
|
+
res = self.get "/translate/job/#{id}/feedback", :query => options
|
141
|
+
check_for_errors(res)
|
142
|
+
res['response']['feedback']
|
143
|
+
end
|
144
|
+
|
145
|
+
#
|
146
|
+
# translate/job/{id}/revisions (GET)
|
147
|
+
#
|
148
|
+
# Gets list of revision resources for a job.
|
149
|
+
#
|
150
|
+
def revisions(id, options = {})
|
151
|
+
res = self.get "/translate/job/#{id}/revisions", :query => options
|
152
|
+
check_for_errors(res)
|
153
|
+
res['response']['revisions']
|
154
|
+
end
|
155
|
+
|
156
|
+
#
|
157
|
+
# translate/job/{job_id}/revision/{id} (GET)
|
158
|
+
#
|
159
|
+
# Gets specific revision for a job.
|
160
|
+
#
|
161
|
+
def revision(job_id, id, options = {})
|
162
|
+
res = self.get "/translate/job/#{job_id}/revision/#{id}", :query => options
|
163
|
+
check_for_errors(res)
|
164
|
+
res['response']['revision']
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
data/lib/mugen/jobs.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
module Mugen
|
2
|
+
class Jobs < Client
|
3
|
+
class << self
|
4
|
+
#
|
5
|
+
# translate/jobs (GET)
|
6
|
+
#
|
7
|
+
# Retrieves a list of resources for the most recent jobs filtered
|
8
|
+
# by the given parameters.
|
9
|
+
#
|
10
|
+
def all(options={})
|
11
|
+
res = self.get "/translate/jobs", :query => options
|
12
|
+
check_for_errors(res)
|
13
|
+
res['response']
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
#
|
18
|
+
# translate/jobs/{id} (GET)
|
19
|
+
#
|
20
|
+
# Retrieves the group of jobs that were previously submitted
|
21
|
+
# together.
|
22
|
+
#
|
23
|
+
def by_group(id, options={})
|
24
|
+
res = self.get "/translate/jobs/#{id}", :query => options
|
25
|
+
check_for_errors(res)
|
26
|
+
res['response']
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# translate/jobs (POST)
|
31
|
+
#
|
32
|
+
# Submits a job or group of jobs to translate.
|
33
|
+
#
|
34
|
+
def create(options = {})
|
35
|
+
res = self.post "/translate/jobs", :body => options
|
36
|
+
check_for_errors(res)
|
37
|
+
res['response']
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Mugen
|
2
|
+
class Service < Client
|
3
|
+
class << self
|
4
|
+
|
5
|
+
#
|
6
|
+
# translate/service/language_pairs (GET)
|
7
|
+
#
|
8
|
+
# Returns supported translation language pairs, tiers, and credit
|
9
|
+
# prices.
|
10
|
+
#
|
11
|
+
def language_pairs(options={})
|
12
|
+
res = self.get "/translate/service/language_pairs", :query => options
|
13
|
+
check_for_errors(res)
|
14
|
+
res['response']
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# translate/service/languages (GET)
|
19
|
+
#
|
20
|
+
# Returns a list of supported languages and their language codes.
|
21
|
+
#
|
22
|
+
def languages(options={})
|
23
|
+
res = self.get "/translate/service/languages", :query => options
|
24
|
+
check_for_errors(res)
|
25
|
+
res['response']
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|