1 ! Copyright (C) 2008 Slava Pestov.
2 ! See https://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays assocs combinators combinators.smart csv
4 grouping http.download 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 "https://raw.githubusercontent.com/webeng/Ip2Country/master/IpToCountry.csv"
13 : download-db ( -- path ) db-url download-once ;
15 TUPLE: ip-entry from to registry assigned city cntry country ;
17 : parse-ip-entry ( row -- ip-entry )
28 ] input<sequence ip-entry boa ;
30 MEMO: ip-db ( -- seq )
31 download-db ascii file-lines
32 [ "#" head? ] reject join-lines string>csv
33 [ parse-ip-entry ] map ;
35 : filter-overlaps ( alist -- alist' )
37 [ first2 [ first second ] [ first first ] bi* < ] filter
40 MEMO: ip-intervals ( -- interval-map )
41 ip-db [ [ [ from>> ] [ to>> ] bi 2array ] keep ] { } map>assoc
42 filter-overlaps <interval-map> ;
44 GENERIC: lookup-ip ( ip -- ip-entry )
46 M: string lookup-ip ipv4-aton lookup-ip ;
48 M: integer lookup-ip ip-intervals interval-at ;