wrtranslate 0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENCE +20 -0
- data/README +87 -0
- data/Rakefile +73 -0
- data/bin/translate +10 -0
- data/install.rb +88 -0
- data/lib/language.rb +47 -0
- data/lib/string.extend.rb +15 -0
- data/lib/translate.rb +274 -0
- data/test/translate_test.rb +196 -0
- data/uninstall.rb +1 -0
- metadata +71 -0
data/LICENCE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 [Martin Catty]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
= Translate
|
2
|
+
|
3
|
+
Translate provides an easy to translate word or expression into another,
|
4
|
+
using wordreference. This website does'nt provide API yet so I decided
|
5
|
+
to create this script which make GET requests and parse results using Hpricot.
|
6
|
+
|
7
|
+
Default translation is english to french but it can be overriden by
|
8
|
+
providing command line options or config file.
|
9
|
+
Translate can be used directly in command line or inside an other program.
|
10
|
+
|
11
|
+
== Installation
|
12
|
+
|
13
|
+
=== Gem installation
|
14
|
+
|
15
|
+
Download and install translate with the following:
|
16
|
+
|
17
|
+
gem install translate
|
18
|
+
|
19
|
+
=== Common installation
|
20
|
+
|
21
|
+
Checkout the source code on github: git clone git://github.com/fuse/translate.git
|
22
|
+
|
23
|
+
ruby install.rb
|
24
|
+
|
25
|
+
It will ask you where you want to install the translate library and binary in
|
26
|
+
your path.
|
27
|
+
|
28
|
+
_Warning_:
|
29
|
+
Be carefull to *NOT* install translate with the both way.
|
30
|
+
|
31
|
+
== Usage
|
32
|
+
|
33
|
+
=== From command line
|
34
|
+
|
35
|
+
translate world
|
36
|
+
Will translate world from english to french.
|
37
|
+
|
38
|
+
translate casa -f it -t en
|
39
|
+
Will translate casa from italian to english.
|
40
|
+
|
41
|
+
If you want to know which language can be used :
|
42
|
+
translate -l
|
43
|
+
|
44
|
+
If you want to know all options of translate :
|
45
|
+
translate -h
|
46
|
+
|
47
|
+
=== From another program
|
48
|
+
|
49
|
+
You only have to create a new instance or the translation class by giving
|
50
|
+
the expression to translate and your options and explicitly call translate.
|
51
|
+
|
52
|
+
translation = Translation.new("maison", { :from => :fr, :to => :en, :more => true })
|
53
|
+
translation.translate
|
54
|
+
|
55
|
+
Results are directly available through translation.items
|
56
|
+
|
57
|
+
=== Setup default options
|
58
|
+
|
59
|
+
If you don't want to retype options each time you're using translate, just
|
60
|
+
create a yaml config file into your home named translate.yml using this syntax :
|
61
|
+
translate:
|
62
|
+
from: fr
|
63
|
+
to: en
|
64
|
+
width: 100
|
65
|
+
more: true
|
66
|
+
|
67
|
+
Priority is given to command line options, config file options and finally
|
68
|
+
default options.
|
69
|
+
|
70
|
+
== Licence
|
71
|
+
|
72
|
+
Translate is available under MIT-LICENSE.
|
73
|
+
|
74
|
+
= Other
|
75
|
+
|
76
|
+
Author: Martin Catty <martin@noremember.org>
|
77
|
+
License: Copyright 2008 by Martin Catty.
|
78
|
+
Released under an MIT-style licence. See the LICENCE file
|
79
|
+
included in the distribution.
|
80
|
+
|
81
|
+
== Warranty
|
82
|
+
|
83
|
+
This software is provided "as is" and without any express or
|
84
|
+
implied warranties, including, without limitation, the implied
|
85
|
+
warranties of merchantibility and fitness for a particular
|
86
|
+
purpose.
|
87
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
require 'rake/contrib/rubyforgepublisher'
|
6
|
+
require 'rubyforge'
|
7
|
+
|
8
|
+
SPEC = Gem::Specification.new do |s|
|
9
|
+
s.name = "wrtranslate"
|
10
|
+
s.version = "0.2"
|
11
|
+
s.author = "Martin Catty"
|
12
|
+
s.email = "martin@noremember.org"
|
13
|
+
s.homepage = "http://github.com/fuse/translate"
|
14
|
+
s.rubyforge_project = "wrtranslate"
|
15
|
+
s.summary = "translate provide an easy way to translate word or expression using wordreference.com"
|
16
|
+
s.description = "translate make get requests and parse the result using hpricot. You can use it inside an other program or directly via command line."
|
17
|
+
s.files = [ "Rakefile", "install.rb", "uninstall.rb", "README", "LICENCE" ] +
|
18
|
+
Dir.glob("{bin,doc,lib,test}/**/*")
|
19
|
+
s.bindir = "bin"
|
20
|
+
s.require_path = "lib"
|
21
|
+
s.test_files = "test/translate_test.rb"
|
22
|
+
s.has_rdoc = true
|
23
|
+
s.extra_rdoc_files = ["README"]
|
24
|
+
s.executables = "translate"
|
25
|
+
s.add_dependency("hpricot")
|
26
|
+
end
|
27
|
+
|
28
|
+
desc 'Run all tests by default'
|
29
|
+
task :default => :test
|
30
|
+
|
31
|
+
task :gem
|
32
|
+
Rake::GemPackageTask.new(SPEC) do |pkg|
|
33
|
+
pkg.need_zip = true
|
34
|
+
pkg.need_tar_bz2 = true
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "Install the application"
|
38
|
+
task :install do
|
39
|
+
ruby "install.rb"
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Publish documentation to RubyForge"
|
43
|
+
task :publish_doc => [:rdoc] do
|
44
|
+
rf = Rake::RubyForgePublisher.new(SPEC.rubyforge_project, 'fuse')
|
45
|
+
rf.upload
|
46
|
+
puts "Published documentation to RubyForge"
|
47
|
+
end
|
48
|
+
|
49
|
+
desc "Release gem #{SPEC.name}-#{SPEC.version}.gem"
|
50
|
+
task :release => [:gem, :publish_doc] do
|
51
|
+
rf = RubyForge.new.configure
|
52
|
+
puts "Logging in"
|
53
|
+
rf.login
|
54
|
+
|
55
|
+
puts "Releasing #{SPEC.name} v.#{SPEC.version}"
|
56
|
+
|
57
|
+
files = Dir.glob('pkg/*.{zip,bz2,gem}')
|
58
|
+
rf.add_release SPEC.rubyforge_project, SPEC.rubyforge_project, SPEC.version, *files
|
59
|
+
end
|
60
|
+
|
61
|
+
Rake::TestTask.new(:test) do |t|
|
62
|
+
t.libs << 'lib'
|
63
|
+
t.pattern = 'test/**/*_test.rb'
|
64
|
+
t.verbose = true
|
65
|
+
end
|
66
|
+
|
67
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
68
|
+
rdoc.title = 'Translate'
|
69
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
70
|
+
rdoc.options << '--charset' << 'utf-8'
|
71
|
+
rdoc.rdoc_files.include('README')
|
72
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
73
|
+
end
|
data/bin/translate
ADDED
data/install.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# Unix's installer for the translate script.
|
2
|
+
require "ftools"
|
3
|
+
|
4
|
+
LIBRARY_PATH = File.join("lib", "translate.rb")
|
5
|
+
EXECUTABLE_PATH = "translate"
|
6
|
+
|
7
|
+
def check_privileges
|
8
|
+
userid = `id -u`.chomp.to_i
|
9
|
+
unless userid.zero?
|
10
|
+
puts "You must have root's privileges to install translate."
|
11
|
+
interrupt
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def interrupt
|
16
|
+
puts "Bye."
|
17
|
+
exit
|
18
|
+
end
|
19
|
+
|
20
|
+
def file_not_found(path)
|
21
|
+
puts "#{path} does'nt exists, installer is going to stop."
|
22
|
+
interrupt
|
23
|
+
end
|
24
|
+
|
25
|
+
def success
|
26
|
+
puts %q{
|
27
|
+
The translate library and executable have been both successfully installed.
|
28
|
+
You can start using it by typing :
|
29
|
+
translate -h
|
30
|
+
}
|
31
|
+
interrupt
|
32
|
+
end
|
33
|
+
|
34
|
+
def executable_available?
|
35
|
+
File.exists?(EXECUTABLE_PATH)
|
36
|
+
end
|
37
|
+
|
38
|
+
def library_available?
|
39
|
+
File.exists?(LIBRARY_PATH)
|
40
|
+
end
|
41
|
+
|
42
|
+
def copy(from, to)
|
43
|
+
if File.directory?(to) and File.writable?(to)
|
44
|
+
filename = File.basename(from)
|
45
|
+
if (File.copy(from, to) rescue false)
|
46
|
+
puts "#{filename} successfully copied to #{to}"
|
47
|
+
else
|
48
|
+
puts "Fail to copy #{filename} to #{to}"
|
49
|
+
interrupt
|
50
|
+
end
|
51
|
+
else
|
52
|
+
puts "Directory #{to} is not a directory or is not writable."
|
53
|
+
interrupt
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def install(from, destinations, name)
|
58
|
+
begin
|
59
|
+
destinations = destinations.reject { |d| "." == d }.uniq.sort
|
60
|
+
puts "Please choose a directory to install #{name} :"
|
61
|
+
destinations.each_with_index do |dir, @index|
|
62
|
+
puts "\t[#{@index += 1}] #{dir}"
|
63
|
+
end
|
64
|
+
puts "\t[#{@index += 1}] Exit installer"
|
65
|
+
choice = STDIN.gets.to_i
|
66
|
+
end while not choice.is_a?(Integer) or not choice.between?(1, @index)
|
67
|
+
choice == @index ? interrupt : copy(from, destinations[choice - 1])
|
68
|
+
return destinations[choice - 1]
|
69
|
+
end
|
70
|
+
|
71
|
+
def install_library
|
72
|
+
library_available? ? install(LIBRARY_PATH, $LOAD_PATH, "the library translate.rb") : file_not_found(LIBRARY_PATH)
|
73
|
+
end
|
74
|
+
|
75
|
+
def install_executable
|
76
|
+
if executable_available?
|
77
|
+
paths = `echo $PATH`.chomp.split(':')
|
78
|
+
destination = install(EXECUTABLE_PATH, paths, "the executable translate")
|
79
|
+
File.chmod(0755, File.join(destination, EXECUTABLE_PATH)) if destination
|
80
|
+
else
|
81
|
+
file_not_found(EXECUTABLE_PATH)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
check_privileges
|
86
|
+
install_library
|
87
|
+
install_executable
|
88
|
+
success
|
data/lib/language.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
module Translate
|
2
|
+
module Language
|
3
|
+
# Language module contains the different languages available and defined
|
4
|
+
# the directions which can be used.
|
5
|
+
EN = "English"
|
6
|
+
FR = "French"
|
7
|
+
IT = "Italian"
|
8
|
+
PL = "Polish"
|
9
|
+
RO = "Romanian"
|
10
|
+
CZ = "Czech"
|
11
|
+
GR = "Greek"
|
12
|
+
TR = "Turkish"
|
13
|
+
ZH = "Chinese"
|
14
|
+
JA = "Japanese"
|
15
|
+
KO = "Korean"
|
16
|
+
|
17
|
+
DIRECTIONS = {
|
18
|
+
EN => [ "CZ", "FR", "GR", "IT", "JA", "KO", "PL", "RO", "TR", "ZH" ],
|
19
|
+
FR => [ "EN" ],
|
20
|
+
IT => [ "EN" ]
|
21
|
+
}
|
22
|
+
|
23
|
+
# Show the available translations on the command line. You can invoke
|
24
|
+
# this method by using :
|
25
|
+
# $ translate -l
|
26
|
+
# It will print the language's abbreviation and real name (in english).
|
27
|
+
def self.available_translations
|
28
|
+
puts "Available translations :\n"
|
29
|
+
(Language.constants - [DIRECTIONS]).sort.each do |l|
|
30
|
+
constant = const_get(l)
|
31
|
+
puts "\t- #{constant} (#{l.downcase}) to #{DIRECTIONS[constant].map { |c|
|
32
|
+
"#{const_get(c)} (#{c.downcase})"
|
33
|
+
}.join(', ')}" if Language::DIRECTIONS.include?(constant)
|
34
|
+
end
|
35
|
+
end # available_translations
|
36
|
+
|
37
|
+
# Check if the original and final languages are available.
|
38
|
+
def self.available_translation?(*args)
|
39
|
+
from, to = args.map { |a| a.to_s.strip.upcase }
|
40
|
+
return false if from.blank? or to.blank?
|
41
|
+
self.const_defined?(from) and self.const_defined?(to) and DIRECTIONS[self.const_get(from)].include?(to)
|
42
|
+
end # available_translation?
|
43
|
+
|
44
|
+
def self.klass_fren; end
|
45
|
+
def self.klass_iten; end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class String
|
2
|
+
def blank?
|
3
|
+
self !~ /\S/
|
4
|
+
end # blank
|
5
|
+
|
6
|
+
def truncate(length = 30, truncate_string = "...")
|
7
|
+
return if blank?
|
8
|
+
(self.length > length ? self[0...(length - truncate_string.length)] + truncate_string : self).to_s
|
9
|
+
end # truncate
|
10
|
+
|
11
|
+
def sanitize
|
12
|
+
# strip html tags and html code of the arrow (=>)
|
13
|
+
self.strip.gsub(/<.*?>|⇒/, '')
|
14
|
+
end #sanitize
|
15
|
+
end
|
data/lib/translate.rb
ADDED
@@ -0,0 +1,274 @@
|
|
1
|
+
module Translate
|
2
|
+
# Translate provides an easy to translate word or expression into another,
|
3
|
+
# using wordreference. This website does'nt provide API yet so I decided
|
4
|
+
# to create this script which make GET requests and parse results using Hpricot.
|
5
|
+
# Default translation is english to french but it can be overriden by
|
6
|
+
# providing command line options or config file.
|
7
|
+
# Translate can be used directly in command line or inside an other program.
|
8
|
+
#
|
9
|
+
# == Command line example
|
10
|
+
#
|
11
|
+
# $ translate world
|
12
|
+
# Will translate world from english to french.
|
13
|
+
# $ translate casa -f it -t en
|
14
|
+
# Will translate casa from italian to english.
|
15
|
+
#
|
16
|
+
# If you want to know which language can be used :
|
17
|
+
# $ translate -l
|
18
|
+
#
|
19
|
+
# If you want to know all options of translate :
|
20
|
+
# $ translate -h
|
21
|
+
#
|
22
|
+
# == Setup default options
|
23
|
+
#
|
24
|
+
# If you don't want to retype options each time you're using translate, just
|
25
|
+
# create a config file into your home named translate.yml using this syntax :
|
26
|
+
# translate:
|
27
|
+
# from: fr
|
28
|
+
# to: en
|
29
|
+
# width: 100
|
30
|
+
# more: true
|
31
|
+
# Priority is given to command line options, config file options and finally
|
32
|
+
# default options.
|
33
|
+
#
|
34
|
+
# == How to use in another program ?
|
35
|
+
#
|
36
|
+
# You only have to create a new instance or the translation class by giving
|
37
|
+
# the expression to translate and your options and explicitly call translate.
|
38
|
+
#
|
39
|
+
# === Example :
|
40
|
+
#
|
41
|
+
# translation = Translation.new("maison", { :from => :fr, :to => :en, :more => true })
|
42
|
+
# translation.translate
|
43
|
+
#
|
44
|
+
# Results are directly available through translation.items
|
45
|
+
|
46
|
+
%w(rubygems net/http hpricot open-uri optparse language string.extend).each do |lib|
|
47
|
+
begin
|
48
|
+
require lib
|
49
|
+
rescue LoadError
|
50
|
+
puts "Fail to load #{lib}, exiting."
|
51
|
+
exit
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# You can change default options below. Default settings translate from english
|
56
|
+
# to french without additional translations.
|
57
|
+
URL = 'http://www.wordreference.com/'
|
58
|
+
# Default width, can be overriden.
|
59
|
+
WIDTH = 78
|
60
|
+
MIN_WIDTH = 40
|
61
|
+
CONFIG_FILE = "translate.yml"
|
62
|
+
|
63
|
+
class Translation
|
64
|
+
attr_accessor :from, :to, :more, :expression, :width, :items, :errors
|
65
|
+
OPTIONS = { :more => false, :from => :en, :to => :fr, :width => WIDTH }
|
66
|
+
|
67
|
+
# Initialize translation with expression and options.
|
68
|
+
# Ensure width will be an integer, and provides an empty array of items.
|
69
|
+
def initialize(expression, options = {})
|
70
|
+
self.expression = expression
|
71
|
+
options = OPTIONS.merge(options)
|
72
|
+
for k in options.keys
|
73
|
+
self.send("#{k}=", options[k]) if self.respond_to?(k)
|
74
|
+
end
|
75
|
+
@items = []
|
76
|
+
@width = @width.to_i
|
77
|
+
end # initialize
|
78
|
+
|
79
|
+
# Provide the from, to combination. Example: from en to fr will give enfr.
|
80
|
+
# Usefull to build the final url.
|
81
|
+
def combination
|
82
|
+
@combination ||= "#{from}#{to}"
|
83
|
+
end # combination
|
84
|
+
|
85
|
+
# Only used when translate is called from command line.
|
86
|
+
# Define the separator between two lines.
|
87
|
+
def separator
|
88
|
+
@separator ||= '-' * width
|
89
|
+
end # separator
|
90
|
+
|
91
|
+
# Parse the document retrieved from tree and add items into
|
92
|
+
# the final results array.
|
93
|
+
def translate
|
94
|
+
return nil unless valid?
|
95
|
+
continue = false
|
96
|
+
@items.clear
|
97
|
+
klass = Language.respond_to?("klass_#{combination}") ? Language.send("klass_#{combination}") : "2"
|
98
|
+
tree.search("table.Rtbl#{klass}/tr").each do |child|
|
99
|
+
head = child.search("td.Head:first").first
|
100
|
+
continue = !! (
|
101
|
+
head.html =~ /Principal/ ||
|
102
|
+
head.attributes['title'] =~ /Principal/ ||
|
103
|
+
(head.html =~ /Additional/ and more) ||
|
104
|
+
(head.attributes['title'] =~ /Additional/)) if head.respond_to?(:html)
|
105
|
+
unless ! continue or child.classes =~ /(evenEx|oddEx)/
|
106
|
+
# strip html tags
|
107
|
+
description = child.search("td.FrCN#{klass}/*").to_s.sanitize
|
108
|
+
translation = child.search("td.ToW#{klass}/*").to_s.sanitize
|
109
|
+
@items << Item.new({
|
110
|
+
:description => description,
|
111
|
+
:translation => translation,
|
112
|
+
:new_line => ! child.search("td.FrW#{klass}").empty?
|
113
|
+
}) unless description.empty? and translation.empty?
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end # translate
|
117
|
+
|
118
|
+
# Only used when translate is called from command line.
|
119
|
+
# Print results in the shell.
|
120
|
+
def print
|
121
|
+
lambda { puts "No results found." ; exit }.call if @items.empty?
|
122
|
+
half = (width - 4) / 2 # 4 : 2 slash and space
|
123
|
+
puts @items.inject("") { |o, item|
|
124
|
+
str = item == @items.first ? "#{separator}\n#{@expression.center(width, ' ')}\n" : ""
|
125
|
+
str += "#{separator}\n" if item.new_line
|
126
|
+
str += " %-#{half}s|" % item.description.truncate(half)
|
127
|
+
str += " %-#{half}s\n" % item.translation.truncate(half)
|
128
|
+
str += "#{separator}\n" if item == @items.last
|
129
|
+
o + str
|
130
|
+
}
|
131
|
+
end # print
|
132
|
+
|
133
|
+
# Only used when translate is called from command line.
|
134
|
+
# Print errors in the shell.
|
135
|
+
def print_errors
|
136
|
+
puts @errors.inject("Some errors encountered :") { |str, e|
|
137
|
+
str += "\n\t- #{e}"
|
138
|
+
}
|
139
|
+
end # print_errors
|
140
|
+
|
141
|
+
# Provide the full document retrieved from the url.
|
142
|
+
def tree
|
143
|
+
@tree ||= Hpricot.parse(retrieve)
|
144
|
+
end # tree
|
145
|
+
|
146
|
+
# Wordreference full url.
|
147
|
+
def url
|
148
|
+
@url ||= URI::parse(URI.escape("#{URL}#{combination}/#{expression}"))
|
149
|
+
end # url
|
150
|
+
|
151
|
+
# Check if the translation is valid, ie. options exists and an expression
|
152
|
+
# has been providen. Build an array of errors which will be printed to the
|
153
|
+
# end user.
|
154
|
+
def valid?
|
155
|
+
@errors = []
|
156
|
+
@errors << "Expression can't be blank." if expression.blank?
|
157
|
+
@errors << "Translation from #{from} to #{to} is not available, use translate -l to show available languages." unless Translate::Language.available_translation?(from, to)
|
158
|
+
@errors << "Width must be an integer >= #{MIN_WIDTH}." unless width.is_a?(Integer) and width >= MIN_WIDTH
|
159
|
+
@errors.empty?
|
160
|
+
end # valid?
|
161
|
+
|
162
|
+
# Call a wordreference url, dynamiquely builded with from expression and combination.
|
163
|
+
# We need to provide an User-Agent otherwise we're redirected to yahoo.
|
164
|
+
def retrieve
|
165
|
+
request = Net::HTTP::Get.new(url.path)
|
166
|
+
request.add_field('User-Agent', 'translate')
|
167
|
+
Net::HTTP.new(url.host, url.port).request(request).body
|
168
|
+
end # retrieve
|
169
|
+
end
|
170
|
+
|
171
|
+
class Item
|
172
|
+
attr_accessor :description, :translation, :new_line
|
173
|
+
|
174
|
+
def initialize(attributes = {})
|
175
|
+
for k in attributes.keys
|
176
|
+
self.send("#{k}=", attributes[k]) if self.respond_to?(k)
|
177
|
+
end
|
178
|
+
end # initialize
|
179
|
+
end
|
180
|
+
|
181
|
+
# Load options from config file if exists.
|
182
|
+
def config
|
183
|
+
if has_config_file?
|
184
|
+
section = YAML::load(File.open(config_file_path))["translate"]
|
185
|
+
return section.nil? ? {} : section.keys.inject({}) { |h, k|
|
186
|
+
h[k.to_sym] = section[k]
|
187
|
+
h
|
188
|
+
}
|
189
|
+
end
|
190
|
+
{}
|
191
|
+
end #config
|
192
|
+
|
193
|
+
# Define config file path.
|
194
|
+
def config_file_path
|
195
|
+
File.join(home, CONFIG_FILE)
|
196
|
+
end # config_file_path
|
197
|
+
|
198
|
+
# Check if a config file has been set or not.
|
199
|
+
def has_config_file?
|
200
|
+
File.readable?(config_file_path)
|
201
|
+
end # has_config_file?
|
202
|
+
|
203
|
+
# Try to return the home path using environement var. Home path is not
|
204
|
+
# set on the same var on unix & windows.
|
205
|
+
def home
|
206
|
+
ENV['HOME'] || ENV['USERPROFILE']
|
207
|
+
end # home
|
208
|
+
|
209
|
+
# Parse the command line to register user's options or display help or examples.
|
210
|
+
def parse_command_line
|
211
|
+
options = {}
|
212
|
+
OptionParser.new do |@parser|
|
213
|
+
@parser.banner = 'Usage: translate word [options]'
|
214
|
+
|
215
|
+
@parser.on('-e', '--example', 'Show some examples.') do |option|
|
216
|
+
puts "Examples :\n"
|
217
|
+
puts "\t ./translate house (default translation from english to french)"
|
218
|
+
puts "\t ./translate house -m (show additional translations)"
|
219
|
+
puts "\t ./translate maison -f fr -t en (translate from french to english)"
|
220
|
+
puts "\t ./translate -f fr -t en 'se moquer' (use single or double quote to escape multiple words)"
|
221
|
+
exit
|
222
|
+
end
|
223
|
+
|
224
|
+
@parser.on('-f', '--from language', String, 'Define original language.') do |option|
|
225
|
+
options[:from] = option
|
226
|
+
end
|
227
|
+
|
228
|
+
@parser.on('-l', '--language', 'Show supported languages / translations.') do |option|
|
229
|
+
Translate::Language.available_translations
|
230
|
+
exit
|
231
|
+
end
|
232
|
+
|
233
|
+
@parser.on('-m', '--more', 'Show additional translations.') do |option|
|
234
|
+
options[:more] = option
|
235
|
+
end
|
236
|
+
|
237
|
+
@parser.on('-t', '--to language', String, 'Define destination language.') do |option|
|
238
|
+
options[:to] = option
|
239
|
+
end
|
240
|
+
|
241
|
+
@parser.on('-w', '--width number', String, "Define width, min width is #{MIN_WIDTH}.") do |option|
|
242
|
+
options[:width] = option
|
243
|
+
end
|
244
|
+
|
245
|
+
@parser.on('-v', '--version', String, 'Show version.') do |option|
|
246
|
+
puts "translate 0.2 Martin Catty <martin@noremember.org>"
|
247
|
+
exit
|
248
|
+
end
|
249
|
+
|
250
|
+
@parser.on_tail('-h', '--help', 'Show this message.') do
|
251
|
+
puts @parser
|
252
|
+
exit
|
253
|
+
end
|
254
|
+
begin
|
255
|
+
@parser.parse!(ARGV)
|
256
|
+
expression = ARGV.empty? ? "" : ARGV.shift.strip
|
257
|
+
return Translation.new(expression, Translation::OPTIONS.merge(config).merge(options))
|
258
|
+
rescue
|
259
|
+
puts $!
|
260
|
+
puts @parser
|
261
|
+
exit
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end # parse_command_line
|
265
|
+
|
266
|
+
# Only used when translate is called from command line.
|
267
|
+
# Call the above methods to show results.
|
268
|
+
def translate
|
269
|
+
trap(:INT) { puts "Bye." ; exit }
|
270
|
+
translation = parse_command_line
|
271
|
+
translation.translate
|
272
|
+
translation.errors.empty? ? translation.print : translation.print_errors
|
273
|
+
end # translate
|
274
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
|
3
|
+
$:.unshift(File.join('..', 'lib'))
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require 'translate'
|
7
|
+
|
8
|
+
class TranslateTest < Test::Unit::TestCase
|
9
|
+
include Translate
|
10
|
+
|
11
|
+
def test_available_translations
|
12
|
+
assert_equal false, Translate::Language.available_translation?("", "")
|
13
|
+
assert_equal false, Translate::Language.available_translation?("fr", "")
|
14
|
+
assert_equal false, Translate::Language.available_translation?("", "fr")
|
15
|
+
assert_equal true, Translate::Language.available_translation?("en", "fr")
|
16
|
+
assert_equal true, Translate::Language.available_translation?(:en, :fr)
|
17
|
+
assert_equal false, Translate::Language.available_translation?("de", "fr") # false, fr is not in de list
|
18
|
+
assert_equal false, Translate::Language.available_translation?("jz", "fr") # false, jz does'nt exist
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_translation_validity
|
22
|
+
translation = Translation.new("word")
|
23
|
+
assert_equal true, translation.valid?
|
24
|
+
|
25
|
+
translation = Translation.new("word", { :from => :fr, :to => :us })
|
26
|
+
assert_equal false, translation.valid?
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_url
|
30
|
+
translation = Translation.new("word")
|
31
|
+
assert_equal "http://www.wordreference.com/enfr/word", translation.url.to_s
|
32
|
+
|
33
|
+
translation = Translation.new("hello world")
|
34
|
+
assert_equal "http://www.wordreference.com/enfr/hello%20world", translation.url.to_s
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_string
|
38
|
+
str = ""
|
39
|
+
assert_equal true, str.blank?
|
40
|
+
|
41
|
+
str = " "
|
42
|
+
assert_equal true, str.blank?
|
43
|
+
|
44
|
+
str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus vel mi. Duis est. In vitae erat."
|
45
|
+
assert_equal "Lorem ipsum dolor sit amet,...", str.truncate
|
46
|
+
assert_equal "Lorem...", str.truncate(8)
|
47
|
+
assert_equal "Lorem ipsum...", str.truncate(14)
|
48
|
+
|
49
|
+
str = "Lorem"
|
50
|
+
assert_equal "Lorem", str.truncate(10)
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_options
|
54
|
+
translation = Translation.new("maison", { :from => :fr, :to => :es, :more => true, :width => 100 })
|
55
|
+
|
56
|
+
assert_equal translation.from, :fr
|
57
|
+
assert_equal translation.to, :es
|
58
|
+
assert_equal translation.more, true
|
59
|
+
assert_equal translation.width, 100
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_translation_enfr
|
63
|
+
translation = Translation.new("house", { :from => :en, :to => :fr })
|
64
|
+
translation.translate
|
65
|
+
assert_equal 5, translation.items.size
|
66
|
+
|
67
|
+
# ensure items' array has been cleared
|
68
|
+
translation.translate
|
69
|
+
assert_equal 5, translation.items.size
|
70
|
+
|
71
|
+
translation.more = true
|
72
|
+
translation.translate
|
73
|
+
assert_equal 27, translation.items.size
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_translation_encz
|
77
|
+
translation = Translation.new("house", { :from => :en, :to => :cz })
|
78
|
+
translation.translate
|
79
|
+
assert_equal 4, translation.items.size
|
80
|
+
|
81
|
+
# no more translation
|
82
|
+
translation.more = true
|
83
|
+
translation.translate
|
84
|
+
assert_equal 4, translation.items.size
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_translation_engr
|
88
|
+
translation = Translation.new("house", { :from => :en, :to => :gr })
|
89
|
+
translation.translate
|
90
|
+
assert_equal 3, translation.items.size
|
91
|
+
|
92
|
+
# no more translation
|
93
|
+
translation.more = true
|
94
|
+
translation.translate
|
95
|
+
assert_equal 3, translation.items.size
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_translation_enit
|
99
|
+
translation = Translation.new("house", { :from => :en, :to => :it })
|
100
|
+
translation.translate
|
101
|
+
assert_equal 4, translation.items.size
|
102
|
+
|
103
|
+
# no more translation
|
104
|
+
translation.more = true
|
105
|
+
translation.translate
|
106
|
+
assert_equal 32, translation.items.size
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_translation_enja
|
110
|
+
translation = Translation.new("house", { :from => :en, :to => :ja })
|
111
|
+
translation.translate
|
112
|
+
assert_equal 3, translation.items.size
|
113
|
+
|
114
|
+
# no more translation
|
115
|
+
translation.more = true
|
116
|
+
translation.translate
|
117
|
+
assert_equal 3, translation.items.size
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_translation_enko
|
121
|
+
translation = Translation.new("house", { :from => :en, :to => :ko })
|
122
|
+
translation.translate
|
123
|
+
assert_equal 3, translation.items.size
|
124
|
+
|
125
|
+
# no more translation
|
126
|
+
translation.more = true
|
127
|
+
translation.translate
|
128
|
+
assert_equal 3, translation.items.size
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_translation_enpl
|
132
|
+
translation = Translation.new("house", { :from => :en, :to => :pl })
|
133
|
+
translation.translate
|
134
|
+
assert_equal 3, translation.items.size
|
135
|
+
|
136
|
+
# no more translation
|
137
|
+
translation.more = true
|
138
|
+
translation.translate
|
139
|
+
assert_equal 3, translation.items.size
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_translation_enro
|
143
|
+
translation = Translation.new("house", { :from => :en, :to => :ro })
|
144
|
+
translation.translate
|
145
|
+
assert_equal 3, translation.items.size
|
146
|
+
|
147
|
+
# no more translation
|
148
|
+
translation.more = true
|
149
|
+
translation.translate
|
150
|
+
assert_equal 3, translation.items.size
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_translation_entr
|
154
|
+
translation = Translation.new("house", { :from => :en, :to => :tr })
|
155
|
+
translation.translate
|
156
|
+
assert_equal 4, translation.items.size
|
157
|
+
|
158
|
+
# no more translation
|
159
|
+
translation.more = true
|
160
|
+
translation.translate
|
161
|
+
assert_equal 4, translation.items.size
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_translation_enzh
|
165
|
+
translation = Translation.new("house", { :from => :en, :to => :zh })
|
166
|
+
translation.translate
|
167
|
+
assert_equal 3, translation.items.size
|
168
|
+
|
169
|
+
# no more translation
|
170
|
+
translation.more = true
|
171
|
+
translation.translate
|
172
|
+
assert_equal 3, translation.items.size
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_translation_fren
|
176
|
+
translation = Translation.new("maison", { :from => :fr, :to => :en })
|
177
|
+
translation.translate
|
178
|
+
assert_equal 2, translation.items.size
|
179
|
+
|
180
|
+
# no more translation
|
181
|
+
translation.more = true
|
182
|
+
translation.translate
|
183
|
+
assert_equal 12, translation.items.size
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_translation_iten
|
187
|
+
translation = Translation.new("casa", { :from => :it, :to => :en })
|
188
|
+
translation.translate
|
189
|
+
assert_equal 2, translation.items.size
|
190
|
+
|
191
|
+
# no more translation
|
192
|
+
translation.more = true
|
193
|
+
translation.translate
|
194
|
+
assert_equal 4, translation.items.size
|
195
|
+
end
|
196
|
+
end
|
data/uninstall.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Uninstall hook code here
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wrtranslate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.2"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Martin Catty
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-06 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hpricot
|
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: translate make get requests and parse the result using hpricot. You can use it inside an other program or directly via command line.
|
26
|
+
email: martin@noremember.org
|
27
|
+
executables:
|
28
|
+
- translate
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README
|
33
|
+
files:
|
34
|
+
- Rakefile
|
35
|
+
- install.rb
|
36
|
+
- uninstall.rb
|
37
|
+
- README
|
38
|
+
- LICENCE
|
39
|
+
- bin/translate
|
40
|
+
- lib/language.rb
|
41
|
+
- lib/string.extend.rb
|
42
|
+
- lib/translate.rb
|
43
|
+
- test/translate_test.rb
|
44
|
+
has_rdoc: true
|
45
|
+
homepage: http://github.com/fuse/translate
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options: []
|
48
|
+
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
version:
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: "0"
|
62
|
+
version:
|
63
|
+
requirements: []
|
64
|
+
|
65
|
+
rubyforge_project: wrtranslate
|
66
|
+
rubygems_version: 1.3.1
|
67
|
+
signing_key:
|
68
|
+
specification_version: 2
|
69
|
+
summary: translate provide an easy way to translate word or expression using wordreference.com
|
70
|
+
test_files:
|
71
|
+
- test/translate_test.rb
|