]> gitweb.factorcode.org Git - factor.git/blob - extra/geo-ip/geo-ip.factor
Merge branch 'master' of http://alfredobeaumont.org/factor
[factor.git] / extra / geo-ip / geo-ip.factor
1 ! Copyright (C) 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: kernel sequences io.files io.launcher io.encodings.ascii
4 io.streams.string http.client generalizations combinators
5 math.parser math.vectors math.intervals interval-maps memoize
6 csv accessors assocs strings math splitting grouping arrays ;
7 IN: geo-ip
8
9 : db-path ( -- path ) "IpToCountry.csv" temp-file ;
10
11 : db-url ( -- url ) "http://software77.net/cgi-bin/ip-country/geo-ip.pl?action=download" ;
12
13 : download-db ( -- path )
14     db-path dup exists? [
15         db-url over ".gz" append download-to
16         { "gunzip" } over ".gz" append (normalize-path) suffix try-process
17     ] unless ;
18
19 TUPLE: ip-entry from to registry assigned city cntry country ;
20
21 : parse-ip-entry ( row -- ip-entry )
22     7 firstn {
23         [ string>number ]
24         [ string>number ]
25         [ ]
26         [ ]
27         [ ]
28         [ ]
29         [ ]
30     } spread ip-entry boa ;
31
32 MEMO: ip-db ( -- seq )
33     download-db ascii file-lines
34     [ "#" head? not ] filter "\n" join <string-reader> csv
35     [ parse-ip-entry ] map ;
36
37 : filter-overlaps ( alist -- alist' )
38     2 clump
39     [ first2 [ first second ] [ first first ] bi* < ] filter
40     [ first ] map ;
41
42 MEMO: ip-intervals ( -- interval-map )
43     ip-db [ [ [ from>> ] [ to>> ] bi 2array ] keep ] { } map>assoc
44     filter-overlaps <interval-map> ;
45
46 GENERIC: lookup-ip ( ip -- ip-entry )
47
48 M: string lookup-ip
49     "." split [ string>number ] map
50     { HEX: 1000000 HEX: 10000 HEX: 100 HEX: 1 } v.
51     lookup-ip ;
52
53 M: integer lookup-ip ip-intervals interval-at ;