Initial import
[zip-doc.git] / zarchive.rb
blob958dc0712e0d739e6a2f07832f17451bb41b3360
1 # Library for accessing a Wikipedia zdump file. 
2
3 # By Stian Haklev (shaklev@gmail.com), 2007
4 # Released under MIT and GPL licenses
5
6 # Usage example: 
7 # require 'zarchive'
8 # archive = ZArchive.new('eo.zdump')
9 # puts ZArchive.get_article('eo/o/s/l/Oslo.html')
11 require 'zcompress'
13 class String
14   def pop(number = 1)
15     self.slice!(-number..-1)
16   end
17 end       
18                 
19 class IO 
20   def readloc(size, offset) 
21     self.seek(offset)
22     self.read(size)
23   end
24 end
26 class ZArchive               
27   def initialize(file)
28     @zdump = File.open(file, 'r')
29     @zdump_loc = @zdump.read(4).unpack('V')[0]
30   end
32   def get_article(url)      
33     loc = get_location(url)
34     return loc ? get_text(*loc) : nil
35   end
37   private
38   def get_text(block_offset, block_size, offset, size)
39     return ZCompress.uncompress( @zdump.readloc( block_size, block_offset ))[offset, size]
40   end
41     
42   def get_location(url)
43     md5 = Digest::MD5.hexdigest(url)
44     firstfour = sprintf("%d", ("0x" + md5[0..3]) ).to_i
45     loc = (firstfour * 8) + @zdump_loc
47     start, size = @zdump.readloc(8, loc).unpack('V2')
48     idx = @zdump.readloc(size, start)
49     hex, *coordinates = idx.pop(32).unpack('H32V4') until ( hex == md5 || idx.empty? )
50     return coordinates if hex == md5
51   end
52 end