Class: Swivel::Connection
- Inherits:
-
Object
- Object
- Swivel::Connection
- Defined in:
- lib/swivel.rb
Defined Under Namespace
Classes: Config
Constant Summary collapse
- @@calls =
[]
Instance Attribute Summary collapse
-
#config ⇒ Object
Returns the value of attribute config.
-
#disable_auto_refresh ⇒ Object
Returns the value of attribute disable_auto_refresh.
Class Method Summary collapse
Instance Method Summary collapse
-
#call(path, params = Hash.new, method = :get, extra_headers = Hash.new) ⇒ Object
Call Swivel’s REST endpoint.
- #call!(*args) ⇒ Object
-
#create_graph(options = Hash.new, persist = false) ⇒ Object
Lets you create a transient graph in Swivel.
-
#initialize(options = Hash.new) ⇒ Connection
constructor
Instantiate a connection to Swivel.
- #inspect ⇒ Object
- #log(str) ⇒ Object
- #name_with_prefix(prefix, name) ⇒ Object
-
#requestify(parameters, prefix = nil) ⇒ Object
copied verbatim from actioncontroller::integration::session.
-
#upload!(options = Hash.new) ⇒ Object
(also: #create_data_set)
Performs an upload, append, or replace to a data_set in Swivel.
Constructor Details
#initialize(options = Hash.new) ⇒ Connection
Instantiate a connection to Swivel. Use the connection to query or upload, append, or replace data. Passed in options will take precedence over values set in ~/.swivelrc.
693 694 695 696 697 698 |
# File 'lib/swivel.rb', line 693 def initialize = Hash.new @config = Config::DEFAULT_CONFIG.clone @config.merge! @headers = [:headers] || Hash.new @headers.merge! 'Accept' => 'application/xml' end |
Instance Attribute Details
#config ⇒ Object
Returns the value of attribute config.
687 688 689 |
# File 'lib/swivel.rb', line 687 def config @config end |
#disable_auto_refresh ⇒ Object
Returns the value of attribute disable_auto_refresh.
687 688 689 |
# File 'lib/swivel.rb', line 687 def disable_auto_refresh @disable_auto_refresh end |
Class Method Details
.reset_calls! ⇒ Object
709 710 711 |
# File 'lib/swivel.rb', line 709 def self.reset_calls! @@calls = [] end |
Instance Method Details
#call(path, params = Hash.new, method = :get, extra_headers = Hash.new) ⇒ Object
Call Swivel’s REST endpoint. This method actually performs the HTTP stuff that you need. and returns objects constructed from the returned XML. If an appropriate class is not available, just returns the XML string.
# returns an object that's a subclass of Swivel::Response
user = swivel.call '/users/1000010'
user.class # => Swivel::User
users = swivel.call '/users'
users.class # => Swivel::List
# returns a string (because an appropriate Swivel::Response subclass doesn't exist)
echo = swivel.call '/test/echo/howdy'
echo.class # => String
However, calling all of those endpoints is tedious. For swivel’s main objects there are some helper methods to get stuff:
data_set = swivel.data_set 1
data_set.class # => Swivel::DataSet
data_set.id # => 1
data_sets = swivel.data_sets
some_graph = swivel.graph 1232132
pwn3r = swivel.user 'visnu'
pwn3r.name # => 'visnu'
All these convenience methoods (yeah, methoods) really do is prettify a get call to:
/object_type or /object_type/id
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 |
# File 'lib/swivel.rb', line 745 def call path, params = Hash.new, method = :get, extra_headers = Hash.new path, query_string = path.split("?") params = requestify(params) query_string += "&" if params and query_string params = "#{query_string}#{params}" path = "/#{config[:path_prefix]}#{path}" unless config[:path_prefix].blank? response = nil elapsed_time = Benchmark.realtime do response = Net::HTTP.start config[:host], config[:port] do |http| request_class = "Net::HTTP::#{method.to_s.camelize}".constantize if [:delete, :post, :put].include? method request = request_class.new path, headers.merge(extra_headers) http.read_timeout = config[:timeout_up] http.request request, params else request = request_class.new "#{path}?#{params}", headers.merge(extra_headers) http.read_timeout = config[:timeout_down] http.request request end end end @@calls << {:url => path, :time => elapsed_time} body = response.body log "#{config[:host]}:#{config[:port]}/#{path}" log body case response.content_type when 'application/xml' doc = REXML::Document.new body if doc.root.elements[1].name.downcase == 'list' h = CobraVsMongoose.xml_to_hash body h = h["response"] if h["response"] resource = h['list']['@resource'] count = h['list']['@count'] total = h['list']['@total'] h = h['list'][resource] h ||= [] List.new nil, self, h, resource, count, total # 2c) enables rails ActiveRecord::Base#to_xml style lists (at root) elsif doc.root.elements.to_a.size == 1 and doc.root.elements[1].attributes['type'] == 'array' h = CobraVsMongoose.xml_to_hash body h = h["response"] if h["response"] list_name = doc.root.elements[1].name member_name = (h[list_name].keys.find{|k| !/^@/.match(k) } || list_name.singularize) list = h[list_name][member_name] || [] list = [list] unless list.is_a?(Array) total = (doc.root.attributes['total'].to_i rescue list.size) # hack to get the gem to parse all array types correctly hack_list = list.map{|i| {member_name => i}} Swivel::List.new nil, @connection, hack_list, member_name, list.size, total else Response.class_for(doc.root.elements[1].name).new body, self, nil end when 'text/csv', 'text/plain' body else raise "Unknown content type: #{response.content_type}" end rescue Exception => e #xml.blank? ? nil : xml warn "Failure while communicating with swivel" warn "Request: #{config[:host]}:#{config[:port]}#{path}" warn "Response: #{body}" raise e end |
#call!(*args) ⇒ Object
816 817 818 819 820 |
# File 'lib/swivel.rb', line 816 def call! *args returning call(*args) do |r| r.raise if Swivel::Error === r end end |
#create_graph(options = Hash.new, persist = false) ⇒ Object
Lets you create a transient graph in Swivel.
If you pass in options => true, your transient graph will be immediately saved.
# build a transient graph, then save it.
transient_graph = swivel.create_graph {...}
graph = transient_graph.save
# a faster way of doing the same thing.
graph = swivel.create_graph {...}.merge(:save => 'true')
Transient graphs exist in Swivel so you can cheaply play around with different visualizations, without saving them to Swivel’s database. The idea is to let you quickly create visualizations and discard the duds and keep the gems. So, create graphs with impunity! And just save the ones you like.
From an object perspective, the big differences between transient and persistent graphs are:
transient_graph = swivel.create_graph {...}
# transient graphs do not have ids. thus, they are not accessible
# at their own page at swivel.com.
transient_graph.id # => nil
# transient graphs have a 'transient' variant
transient_graph.variant # => 'transient'
# transient graphs have digests whereas persisted graphs do not.
# digests act as a unique identifier for transient graphs. e.g.,
# you'd use the digest to build urls to the transient graph's image.
transient_graph.digest.blank? # => false
transient_graph.image_url.blank? # => false
Please don’t save transient graphs you don’t want to end up keeping around. It’s the most environmentally friendly thing to do.
required parameters
-
-
LineGraph, BarGraph, HorizontalBarGraph, PieGraph, or ScatterGraph
-
– TODO: that sucks. i want: line, bar, hbar, pie, scatter, spark ++
optional parameters
-
options a comma separated list of join data_column ids
-
options a comma separated list of group by data_column ids
-
options aggregation functions for group_by_columns. one of: AvgFunction, ConcatFunction, MaxFunction, MinFunction, SumFunction, CountFunction, DistinctCountFunction
-
options a comma separated list of order-by data_column ids
-
options which sort to apply to the order_by_column. one of: ASC, DESC, ALPHABETICAL, UNSORTED
-
options time-scale of your X-axis, if applicable. one of: YEARLY, QUARTERLY, MONTHLY, WEEKLY, DAILY, HOURLY, BY_MINUTE, BY_SECOND
-
options time-range of your X-axis, if applicable. Swivel understands many human readable date/time formats. Examples: “3 years ago to now”, “1 month”, “1992-2004”.
-
options y-scale of the graph you’re creating, if applicable. one of: ABSOLUTE, AVERAGE, RANGE, RELATIVE, PERCENT
1015 1016 1017 1018 1019 1020 1021 1022 |
# File 'lib/swivel.rb', line 1015 def create_graph = Hash.new, persist = false .merge! :save => 'true' if persist unless .has_key? :order_by_column .merge! :order_by_column => [:columns].split(',').first, :order_by_direction => 'DESC' end call '/graphs', , :post end |
#inspect ⇒ Object
700 701 702 |
# File 'lib/swivel.rb', line 700 def inspect super.sub /:api_key=>"[^"]*"/, ':api_key=>[FILTERED]' end |
#log(str) ⇒ Object
822 823 824 825 826 827 828 829 830 |
# File 'lib/swivel.rb', line 822 def log str unless config[:logfile] == nil unless @logger @logger = Logger.new(config[:logfile]) @logger.level = Logger::INFO end @logger.info(str) end end |
#name_with_prefix(prefix, name) ⇒ Object
1039 1040 1041 |
# File 'lib/swivel.rb', line 1039 def name_with_prefix(prefix, name) prefix ? "#{prefix}[#{name}]" : name.to_s end |
#requestify(parameters, prefix = nil) ⇒ Object
copied verbatim from actioncontroller::integration::session
1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 |
# File 'lib/swivel.rb', line 1026 def requestify(parameters, prefix=nil) if Hash === parameters return nil if parameters.empty? parameters.map { |k,v| requestify(v, name_with_prefix(prefix, k)) }.join("&") elsif Array === parameters parameters.map { |v| requestify(v, name_with_prefix(prefix, "")) }.join("&") elsif prefix.nil? parameters else "#{CGI.escape(prefix)}=#{CGI.escape(parameters.to_s)}" end end |
#upload!(options = Hash.new) ⇒ Object Also known as: create_data_set
Performs an upload, append, or replace to a data_set in Swivel.
# upload a file to swivel
data_set = swivel.upload {...}
In order to upload, append, or replace, you must have a valid api key. Get a Swivel API key.
# append to a data_set already in Swivel
more_data = `cat /tmp/more.csv`
data_set = swivel.append {:data => more_data}.merge(:id => data_set_id)
# replace underlying data in a data_set that already exists on Swivel
new_data = `cat /tmp/new.csv`
data_set = swivel.replace {:data => new_data}.merge(:id => data_set_id)
In order to append or replace a data_set, you must be the owner of the data. The new data must conform to the same column structure as the original data.
required parameters
-
options - data_set id that you want to append/replace. (append, replace only)
-
options - name for the data_set. (upload only)
-
options - citation for the data_set. e.g., U.N. (upload only)
-
options - a string of actual csv data. when appending or replacing data, a header row is optional. (upload, append, and replace)
-
options - tags for the data_set (upload only)
optional parameters (upload only; not for append or replace)
-
options - description for the data_set
-
options - when true, swivel tries to figure out the column names, column types, and column separator character automatically from the csv data. when missing or false, you must also supply options, options, and options.
-
options - a comma-separated string of column names. only send this option when auto_estimate is missing or false.
-
options - a comma-separated string of column types. possible types are DateTimeDataColumn, BooleanDataColumn, CurrencyDataColumn, NumberDataColumn, WholeNumberDataColumn, PercentageDataColumn, TextDataColumn. only send this option when auto_estimate is missing or false.
-
options - a character. usually a ‘,’. only send this option when auto_estimate is false.
-
options - a url to an image you’d like to associate with your data_set.
-
options - a url to the source for your image, for proper attribution.
A few limitations since swivel.rb is yet nascent and in its formative days.
-
You must post data as a string of text.
-
Actually, that’s it, I think.
911 912 913 914 915 916 917 918 919 920 921 922 923 924 |
# File 'lib/swivel.rb', line 911 def upload! = Hash.new opts = .clone opts[:mode] ||= 'initial' uri, method = case opts[:mode] when 'append', 'replace' ["/data_sets/#{opts[:id]}", :put] else opts.reverse_merge! DEFAULT_UPLOAD_OPTIONS ['/data_sets', :post] end call! uri, opts, method end |