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 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
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $:.unshift File.join(File.expand_path(File.dirname(__FILE__)), %w[.. lib])
3
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib]))
4
4
  require 'dephine'
5
5
 
6
6
  Dephine::CLI.start(ARGV)
@@ -15,4 +15,6 @@ Gem::Specification.new do |gem|
15
15
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
16
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
17
  gem.require_paths = ["lib"]
18
+
19
+ gem.add_dependency 'ncursesw', '~> 1.2.4'
18
20
  end
@@ -1,3 +1,4 @@
1
1
  require 'dephine/version'
2
2
  require 'dephine/dictionary'
3
3
  require 'dephine/cli'
4
+ require 'dephine/tui'
@@ -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
- class << self
4
- def start(args)
5
- banner = []
6
- banner << 'Dephine, Google dictionary in terminal'
7
- banner << 'Usage: dephine [word]'
8
-
9
- if args.empty?
10
- puts banner.join("\n")
11
- else
12
- define(args[0])
13
- end
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
- private
17
- def define(arg)
18
- word = Dephine::Dictionary.new(arg)
62
+ t = Dephine::TUI.new
63
+ t.puts arg
19
64
 
20
- if word.meanings.empty?
21
- abort("Word not found in the dictionary!")
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
- puts arg
25
- word.meanings.each do |m|
26
- puts
27
- puts "#{m[:type].downcase} #{m[:phonetic]}"
28
- m[:meanings].each do |d|
29
- puts " #{d[:text]}"
30
- d[:examples].each do |eg|
31
- puts " - #{eg}"
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
@@ -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] << {
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Dephine
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
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.1.1
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-01-16 00:00:00.000000000 Z
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.24
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: