retscli 0.1.0 → 0.2.0

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: 64bb6b1cc5838d8be49673141144e7273b4bfb7c
4
- data.tar.gz: 1d8b9c3f187d02e7de06d7a2f69be987adb4c57b
3
+ metadata.gz: 9d3f0be17b3b7a93c8f2d63263c5b15c41fb33ac
4
+ data.tar.gz: 9a33fb19a66b9376b92daa6bf978ef6799a7fb26
5
5
  SHA512:
6
- metadata.gz: f4f290c630981363f30220c14b11a9213fbb367f03ef87b5aa7c32f709a9b71e26acb800c39cefacc4ab18034446fc4e5132de29a19ff7667b83ab39a11a5625
7
- data.tar.gz: 9349b62d0c680a86903829081fd1d43150f38894853449c8661e150946ef56f97975e107c57848959bdcdd4343ccd59d2bc5cf3717c372c184cb304015ce28b6
6
+ metadata.gz: 57050020e021497315530ff16078dd6bcf8fe306210250ed0df42ba317b7816bfcb4eb9196778de91adc68456a77fcce5c530edcf56c7a4a0396230fef29ddba
7
+ data.tar.gz: 935757b2d9d36faca77457689fe7e715a766221b24ca85ea0b0dcf868db9bbca3199f9adff22da9b2fa59e1d10afc966ed81e0101afb960be0210d94dffd6006
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1.8
5
+ - 2.2.4
6
+ - 2.3.0
7
+ before_install: gem install bundler -v 1.11
@@ -0,0 +1,6 @@
1
+ # 0.2.0
2
+ - Ability to search resources
3
+ - Better error handling
4
+ - Debug mode
5
+ - Ability to login inside console incase session becomes invalid
6
+ - Fix user agent password flag
data/README.md CHANGED
@@ -1,16 +1,28 @@
1
- # Retscli
1
+ # retscli
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/retscli.svg)](https://badge.fury.io/rb/retscli)
4
+ [![Build Status](https://travis-ci.org/summera/retscli.svg?branch=master)](https://travis-ci.org/summera/retscli)
5
+
2
6
  CLI for querying RETS servers and searching metadata.
3
7
 
4
8
  This gem is built on top of the [rets](http://github.com/estately/rets) gem, which handles the actual querying and parsing of the RETS server requests. Big thanks to the [Estately](http://www.estately.com) team for their work!
5
9
 
6
- ![retscli gif](https://github.com/summera/gifs/blob/master/retscli/retscli.gif?raw=true)
10
+ ![retscli gif](https://github.com/summera/gifs/blob/master/retscli/search_metadata_cropped.gif?raw=true)
11
+ ![retscli png](https://github.com/summera/gifs/blob/master/retscli/search.png?raw=true)
7
12
 
8
13
  ## Installation
9
14
  $ gem install retscli
10
15
 
16
+ ## Features
17
+ - Search metadata for keywords. Results are highlighted for readability.
18
+ - Search resources. Results are displayed in a nicely formatted ascii table.
19
+ - Open command results in your editor of choice.
20
+ - Debug RETS requests and queries in debug mode.
21
+ - Command results are paged using less by default.
22
+
11
23
  ## Usage
12
24
 
13
- #### Shell Commands
25
+ #### CLI Commands
14
26
  ```bash
15
27
  $ retscli help
16
28
  Commands:
@@ -28,15 +40,20 @@ Usage:
28
40
  retscli console [LOGIN URL]
29
41
 
30
42
  Options:
31
- -u, [--username=USERNAME]
32
- -p, [--password=PASSWORD]
33
- -v, [--version=VERSION]
34
- -a, [--agent=AGENT]
35
- -ap, [--ua-password=UA_PASSWORD]
43
+ -u, [--username=USERNAME] # Username
44
+ -p, [--password=PASSWORD] # Password
45
+ -v, [--version=VERSION] # Rets version
46
+ # Default: RETS/1.7.2
47
+ -a, [--agent=AGENT] # User agent
48
+ -t, [--ua-password=UA_PASSWORD] # User agent password
49
+ -d, [--debug], [--no-debug] # Debug mode
36
50
 
37
51
  Start rets console
38
52
  ```
39
53
 
54
+ #### Debug Mode
55
+ To view requests being made to the RETS server, enable debug mode with the `-d` flag. Once enabled, helpful info will be logged to `$stdout`. This is helpful to debug errors thrown by the RETS server and to adjust queries.
56
+
40
57
  #### Rets Console Commands
41
58
  After dropping into the RETS console, you get a bunch of useful commands for searching and exploring the RETS server
42
59
 
@@ -45,15 +62,17 @@ $ retscli console http://rets.server.com -u summera -p password
45
62
 
46
63
  summera@rets.server.com > help
47
64
  Commands:
48
- capabilities # Display capabilities for rets server
49
- classes [RESOURCE] # List available classes for resource
50
- help [COMMAND] # Describe available commands or one specific command
51
- metadata # View metadata
52
- objects [RESOURCE] # List available objects for resource
53
- resources # List available resources
54
- search-metadata # Search metadata tables
55
- tables [RESOURCE] [CLASS] # List available tables for class of resource
56
- timezone-offset # System timezone offset
65
+ capabilities # Display capabilities for rets server
66
+ classes [RESOURCE] # List available classes for resource
67
+ help [COMMAND] # Describe available commands or one specific command
68
+ login # Re-Login to RETS server. Use if session is no longer valid
69
+ metadata # View metadata
70
+ objects [RESOURCE] # List available objects for resource
71
+ resources # List available resources
72
+ search [RESOURCE] [CLASS] [QUERY] # Search resources, e.g. properties, open houses, etc.
73
+ search-metadata # Search metadata tables
74
+ tables [RESOURCE] [CLASS] # List available tables for class of resource
75
+ timezone-offset # System timezone offset
57
76
  ```
58
77
 
59
78
  Again, to see available flags/options, run help on the command. Many of the commands have an `editor` option if you feel the need to get down and dirty in your editor of choice.
@@ -75,11 +94,12 @@ Search metadata tables
75
94
  ## Notes
76
95
  - When opening output in your editor, retscli will check the `$EDITOR` environment variable. If this is not set, it falls back to nano.
77
96
  - Much of the output is piped through `less` by default to allow for easy paging. If you'd like to change this, set your preferred pager in the `$PAGER` environment variable.
78
- - Retscli uses the ruby readline module for the rets console
97
+ - Retscli uses the ruby readline module for the rets console.
98
+ - If any arguments and/or options have spaces in them, you will need to wrap them in quotes so that retscli does not split on the spaces.
79
99
 
80
100
  ## Contributing
81
101
 
82
- 1. Fork it ( https://github.com/ianks/octodown/fork )
102
+ 1. Fork it ( https://github.com/summera/retscli/fork )
83
103
  1. Create your feature branch (`git checkout -b my-new-feature`)
84
104
  1. Commit your changes (`git commit -am 'Add some feature'`)
85
105
  1. Run the test suite (`bundle exec rake`)
@@ -9,11 +9,12 @@ module Retscli
9
9
  class Cli < Thor
10
10
 
11
11
  desc 'validate [LOGIN URL]', 'Validate rets credentials'
12
- method_option :username, aliases: '-u'
13
- method_option :password, aliases: '-p'
14
- method_option :version, aliases: '-v'
15
- method_option :agent, aliases: '-a'
16
- method_option :ua_password, aliases: '-ap'
12
+ method_option :username, aliases: '-u', :desc => 'Username'
13
+ method_option :password, aliases: '-p', :desc => 'Password'
14
+ method_option :version, aliases: '-v', :desc => 'Rets version', :default => 'RETS/1.7.2'
15
+ method_option :agent, aliases: '-a', :desc => 'User agent'
16
+ method_option :ua_password, aliases: '-t', :desc => 'User agent password'
17
+ method_option :debug, :aliases => '-d', :desc => 'Debug mode', :type => :boolean, :default => false
17
18
  def validate(url)
18
19
  client = rets_client(url, options)
19
20
 
@@ -29,11 +30,12 @@ module Retscli
29
30
  end
30
31
 
31
32
  desc 'capabilities [LOGIN URL]', 'Display capabilities for rets server'
32
- method_option :username, aliases: '-u'
33
- method_option :password, aliases: '-p'
34
- method_option :version, aliases: '-v'
35
- method_option :agent, aliases: '-a'
36
- method_option :ua_password, aliases: '-ap'
33
+ method_option :username, aliases: '-u', :desc => 'Username'
34
+ method_option :password, aliases: '-p', :desc => 'Password'
35
+ method_option :version, aliases: '-v', :desc => 'Rets version', :default => 'RETS/1.7.2'
36
+ method_option :agent, aliases: '-a', :desc => 'User agent'
37
+ method_option :ua_password, aliases: '-t', :desc => 'User agent password'
38
+ method_option :debug, :aliases => '-d', :desc => 'Debug mode', :type => :boolean, :default => false
37
39
  def capabilities(url)
38
40
  client = rets_client(url, options)
39
41
 
@@ -48,25 +50,29 @@ module Retscli
48
50
  end
49
51
 
50
52
  desc 'console [LOGIN URL]', 'Start rets console'
51
- method_option :username, aliases: '-u'
52
- method_option :password, aliases: '-p'
53
- method_option :version, aliases: '-v'
54
- method_option :agent, aliases: '-a'
55
- method_option :ua_password, aliases: '-ap'
53
+ method_option :username, aliases: '-u', :desc => 'Username'
54
+ method_option :password, aliases: '-p', :desc => 'Password'
55
+ method_option :version, aliases: '-v', :desc => 'Rets version', :default => 'RETS/1.7.2'
56
+ method_option :agent, aliases: '-a', :desc => 'User agent'
57
+ method_option :ua_password, aliases: '-t', :desc => 'User agent password'
58
+ method_option :debug, :aliases => '-d', :desc => 'Debug mode', :type => :boolean, :default => false
56
59
  def console(url)
57
60
  client = rets_client(url, options)
58
61
  Retscli::Shell.new(client).start
59
62
  end
60
63
 
61
64
  no_commands do
62
- def rets_client(url, params)
65
+ def rets_client(url, params={})
66
+ logger = options[:debug] ? Logger.new($stdout) : nil
67
+
63
68
  ::Rets::Client.new({
64
69
  :login_url => url,
65
70
  :username => params[:username],
66
71
  :password => params[:password],
67
72
  :version => params[:version],
68
73
  :agent => params[:agent],
69
- :ua_password => params[:ua_password]
74
+ :ua_password => params[:ua_password],
75
+ :logger => logger
70
76
  })
71
77
  end
72
78
  end
@@ -2,11 +2,19 @@ require "terminal-table"
2
2
 
3
3
  module Retscli
4
4
  class DisplayAdapter
5
+ NO_RESULTS = 'No Results'.freeze
6
+ EMPTY_VALUE = '<empty>'.freeze
7
+
5
8
  def initialize(client)
6
9
  @client = client
7
10
  @colorer = ::Thor::Shell::Color.new
8
11
  end
9
12
 
13
+ def login
14
+ @client.login
15
+ set_color("\u2713 Logged in", :green)
16
+ end
17
+
10
18
  def capabilities
11
19
  Terminal::Table.new(:rows => @client.capabilities.to_a)
12
20
  end
@@ -108,6 +116,30 @@ module Retscli
108
116
  search_results
109
117
  end
110
118
 
119
+ def search(resource, klass, query, options={})
120
+ select = options[:select] ? options[:select].join(',') : ''
121
+ count = options[:count] ? 2 : 0
122
+
123
+ results = @client.find(
124
+ :all,
125
+ search_type: resource,
126
+ class: klass,
127
+ query: query,
128
+ select: select,
129
+ limit: options[:limit],
130
+ offset: options[:offset],
131
+ count: count,
132
+ format: options[:format],
133
+ no_records_not_an_error: true
134
+ )
135
+
136
+ if results.is_a?(Integer)
137
+ resource_table([{ 'count' => results }])
138
+ else
139
+ resource_table(results)
140
+ end
141
+ end
142
+
111
143
  def page(output)
112
144
  begin
113
145
  pager = ENV['PAGER'] || 'less'
@@ -122,6 +154,18 @@ module Retscli
122
154
  end
123
155
 
124
156
  private
157
+ def resource_table(results=[])
158
+ term_table = Terminal::Table.new
159
+ if results.empty?
160
+ term_table.rows = [[NO_RESULTS]]
161
+ else
162
+ term_table.headings = results.first.keys
163
+ term_table.rows = results.map{ |result| result.values.map!{ |value| value.to_s.empty? ? EMPTY_VALUE : value } }
164
+ end
165
+
166
+ term_table
167
+ end
168
+
125
169
  def open_tempfile_with_content(editor, initial_content)
126
170
  temp_file do |f|
127
171
  f.puts(initial_content)
@@ -18,24 +18,24 @@ module Retscli
18
18
  end
19
19
 
20
20
  def start
21
- begin
22
- while line = readline_with_hist_management
23
- if EXIT_COMMANDS.include?(line)
24
- close
25
- else
26
- execute_shell_command(line)
27
- end
21
+ while line = readline_with_hist_management
22
+ if EXIT_COMMANDS.include?(line)
23
+ close
24
+ else
25
+ execute_shell_command(line)
28
26
  end
29
- rescue Interrupt
30
- close
31
27
  end
32
28
  end
33
29
 
34
30
  # NOTE: this should probably be private, but making it public allowed
35
31
  # for easier testing without having to deal with mocking readline. Can we
36
32
  # find a better way?
37
- def execute_shell_command(line)
38
- Retscli::ShellCommands.start(split_line(line), :display_adapter => @display_adapter)
33
+ def execute_shell_command(line, out=$stdout)
34
+ begin
35
+ Retscli::ShellCommands.start(split_line(line), :display_adapter => @display_adapter)
36
+ rescue => e
37
+ out.puts @colorer.set_color(e.message, :red)
38
+ end
39
39
  end
40
40
 
41
41
  private
@@ -86,7 +86,13 @@ module Retscli
86
86
 
87
87
  def close
88
88
  system('stty', @stty_save)
89
- @client.logout
89
+
90
+ begin
91
+ @client.logout
92
+ rescue => e
93
+ puts @colorer.set_color(e.message, :red)
94
+ end
95
+
90
96
  exit
91
97
  end
92
98
  end
@@ -17,6 +17,11 @@ module Retscli
17
17
  all_commands.keys.map{ |command| command.gsub('_', '-') }
18
18
  end
19
19
 
20
+ desc 'login', 'Re-Login to RETS server. Use if session is no longer valid'
21
+ def login
22
+ puts @display_adapter.login
23
+ end
24
+
20
25
  desc 'capabilities', 'Display capabilities for rets server'
21
26
  def capabilities
22
27
  @display_adapter.page(@display_adapter.capabilities)
@@ -97,5 +102,24 @@ module Retscli
97
102
  end
98
103
 
99
104
  map 'search-metadata' => :search_metadata
105
+
106
+ desc 'search [RESOURCE] [CLASS] [QUERY]', 'Search resources, e.g. properties, open houses, etc.'
107
+ method_option :limit, :aliases => '-l', :desc => 'limit', :type => :numeric, :default => 20
108
+ method_option :offset, :aliases => '-o', :desc => 'Offset', :type => :numeric
109
+ method_option :count, :aliases => '-c', :desc => 'Return result count', :type => :boolean, :default => false
110
+ method_option :select, :aliases => '-s', :desc => 'Select specific fields from records', :type => :array, :default => []
111
+ method_option :format, :aliases => '-f', :desc => 'Rets data return format', :enum => ['COMPACT', 'COMPACT-DECODED', 'STANDARD-XML'], :default => 'COMPACT-DECODED'
112
+ def search(resource, klass, query)
113
+ search_options = {
114
+ :limit => options[:limit],
115
+ :offset => options[:offset],
116
+ :count => options[:count],
117
+ :select => options[:select],
118
+ :format => options[:format]
119
+ }
120
+
121
+ results = @display_adapter.search(resource, klass, query, search_options)
122
+ @display_adapter.page(results)
123
+ end
100
124
  end
101
125
  end
@@ -1,3 +1,3 @@
1
1
  module Retscli
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: retscli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ari Summer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-04-12 00:00:00.000000000 Z
11
+ date: 2016-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rets
@@ -117,6 +117,8 @@ extensions: []
117
117
  extra_rdoc_files: []
118
118
  files:
119
119
  - ".gitignore"
120
+ - ".travis.yml"
121
+ - CHANGELOG.md
120
122
  - Gemfile
121
123
  - LICENSE.txt
122
124
  - README.md