srcforge 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.txt +3 -0
- data/bin/srcforge +13 -0
- data/docs/README.txt +105 -0
- data/lib/sourceforge.rb +475 -0
- data/srcforge.gemspec +31 -0
- metadata +68 -0
data/HISTORY.txt
ADDED
data/bin/srcforge
ADDED
data/docs/README.txt
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
|
2
|
+
This script allows you to easily automate the downloading of
|
3
|
+
the latest version of any sourceforge project (as stored up
|
4
|
+
to 31/03/2006) from any of sourceforge server by having it
|
5
|
+
parse the web pages for the project and extract the latest
|
6
|
+
release.
|
7
|
+
It supports connecting through a proxy if either the
|
8
|
+
environment variable HTTP_PROXY or http_proxy is defined.
|
9
|
+
Also, downloads can be resumed like wget, in case the
|
10
|
+
download is abruptly terminated.
|
11
|
+
If .md5 checksums are available, they will also be downloaded
|
12
|
+
and verified using ruby's digest/md5.
|
13
|
+
|
14
|
+
|
15
|
+
Use:
|
16
|
+
srcforge -h
|
17
|
+
|
18
|
+
to obtain a list of the latest command-line switches.
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
Common Usage:
|
23
|
+
|
24
|
+
> srcforge [options] <project>
|
25
|
+
|
26
|
+
where <project> is a valid sourceforge project, as named in the
|
27
|
+
http://sourceforge.net/projects/<project>.
|
28
|
+
|
29
|
+
The default behavior of the script is to try to to download files through
|
30
|
+
a proxy if possible and to download binary files for your platform and
|
31
|
+
That is, .exe's or .zip's for windows, and tar.gz files for others.
|
32
|
+
|
33
|
+
|
34
|
+
Example 1: Downloading binaries
|
35
|
+
---------
|
36
|
+
|
37
|
+
> srcforge scons
|
38
|
+
Using proxy 127.0.0.1:8118
|
39
|
+
Connecting to sourceforge...
|
40
|
+
Files to download:
|
41
|
+
1) scons-0.96.92.win32.exe *YES*
|
42
|
+
|
43
|
+
Downloading from 'easynews.dl.sourceforge.net':
|
44
|
+
scons-0.96.92.win32.exe 437641 bytes.
|
45
|
+
|--------------------------------------------------------------------|
|
46
|
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
Example 2: Downloading source code only
|
51
|
+
---------
|
52
|
+
|
53
|
+
> srcforge scons -src
|
54
|
+
Using proxy 127.0.0.1:8118
|
55
|
+
Connecting to sourceforge...
|
56
|
+
Files to download:
|
57
|
+
1) scons-src-0.96.92.tar.gz *YES*
|
58
|
+
|
59
|
+
Downloading from 'easynews.dl.sourceforge.net':
|
60
|
+
scons-src-0.96.92.tar.gz 1375075 bytes.
|
61
|
+
|--------------------------------------------------------------------|
|
62
|
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
Example 3: Downloading everything for all platforms
|
68
|
+
---------
|
69
|
+
|
70
|
+
> srcforge scons -all
|
71
|
+
Using proxy 127.0.0.1:8118
|
72
|
+
Connecting to sourceforge...
|
73
|
+
Files to download:
|
74
|
+
1) scons-0.96.92-1.noarch.rpm *YES*
|
75
|
+
2) scons-0.96.92.tar.gz *YES*
|
76
|
+
3) scons-0.96.92.win32.exe *YES*
|
77
|
+
4) scons-0.96.92.zip *YES*
|
78
|
+
5) scons-local-0.96.92.tar.gz *YES*
|
79
|
+
6) scons-local-0.96.92.zip *YES*
|
80
|
+
|
81
|
+
Downloading from 'easynews.dl.sourceforge.net':
|
82
|
+
scons-0.96.92-1.noarch.rpm 644187 bytes.
|
83
|
+
.....etc....
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
Example 4: Choose what to download
|
90
|
+
---------
|
91
|
+
|
92
|
+
> srcforge scons -all -ch
|
93
|
+
Using proxy 127.0.0.1:8118
|
94
|
+
Connecting to sourceforge...
|
95
|
+
Files to download:
|
96
|
+
1) scons-0.96.92-1.noarch.rpm
|
97
|
+
2) scons-0.96.92.tar.gz
|
98
|
+
3) scons-0.96.92.win32.exe
|
99
|
+
4) scons-0.96.92.zip
|
100
|
+
5) scons-local-0.96.92.tar.gz
|
101
|
+
6) scons-local-0.96.92.zip
|
102
|
+
|
103
|
+
Choose one or more files to download:
|
104
|
+
(Use '1 3 4' to toggle file or '3-5' for toggling a range)
|
105
|
+
>
|
data/lib/sourceforge.rb
ADDED
@@ -0,0 +1,475 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'uri'
|
5
|
+
|
6
|
+
# Additional libraries ( from rubygems )
|
7
|
+
require 'web/htmltools/xmltree' # narf htmltools parser
|
8
|
+
require 'Getopt/Declare'
|
9
|
+
|
10
|
+
|
11
|
+
#
|
12
|
+
# Trap interrupts and exit gracefully.
|
13
|
+
#
|
14
|
+
BEGIN {
|
15
|
+
trap('INT') {
|
16
|
+
$stderr.puts "[CTRL-C] Aborting..."
|
17
|
+
exit(1)
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
|
22
|
+
class SourceForge
|
23
|
+
CHECKSUMS = 'md5'
|
24
|
+
|
25
|
+
DEFAULT_SERVERS = [
|
26
|
+
'easynews', # US
|
27
|
+
'umn', # US
|
28
|
+
'ufpr', # brazil
|
29
|
+
'kent', # UK
|
30
|
+
'surfnet', # NL
|
31
|
+
'internap', # US
|
32
|
+
'ovh', # FR
|
33
|
+
'switch', # CH
|
34
|
+
'heanet', # IE
|
35
|
+
'superb', # US
|
36
|
+
'nchc', # TW
|
37
|
+
'jaist', # JP
|
38
|
+
'mesh', # DE
|
39
|
+
]
|
40
|
+
|
41
|
+
#
|
42
|
+
# Parse command-line arguments.
|
43
|
+
#
|
44
|
+
def parse_args
|
45
|
+
@args = Getopt::Declare.new(<<'EOH')
|
46
|
+
|
47
|
+
This script allows you to easily automate the downloading of
|
48
|
+
the latest version of any sourceforge project (as stored up
|
49
|
+
to 31/03/2006) from any of sourceforge server by having it
|
50
|
+
parse the web pages for the project and extract the latest
|
51
|
+
release.
|
52
|
+
It supports connecting through a proxy if either the
|
53
|
+
environment variable HTTP_PROXY or http_proxy is defined.
|
54
|
+
Also, downloads can be resumed like wget, in case the
|
55
|
+
download is abruptly terminated.
|
56
|
+
If .md5 checksums are available, they will also be downloaded
|
57
|
+
and verified using ruby's digest/md5.
|
58
|
+
|
59
|
+
Options:
|
60
|
+
-np connect to the net without a proxy
|
61
|
+
-all Try download all files for all OSes.
|
62
|
+
Default: only current os.
|
63
|
+
-o <dir:d> Output directory to place files in.
|
64
|
+
Default: .
|
65
|
+
-src Try to download source files only.
|
66
|
+
-ls list valid names of servers to download
|
67
|
+
from.
|
68
|
+
-s <server:s> name of the server to download from.
|
69
|
+
Default: #{@server}.
|
70
|
+
-ch [<num:+i>...] Choose to download some files only.
|
71
|
+
<project:s>... name of the project(s) to download.
|
72
|
+
|
73
|
+
EOH
|
74
|
+
|
75
|
+
@server = @args['-s'] || DEFAULT_SERVERS[0]
|
76
|
+
|
77
|
+
dir = @args['-o'] || '.'
|
78
|
+
Dir.chdir(dir)
|
79
|
+
|
80
|
+
### This proxy is set to use Privoxy/TOR's default configuration.
|
81
|
+
### If no proxy, make @proxy_host = nil or use -np option.
|
82
|
+
unless @args['-np']
|
83
|
+
@proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
|
84
|
+
if @proxy.kind_of?(String)
|
85
|
+
@proxy =~ /http:\/\/([^:]+):(\d+)/
|
86
|
+
@proxy_host = $1
|
87
|
+
@proxy_port = $2
|
88
|
+
puts "Using proxy #{@proxy_host}:#{@proxy_port}"
|
89
|
+
end
|
90
|
+
@proxy_user = nil
|
91
|
+
@proxy_pass = nil
|
92
|
+
end
|
93
|
+
|
94
|
+
if @args['-ls']
|
95
|
+
puts DEFAULT_SERVERS
|
96
|
+
exit
|
97
|
+
end
|
98
|
+
|
99
|
+
@project_list = @args['<project>']
|
100
|
+
unless @project_list
|
101
|
+
$stderr.puts "Error: required parameter '<project>' missing."
|
102
|
+
$stderr.puts
|
103
|
+
$stderr.puts "(try '#{$0} -help' for more information)"
|
104
|
+
exit(1)
|
105
|
+
end
|
106
|
+
|
107
|
+
@proxy = Net::HTTP::Proxy(@proxy_host, @proxy_port,
|
108
|
+
@proxy_user, @proxy_pass)
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
#
|
113
|
+
# Given a project, try to find the latest file releases for it
|
114
|
+
# in sourceforge.
|
115
|
+
#
|
116
|
+
# Return: Array of files
|
117
|
+
#
|
118
|
+
def find_latest_releases
|
119
|
+
puts "Connecting to sourceforge..."
|
120
|
+
url = URI.parse( 'http://sourceforge.net/projects/' + @project )
|
121
|
+
req = Net::HTTP::Get.new(url.path)
|
122
|
+
|
123
|
+
|
124
|
+
http = @proxy.start(url.host)
|
125
|
+
res = http.request(req)
|
126
|
+
if res.code.to_i != 200
|
127
|
+
$stderr.puts "Could not open connection to sourceforge. Error code: #{res.code}"
|
128
|
+
$stderr.puts res.message
|
129
|
+
$stderr.puts res.body
|
130
|
+
exit(res.code.to_i)
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
res.body =~ /(\/project\/showfiles.php\?group_id=\d+)/
|
135
|
+
path = $1
|
136
|
+
unless path
|
137
|
+
$stderr.puts "Non-existent project \"#{@project}\"."
|
138
|
+
exit(1)
|
139
|
+
end
|
140
|
+
|
141
|
+
req = Net::HTTP::Get.new(path)
|
142
|
+
res = http.request(req)
|
143
|
+
if res.code.to_i != 200
|
144
|
+
$stderr.puts "Could not get #{path}. Error code: #{res.code}"
|
145
|
+
$stderr.puts res.message
|
146
|
+
$stderr.puts res.body
|
147
|
+
exit(200)
|
148
|
+
end
|
149
|
+
|
150
|
+
p = HTMLTree::XMLParser.new(false, true)
|
151
|
+
p.feed( res.body )
|
152
|
+
xml = p.tree
|
153
|
+
|
154
|
+
re = /^http:\/\/prdownloads\.sourceforge\.net\/#{@project}\/([^\?]+)/
|
155
|
+
|
156
|
+
files = []
|
157
|
+
xml.elements.each('//tr/td/a') { |x|
|
158
|
+
parent = x.parent.parent
|
159
|
+
clas = parent.attributes['class']
|
160
|
+
next if clas != 'show'
|
161
|
+
attr = x.attributes['href']
|
162
|
+
next if attr !~ re
|
163
|
+
files << $1
|
164
|
+
}
|
165
|
+
|
166
|
+
return files
|
167
|
+
end
|
168
|
+
|
169
|
+
#
|
170
|
+
# Start downloading files stored in @downloads array
|
171
|
+
#
|
172
|
+
def start_downloads
|
173
|
+
path = "http://#{@server}.dl.sourceforge.net/sourceforge/#{@project}/"
|
174
|
+
url = URI.parse( path )
|
175
|
+
puts
|
176
|
+
puts "Downloading from '#{url.host}':"
|
177
|
+
|
178
|
+
@downloads.each { |d|
|
179
|
+
print "\t#{d}"
|
180
|
+
|
181
|
+
begin
|
182
|
+
f = nil
|
183
|
+
header = nil
|
184
|
+
existSize = 0
|
185
|
+
|
186
|
+
http = @proxy.start(url.host)
|
187
|
+
if File.exists?(d) and File.size(d) > 0
|
188
|
+
existSize = File.size(d)
|
189
|
+
f = open(d, 'ab')
|
190
|
+
header = { 'Range' => 'bytes=%d-' % existSize }
|
191
|
+
else
|
192
|
+
f = open(d, 'wb')
|
193
|
+
end
|
194
|
+
req = Net::HTTP::Get.new( url.path + d, header )
|
195
|
+
|
196
|
+
http.request( req, header ) { |response|
|
197
|
+
webSize = response.content_length.to_i + existSize
|
198
|
+
if webSize == existSize
|
199
|
+
puts "\tAlready downloaded."
|
200
|
+
break
|
201
|
+
end
|
202
|
+
|
203
|
+
code = response.code.to_i
|
204
|
+
if code == 302
|
205
|
+
puts "\t** NOT IN MIRROR **"
|
206
|
+
break
|
207
|
+
elsif code != 200 and code != 206
|
208
|
+
puts response.body
|
209
|
+
break
|
210
|
+
else
|
211
|
+
size = webSize - existSize
|
212
|
+
if size == webSize
|
213
|
+
puts "\t#{webSize} bytes."
|
214
|
+
else
|
215
|
+
if code != 204
|
216
|
+
f = open(d, 'wb')
|
217
|
+
puts "\t#{webSize} bytes."
|
218
|
+
else
|
219
|
+
puts " Continue #{size} of #{webSize} bytes."
|
220
|
+
end
|
221
|
+
end
|
222
|
+
###
|
223
|
+
line_length = 68
|
224
|
+
puts "\t|" + '-'*line_length + '|'
|
225
|
+
num = (existSize.to_f / webSize.to_f * line_length).to_i
|
226
|
+
$stdout.print "\t " + '#' * num
|
227
|
+
$stdout.flush
|
228
|
+
numBytes = existSize.to_f
|
229
|
+
response.read_body { |data|
|
230
|
+
f.print data
|
231
|
+
numBytes += data.size
|
232
|
+
newnum = (numBytes / webSize.to_f * line_length).to_i - num
|
233
|
+
if newnum > 0
|
234
|
+
$stdout.print '+' * newnum
|
235
|
+
$stdout.flush
|
236
|
+
num += newnum
|
237
|
+
end
|
238
|
+
}
|
239
|
+
puts
|
240
|
+
end
|
241
|
+
}
|
242
|
+
# When using TOR, sometimes when a circuit changes, you can
|
243
|
+
# end up with a timeout/response error. We just retry the request.
|
244
|
+
rescue Timeout::Error, Net::HTTPBadResponse => e
|
245
|
+
puts " #{e} - retry"
|
246
|
+
retry
|
247
|
+
end
|
248
|
+
|
249
|
+
f.close
|
250
|
+
}
|
251
|
+
end
|
252
|
+
|
253
|
+
|
254
|
+
#
|
255
|
+
# Filter downloads. If any regex of filter matches, all other
|
256
|
+
# elements are removed.
|
257
|
+
# Also, checksum files are added to downloads (if available)
|
258
|
+
#
|
259
|
+
def filter_downloads(filter)
|
260
|
+
checksums = @downloads.grep(/\.#{CHECKSUMS}$/i)
|
261
|
+
|
262
|
+
filter.each { |re|
|
263
|
+
unless @downloads.grep(re).empty?
|
264
|
+
@downloads.delete_if { |f| f !~ re }
|
265
|
+
break
|
266
|
+
end
|
267
|
+
}
|
268
|
+
|
269
|
+
@downloads.each { |d|
|
270
|
+
item = checksums.grep(/^#{d}\.#{CHECKSUMS}$/)
|
271
|
+
next if item.empty?
|
272
|
+
@checksums << item[0]
|
273
|
+
}
|
274
|
+
@downloads += @checksums
|
275
|
+
end
|
276
|
+
|
277
|
+
#
|
278
|
+
# Print out a menu with the list of files to download.
|
279
|
+
#
|
280
|
+
def file_menu(filter)
|
281
|
+
puts "Files to download:"
|
282
|
+
@downloads.each_with_index { |x, i|
|
283
|
+
print "\t%2d) %-40s" % [i+1, x]
|
284
|
+
if filter.include?(i+1)
|
285
|
+
print "\t*YES*"
|
286
|
+
end
|
287
|
+
print "\n"
|
288
|
+
}
|
289
|
+
end
|
290
|
+
|
291
|
+
#
|
292
|
+
# Ask user to choose some files.
|
293
|
+
#
|
294
|
+
def choose_files
|
295
|
+
puts
|
296
|
+
puts "Choose one or more files to download:"
|
297
|
+
puts "(Use '1 3 4' to toggle file or '3-5' for toggling a range)"
|
298
|
+
print ">"
|
299
|
+
cmd = $stdin.gets.split(/[,\s]+/)
|
300
|
+
answer = []
|
301
|
+
cmd.each { |c|
|
302
|
+
if c =~ /(\d+)-(\d+)/
|
303
|
+
answer += ($1.to_i..$2.to_i).to_a
|
304
|
+
else
|
305
|
+
answer << c.to_i
|
306
|
+
end
|
307
|
+
}
|
308
|
+
return answer.uniq
|
309
|
+
end
|
310
|
+
|
311
|
+
#
|
312
|
+
# Do the download of files
|
313
|
+
#
|
314
|
+
def do_download
|
315
|
+
@checksums = []
|
316
|
+
|
317
|
+
if @args['-src'] and @downloads.size > 1
|
318
|
+
@downloads.delete_if { |f| f =~ /\.(exe|rpm|deb)$/i }
|
319
|
+
|
320
|
+
# If files are labelled with src or source, remove
|
321
|
+
# all other files from list.
|
322
|
+
src_re = /(?:src|source)/i
|
323
|
+
unless @downloads.grep(src_re).empty?
|
324
|
+
@downloads.delete_if { |f| f !~ src_re }
|
325
|
+
end
|
326
|
+
|
327
|
+
# If sources are available in multiple compression
|
328
|
+
# formats, prefer smallest linux format.
|
329
|
+
filter_downloads(
|
330
|
+
[
|
331
|
+
/\.tar\.7za$/i,
|
332
|
+
/\.tar\.bz2$/i,
|
333
|
+
/\.tar\.gz$/i,
|
334
|
+
/\.tgz$/i,
|
335
|
+
/\.zip$/i,
|
336
|
+
/\.tar$/i,
|
337
|
+
]
|
338
|
+
)
|
339
|
+
else
|
340
|
+
# Delete any source file archives...
|
341
|
+
@downloads.delete_if { |f| f =~ /(?:src|source)/i }
|
342
|
+
|
343
|
+
|
344
|
+
if @downloads.size > 1 and not @args['-all']
|
345
|
+
# if more than one download, choose based on platform
|
346
|
+
filter = [
|
347
|
+
/\.tar\.bz2$/i,
|
348
|
+
/\.tar\.gz$/i,
|
349
|
+
/\.tgz$/i,
|
350
|
+
/\.sh$/i
|
351
|
+
]
|
352
|
+
|
353
|
+
case RUBY_PLATFORM
|
354
|
+
when /mswin/
|
355
|
+
unless @downloads.grep(/\.(exe|zip)$/).empty?
|
356
|
+
filter = [
|
357
|
+
/\.exe$/i,
|
358
|
+
/\.zip$/i,
|
359
|
+
/\.tar\.bz2$/i,
|
360
|
+
/\.tar\.gz$/i,
|
361
|
+
/\.tgz$/i,
|
362
|
+
/\.sh$/i
|
363
|
+
]
|
364
|
+
end
|
365
|
+
when /linux/
|
366
|
+
unless @downloads.grep(/\.(rpm|deb)$/).empty?
|
367
|
+
filter = [
|
368
|
+
/\.rpm$/i,
|
369
|
+
/\.deb$/i,
|
370
|
+
/\.tar\.bz2$/i,
|
371
|
+
/\.tar\.gz$/i,
|
372
|
+
/\.tgz$/i,
|
373
|
+
/\.sh$/i
|
374
|
+
]
|
375
|
+
end
|
376
|
+
when /osx/
|
377
|
+
unless @downloads.grep(/\.dmg$/).empty?
|
378
|
+
filter = [
|
379
|
+
/\.dmg$/i,
|
380
|
+
/\.tar\.bz2$/i,
|
381
|
+
/\.tar\.gz$/i,
|
382
|
+
/\.tgz$/i,
|
383
|
+
/\.sh$/i
|
384
|
+
]
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
filter_downloads(filter)
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
if @downloads.empty?
|
393
|
+
puts "Nothing to download."
|
394
|
+
exit(1)
|
395
|
+
end
|
396
|
+
|
397
|
+
|
398
|
+
filter = (1..@downloads.size).to_a
|
399
|
+
|
400
|
+
if @args['-ch']
|
401
|
+
filter = @args['-ch']
|
402
|
+
end
|
403
|
+
|
404
|
+
if @args['-ch'] and filter.empty?
|
405
|
+
answer = [1]
|
406
|
+
while not answer.empty?
|
407
|
+
file_menu(filter)
|
408
|
+
answer = choose_files
|
409
|
+
filter = filter + answer - ( filter & answer )
|
410
|
+
end
|
411
|
+
else
|
412
|
+
file_menu(filter)
|
413
|
+
end
|
414
|
+
|
415
|
+
unless filter.empty?
|
416
|
+
i = 0
|
417
|
+
@downloads.delete_if {
|
418
|
+
i += 1
|
419
|
+
not filter.include?(i)
|
420
|
+
}
|
421
|
+
end
|
422
|
+
|
423
|
+
if @downloads.empty?
|
424
|
+
puts "Nothing to download."
|
425
|
+
exit(1)
|
426
|
+
end
|
427
|
+
|
428
|
+
start_downloads
|
429
|
+
end
|
430
|
+
|
431
|
+
|
432
|
+
#
|
433
|
+
# For each checksum downloaded, verify it.
|
434
|
+
#
|
435
|
+
def verify_checksums
|
436
|
+
return if @checksums.empty?
|
437
|
+
|
438
|
+
require 'digest/md5'
|
439
|
+
|
440
|
+
puts "Verifying Checksums..."
|
441
|
+
|
442
|
+
@checksums.each { |c|
|
443
|
+
File.open(c, 'r') { |cm|
|
444
|
+
while not cm.eof?
|
445
|
+
line = cm.readline
|
446
|
+
checksum, file = line.split(/\s+/)
|
447
|
+
sum = Digest::MD5.new
|
448
|
+
File.open(file, 'rb') { |f|
|
449
|
+
while not f.eof?
|
450
|
+
sum << f.read(8196)
|
451
|
+
end
|
452
|
+
}
|
453
|
+
print "\t#{file}...\t"
|
454
|
+
if sum != checksum
|
455
|
+
puts "FAILED!!!"
|
456
|
+
else
|
457
|
+
puts "OK"
|
458
|
+
end
|
459
|
+
end
|
460
|
+
}
|
461
|
+
}
|
462
|
+
end
|
463
|
+
|
464
|
+
#
|
465
|
+
# Constructor.
|
466
|
+
#
|
467
|
+
def initialize
|
468
|
+
parse_args
|
469
|
+
@project_list.each { |@project|
|
470
|
+
@downloads = find_latest_releases
|
471
|
+
do_download
|
472
|
+
verify_checksums
|
473
|
+
}
|
474
|
+
end
|
475
|
+
end
|
data/srcforge.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
|
3
|
+
spec = Gem::Specification.new do |spec|
|
4
|
+
spec.name = "srcforge"
|
5
|
+
spec.version = '0.1.0'
|
6
|
+
spec.author = "Gonzalo Garramuno"
|
7
|
+
spec.email = 'ggarram@advance.dsl.com.ar'
|
8
|
+
spec.homepage = 'http://www.rubyforge.org/projects/srcforge/'
|
9
|
+
spec.summary = 'Download tool for files at sourceforge.net.'
|
10
|
+
spec.executables = ['srcforge']
|
11
|
+
spec.files = ['bin/srcforge', 'lib/sourceforge.rb']
|
12
|
+
spec.description = <<-EOF
|
13
|
+
This script allows you to easily automate the downloading of
|
14
|
+
the latest version of any sourceforge project (as stored up
|
15
|
+
to 31/03/2006) from any of sourceforge server by having it
|
16
|
+
parse the web pages for the project and extract the latest
|
17
|
+
release.
|
18
|
+
It supports connecting through a proxy if either the
|
19
|
+
environment variable HTTP_PROXY or http_proxy is defined.
|
20
|
+
Also, downloads can be resumed like wget, in case the
|
21
|
+
download is abruptly terminated.
|
22
|
+
If .md5 checksums are available, they will also be downloaded
|
23
|
+
and verified using ruby's digest/md5.
|
24
|
+
EOF
|
25
|
+
spec.add_dependency("narf", ">= 0.7.3")
|
26
|
+
spec.add_dependency("getopt-declare", ">= 1.12")
|
27
|
+
spec.extra_rdoc_files = ["HISTORY.txt", "srcforge.gemspec"] + Dir.glob("docs/README.txt")
|
28
|
+
spec.has_rdoc = true
|
29
|
+
spec.rubyforge_project = 'srcforge'
|
30
|
+
spec.required_ruby_version = '>= 1.8.0'
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: srcforge
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.1.0
|
7
|
+
date: 2006-05-17 00:00:00 -03:00
|
8
|
+
summary: Download tool for files at sourceforge.net.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: ggarram@advance.dsl.com.ar
|
12
|
+
homepage: http://www.rubyforge.org/projects/srcforge/
|
13
|
+
rubyforge_project: srcforge
|
14
|
+
description: This script allows you to easily automate the downloading of the latest version of any sourceforge project (as stored up to 31/03/2006) from any of sourceforge server by having it parse the web pages for the project and extract the latest release. It supports connecting through a proxy if either the environment variable HTTP_PROXY or http_proxy is defined. Also, downloads can be resumed like wget, in case the download is abruptly terminated. If .md5 checksums are available, they will also be downloaded and verified using ruby's digest/md5.
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.8.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
authors:
|
29
|
+
- Gonzalo Garramuno
|
30
|
+
files:
|
31
|
+
- bin/srcforge
|
32
|
+
- lib/sourceforge.rb
|
33
|
+
- HISTORY.txt
|
34
|
+
- srcforge.gemspec
|
35
|
+
- docs/README.txt
|
36
|
+
test_files: []
|
37
|
+
|
38
|
+
rdoc_options: []
|
39
|
+
|
40
|
+
extra_rdoc_files:
|
41
|
+
- HISTORY.txt
|
42
|
+
- srcforge.gemspec
|
43
|
+
- docs/README.txt
|
44
|
+
executables:
|
45
|
+
- srcforge
|
46
|
+
extensions: []
|
47
|
+
|
48
|
+
requirements: []
|
49
|
+
|
50
|
+
dependencies:
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: narf
|
53
|
+
version_requirement:
|
54
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: 0.7.3
|
59
|
+
version:
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: getopt-declare
|
62
|
+
version_requirement:
|
63
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "1.12"
|
68
|
+
version:
|