clipboard_manager 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.rdoc +91 -0
- data/data/VERSION +1 -0
- data/data/logo.png +0 -0
- data/data/nope.png +0 -0
- data/data/off.png +0 -0
- data/data/ok.png +0 -0
- data/data/ready.png +0 -0
- data/data/working.png +0 -0
- data/lib/clipboard_manager.rb +5 -0
- data/lib/clipboard_manager/clipboard_manager.rb +189 -0
- data/lib/clipboard_manager/config.rb +109 -0
- data/lib/clipboard_manager/version.rb +3 -0
- metadata +64 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 53024fd293247de67210024d61edc496a1f1ea7e
|
4
|
+
data.tar.gz: e55402d00cfdbc6af25f522d3401ec0ffc9ec5a7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ef8b740ce48668df19173deec7a232d165bad64d27f9aa5d67f66f645aa20fe07d15143f63c554be5b157034a6f7978451417660940e6a1a49082eca71b2e289
|
7
|
+
data.tar.gz: 9a8be19c9b0088c72fbc353862ff229e655bb77721f66b14606d4d06667f04d0c68ff242704b7af7840f83f3be156c7809ccd2194d7801bdb20f986e2655699e
|
data/README.rdoc
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
= clipboard_manager
|
2
|
+
|
3
|
+
== DESCRIPTION:
|
4
|
+
|
5
|
+
Ruby Gtk3App Clipboard Manager.
|
6
|
+
|
7
|
+
== SYNOPSIS:
|
8
|
+
|
9
|
+
gtk3app clipboard_manager [options]
|
10
|
+
|
11
|
+
== FEATURES
|
12
|
+
|
13
|
+
* wget youtube-dl mplayer command to play youtube video
|
14
|
+
* firefox opens amazon webpage
|
15
|
+
* espeak
|
16
|
+
* history
|
17
|
+
|
18
|
+
== INSTALL:
|
19
|
+
|
20
|
+
$ sudo gem install clipboard_manager
|
21
|
+
|
22
|
+
== CONFIGURATION:
|
23
|
+
|
24
|
+
After an initial run, your user configuration will found in:
|
25
|
+
|
26
|
+
~/.config/gtk3app/clipboardmanager/config.yml
|
27
|
+
|
28
|
+
Towards the bottom of the file you will find the available tasks:
|
29
|
+
|
30
|
+
:tasks:
|
31
|
+
:mplayer:
|
32
|
+
- https?://www\.youtube\.com/\S+
|
33
|
+
- :system
|
34
|
+
- wget -O - $(youtube-dl -f 5/36/17/18 -g '$0') | mplayer -really-quiet -cache 8192
|
35
|
+
-cache-min 1 - &
|
36
|
+
:firefox:
|
37
|
+
- "^https?://www.amazon.com/"
|
38
|
+
- :firefox
|
39
|
+
:espeak:
|
40
|
+
- ".{80,}"
|
41
|
+
- :espeak
|
42
|
+
|
43
|
+
It is by this configuration that one can modify and add tasks.
|
44
|
+
|
45
|
+
The _mplayer_ task will run when the clipboard text matches a youtube link.
|
46
|
+
It will run the given system command "wget.. youtube_dl... '$0' | mplayer ...",
|
47
|
+
where $0 will be replaced by the match.
|
48
|
+
|
49
|
+
The _firefox_ task will run when the clipboard text matches an amazon link.
|
50
|
+
It will open the link with firfox.
|
51
|
+
|
52
|
+
The _espeak_ task will run the the clipboard text is at least 80 characters long.
|
53
|
+
It will have espeak read the text.
|
54
|
+
|
55
|
+
Currently, clipboard_manager has three tasks methods: bashit(system), firefox, and espeak.
|
56
|
+
|
57
|
+
For firefox and espeak, the pattern is used to recognize the text.
|
58
|
+
The whole copied text is used to pass on to firefox as a url, or espeak as text to be read.
|
59
|
+
|
60
|
+
bashit is more complicated.
|
61
|
+
It requires a command string which it will substitute $0, $1, $2... with match data.
|
62
|
+
It then passes the string to system.
|
63
|
+
|
64
|
+
See clipboard_manager/clipboard_manager.rb[https://github.com/carlosjhr64/clipboard_manager/blob/master/lib/clipboard_manager/clipboard_manager.rb]
|
65
|
+
for details.
|
66
|
+
Specifically, methods #espeak, #firefox, and #bashit, which are called from #manage.
|
67
|
+
|
68
|
+
== LICENSE:
|
69
|
+
|
70
|
+
(The MIT License)
|
71
|
+
|
72
|
+
Copyright (c) 2014 carlosjhr64
|
73
|
+
|
74
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
75
|
+
a copy of this software and associated documentation files (the
|
76
|
+
'Software'), to deal in the Software without restriction, including
|
77
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
78
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
79
|
+
permit persons to whom the Software is furnished to do so, subject to
|
80
|
+
the following conditions:
|
81
|
+
|
82
|
+
The above copyright notice and this permission notice shall be
|
83
|
+
included in all copies or substantial portions of the Software.
|
84
|
+
|
85
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
88
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
89
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
90
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
91
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
data/data/logo.png
ADDED
Binary file
|
data/data/nope.png
ADDED
Binary file
|
data/data/off.png
ADDED
Binary file
|
data/data/ok.png
ADDED
Binary file
|
data/data/ready.png
ADDED
Binary file
|
data/data/working.png
ADDED
Binary file
|
@@ -0,0 +1,189 @@
|
|
1
|
+
module ClipboardManager
|
2
|
+
using Rafini::Exception
|
3
|
+
|
4
|
+
def self.options=(opts)
|
5
|
+
@@options=opts
|
6
|
+
end
|
7
|
+
def self.options
|
8
|
+
@@options
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.run(program)
|
12
|
+
ClipboardManager.new(program)
|
13
|
+
end
|
14
|
+
|
15
|
+
class ClipboardManager
|
16
|
+
CLIPBOARD = Gtk::Clipboard.get(Gdk::Selection::CLIPBOARD)
|
17
|
+
|
18
|
+
def initialize(program)
|
19
|
+
@program = program
|
20
|
+
@image = program.mini.children.first
|
21
|
+
@timer = nil
|
22
|
+
|
23
|
+
@working = Gdk::Pixbuf.new(file: CONFIG[:Working])
|
24
|
+
@ok = Gdk::Pixbuf.new(file: CONFIG[:Ok])
|
25
|
+
@nope = Gdk::Pixbuf.new(file: CONFIG[:Nope])
|
26
|
+
@ready = Gdk::Pixbuf.new(file: CONFIG[:Ready])
|
27
|
+
@off = Gdk::Pixbuf.new(file: CONFIG[:Off])
|
28
|
+
|
29
|
+
@is_pwd = Regexp.new(CONFIG[:IsPwd], Regexp::EXTENDED)
|
30
|
+
|
31
|
+
|
32
|
+
program.mini_menu.append_menu_item(:toggle!){toggle}
|
33
|
+
status(@ready)
|
34
|
+
|
35
|
+
@history, @previous = [], nil
|
36
|
+
request_text do |text|
|
37
|
+
if text
|
38
|
+
add_history text
|
39
|
+
@previous = text
|
40
|
+
end
|
41
|
+
Rafini.thread_bang!{cycle}
|
42
|
+
end
|
43
|
+
|
44
|
+
window = program.window
|
45
|
+
vbox = Such::Box.new window, :vbox!
|
46
|
+
|
47
|
+
@ask = Such::CheckButton.new vbox, :ask!
|
48
|
+
@ask.active = ::ClipboardManager.options[:ask, true]
|
49
|
+
|
50
|
+
@running = Such::CheckButton.new(vbox, :running!, 'toggled'){toggled}
|
51
|
+
@running.active = ::ClipboardManager.options[:running, true]
|
52
|
+
|
53
|
+
Such::Label.new vbox, :tasks!
|
54
|
+
|
55
|
+
@checks = {}
|
56
|
+
CONFIG[:tasks].keys.each do |key|
|
57
|
+
@checks[key] = Such::CheckButton.new(vbox, [key.to_s.capitalize], {set_active: true})
|
58
|
+
end
|
59
|
+
|
60
|
+
Such::Button.new(vbox, :history_button!){do_history}
|
61
|
+
|
62
|
+
window.show_all
|
63
|
+
end
|
64
|
+
|
65
|
+
# https://github.com/ruby-gnome2/ruby-gnome2/blob/master/gtk3/sample/misc/dialog.rb
|
66
|
+
def do_history
|
67
|
+
dialog = Such::Dialog.new :history_dialog!
|
68
|
+
dialog.add_button(Gtk::Stock::CANCEL, Gtk::ResponseType::CANCEL)
|
69
|
+
dialog.add_button(Gtk::Stock::OK, Gtk::ResponseType::OK)
|
70
|
+
combo = Such::ComboBoxText.new dialog.child, :history_combo!
|
71
|
+
@history.each do |str|
|
72
|
+
if str.length > CONFIG[:MaxString]
|
73
|
+
n = CONFIG[:MaxString]/2 - 1
|
74
|
+
str = "#{str[0..n]}...#{str[-n..-1]}"
|
75
|
+
end
|
76
|
+
combo.append_text(str)
|
77
|
+
end
|
78
|
+
dialog.show_all
|
79
|
+
if dialog.run==Gtk::ResponseType::OK and combo.active_text
|
80
|
+
@previous = nil
|
81
|
+
CLIPBOARD.text = @history[combo.active]
|
82
|
+
end
|
83
|
+
dialog.destroy
|
84
|
+
end
|
85
|
+
|
86
|
+
def toggled
|
87
|
+
@running.active? ? status(@ready) : status(@off)
|
88
|
+
end
|
89
|
+
|
90
|
+
def toggle
|
91
|
+
request_text do |text|
|
92
|
+
@previous = text
|
93
|
+
@running.active = !@running.active?
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def request_text
|
98
|
+
CLIPBOARD.request_text do |_, text|
|
99
|
+
# nil anything that looks like a pwd.
|
100
|
+
(@is_pwd=~text)? yield(nil) : yield(text)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def status(type)
|
105
|
+
@image.set_pixbuf(type)
|
106
|
+
@timer = Time.now
|
107
|
+
end
|
108
|
+
|
109
|
+
def cycle
|
110
|
+
while true
|
111
|
+
step if @running.active?
|
112
|
+
sleep CONFIG[:Sleep]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def step
|
117
|
+
if @timer and Time.now - @timer > CONFIG[:TimeOut]
|
118
|
+
@timer = nil
|
119
|
+
status @ready
|
120
|
+
end
|
121
|
+
request_text do |text|
|
122
|
+
unless text.nil? or @previous == text
|
123
|
+
@previous = text
|
124
|
+
status @working
|
125
|
+
Rafini.thread_bang!{manage(text)}
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def add_history(text)
|
131
|
+
@history.unshift text
|
132
|
+
@history.uniq!
|
133
|
+
@history.pop if @history.length > CONFIG[:MaxHistory]
|
134
|
+
end
|
135
|
+
|
136
|
+
def manage(text)
|
137
|
+
add_history text
|
138
|
+
CONFIG[:tasks].each do |name, _|
|
139
|
+
next unless @checks[name].active?
|
140
|
+
rgx, mth, str = _
|
141
|
+
rgx = Regexp.new(rgx, Regexp::EXTENDED)
|
142
|
+
if md=rgx.match(text) and question?(name)
|
143
|
+
CLIPBOARD.text=Rafini::Empty::STRING
|
144
|
+
begin
|
145
|
+
case mth
|
146
|
+
when :espeak
|
147
|
+
espeak(text)
|
148
|
+
when :firefox
|
149
|
+
firefox(text)
|
150
|
+
when :system
|
151
|
+
bashit(md, str)
|
152
|
+
else
|
153
|
+
raise "Method #{mth} not implemented."
|
154
|
+
end
|
155
|
+
status(@ok)
|
156
|
+
rescue RuntimeError
|
157
|
+
$!.puts
|
158
|
+
status(@nope) # TODO it's not just nope!
|
159
|
+
end
|
160
|
+
return
|
161
|
+
end
|
162
|
+
end
|
163
|
+
status(@nope)
|
164
|
+
end
|
165
|
+
|
166
|
+
def question?(wut)
|
167
|
+
@ask.active? ? system("zenity --question --text='#{wut}'") : true
|
168
|
+
end
|
169
|
+
|
170
|
+
def espeak(text)
|
171
|
+
IO.popen('espeak --stdin', 'w'){|e|e.puts text.strip}
|
172
|
+
end
|
173
|
+
|
174
|
+
def firefox(text)
|
175
|
+
raise "not a url" unless text =~ /^https?:\/\/\S+$/
|
176
|
+
raise "quote not allowed in url" if text =~ /'/
|
177
|
+
system("firefox '#{text}' &")
|
178
|
+
end
|
179
|
+
|
180
|
+
def bashit(md, str)
|
181
|
+
(md.length-1).downto(0) do |i|
|
182
|
+
str = str.gsub(/\$#{i}/, md[i])
|
183
|
+
$stderr.puts str if $VERBOSE
|
184
|
+
system str
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module ClipboardManager
|
2
|
+
|
3
|
+
help = <<-HELP # TODO
|
4
|
+
Usage: gtk3app clipboardmanager [options]
|
5
|
+
Options:
|
6
|
+
--ask Ask for confirmation.
|
7
|
+
--running Start in active mode.
|
8
|
+
Default for options is true,
|
9
|
+
use no-ask and no-running for false.
|
10
|
+
HELP
|
11
|
+
|
12
|
+
APPDIR = File.dirname File.dirname __dir__
|
13
|
+
|
14
|
+
is_pwd =
|
15
|
+
'\A
|
16
|
+
(?!\w+:\/\/) # not like url
|
17
|
+
(?!\/[a-z]+\/[a-z]) # not like linux path
|
18
|
+
(?![a-z]+\/[a-z]+\/) # not like relative path
|
19
|
+
(?=.*\d) # at least on diget
|
20
|
+
(?=.*[a-z]) # at least one lower case letter
|
21
|
+
(?=.*[A-Z]) # at least one upper case letter
|
22
|
+
(?=.*[^\w\s]) # at least one special character
|
23
|
+
.{4,43}$ # 4 to 43 in length
|
24
|
+
\Z'
|
25
|
+
|
26
|
+
a0 = Rafini::Empty::ARRAY
|
27
|
+
h0 = Rafini::Empty::HASH
|
28
|
+
s0 = Rafini::Empty::STRING
|
29
|
+
|
30
|
+
CONFIG = {
|
31
|
+
Help: help,
|
32
|
+
|
33
|
+
TimeOut: 3,
|
34
|
+
Sleep: 0.5,
|
35
|
+
MaxHistory: 13,
|
36
|
+
MaxString: 60,
|
37
|
+
|
38
|
+
IsPwd: is_pwd,
|
39
|
+
|
40
|
+
Working: "#{XDG['DATA']}/gtk3app/clipboardmanager/working.png",
|
41
|
+
Ok: "#{XDG['DATA']}/gtk3app/clipboardmanager/ok.png",
|
42
|
+
Nope: "#{XDG['DATA']}/gtk3app/clipboardmanager/nope.png",
|
43
|
+
Ready: "#{XDG['DATA']}/gtk3app/clipboardmanager/ready.png",
|
44
|
+
Off: "#{XDG['DATA']}/gtk3app/clipboardmanager/off.png",
|
45
|
+
|
46
|
+
thing: {
|
47
|
+
|
48
|
+
HelpFile: "https://github.com/carlosjhr64/clipboard_manager",
|
49
|
+
Logo: "#{XDG['DATA']}/gtk3app/clipboardmanager/logo.png",
|
50
|
+
|
51
|
+
about_dialog: {
|
52
|
+
set_program_name: 'Clipboard Manager',
|
53
|
+
set_version: VERSION,
|
54
|
+
set_copyright: '(c) 2014 CarlosJHR64',
|
55
|
+
set_comments: 'A Ruby Gtk3App Clipboard Manager ',
|
56
|
+
set_website: 'https://github.com/carlosjhr64/clipboard_manager',
|
57
|
+
set_website_label: 'See it at GitHub!',
|
58
|
+
},
|
59
|
+
|
60
|
+
TOGGLE: ['Toggle On/Off'],
|
61
|
+
toggle!: [:TOGGLE, 'activate'],
|
62
|
+
|
63
|
+
window: {
|
64
|
+
set_title: "Clipboard Manager",
|
65
|
+
set_window_position: :center,
|
66
|
+
},
|
67
|
+
|
68
|
+
VBOX: [:vertical],
|
69
|
+
vbox: h0,
|
70
|
+
vbox!: [:VBOX, :vbox],
|
71
|
+
|
72
|
+
ASK: ['Ask For Confirmation'],
|
73
|
+
ask: h0,
|
74
|
+
ask!: [:ASK, :ask],
|
75
|
+
|
76
|
+
RUNNING: ['On/Off'],
|
77
|
+
running: h0,
|
78
|
+
running!: [:RUNNING, :running],
|
79
|
+
|
80
|
+
TASKS: ['Tasks:'],
|
81
|
+
tasks: h0,
|
82
|
+
tasks!: [:TASKS, :tasks],
|
83
|
+
|
84
|
+
HISTORY_BUTTON: [label: 'History'],
|
85
|
+
history_button: h0,
|
86
|
+
history_button!: [:HISTORY_BUTTON, :history_button],
|
87
|
+
|
88
|
+
HISTORY_DIALOG: [],
|
89
|
+
history_dialog: {},
|
90
|
+
history_dialog!: [:HISTORY_DIALOG, :history_dialog],
|
91
|
+
|
92
|
+
HISTORY_COMBO: [],
|
93
|
+
history_combo: {},
|
94
|
+
history_combo!: [:HISTORY_COMBO, :history_combo],
|
95
|
+
},
|
96
|
+
|
97
|
+
# Note that Ruby 2 hashes preserves order, and order here is important.
|
98
|
+
tasks: {
|
99
|
+
mplayer: [
|
100
|
+
'https?://www\.youtube\.com/\S+',
|
101
|
+
:system,
|
102
|
+
"wget -O - $(youtube-dl -f 5/36/17/18 -g '$0') | mplayer -really-quiet -cache 8192 -cache-min 1 - &",
|
103
|
+
],
|
104
|
+
firefox: ['^https?://www.amazon.com/', :firefox],
|
105
|
+
espeak: ['.{80,}', :espeak],
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: clipboard_manager
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- carlosjhr64
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-11-29 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |
|
14
|
+
Ruby Gtk3App Clipboard Manager.
|
15
|
+
email: carlosjhr64@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files:
|
19
|
+
- README.rdoc
|
20
|
+
files:
|
21
|
+
- README.rdoc
|
22
|
+
- data/VERSION
|
23
|
+
- data/logo.png
|
24
|
+
- data/nope.png
|
25
|
+
- data/off.png
|
26
|
+
- data/ok.png
|
27
|
+
- data/ready.png
|
28
|
+
- data/working.png
|
29
|
+
- lib/clipboard_manager.rb
|
30
|
+
- lib/clipboard_manager/clipboard_manager.rb
|
31
|
+
- lib/clipboard_manager/config.rb
|
32
|
+
- lib/clipboard_manager/version.rb
|
33
|
+
homepage: https://github.com/carlosjhr64/clipboard_manager
|
34
|
+
licenses:
|
35
|
+
- MIT
|
36
|
+
metadata: {}
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options:
|
39
|
+
- "--main"
|
40
|
+
- README.rdoc
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
requirements:
|
54
|
+
- 'ruby: ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-linux]'
|
55
|
+
- 'zenity: 3.8.0'
|
56
|
+
- 'firefox: Mozilla Firefox 33.1'
|
57
|
+
- 'system: linux/bash'
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 2.4.1
|
60
|
+
signing_key:
|
61
|
+
specification_version: 4
|
62
|
+
summary: Ruby Gtk3App Clipboard Manager.
|
63
|
+
test_files: []
|
64
|
+
has_rdoc:
|