wrtranslate 0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|