link_finder 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in link_finder.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # LinkFinder
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'link_finder'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install link_finder
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/link_finder ADDED
@@ -0,0 +1,7 @@
1
+
2
+ #!/usr/bin/env ruby
3
+
4
+ require 'gtk2'
5
+ require 'link_finder.rb'
6
+
7
+ lf = LinkFinder::Finder.new
data/install.sh ADDED
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+ source /home/tuxer/.rvm/scripts/rvm
3
+ rake install
@@ -0,0 +1,3 @@
1
+ module LinkFinder
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,283 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <interface>
3
+ <requires lib="gtk+" version="2.24"/>
4
+ <!-- interface-naming-policy project-wide -->
5
+ <object class="GtkAdjustment" id="adj_recurse">
6
+ <property name="lower">2</property>
7
+ <property name="upper">10</property>
8
+ <property name="value">2</property>
9
+ <property name="step_increment">1</property>
10
+ <property name="page_increment">1</property>
11
+ </object>
12
+ <object class="GtkAdjustment" id="adj_threads">
13
+ <property name="lower">1</property>
14
+ <property name="upper">300</property>
15
+ <property name="value">10</property>
16
+ <property name="step_increment">1</property>
17
+ <property name="page_increment">10</property>
18
+ </object>
19
+ <object class="GtkWindow" id="wnd_main">
20
+ <property name="can_focus">False</property>
21
+ <property name="border_width">14</property>
22
+ <property name="window_position">center</property>
23
+ <property name="default_width">700</property>
24
+ <property name="default_height">480</property>
25
+ <signal name="destroy" handler="on_wnd_main_destroy" swapped="no"/>
26
+ <signal name="delete-event" handler="on_wnd_main_delete_event" swapped="no"/>
27
+ <child>
28
+ <object class="GtkVBox" id="vbox1">
29
+ <property name="visible">True</property>
30
+ <property name="can_focus">False</property>
31
+ <child>
32
+ <object class="GtkHBox" id="hbox1">
33
+ <property name="visible">True</property>
34
+ <property name="can_focus">False</property>
35
+ <child>
36
+ <object class="GtkVBox" id="vbox2">
37
+ <property name="visible">True</property>
38
+ <property name="can_focus">False</property>
39
+ <child>
40
+ <object class="GtkHBox" id="hbox3">
41
+ <property name="visible">True</property>
42
+ <property name="can_focus">False</property>
43
+ <child>
44
+ <object class="GtkLabel" id="label1">
45
+ <property name="visible">True</property>
46
+ <property name="can_focus">False</property>
47
+ <property name="label" translatable="yes">Список ссылок:</property>
48
+ </object>
49
+ <packing>
50
+ <property name="expand">False</property>
51
+ <property name="fill">True</property>
52
+ <property name="position">0</property>
53
+ </packing>
54
+ </child>
55
+ <child>
56
+ <object class="GtkFileChooserButton" id="fcb_links">
57
+ <property name="visible">True</property>
58
+ <property name="can_focus">False</property>
59
+ <signal name="file-set" handler="on_fcb_links_file_set" swapped="no"/>
60
+ </object>
61
+ <packing>
62
+ <property name="expand">True</property>
63
+ <property name="fill">True</property>
64
+ <property name="padding">4</property>
65
+ <property name="position">1</property>
66
+ </packing>
67
+ </child>
68
+ </object>
69
+ <packing>
70
+ <property name="expand">True</property>
71
+ <property name="fill">True</property>
72
+ <property name="position">0</property>
73
+ </packing>
74
+ </child>
75
+ </object>
76
+ <packing>
77
+ <property name="expand">True</property>
78
+ <property name="fill">True</property>
79
+ <property name="position">0</property>
80
+ </packing>
81
+ </child>
82
+ <child>
83
+ <object class="GtkVBox" id="vbox3">
84
+ <property name="visible">True</property>
85
+ <property name="can_focus">False</property>
86
+ <child>
87
+ <object class="GtkHBox" id="hbox4">
88
+ <property name="visible">True</property>
89
+ <property name="can_focus">False</property>
90
+ <child>
91
+ <object class="GtkLabel" id="label2">
92
+ <property name="visible">True</property>
93
+ <property name="can_focus">False</property>
94
+ <property name="label" translatable="yes">Список сайтов:</property>
95
+ </object>
96
+ <packing>
97
+ <property name="expand">False</property>
98
+ <property name="fill">True</property>
99
+ <property name="position">0</property>
100
+ </packing>
101
+ </child>
102
+ <child>
103
+ <object class="GtkFileChooserButton" id="fcb_sites">
104
+ <property name="visible">True</property>
105
+ <property name="can_focus">False</property>
106
+ <signal name="file-set" handler="on_fcb_sites_file_set" swapped="no"/>
107
+ </object>
108
+ <packing>
109
+ <property name="expand">True</property>
110
+ <property name="fill">True</property>
111
+ <property name="padding">4</property>
112
+ <property name="position">1</property>
113
+ </packing>
114
+ </child>
115
+ </object>
116
+ <packing>
117
+ <property name="expand">True</property>
118
+ <property name="fill">True</property>
119
+ <property name="position">0</property>
120
+ </packing>
121
+ </child>
122
+ </object>
123
+ <packing>
124
+ <property name="expand">True</property>
125
+ <property name="fill">True</property>
126
+ <property name="position">1</property>
127
+ </packing>
128
+ </child>
129
+ </object>
130
+ <packing>
131
+ <property name="expand">False</property>
132
+ <property name="fill">True</property>
133
+ <property name="position">0</property>
134
+ </packing>
135
+ </child>
136
+ <child>
137
+ <object class="GtkHSeparator" id="hseparator1">
138
+ <property name="height_request">8</property>
139
+ <property name="visible">True</property>
140
+ <property name="can_focus">False</property>
141
+ </object>
142
+ <packing>
143
+ <property name="expand">False</property>
144
+ <property name="fill">True</property>
145
+ <property name="padding">4</property>
146
+ <property name="position">1</property>
147
+ </packing>
148
+ </child>
149
+ <child>
150
+ <object class="GtkHBox" id="hbox2">
151
+ <property name="visible">True</property>
152
+ <property name="can_focus">False</property>
153
+ <child>
154
+ <object class="GtkLabel" id="label4">
155
+ <property name="visible">True</property>
156
+ <property name="can_focus">False</property>
157
+ <property name="label" translatable="yes">Рекурсия:</property>
158
+ </object>
159
+ <packing>
160
+ <property name="expand">False</property>
161
+ <property name="fill">True</property>
162
+ <property name="padding">4</property>
163
+ <property name="position">0</property>
164
+ </packing>
165
+ </child>
166
+ <child>
167
+ <object class="GtkSpinButton" id="sb_recurse">
168
+ <property name="visible">True</property>
169
+ <property name="can_focus">True</property>
170
+ <property name="invisible_char">•</property>
171
+ <property name="primary_icon_activatable">False</property>
172
+ <property name="secondary_icon_activatable">False</property>
173
+ <property name="primary_icon_sensitive">True</property>
174
+ <property name="secondary_icon_sensitive">True</property>
175
+ <property name="adjustment">adj_recurse</property>
176
+ </object>
177
+ <packing>
178
+ <property name="expand">False</property>
179
+ <property name="fill">True</property>
180
+ <property name="padding">4</property>
181
+ <property name="position">1</property>
182
+ </packing>
183
+ </child>
184
+ <child>
185
+ <object class="GtkLabel" id="label3">
186
+ <property name="visible">True</property>
187
+ <property name="can_focus">False</property>
188
+ <property name="label" translatable="yes">Потоков:</property>
189
+ </object>
190
+ <packing>
191
+ <property name="expand">False</property>
192
+ <property name="fill">True</property>
193
+ <property name="padding">4</property>
194
+ <property name="position">2</property>
195
+ </packing>
196
+ </child>
197
+ <child>
198
+ <object class="GtkSpinButton" id="sb_threads">
199
+ <property name="visible">True</property>
200
+ <property name="sensitive">False</property>
201
+ <property name="can_focus">True</property>
202
+ <property name="invisible_char">•</property>
203
+ <property name="primary_icon_activatable">False</property>
204
+ <property name="secondary_icon_activatable">False</property>
205
+ <property name="primary_icon_sensitive">True</property>
206
+ <property name="secondary_icon_sensitive">True</property>
207
+ <property name="adjustment">adj_threads</property>
208
+ <property name="numeric">True</property>
209
+ <signal name="value-changed" handler="on_sb_threads_value_changed" swapped="no"/>
210
+ </object>
211
+ <packing>
212
+ <property name="expand">False</property>
213
+ <property name="fill">True</property>
214
+ <property name="padding">5</property>
215
+ <property name="position">3</property>
216
+ </packing>
217
+ </child>
218
+ <child>
219
+ <object class="GtkToggleButton" id="tbtn_startstop">
220
+ <property name="label" translatable="yes">Старт / Стоп</property>
221
+ <property name="visible">True</property>
222
+ <property name="sensitive">False</property>
223
+ <property name="can_focus">True</property>
224
+ <property name="receives_default">True</property>
225
+ <property name="use_action_appearance">False</property>
226
+ <signal name="toggled" handler="on_tbtn_startstop_toggled" swapped="no"/>
227
+ </object>
228
+ <packing>
229
+ <property name="expand">False</property>
230
+ <property name="fill">True</property>
231
+ <property name="padding">4</property>
232
+ <property name="position">4</property>
233
+ </packing>
234
+ </child>
235
+ <child>
236
+ <object class="GtkProgressBar" id="pb_progress">
237
+ <property name="visible">True</property>
238
+ <property name="can_focus">False</property>
239
+ </object>
240
+ <packing>
241
+ <property name="expand">True</property>
242
+ <property name="fill">True</property>
243
+ <property name="padding">4</property>
244
+ <property name="position">5</property>
245
+ </packing>
246
+ </child>
247
+ </object>
248
+ <packing>
249
+ <property name="expand">False</property>
250
+ <property name="fill">True</property>
251
+ <property name="position">2</property>
252
+ </packing>
253
+ </child>
254
+ <child>
255
+ <object class="GtkHSeparator" id="hseparator2">
256
+ <property name="height_request">8</property>
257
+ <property name="visible">True</property>
258
+ <property name="can_focus">False</property>
259
+ </object>
260
+ <packing>
261
+ <property name="expand">False</property>
262
+ <property name="fill">True</property>
263
+ <property name="padding">4</property>
264
+ <property name="position">3</property>
265
+ </packing>
266
+ </child>
267
+ <child>
268
+ <object class="GtkImage" id="img_diagram">
269
+ <property name="visible">True</property>
270
+ <property name="can_focus">False</property>
271
+ <property name="stock">gtk-missing-image</property>
272
+ </object>
273
+ <packing>
274
+ <property name="expand">True</property>
275
+ <property name="fill">True</property>
276
+ <property name="padding">4</property>
277
+ <property name="position">4</property>
278
+ </packing>
279
+ </child>
280
+ </object>
281
+ </child>
282
+ </object>
283
+ </interface>
@@ -0,0 +1,277 @@
1
+ # encoding: utf-8
2
+ require "link_finder/version"
3
+ require "gtk2"
4
+ require "nokogiri"
5
+ require "open-uri"
6
+ require "timeout"
7
+ require "thread"
8
+ require "gruff"
9
+
10
+ module LinkFinder
11
+ class Finder
12
+ def initialize
13
+ trap("SIGINT") { exit! }
14
+ @mutex = Mutex.new
15
+
16
+ Gtk.init
17
+ builder = Gtk::Builder.new
18
+ builder.add_from_file(File.join(File.dirname(__FILE__), 'link_finder.glade'))
19
+ builder.connect_signals {|handler| method(handler) }
20
+
21
+ @wnd_main = builder.get_object('wnd_main')
22
+ @fcb_links = builder.get_object('fcb_links')
23
+ @fcb_sites = builder.get_object('fcb_sites')
24
+ @tbtn_startstop = builder.get_object('tbtn_startstop')
25
+ @sb_threads = builder.get_object('sb_threads')
26
+ @adj_threads = builder.get_object('adj_threads')
27
+ @sb_recurse = builder.get_object('sb_recurse')
28
+ @adj_recurse = builder.get_object('adj_recurse')
29
+ @pb_progress = builder.get_object('pb_progress')
30
+ @img_diagram = builder.get_object('img_diagram')
31
+
32
+ @options = {}
33
+ begin
34
+ @options = File.open(File.join(File.dirname(__FILE__), "options.dat"), "rb") {|f| Marshal.load(f)}
35
+ rescue Exception => e
36
+ puts e
37
+ end
38
+
39
+ @fcb_links.filename = @options[:links_filename] unless @options[:links_filename].nil?
40
+ @fcb_sites.filename = @options[:sites_filename] unless @options[:sites_filename].nil?
41
+ @options[:threads] = 5 if @options[:threads].nil?
42
+ @adj_threads.value = @options[:threads]
43
+ @options[:recurse] = 2 if @options[:recurse].nil?
44
+ @adj_recurse.value = @options[:recurse]
45
+
46
+ sensitive_state
47
+
48
+ @wnd_main.show
49
+ Gtk.main
50
+ end
51
+
52
+ def on_wnd_main_destroy
53
+ gtk_main_quit
54
+ end
55
+
56
+ def gtk_main_quit
57
+ @browser.close unless @browser.nil?
58
+ Gtk.main_quit()
59
+ end
60
+
61
+ def on_wnd_main_delete_event(widget, event)
62
+ begin
63
+ File.open(File.join(File.dirname(__FILE__), "options.dat"), "wb") {|f| Marshal.dump(@options, f)}
64
+ rescue Exception => e
65
+ puts e
66
+ end
67
+ return false
68
+ end
69
+
70
+ def on_fcb_links_file_set(widget)
71
+ @options[:links_filename] = widget.filename
72
+ sensitive_state
73
+ end
74
+
75
+ def on_fcb_sites_file_set(widget)
76
+ @options[:sites_filename] = widget.filename
77
+ sensitive_state
78
+ end
79
+
80
+ def on_sb_threads_value_changed(widget)
81
+ @options[:threads] = @adj_threads.value
82
+ end
83
+
84
+ def on_sb_recurse_value_changed(widget)
85
+ @options[:recurse] = @adj_recurse.value
86
+ end
87
+
88
+ def on_tbtn_startstop_toggled(widget)
89
+ if widget.active?
90
+ start_process
91
+ else
92
+ stop_process
93
+ end
94
+ end
95
+
96
+ def sensitive_state
97
+ result = (!@options[:links_filename].nil? and !@options[:sites_filename].nil?)
98
+ @tbtn_startstop.sensitive = result
99
+ @sb_threads.sensitive = result
100
+ @sb_recurse.sensitive = result
101
+ end
102
+
103
+ def progress_reset
104
+ @pb_progress.text = " "
105
+ @pb_progress.fraction = 0
106
+ end
107
+
108
+ def progress_set(max, value)
109
+ perc = value * 100 / max
110
+ @pb_progress.text = "#{value} из #{max}"
111
+ @pb_progress.fraction = perc * 0.01
112
+ Gtk::main_iteration_do(blocking = false) while Gtk::events_pending?
113
+ end
114
+
115
+ def dia_refresh
116
+ pixbuf = Gdk::Pixbuf.new("/home/chemt79/result.png", 700, 520)
117
+ @img_diagram.pixbuf = pixbuf
118
+ Gtk::main_iteration_do(blocking = false) while Gtk::events_pending?
119
+ end
120
+
121
+ def start_process
122
+ progress_reset
123
+ @progress_value = 0
124
+
125
+ @fcb_links.sensitive =
126
+ @fcb_sites.sensitive =
127
+ @sb_threads.sensitive =
128
+ @sb_recurse.sensitive = false
129
+
130
+ @threads = []
131
+ @result = []
132
+ @main_thread = Thread.new do
133
+ @links = File.open(@options[:links_filename], "rb:UTF-8").read.split("\n").map do |l|
134
+ begin
135
+ URI.parse(l.gsub(/[\n\r]/, '')).to_s
136
+ rescue Exception => e
137
+ puts e
138
+ end
139
+ end
140
+
141
+ @sites = File.open(@options[:sites_filename], "rb:UTF-8").read.split(/\n/).map do |s|
142
+ begin
143
+ uri = URI.parse(s.gsub(/[\n\r]/, ''))
144
+ URI::HTTP.new('http', nil, uri.host, nil, nil, nil, nil, nil, nil).to_s
145
+ rescue Exception => e
146
+ puts e
147
+ end
148
+ end
149
+
150
+ section = 0
151
+ @sites.each_index do |index|
152
+ site = @sites[index]
153
+
154
+ sleep 0.1 while (Thread.list.length() - 1 > @options[:threads])
155
+ @threads << Thread.new(site, @links, @options[:recurse]) do |site, links, recurse|
156
+ r = []
157
+ recurse_select_refs(site, site, links.clone, r, recurse)
158
+ @mutex.synchronize do
159
+ r.each { |t| @result << t }
160
+ @progress_value += 1
161
+ progress_set(@sites.length, @progress_value)
162
+
163
+ if @progress_value >= section
164
+ section += @sites.length / 100
165
+ dia_data = []
166
+ @links.each do |l|
167
+ c = 0
168
+ @result.each { |r| c += 1 if r[:link] == l }
169
+ dia_data << {:link => l, :count => c}
170
+ end
171
+ dia = Gruff::Bar.new
172
+ dia.title = "Отчет"
173
+ dia_data.each { |d| dia.data(d[:link], d[:count]) }
174
+ dia.write("/home/chemt79/result.png")
175
+ dia_refresh
176
+ end
177
+ end
178
+ end
179
+
180
+ break if index >= 10
181
+ end
182
+ @threads.each {|t| t.join}
183
+
184
+ dia_data = []
185
+ File.open("/home/chemt79/result.txt", "wb:UTF-8") do |f|
186
+ f.write Time.now.to_s + "\n"
187
+ all = @sites.length
188
+ @result.each do |r|
189
+ url = URI.parse(r[:page])
190
+ url = URI::HTTP.new('http', nil, url.host, nil, nil, nil, nil, nil, nil).to_s
191
+ index = @sites.index(url)
192
+ @sites.delete_at(index) unless index.nil?
193
+ end
194
+ no = @sites.length
195
+ yes = all - no
196
+
197
+ f.write "Обработано сайтов #{all}\n"
198
+ f.write "Ссылки найдены на #{yes} сайтах\n"
199
+ f.write "Ссылки не обнаружены на #{no} сайтах\n"
200
+ f.write "Эффективность размещения #{(yes.to_f * 100 / all.to_f).round(2).to_s}%\n"
201
+
202
+ f.write "\n\nНайденные ссылки:\n"
203
+ f.write "-----------------------\n"
204
+
205
+ @links.each do |l|
206
+ f.write "#{l}:\n---\n"
207
+ c = 0
208
+ @result.each do |r|
209
+ if r[:link] == l
210
+ c += 1
211
+ f.write "#{r[:page]}\n"
212
+ end
213
+ end
214
+ dia_data << {:link => l, :count => c}
215
+ end
216
+
217
+ f.write "\n\nНе найденные ссылки:\n"
218
+ f.write "-----------------------\n"
219
+ @sites.each do |s|
220
+ f.write "#{s}\n"
221
+ end
222
+ end
223
+ dia = Gruff::Bar.new
224
+ dia.title = "Отчет"
225
+ dia_data.each { |d| dia.data(d[:link], d[:count]) }
226
+ dia.write("/home/chemt79/result.png")
227
+ dia_refresh
228
+ end
229
+ end
230
+
231
+ def stop_process
232
+ @main_thread.kill unless @main_thread.nil?
233
+ @threads.each { |t| t.kill }
234
+ progress_reset
235
+ @fcb_links.sensitive =
236
+ @fcb_sites.sensitive =
237
+ @sb_threads.sensitive =
238
+ @sb_recurse.sensitive = true
239
+ end
240
+
241
+ def recurse_select_refs(host, url, links, result, recurse)
242
+ return if recurse <= 0
243
+
244
+ doc = ''
245
+ begin
246
+ status = Timeout::timeout(10) do
247
+ doc = Nokogiri::HTML(open(url))
248
+ end
249
+ rescue Exception => e
250
+ puts e
251
+ return nil
252
+ end
253
+
254
+ refs = doc.xpath('//a')
255
+ refs.each do |r|
256
+ begin
257
+ uri = URI.parse(r['href'])
258
+ rescue Exception => e
259
+ puts e.to_s + '-' + r['href'].to_s
260
+ next
261
+ end
262
+
263
+ uri.scheme = URI.parse(host).scheme if uri.scheme.nil?
264
+ uri.host = URI.parse(host).host if uri.host.nil?
265
+
266
+ index = links.index(uri.to_s)
267
+ result << { :page => url, :link => uri.to_s } unless index.nil?
268
+
269
+ # puts ".#{recurse} - #{uri.to_s}"
270
+
271
+ recurse_select_refs(host, uri.to_s, links, result, recurse - 1) if uri.host == URI.parse(host).host
272
+ end
273
+ end
274
+ end
275
+
276
+ # Your code goes here...
277
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'link_finder/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "link_finder"
8
+ gem.version = LinkFinder::VERSION
9
+ gem.authors = ["Chemeris P.Taras"]
10
+ gem.email = ["chemt79@gmail.com"]
11
+ gem.description = %q{Искалка ссылок на сайтах}
12
+ gem.summary = %q{Утилита}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: link_finder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chemeris P.Taras
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-17 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Искалка ссылок на сайтах
15
+ email:
16
+ - chemt79@gmail.com
17
+ executables:
18
+ - link_finder
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - .gitignore
23
+ - Gemfile
24
+ - LICENSE.txt
25
+ - README.md
26
+ - Rakefile
27
+ - bin/link_finder
28
+ - install.sh
29
+ - lib/link_finder.glade
30
+ - lib/link_finder.rb
31
+ - lib/link_finder/version.rb
32
+ - link_finder.gemspec
33
+ homepage: ''
34
+ licenses: []
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ requirements: []
52
+ rubyforge_project:
53
+ rubygems_version: 1.8.24
54
+ signing_key:
55
+ specification_version: 3
56
+ summary: Утилита
57
+ test_files: []