dephine 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +14 -0
- data/bin/dephine +1 -1
- data/dephine.gemspec +2 -0
- data/lib/dephine.rb +1 -0
- data/lib/dephine/cli.rb +91 -26
- data/lib/dephine/dictionary.rb +11 -1
- data/lib/dephine/tui.rb +170 -0
- data/lib/dephine/version.rb +1 -1
- metadata +21 -5
data/README.md
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
Google dictionary in terminal
|
4
4
|
|
5
|
+
## Requirements
|
6
|
+
|
7
|
+
* Ruby (1.9)
|
8
|
+
* libncursesw5-dev
|
9
|
+
* [mpg123](http://www.mpg123.de/) (<b>it's not required for OS X</b>)
|
10
|
+
|
5
11
|
## Installation
|
6
12
|
|
7
13
|
$ gem install dephine
|
@@ -22,6 +28,14 @@ Google dictionary in terminal
|
|
22
28
|
Used to indicate a range
|
23
29
|
- he trains anything from seven to eight hours a day
|
24
30
|
|
31
|
+
## Hot-keys
|
32
|
+
|
33
|
+
* Arrow keys.
|
34
|
+
* `Ctrl-n` / `j` to scroll down.
|
35
|
+
* `Ctrl-p` / `k` to scroll up.
|
36
|
+
* `p` to pronounce.
|
37
|
+
* `q` to quit.
|
38
|
+
|
25
39
|
## Contributing
|
26
40
|
|
27
41
|
1. Fork it
|
data/bin/dephine
CHANGED
data/dephine.gemspec
CHANGED
data/lib/dephine.rb
CHANGED
data/lib/dephine/cli.rb
CHANGED
@@ -1,39 +1,104 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
1
3
|
module Dephine
|
4
|
+
|
5
|
+
# Public: Make a simple Command Line Interface.
|
6
|
+
# To use this class the 'start' class method should be called.
|
7
|
+
#
|
8
|
+
# Examples
|
9
|
+
#
|
10
|
+
# CLI.start(ARGV)
|
11
|
+
# # => nil
|
2
12
|
class CLI
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
13
|
+
|
14
|
+
# Public: Use cli arguments for running the application.
|
15
|
+
#
|
16
|
+
# Returns nothing.
|
17
|
+
def self.start(args)
|
18
|
+
banner = []
|
19
|
+
banner << 'Dephine, Google dictionary in terminal'
|
20
|
+
banner << 'Usage: dephine [word]'
|
21
|
+
|
22
|
+
if args.empty?
|
23
|
+
puts banner.join("\n")
|
24
|
+
else
|
25
|
+
define(args[0])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Public: Cross-platform way of finding an executable in the $PATH.
|
30
|
+
#
|
31
|
+
# which('ruby') #=> /usr/bin/ruby
|
32
|
+
def self.which(cmd)
|
33
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
34
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
35
|
+
exts.each { |ext|
|
36
|
+
exe = "#{path}/#{cmd}#{ext}"
|
37
|
+
return exe if File.executable? exe
|
38
|
+
}
|
39
|
+
end
|
40
|
+
return nil
|
41
|
+
end
|
42
|
+
|
43
|
+
# Public: Play word pronunciation.
|
44
|
+
# This method uses either mpg123 or afplay to play the audio file.
|
45
|
+
#
|
46
|
+
# audio - The String that should be path of an audio file to be played.
|
47
|
+
def self.play(audio)
|
48
|
+
player = which('mpg123') || which('afplay')
|
49
|
+
system("#{player} #{audio} 2>/dev/null")
|
50
|
+
end
|
51
|
+
|
52
|
+
# Internal: Display definitions of a word.
|
53
|
+
#
|
54
|
+
# arg - The String that will be defined.
|
55
|
+
def self.define(arg)
|
56
|
+
word = Dephine::Dictionary.new(arg)
|
57
|
+
|
58
|
+
if word.meanings.empty?
|
59
|
+
abort("Word not found in the dictionary!")
|
14
60
|
end
|
15
61
|
|
16
|
-
|
17
|
-
|
18
|
-
word = Dephine::Dictionary.new(arg)
|
62
|
+
t = Dephine::TUI.new
|
63
|
+
t.puts arg
|
19
64
|
|
20
|
-
|
21
|
-
|
65
|
+
word.meanings.each do |m|
|
66
|
+
t.puts
|
67
|
+
t.puts "#{m[:type].downcase} #{m[:phonetic]}"
|
68
|
+
m[:meanings].each do |d|
|
69
|
+
t.puts " #{d[:text]}"
|
70
|
+
d[:examples].each do |eg|
|
71
|
+
t.puts " - #{eg}"
|
72
|
+
end
|
73
|
+
t.puts
|
22
74
|
end
|
75
|
+
end
|
23
76
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
puts
|
77
|
+
if word.pronunciations.length > 0
|
78
|
+
# create tempfile
|
79
|
+
file = Tempfile.new('temp-pronunciation.mp3')
|
80
|
+
|
81
|
+
# download pronunciation mp3 and save to tempfile
|
82
|
+
File.open(file, "wb") do |saved_file|
|
83
|
+
open(word.pronunciations[0][:url], 'rb') do |read_file|
|
84
|
+
saved_file.write(read_file.read)
|
34
85
|
end
|
35
86
|
end
|
87
|
+
file.close()
|
88
|
+
|
89
|
+
# play tempfile
|
90
|
+
t.set_key 'p' do
|
91
|
+
play(file.path)
|
92
|
+
end
|
36
93
|
end
|
94
|
+
|
95
|
+
t.close
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
class << self
|
100
|
+
private :define
|
37
101
|
end
|
102
|
+
|
38
103
|
end
|
39
104
|
end
|
data/lib/dephine/dictionary.rb
CHANGED
@@ -4,7 +4,7 @@ require 'json'
|
|
4
4
|
module Dephine
|
5
5
|
class Dictionary
|
6
6
|
# Public: Returns the Array meanings of the word.
|
7
|
-
attr_reader :meanings
|
7
|
+
attr_reader :meanings, :pronunciations
|
8
8
|
|
9
9
|
# Public: Initialize some definitions of a word.
|
10
10
|
#
|
@@ -13,6 +13,7 @@ module Dephine
|
|
13
13
|
raise ArgumentError, "Word shouldn't be blank" if word.empty?
|
14
14
|
|
15
15
|
@meanings = []
|
16
|
+
@pronunciations = []
|
16
17
|
url = "https://www.google.com/dictionary/json?callback=define&q=#{word}&" \
|
17
18
|
"sl=en&tl=en&restrict=pr%2Cde&client=te"
|
18
19
|
|
@@ -26,6 +27,15 @@ module Dephine
|
|
26
27
|
meanings: []
|
27
28
|
}
|
28
29
|
|
30
|
+
# add pronunciation
|
31
|
+
primary['terms'].each do |term|
|
32
|
+
if term['type'] == 'sound'
|
33
|
+
@pronunciations << {
|
34
|
+
url: term['text'],
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
29
39
|
# add meanings
|
30
40
|
primary['entries'][1..-1].each do |entry|
|
31
41
|
@meanings[-1][:meanings] << {
|
data/lib/dephine/tui.rb
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
require 'ncursesw'
|
2
|
+
|
3
|
+
module Dephine
|
4
|
+
|
5
|
+
# Public: Terminal User Interface for making a simple UI.
|
6
|
+
# All methods are instance methods and should be called on an instance.
|
7
|
+
#
|
8
|
+
# Examples
|
9
|
+
#
|
10
|
+
# t = TUI.new
|
11
|
+
# t.puts 'it uses ncurses'
|
12
|
+
# t.close
|
13
|
+
# # => 'it uses ncurses'
|
14
|
+
class TUI
|
15
|
+
# Public: Initialize a terminal user interface.
|
16
|
+
def initialize
|
17
|
+
Ncurses.initscr
|
18
|
+
Ncurses.nonl
|
19
|
+
Ncurses.cbreak
|
20
|
+
Ncurses.noecho
|
21
|
+
|
22
|
+
@screen = Ncurses.stdscr
|
23
|
+
@screen.scrollok(true)
|
24
|
+
@screen.keypad(true)
|
25
|
+
|
26
|
+
@top = 0
|
27
|
+
@contexts = []
|
28
|
+
@callbacks = {}
|
29
|
+
end
|
30
|
+
|
31
|
+
def maxy
|
32
|
+
@screen.getmaxy
|
33
|
+
end
|
34
|
+
|
35
|
+
# Public: Add a String to an Array named 'contexts'.
|
36
|
+
# This method basically doesn't act like the built-in method 'puts',
|
37
|
+
# but values of 'contexts' will be printed.
|
38
|
+
#
|
39
|
+
# text - The String that will be pushed to an Array.
|
40
|
+
#
|
41
|
+
# Returns the contexts Array.
|
42
|
+
def puts(text = '')
|
43
|
+
@contexts << text
|
44
|
+
end
|
45
|
+
|
46
|
+
# Public: Move up the scroll.
|
47
|
+
#
|
48
|
+
# Returns true or fase.
|
49
|
+
def scroll_up
|
50
|
+
if @top > 0
|
51
|
+
@screen.scrl(-1)
|
52
|
+
@top -= 1
|
53
|
+
str = @contexts[@top]
|
54
|
+
|
55
|
+
if str
|
56
|
+
@screen.move(0, 0)
|
57
|
+
@screen.addstr(str)
|
58
|
+
end
|
59
|
+
|
60
|
+
true
|
61
|
+
|
62
|
+
else
|
63
|
+
false
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Public: Move down the scroll.
|
68
|
+
#
|
69
|
+
# Returns true or false.
|
70
|
+
def scroll_down
|
71
|
+
if @top + maxy < @contexts.length
|
72
|
+
@screen.scrl(1)
|
73
|
+
@top += 1
|
74
|
+
str = @contexts[@top + maxy - 1]
|
75
|
+
|
76
|
+
if str
|
77
|
+
@screen.move(maxy - 1, 0)
|
78
|
+
@screen.addstr(str)
|
79
|
+
end
|
80
|
+
|
81
|
+
true
|
82
|
+
|
83
|
+
else
|
84
|
+
false
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Internal: Set some hot-keys for performing basic things.
|
89
|
+
# Basic things are scroll up, scroll down and quit.
|
90
|
+
#
|
91
|
+
# Returns nothing.
|
92
|
+
def hotkeys
|
93
|
+
loop do
|
94
|
+
c = @screen.getch
|
95
|
+
|
96
|
+
case c
|
97
|
+
when Ncurses::KEY_DOWN, 14, 'j'.ord
|
98
|
+
scroll_down
|
99
|
+
|
100
|
+
when Ncurses::KEY_UP, 16, 'k'.ord
|
101
|
+
scroll_up
|
102
|
+
|
103
|
+
when Ncurses::KEY_NPAGE
|
104
|
+
(maxy - 2).times do
|
105
|
+
break if !scroll_down
|
106
|
+
end
|
107
|
+
|
108
|
+
when Ncurses::KEY_PPAGE
|
109
|
+
(maxy - 2).times do
|
110
|
+
break if !scroll_up
|
111
|
+
end
|
112
|
+
|
113
|
+
when Ncurses::KEY_LEFT
|
114
|
+
while scroll_up; end
|
115
|
+
|
116
|
+
when Ncurses::KEY_RIGHT
|
117
|
+
while scroll_down; end
|
118
|
+
|
119
|
+
when 'q'.ord
|
120
|
+
break
|
121
|
+
|
122
|
+
when @callbacks[c]
|
123
|
+
true
|
124
|
+
|
125
|
+
else
|
126
|
+
@screen.move(0, 0)
|
127
|
+
@screen.addstr("[unknown key `#{Ncurses.keyname(c)}'=#{c}] ")
|
128
|
+
end
|
129
|
+
|
130
|
+
@screen.move(0, 0)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Public: Set a hot-key for calling a block.
|
135
|
+
#
|
136
|
+
# key - The key to be set as a hot-key.
|
137
|
+
# block - The block to be called when pressing the key.
|
138
|
+
#
|
139
|
+
# Examples
|
140
|
+
#
|
141
|
+
# set_key 'q' do
|
142
|
+
# quit
|
143
|
+
# end
|
144
|
+
# # => nil
|
145
|
+
#
|
146
|
+
# Returns nothing.
|
147
|
+
def set_key(key, &block)
|
148
|
+
@callbacks[key.ord] = block
|
149
|
+
end
|
150
|
+
|
151
|
+
# Public: Close the created terminal user interface.
|
152
|
+
# This method should be called for closing the terminal user interface.
|
153
|
+
#
|
154
|
+
# Returns nothing.
|
155
|
+
def close
|
156
|
+
@contexts[0..maxy-1].each_with_index do |line, idx|
|
157
|
+
@screen.move(idx, 0)
|
158
|
+
@screen.addstr(line.to_s)
|
159
|
+
end
|
160
|
+
|
161
|
+
@screen.move(0, 0)
|
162
|
+
@screen.refresh
|
163
|
+
hotkeys
|
164
|
+
Ncurses.endwin
|
165
|
+
end
|
166
|
+
|
167
|
+
private :hotkeys
|
168
|
+
|
169
|
+
end
|
170
|
+
end
|
data/lib/dephine/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dephine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
13
|
-
dependencies:
|
12
|
+
date: 2013-02-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ncursesw
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.2.4
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.2.4
|
14
30
|
description:
|
15
31
|
email:
|
16
32
|
- contact@s1n4.com
|
@@ -29,6 +45,7 @@ files:
|
|
29
45
|
- lib/dephine.rb
|
30
46
|
- lib/dephine/cli.rb
|
31
47
|
- lib/dephine/dictionary.rb
|
48
|
+
- lib/dephine/tui.rb
|
32
49
|
- lib/dephine/version.rb
|
33
50
|
homepage: http://s1n4.com/dephine
|
34
51
|
licenses: []
|
@@ -50,9 +67,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
50
67
|
version: '0'
|
51
68
|
requirements: []
|
52
69
|
rubyforge_project:
|
53
|
-
rubygems_version: 1.8.
|
70
|
+
rubygems_version: 1.8.23
|
54
71
|
signing_key:
|
55
72
|
specification_version: 3
|
56
73
|
summary: Google dictionary in terminal
|
57
74
|
test_files: []
|
58
|
-
has_rdoc:
|