diff --git a/extra/geo-ip/authors.txt b/extra/geo-ip/authors.txt new file mode 100644 index 0000000000..1901f27a24 --- /dev/null +++ b/extra/geo-ip/authors.txt @@ -0,0 +1 @@ +Slava Pestov diff --git a/extra/geo-ip/geo-ip.factor b/extra/geo-ip/geo-ip.factor new file mode 100644 index 0000000000..5926dd596d --- /dev/null +++ b/extra/geo-ip/geo-ip.factor @@ -0,0 +1,46 @@ +USING: kernel sequences io.files io.launcher io.encodings.ascii +io.streams.string http.client sequences.lib combinators +math.parser math.vectors math.intervals interval-maps memoize +csv accessors assocs strings math splitting ; +IN: geo-ip + +: db-path "IpToCountry.csv" temp-file ; + +: db-url "http://software77.net/cgi-bin/ip-country/geo-ip.pl?action=download" ; + +: download-db ( -- path ) + db-path dup exists? [ + db-url over ".gz" append download-to + { "gunzip" } over ".gz" append (normalize-path) suffix try-process + ] unless ; + +TUPLE: ip-entry from to registry assigned city cntry country ; + +: parse-ip-entry ( row -- ip-entry ) + 7 firstn { + [ string>number ] + [ string>number ] + [ ] + [ ] + [ ] + [ ] + [ ] + } spread ip-entry boa ; + +MEMO: ip-db ( -- seq ) + download-db ascii file-lines + [ "#" head? not ] filter "\n" join csv + [ parse-ip-entry ] map ; + +MEMO: ip-intervals ( -- interval-map ) + ip-db [ [ [ from>> ] [ to>> ] bi [a,b] ] keep ] { } map>assoc + ; + +GENERIC: lookup-ip ( ip -- ip-entry ) + +M: string lookup-ip + "." split [ string>number ] map + { HEX: 1000000 HEX: 10000 HEX: 100 1 } v. + lookup-ip ; + +M: integer lookup-ip ip-intervals interval-at ; diff --git a/extra/geo-ip/summary.txt b/extra/geo-ip/summary.txt new file mode 100644 index 0000000000..402d3230f1 --- /dev/null +++ b/extra/geo-ip/summary.txt @@ -0,0 +1 @@ +IP address geolocation using database from http://software77.net/cgi-bin/ip-country/ diff --git a/extra/geo-ip/tags.txt b/extra/geo-ip/tags.txt new file mode 100644 index 0000000000..0aef4feca8 --- /dev/null +++ b/extra/geo-ip/tags.txt @@ -0,0 +1 @@ +enterprise