1 ! Copyright (C) 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays assocs combinators combinators.smart csv
4 grouping http.client interval-maps io.encodings.ascii io.files
5 io.files.temp io.launcher io.pathnames ip-parser kernel math
6 math.parser sequences splitting strings ;
9 : db-path ( -- path ) "IpToCountry.csv" cache-file ;
11 CONSTANT: db-url "http://software77.net/geo-ip/?DL=1"
13 : download-db ( -- path )
14 db-path dup file-exists? [
15 db-url over ".gz" append download-to
16 { "gunzip" } over ".gz" append absolute-path suffix try-process
19 TUPLE: ip-entry from to registry assigned city cntry country ;
21 : parse-ip-entry ( row -- ip-entry )
32 ] input<sequence ip-entry boa ;
34 MEMO: ip-db ( -- seq )
35 download-db ascii file-lines
36 [ "#" head? ] reject join-lines string>csv
37 [ parse-ip-entry ] map ;
39 : filter-overlaps ( alist -- alist' )
41 [ first2 [ first second ] [ first first ] bi* < ] filter
44 MEMO: ip-intervals ( -- interval-map )
45 ip-db [ [ [ from>> ] [ to>> ] bi 2array ] keep ] { } map>assoc
46 filter-overlaps <interval-map> ;
48 GENERIC: lookup-ip ( ip -- ip-entry )
50 M: string lookup-ip ipv4-aton lookup-ip ;
52 M: integer lookup-ip ip-intervals interval-at ;