hackpad-cli 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fb3d4f67776326cac794826db144053a0e8f7e77
4
- data.tar.gz: ff10d38d124cf94e61e7dc24075ba6267f167a49
3
+ metadata.gz: ec98c6b6d399cc33172d9a3ac28928d7e55e4c7c
4
+ data.tar.gz: 02cacca94e93f019eacbb6656facde0bf6da7a77
5
5
  SHA512:
6
- metadata.gz: 6b09a50391fa3911944a0a13c50e21f7fb766a16fbc6a00d54cfebf3f1a10616c2a0728a6c84ceb5cf56585b47df2200304da83b236c6b318c72b37bcbf1b43e
7
- data.tar.gz: f06e4d88f32f0fab0dbea052cbef7b959c92ca9f93a426edb74f243590542a52d88beb39b4d95db5fc591a85f50166f21203638300324249ad0e75acb94f9948
6
+ metadata.gz: 524979fef3768413d2b37695c90282712c7fd9764e37478e7a6fff4b9704ab7db9a1b638fd152910fdb524cc443de2a4d29895d9c0ab274a42dc84ef3815b24a
7
+ data.tar.gz: a32ff357be9208fd0d85ce050c0171277719868fa06c0f57be92d5ed6e0e701cc6057d1e62c5661146896d28eddf78f6512f36424e738c168df363136b854696
data/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ repo_token: LH9PLfB9g4e8PIt5fDw06hQ2ac8ivdY48
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ cache: bundler
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.1.1
6
+
data/CHANGELOG.md CHANGED
@@ -1,26 +1,36 @@
1
1
  Hackpad-cli changelog
2
2
  ==========================
3
3
 
4
- v0.0.4 - 2014-04-01
4
+ v0.0.5 - 2014-05-04
5
5
  --------------------
6
6
 
7
- * add options in pad info for `hpcli info [pad_id]`
8
- * implement a search command `hpcli search [term]`
7
+ - add a dot-timer for when padlist refreshes so one knows that something is happening
8
+ - add an option `-u` to display urls rather than pad id
9
+ - add an option `-r` to force the refresh of the cache
10
+ - add storage of cache for pad and pad lists
11
+ - add some tests
12
+ - add a flag for removing colors `-p`
9
13
 
10
- v0.0.3 - 2014-04-01
14
+ v0.0.4 - 2014-05-01
15
+ --------------------
16
+
17
+ - add options in pad info for `hpcli info [pad_id]`
18
+ - implement a search command `hpcli search [term]`
19
+
20
+ v0.0.3 - 2014-05-01
11
21
  --------------
12
22
 
13
- * add a better way to manage alternative configuration file
14
- * fix alternate config dir setup
15
- * verify compat with ruby 1.9.3
16
- * better readme
23
+ - add a better way to manage alternative configuration file
24
+ - fix alternate config dir setup
25
+ - verify compat with ruby 1.9.3
26
+ - better readme
17
27
 
18
- v0.0.2 - 2014-04-01
28
+ v0.0.2 - 2014-05-01
19
29
  ---------------
20
30
 
21
- * damn, forgot to remove awesome_print. huhu
31
+ - damn, forgot to remove awesome_print. huhu
22
32
 
23
- v0.0.1 - 2014-04-01
33
+ v0.0.1 - 2014-05-01
24
34
  ------------------------
25
35
 
26
- * initial release of a draft
36
+ - initial release of a draft
data/README.md CHANGED
@@ -1,13 +1,21 @@
1
1
  Hackpad-Cli
2
2
  ===================
3
3
 
4
+ [![Gem Version](https://badge.fury.io/rb/hackpad-cli.png)](http://rubygems.org/gems/hackpad-cli)
5
+ [![Build Status](https://travis-ci.org/mose/hackpad-cli.png?branch=master)](https://travis-ci.org/mose/hackpad-cli)
6
+ [![Coverage Status](https://coveralls.io/repos/mose/hackpad-cli/badge.png)](https://coveralls.io/r/mose/hackpad-cli)
7
+ [![Dependency Status](https://gemnasium.com/mose/hackpad-cli.svg)](https://gemnasium.com/mose/hackpad-cli)
8
+ [![Code Climate](https://codeclimate.com/github/mose/hackpad-cli.png)](https://codeclimate.com/github/mose/hackpad-cli)
9
+
10
+ ----
11
+
4
12
  This is a command-line utility to check and manipulate hackpad documents.
5
13
  It uses Hackpad REST API 1.0 https://hackpad.com/fQD2DRz22Wf and was tested with ruby 1.9.3 and 2.1.1.
6
14
 
7
15
  Initially this tool was created to overcome the frustration of the md export of pads,
8
- because we need to copy them to other places sometimes. Proper markdown would be appreciated.
16
+ because we need to copy them to other places sometimes. Proper markdown would be appreciated. It does that by transforming the html in markdown with the https://github.com/xijo/reverse_markdown gem.
9
17
 
10
- So for now, it does that, by transforming the html in markdown with the https://github.com/xijo/reverse_markdown gem.
18
+ Then it felt right to cache the pads content and list because then we can browse and search in the whole workspace very fast. So by default the `list`, `show` and `info` are cached unless you pass the `-r` option at the end of the commandline. Note that the longest is the `list` because the API don't provide pads titles, so `hpcli list` actually downloads the whole list of the pads in txt format. But it makes the `info` and the `show` very fast after that.
11
19
 
12
20
  Installation
13
21
  ------------------
@@ -25,11 +33,24 @@ Usage
25
33
 
26
34
  (use `bundle exec` if you need, mostly in clone mode when not using rvm)
27
35
 
28
- hpcli # will show help
29
- hpcli list # gets a list of pads you have access to
30
- hpcli get <pad_id> md # will spit out the content in nice markdown
31
- # and you can use alternate config
32
- hpcli list -w alt
36
+ ```
37
+ Commands:
38
+ hpcli help [COMMAND] # Describe available commands or one specific command
39
+ hpcli info [pad_id] # gets info for the pad <pad_id>.
40
+ hpcli list # Lists available pads.
41
+ hpcli search [term] # Lists available pads matching [term].
42
+ hpcli show [pad_id] [format] # shows pad <pad_id> in format [html,txt,md] (default txt).
43
+ hpcli version # Displays the hackpad-cli version.
44
+
45
+ Options:
46
+ -c, [--configdir=CONFIGDIR] # Path to the hackpad-cli directory to use.
47
+ # Default: /home/mose/.hackpad-cli/
48
+ -w, [--workspace=WORKSPACE] # Name of the workspace to use.
49
+ # Default: default
50
+ -r, [--refresh], [--no-refresh] # Add this if you want refresh the cache.
51
+ -u, [--urls], [--no-urls] # Displays urls rather than pad ids.
52
+ -p, [--plain], [--no-plain] # Add this if you don't want colors.
53
+ ```
33
54
 
34
55
  At first launch it will create your config dir (default ~/.hackpad-cli/), and will ask you questions to create the config file (default is .. default.yml). If you pass the `-w whatever` option at the end, it will ask questions again to write whatever.yml config file.
35
56
 
@@ -39,20 +60,24 @@ Roadmap and todoz
39
60
 
40
61
  Check the [Changelog](CHANGELOG.md) for past evolutions.
41
62
 
42
- * cache the pads list in a local storage
43
- * refresh cache according to last cached date
44
- * add commands for creating a new pad, linked to $EDITOR
45
- * add admin commands for managing users
46
- * nag hackpad for they add REST endpoints to query collections
47
- * write proper tests
48
- * add freaking cool badges on the readme
49
- * add a gateway to github so a pad could be copied over a wiki page directly or in a repo somehow
50
- * implement pretty much all what the hackpad API v1 offers
63
+ - for v0.1.0
64
+ - <s>add freaking cool badges on the readme</s>
65
+ - <s>cache the pads list in a local storage</s>
66
+ - <s>have a choice to refresh cache</s>
67
+ - display cached date in output
68
+ - write proper tests
69
+ - for v0.2.0
70
+ - add commands for creating a new pad, linked to $EDITOR
71
+ - add a gateway to github so a pad could be copied over a wiki page directly or in a repo somehow
72
+ - for v0.3.0
73
+ - add admin commands for managing users
74
+ - implement pretty much all what the hackpad API v1 offers
75
+ - nag hackpad for they add REST endpoints to query collections
51
76
 
52
77
  Contributing
53
78
  ------------------
54
79
 
55
- 1. Fork it ( http://github.com/<my-github-username>/hackpad-cli/fork )
80
+ 1. Fork it
56
81
  2. Create your feature branch (`git checkout -b my-new-feature`)
57
82
  3. Commit your changes (`git commit -am 'Add some feature'`)
58
83
  4. Push to the branch (`git push origin my-new-feature`)
data/Rakefile CHANGED
@@ -1 +1,20 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ require 'bundler/setup'
1
8
  require "bundler/gem_tasks"
9
+ require "rake/testtask"
10
+ require "rspec/core/rake_task" # RSpec 2.0
11
+
12
+ desc "launch rspec tests"
13
+ task :spec do
14
+ RSpec::Core::RakeTask.new(:spec) do |t|
15
+ t.rspec_opts = ["-c", "-f progress", "-r ./spec/spec_helper.rb"]
16
+ t.pattern = 'spec/lib/**/*_spec.rb'
17
+ end
18
+ end
19
+
20
+ task :default => :spec
data/bin/hpcli CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative "../lib/hackpad/cli"
3
+ require_relative "../lib/hackpad/cli/runner"
4
4
 
5
- Hackpad::Cli.start
5
+ Hackpad::Cli::Runner.start
data/hackpad-cli.gemspec CHANGED
@@ -25,4 +25,7 @@ Gem::Specification.new do |spec|
25
25
 
26
26
  spec.add_development_dependency "bundler", "~> 1.5"
27
27
  spec.add_development_dependency "rake"
28
+ spec.add_development_dependency "rspec"
29
+ spec.add_development_dependency "webmock"
30
+ spec.add_development_dependency "coveralls"
28
31
  end
@@ -0,0 +1,60 @@
1
+ require 'oauth'
2
+ require 'net/http'
3
+ require 'json'
4
+
5
+ module Hackpad
6
+ module Cli
7
+
8
+ class ApiException < StandardError
9
+ end
10
+
11
+ module Api
12
+ extend self
13
+
14
+ def prepare(config)
15
+ site = URI.parse config['site']
16
+ consumer = OAuth::Consumer.new(
17
+ config['client_id'],
18
+ config['secret'],
19
+ site: config['site']
20
+ )
21
+ @token = OAuth::AccessToken.new consumer
22
+ end
23
+
24
+ def search(term, start=0)
25
+ get "/api/1.0/search?q=#{CGI.escape term}&start=#{start}&limit=100"
26
+ end
27
+
28
+ def list
29
+ get "/api/1.0/pads/all"
30
+ end
31
+
32
+ def title(id)
33
+ show(id, 'txt').lines.first
34
+ end
35
+
36
+ def read_options(id)
37
+ get "/api/1.0/pad/#{id}/options"
38
+ end
39
+
40
+ def read(id, ext)
41
+ get "/api/1.0/pad/#{id}/content.#{ext}", false
42
+ end
43
+
44
+ def get(url, json=true)
45
+ res = @token.get url
46
+ if res.is_a? Net::HTTPSuccess
47
+ puts res.body.inspect if ENV['DEBUG']
48
+ if json
49
+ JSON.parse res.body
50
+ else
51
+ res.body
52
+ end
53
+ else
54
+ raise ApiException, "HTTP error, code #{res.code}"
55
+ end
56
+ end
57
+
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,79 @@
1
+ require 'reverse_markdown'
2
+ require 'colorize'
3
+
4
+ require_relative 'config'
5
+ require_relative 'api'
6
+ require_relative 'store'
7
+ require_relative 'pad'
8
+ require_relative 'padlist'
9
+
10
+ module Hackpad
11
+ module Cli
12
+ class Client
13
+
14
+ def initialize(options)
15
+ @options = options
16
+ Store.prepare @options
17
+ @config = Config.load @options
18
+ Api.prepare @config
19
+ if @options[:plain]
20
+ load File.expand_path('../plain_colors.rb', __FILE__)
21
+ end
22
+ end
23
+
24
+ # GET /api/1.0/pads/all
25
+ def search(term,start=0)
26
+ payload = Api.search(term,start)
27
+ payload.each do |a|
28
+ puts "#{(@config['site'] + '/') if @options['urls']}#{a['id'].bold} - #{unescape(a['title']).yellow}"
29
+ puts " #{extract a['snippet']}"
30
+ end
31
+ end
32
+
33
+ def list
34
+ padlist = Padlist.new @options['refresh']
35
+ puts padlist.all.map { |pad|
36
+ "#{(@config['site'] + '/') if @options['urls']}#{pad.id} - #{pad.title}"
37
+ }
38
+ end
39
+
40
+ def info(id)
41
+ pad = Pad.new id
42
+ pad.load 'txt'
43
+ table "Id", "#{id}".bold
44
+ table "Title", "#{pad.title}".yellow
45
+ table "URI", "#{@config['site']}/#{id}"
46
+ table "Chars", "#{pad.chars}"
47
+ table "Lines", "#{pad.lines}"
48
+ table "Guest Policy", "#{pad.guest_policy}"
49
+ table "Moderated", "#{pad.moderated}"
50
+ end
51
+
52
+ def show(id,format)
53
+ ext = (format == 'md') ? 'html' : format
54
+ pad = Pad.new id
55
+ pad.load ext
56
+ if format == 'md'
57
+ puts ReverseMarkdown.convert(pad.content, github_flavored: true)
58
+ else
59
+ puts pad.content
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def unescape(s)
66
+ CGI.unescapeHTML s
67
+ end
68
+
69
+ def extract(s)
70
+ unescape(s).gsub(/<b class="hit">([^<]*)<\/b>/) { |e| $1.cyan.bold }
71
+ end
72
+
73
+ def table(key,value)
74
+ printf "%-20s %s\n", key, value
75
+ end
76
+
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,42 @@
1
+ module Hackpad
2
+ module Cli
3
+ module Config
4
+ extend self
5
+
6
+ def load(options)
7
+ configdir = options[:configdir]
8
+ configfile = File.join(configdir, "#{options[:workspace]}.yml")
9
+ # temporary migration path
10
+ if !File.exists?(configfile) && File.exists?(File.join(configdir, "config.yml"))
11
+ FileUtils.mv File.join(configdir, "config.yml"), configfile
12
+ end
13
+ if !Dir.exists?(configdir) || !File.exists?(configfile)
14
+ setup configfile
15
+ end
16
+ YAML::load_file configfile
17
+ end
18
+
19
+ private
20
+
21
+ def setup(configfile)
22
+ config = {}
23
+ FileUtils.mkdir_p File.dirname(configfile)
24
+ puts "We need first to initialize your hackpad-cli configuration.".blue
25
+ puts "Please gather your information from https://<subdomain>.hackpad.com/ep/account/settings/".light_blue
26
+ print "What is your Client ID? "
27
+ STDOUT.flush
28
+ config['client_id'] = STDIN.gets.chomp
29
+ print "What is your Secret Key? "
30
+ STDOUT.flush
31
+ config['secret'] = STDIN.gets.chomp
32
+ print "What is the URI of your pad? "
33
+ STDOUT.flush
34
+ config['site'] = STDIN.gets.chomp
35
+ File.open(configfile, "w") do |f|
36
+ f.write YAML::dump(config)
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,52 @@
1
+ require_relative "store"
2
+ require_relative "api"
3
+
4
+ module Hackpad
5
+ module Cli
6
+ class UndefinedPad < StandardError
7
+ end
8
+ class UnknownFormat < StandardError
9
+ end
10
+
11
+ class Pad
12
+
13
+ attr_reader :id, :content, :guest_policy, :moderated
14
+
15
+ def initialize(id)
16
+ @id = id
17
+ end
18
+
19
+ def title
20
+ @title ||= (@content.lines.first.strip if @content)
21
+ end
22
+
23
+ def chars
24
+ @content.length if @content
25
+ end
26
+
27
+ def lines
28
+ @content.lines.count if @content
29
+ end
30
+
31
+ def load(ext, refresh=false)
32
+ raise UnknownFormat unless FORMATS.include? ext
33
+ raise UndefinedPad unless @id
34
+ if refresh or !Store.exists? ext, id
35
+ @content = Api.read id, ext
36
+ Store.save self, ext
37
+ options = Api.read_options id
38
+ @guest_policy = options['guestPolicy']
39
+ @moderated = !!options['isModerated']
40
+ Store.save_meta @id, options
41
+ else
42
+ @content = Store.read id, ext
43
+ options = Store.read_options id
44
+ @guest_policy = options['guestPolicy']
45
+ @moderated = !!options['isModerated']
46
+ end
47
+ end
48
+
49
+ end
50
+ end
51
+ end
52
+
@@ -0,0 +1,32 @@
1
+ require_relative "store"
2
+ require_relative "api"
3
+ require_relative "pad"
4
+
5
+ module Hackpad
6
+ module Cli
7
+ class Padlist
8
+
9
+ attr_reader :all
10
+
11
+ def initialize(refresh=false)
12
+ if refresh or !Store.exists? "padlist"
13
+ print "Refreshing "
14
+ list = Api.list
15
+ @all = []
16
+ list.each do |a|
17
+ print "."
18
+ pad = Pad.new a
19
+ pad.load 'txt', refresh
20
+ @all << OpenStruct.new( id: a, title: pad.title )
21
+ end
22
+ puts " all done."
23
+ Store.save_list all
24
+ else
25
+ @all = Store.read_list
26
+ end
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+
@@ -0,0 +1,5 @@
1
+ class String
2
+ def colorize(params)
3
+ self
4
+ end
5
+ end
@@ -0,0 +1,74 @@
1
+ require "thor"
2
+ require "yaml"
3
+ require_relative "client"
4
+ require_relative "version"
5
+
6
+ module Hackpad
7
+ module Cli
8
+ class Runner < Thor
9
+
10
+ class_option :configdir,
11
+ aliases: "-c",
12
+ default: File.join(ENV["HOME"], ".hackpad-cli/"),
13
+ desc: "Path to the hackpad-cli directory to use."
14
+
15
+ class_option :workspace,
16
+ aliases: "-w",
17
+ default: "default",
18
+ desc: "Name of the workspace to use."
19
+
20
+ class_option :refresh,
21
+ aliases: "-r",
22
+ type: 'boolean',
23
+ default: false,
24
+ desc: "Add this if you want refresh the cache."
25
+
26
+ class_option :urls,
27
+ aliases: "-u",
28
+ type: 'boolean',
29
+ default: false,
30
+ desc: "Displays urls rather than pad ids."
31
+
32
+ class_option :plain,
33
+ aliases: "-p",
34
+ type: 'boolean',
35
+ default: false,
36
+ desc: "Add this if you don't want colors."
37
+
38
+ default_task :help
39
+
40
+ desc "search [term]", "Lists available pads matching [term]."
41
+ def search(term)
42
+ Hackpad::Cli::Client.new(options).search term
43
+ end
44
+
45
+ desc "list", "Lists available pads."
46
+ def list
47
+ Hackpad::Cli::Client.new(options).list
48
+ end
49
+
50
+ desc "info [pad_id]", "gets info for the pad <pad_id>."
51
+ def info(pad)
52
+ Hackpad::Cli::Client.new(options).info pad
53
+ end
54
+
55
+ desc "show [pad_id] [format]", "shows pad <pad_id> in format [html,txt,md] (default txt)."
56
+ def show(pad,format='txt')
57
+ Hackpad::Cli::Client.new(options).show pad, format
58
+ end
59
+
60
+ desc "version", "Displays the hackpad-cli version."
61
+ def version
62
+ puts Hackpad::Cli::VERSION
63
+ end
64
+
65
+
66
+ desc "colors", "displays colorize color matrix.", hide: true
67
+ def colors
68
+ require 'colorize'
69
+ String.color_matrix ' xoxo '
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,62 @@
1
+ require 'json'
2
+ require_relative '../cli'
3
+
4
+ module Hackpad
5
+ module Cli
6
+ module Store
7
+ extend self
8
+
9
+ def prepare(config)
10
+ @refresh = config['refresh']
11
+ @dir = File.join(config['configdir'], config['workspace'])
12
+ @pads_dir = File.join(@dir, 'pads')
13
+ @list_cache = File.join(@dir, 'pads.list')
14
+ FileUtils.mkdir_p @dir unless Dir.exists?(@dir)
15
+ (Hackpad::Cli::FORMATS + ['meta']).each { |f| FileUtils.mkdir_p File.join(@pads_dir, f) }
16
+ end
17
+
18
+ def exists?(*path)
19
+ !@refresh && File.exists?(File.join(@pads_dir, *path))
20
+ end
21
+
22
+ def save(pad, ext)
23
+ File.open(File.join(@pads_dir, ext, pad.id), 'w') do |f|
24
+ f.puts pad.content
25
+ end
26
+ end
27
+
28
+ def save_meta(id, options)
29
+ File.open(File.join(@pads_dir, 'meta', id), 'w') do |f|
30
+ f.puts JSON.pretty_generate(options)
31
+ end
32
+ end
33
+
34
+ def save_list(pads)
35
+ File.open(File.join(@pads_dir, 'padlist'), 'w') do |f|
36
+ pads.each do |p|
37
+ f.puts "#{p.id} #{p.title}"
38
+ end
39
+ end
40
+ end
41
+
42
+ def read(id, ext)
43
+ file = File.join(@pads_dir, ext, id)
44
+ File.read(file)
45
+ end
46
+
47
+ def read_options(id)
48
+ file = File.join(@pads_dir, 'meta', id)
49
+ JSON.parse File.read(file)
50
+ end
51
+
52
+ def read_list
53
+ File.read(File.join(@pads_dir, 'padlist')).lines.reduce([]) { |a,line|
54
+ /(?<id>[a-zA-Z0-9]*) (?<title>.*)/ =~ line
55
+ a << OpenStruct.new( id: id, title: title )
56
+ a
57
+ }
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -1,7 +1,5 @@
1
- require "thor"
2
-
3
1
  module Hackpad
4
- class Cli < Thor
5
- VERSION = "0.0.4"
2
+ module Cli
3
+ VERSION = "0.0.5"
6
4
  end
7
5
  end
data/lib/hackpad/cli.rb CHANGED
@@ -1,44 +1,5 @@
1
- require "thor"
2
- require "colorize"
3
- require "yaml"
4
- require_relative "client"
5
-
6
1
  module Hackpad
7
-
8
- class Cli < Thor
9
-
10
- class_option :configdir,
11
- aliases: "-c",
12
- default: File.join(ENV["HOME"], ".hackpad-cli/"),
13
- desc: "Path to the hackpad-cli directory to use."
14
-
15
- class_option :workspace,
16
- aliases: "-w",
17
- default: "default",
18
- desc: "Name of the workspace to use."
19
-
20
- default_task :help
21
-
22
- desc "search [term]", "Lists available pads matching [term]."
23
- def search(term)
24
- Hackpad::Client.new(options).search term
25
- end
26
-
27
- desc "list", "Lists available pads."
28
- def list
29
- Hackpad::Client.new(options).listall
30
- end
31
-
32
- desc "getinfo [pad_id]", "gets info for the pad <pad_id>."
33
- def info(pad)
34
- Hackpad::Client.new(options).getinfo pad
35
- end
36
-
37
- desc "show [pad_id] [format]", "shows pad <pad_id> in format [html,txt,md] (default txt)."
38
- def show(pad,format='txt')
39
- Hackpad::Client.new(options).show pad, format
40
- end
41
-
2
+ module Cli
3
+ FORMATS = %w(txt md html)
42
4
  end
43
-
44
5
  end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require "hackpad/cli/client"
5
+
6
+ describe Hackpad::Cli::Client do
7
+
8
+ pending "Hackpad::Cli::Client.new"
9
+ pending "Hackpad::Cli::Client.search"
10
+ pending "Hackpad::Cli::Client.list"
11
+ pending "Hackpad::Cli::Client.info"
12
+ pending "Hackpad::Cli::Client.show"
13
+
14
+ end
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require "hackpad/cli"
5
+ require "hackpad/cli/pad"
6
+ require "hackpad/cli/api"
7
+ require "hackpad/cli/store"
8
+
9
+ describe Hackpad::Cli::Pad do
10
+
11
+ before :each do
12
+ Hackpad::Cli::Api.stub(:read).with('123', 'txt').and_return("content\nand body")
13
+ Hackpad::Cli::Api.stub(:read_options).with('123').and_return({"success" => "true"})
14
+ options = {
15
+ "configdir" => File.expand_path('../../../files', __FILE__),
16
+ "workspace" => 'default'
17
+ }
18
+ Hackpad::Cli::Store.prepare options
19
+ @pad = Hackpad::Cli::Pad.new "123"
20
+ @pad.load 'txt'
21
+ end
22
+
23
+ after :each do
24
+ FileUtils.rm_rf File.expand_path('../../../files/default', __FILE__)
25
+ end
26
+
27
+ it "creates a new pad object" do
28
+ expect(@pad.id).to eq "123"
29
+ end
30
+
31
+ it "Can extract the title" do
32
+ expect(@pad.title).to eq "content"
33
+ end
34
+ it "Can count chars from content" do
35
+ expect(@pad.chars).to be 16
36
+ end
37
+ it "Can count lines from content" do
38
+ expect(@pad.lines).to be 2
39
+ end
40
+
41
+ end
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require "hackpad/cli/runner"
5
+ require "hackpad/cli/client"
6
+
7
+ describe Hackpad::Cli::Runner do
8
+
9
+ before :each do
10
+ @cli = Hackpad::Cli::Runner.new
11
+ Hackpad::Cli::Client.stub(:new, {}).and_return(Object)
12
+ end
13
+
14
+ it "calls the search method in client class" do
15
+ Object.stub(:search)
16
+ @cli.shell.mute do
17
+ @cli.search "xxx"
18
+ end
19
+ end
20
+
21
+ it "calls the list method in client class" do
22
+ Object.stub(:list)
23
+ @cli.shell.mute do
24
+ @cli.list
25
+ end
26
+ end
27
+
28
+ it "calls the list method in client class" do
29
+ Object.stub(:list)
30
+ @cli.shell.mute do
31
+ @cli.list
32
+ end
33
+ end
34
+
35
+ it "calls the info method in client class" do
36
+ Object.stub(:info)
37
+ @cli.shell.mute do
38
+ @cli.info 'pad'
39
+ end
40
+ end
41
+
42
+ it "calls the show method in client class" do
43
+ Object.stub(:show)
44
+ @cli.shell.mute do
45
+ @cli.show 'pad', 'md'
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require "hackpad/cli/store"
5
+
6
+ describe Hackpad::Cli::Store do
7
+
8
+ before :each do
9
+ options = {
10
+ "configdir" => File.expand_path('../../../files', __FILE__),
11
+ "workspace" => 'default'
12
+ }
13
+ Hackpad::Cli::Store.prepare options
14
+ end
15
+
16
+ it "reads pads list from file" do
17
+ File.stub(:read).and_return("gy23ui first one\ngy3u4 second one\n23489g third")
18
+ list = Hackpad::Cli::Store.read_list
19
+ expect(list).to be_an Array
20
+ expect(list[0]).to be_an OpenStruct
21
+ expect(list[0].id).to eq "gy23ui"
22
+ expect(list[0].title).to eq "first one"
23
+ expect(list[2].id).to eq "23489g"
24
+ expect(list[2].title).to eq "third"
25
+ end
26
+
27
+ end
@@ -0,0 +1,13 @@
1
+ $LOAD_PATH << File.expand_path('../../lib', __FILE__)
2
+ require 'rubygems'
3
+ require 'bundler'
4
+
5
+ require 'coveralls'
6
+ Coveralls.wear!
7
+
8
+ RSpec.configure do |config|
9
+ config.mock_with :rspec
10
+ config.expect_with :rspec do |c|
11
+ c.syntax = :expect
12
+ end
13
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hackpad-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - mose
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-01 00:00:00.000000000 Z
11
+ date: 2014-05-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -94,6 +94,48 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: webmock
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: coveralls
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
97
139
  description: A Command Line Interface for consuming the Hackpad REST API.
98
140
  email:
99
141
  - mose@mose.com
@@ -102,9 +144,11 @@ executables:
102
144
  extensions: []
103
145
  extra_rdoc_files: []
104
146
  files:
147
+ - ".coveralls.yml"
105
148
  - ".gitignore"
106
149
  - ".ruby-gemset"
107
150
  - ".ruby-version"
151
+ - ".travis.yml"
108
152
  - CHANGELOG.md
109
153
  - Gemfile
110
154
  - LICENSE.txt
@@ -113,10 +157,20 @@ files:
113
157
  - bin/hpcli
114
158
  - hackpad-cli.gemspec
115
159
  - lib/hackpad/cli.rb
160
+ - lib/hackpad/cli/api.rb
161
+ - lib/hackpad/cli/client.rb
162
+ - lib/hackpad/cli/config.rb
163
+ - lib/hackpad/cli/pad.rb
164
+ - lib/hackpad/cli/padlist.rb
165
+ - lib/hackpad/cli/plain_colors.rb
166
+ - lib/hackpad/cli/runner.rb
167
+ - lib/hackpad/cli/store.rb
116
168
  - lib/hackpad/cli/version.rb
117
- - lib/hackpad/client.rb
118
- - lib/hackpad/config.rb
119
- - lib/hackpad/store.rb
169
+ - spec/lib/hackpad/cli/client_spec.rb
170
+ - spec/lib/hackpad/cli/pad_spec.rb
171
+ - spec/lib/hackpad/cli/runner_spec.rb
172
+ - spec/lib/hackpad/cli/store_spec.rb
173
+ - spec/spec_helper.rb
120
174
  homepage: https://github.com/mose/hackpad-cli
121
175
  licenses:
122
176
  - MIT
@@ -141,4 +195,9 @@ rubygems_version: 2.2.2
141
195
  signing_key:
142
196
  specification_version: 4
143
197
  summary: CLI for hackpad browsing and editing.
144
- test_files: []
198
+ test_files:
199
+ - spec/lib/hackpad/cli/client_spec.rb
200
+ - spec/lib/hackpad/cli/pad_spec.rb
201
+ - spec/lib/hackpad/cli/runner_spec.rb
202
+ - spec/lib/hackpad/cli/store_spec.rb
203
+ - spec/spec_helper.rb
@@ -1,100 +0,0 @@
1
- require 'oauth'
2
- require 'net/http'
3
- require 'json'
4
- require 'cgi'
5
- require 'reverse_markdown'
6
-
7
- require_relative 'config'
8
-
9
- module Hackpad
10
- class Client
11
-
12
- def initialize(options)
13
- @config = Config.load options
14
- site = URI.parse @config['site']
15
- consumer = OAuth::Consumer.new(
16
- @config['client_id'],
17
- @config['secret'],
18
- site: @config['site']
19
- )
20
- @token = OAuth::AccessToken.new consumer
21
- end
22
-
23
- # GET /api/1.0/pads/all
24
- def search(term,start=0)
25
- res = @token.get "/api/1.0/search?q=#{CGI.escape term}&start=#{start}&limit=100"
26
- if res.is_a? Net::HTTPSuccess
27
- all = JSON.parse res.body
28
- all.each do |a|
29
- puts "#{a['id'].bold} - #{unescape(a['title']).colorize(:yellow)}\n #{extract a['snippet']}"
30
- end
31
-
32
- else
33
- puts "#{res.inspect}".colorize :red
34
- puts "#{res.body}".colorize :red
35
- return back
36
- end
37
- end
38
-
39
- def listall
40
- res = @token.get "/api/1.0/pads/all"
41
- if res.is_a? Net::HTTPSuccess
42
- all = JSON.parse res.body
43
- all.each do |a|
44
- getinfo(a)
45
- end
46
- else
47
- puts "#{res.inspect}".colorize :red
48
- puts "#{res.body}".colorize :red
49
- return back
50
- end
51
- end
52
-
53
- def getinfo(pad)
54
- res = @token.get "/api/1.0/pad/#{pad}/content.txt"
55
- if res.is_a? Net::HTTPSuccess
56
- printf "%-20s %s\n", "Id", "#{pad}".bold
57
- printf "%-20s %s\n", "Title", "#{res.body.lines.first.chomp}".colorize(:yellow)
58
- printf "%-20s %s\n", "URI", "#{@config['site']}/#{pad}"
59
- printf "%-20s %s\n", "Size", "#{res.body.length} chars"
60
- else
61
- puts "#{pad} failed".colorize :red
62
- end
63
- res = @token.get "/api/1.0/pad/#{pad}/options"
64
- if res.is_a? Net::HTTPSuccess
65
- a = JSON.parse res.body
66
- printf "%-20s %s\n", "Guest Policy", "#{a['options']['guestPolicy']}"
67
- printf "%-20s %s\n", "Moderated", "#{a['options']['isModerated'] || "No"}"
68
- else
69
- puts "#{pad} failed".colorize :red
70
- end
71
- end
72
-
73
- def show(pad,format)
74
- ext = (format == 'md') ? 'html' : format
75
- res = @token.get "/api/1.0/pad/#{pad}/content.#{ext}"
76
- if res.is_a? Net::HTTPSuccess
77
- puts "#{@config['site']}/#{pad}"
78
- puts
79
- if format == 'md'
80
- puts ReverseMarkdown.convert(res.body, github_flavored: true)
81
- else
82
- puts res.body
83
- end
84
- else
85
- puts "#{pad} failed".colorize :red
86
- end
87
- end
88
-
89
- private
90
-
91
- def unescape(s)
92
- CGI.unescapeHTML s
93
- end
94
-
95
- def extract(s)
96
- unescape(s).gsub(/<b class="hit">([^<]*)<\/b>/) { |e| $1.colorize(:cyan).bold }
97
- end
98
-
99
- end
100
- end
@@ -1,40 +0,0 @@
1
- module Hackpad
2
- module Config
3
- extend self
4
-
5
- def load(options)
6
- configdir = options[:configdir]
7
- configfile = File.join(configdir, "#{options[:workspace]}.yml")
8
- # temporary migration path
9
- if !File.exists?(configfile) && File.exists?(File.join(configdir, "config.yml"))
10
- FileUtils.mv File.join(configdir, "config.yml"), configfile
11
- end
12
- if !Dir.exists?(configdir) || !File.exists?(configfile)
13
- setup configfile
14
- end
15
- YAML::load_file configfile
16
- end
17
-
18
- private
19
-
20
- def setup(configfile)
21
- config = {}
22
- FileUtils.mkdir_p File.dirname(configfile)
23
- puts "We need first to initialize your hackpad-cli configuration.".colorize(:blue)
24
- puts "Please gather your information from https://<subdomain>.hackpad.com/ep/account/settings/"
25
- print "What is your Client ID? "
26
- STDOUT.flush
27
- config['client_id'] = STDIN.gets.chomp
28
- print "What is your Secret Key? "
29
- STDOUT.flush
30
- config['secret'] = STDIN.gets.chomp
31
- print "What is the URI of your pad? "
32
- STDOUT.flush
33
- config['site'] = STDIN.gets.chomp
34
- File.open(configfile, "w") do |f|
35
- f.write YAML::dump(config)
36
- end
37
- end
38
-
39
- end
40
- end
data/lib/hackpad/store.rb DELETED
@@ -1,8 +0,0 @@
1
- module Hackpad
2
- class Store
3
-
4
- def initialize(config)
5
- end
6
-
7
- end
8
- end