zenpush 0.1.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.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ pkg
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # A sample Gemfile
2
+ source "http://rubygems.org"
3
+
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,32 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ zenpush (0.1.0)
5
+ awesome_print (~> 1.0.0)
6
+ boson (~> 1.0)
7
+ httparty (~> 0.8.0)
8
+ json_pure (~> 1.5.1)
9
+ redcarpet (~> 2.1.0)
10
+
11
+ GEM
12
+ remote: http://rubygems.org/
13
+ specs:
14
+ awesome_print (1.0.2)
15
+ boson (1.1.0)
16
+ httparty (0.8.1)
17
+ multi_json
18
+ multi_xml
19
+ json_pure (1.5.4)
20
+ spruz (~> 0.2.8)
21
+ multi_json (1.1.0)
22
+ multi_xml (0.4.1)
23
+ rake (0.9.2.2)
24
+ redcarpet (2.1.0)
25
+ spruz (0.2.13)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ rake
32
+ zenpush!
data/History.txt ADDED
@@ -0,0 +1,5 @@
1
+ == 0.1.0
2
+
3
+ * Original version
4
+ * List categories, forums, entries
5
+ * Convert entries from Markdown to HTML push them to Zendesk
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2012 CleverScale
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,73 @@
1
+ # ZenPush
2
+
3
+ This gem allows editing your Zendesk knowledge base in Markdown. It's a command-line tool.
4
+
5
+ ## Getting Started
6
+
7
+ $ gem install zenpush
8
+
9
+ Run it:
10
+
11
+ $ zenpush <command> <args>
12
+ $ zp <command> <args>
13
+
14
+ ## Requirements:
15
+
16
+ Only installs pure JSON gem json_pure by default. If you are able to install the C-extension json gem, it will use that instead.
17
+
18
+ Try:
19
+
20
+ $ gem install json zenpush
21
+
22
+ ## Configuration
23
+
24
+ Create a `zenpush.yml` file in your home directory. Here is an example:
25
+
26
+ ---
27
+ uri: https://myproduct.zendesk.com
28
+ user: email@address.com/token
29
+ password: LoDsQlEtBXSd8clW87DgWi0VNFod3U9xQggzwJEH
30
+
31
+ You can find your API token at https://myproduct.zendesk.com/settings/api.
32
+
33
+ ## Usage
34
+
35
+ ### Listing categories
36
+
37
+ $ zp categories
38
+
39
+ ### Listing forums
40
+
41
+ $ zp forums
42
+
43
+ ### Listing entries in a forum
44
+
45
+ $ zp entries -f <forum_id>
46
+ $ zp entries -F <forum_name>
47
+
48
+ ### Creating/updating an entry
49
+
50
+ Keep an organized folder of your categories, forums, and entries. Let's say I have the category "Documentation", containing a forum "REST API", and the entries "Introduction" and "Authentication"; you'll want to keep this file structure:
51
+
52
+ Documentation/REST API/Introduction.md
53
+ Documentation/REST API/Authentication.md
54
+
55
+ Creating or updating an entry:
56
+
57
+ $ zp push -f <path_to_markdown_file>
58
+
59
+ Following the previous example, you would type:
60
+
61
+ [~/KB/Documentation/REST API]$ zp push -f Authentication.md
62
+ [~/KB/Documentation]$ zp push -f REST API/Authentication.md
63
+ [~/KB]$ zp push -f REST Documentation/API/Authentication.md
64
+
65
+ The gem will automatically discover the category and forum name of a given entry file. It will also convert your Markdown syntax in HTML before sending it to Zendesk.
66
+
67
+ ### Check if an entry exists
68
+
69
+ $ zp exists? -f <path_to_markdown_file>
70
+
71
+ ## Contributors
72
+
73
+ * @nfo
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/setup"
2
+ Bundler::GemHelper.install_tasks
data/bin/zenpush ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'zenpush'
4
+ ZenPush::Runner.start
data/bin/zp ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'zenpush'
4
+ ZenPush::Runner.start
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+ require 'redcarpet/compat'
3
+
4
+ module ZenPush
5
+ class Markdown
6
+
7
+ # Convert a markdown file to HTML, removing all <code> tags,
8
+ # which make Zendesk remove carriage returns.
9
+ def self.to_zendesk_html(file)
10
+ ::Markdown.new(File.read(file)).to_html.gsub(/<\/?code>/, '')
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,55 @@
1
+ # encoding: UTF-8
2
+ require 'boson/runner'
3
+ require 'ap'
4
+
5
+ module ZenPush
6
+ class Runner < Boson::Runner
7
+
8
+ desc 'List categories'
9
+ def categories(options = {})
10
+ ap ZenPush.z.categories
11
+ end
12
+
13
+ desc 'List forums'
14
+ def forums(options = {})
15
+ ap ZenPush.z.forums
16
+ end
17
+
18
+ option :forum_id, :type => :numeric
19
+ desc 'List entries'
20
+ def entries(options = {})
21
+ ap ZenPush.z.entries(options[:forum_id])
22
+ end
23
+
24
+ desc 'Does the entry matching the given file exist ?'
25
+ option :file, :type => :string
26
+ def exists?(options = {})
27
+ category_name, forum_name, entry_title = ZenPush.file_to_category_forum_entry(options[:file])
28
+ entry = ZenPush.z.find_entry(category_name, forum_name, entry_title)
29
+ ap !!entry
30
+ end
31
+
32
+ desc 'Create or update an entry from the given file'
33
+ option :file, :type => :string
34
+ def push(options = {})
35
+ category_name, forum_name, entry_title = ZenPush.file_to_category_forum_entry(options[:file])
36
+
37
+ entry_body = ZenPush::Markdown.to_zendesk_html(options[:file])
38
+
39
+ entry = ZenPush.z.find_entry(category_name, forum_name, entry_title)
40
+ if entry
41
+ # UPDATE THE ENTRY
42
+ ap ZenPush.z.put_entry(entry['id'], entry_body)
43
+ else
44
+ forum = ZenPush.z.find_forum(category_name, forum_name)
45
+ if forum
46
+ # CREATE THE ENTRY
47
+ ap ZenPush.z.post_entry(forum['id'], entry_title, entry_body)
48
+ else
49
+ ap "Could not find a forum named '#{forum_name}' in the category '#{category_name}'"
50
+ exit(-1)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,4 @@
1
+ # encoding: UTF-8
2
+ module ZenPush
3
+ VERSION = "0.1.0"
4
+ end
@@ -0,0 +1,111 @@
1
+ # encoding: UTF-8
2
+ require 'json'
3
+ require 'yaml'
4
+ require 'httparty'
5
+
6
+ module ZenPush
7
+ class Zendesk
8
+ include HTTParty
9
+
10
+ headers 'Content-Type' => 'application/json'
11
+ # debug_output
12
+
13
+ def initialize(b = nil, u = nil, p = nil)
14
+ if b.nil? || u.nil? || p.nil?
15
+ creds = YAML.load_file(File.join(ENV['HOME'], '.zenpush.yml'))
16
+ b ||= creds['uri']
17
+ u ||= creds['user']
18
+ p ||= creds['password']
19
+ end
20
+
21
+ self.class.base_uri b + '/api/v1'
22
+ self.class.basic_auth u, p
23
+ end
24
+
25
+ def get(uri, options = {})
26
+ self.class.get(uri, options)
27
+ end
28
+
29
+ def post(uri, options = {})
30
+ self.class.post(uri, options)
31
+ end
32
+
33
+ def put(uri, options = {})
34
+ self.class.put(uri, options)
35
+ end
36
+
37
+ def delete(uri, options = {})
38
+ self.class.delete(uri, options)
39
+ end
40
+
41
+ def categories(options = {})
42
+ self.get('/categories.json', options).parsed_response
43
+ end
44
+
45
+ def category(category_id, options = {})
46
+ self.get("/categories/#{category_id}.json", options).parsed_response
47
+ end
48
+
49
+ def forums(options = {})
50
+ self.get('/forums.json', options).parsed_response
51
+ end
52
+
53
+ def forum(forum_id, options = {})
54
+ self.get("/forums/#{forum_id}.json", options).parsed_response
55
+ end
56
+
57
+ def users(options = {})
58
+ self.get('/users.json', options).parsed_response
59
+ end
60
+
61
+ def entries(forum_id, options = {})
62
+ self.get("/forums/#{forum_id}/entries.json", options).parsed_response
63
+ end
64
+
65
+ def entry(entry_id, options = {})
66
+ self.get("/entries/#{entry_id}.json", options).parsed_response
67
+ end
68
+
69
+ # Find category by name
70
+ def find_category(category_name, options = {})
71
+ self.categories.detect {|c| c['name'] == category_name}
72
+ end
73
+
74
+ # Find forum by name, knowing the category name
75
+ def find_forum(category_name, forum_name, options = {})
76
+ category = self.find_category(category_name, options)
77
+ if category
78
+ self.forums.detect {|f| f['name'] == forum_name}
79
+ end
80
+ end
81
+
82
+ # Find entry by name, knowing the forum name and category name
83
+ def find_entry(category_name, forum_name, entry_title, options = {})
84
+ forum = self.find_forum(category_name, forum_name, options)
85
+ if forum
86
+ self.entries(forum['id'], options).detect {|e| e['title'] == entry_title}
87
+ end
88
+ end
89
+
90
+ # Create an entry in the given forum id
91
+ def post_entry(forum_id, entry_title, entry_body, options = {})
92
+ self.post("/entries.json",
93
+ options.merge(
94
+ :body => { :entry => {
95
+ :forum_id => forum_id, :title => entry_title, :body => entry_body
96
+ } }.to_json
97
+ )
98
+ )
99
+ end
100
+
101
+ # Update an entry in the given forum id
102
+ def put_entry(entry_id, entry_body, options = {})
103
+ self.put("/entries/#{entry_id}.json",
104
+ options.merge(
105
+ :body => { :entry => { :body => entry_body } }.to_json
106
+ )
107
+ )
108
+ end
109
+
110
+ end
111
+ end
data/lib/zenpush.rb ADDED
@@ -0,0 +1,23 @@
1
+ # encoding: UTF-8
2
+ require 'zenpush/runner'
3
+ require 'zenpush/zendesk'
4
+ require 'zenpush/markdown'
5
+
6
+ module ZenPush
7
+ extend self
8
+
9
+ # Zendesk API
10
+ def z
11
+ @z ||= ZenPush::Zendesk.new
12
+ end
13
+
14
+ #
15
+ def file_to_category_forum_entry(file)
16
+ absolute_path = File.realpath(file)
17
+ parts = absolute_path.split('/')
18
+ entry_name = File.basename(absolute_path, '.md') # TODO support .markdown and make it case insensitive
19
+ forum_name = parts[-2]
20
+ category_name = parts[-3]
21
+ return category_name, forum_name, entry_name
22
+ end
23
+ end
data/zenpush.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # encoding: UTF-8
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "zenpush/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "zenpush"
7
+ s.version = ZenPush::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Nicolas Fouché"]
10
+ s.email = ["nicolas.fouche@cleverscale.com"]
11
+ s.homepage = "https://github.com/cleverscale/zenpush"
12
+ s.summary = "Push your markdown files to your Zendesk knowledge base"
13
+ s.description = "Push your markdown files to your Zendesk knowledge base"
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+ s.rdoc_options = ["--charset=UTF-8"]
20
+
21
+ s.add_dependency "boson", "~> 1.0" # Command line
22
+ s.add_dependency "httparty", "~> 0.8.0" # Zendesk API calls
23
+ s.add_dependency "redcarpet", "~> 2.1.0" # Markdown to HTML
24
+ s.add_dependency "awesome_print", "~> 1.0.0" # Colorized output of Zendesk responses
25
+ s.add_dependency "json_pure", "~> 1.5.1" # The C-gem "json" will still be used instead if it's installed
26
+
27
+ s.add_development_dependency "rake"
28
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zenpush
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nicolas Fouché
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: boson
16
+ requirement: &70100188010080 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70100188010080
25
+ - !ruby/object:Gem::Dependency
26
+ name: httparty
27
+ requirement: &70100188008860 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.8.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70100188008860
36
+ - !ruby/object:Gem::Dependency
37
+ name: redcarpet
38
+ requirement: &70100187769000 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 2.1.0
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70100187769000
47
+ - !ruby/object:Gem::Dependency
48
+ name: awesome_print
49
+ requirement: &70100187768300 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.0
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70100187768300
58
+ - !ruby/object:Gem::Dependency
59
+ name: json_pure
60
+ requirement: &70100187767540 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 1.5.1
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70100187767540
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: &70100187766900 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70100187766900
80
+ description: Push your markdown files to your Zendesk knowledge base
81
+ email:
82
+ - nicolas.fouche@cleverscale.com
83
+ executables:
84
+ - zenpush
85
+ - zp
86
+ extensions: []
87
+ extra_rdoc_files: []
88
+ files:
89
+ - .gitignore
90
+ - Gemfile
91
+ - Gemfile.lock
92
+ - History.txt
93
+ - LICENSE
94
+ - README.markdown
95
+ - Rakefile
96
+ - bin/zenpush
97
+ - bin/zp
98
+ - lib/zenpush.rb
99
+ - lib/zenpush/markdown.rb
100
+ - lib/zenpush/runner.rb
101
+ - lib/zenpush/version.rb
102
+ - lib/zenpush/zendesk.rb
103
+ - zenpush.gemspec
104
+ homepage: https://github.com/cleverscale/zenpush
105
+ licenses: []
106
+ post_install_message:
107
+ rdoc_options:
108
+ - --charset=UTF-8
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ! '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ segments:
118
+ - 0
119
+ hash: -3134286403274189971
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ segments:
127
+ - 0
128
+ hash: -3134286403274189971
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 1.8.17
132
+ signing_key:
133
+ specification_version: 3
134
+ summary: Push your markdown files to your Zendesk knowledge base
135
+ test_files: []