Module: Scaretable

Defined in:
lib/scaretable.rb,
lib/scaretable/version.rb

Overview

unstable evil Airtable interface

Defined Under Namespace

Classes: Error

Constant Summary collapse

VERSION =
'0.1.0'

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.connObject



61
62
63
64
65
66
67
68
69
# File 'lib/scaretable.rb', line 61

def conn
  @conn ||= Faraday.new do |f|
    f.request :url_encoded
    f.adapter Faraday.default_adapter
    f.response :raise_error
    # "Hello Airtable, am Firefox. Please give me your secrets."
    f.headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:137.0) Gecko/20100101 Firefox/137.0'
  end
end

.timezoneObject

Returns the value of attribute timezone.



13
14
15
# File 'lib/scaretable.rb', line 13

def timezone
  @timezone
end

Class Method Details

.effective_timezoneObject



57
58
59
# File 'lib/scaretable.rb', line 57

def effective_timezone
  timezone || 'America/New_York' # let's be real is it ever not gonna be EST
end

.get_csv(base_id, share_id, view_id = nil) ⇒ Object

given an appxxx, a shrxxx (and a viwxxx if you’re feeling generous), get CSV content ready to feed into CSV.parse



18
19
20
21
# File 'lib/scaretable.rb', line 18

def get_csv(base_id, share_id, view_id = nil)
  url = get_csv_url(base_id, share_id, view_id)
  conn.get(url).body.sub("\uFEFF", '') # U woTF m-8? BOMs away...
end

.get_csv_url(base_id, share_id, view_id = nil) ⇒ Object

you ship an appxxx, a shrxxx (and a viwxxx if you’re feeling generous), we ship a URL at which airtable thinks you might find a CSV



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/scaretable.rb', line 25

def get_csv_url(base_id, share_id, view_id = nil)
  params = grab_params(base_id, share_id)

  access_policy = params['accessPolicy'] or raise Error, 'where accessPolicy? did you check between the couch cushions?'
  actions = JSON.parse(access_policy, symbolize_names: true)[:allowedActions] or raise Error, 'no allowedActions? god forbid women do anything'
  view_id ||= actions.find { |a| a[:modelClassName] == 'view' }
                     &.dig(:modelIdSelector) or raise Error, 'no view id? visionblind.'

  resp = conn.get(
    "https://airtable.com/v0.3/view/#{view_id}/downloadCsv",
    {
      'x-time-zone' => effective_timezone,
      'x-user-locale' => 'en',
      'x-airtable-application-id' => base_id,
      'stringifiedObjectParams' => { origin: 'viewMenuPopover' } # me when i lie:
    }.merge(
      # i think these are the only ones we need?
      params.slice('accessPolicy', 'requestId')
    )
  )

  location = resp.headers['location'] or raise Error, "idk where i'm going with this"
  location
end

.grab_params(base_id, share_id) ⇒ Object



50
51
52
53
54
55
# File 'lib/scaretable.rb', line 50

def grab_params(base_id, share_id)
  page = conn.get("https://airtable.com/#{base_id}/#{share_id}").body
  /urlWithParams: "(.*?)"/ =~ page or raise Error, 'urlWithParams? never heard of her :-('
  q = URI(::Regexp.last_match(1).gsub('\u002F', '/')).query or raise Error, 'congrats! you found the string with no query params!' # why is it Like That
  URI.decode_www_form(q).to_h
end