start refactoring - works so far
[zip-doc.git] / zarchive.rb
blob52e391f93747a54e8bab3a59887ed45d06b847b4
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'
12 require 'digest'
14 class String
15   def pop(number = 1)
16     self.slice!(-number..-1)
17   end
18 end       
19                 
20 class IO 
21   def readloc(size, offset) 
22     self.seek(offset)
23     self.read(size)
24   end
25 end
27 class ZArchive               
28   def initialize(file)
29     @zdump = File.open(file, 'r')
30     @zdump_loc = @zdump.read(4).unpack('V')[0]
31   end
33   def get_article(url)      
34     loc = get_location(url)
35     return loc ? get_text(*loc) : nil
36   end
38   private
39   def get_text(block_offset, block_size, offset, size)
40     return ZCompress.uncompress( @zdump.readloc( block_size, block_offset ))[offset, size]
41   end
42     
43   def get_location(url)
44     md5 = Digest::MD5.hexdigest(url)
45     firstfour = sprintf("%d", ("0x" + md5[0..3]) ).to_i
46     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