Class: TableSetter::Table

Inherits:
Object
  • Object
show all
Defined in:
lib/table_setter/table.rb

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Table) initialize(slug, opts = {:defer => false})

A new Table should accept a slug, mapped to a yaml in the tables directory, optionally you can defer loading of the table until you’re ready to render it.



14
15
16
17
18
19
20
21
22
# File 'lib/table_setter/table.rb', line 14

def initialize(slug, opts={:defer => false})
  options = indifferent_access YAML.load_file(Table.table_path(slug))
  @table_opts = options[:table]
  @table_opts[:slug] = slug
  @deferred = opts[:defer]
  if !@deferred
    self.load
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

- (Object) method_missing(method)

We magically need access to the top level keys like google_key, or uri for the other methods. It’s a bit dangerous because everything returns nil otherwise. At some point we should eval and create methods at boot time.



115
116
117
118
119
# File 'lib/table_setter/table.rb', line 115

def method_missing(method)
  if @table_opts[method]
    @table_opts[method]
  end
end

Instance Attribute Details

- (Object) data (readonly)

The Table class handles processing the yaml processing and csv loading, through table fu



10
11
12
# File 'lib/table_setter/table.rb', line 10

def data
  @data
end

- (Object) facets (readonly)

The Table class handles processing the yaml processing and csv loading, through table fu



10
11
12
# File 'lib/table_setter/table.rb', line 10

def facets
  @facets
end

- (Object) next_page (readonly)

The Table class handles processing the yaml processing and csv loading, through table fu



10
11
12
# File 'lib/table_setter/table.rb', line 10

def next_page
  @next_page
end

- (Object) page (readonly)

The Table class handles processing the yaml processing and csv loading, through table fu



10
11
12
# File 'lib/table_setter/table.rb', line 10

def page
  @page
end

- (Object) prev_page (readonly)

The Table class handles processing the yaml processing and csv loading, through table fu



10
11
12
# File 'lib/table_setter/table.rb', line 10

def prev_page
  @prev_page
end

- (Object) table_opts (readonly)

The Table class handles processing the yaml processing and csv loading, through table fu



10
11
12
# File 'lib/table_setter/table.rb', line 10

def table_opts
  @table_opts
end

Class Method Details

+ (Object) all

Returns all the tables in the table directory. Each table is deferred so accessing the @data attribute will throw and error.



180
181
182
183
184
185
186
187
# File 'lib/table_setter/table.rb', line 180

def all
  tables=[]
  Dir.glob("#{TableSetter.table_path}/*.yml").each do |file|
    table = new(File.basename(file, ".yml"), :defer => true)
    tables << table if table.live
  end
  tables
end

+ (Boolean) exists?(slug)

Does a table with this slug exist?

Returns:

  • (Boolean)


211
212
213
# File 'lib/table_setter/table.rb', line 211

def exists?(slug)
  File.exists? table_path(slug)
end

+ (Object) fresh_yaml_time

fresh_yaml_time checks each file in the tables directory and returns the newest file’s modification time — there’s probably a more unix-y way to do this but for now this is plenty speedy.



192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/table_setter/table.rb', line 192

def fresh_yaml_time
  newest_file = Dir["#{TableSetter.table_path}/*.yml"].inject do |memo, obj|
    memo_time = File.new(File.expand_path memo).mtime
    obj_time = File.new(File.expand_path obj).mtime
    if memo_time > obj_time
      memo
    else
      obj
    end
  end
  File.new(newest_file).mtime
end

+ (Object) table_path(slug)

Convenience method for looking up by slug.



206
207
208
# File 'lib/table_setter/table.rb', line 206

def table_path(slug)
  "#{TableSetter.table_path}#{slug}.yml"
end

Instance Method Details

- (Object) csv_data

The csv_data for the table fu instance is loaded either from the remote source or from a local file, depending on the keys present in the yaml file.



42
43
44
45
46
47
# File 'lib/table_setter/table.rb', line 42

def csv_data
  case
  when google_key || url then Curl::Easy.perform(uri).body_str
  when file then File.open(uri).read
  end
end

- (Boolean) faceted?

Returns:

  • (Boolean)


65
66
67
# File 'lib/table_setter/table.rb', line 65

def faceted?
  !@facets.nil?
end

- (Boolean) hard_paginate?

hard_paginate instructs the app to render batches of a table.

Returns:

  • (Boolean)


75
76
77
# File 'lib/table_setter/table.rb', line 75

def hard_paginate?
  @table_opts[:hard_paginate] == true
end

- (Object) load

The load method handles the actual request either to the file system or remote url. It performs the requested data manipulations form the yml file after the data has been loaded. We’re keeping this explicit to control against unnecessary http requests.



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/table_setter/table.rb', line 27

def load
  csv = csv_data
  if @table_opts[:column_options]
    @table_opts[:column_options]['style'] ||= {}
  end
  @data = TableFu.new(csv_data, @table_opts[:column_options] || {})
  if @table_opts[:faceting]
    @data.col_opts[:ignored] = [@table_opts[:faceting][:facet_by]]
    @facets = @data.faceted_by @table_opts[:faceting][:facet_by]
  end
  @data.delete_rows! @table_opts[:dead_rows] if @table_opts[:dead_rows]
end

- (Object) paginate!(curr_page)

paginate uses TableFu’s only! method to batch the table. It also computes the page attributes which are nil and meaningless otherwise.

Raises:

  • (ArgumentError)


86
87
88
89
90
91
92
93
94
# File 'lib/table_setter/table.rb', line 86

def paginate!(curr_page)
  return if !hard_paginate?
  @page = curr_page.to_i
  raise ArgumentError if @page < 1 || @page > total_pages
  adj_page = @page - 1 > 0 ? @page - 1 : 0
  @prev_page = adj_page > 0 ? adj_page : nil
  @next_page = page < total_pages ? (@page + 1) : nil
  @data.only!(adj_page * per_page..(@page * per_page - 1))
end

- (Object) per_page

The number of rows per page. Defaults to 20



80
81
82
# File 'lib/table_setter/table.rb', line 80

def per_page
  @table_opts[:per_page] || 20
end

- (Object) sort_array

A convienence method to return the sort array for table setter.



104
105
106
107
108
109
110
# File 'lib/table_setter/table.rb', line 104

def sort_array
  if @data.sorted_by
    @data.sorted_by.inject([]) do |memo, (key, value)|
      memo << [@data.columns.index(key), value == 'descending' ? 1 : 0]
    end
  end
end

- (Boolean) sortable?

A table isn’t sortable by tablesorter if it’s either faceted or multi-page paginated.

Returns:

  • (Boolean)


70
71
72
# File 'lib/table_setter/table.rb', line 70

def sortable?
  !faceted? && !hard_paginate?
end

- (Object) total_pages

The total pages we’ll have. We need to calculate it before paginate, so that we still have the full @data.rows.length



99
100
101
# File 'lib/table_setter/table.rb', line 99

def total_pages
  @total_pages ||= (@data.rows.length / per_page.to_f).ceil
end

- (Object) updated_at

The real updated_at of a Table instance is the newer modification time of the csv file or the yaml file. Updates to either resource should break the cache.



60
61
62
63
# File 'lib/table_setter/table.rb', line 60

def updated_at
  csv_time = google_key.nil? ? modification_time(uri) : google_modification_time
  (csv_time > yaml_time ? csv_time : yaml_time).to_s
end

- (Object) uri

Returns a usable uri based on what sort of input we have.



50
51
52
53
54
55
56
# File 'lib/table_setter/table.rb', line 50

def uri
  case
  when google_key then "http://spreadsheets.google.com/pub?key=#{google_key}&output=csv"
  when url then url
  when file then File.expand_path("#{TableSetter.table_path}#{file}")
  end
end