rviki 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ == 2012-04-10 14:00:00 +0000 Nia M <nia@viki.com>
2
+
3
+ * Created rviki
@@ -0,0 +1,34 @@
1
+ # RViki readme
2
+
3
+
4
+ RViki is a Ruby client gem for Viki.com API.
5
+
6
+
7
+ ## Usage
8
+
9
+ ### Client Request
10
+
11
+ v = RViki::Client.new
12
+ v.shows
13
+ v.shows(language_code: "en")
14
+ v.shows(id: 50)
15
+ v.shows(id: 50, language_code: "es")
16
+
17
+ ### Print Utilities
18
+
19
+ vpr = RViki::Printer.new([:clipboard, :stdout])
20
+ vpr.object = v.shows.parsed_response["films"]
21
+ vpr.tabular
22
+ vpr.pretty_ruby
23
+ vpr.pretty_json
24
+
25
+ Clipboard output is only for Mac, for now.
26
+
27
+ ### Woot! Command Line!
28
+
29
+ $ rviki shows
30
+ $ rviki shows_item 50
31
+ $ rviki shows_item 50 es
32
+ $ rviki shows -f pretty_json 50
33
+ $ rviki shows -o clipboard,stdout 50
34
+
@@ -0,0 +1,36 @@
1
+ begin
2
+ require "rubygems"
3
+ require "bundler"
4
+ rescue LoadError
5
+ raise "Could not load the bundler gem. Install it with `gem install bundler`."
6
+ end
7
+
8
+ if Gem::Version.new(Bundler::VERSION) <= Gem::Version.new("1.0.0")
9
+ raise RuntimeError, "Your bundler version is too old for Mail" +
10
+ "Run `gem install bundler` to upgrade."
11
+ end
12
+
13
+ begin
14
+ # Set up load paths for all bundled gems
15
+ ENV["BUNDLE_GEMFILE"] = File.expand_path("../Gemfile", __FILE__)
16
+ Bundler.setup
17
+ rescue Bundler::GemNotFound
18
+ raise RuntimeError, "Bundler couldn't find some gems." +
19
+ "Did you run `bundle install`?"
20
+ end
21
+
22
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
23
+
24
+ require 'rspec/core/rake_task'
25
+ RSpec::Core::RakeTask.new(:spec)
26
+ task :default => :spec
27
+
28
+ require "rviki/version"
29
+
30
+ task :build do
31
+ system "gem build rviki.gemspec"
32
+ end
33
+
34
+ task :release => :build do
35
+ system "gem push rviki-#{RViki::VERSION::STRING}"
36
+ end
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require "pathname"
5
+ bin_file = Pathname.new(__FILE__).realpath
6
+ $:.unshift File.expand_path("../lib", bin_file)
7
+
8
+ require "rviki/cli"
9
+ cli = RViki::Cli.new
10
+ cli.execute(*ARGV)
11
+ rescue Interrupt
12
+ `stty icanon echo`
13
+ puts("\n ! Command cancelled.")
14
+ end
15
+
@@ -0,0 +1,4 @@
1
+ major:0
2
+ minor:0
3
+ patch:1
4
+ build:
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+ module RViki
3
+ require 'pp'
4
+ require 'json'
5
+ require 'httparty'
6
+ require 'rviki/version'
7
+ require 'rviki/routable'
8
+ require 'rviki/client'
9
+ require 'rviki/printer'
10
+ end
@@ -0,0 +1,138 @@
1
+ # encoding: utf-8
2
+
3
+ require 'optparse'
4
+ require 'rviki'
5
+
6
+ module RViki
7
+ module Registrable
8
+ def self.included(base)
9
+ base.send :extend, ClassMethods
10
+ end
11
+
12
+ module ClassMethods
13
+ def register_command(command_sym, args)
14
+ registered_commands[command_sym] = args
15
+ end
16
+
17
+ def registered_commands
18
+ @registered_commands ||= {}
19
+ end
20
+ end
21
+ end
22
+
23
+ class Cli
24
+ include Registrable
25
+
26
+ register_command :shows, [:language_code]
27
+ register_command :shows_item, [:id, :language_code]
28
+ register_command :featured, []
29
+ register_command :news, [:language_code]
30
+
31
+ register_command :channels, [:watchable_by_country, :lang_code]
32
+ register_command :channels_item, [:id, :watchable_by_country, :lang_code]
33
+ register_command :channel_videos, [:id]
34
+
35
+ register_command :posts, [:lang_code]
36
+
37
+ register_command :videos, []
38
+ register_command :video_casts, [:id]
39
+ register_command :video_parts, [:id]
40
+ register_command :video_posts, [:id]
41
+
42
+ def initialize
43
+ @client = RViki::Client.new
44
+ @printer = RViki::Printer.new([:stdout])
45
+
46
+ @print_opts_parser = OptionParser.new do |pop|
47
+ pop.banner = "Print Options:"
48
+ pop.on("-f", "--format FORMAT", [:tabular, :pretty_json, :pretty_ruby],
49
+ "Print with FORMAT (tabular (only for array), pretty_json, or pretty_ruby)") do |pf|
50
+ printer.format = pf
51
+ end
52
+
53
+ pop.on("-o", "--output clipboard,stdout", Array,
54
+ "Output to OUTPUT_TARGET (clipboard, stdout)") do |o|
55
+ o = o.map(&:to_sym)
56
+ if (o.include?(:clipboard) || o.include?(:stdout))
57
+ printer.targets = o
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ def execute(*args)
64
+ @cmd = args.shift
65
+ @cmd = @cmd.to_sym if @cmd
66
+ unless valid_command?
67
+ puts <<-EOL
68
+
69
+ Command not found: #{@cmd}
70
+ ----------------------------------------
71
+
72
+ RViki Version #{RViki::VERSION::STRING} for Viki API V2
73
+ Usage: rviki <api_endpoint> [--opt optvalue] [api_param1] [api_param2]
74
+
75
+ Available API Endpoints:
76
+ #{commands_listing}
77
+ #{print_opts_parser}
78
+
79
+ Examples:
80
+
81
+ $ rviki featured
82
+ $ rviki shows -o clipboard
83
+ $ rviki shows_item 50
84
+ $ rviki shows_item 50 es
85
+ $ rviki shows -f pretty_json 50
86
+ $ rviki shows -o clipboard,stdout 50
87
+
88
+ EOL
89
+ exit(1)
90
+ end
91
+
92
+ @cmd_args = self.class.registered_commands[@cmd]
93
+ extract_options args
94
+ response = client.send(@cmd, client_options_hash)
95
+ printer.object = response.parsed_response
96
+ printer.do_print
97
+ end
98
+
99
+ protected
100
+
101
+ attr_reader :client, :printer, :client_options, :print_opts_parser
102
+
103
+ def commands_listing
104
+ result = ""
105
+ self.class.registered_commands.each do |endpoint, params|
106
+ result += " #{endpoint}"
107
+ result += "\n params: #{params.map{|pr| "[:#{pr}]"}.join(' ')}" if params && !params.empty?
108
+ result += "\n"
109
+ end
110
+ result
111
+ end
112
+
113
+ def extract_options(args)
114
+ client_opts_i = 0
115
+ args.each_with_index do |a, i|
116
+ client_opts_i += 2 if a.start_with?("-")
117
+ end
118
+
119
+ @printer_options = args[0...client_opts_i]
120
+ print_opts_parser.parse! @printer_options
121
+ @client_options = args[client_opts_i..-1]
122
+ true
123
+ end
124
+
125
+ def client_options_hash
126
+ options = {}
127
+ client_options.each_with_index do |a, i|
128
+ options[@cmd_args[i]] = a
129
+ end
130
+ options
131
+ end
132
+
133
+ def valid_command?
134
+ @cmd && !@cmd.empty? && self.class.registered_commands.has_key?(@cmd)
135
+ end
136
+ end
137
+ end
138
+
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ module RViki
3
+ class Client
4
+ include Routable
5
+
6
+ base_uri 'http://www.viki.com/api/v2'
7
+ headers "Content-Type" => "application/json", "User-Agent" => "VikiMobile/4.0 RViki::Client"
8
+ format :json
9
+
10
+ route_get "/shows.json", as: :shows
11
+ route_get "/shows/:id.json", as: :shows_item
12
+ route_get "/featured.json", as: :featured
13
+ route_get "/news.json", as: :news
14
+
15
+ route_get "/channels.json", as: :channels
16
+ route_get "/channels/:id.json", as: :channels_item
17
+ route_get "/channel/:id/videos.json", as: :channel_videos
18
+
19
+ route_get "/posts.json", as: :posts
20
+
21
+ route_get "/videos.json", as: :videos
22
+ route_get "/videos/:id/casts.json", as: :video_casts
23
+ route_get "/videos/:id/parts.json", as: :video_parts
24
+ route_get "/videos/:id/recommended.json", as: :video_posts
25
+ end
26
+ end
27
+
@@ -0,0 +1,77 @@
1
+ # encoding: utf-8
2
+ module RViki
3
+ class Printer
4
+ attr_accessor :targets, :object, :format
5
+
6
+ def initialize(print_targets=[:stdout])
7
+ self.targets = print_targets
8
+ end
9
+
10
+ def do_print
11
+ if self.format
12
+ begin
13
+ self.send(self.format)
14
+ rescue Exception
15
+ self.pretty_json
16
+ end
17
+ else
18
+ self.pretty_json
19
+ end
20
+ end
21
+
22
+ def tabular
23
+ return unless inputs_valid?
24
+ raise "Cannot print tabular data because parsed response is not an array" unless object.is_a?(Array)
25
+
26
+ out = object.first.keys.join("\t") + "\n"
27
+ object.each { |item| out += (item.values.join("\t") + "\n") }
28
+ do_output out
29
+ end
30
+
31
+ def pretty_ruby
32
+ return unless inputs_valid?
33
+ do_output object.pretty_inspect
34
+ end
35
+
36
+ def pretty_json
37
+ return unless inputs_valid?
38
+ do_output JSON.pretty_generate(object)
39
+ end
40
+
41
+ private
42
+
43
+ def inputs_valid?
44
+ raise "Please use array of symbols as targets" unless self.targets.is_a?(Array)
45
+ if !object || object.empty?
46
+ puts "[RViki::Client -- WARNING!] List is empty. Nothing to do here."
47
+ return false
48
+ end
49
+ true
50
+ end
51
+
52
+ def do_output(out)
53
+ self.targets.each do |target|
54
+ case target
55
+ when :stdout
56
+ puts out
57
+ when :clipboard
58
+ if command?('pbcopy')
59
+ IO.popen('pbcopy', 'r+') { |cl| cl.puts out }
60
+ elsif command?('xsel')
61
+ IO.popen('xsel –clipboard –input', 'r+') { |cl| cl.puts out }
62
+ else
63
+ puts "[RViki::Client] Cannot copy to clipboard. There is no pbcopy (Mac) or xsel (Linux) installed. Please look for one of them in Google. Thanks."
64
+ end
65
+ else
66
+ puts "[RViki::Client -- WARNING!] Invalid target #{target.inspect}"
67
+ end
68
+ end
69
+ end
70
+
71
+ def command?(name)
72
+ `which #{name}`
73
+ $?.success?
74
+ end
75
+ end
76
+ end
77
+
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ module RViki
3
+ module Routable
4
+ def self.included(base)
5
+ base.send :include, HTTParty
6
+ base.send :extend, ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ def routes
11
+ @routes ||= {}
12
+ end
13
+
14
+ def route_get(route_pattern, args)
15
+ param_keys = route_pattern.scan(/:\w+/).map { |key| key[1..-1].to_sym }
16
+ api_name = args[:as]
17
+ routes[api_name] = [ route_pattern, param_keys ]
18
+
19
+ define_method(api_name) do |params={}|
20
+ request_path = route_pattern.dup
21
+ param_keys.each do |param_key|
22
+ if (value = params[param_key])
23
+ request_path.gsub!(":#{param_key}", value.to_s)
24
+ params.delete(param_key)
25
+ end
26
+ end
27
+ self.class.get(request_path, query: params)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ module RViki
3
+ module VERSION
4
+
5
+ version = {}
6
+ File.read(File.join(File.dirname(__FILE__), '../', 'VERSION')).each_line do |line|
7
+ type, value = line.chomp.split(":")
8
+ next if type =~ /^ +$/ || value =~ /^ +$/
9
+ version[type] = value
10
+ end
11
+
12
+ MAJOR = version['major']
13
+ MINOR = version['minor']
14
+ PATCH = version['patch']
15
+ BUILD = version['build']
16
+
17
+ STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
18
+
19
+ def self.version
20
+ STRING
21
+ end
22
+
23
+ end
24
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rviki
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nia M
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-17 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httparty
16
+ requirement: &70117459607260 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70117459607260
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &70117459605860 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 2.5.1
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70117459605860
36
+ - !ruby/object:Gem::Dependency
37
+ name: ZenTest
38
+ requirement: &70117459605200 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 4.5.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70117459605200
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: &70117459604300 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 0.8.7
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70117459604300
58
+ - !ruby/object:Gem::Dependency
59
+ name: bundler
60
+ requirement: &70117459602640 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: 1.0.12
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70117459602640
69
+ description: A short description
70
+ email:
71
+ - nia@viki.com
72
+ executables:
73
+ - rviki
74
+ extensions: []
75
+ extra_rdoc_files:
76
+ - README.md
77
+ - CHANGELOG
78
+ files:
79
+ - README.md
80
+ - Rakefile
81
+ - lib/rviki/cli.rb
82
+ - lib/rviki/client.rb
83
+ - lib/rviki/printer.rb
84
+ - lib/rviki/routable.rb
85
+ - lib/rviki/version.rb
86
+ - lib/rviki.rb
87
+ - lib/VERSION
88
+ - CHANGELOG
89
+ - bin/rviki
90
+ homepage: ''
91
+ licenses:
92
+ - ''
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ! '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubyforge_project:
111
+ rubygems_version: 1.8.10
112
+ signing_key:
113
+ specification_version: 3
114
+ summary: A longer summary
115
+ test_files: []