geoip 1.3.3 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/Rakefile +1 -0
- data/geoip.gemspec +8 -21
- data/lib/geoip.rb +8 -2
- data/test/csvORG2dat.py +246 -0
- data/test/organizations.csv +5 -0
- data/test/organizations.dat +0 -0
- metadata +8 -15
- data/config/website.yml +0 -2
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/script/txt2html +0 -66
- data/website/index.txt +0 -79
- data/website/javascripts/rounded_corners_lite.inc.js +0 -285
- data/website/stylesheets/screen.css +0 -138
- data/website/template.rhtml +0 -48
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
OGVjZjkwZDUwYTYyYWE2NWJlNWE2Mjc5NGY5NDYwODc4MTY0YTRhMw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MmMzMWI5ODg0Yjc5MDgyNWVkZjM4NzI3YmI2ZjgwYjM4ZmY3MmMxOA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NDcyNDUzYzZhNzA2Njg0MDEzMjg0ZTM2NjVjMjQ4NzQzNDcwZDcxNDkyMmQx
|
10
|
+
ODIyOGJlMTI1NzBlNWNjMDdiMWFlZWViZTk5ZTE1ZTVmNTU2Zjg4ZGJkODRl
|
11
|
+
NmEyYzQyYmUwODZjMzlhOGIwMTE4NjY5YjNmNjgyNjIzNTJlMWQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MDE3MDcwNjE1ZDRiMjM3NGJlMDQ3ODljMzgwNWQyOTFmN2Q5YmNhNGE0YTk5
|
14
|
+
NGI2ZDVmMGRjODE1ZjI3NDRlZWYwOWEyYmFlM2I2YTQzZTUxMTlhNmM4ZjBl
|
15
|
+
MDA3YTI2NWFlOTY4ZWY4ZjA3ZWZhYTAzMTZhZDc1YWRiMzAyNDg=
|
data/Rakefile
CHANGED
@@ -20,6 +20,7 @@ and the city, ISP and other information, if you have that database version.}
|
|
20
20
|
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
21
21
|
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
22
22
|
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
23
|
+
gem.files.exclude "website/**/*.*", "script/*", "config/*"
|
23
24
|
end
|
24
25
|
Jeweler::RubygemsDotOrgTasks.new
|
25
26
|
|
data/geoip.gemspec
CHANGED
@@ -2,14 +2,15 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: geoip 1.3.4 ruby lib
|
5
6
|
|
6
7
|
Gem::Specification.new do |s|
|
7
8
|
s.name = "geoip"
|
8
|
-
s.version = "1.3.
|
9
|
+
s.version = "1.3.4"
|
9
10
|
|
10
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
12
|
s.authors = ["Clifford Heath", "Roland Moriz"]
|
12
|
-
s.date = "2013-
|
13
|
+
s.date = "2013-12-16"
|
13
14
|
s.description = "GeoIP searches a GeoIP database for a given host or IP address, and\nreturns information about the country where the IP address is allocated,\nand the city, ISP and other information, if you have that database version."
|
14
15
|
s.email = ["clifford.heath@gmail.com", "rmoriz@gmail.com"]
|
15
16
|
s.executables = ["geoip"]
|
@@ -23,7 +24,6 @@ Gem::Specification.new do |s|
|
|
23
24
|
"README.rdoc",
|
24
25
|
"Rakefile",
|
25
26
|
"bin/geoip",
|
26
|
-
"config/website.yml",
|
27
27
|
"data/geoip/country_code.yml",
|
28
28
|
"data/geoip/country_code3.yml",
|
29
29
|
"data/geoip/country_continent.yml",
|
@@ -32,29 +32,16 @@ Gem::Specification.new do |s|
|
|
32
32
|
"data/geoip/time_zone.yml",
|
33
33
|
"geoip.gemspec",
|
34
34
|
"lib/geoip.rb",
|
35
|
-
"
|
36
|
-
"
|
37
|
-
"
|
35
|
+
"test/csvORG2dat.py",
|
36
|
+
"test/organizations.csv",
|
37
|
+
"test/organizations.dat",
|
38
38
|
"test/test_geoip.rb",
|
39
|
-
"test/test_helper.rb"
|
40
|
-
"website/index.txt",
|
41
|
-
"website/javascripts/rounded_corners_lite.inc.js",
|
42
|
-
"website/stylesheets/screen.css",
|
43
|
-
"website/template.rhtml"
|
39
|
+
"test/test_helper.rb"
|
44
40
|
]
|
45
41
|
s.homepage = "http://github.com/cjheath/geoip"
|
46
42
|
s.licenses = ["LGPL"]
|
47
43
|
s.require_paths = ["lib"]
|
48
|
-
s.rubygems_version = "1.
|
44
|
+
s.rubygems_version = "2.1.10"
|
49
45
|
s.summary = "GeoIP searches a GeoIP database for a given host or IP address, and returns information about the country where the IP address is allocated, and the city, ISP and other information, if you have that database version."
|
50
|
-
|
51
|
-
if s.respond_to? :specification_version then
|
52
|
-
s.specification_version = 3
|
53
|
-
|
54
|
-
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
55
|
-
else
|
56
|
-
end
|
57
|
-
else
|
58
|
-
end
|
59
46
|
end
|
60
47
|
|
data/lib/geoip.rb
CHANGED
@@ -58,7 +58,7 @@ require 'yaml'
|
|
58
58
|
class GeoIP
|
59
59
|
|
60
60
|
# The GeoIP GEM version number
|
61
|
-
VERSION = "1.3.
|
61
|
+
VERSION = "1.3.4"
|
62
62
|
|
63
63
|
# The +data/+ directory for geoip
|
64
64
|
DATA_DIR = File.expand_path(File.join(File.dirname(__FILE__),'..','data','geoip'))
|
@@ -154,6 +154,12 @@ class GeoIP
|
|
154
154
|
|
155
155
|
end
|
156
156
|
|
157
|
+
class ISP < Struct.new(:lsp)
|
158
|
+
def to_hash
|
159
|
+
Hash[each_pair.to_a]
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
157
163
|
# The Edition number that identifies which kind of database you've opened
|
158
164
|
attr_reader :database_type
|
159
165
|
|
@@ -347,7 +353,7 @@ class GeoIP
|
|
347
353
|
|
348
354
|
record = atomic_read(MAX_ORG_RECORD_LENGTH, off)
|
349
355
|
record = record.sub(/\000.*/n, '')
|
350
|
-
record
|
356
|
+
record.start_with?('*') ? nil : ISP.new(record)
|
351
357
|
end
|
352
358
|
|
353
359
|
# Search a ASN GeoIP database for the specified host, returning the AS
|
data/test/csvORG2dat.py
ADDED
@@ -0,0 +1,246 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# Source : https://github.com/mteodoro/mmutils
|
3
|
+
|
4
|
+
import sys
|
5
|
+
import logging
|
6
|
+
import logging.handlers
|
7
|
+
import optparse
|
8
|
+
|
9
|
+
import csv
|
10
|
+
import fileinput
|
11
|
+
import itertools
|
12
|
+
import struct
|
13
|
+
import time
|
14
|
+
|
15
|
+
from functools import partial
|
16
|
+
|
17
|
+
import ipaddr
|
18
|
+
|
19
|
+
def init_logger(opts):
|
20
|
+
level = logging.INFO
|
21
|
+
handler = logging.StreamHandler()
|
22
|
+
#handler = logging.handlers.SysLogHandler(address='/dev/log')
|
23
|
+
if opts.debug:
|
24
|
+
level = logging.DEBUG
|
25
|
+
handler = logging.StreamHandler()
|
26
|
+
root = logging.getLogger()
|
27
|
+
root.setLevel(level)
|
28
|
+
root.addHandler(handler)
|
29
|
+
|
30
|
+
def parse_args(argv):
|
31
|
+
if argv is None:
|
32
|
+
argv = sys.argv[1:]
|
33
|
+
p = optparse.OptionParser()
|
34
|
+
|
35
|
+
cmdlist = []
|
36
|
+
for cmd, (f, usage) in sorted(cmds.iteritems()):
|
37
|
+
cmdlist.append('%-8s\t%%prog %s' % (cmd, usage))
|
38
|
+
cmdlist = '\n '.join(cmdlist)
|
39
|
+
|
40
|
+
p.usage = '%%prog [options] <cmd> <arg>+\n\nExamples:\n %s' % cmdlist
|
41
|
+
p.add_option('-d', '--debug', action='store_true',
|
42
|
+
default=False, help="debug mode")
|
43
|
+
p.add_option('-g', '--geoip', action='store_true',
|
44
|
+
default=False, help='test with C GeoIP module')
|
45
|
+
p.add_option('-w', '--write-dat', help='write filename.dat')
|
46
|
+
opts, args = p.parse_args(argv)
|
47
|
+
|
48
|
+
#sanity check
|
49
|
+
if not args or args[0] not in cmds:
|
50
|
+
p.error('missing command. choose from: %s' % ' '.join(sorted(cmds)))
|
51
|
+
|
52
|
+
return opts, args
|
53
|
+
|
54
|
+
def gen_csv(f):
|
55
|
+
"""peek at rows from a csv and start yielding when we get past the comments
|
56
|
+
to a row that starts with an int (split at : to check IPv6)"""
|
57
|
+
def startswith_int(row):
|
58
|
+
try:
|
59
|
+
int(row[0].split(':', 1)[0])
|
60
|
+
return True
|
61
|
+
except ValueError:
|
62
|
+
return False
|
63
|
+
|
64
|
+
cr = csv.reader(f)
|
65
|
+
#return itertools.dropwhile(lambda x: not startswith_int(x), cr)
|
66
|
+
return cr
|
67
|
+
|
68
|
+
class RadixTreeNode(object):
|
69
|
+
__slots__ = ['segment', 'lhs', 'rhs']
|
70
|
+
def __init__(self, segment):
|
71
|
+
self.segment = segment
|
72
|
+
self.lhs = None
|
73
|
+
self.rhs = None
|
74
|
+
|
75
|
+
|
76
|
+
class RadixTree(object):
|
77
|
+
def __init__(self, debug=False):
|
78
|
+
self.debug = False
|
79
|
+
|
80
|
+
self.netcount = 0
|
81
|
+
self.segments = [RadixTreeNode(0)]
|
82
|
+
self.data_offsets = {}
|
83
|
+
self.data_segments = []
|
84
|
+
self.cur_offset = 1
|
85
|
+
|
86
|
+
def __setitem__(self, net, data):
|
87
|
+
self.netcount += 1
|
88
|
+
inet = int(net)
|
89
|
+
node = self.segments[0]
|
90
|
+
for depth in range(self.seek_depth, self.seek_depth - (net.prefixlen-1), -1):
|
91
|
+
if inet & (1 << depth):
|
92
|
+
if not node.rhs:
|
93
|
+
node.rhs = RadixTreeNode(len(self.segments))
|
94
|
+
self.segments.append(node.rhs)
|
95
|
+
node = node.rhs
|
96
|
+
else:
|
97
|
+
if not node.lhs:
|
98
|
+
node.lhs = RadixTreeNode(len(self.segments))
|
99
|
+
self.segments.append(node.lhs)
|
100
|
+
node = node.lhs
|
101
|
+
|
102
|
+
if not data in self.data_offsets:
|
103
|
+
self.data_offsets[data] = self.cur_offset
|
104
|
+
enc_data = self.encode(*data)
|
105
|
+
self.data_segments.append(enc_data)
|
106
|
+
self.cur_offset += (len(enc_data))
|
107
|
+
|
108
|
+
if self.debug:
|
109
|
+
#store net after data for easier debugging
|
110
|
+
data = data, net
|
111
|
+
|
112
|
+
if inet & (1 << self.seek_depth - (net.prefixlen-1)):
|
113
|
+
node.rhs = data
|
114
|
+
else:
|
115
|
+
node.lhs = data
|
116
|
+
|
117
|
+
def gen_nets(self, opts, args):
|
118
|
+
raise NotImplementedError
|
119
|
+
|
120
|
+
def load(self, opts, args):
|
121
|
+
for nets, data in self.gen_nets(opts, args):
|
122
|
+
for net in nets:
|
123
|
+
self[net] = data
|
124
|
+
|
125
|
+
def dump_node(self, node):
|
126
|
+
if not node:
|
127
|
+
#empty leaf
|
128
|
+
return '--'
|
129
|
+
elif isinstance(node, RadixTreeNode):
|
130
|
+
#internal node
|
131
|
+
return node.segment
|
132
|
+
else:
|
133
|
+
#data leaf
|
134
|
+
data = node[0] if self.debug else node
|
135
|
+
return '%d %s' % (len(self.segments) + self.data_offsets[data], node)
|
136
|
+
|
137
|
+
def dump(self):
|
138
|
+
for node in self.segments:
|
139
|
+
print node.segment, [self.dump_node(node.lhs), self.dump_node(node.rhs)]
|
140
|
+
|
141
|
+
def encode(self, *args):
|
142
|
+
raise NotImplementedError
|
143
|
+
|
144
|
+
def encode_rec(self, rec, reclen):
|
145
|
+
"""encode rec as 4-byte little-endian int, then truncate it to reclen"""
|
146
|
+
assert(reclen <= 4)
|
147
|
+
return struct.pack('<I', rec)[:reclen]
|
148
|
+
|
149
|
+
def serialize_node(self, node):
|
150
|
+
if not node:
|
151
|
+
#empty leaf
|
152
|
+
rec = len(self.segments)
|
153
|
+
elif isinstance(node, RadixTreeNode):
|
154
|
+
#internal node
|
155
|
+
rec = node.segment
|
156
|
+
else:
|
157
|
+
#data leaf
|
158
|
+
data = node[0] if self.debug else node
|
159
|
+
rec = len(self.segments) + self.data_offsets[data]
|
160
|
+
return self.encode_rec(rec, self.reclen)
|
161
|
+
|
162
|
+
def serialize(self, f):
|
163
|
+
if len(self.segments) >= 2 ** (8 * self.segreclen):
|
164
|
+
logging.warning('too many segments for final segment record size!')
|
165
|
+
|
166
|
+
for node in self.segments:
|
167
|
+
f.write(self.serialize_node(node.lhs))
|
168
|
+
f.write(self.serialize_node(node.rhs))
|
169
|
+
|
170
|
+
f.write(chr(42)) #So long, and thanks for all the fish!
|
171
|
+
f.write(''.join(self.data_segments))
|
172
|
+
|
173
|
+
f.write('bat.bast') #.dat file comment - can be anything
|
174
|
+
f.write(chr(0xFF) * 3)
|
175
|
+
f.write(chr(self.edition))
|
176
|
+
f.write(self.encode_rec(len(self.segments), self.segreclen))
|
177
|
+
|
178
|
+
class ORGIPRadixTree(RadixTree):
|
179
|
+
usage = '-w mmorg.dat mmorg_ip GeoIPORG.csv'
|
180
|
+
cmd = 'mmorg_ip'
|
181
|
+
seek_depth = 31
|
182
|
+
edition = 5
|
183
|
+
reclen = 4
|
184
|
+
segreclen = 4
|
185
|
+
|
186
|
+
def gen_nets(self, opts, args):
|
187
|
+
for lo, hi, org in gen_csv(fileinput.input(args)):
|
188
|
+
lo, hi = ipaddr.IPAddress(lo), ipaddr.IPAddress(hi)
|
189
|
+
nets = ipaddr.summarize_address_range(lo, hi)
|
190
|
+
#print 'lo %s - li %s - nets %s - org %s' % (lo, hi, nets, org)
|
191
|
+
yield nets, (org,)
|
192
|
+
|
193
|
+
def encode(self, data):
|
194
|
+
return data + '\0'
|
195
|
+
|
196
|
+
class ORGNetworkRadixTree(RadixTree):
|
197
|
+
usage = '-w mmorg.dat mmorg_net GeoIPORG.csv'
|
198
|
+
cmd = 'mmorg_net'
|
199
|
+
seek_depth = 31
|
200
|
+
edition = 5
|
201
|
+
reclen = 4
|
202
|
+
segreclen = 4
|
203
|
+
|
204
|
+
def gen_nets(self, opts, args):
|
205
|
+
for net, org in gen_csv(fileinput.input(args)):
|
206
|
+
net = [ipaddr.IPNetwork(net)]
|
207
|
+
yield net, (org,)
|
208
|
+
|
209
|
+
def encode(self, data):
|
210
|
+
return data + '\0'
|
211
|
+
|
212
|
+
def build_dat(RTree, opts, args):
|
213
|
+
tstart = time.time()
|
214
|
+
r = RTree(debug=opts.debug)
|
215
|
+
|
216
|
+
r.load(opts, args)
|
217
|
+
|
218
|
+
if opts.debug:
|
219
|
+
r.dump()
|
220
|
+
|
221
|
+
with open(opts.write_dat, 'wb') as f:
|
222
|
+
r.serialize(f)
|
223
|
+
|
224
|
+
tstop = time.time()
|
225
|
+
print 'wrote %d-node trie with %d networks (%d distinct labels) in %d seconds' % (
|
226
|
+
len(r.segments), r.netcount, len(r.data_offsets), tstop - tstart)
|
227
|
+
|
228
|
+
|
229
|
+
rtrees = [ORGIPRadixTree, ORGNetworkRadixTree]
|
230
|
+
cmds = dict((rtree.cmd, (partial(build_dat, rtree), rtree.usage)) for rtree in rtrees)
|
231
|
+
|
232
|
+
def main(argv=None):
|
233
|
+
global opts
|
234
|
+
opts, args = parse_args(argv)
|
235
|
+
init_logger(opts)
|
236
|
+
logging.debug(opts)
|
237
|
+
logging.debug(args)
|
238
|
+
|
239
|
+
cmd = args.pop(0)
|
240
|
+
cmd, usage = cmds[cmd]
|
241
|
+
return cmd(opts, args)
|
242
|
+
|
243
|
+
if __name__ == '__main__':
|
244
|
+
rval = main()
|
245
|
+
logging.shutdown()
|
246
|
+
sys.exit(rval)
|
Binary file
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geoip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
5
|
-
prerelease:
|
4
|
+
version: 1.3.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Clifford Heath
|
@@ -10,7 +9,7 @@ authors:
|
|
10
9
|
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date: 2013-
|
12
|
+
date: 2013-12-16 00:00:00.000000000 Z
|
14
13
|
dependencies: []
|
15
14
|
description: ! 'GeoIP searches a GeoIP database for a given host or IP address, and
|
16
15
|
|
@@ -32,7 +31,6 @@ files:
|
|
32
31
|
- README.rdoc
|
33
32
|
- Rakefile
|
34
33
|
- bin/geoip
|
35
|
-
- config/website.yml
|
36
34
|
- data/geoip/country_code.yml
|
37
35
|
- data/geoip/country_code3.yml
|
38
36
|
- data/geoip/country_continent.yml
|
@@ -41,39 +39,34 @@ files:
|
|
41
39
|
- data/geoip/time_zone.yml
|
42
40
|
- geoip.gemspec
|
43
41
|
- lib/geoip.rb
|
44
|
-
-
|
45
|
-
-
|
46
|
-
-
|
42
|
+
- test/csvORG2dat.py
|
43
|
+
- test/organizations.csv
|
44
|
+
- test/organizations.dat
|
47
45
|
- test/test_geoip.rb
|
48
46
|
- test/test_helper.rb
|
49
|
-
- website/index.txt
|
50
|
-
- website/javascripts/rounded_corners_lite.inc.js
|
51
|
-
- website/stylesheets/screen.css
|
52
|
-
- website/template.rhtml
|
53
47
|
homepage: http://github.com/cjheath/geoip
|
54
48
|
licenses:
|
55
49
|
- LGPL
|
50
|
+
metadata: {}
|
56
51
|
post_install_message:
|
57
52
|
rdoc_options: []
|
58
53
|
require_paths:
|
59
54
|
- lib
|
60
55
|
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
-
none: false
|
62
56
|
requirements:
|
63
57
|
- - ! '>='
|
64
58
|
- !ruby/object:Gem::Version
|
65
59
|
version: '0'
|
66
60
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
-
none: false
|
68
61
|
requirements:
|
69
62
|
- - ! '>='
|
70
63
|
- !ruby/object:Gem::Version
|
71
64
|
version: '0'
|
72
65
|
requirements: []
|
73
66
|
rubyforge_project:
|
74
|
-
rubygems_version: 1.
|
67
|
+
rubygems_version: 2.1.10
|
75
68
|
signing_key:
|
76
|
-
specification_version:
|
69
|
+
specification_version: 4
|
77
70
|
summary: GeoIP searches a GeoIP database for a given host or IP address, and returns
|
78
71
|
information about the country where the IP address is allocated, and the city, ISP
|
79
72
|
and other information, if you have that database version.
|
data/config/website.yml
DELETED
data/script/destroy
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
-
|
4
|
-
begin
|
5
|
-
require 'rubigen'
|
6
|
-
rescue LoadError
|
7
|
-
require 'rubygems'
|
8
|
-
require 'rubigen'
|
9
|
-
end
|
10
|
-
require 'rubigen/scripts/destroy'
|
11
|
-
|
12
|
-
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
-
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
-
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
-
|
4
|
-
begin
|
5
|
-
require 'rubigen'
|
6
|
-
rescue LoadError
|
7
|
-
require 'rubygems'
|
8
|
-
require 'rubigen'
|
9
|
-
end
|
10
|
-
require 'rubigen/scripts/generate'
|
11
|
-
|
12
|
-
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
-
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
-
RubiGen::Scripts::Generate.new.run(ARGV)
|
data/script/txt2html
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'redcloth'
|
5
|
-
require 'erb'
|
6
|
-
require './' + File.dirname(__FILE__) + '/../lib/geoip.rb'
|
7
|
-
|
8
|
-
version = GeoIP::VERSION
|
9
|
-
download = 'http://rubyforge.org/projects/geoip'
|
10
|
-
|
11
|
-
class Fixnum
|
12
|
-
def ordinal
|
13
|
-
# teens
|
14
|
-
return 'th' if (10..19).include?(self % 100)
|
15
|
-
# others
|
16
|
-
case self % 10
|
17
|
-
when 1; return 'st'
|
18
|
-
when 2; return 'nd'
|
19
|
-
when 3; return 'rd'
|
20
|
-
else return 'th'
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
class Time
|
26
|
-
def pretty
|
27
|
-
return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def convert_syntax(syntax, source)
|
32
|
-
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
33
|
-
end
|
34
|
-
|
35
|
-
if ARGV.length >= 1
|
36
|
-
src, template = ARGV
|
37
|
-
template ||= File.join(File.dirname(__FILE__), '/../website/template.rhtml')
|
38
|
-
|
39
|
-
else
|
40
|
-
puts("Usage: #{File.split($0).last} source.txt [template.rhtml] > output.html")
|
41
|
-
exit!
|
42
|
-
end
|
43
|
-
|
44
|
-
template = ERB.new(File.open(template).read)
|
45
|
-
|
46
|
-
title = nil
|
47
|
-
body = nil
|
48
|
-
File.open(src) do |fsrc|
|
49
|
-
title_text = fsrc.readline
|
50
|
-
body_text = fsrc.read
|
51
|
-
syntax_items = []
|
52
|
-
body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
|
53
|
-
ident = syntax_items.length
|
54
|
-
element, syntax, source = $1, $2, $3
|
55
|
-
syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
|
56
|
-
"syntax-temp-#{ident}"
|
57
|
-
}
|
58
|
-
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
59
|
-
body = RedCloth.new(body_text).to_html
|
60
|
-
body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
|
61
|
-
end
|
62
|
-
stat = File.stat(src)
|
63
|
-
created = stat.ctime
|
64
|
-
modified = stat.mtime
|
65
|
-
|
66
|
-
$stdout << template.result(binding)
|
data/website/index.txt
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
h1. geoip
|
2
|
-
|
3
|
-
h2. 'Geographic info for an IP address'
|
4
|
-
|
5
|
-
h2. What
|
6
|
-
|
7
|
-
GeoIP searches a GeoIP database from http://maxmind.com for a given host or IP address,
|
8
|
-
and returns information about the country, city and/or ISP for that IP address,
|
9
|
-
depending on the database version.
|
10
|
-
|
11
|
-
h2. Installing
|
12
|
-
|
13
|
-
<pre>sudo gem install geoip</pre>
|
14
|
-
|
15
|
-
h2. Locations
|
16
|
-
|
17
|
-
"http://github.com/cjheath/geoip":http://github.com/cjheath/geoip
|
18
|
-
<br>
|
19
|
-
"http://geoip.rubyforge.org/":http://geoip.rubyforge.org/
|
20
|
-
|
21
|
-
h2. Prerequisites
|
22
|
-
|
23
|
-
You need one of the free GeoLite country, city or ASN databases, or a subscription database version.
|
24
|
-
The last known download locations for the GeoLite database versions are
|
25
|
-
"http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz":http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
|
26
|
-
"http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz":http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
|
27
|
-
"http://geolite.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz":http://geolite.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz
|
28
|
-
|
29
|
-
This API requires the database to be decompressed for searching.
|
30
|
-
|
31
|
-
h2. Example
|
32
|
-
|
33
|
-
<pre>
|
34
|
-
require 'geoip'
|
35
|
-
c = GeoIP.new('GeoIP.dat').country('www.nokia.com')
|
36
|
-
=> ["www.nokia.com", "147.243.3.83", 69, "FI", "FIN", "Finland", "EU"]
|
37
|
-
c.country_code3
|
38
|
-
=> "FIN"
|
39
|
-
c.to_hash
|
40
|
-
=> {:country_code3=>"FIN", :country_name=>"Finland", :continent_code=>"EU",
|
41
|
-
:request=>"www.nokia.com", :country_code=>69, :country_code2=>"FI", :ip=>"147.243.3.83"}
|
42
|
-
<br>
|
43
|
-
c = GeoIP.new('GeoLiteCity.dat').city('github.com')
|
44
|
-
=> ["github.com", "207.97.227.239", "US", "USA", "United States", "NA", "CA",
|
45
|
-
"San Francisco", "94110", 37.7484, -122.4156, 807, 415, "America/Los_Angeles"]
|
46
|
-
>> c.longitude
|
47
|
-
=> -122.4156
|
48
|
-
>> c.timezone
|
49
|
-
=> "America/Los_Angeles"
|
50
|
-
<br>
|
51
|
-
c = GeoIP.new('GeoIPASNum.dat').asn("www.fsb.ru")
|
52
|
-
=> ["AS8342", "RTComm.RU Autonomous System"]
|
53
|
-
</pre>
|
54
|
-
|
55
|
-
h2. Source Repository
|
56
|
-
|
57
|
-
The trunk repository is <code>http://github.com/cjheath/geoip</code>
|
58
|
-
|
59
|
-
h2. License
|
60
|
-
|
61
|
-
I don't normally use the GPL license, but this one is derived
|
62
|
-
from Maxmind's code, so I use the license they use.
|
63
|
-
|
64
|
-
This version Copyright (C) 2005 Clifford Heath
|
65
|
-
Derived from the C version, Copyright (C) 2003 MaxMind LLC
|
66
|
-
|
67
|
-
This library is free software; you can redistribute it and/or
|
68
|
-
modify it under the terms of the GNU Lesser General Public
|
69
|
-
License as published by the Free Software Foundation; either
|
70
|
-
version 2.1 of the License, or (at your option) any later version.
|
71
|
-
|
72
|
-
This library is distributed in the hope that it will be useful,
|
73
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
74
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
75
|
-
Lesser General Public License for more details.
|
76
|
-
|
77
|
-
You should have received a copy of the GNU Lesser General Public
|
78
|
-
License along with this library; if not, write to the Free Software
|
79
|
-
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
@@ -1,285 +0,0 @@
|
|
1
|
-
|
2
|
-
/****************************************************************
|
3
|
-
* *
|
4
|
-
* curvyCorners *
|
5
|
-
* ------------ *
|
6
|
-
* *
|
7
|
-
* This script generates rounded corners for your divs. *
|
8
|
-
* *
|
9
|
-
* Version 1.2.9 *
|
10
|
-
* Copyright (c) 2006 Cameron Cooke *
|
11
|
-
* By: Cameron Cooke and Tim Hutchison. *
|
12
|
-
* *
|
13
|
-
* *
|
14
|
-
* Website: http://www.curvycorners.net *
|
15
|
-
* Email: info@totalinfinity.com *
|
16
|
-
* Forum: http://www.curvycorners.net/forum/ *
|
17
|
-
* *
|
18
|
-
* *
|
19
|
-
* This library is free software; you can redistribute *
|
20
|
-
* it and/or modify it under the terms of the GNU *
|
21
|
-
* Lesser General Public License as published by the *
|
22
|
-
* Free Software Foundation; either version 2.1 of the *
|
23
|
-
* License, or (at your option) any later version. *
|
24
|
-
* *
|
25
|
-
* This library is distributed in the hope that it will *
|
26
|
-
* be useful, but WITHOUT ANY WARRANTY; without even the *
|
27
|
-
* implied warranty of MERCHANTABILITY or FITNESS FOR A *
|
28
|
-
* PARTICULAR PURPOSE. See the GNU Lesser General Public *
|
29
|
-
* License for more details. *
|
30
|
-
* *
|
31
|
-
* You should have received a copy of the GNU Lesser *
|
32
|
-
* General Public License along with this library; *
|
33
|
-
* Inc., 59 Temple Place, Suite 330, Boston, *
|
34
|
-
* MA 02111-1307 USA *
|
35
|
-
* *
|
36
|
-
****************************************************************/
|
37
|
-
|
38
|
-
var isIE = navigator.userAgent.toLowerCase().indexOf("msie") > -1; var isMoz = document.implementation && document.implementation.createDocument; var isSafari = ((navigator.userAgent.toLowerCase().indexOf('safari')!=-1)&&(navigator.userAgent.toLowerCase().indexOf('mac')!=-1))?true:false; function curvyCorners()
|
39
|
-
{ if(typeof(arguments[0]) != "object") throw newCurvyError("First parameter of curvyCorners() must be an object."); if(typeof(arguments[1]) != "object" && typeof(arguments[1]) != "string") throw newCurvyError("Second parameter of curvyCorners() must be an object or a class name."); if(typeof(arguments[1]) == "string")
|
40
|
-
{ var startIndex = 0; var boxCol = getElementsByClass(arguments[1]);}
|
41
|
-
else
|
42
|
-
{ var startIndex = 1; var boxCol = arguments;}
|
43
|
-
var curvyCornersCol = new Array(); if(arguments[0].validTags)
|
44
|
-
var validElements = arguments[0].validTags; else
|
45
|
-
var validElements = ["div"]; for(var i = startIndex, j = boxCol.length; i < j; i++)
|
46
|
-
{ var currentTag = boxCol[i].tagName.toLowerCase(); if(inArray(validElements, currentTag) !== false)
|
47
|
-
{ curvyCornersCol[curvyCornersCol.length] = new curvyObject(arguments[0], boxCol[i]);}
|
48
|
-
}
|
49
|
-
this.objects = curvyCornersCol; this.applyCornersToAll = function()
|
50
|
-
{ for(var x = 0, k = this.objects.length; x < k; x++)
|
51
|
-
{ this.objects[x].applyCorners();}
|
52
|
-
}
|
53
|
-
}
|
54
|
-
function curvyObject()
|
55
|
-
{ this.box = arguments[1]; this.settings = arguments[0]; this.topContainer = null; this.bottomContainer = null; this.masterCorners = new Array(); this.contentDIV = null; var boxHeight = get_style(this.box, "height", "height"); var boxWidth = get_style(this.box, "width", "width"); var borderWidth = get_style(this.box, "borderTopWidth", "border-top-width"); var borderColour = get_style(this.box, "borderTopColor", "border-top-color"); var boxColour = get_style(this.box, "backgroundColor", "background-color"); var backgroundImage = get_style(this.box, "backgroundImage", "background-image"); var boxPosition = get_style(this.box, "position", "position"); var boxPadding = get_style(this.box, "paddingTop", "padding-top"); this.boxHeight = parseInt(((boxHeight != "" && boxHeight != "auto" && boxHeight.indexOf("%") == -1)? boxHeight.substring(0, boxHeight.indexOf("px")) : this.box.scrollHeight)); this.boxWidth = parseInt(((boxWidth != "" && boxWidth != "auto" && boxWidth.indexOf("%") == -1)? boxWidth.substring(0, boxWidth.indexOf("px")) : this.box.scrollWidth)); this.borderWidth = parseInt(((borderWidth != "" && borderWidth.indexOf("px") !== -1)? borderWidth.slice(0, borderWidth.indexOf("px")) : 0)); this.boxColour = format_colour(boxColour); this.boxPadding = parseInt(((boxPadding != "" && boxPadding.indexOf("px") !== -1)? boxPadding.slice(0, boxPadding.indexOf("px")) : 0)); this.borderColour = format_colour(borderColour); this.borderString = this.borderWidth + "px" + " solid " + this.borderColour; this.backgroundImage = ((backgroundImage != "none")? backgroundImage : ""); this.boxContent = this.box.innerHTML; if(boxPosition != "absolute") this.box.style.position = "relative"; this.box.style.padding = "0px"; if(isIE && boxWidth == "auto" && boxHeight == "auto") this.box.style.width = "100%"; if(this.settings.autoPad == true && this.boxPadding > 0)
|
56
|
-
this.box.innerHTML = ""; this.applyCorners = function()
|
57
|
-
{ for(var t = 0; t < 2; t++)
|
58
|
-
{ switch(t)
|
59
|
-
{ case 0:
|
60
|
-
if(this.settings.tl || this.settings.tr)
|
61
|
-
{ var newMainContainer = document.createElement("DIV"); newMainContainer.style.width = "100%"; newMainContainer.style.fontSize = "1px"; newMainContainer.style.overflow = "hidden"; newMainContainer.style.position = "absolute"; newMainContainer.style.paddingLeft = this.borderWidth + "px"; newMainContainer.style.paddingRight = this.borderWidth + "px"; var topMaxRadius = Math.max(this.settings.tl ? this.settings.tl.radius : 0, this.settings.tr ? this.settings.tr.radius : 0); newMainContainer.style.height = topMaxRadius + "px"; newMainContainer.style.top = 0 - topMaxRadius + "px"; newMainContainer.style.left = 0 - this.borderWidth + "px"; this.topContainer = this.box.appendChild(newMainContainer);}
|
62
|
-
break; case 1:
|
63
|
-
if(this.settings.bl || this.settings.br)
|
64
|
-
{ var newMainContainer = document.createElement("DIV"); newMainContainer.style.width = "100%"; newMainContainer.style.fontSize = "1px"; newMainContainer.style.overflow = "hidden"; newMainContainer.style.position = "absolute"; newMainContainer.style.paddingLeft = this.borderWidth + "px"; newMainContainer.style.paddingRight = this.borderWidth + "px"; var botMaxRadius = Math.max(this.settings.bl ? this.settings.bl.radius : 0, this.settings.br ? this.settings.br.radius : 0); newMainContainer.style.height = botMaxRadius + "px"; newMainContainer.style.bottom = 0 - botMaxRadius + "px"; newMainContainer.style.left = 0 - this.borderWidth + "px"; this.bottomContainer = this.box.appendChild(newMainContainer);}
|
65
|
-
break;}
|
66
|
-
}
|
67
|
-
if(this.topContainer) this.box.style.borderTopWidth = "0px"; if(this.bottomContainer) this.box.style.borderBottomWidth = "0px"; var corners = ["tr", "tl", "br", "bl"]; for(var i in corners)
|
68
|
-
{ if(i > -1 < 4)
|
69
|
-
{ var cc = corners[i]; if(!this.settings[cc])
|
70
|
-
{ if(((cc == "tr" || cc == "tl") && this.topContainer != null) || ((cc == "br" || cc == "bl") && this.bottomContainer != null))
|
71
|
-
{ var newCorner = document.createElement("DIV"); newCorner.style.position = "relative"; newCorner.style.fontSize = "1px"; newCorner.style.overflow = "hidden"; if(this.backgroundImage == "")
|
72
|
-
newCorner.style.backgroundColor = this.boxColour; else
|
73
|
-
newCorner.style.backgroundImage = this.backgroundImage; switch(cc)
|
74
|
-
{ case "tl":
|
75
|
-
newCorner.style.height = topMaxRadius - this.borderWidth + "px"; newCorner.style.marginRight = this.settings.tr.radius - (this.borderWidth*2) + "px"; newCorner.style.borderLeft = this.borderString; newCorner.style.borderTop = this.borderString; newCorner.style.left = -this.borderWidth + "px"; break; case "tr":
|
76
|
-
newCorner.style.height = topMaxRadius - this.borderWidth + "px"; newCorner.style.marginLeft = this.settings.tl.radius - (this.borderWidth*2) + "px"; newCorner.style.borderRight = this.borderString; newCorner.style.borderTop = this.borderString; newCorner.style.backgroundPosition = "-" + (topMaxRadius + this.borderWidth) + "px 0px"; newCorner.style.left = this.borderWidth + "px"; break; case "bl":
|
77
|
-
newCorner.style.height = botMaxRadius - this.borderWidth + "px"; newCorner.style.marginRight = this.settings.br.radius - (this.borderWidth*2) + "px"; newCorner.style.borderLeft = this.borderString; newCorner.style.borderBottom = this.borderString; newCorner.style.left = -this.borderWidth + "px"; newCorner.style.backgroundPosition = "-" + (this.borderWidth) + "px -" + (this.boxHeight + (botMaxRadius + this.borderWidth)) + "px"; break; case "br":
|
78
|
-
newCorner.style.height = botMaxRadius - this.borderWidth + "px"; newCorner.style.marginLeft = this.settings.bl.radius - (this.borderWidth*2) + "px"; newCorner.style.borderRight = this.borderString; newCorner.style.borderBottom = this.borderString; newCorner.style.left = this.borderWidth + "px"
|
79
|
-
newCorner.style.backgroundPosition = "-" + (botMaxRadius + this.borderWidth) + "px -" + (this.boxHeight + (botMaxRadius + this.borderWidth)) + "px"; break;}
|
80
|
-
}
|
81
|
-
}
|
82
|
-
else
|
83
|
-
{ if(this.masterCorners[this.settings[cc].radius])
|
84
|
-
{ var newCorner = this.masterCorners[this.settings[cc].radius].cloneNode(true);}
|
85
|
-
else
|
86
|
-
{ var newCorner = document.createElement("DIV"); newCorner.style.height = this.settings[cc].radius + "px"; newCorner.style.width = this.settings[cc].radius + "px"; newCorner.style.position = "absolute"; newCorner.style.fontSize = "1px"; newCorner.style.overflow = "hidden"; var borderRadius = parseInt(this.settings[cc].radius - this.borderWidth); for(var intx = 0, j = this.settings[cc].radius; intx < j; intx++)
|
87
|
-
{ if((intx +1) >= borderRadius)
|
88
|
-
var y1 = -1; else
|
89
|
-
var y1 = (Math.floor(Math.sqrt(Math.pow(borderRadius, 2) - Math.pow((intx+1), 2))) - 1); if(borderRadius != j)
|
90
|
-
{ if((intx) >= borderRadius)
|
91
|
-
var y2 = -1; else
|
92
|
-
var y2 = Math.ceil(Math.sqrt(Math.pow(borderRadius,2) - Math.pow(intx, 2))); if((intx+1) >= j)
|
93
|
-
var y3 = -1; else
|
94
|
-
var y3 = (Math.floor(Math.sqrt(Math.pow(j ,2) - Math.pow((intx+1), 2))) - 1);}
|
95
|
-
if((intx) >= j)
|
96
|
-
var y4 = -1; else
|
97
|
-
var y4 = Math.ceil(Math.sqrt(Math.pow(j ,2) - Math.pow(intx, 2))); if(y1 > -1) this.drawPixel(intx, 0, this.boxColour, 100, (y1+1), newCorner, -1, this.settings[cc].radius); if(borderRadius != j)
|
98
|
-
{ for(var inty = (y1 + 1); inty < y2; inty++)
|
99
|
-
{ if(this.settings.antiAlias)
|
100
|
-
{ if(this.backgroundImage != "")
|
101
|
-
{ var borderFract = (pixelFraction(intx, inty, borderRadius) * 100); if(borderFract < 30)
|
102
|
-
{ this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, 0, this.settings[cc].radius);}
|
103
|
-
else
|
104
|
-
{ this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, -1, this.settings[cc].radius);}
|
105
|
-
}
|
106
|
-
else
|
107
|
-
{ var pixelcolour = BlendColour(this.boxColour, this.borderColour, pixelFraction(intx, inty, borderRadius)); this.drawPixel(intx, inty, pixelcolour, 100, 1, newCorner, 0, this.settings[cc].radius, cc);}
|
108
|
-
}
|
109
|
-
}
|
110
|
-
if(this.settings.antiAlias)
|
111
|
-
{ if(y3 >= y2)
|
112
|
-
{ if (y2 == -1) y2 = 0; this.drawPixel(intx, y2, this.borderColour, 100, (y3 - y2 + 1), newCorner, 0, 0);}
|
113
|
-
}
|
114
|
-
else
|
115
|
-
{ if(y3 >= y1)
|
116
|
-
{ this.drawPixel(intx, (y1 + 1), this.borderColour, 100, (y3 - y1), newCorner, 0, 0);}
|
117
|
-
}
|
118
|
-
var outsideColour = this.borderColour;}
|
119
|
-
else
|
120
|
-
{ var outsideColour = this.boxColour; var y3 = y1;}
|
121
|
-
if(this.settings.antiAlias)
|
122
|
-
{ for(var inty = (y3 + 1); inty < y4; inty++)
|
123
|
-
{ this.drawPixel(intx, inty, outsideColour, (pixelFraction(intx, inty , j) * 100), 1, newCorner, ((this.borderWidth > 0)? 0 : -1), this.settings[cc].radius);}
|
124
|
-
}
|
125
|
-
}
|
126
|
-
this.masterCorners[this.settings[cc].radius] = newCorner.cloneNode(true);}
|
127
|
-
if(cc != "br")
|
128
|
-
{ for(var t = 0, k = newCorner.childNodes.length; t < k; t++)
|
129
|
-
{ var pixelBar = newCorner.childNodes[t]; var pixelBarTop = parseInt(pixelBar.style.top.substring(0, pixelBar.style.top.indexOf("px"))); var pixelBarLeft = parseInt(pixelBar.style.left.substring(0, pixelBar.style.left.indexOf("px"))); var pixelBarHeight = parseInt(pixelBar.style.height.substring(0, pixelBar.style.height.indexOf("px"))); if(cc == "tl" || cc == "bl"){ pixelBar.style.left = this.settings[cc].radius -pixelBarLeft -1 + "px";}
|
130
|
-
if(cc == "tr" || cc == "tl"){ pixelBar.style.top = this.settings[cc].radius -pixelBarHeight -pixelBarTop + "px";}
|
131
|
-
switch(cc)
|
132
|
-
{ case "tr":
|
133
|
-
pixelBar.style.backgroundPosition = "-" + Math.abs((this.boxWidth - this.settings[cc].radius + this.borderWidth) + pixelBarLeft) + "px -" + Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + "px"; break; case "tl":
|
134
|
-
pixelBar.style.backgroundPosition = "-" + Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + "px -" + Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + "px"; break; case "bl":
|
135
|
-
pixelBar.style.backgroundPosition = "-" + Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + "px -" + Math.abs((this.boxHeight + this.settings[cc].radius + pixelBarTop) -this.borderWidth) + "px"; break;}
|
136
|
-
}
|
137
|
-
}
|
138
|
-
}
|
139
|
-
if(newCorner)
|
140
|
-
{ switch(cc)
|
141
|
-
{ case "tl":
|
142
|
-
if(newCorner.style.position == "absolute") newCorner.style.top = "0px"; if(newCorner.style.position == "absolute") newCorner.style.left = "0px"; if(this.topContainer) this.topContainer.appendChild(newCorner); break; case "tr":
|
143
|
-
if(newCorner.style.position == "absolute") newCorner.style.top = "0px"; if(newCorner.style.position == "absolute") newCorner.style.right = "0px"; if(this.topContainer) this.topContainer.appendChild(newCorner); break; case "bl":
|
144
|
-
if(newCorner.style.position == "absolute") newCorner.style.bottom = "0px"; if(newCorner.style.position == "absolute") newCorner.style.left = "0px"; if(this.bottomContainer) this.bottomContainer.appendChild(newCorner); break; case "br":
|
145
|
-
if(newCorner.style.position == "absolute") newCorner.style.bottom = "0px"; if(newCorner.style.position == "absolute") newCorner.style.right = "0px"; if(this.bottomContainer) this.bottomContainer.appendChild(newCorner); break;}
|
146
|
-
}
|
147
|
-
}
|
148
|
-
}
|
149
|
-
var radiusDiff = new Array(); radiusDiff["t"] = Math.abs(this.settings.tl.radius - this.settings.tr.radius)
|
150
|
-
radiusDiff["b"] = Math.abs(this.settings.bl.radius - this.settings.br.radius); for(z in radiusDiff)
|
151
|
-
{ if(z == "t" || z == "b")
|
152
|
-
{ if(radiusDiff[z])
|
153
|
-
{ var smallerCornerType = ((this.settings[z + "l"].radius < this.settings[z + "r"].radius)? z +"l" : z +"r"); var newFiller = document.createElement("DIV"); newFiller.style.height = radiusDiff[z] + "px"; newFiller.style.width = this.settings[smallerCornerType].radius+ "px"
|
154
|
-
newFiller.style.position = "absolute"; newFiller.style.fontSize = "1px"; newFiller.style.overflow = "hidden"; newFiller.style.backgroundColor = this.boxColour; switch(smallerCornerType)
|
155
|
-
{ case "tl":
|
156
|
-
newFiller.style.bottom = "0px"; newFiller.style.left = "0px"; newFiller.style.borderLeft = this.borderString; this.topContainer.appendChild(newFiller); break; case "tr":
|
157
|
-
newFiller.style.bottom = "0px"; newFiller.style.right = "0px"; newFiller.style.borderRight = this.borderString; this.topContainer.appendChild(newFiller); break; case "bl":
|
158
|
-
newFiller.style.top = "0px"; newFiller.style.left = "0px"; newFiller.style.borderLeft = this.borderString; this.bottomContainer.appendChild(newFiller); break; case "br":
|
159
|
-
newFiller.style.top = "0px"; newFiller.style.right = "0px"; newFiller.style.borderRight = this.borderString; this.bottomContainer.appendChild(newFiller); break;}
|
160
|
-
}
|
161
|
-
var newFillerBar = document.createElement("DIV"); newFillerBar.style.position = "relative"; newFillerBar.style.fontSize = "1px"; newFillerBar.style.overflow = "hidden"; newFillerBar.style.backgroundColor = this.boxColour; newFillerBar.style.backgroundImage = this.backgroundImage; switch(z)
|
162
|
-
{ case "t":
|
163
|
-
if(this.topContainer)
|
164
|
-
{ if(this.settings.tl.radius && this.settings.tr.radius)
|
165
|
-
{ newFillerBar.style.height = topMaxRadius - this.borderWidth + "px"; newFillerBar.style.marginLeft = this.settings.tl.radius - this.borderWidth + "px"; newFillerBar.style.marginRight = this.settings.tr.radius - this.borderWidth + "px"; newFillerBar.style.borderTop = this.borderString; if(this.backgroundImage != "")
|
166
|
-
newFillerBar.style.backgroundPosition = "-" + (topMaxRadius + this.borderWidth) + "px 0px"; this.topContainer.appendChild(newFillerBar);}
|
167
|
-
this.box.style.backgroundPosition = "0px -" + (topMaxRadius - this.borderWidth) + "px";}
|
168
|
-
break; case "b":
|
169
|
-
if(this.bottomContainer)
|
170
|
-
{ if(this.settings.bl.radius && this.settings.br.radius)
|
171
|
-
{ newFillerBar.style.height = botMaxRadius - this.borderWidth + "px"; newFillerBar.style.marginLeft = this.settings.bl.radius - this.borderWidth + "px"; newFillerBar.style.marginRight = this.settings.br.radius - this.borderWidth + "px"; newFillerBar.style.borderBottom = this.borderString; if(this.backgroundImage != "")
|
172
|
-
newFillerBar.style.backgroundPosition = "-" + (botMaxRadius + this.borderWidth) + "px -" + (this.boxHeight + (topMaxRadius + this.borderWidth)) + "px"; this.bottomContainer.appendChild(newFillerBar);}
|
173
|
-
}
|
174
|
-
break;}
|
175
|
-
}
|
176
|
-
}
|
177
|
-
if(this.settings.autoPad == true && this.boxPadding > 0)
|
178
|
-
{ var contentContainer = document.createElement("DIV"); contentContainer.style.position = "relative"; contentContainer.innerHTML = this.boxContent; contentContainer.className = "autoPadDiv"; var topPadding = Math.abs(topMaxRadius - this.boxPadding); var botPadding = Math.abs(botMaxRadius - this.boxPadding); if(topMaxRadius < this.boxPadding)
|
179
|
-
contentContainer.style.paddingTop = topPadding + "px"; if(botMaxRadius < this.boxPadding)
|
180
|
-
contentContainer.style.paddingBottom = botMaxRadius + "px"; contentContainer.style.paddingLeft = this.boxPadding + "px"; contentContainer.style.paddingRight = this.boxPadding + "px"; this.contentDIV = this.box.appendChild(contentContainer);}
|
181
|
-
}
|
182
|
-
this.drawPixel = function(intx, inty, colour, transAmount, height, newCorner, image, cornerRadius)
|
183
|
-
{ var pixel = document.createElement("DIV"); pixel.style.height = height + "px"; pixel.style.width = "1px"; pixel.style.position = "absolute"; pixel.style.fontSize = "1px"; pixel.style.overflow = "hidden"; var topMaxRadius = Math.max(this.settings["tr"].radius, this.settings["tl"].radius); if(image == -1 && this.backgroundImage != "")
|
184
|
-
{ pixel.style.backgroundImage = this.backgroundImage; pixel.style.backgroundPosition = "-" + (this.boxWidth - (cornerRadius - intx) + this.borderWidth) + "px -" + ((this.boxHeight + topMaxRadius + inty) -this.borderWidth) + "px";}
|
185
|
-
else
|
186
|
-
{ pixel.style.backgroundColor = colour;}
|
187
|
-
if (transAmount != 100)
|
188
|
-
setOpacity(pixel, transAmount); pixel.style.top = inty + "px"; pixel.style.left = intx + "px"; newCorner.appendChild(pixel);}
|
189
|
-
}
|
190
|
-
function insertAfter(parent, node, referenceNode)
|
191
|
-
{ parent.insertBefore(node, referenceNode.nextSibling);}
|
192
|
-
function BlendColour(Col1, Col2, Col1Fraction)
|
193
|
-
{ var red1 = parseInt(Col1.substr(1,2),16); var green1 = parseInt(Col1.substr(3,2),16); var blue1 = parseInt(Col1.substr(5,2),16); var red2 = parseInt(Col2.substr(1,2),16); var green2 = parseInt(Col2.substr(3,2),16); var blue2 = parseInt(Col2.substr(5,2),16); if(Col1Fraction > 1 || Col1Fraction < 0) Col1Fraction = 1; var endRed = Math.round((red1 * Col1Fraction) + (red2 * (1 - Col1Fraction))); if(endRed > 255) endRed = 255; if(endRed < 0) endRed = 0; var endGreen = Math.round((green1 * Col1Fraction) + (green2 * (1 - Col1Fraction))); if(endGreen > 255) endGreen = 255; if(endGreen < 0) endGreen = 0; var endBlue = Math.round((blue1 * Col1Fraction) + (blue2 * (1 - Col1Fraction))); if(endBlue > 255) endBlue = 255; if(endBlue < 0) endBlue = 0; return "#" + IntToHex(endRed)+ IntToHex(endGreen)+ IntToHex(endBlue);}
|
194
|
-
function IntToHex(strNum)
|
195
|
-
{ base = strNum / 16; rem = strNum % 16; base = base - (rem / 16); baseS = MakeHex(base); remS = MakeHex(rem); return baseS + '' + remS;}
|
196
|
-
function MakeHex(x)
|
197
|
-
{ if((x >= 0) && (x <= 9))
|
198
|
-
{ return x;}
|
199
|
-
else
|
200
|
-
{ switch(x)
|
201
|
-
{ case 10: return "A"; case 11: return "B"; case 12: return "C"; case 13: return "D"; case 14: return "E"; case 15: return "F";}
|
202
|
-
}
|
203
|
-
}
|
204
|
-
function pixelFraction(x, y, r)
|
205
|
-
{ var pixelfraction = 0; var xvalues = new Array(1); var yvalues = new Array(1); var point = 0; var whatsides = ""; var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x,2))); if ((intersect >= y) && (intersect < (y+1)))
|
206
|
-
{ whatsides = "Left"; xvalues[point] = 0; yvalues[point] = intersect - y; point = point + 1;}
|
207
|
-
var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y+1,2))); if ((intersect >= x) && (intersect < (x+1)))
|
208
|
-
{ whatsides = whatsides + "Top"; xvalues[point] = intersect - x; yvalues[point] = 1; point = point + 1;}
|
209
|
-
var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x+1,2))); if ((intersect >= y) && (intersect < (y+1)))
|
210
|
-
{ whatsides = whatsides + "Right"; xvalues[point] = 1; yvalues[point] = intersect - y; point = point + 1;}
|
211
|
-
var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y,2))); if ((intersect >= x) && (intersect < (x+1)))
|
212
|
-
{ whatsides = whatsides + "Bottom"; xvalues[point] = intersect - x; yvalues[point] = 0;}
|
213
|
-
switch (whatsides)
|
214
|
-
{ case "LeftRight":
|
215
|
-
pixelfraction = Math.min(yvalues[0],yvalues[1]) + ((Math.max(yvalues[0],yvalues[1]) - Math.min(yvalues[0],yvalues[1]))/2); break; case "TopRight":
|
216
|
-
pixelfraction = 1-(((1-xvalues[0])*(1-yvalues[1]))/2); break; case "TopBottom":
|
217
|
-
pixelfraction = Math.min(xvalues[0],xvalues[1]) + ((Math.max(xvalues[0],xvalues[1]) - Math.min(xvalues[0],xvalues[1]))/2); break; case "LeftBottom":
|
218
|
-
pixelfraction = (yvalues[0]*xvalues[1])/2; break; default:
|
219
|
-
pixelfraction = 1;}
|
220
|
-
return pixelfraction;}
|
221
|
-
function rgb2Hex(rgbColour)
|
222
|
-
{ try{ var rgbArray = rgb2Array(rgbColour); var red = parseInt(rgbArray[0]); var green = parseInt(rgbArray[1]); var blue = parseInt(rgbArray[2]); var hexColour = "#" + IntToHex(red) + IntToHex(green) + IntToHex(blue);}
|
223
|
-
catch(e){ alert("There was an error converting the RGB value to Hexadecimal in function rgb2Hex");}
|
224
|
-
return hexColour;}
|
225
|
-
function rgb2Array(rgbColour)
|
226
|
-
{ var rgbValues = rgbColour.substring(4, rgbColour.indexOf(")")); var rgbArray = rgbValues.split(", "); return rgbArray;}
|
227
|
-
function setOpacity(obj, opacity)
|
228
|
-
{ opacity = (opacity == 100)?99.999:opacity; if(isSafari && obj.tagName != "IFRAME")
|
229
|
-
{ var rgbArray = rgb2Array(obj.style.backgroundColor); var red = parseInt(rgbArray[0]); var green = parseInt(rgbArray[1]); var blue = parseInt(rgbArray[2]); obj.style.backgroundColor = "rgba(" + red + ", " + green + ", " + blue + ", " + opacity/100 + ")";}
|
230
|
-
else if(typeof(obj.style.opacity) != "undefined")
|
231
|
-
{ obj.style.opacity = opacity/100;}
|
232
|
-
else if(typeof(obj.style.MozOpacity) != "undefined")
|
233
|
-
{ obj.style.MozOpacity = opacity/100;}
|
234
|
-
else if(typeof(obj.style.filter) != "undefined")
|
235
|
-
{ obj.style.filter = "alpha(opacity:" + opacity + ")";}
|
236
|
-
else if(typeof(obj.style.KHTMLOpacity) != "undefined")
|
237
|
-
{ obj.style.KHTMLOpacity = opacity/100;}
|
238
|
-
}
|
239
|
-
function inArray(array, value)
|
240
|
-
{ for(var i = 0; i < array.length; i++){ if (array[i] === value) return i;}
|
241
|
-
return false;}
|
242
|
-
function inArrayKey(array, value)
|
243
|
-
{ for(key in array){ if(key === value) return true;}
|
244
|
-
return false;}
|
245
|
-
function addEvent(elm, evType, fn, useCapture) { if (elm.addEventListener) { elm.addEventListener(evType, fn, useCapture); return true;}
|
246
|
-
else if (elm.attachEvent) { var r = elm.attachEvent('on' + evType, fn); return r;}
|
247
|
-
else { elm['on' + evType] = fn;}
|
248
|
-
}
|
249
|
-
function removeEvent(obj, evType, fn, useCapture){ if (obj.removeEventListener){ obj.removeEventListener(evType, fn, useCapture); return true;} else if (obj.detachEvent){ var r = obj.detachEvent("on"+evType, fn); return r;} else { alert("Handler could not be removed");}
|
250
|
-
}
|
251
|
-
function format_colour(colour)
|
252
|
-
{ var returnColour = "#ffffff"; if(colour != "" && colour != "transparent")
|
253
|
-
{ if(colour.substr(0, 3) == "rgb")
|
254
|
-
{ returnColour = rgb2Hex(colour);}
|
255
|
-
else if(colour.length == 4)
|
256
|
-
{ returnColour = "#" + colour.substring(1, 2) + colour.substring(1, 2) + colour.substring(2, 3) + colour.substring(2, 3) + colour.substring(3, 4) + colour.substring(3, 4);}
|
257
|
-
else
|
258
|
-
{ returnColour = colour;}
|
259
|
-
}
|
260
|
-
return returnColour;}
|
261
|
-
function get_style(obj, property, propertyNS)
|
262
|
-
{ try
|
263
|
-
{ if(obj.currentStyle)
|
264
|
-
{ var returnVal = eval("obj.currentStyle." + property);}
|
265
|
-
else
|
266
|
-
{ if(isSafari && obj.style.display == "none")
|
267
|
-
{ obj.style.display = ""; var wasHidden = true;}
|
268
|
-
var returnVal = document.defaultView.getComputedStyle(obj, '').getPropertyValue(propertyNS); if(isSafari && wasHidden)
|
269
|
-
{ obj.style.display = "none";}
|
270
|
-
}
|
271
|
-
}
|
272
|
-
catch(e)
|
273
|
-
{ }
|
274
|
-
return returnVal;}
|
275
|
-
function getElementsByClass(searchClass, node, tag)
|
276
|
-
{ var classElements = new Array(); if(node == null)
|
277
|
-
node = document; if(tag == null)
|
278
|
-
tag = '*'; var els = node.getElementsByTagName(tag); var elsLen = els.length; var pattern = new RegExp("(^|\s)"+searchClass+"(\s|$)"); for (i = 0, j = 0; i < elsLen; i++)
|
279
|
-
{ if(pattern.test(els[i].className))
|
280
|
-
{ classElements[j] = els[i]; j++;}
|
281
|
-
}
|
282
|
-
return classElements;}
|
283
|
-
function newCurvyError(errorMessage)
|
284
|
-
{ return new Error("curvyCorners Error:\n" + errorMessage)
|
285
|
-
}
|
@@ -1,138 +0,0 @@
|
|
1
|
-
body {
|
2
|
-
background-color: #E1D1F1;
|
3
|
-
font-family: "Georgia", sans-serif;
|
4
|
-
font-size: 16px;
|
5
|
-
line-height: 1.6em;
|
6
|
-
padding: 1.6em 0 0 0;
|
7
|
-
color: #333;
|
8
|
-
}
|
9
|
-
h1, h2, h3, h4, h5, h6 {
|
10
|
-
color: #444;
|
11
|
-
}
|
12
|
-
h1 {
|
13
|
-
font-family: sans-serif;
|
14
|
-
font-weight: normal;
|
15
|
-
font-size: 4em;
|
16
|
-
line-height: 0.8em;
|
17
|
-
letter-spacing: -0.1ex;
|
18
|
-
margin: 5px;
|
19
|
-
}
|
20
|
-
li {
|
21
|
-
padding: 0;
|
22
|
-
margin: 0;
|
23
|
-
list-style-type: square;
|
24
|
-
}
|
25
|
-
a {
|
26
|
-
color: #5E5AFF;
|
27
|
-
background-color: #DAC;
|
28
|
-
font-weight: normal;
|
29
|
-
text-decoration: underline;
|
30
|
-
}
|
31
|
-
blockquote {
|
32
|
-
font-size: 90%;
|
33
|
-
font-style: italic;
|
34
|
-
border-left: 1px solid #111;
|
35
|
-
padding-left: 1em;
|
36
|
-
}
|
37
|
-
.caps {
|
38
|
-
font-size: 80%;
|
39
|
-
}
|
40
|
-
|
41
|
-
#main {
|
42
|
-
width: 45em;
|
43
|
-
padding: 0;
|
44
|
-
margin: 0 auto;
|
45
|
-
}
|
46
|
-
.coda {
|
47
|
-
text-align: right;
|
48
|
-
color: #77f;
|
49
|
-
font-size: smaller;
|
50
|
-
}
|
51
|
-
|
52
|
-
table {
|
53
|
-
font-size: 90%;
|
54
|
-
line-height: 1.4em;
|
55
|
-
color: #ff8;
|
56
|
-
background-color: #111;
|
57
|
-
padding: 2px 10px 2px 10px;
|
58
|
-
border-style: dashed;
|
59
|
-
}
|
60
|
-
|
61
|
-
th {
|
62
|
-
color: #fff;
|
63
|
-
}
|
64
|
-
|
65
|
-
td {
|
66
|
-
padding: 2px 10px 2px 10px;
|
67
|
-
}
|
68
|
-
|
69
|
-
.success {
|
70
|
-
color: #0CC52B;
|
71
|
-
}
|
72
|
-
|
73
|
-
.failed {
|
74
|
-
color: #E90A1B;
|
75
|
-
}
|
76
|
-
|
77
|
-
.unknown {
|
78
|
-
color: #995000;
|
79
|
-
}
|
80
|
-
pre, code {
|
81
|
-
font-family: monospace;
|
82
|
-
font-size: 90%;
|
83
|
-
line-height: 1.4em;
|
84
|
-
color: #ff8;
|
85
|
-
background-color: #111;
|
86
|
-
padding: 2px 10px 2px 10px;
|
87
|
-
}
|
88
|
-
.comment { color: #aaa; font-style: italic; }
|
89
|
-
.keyword { color: #eff; font-weight: bold; }
|
90
|
-
.punct { color: #eee; font-weight: bold; }
|
91
|
-
.symbol { color: #0bb; }
|
92
|
-
.string { color: #6b4; }
|
93
|
-
.ident { color: #ff8; }
|
94
|
-
.constant { color: #66f; }
|
95
|
-
.regex { color: #ec6; }
|
96
|
-
.number { color: #F99; }
|
97
|
-
.expr { color: #227; }
|
98
|
-
|
99
|
-
#version {
|
100
|
-
float: right;
|
101
|
-
text-align: right;
|
102
|
-
font-family: sans-serif;
|
103
|
-
font-weight: normal;
|
104
|
-
background-color: #B3ABFF;
|
105
|
-
color: #141331;
|
106
|
-
padding: 15px 20px 10px 20px;
|
107
|
-
margin: 0 auto;
|
108
|
-
margin-top: 15px;
|
109
|
-
border: 3px solid #141331;
|
110
|
-
}
|
111
|
-
|
112
|
-
#version .numbers {
|
113
|
-
display: block;
|
114
|
-
font-size: 4em;
|
115
|
-
line-height: 0.8em;
|
116
|
-
letter-spacing: -0.1ex;
|
117
|
-
margin-bottom: 15px;
|
118
|
-
}
|
119
|
-
|
120
|
-
#version p {
|
121
|
-
text-decoration: none;
|
122
|
-
color: #141331;
|
123
|
-
background-color: #B3ABFF;
|
124
|
-
margin: 0;
|
125
|
-
padding: 0;
|
126
|
-
}
|
127
|
-
|
128
|
-
#version a {
|
129
|
-
text-decoration: none;
|
130
|
-
color: #141331;
|
131
|
-
background-color: #B3ABFF;
|
132
|
-
}
|
133
|
-
|
134
|
-
.clickable {
|
135
|
-
cursor: pointer;
|
136
|
-
cursor: hand;
|
137
|
-
}
|
138
|
-
|
data/website/template.rhtml
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
-
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
-
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
-
<head>
|
5
|
-
<link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
|
6
|
-
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
7
|
-
<title>
|
8
|
-
<%= title %>
|
9
|
-
</title>
|
10
|
-
<script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
|
11
|
-
<style>
|
12
|
-
|
13
|
-
</style>
|
14
|
-
<script type="text/javascript">
|
15
|
-
window.onload = function() {
|
16
|
-
settings = {
|
17
|
-
tl: { radius: 10 },
|
18
|
-
tr: { radius: 10 },
|
19
|
-
bl: { radius: 10 },
|
20
|
-
br: { radius: 10 },
|
21
|
-
antiAlias: true,
|
22
|
-
autoPad: true,
|
23
|
-
validTags: ["div"]
|
24
|
-
}
|
25
|
-
var versionBox = new curvyCorners(settings, document.getElementById("version"));
|
26
|
-
versionBox.applyCornersToAll();
|
27
|
-
}
|
28
|
-
</script>
|
29
|
-
</head>
|
30
|
-
<body>
|
31
|
-
<div id="main">
|
32
|
-
|
33
|
-
<h1><%= title %></h1>
|
34
|
-
<div id="version" class="clickable" onclick='document.location = "<%= download %>"; return false'>
|
35
|
-
<p>Get Version</p>
|
36
|
-
<a href="<%= download %>" class="numbers"><%= version %></a>
|
37
|
-
</div>
|
38
|
-
<%= body %>
|
39
|
-
<p class="coda">
|
40
|
-
<a href="cjheath@rubyforge.org">Clifford Heath</a>, <%= modified.pretty %><br>
|
41
|
-
Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
|
42
|
-
</p>
|
43
|
-
</div>
|
44
|
-
|
45
|
-
<!-- insert site tracking codes here, like Google Urchin -->
|
46
|
-
|
47
|
-
</body>
|
48
|
-
</html>
|