hackpad-cli 0.0.4 → 0.0.5

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: 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