broker 0.0.9 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 22906356dab990f2e1791980fd4259d5c915c1e1
4
- data.tar.gz: b509f861be4137165f8b92e5f7667dbb891fdca7
3
+ metadata.gz: 06703642e42f471850e220882e24d2e0b3cd54b7
4
+ data.tar.gz: 0996bd3519546efc94b153e53ba5e42da45e6570
5
5
  SHA512:
6
- metadata.gz: ed637b3ac16bbb1346fbee41f7bd52e456441cf4b74a47a4a2bfe66423bde82e6876b879657f841e13c1abaf925a25970cda27fe0b07f81e1fb6e9849c4ffd86
7
- data.tar.gz: 12de6c2ad9ddc465aed4423e8c4d5eaec4f1bd503e9b49eb57384f029254bea79248b3e654452c86cab6166dd75bedd64da4bbfcbf1b0d03d71b4a259ad76923
6
+ metadata.gz: 18fdb75b3817fa85cfb7f7a23b0daa644fcfcc2bf471bc0a4ee61914d253751dc5abaa813322f406481867a838687c4301feb34d737790d9167ba49fc0e63863
7
+ data.tar.gz: 463b7df4a4699a1c03295579ce154b88841bfb57cf5d26c4d85afd52c577b51668b9234f6b5ddb5c5aab6eb53424056d9ddf8b5c8e48c8770785720bf78d916a
data/broker.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |gem|
8
8
  gem.version = Broker::VERSION
9
9
  gem.authors = ["Shawn Henley"]
10
10
  gem.email = ["shawn@luckysailor.net"]
11
- gem.description = gem.summary = "Automate the importing and exporting of data with Quickbase applications, using post requests."
11
+ gem.description = gem.summary = "Simple utility to automate the importing of data through the Quickbase API by polling a folder queue for new files, and pushing the data to your Quickbase apps."
12
12
  gem.homepage = "https://github.com/luckysailor/broker"
13
13
  gem.license = "MIT"
14
14
 
@@ -9,7 +9,7 @@ module Broker
9
9
 
10
10
  def self.boot!
11
11
  puts "starting up"
12
- puts "watching for files in #{Broker.queue}"
12
+ puts "watching for files in #{Broker.options[:queue]}"
13
13
  end
14
14
 
15
15
  end
data/lib/broker/cli.rb CHANGED
@@ -39,17 +39,18 @@ module Broker
39
39
  banner: "Generate your queue folder structure"
40
40
  def queue
41
41
  require 'broker'
42
- empty_dir = !Dir.exists?(Broker.queue)
42
+ empty_dir = !Dir.exists?(Broker.options[:queue])
43
43
 
44
44
  if options[:create] && empty_dir
45
- FileUtils.mkdir Broker.queue
45
+ FileUtils.mkdir Broker.options[:queue]
46
+ FileUtils.mkdir Broker.options[:processed_path]
46
47
  say "Your Q has been created at:"
47
- puts "#{Broker.queue}"
48
+ puts "#{Broker.options[:queue]}"
48
49
  end
49
50
 
50
51
  if options[:update] && !empty_dir
51
- base_path = "#{Broker.queue}"
52
- roots = Broker.tables.keys
52
+ base_path = "#{Broker.options[:queue]}"
53
+ roots = Broker.table_keys
53
54
  tables = []
54
55
 
55
56
  make_tree(base_path, roots)
data/lib/broker/export.rb CHANGED
@@ -1,7 +1,7 @@
1
- require 'broker/session'
1
+ require 'broker/qb/session'
2
2
 
3
3
  module Broker
4
- class Export < Broker::Session
4
+ class Export < Broker::QB::Session
5
5
 
6
6
  def initialize(opt={})
7
7
  super(opt)
@@ -0,0 +1,24 @@
1
+ require 'broker/queue'
2
+
3
+ module Broker
4
+ class Finder
5
+
6
+ def initialize(q)
7
+ opt = Broker.options
8
+ @queue = q
9
+ @dir = File.join(opt[:queue], "**", "*.#{opt[:file_ext].to_s}")
10
+ end
11
+
12
+ def check
13
+ files = get
14
+ @queue.push(files) unless files.empty?
15
+ end
16
+
17
+ private
18
+
19
+ def get
20
+ Dir.glob(@dir)
21
+ end
22
+
23
+ end
24
+ end
data/lib/broker/import.rb CHANGED
@@ -1,11 +1,22 @@
1
- require 'broker'
2
- require 'broker/client/quickbase_client'
1
+ require 'broker/session'
3
2
 
4
3
  module Broker
5
- class Import
6
-
7
-
8
-
4
+ class Import < Broker::Session
5
+
6
+ def fire_event(payload)
7
+ @payload = payload
8
+ if qb_ready?(@payload.pkg.app_key) && respond_to?(ext)
9
+ return send(ext)
10
+ end
11
+ end
9
12
 
13
+ def csv
14
+ @client.importCSVFile(@payload.pkg.file, @payload.pkg.dbid)
15
+ end
16
+
17
+ def txt
18
+ @client.importTSVFile(@payload.pkg.file, @payload.pkg.dbid)
19
+ end
20
+
10
21
  end
11
22
  end
@@ -1,6 +1,43 @@
1
1
  require 'broker/utility'
2
+ require 'broker/queue'
3
+ require 'broker/import'
4
+ require 'broker/finder'
2
5
 
3
6
  module Broker
7
+ module Event
8
+ def register(arr)
9
+ arr || return
10
+ puts "Event has been registered with: #{arr.inspect}"
11
+ unless arr.empty?
12
+ begin
13
+ session = Broker::Import.new(:app => Broker.any_app)
14
+ rescue ArgumentError => e
15
+ @failed = true
16
+ puts "Cant login to QB, invalid app name"
17
+ puts e.message
18
+ end
19
+ @failed || transport(session)
20
+ end
21
+
22
+ end
23
+
24
+ def transport(session)
25
+ while !@queue.empty?
26
+ payload = @queue.next
27
+ results = payload.commit(session)
28
+ puts "#{results.inspect}"
29
+ @queue.success(payload)
30
+ # Need to handle failure and add payload to queues failed
31
+ # Need to handle success and move file out and alert queue
32
+ end
33
+ puts "Session Terminated: #{session.sign_out}"
34
+ puts "Processed: #{@queue.processed}"
35
+ puts "Pending: #{@queue.pending.inspect}"
36
+ puts "Failed: #{@queue.failed.inspect}"
37
+ end
38
+
39
+ end
40
+
4
41
  class Launcher
5
42
 
6
43
  def initialize
@@ -23,11 +60,14 @@ module Broker
23
60
 
24
61
  class Poller
25
62
  include Utility
63
+ include Event
26
64
 
27
65
  def initialize
28
- @finished = false
29
- @wait_time = Broker.poll_interval
30
- @folder = Broker.queue
66
+ @finished = false
67
+ @wait_time = Broker.options[:poll_interval]
68
+ @folder = Broker.options[:queue]
69
+ @queue = Broker::Queue.new
70
+ @finder = Broker::Finder.new(@queue)
31
71
  end
32
72
 
33
73
  def terminate
@@ -46,7 +86,7 @@ module Broker
46
86
  pause_first
47
87
 
48
88
  while !@finished
49
- puts "Checking for new files in #{@folder}"
89
+ register(@finder.check)
50
90
  wait
51
91
  end
52
92
  end
@@ -0,0 +1,51 @@
1
+ require 'ostruct'
2
+
3
+ module Broker
4
+ class Payload
5
+
6
+ attr_reader :pkg
7
+
8
+ class << self
9
+
10
+ def parse(single_path)
11
+
12
+ attrs = {
13
+ file: single_path,
14
+ dbid: nil,
15
+ app: nil,
16
+ app_key: nil,
17
+ table: nil
18
+ }
19
+
20
+ # TODO: Rewrite!
21
+ # Sloppy, need a more elegant way to pop values off the stack
22
+ slots = single_path.split("/")
23
+ slots.pop
24
+ t = slots.pop
25
+ a = slots.pop
26
+
27
+ _id = Broker.lookup_tbid({app: a, table: t})
28
+ attrs[:dbid], attrs[:app], attrs[:app_key], attrs[:table] = _id, Broker.lookup_appname(a), a, t
29
+
30
+ new(attrs)
31
+ end
32
+
33
+ def chunk(arr)
34
+ 3.times { yield arr.pop }
35
+ end
36
+ end
37
+
38
+ def initialize(opt={})
39
+ @pkg = OpenStruct.new(file: opt[:file],
40
+ dbid: opt[:dbid],
41
+ app: opt[:app],
42
+ app_key: opt[:app_key],
43
+ table: opt[:table])
44
+ end
45
+
46
+ def commit(session)
47
+ session.fire_event(self)
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,43 @@
1
+ require 'broker/payload'
2
+
3
+ module Broker
4
+ class Queue
5
+
6
+ attr_reader :processed, :pending, :failed
7
+
8
+ def initialize
9
+ @processed = 0
10
+ @pending = []
11
+ @failed = []
12
+ end
13
+
14
+ def push(paths)
15
+ paths.each { |p| @pending << Broker::Payload.parse(p) }
16
+ end
17
+
18
+ def next
19
+ @pending.pop
20
+ end
21
+
22
+ def empty?
23
+ @pending.empty?
24
+ end
25
+
26
+ def failure(payload)
27
+ @failed << payload
28
+ end
29
+
30
+ def success(payload)
31
+ @processed +=1
32
+ move payload
33
+ end
34
+
35
+ private
36
+
37
+ def move(payload)
38
+ f = File.basename(payload.pkg.file)
39
+ FileUtils.mv payload.pkg.file, File.join(Broker.options[:processed_path],"/", f)
40
+ end
41
+
42
+ end
43
+ end
@@ -1,34 +1,66 @@
1
- require 'broker'
2
1
  require 'broker/client/quickbase_client'
3
2
 
4
3
  module Broker
5
- class Session
6
-
7
- attr_reader :client, :app
4
+ # module QB
5
+ class Session
6
+
7
+ attr_reader :client, :app, :ext
8
8
 
9
- def initialize(opt={})
10
- @app = opt[:app]
9
+ def initialize(opt={})
10
+ @app = Broker.lookup_appname(opt[:app])
11
+ @ext = Broker.options[:file_ext]
11
12
 
12
- credentials = {
13
- "username" => Broker.secrets['USER'],
14
- "password" => Broker.secrets['PASSWORD'],
15
- "appname" => @app,
16
- "org" => Broker.secrets['ORG'],
17
- "apptoken" => opt[:token] || Broker.tables[@app]['token']
18
- }
13
+ credentials = {
14
+ "username" => Broker.secrets['USERNAME'],
15
+ "password" => Broker.secrets['PASSWORD'],
16
+ "appname" => @app,
17
+ "org" => Broker.secrets['ORG'],
18
+ "apptoken" => opt[:token] || Broker.secrets['TOKEN']
19
+ }
20
+
21
+ begin
22
+ @client = QuickBase::Client.init(credentials)
23
+ rescue => e
24
+ puts e.message
25
+ #raise ArgumentError
26
+ ensure
27
+ # We successfully logged into quickbase, but supplied an invalid app name
28
+ if @client && @client.errcode == "32"
29
+ @client.signOut
30
+ raise ArgumentError
31
+ end
32
+ end
33
+ end
19
34
 
20
- @client = QuickBase::Client.init(credentials)
21
- end
22
-
23
- def get_field_names(table)
24
- table &&= table.to_s
25
- db = Broker.tables[@app]['tables'][table]
26
- db && @client.getFieldNames(db, "", true)
27
- end
35
+ def fire_event
36
+ raise NotImplementedError
37
+ end
38
+
39
+ def sign_out
40
+ @client.signOut
41
+ end
42
+
43
+ def qb_ready?(name)
44
+ app_name = Broker.lookup_appname(name)
45
+ unless app_name == @client.dbname
46
+ return app_name && change_app(app_name, name)
47
+ end
48
+ true
49
+ end
28
50
 
29
- def sign_out
30
- @client.signOut
51
+ def field_names(table)
52
+ table &&= table.to_s
53
+ db = Broker.tables[@app]['tables'][table]
54
+ db && @client.getFieldNames(db, "", true)
55
+ end
56
+
57
+ private
58
+
59
+ def change_app(app_name, app_key)
60
+ @app = app_key.to_s
61
+ @client.findDBByname(app_name)
62
+ @client.dbname == app_name
63
+ end
31
64
  end
32
-
33
- end
65
+ # end
34
66
  end
@@ -11,6 +11,9 @@ Broker.setup do |config|
11
11
  # Directory where your import files will be queued for import
12
12
  config.queue = 'broker_queue'
13
13
 
14
+ # Directory where your successful imported files will be moved
15
+ config.processed_path = 'broker_processed'
16
+
14
17
  # Uncomment to change the default file type to use for importing
15
18
  # [:csv, :tab]
16
19
  #config.file_ext = :csv
@@ -1,3 +1,3 @@
1
1
  module Broker
2
- VERSION = "0.0.9"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/broker.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'broker/version'
2
+ #require 'broker/session'
2
3
  require 'yaml'
3
4
 
4
5
  module Broker
@@ -10,23 +11,30 @@ module Broker
10
11
  initializer: 'config/initializers/broker.rb',
11
12
  poll_interval: 300,
12
13
  queue: 'broker_queue',
13
- file_ext: :csv
14
+ processed_path: 'broker_processed',
15
+ file_ext: :csv,
16
+ enqueued: []
14
17
  }
15
18
 
16
- @@secrets_path = @@secrets_path ||= DEFAULTS[:secrets_path]
17
- @@tables_path = @@tables_path ||= DEFAULTS[:tables_path]
18
- @@initializer = @@initializer ||= DEFAULTS[:initializer]
19
- @@poll_interval = @poll_interval ||= DEFAULTS[:poll_interval]
20
- @@queue = @@queue ||= DEFAULTS[:queue]
21
- @@file_ext = @@file_ext ||= DEFAULTS[:file_ext]
19
+ def self.load_config(dest)
20
+ YAML.load_file(dest) rescue {}
21
+ end
22
+
23
+ @@secrets = @@secrets ||= load_config(DEFAULTS[:secrets_path])
24
+ @@tables = @@tables ||= load_config(DEFAULTS[:tables_path])
22
25
 
23
- @@secrets = YAML.load_file(@@secrets_path) rescue {}
24
- @@tables = YAML.load_file(@@tables_path) rescue {}
26
+ def self.options
27
+ @options ||= DEFAULTS.dup
28
+ end
25
29
 
26
30
  def self.lookup_tbid(opt={})
27
31
  tables[opt[:app]]['tables'][opt[:table]]
28
32
  end
29
33
 
34
+ def self.lookup_appname(key)
35
+ tables[key.to_s]['name']
36
+ end
37
+
30
38
  def self.path
31
39
  Dir.pwd
32
40
  end
@@ -40,76 +48,62 @@ module Broker
40
48
  end
41
49
 
42
50
  def self.config_files
43
- [secrets_path, tables_path, initializer]
51
+ fs = [:secrets_path, :tables_path, :initializer]
52
+ options.select { |opt| fs.include? opt }.values
44
53
  end
45
54
 
46
- # def self.options
47
- # @options ||= DEFAULTS.dup
48
- # end
49
- #
50
- # def self.options=(opt)
51
- # @options = opt
52
- # end
53
-
54
- def self.poll_interval
55
- @@poll_interval
55
+ def self.secrets
56
+ @@secrets
56
57
  end
57
58
 
58
- def self.poll_interval=(val)
59
- @@poll_interval = val
59
+ def self.tables
60
+ @@tables
60
61
  end
61
62
 
62
- def self.queue
63
- @@queue
63
+ def self.table_keys
64
+ tables.keys
64
65
  end
65
66
 
66
- def self.queue=(val)
67
- @@queue = val
67
+ def self.any_app
68
+ table_keys.first
68
69
  end
69
70
 
70
- def file_ext
71
- @@file_ext
72
- end
71
+ # Initializer setter methods
72
+ # Loaded at runtime in initializers/broker.rb
73
+ # Broker.setup do |config|
74
+ # config.secrets_path = /my/updated/path.yml
75
+ # end
73
76
 
74
- def file_ext=(val)
75
- @@file_ext = val if [:csv, :tab].include? val
76
- end
77
-
78
- def self.secrets
79
- @@secrets
77
+ def self.initializer=(val)
78
+ options[:initializer] = val
80
79
  end
81
80
 
82
- def self.secrets_path
83
- @@secrets_path
81
+ def self.secrets_path=(pa)
82
+ options[:secrets_path] = pa
83
+ @@secrets = load_config(pa)
84
84
  end
85
85
 
86
- def self.secrets_path=(val)
87
- @@secrets_path = val
88
- @@secrets = YAML.load_file(@@secrets_path) rescue {}
86
+ def self.tables_path=(pa)
87
+ options[:tables_path] = pa
88
+ @@tables = load_config(pa)
89
89
  end
90
90
 
91
- def self.tables
92
- @@tables
91
+ def self.queue=(val)
92
+ options[:queue] = val
93
93
  end
94
94
 
95
- def self.tables_path
96
- @@tables_path
95
+ def self.processed_path=(pa)
96
+ options[:processed_path] = pa
97
97
  end
98
98
 
99
- def self.tables_path=(val)
100
- @@tables_path = val
101
- @@tables = YAML.load_file(@@tables_path) rescue {}
99
+ def self.poll_interval=(val)
100
+ options[:poll_interval] = val
102
101
  end
103
102
 
104
- def self.initializer
105
- @@initializer
103
+ def file_ext=(val)
104
+ options[:file_ext] = val if [:csv, :tab].include? val
106
105
  end
107
106
 
108
- def self.initializer=(val)
109
- @@initializer = val
110
- end
111
-
112
107
  end
113
108
 
114
109
  require 'broker/application'
115
-
data/web/views/layout.erb CHANGED
@@ -39,7 +39,7 @@
39
39
  <p class="navbar-text" style="color:white;">Broker v<%= Broker::VERSION %></p>
40
40
  </li>
41
41
  <li>
42
- <p class="navbar-text">Queue: <%= Broker.queue %></p>
42
+ <p class="navbar-text">Queue: <%= Broker.options[:queue] %></p>
43
43
  </li>
44
44
  <li>
45
45
  <p class="navbar-text"><%= 'Time' %>: <%= Time.now.localtime.strftime('%H:%M:%S CST') %></p>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: broker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shawn Henley
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-20 00:00:00.000000000 Z
11
+ date: 2015-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,8 +52,9 @@ dependencies:
52
52
  - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- description: Automate the importing and exporting of data with Quickbase applications,
56
- using post requests.
55
+ description: Simple utility to automate the importing of data through the Quickbase
56
+ API by polling a folder queue for new files, and pushing the data to your Quickbase
57
+ apps.
57
58
  email:
58
59
  - shawn@luckysailor.net
59
60
  executables:
@@ -76,8 +77,11 @@ files:
76
77
  - lib/broker/client/QuickBaseMisc.rb
77
78
  - lib/broker/client/quickbase_client.rb
78
79
  - lib/broker/export.rb
80
+ - lib/broker/finder.rb
79
81
  - lib/broker/import.rb
80
82
  - lib/broker/launcher.rb
83
+ - lib/broker/payload.rb
84
+ - lib/broker/queue.rb
81
85
  - lib/broker/session.rb
82
86
  - lib/broker/templates/broker.rb
83
87
  - lib/broker/templates/quickbase_tables.yml
@@ -121,6 +125,7 @@ rubyforge_project:
121
125
  rubygems_version: 2.0.6
122
126
  signing_key:
123
127
  specification_version: 4
124
- summary: Automate the importing and exporting of data with Quickbase applications,
125
- using post requests.
128
+ summary: Simple utility to automate the importing of data through the Quickbase API
129
+ by polling a folder queue for new files, and pushing the data to your Quickbase
130
+ apps.
126
131
  test_files: []