conformist 0.0.1
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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.markdown +126 -0
- data/Rakefile +23 -0
- data/conformist.gemspec +27 -0
- data/lib/conformist.rb +26 -0
- data/lib/conformist/base.rb +49 -0
- data/lib/conformist/column.rb +30 -0
- data/lib/conformist/row.rb +26 -0
- data/lib/conformist/version.rb +3 -0
- data/test/conformist/base_test.rb +39 -0
- data/test/conformist/column_test.rb +43 -0
- data/test/conformist/conformist_test.rb +21 -0
- data/test/conformist/row_test.rb +21 -0
- data/test/definitions/acma.rb +16 -0
- data/test/definitions/fcc.rb +15 -0
- data/test/fixtures/acma.csv +5 -0
- data/test/fixtures/fcc.txt +5 -0
- data/test/helper.rb +13 -0
- metadata +97 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2011 Tate Johnson <tate@tatey.com>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
# Conformist
|
2
|
+
|
3
|
+
Conformist lets you bend CSVs to your will. Let multiple, different input files conform to a single interface without rewriting your parser each time.
|
4
|
+
|
5
|
+
Motivation for this project came from the desire to simplify importing data from various government organisations into [Antenna Mate](http://antennamate.com). The data from each government was similar, but had completely different formatting. Some pieces of data needed preprocessing while others simply needed to be concatenated together. I did not want to write a new parser for each new government organisation. Instead, I created Conformist.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Conformist is available from rubygems.org.
|
10
|
+
|
11
|
+
``` sh
|
12
|
+
$ gem install conformist
|
13
|
+
```
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
You create a Ruby class, mix-in `Conformist::Base` and declare how an input file should map to a single interface.
|
18
|
+
|
19
|
+
``` ruby
|
20
|
+
require 'conformist'
|
21
|
+
|
22
|
+
class Citizen1
|
23
|
+
include Conformist::Base
|
24
|
+
|
25
|
+
column :name, 0, 1
|
26
|
+
column :address, 2 do |value|
|
27
|
+
value.upcase
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Citizen2
|
32
|
+
include Conformist::Base
|
33
|
+
|
34
|
+
column :name, 0
|
35
|
+
column :address, 1
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
Load up your definitions and enumerate over each row in the input file.
|
40
|
+
|
41
|
+
``` ruby
|
42
|
+
Conformist.foreach Citizen1.load('citizens1.csv'), Citizen2.load('citizens2.csv') do |row|
|
43
|
+
Citizen.create! row
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
Each object passed into the block will be a hash. Perfect for passing to a model to save into a datastore (Or whatever tickles your fancy).
|
48
|
+
|
49
|
+
### Option
|
50
|
+
|
51
|
+
Conformist uses CSV (Formally FasterCSV) to perform the heavy lifting. You can declare options that should be passed to CSV at runtime. It is safe to call `option` multiple times.
|
52
|
+
|
53
|
+
``` ruby
|
54
|
+
option :col_sep => ','
|
55
|
+
option :quote_char => '"'
|
56
|
+
```
|
57
|
+
|
58
|
+
### One Column
|
59
|
+
|
60
|
+
Maps the first column in the input file to the `:first_name` key-value pair. Indexing starts at zero.
|
61
|
+
|
62
|
+
``` ruby
|
63
|
+
column :first_name, 0
|
64
|
+
```
|
65
|
+
|
66
|
+
### Many Columns
|
67
|
+
|
68
|
+
Maps the first and second columns in the input file to the `:name` key-value pair and implicitly concatenates the values.
|
69
|
+
|
70
|
+
``` ruby
|
71
|
+
column :name, 0, 1
|
72
|
+
```
|
73
|
+
|
74
|
+
Indexing is completely arbitrary and you can map any combination.
|
75
|
+
|
76
|
+
``` ruby
|
77
|
+
column :name_and_address, 0, 2
|
78
|
+
```
|
79
|
+
|
80
|
+
### Preprocessing
|
81
|
+
|
82
|
+
Sometimes you will want to manipulate values before they're conformed. You can pass a block and get access to the values. The return value of the expression becomes the conformed output.
|
83
|
+
|
84
|
+
``` ruby
|
85
|
+
column :name, 0, 1 do |values|
|
86
|
+
values.map { |v| v.upcase } * ' '
|
87
|
+
end
|
88
|
+
```
|
89
|
+
|
90
|
+
Works with one column too. Instead of getting an array of strings, you get one string.
|
91
|
+
|
92
|
+
``` ruby
|
93
|
+
column :first_name, 0 do |value|
|
94
|
+
value.upcase
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
98
|
+
### Virtual Columns
|
99
|
+
|
100
|
+
Declare a column you want included in the conformed output that is not based on the input file. This is useful when you need to set values based on the conformist definition.
|
101
|
+
|
102
|
+
``` ruby
|
103
|
+
column :day do
|
104
|
+
1
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
## Compatibility
|
109
|
+
|
110
|
+
* 1.9.2-p180
|
111
|
+
* 1.8.7-p334
|
112
|
+
* jruby-1.6.1
|
113
|
+
|
114
|
+
## Contributing
|
115
|
+
|
116
|
+
Patches welcome!
|
117
|
+
|
118
|
+
1. Fork the repository
|
119
|
+
2. Create a topic branch
|
120
|
+
3. Write tests and make changes
|
121
|
+
4. Make sure the tests pass by running `rake`
|
122
|
+
5. Push and send a pull request on GitHub
|
123
|
+
|
124
|
+
## Copyright
|
125
|
+
|
126
|
+
Copyright © 2011 Tate Johnson. Conformist is released under the MIT license. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
begin
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler'
|
4
|
+
rescue LoadError
|
5
|
+
raise 'Could not load the bundler gem. Install it with `gem install bundler`.'
|
6
|
+
end
|
7
|
+
|
8
|
+
begin
|
9
|
+
Bundler.setup
|
10
|
+
rescue Bundler::GemNotFound
|
11
|
+
raise RuntimeError, "Bundler couldn't find some gems." +
|
12
|
+
"Did you run `bundle install`?"
|
13
|
+
end
|
14
|
+
|
15
|
+
Bundler::GemHelper.install_tasks
|
16
|
+
|
17
|
+
require 'rake/testtask'
|
18
|
+
Rake::TestTask.new(:test) do |test|
|
19
|
+
test.libs << 'test'
|
20
|
+
test.pattern = 'test/**/*_test.rb'
|
21
|
+
end
|
22
|
+
|
23
|
+
task :default => :test
|
data/conformist.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "conformist/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "conformist"
|
7
|
+
s.version = Conformist::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Tate Johnson"]
|
10
|
+
s.email = ["tate@tatey.com"]
|
11
|
+
s.homepage = "https://github.com/tatey/conformist"
|
12
|
+
s.summary = %q{Let multiple, different input files conform to a single interface.}
|
13
|
+
s.description = %q{Conformist lets you bend CSVs to your will. Let multiple, different input files conform to a single interface without rewriting your parser each time.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "conformist"
|
16
|
+
|
17
|
+
s.required_ruby_version = '>= 1.8.7'
|
18
|
+
|
19
|
+
s.add_development_dependency 'rake', '~> 0.8.7'
|
20
|
+
s.add_development_dependency 'minitest', '~> 2.1.0' if RUBY_VERSION < '1.9.0'
|
21
|
+
s.add_dependency 'fastercsv', "~> 1.5.4" if RUBY_VERSION < '1.9.0'
|
22
|
+
|
23
|
+
s.files = `git ls-files`.split("\n")
|
24
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
25
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
26
|
+
s.require_paths = ["lib"]
|
27
|
+
end
|
data/lib/conformist.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
if RUBY_VERSION >= '1.9.0'
|
2
|
+
require 'csv'
|
3
|
+
else
|
4
|
+
require 'fastercsv'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'conformist/base'
|
8
|
+
require 'conformist/column'
|
9
|
+
require 'conformist/row'
|
10
|
+
|
11
|
+
module Conformist
|
12
|
+
CSV = RUBY_VERSION >= '1.9.0' ? ::CSV : FasterCSV
|
13
|
+
|
14
|
+
# Enumerate over each row from multiple input files.
|
15
|
+
#
|
16
|
+
# Example:
|
17
|
+
#
|
18
|
+
# Conformist::Base.foreach Input1.load('input.csv'), Input2.load('input.csv') do |row|
|
19
|
+
# Model.create! row
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# Returns nothing.
|
23
|
+
def self.foreach *bases, &block
|
24
|
+
bases.each { |base| base.foreach(&block) }
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Conformist
|
2
|
+
module Base
|
3
|
+
def self.included base
|
4
|
+
base.class_eval do
|
5
|
+
extend ClassMethods
|
6
|
+
|
7
|
+
attr_accessor :path
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# Enumerate over each row in the input file.
|
12
|
+
#
|
13
|
+
# Example:
|
14
|
+
#
|
15
|
+
# input1 = Input1.load 'input1.csv'
|
16
|
+
# input1.foreach do |row|
|
17
|
+
# Model.create! row
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# Returns nothing.
|
21
|
+
def foreach &block
|
22
|
+
CSV.foreach(path, self.class.options) do |row|
|
23
|
+
yield Row.new(self.class.columns, row).to_hash
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
def column name, *indexes, &preprocessor
|
29
|
+
columns << Column.new(name, *indexes, &preprocessor)
|
30
|
+
end
|
31
|
+
|
32
|
+
def columns
|
33
|
+
@columns ||= []
|
34
|
+
end
|
35
|
+
|
36
|
+
def option value
|
37
|
+
options.merge! value
|
38
|
+
end
|
39
|
+
|
40
|
+
def options
|
41
|
+
@options ||= {}
|
42
|
+
end
|
43
|
+
|
44
|
+
def load path
|
45
|
+
new.tap { |object| object.path = path }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Conformist
|
2
|
+
class Column
|
3
|
+
attr_reader :name, :indexes, :preprocessor
|
4
|
+
|
5
|
+
def initialize name, *indexes, &preprocessor
|
6
|
+
@name, @indexes, @preprocessor = name, indexes, preprocessor
|
7
|
+
end
|
8
|
+
|
9
|
+
# Map column(s) into a single value, strips whitespace and performs
|
10
|
+
# any preprocessing. Takes a +row+ argument that should behave as an
|
11
|
+
# array-like object.
|
12
|
+
#
|
13
|
+
# Example:
|
14
|
+
#
|
15
|
+
# row = ['Hello', 'World']
|
16
|
+
# column = Column.new :first, 0
|
17
|
+
# column.value_in row # => 'Hello'
|
18
|
+
#
|
19
|
+
# Returns preprocessed value.
|
20
|
+
def values_in row
|
21
|
+
values = indexes.map { |index| (row[index] || String.new).strip }
|
22
|
+
values = values.first if values.size == 1
|
23
|
+
if preprocessor.respond_to? :call
|
24
|
+
preprocessor.call values
|
25
|
+
else
|
26
|
+
values
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Conformist
|
2
|
+
class Row
|
3
|
+
attr_reader :columns, :row
|
4
|
+
|
5
|
+
def initialize columns, row
|
6
|
+
@columns, @row = columns, row
|
7
|
+
end
|
8
|
+
|
9
|
+
# Extracts key-value pairs for each column in the row. Will implicitly
|
10
|
+
# join an array into a string.
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
#
|
14
|
+
# row = Row.new columns, csv_row
|
15
|
+
# row.to_hash # => {:first => 'Hello', :second => 'World'}
|
16
|
+
#
|
17
|
+
# Returns conformed hash.
|
18
|
+
def to_hash
|
19
|
+
columns.inject({}) do |attributes, column|
|
20
|
+
values = column.values_in row
|
21
|
+
values = values.join if values.respond_to? :join
|
22
|
+
attributes.merge column.name => values
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class BaseTest < MiniTest::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@klass = Class.new.tap { |klass| klass.send :include, Conformist::Base }
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_option
|
9
|
+
@klass.option :a => 1
|
10
|
+
@klass.option :b => 2
|
11
|
+
assert_equal({:a => 1, :b => 2}, @klass.options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_column
|
15
|
+
@klass.column :a, 0
|
16
|
+
@klass.column :b, 1
|
17
|
+
assert_equal 2, @klass.columns.size
|
18
|
+
assert_instance_of Conformist::Column, @klass.columns[rand(2)]
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_load
|
22
|
+
instance = @klass.load 'file'
|
23
|
+
assert_equal 'file', instance.path
|
24
|
+
assert_instance_of @klass, instance
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_foreach
|
28
|
+
rows = [
|
29
|
+
{:name => "CRAFERS", :callsign => "ABS2", :latitude => "34 58 49S", :signtal_type => "digital"},
|
30
|
+
{:name => "CRAFERS", :callsign => "SAS7", :latitude => "34 58 57S", :signtal_type => "digital"},
|
31
|
+
{:name => "CRAFERS", :callsign => "NWS9", :latitude => "34 59 02S", :signtal_type => "digital"},
|
32
|
+
{:name => "CRAFERS", :callsign => "ADS10", :latitude => "34 59 02S", :signtal_type => "digital"},
|
33
|
+
{:name => "CRAFERS", :callsign => "ADS10", :latitude => "34 58 57S", :signtal_type => "digital"}
|
34
|
+
]
|
35
|
+
ACMA.load(fixture('acma.csv')).foreach do |row|
|
36
|
+
assert_equal rows.shift, row
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class ColumnTest < MiniTest::Unit::TestCase
|
4
|
+
def test_name
|
5
|
+
column = Conformist::Column.new :foo
|
6
|
+
assert_equal :foo, column.name
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_one_index
|
10
|
+
column = Conformist::Column.new :foo, 0
|
11
|
+
assert_equal 'a', column.values_in(stub_row)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_preprocess_with_one_index
|
15
|
+
column = Conformist::Column.new(:foo, 0) { |value| value.upcase }
|
16
|
+
assert_equal 'A', column.values_in(stub_row)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_many_indexes
|
20
|
+
column = Conformist::Column.new :foo, 1, 2, 3
|
21
|
+
assert_equal ['b', 'c', 'd'], column.values_in(stub_row)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_preprocess_with_many_indexes
|
25
|
+
column = Conformist::Column.new(:foo, 1, 2, 3) { |values| values.reverse }
|
26
|
+
assert_equal ['d', 'c', 'b'], column.values_in(stub_row)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_virtual
|
30
|
+
column = Conformist::Column.new(:foo) { 'a' }
|
31
|
+
assert_equal 'a', column.values_in(stub_row)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_strip_whitespace
|
35
|
+
column = Conformist::Column.new(:foo, 0)
|
36
|
+
assert_equal 'a', column.values_in([' a '])
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_nil_empty_string
|
40
|
+
column = Conformist::Column.new(:foo, 0)
|
41
|
+
assert_equal '', column.values_in([])
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class ConformistTest < MiniTest::Unit::TestCase
|
4
|
+
def test_foreach
|
5
|
+
rows = [
|
6
|
+
{:name => "CRAFERS", :callsign => "ABS2", :latitude => "34 58 49S", :signtal_type => "digital"},
|
7
|
+
{:name => "CRAFERS", :callsign => "SAS7", :latitude => "34 58 57S", :signtal_type => "digital"},
|
8
|
+
{:name => "CRAFERS", :callsign => "NWS9", :latitude => "34 59 02S", :signtal_type => "digital"},
|
9
|
+
{:name => "CRAFERS", :callsign => "ADS10", :latitude => "34 59 02S", :signtal_type => "digital"},
|
10
|
+
{:name => "CRAFERS", :callsign => "ADS10", :latitude => "34 58 57S", :signtal_type => "digital"},
|
11
|
+
{:name => "LOS ANGELES, CA", :callsign => "KVTU-LP", :latitude => "34 11 13.90 N", :signtal_type => "digital"},
|
12
|
+
{:name => "BAKERSFIELD, CA", :callsign => "NEW", :latitude => "35 12 6.00 N", :signtal_type => "digital"},
|
13
|
+
{:name => "YUCA VALLEY, CA", :callsign => "NEW", :latitude => "34 9 10.10 N", :signtal_type => "digital"},
|
14
|
+
{:name => "SACRAMENTO, CA", :callsign => "KCSO-LD", :latitude => "38 7 10.00 N", :signtal_type => "digital"},
|
15
|
+
{:name => "LOS ANGELES, CA", :callsign => "KVTU-LP", :latitude => "34 13 38.00 N", :signtal_type => "digital"}
|
16
|
+
]
|
17
|
+
Conformist.foreach ACMA.load(fixture('acma.csv')), FCC.load(fixture('fcc.txt')) do |row|
|
18
|
+
assert_equal rows.shift, row
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class RowTest < MiniTest::Unit::TestCase
|
4
|
+
def test_to_hash_should_join_array
|
5
|
+
column = Conformist::Column.new(:foo, 0, 1, 2)
|
6
|
+
row = Conformist::Row.new [column], stub_row
|
7
|
+
assert_equal({:foo => 'abc'}, row.to_hash)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_to_hash_should_not_join_string
|
11
|
+
column = Conformist::Column.new(:foo, 0, 1, 2) { |values| values.join('-').upcase }
|
12
|
+
row = Conformist::Row.new [column], stub_row
|
13
|
+
assert_equal({:foo => 'A-B-C'}, row.to_hash)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_to_hash_with_many_columns
|
17
|
+
columns = Conformist::Column.new(:foo, 0), Conformist::Column.new(:bar, 1, 2, 3)
|
18
|
+
row = Conformist::Row.new columns, stub_row
|
19
|
+
assert_equal({:foo => 'a', :bar => 'bcd'}, row.to_hash)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class FCC
|
2
|
+
include Conformist::Base
|
3
|
+
|
4
|
+
option :col_sep => '|'
|
5
|
+
|
6
|
+
column :name, 10, 11 do |values|
|
7
|
+
"#{values[0].upcase}, #{values[-1]}"
|
8
|
+
end
|
9
|
+
column :callsign, 1
|
10
|
+
column :latitude, 20, 21, 22, 19 do |values|
|
11
|
+
values.join(' ')
|
12
|
+
end
|
13
|
+
column :signtal_type do
|
14
|
+
'digital'
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class ACMA
|
2
|
+
include Conformist::Base
|
3
|
+
|
4
|
+
option :col_sep => ','
|
5
|
+
option :quote_char => '"'
|
6
|
+
|
7
|
+
column :name, 11 do |value|
|
8
|
+
value.match(/[A-Z]+$/)[0].upcase
|
9
|
+
end
|
10
|
+
column :callsign, 1
|
11
|
+
column :latitude, 15
|
12
|
+
column :signtal_type do
|
13
|
+
'digital'
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
Adelaide,ABS2,64.26,National,H,124,OD,200000,57001,1198821,23139,ntl Tower Summit Road CRAFERS,54,290707,6126723,34 58 49S,138 42 25E,SA,2,,,,Issued
|
2
|
+
Adelaide,SAS7,182.26,Commercial,H,122,OD,200000,122001,1139429,23181,Channel 7/10 Site 115 Summit Road CRAFERS,54,290670,6126481,34 58 57S,138 42 24E,SA,7,122,ADELAIDE TV1,162,Issued
|
3
|
+
Adelaide,NWS9,196.26,Commercial,H,144,OD,200000,121001,1384392,23132,NWS 9 site 109 Summit Road CRAFERS,54,290698,6126331,34 59 02S,138 42 25E,SA,9,121,ADELAIDE TV1,162,Issued
|
4
|
+
Adelaide,ADS10,209.25,Commercial,H,144,OD,200000,120001,1904367,23132,NWS 9 site 109 Summit Road CRAFERS,54,290698,6126331,34 59 02S,138 42 25E,SA,10,120,ADELAIDE TV1,162,Issued
|
5
|
+
Adelaide,ADS10,209.25,Commercial,H,122,OD,200000,120001,1384005,23181,Channel 7/10 Site 115 Summit Road CRAFERS,54,290670,6126481,34 58 57S,138 42 24E,SA,10,120,ADELAIDE TV1,162,Issued
|
@@ -0,0 +1,5 @@
|
|
1
|
+
|KVTU-LP |- |LD |3 |DA | |- |- |APP |LOS ANGELES |CA |US |BDFCDVL-20100309ABS |0.25 kW |- |0.0 |- |130176 |N |34 |11 |13.90 |W |117 |42 |1.00 |MARK C. ALLEN | 0.00 km | 0.00 mi | 0.00 deg |1702. m|- |20780 |240. |1015693 |9. |1359585 |
|
2
|
+
|NEW |- |LD |3 |ND | |- |- |APP |BAKERSFIELD |CA |US |BMJADVL-20100520ABV |0.3 kW |- |0.0 |- |130049 |N |35 |12 |6.00 |W |119 |5 |26.10 |JOHN R. POWLEY | 0.00 km | 0.00 mi | 0.00 deg |143.2 m|- |100298 |- |1015627 |50. |1368486 |
|
3
|
+
|NEW |- |LD |3 |ND | |- |- |APP |YUCA VALLEY |CA |US |BMJADVL-20100520ADI |0.3 kW |- |0.0 |- |129831 |N |34 |9 |10.10 |W |116 |23 |19.10 |JOHN R. POWLEY | 0.00 km | 0.00 mi | 0.00 deg |1179. m|- |100305 |- |1028564 |20. |1370146 |
|
4
|
+
|KCSO-LD |- |LD |3 |DA | |- |- |LIC |SACRAMENTO |CA |US |BLDVL -20100825AAQ |0.3 kW |- |0.0 |- |18998 |N |38 |7 |10.00 |W |120 |43 |27.00 |SAINTE 51, L.P. | 0.00 km | 0.00 mi | 0.00 deg |948.5 m|- |96076 |270. |1050375 |114. |1396970 |
|
5
|
+
|KVTU-LP |- |TX |3 |DA |+ |- |- |CP MOD |LOS ANGELES |CA |US |BMPTVL -20100826AFT |0.498 kW |- |0.0 |- |130176 |N |34 |13 |38.00 |W |118 |4 |3.00 |MARK C. ALLEN | 0.00 km | 0.00 mi | 0.00 deg |1784. m|- |101585 |0. |1007719 |43. |1397199 |
|
data/test/helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: conformist
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tate Johnson
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-04-27 00:00:00 +10:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rake
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.8.7
|
24
|
+
type: :development
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: *id001
|
27
|
+
description: Conformist lets you bend CSVs to your will. Let multiple, different input files conform to a single interface without rewriting your parser each time.
|
28
|
+
email:
|
29
|
+
- tate@tatey.com
|
30
|
+
executables: []
|
31
|
+
|
32
|
+
extensions: []
|
33
|
+
|
34
|
+
extra_rdoc_files: []
|
35
|
+
|
36
|
+
files:
|
37
|
+
- .gitignore
|
38
|
+
- Gemfile
|
39
|
+
- LICENSE
|
40
|
+
- README.markdown
|
41
|
+
- Rakefile
|
42
|
+
- conformist.gemspec
|
43
|
+
- lib/conformist.rb
|
44
|
+
- lib/conformist/base.rb
|
45
|
+
- lib/conformist/column.rb
|
46
|
+
- lib/conformist/row.rb
|
47
|
+
- lib/conformist/version.rb
|
48
|
+
- test/conformist/base_test.rb
|
49
|
+
- test/conformist/column_test.rb
|
50
|
+
- test/conformist/conformist_test.rb
|
51
|
+
- test/conformist/row_test.rb
|
52
|
+
- test/definitions/acma.rb
|
53
|
+
- test/definitions/fcc.rb
|
54
|
+
- test/fixtures/acma.csv
|
55
|
+
- test/fixtures/fcc.txt
|
56
|
+
- test/helper.rb
|
57
|
+
has_rdoc: true
|
58
|
+
homepage: https://github.com/tatey/conformist
|
59
|
+
licenses: []
|
60
|
+
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: 1.8.7
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: -2005375605145254914
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
requirements: []
|
82
|
+
|
83
|
+
rubyforge_project: conformist
|
84
|
+
rubygems_version: 1.6.2
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: Let multiple, different input files conform to a single interface.
|
88
|
+
test_files:
|
89
|
+
- test/conformist/base_test.rb
|
90
|
+
- test/conformist/column_test.rb
|
91
|
+
- test/conformist/conformist_test.rb
|
92
|
+
- test/conformist/row_test.rb
|
93
|
+
- test/definitions/acma.rb
|
94
|
+
- test/definitions/fcc.rb
|
95
|
+
- test/fixtures/acma.csv
|
96
|
+
- test/fixtures/fcc.txt
|
97
|
+
- test/helper.rb
|