shabng 0.0.2

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.
Files changed (7) hide show
  1. data/DOC/CommandRef.rdoc +60 -0
  2. data/LICENSE +27 -0
  3. data/README +30 -0
  4. data/bin/shabng +140 -0
  5. data/lib/post.rb +113 -0
  6. data/shabng.gemspec +55 -0
  7. metadata +132 -0
@@ -0,0 +1,60 @@
1
+ = Using shabng
2
+
3
+ Shabng is a command line client for accessing the blogging service at http://shabng.com. Visit the site to sign up for a free account and create your first blog. Once done, you'll be given an API key; you'll use this to access the service from any Ruby-fied console.
4
+
5
+ == Installing Shabng
6
+
7
+ Currently only available as a Ruby Gem, run:
8
+
9
+ sudo gem install shabng
10
+
11
+ == Initial setup
12
+
13
+ Simply run the command, and you'll be guided through the setup steps:
14
+
15
+ shabng
16
+
17
+ You'll be asked to enter the API key, and to choose your editing app.
18
+
19
+ == Creating a new post
20
+
21
+ shabng new
22
+
23
+ You'll be prompted to give your new post a title. Your editor will then open, and you can write your post. Save and close the document, and Shabng will save it on the server with a Draft status (unpublished).
24
+
25
+ == Editing a post
26
+
27
+ Shabng lets you edit posts based on an action, followed by an ID number to act upon. The process involves first getting the ID you want. If you're editing a post you just wrote, the *new* action responds with the ID so you can proceed immediately. Otherwise, you can use the list command:
28
+
29
+ shabng list
30
+
31
+ And you'll see a list of all your posts. Now, when editing, you can choose the attribute to edit (currently title, body, pubdate and categories). Here are a few examples:
32
+
33
+ shabng edit title 3
34
+ shabng edit body 2
35
+ shabng edit pubdate 4
36
+ shabng edit categories 1
37
+
38
+ Just follow the instructions to complete the steps.
39
+
40
+ == Going live with a post
41
+
42
+ When you're ready to go live with your post, issue the push command:
43
+
44
+ shabng push 3
45
+
46
+ if you change your mind, use the pull command:
47
+
48
+ shabng pull 3
49
+
50
+ == Managing Categories
51
+
52
+ You can create the categories that you attach to your post. For example:
53
+
54
+ shabng new category
55
+
56
+ Follow the prompt to create a new category name.
57
+
58
+ == Support
59
+
60
+ If you need further assistance, visit http://shabng.com.
data/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2010, Aaron Vegh
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ * Neither the name of the author/s, nor the names of the project's
15
+ contributors may be used to endorse or promote products derived from this
16
+ software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README ADDED
@@ -0,0 +1,30 @@
1
+ = Shabang#!
2
+
3
+ Shabang is a blogging service for those who prefer to blog from the command line. Sign up for a free account at http://shabng.com. Once you've created your account and picked a name for your blog, you'll get an API key to interact with that blog using this command line program.
4
+
5
+ Shabang is written in Ruby, and uses the rest-client library to interact with the web service. You may modify this code, or re-implement it in other languages if you wish; it's presented as-is for your hacking pleasure.
6
+
7
+ == Authors
8
+
9
+ * Aaron Vegh (aaron@innoveghtive.com and @aaronvegh on Twitter)
10
+
11
+ == Installation
12
+
13
+ If you're using RubyGems, you can install it via:
14
+
15
+ $ sudo gem install shabang
16
+
17
+ We'll provide additional install instructions as those methods become available. It's early days, folks.
18
+
19
+ == Instructions
20
+
21
+ See the DOC file for using Shabang.
22
+
23
+ == Support
24
+
25
+ Have problems? Contact Aaron Vegh (aaron@innoveghtive.com). Try to be nice.
26
+
27
+ == License
28
+
29
+ See the LICENSE file included with the distribution for licensing and
30
+ copyright details.
data/bin/shabng ADDED
@@ -0,0 +1,140 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'rubygems'
4
+ require 'parseconfig'
5
+ require 'rest-client'
6
+ require 'console_editor'
7
+ require 'xmlsimple'
8
+ require 'ap'
9
+ require 'post.rb'
10
+
11
+ SB_VERSION = "0.0.2"
12
+
13
+ # get configuration file
14
+ # and conduct testing to ensure proper setup
15
+ config_path = File.expand_path('~/.shabng.conf')
16
+ if File.exists?(config_path)
17
+ conf = ParseConfig.new(config_path)
18
+ else
19
+ puts "New user detected."
20
+ print "Enter your blog key (from the web site): "
21
+ key = STDIN.gets.chomp
22
+ config = "apikey = " + key
23
+
24
+ puts "Choose your text editor from this list: "
25
+ puts "nano, vi, emacs, mate, bbedit"
26
+ editor = STDIN.gets.chomp
27
+ config += "\neditor = " + editor
28
+
29
+ conf_file = File.open(config_path, "w+")
30
+ conf_file.write config
31
+
32
+ puts "New config file written."
33
+ exit
34
+ end
35
+
36
+ @apikey = conf.get_value("apikey")
37
+ @editor = conf.get_value("editor")
38
+ @urlstring = "http://shabng.com"
39
+
40
+ # with our initial data set, let's check the server for a proper connection
41
+ # this will be done in the guise of a client update check.
42
+ # probably not entirely efficient to make this ping on every request, but I'm lazy.
43
+
44
+ check = RestClient.get @urlstring + "/accounts/version", :params=>{:api_key=>@apikey}
45
+
46
+ if check
47
+ vstring = XmlSimple.xml_in(check)
48
+ version = vstring["version"].first
49
+ if version != SB_VERSION
50
+ puts "A newer version of shabng is available. Please run 'sudo gem update shabng'."
51
+ end
52
+ else
53
+ puts "There are problems connecting to the server. Check the site to confirm."
54
+ exit
55
+ end
56
+
57
+ arg = ARGV[0]
58
+ arg2 = ARGV[1]
59
+ arg3 = ARGV[2]
60
+
61
+ if arg == "list"
62
+ # list all blog posts
63
+ puts "Here are your blog postings..."
64
+ @post = Post.new(@urlstring, @apikey)
65
+ @post.list
66
+
67
+ elsif arg == "new"
68
+ if arg2.nil? || arg2 == "post"
69
+ # create new blog post
70
+ print "Enter post title: "
71
+ title = STDIN.gets.chomp
72
+ eval "#{@editor} '/tmp/#{title}'"
73
+ @post = Post.new(@urlstring, @apikey, @editor)
74
+ @post.title = title
75
+ @post.body = File.new("/tmp/"+title).read
76
+ @post.publication_date = Time.now
77
+ @post.status = "Draft"
78
+ @post.add
79
+ elsif arg2 == "category"
80
+ print "Enter new category name: "
81
+ category = STDIN.gets.chomp
82
+ @post = Post.new(@urlstring, @apikey)
83
+ @post.newcat(category)
84
+ end
85
+
86
+ elsif arg == "edit"
87
+ # edit existing blog post
88
+ if arg2.nil?
89
+ puts "Please specify an element to edit: title, body, pubdate, categories."
90
+ elsif arg3.nil?
91
+ puts "Please specify a post to edit using the ID from the list command."
92
+ else
93
+ @post = Post.new(@urlstring, @apikey, @editor)
94
+ @post.edit(arg2, arg3)
95
+ end
96
+
97
+ elsif arg == "push"
98
+ if arg2.nil?
99
+ puts "Use a post ID with this argument to specify what to push live."
100
+ else
101
+ @post = Post.new(@urlstring, @apikey)
102
+ @post.push(arg2)
103
+ end
104
+
105
+ elsif arg == "pull"
106
+ if arg2.nil?
107
+ puts "Use a post ID with this argument to specify what to remove from your blog."
108
+ else
109
+ @post = Post.new(@urlstring, @apikey)
110
+ @post.pull(arg2)
111
+ end
112
+
113
+ # hold off on delete until rest-client supports params with delete request, so we can authenticate!
114
+ # https://github.com/archiloque/rest-client/issues#issue/48
115
+ elsif arg == "delete"
116
+ # delete blog post
117
+ if arg2.nil?
118
+ puts "Use a post ID with this argument to specify what to delete from your blog."
119
+ else
120
+ @post = Post.new(@urlstring, @apikey)
121
+ @post.destroy(arg2)
122
+ end
123
+
124
+ elsif arg == "setup"
125
+ # create database and perform initial setup
126
+
127
+
128
+
129
+ elsif arg == "create_database"
130
+ @name = @newname
131
+
132
+ elsif arg == "help"
133
+
134
+
135
+ else
136
+ puts "Shabng version " + SB_VERSION + "."
137
+ puts "Run with 'new' to create a new post."
138
+ puts "Run with 'list' to view existing posts."
139
+ end
140
+
data/lib/post.rb ADDED
@@ -0,0 +1,113 @@
1
+ require 'rubygems'
2
+ require 'rest-client'
3
+ require 'xmlsimple'
4
+ require 'time'
5
+ require 'ap'
6
+ class Post
7
+
8
+ attr_accessor :title, :body, :publication_date, :status, :blogid, :apikey
9
+
10
+ def initialize(urlstring, apikey, editor="nano")
11
+ @urlstring = urlstring
12
+ @apikey = apikey
13
+ @editor = editor
14
+ end
15
+
16
+ def add
17
+ save = RestClient.post @urlstring + "/posts", :api_key=>@apikey, :post => {:title=>title, :body=>body, :publication_date=>publication_date, :status=>status}
18
+ post = XmlSimple.xml_in(save)
19
+ file_contents = File.new("/tmp/"+title).read
20
+ puts "Blog post has been saved with ID " + post["id"].first["content"]
21
+ end
22
+
23
+ def list
24
+ docs = RestClient.get @urlstring + "/posts", :params=>{:api_key=>@apikey}
25
+ posts = XmlSimple.xml_in(docs)
26
+ if posts["post"].nil? == false
27
+ posts["post"].each do |d|
28
+ pubdate = Time.parse(d["publication-date"].first["content"])
29
+ puts "[" + d["id"].first["content"] + "] " + d["title"].first + " - " + pubdate.strftime("%Y-%m-%d") + " - " + d["status"].first
30
+ end
31
+ else
32
+ puts "No postings yet. Use the new command to create your first!"
33
+ end
34
+ end
35
+
36
+ def edit(action, sel)
37
+ xml = RestClient.get @urlstring + "/posts/" + sel + "/edit", :params=>{:api_key => @apikey}
38
+ post = XmlSimple.xml_in(xml)
39
+ body = post["body"].first
40
+ title = post["title"].first
41
+
42
+ if action == "body"
43
+ # edit chosen doc
44
+ filename = "/tmp/"+title
45
+ tempfile = File.new(filename, "w")
46
+ tempfile.write body
47
+ tempfile.close
48
+ puts "Editing with " + @editor
49
+ eval "#{@editor} '#{filename}'"
50
+
51
+ newbody = File.new(filename, "r").read
52
+ save = RestClient.put @urlstring + "/posts/" + sel, :api_key => @apikey, :post => {:body=>newbody}
53
+
54
+ elsif action == "title"
55
+ print "Enter new title [" + title + "]: "
56
+ newtitle = STDIN.gets.chomp
57
+ if newtitle != title && newtitle != ""
58
+ save = RestClient.put @urlstring + "/posts/" + sel, :api_key => @apikey, :post => {:title=>newtitle}
59
+ end
60
+
61
+ elsif action == "pubdate"
62
+ print "Enter new publication date [YYYY-MM-DD]: "
63
+ newdate = STDIN.gets.chomp
64
+ parseddate = Time.parse(newdate)
65
+ if parseddate
66
+ save = RestClient.put @urlstring + "/posts/" + sel, :api_key => @apikey, :post => {:publication_date=>parseddate}
67
+ else
68
+ puts "Incorrect date format. Please try again."
69
+ end
70
+
71
+ elsif action == "categories"
72
+ # get all categories
73
+ xml = RestClient.get @urlstring + "/categories", :params=>{:api_key => @apikey}
74
+ post = XmlSimple.xml_in(xml)
75
+ require 'rubygems'
76
+ require 'ap'
77
+ #ap(post)
78
+ post["category"].each do |c|
79
+ puts "[" + c["id"].first["content"] + "] " + c["name"].first
80
+ end
81
+ puts "Enter a comma-separated list of category IDs: "
82
+ cats = STDIN.gets.chomp
83
+ cats = cats.gsub(" ", "").split(",")
84
+
85
+ save = RestClient.put @urlstring + "/posts/" + sel, :api_key => @apikey, :categories=>cats
86
+
87
+ end
88
+
89
+ puts "Blog post has been saved!"
90
+
91
+ end
92
+
93
+ def newcat(cat)
94
+ save = RestClient.post @urlstring + "/categories", :api_key => @apikey, :category=>cat
95
+ puts "New category has been saved!"
96
+ end
97
+
98
+ def push(sel)
99
+ save = RestClient.put @urlstring + "/posts/" + sel, :api_key => @apikey, :post => {:status=>"Published"}
100
+ puts "Your post is now live."
101
+ end
102
+
103
+ def pull(sel)
104
+ save = RestClient.put @urlstring + "/posts/" + sel, :api_key => @apikey, :post => {:status=>"Draft"}
105
+ puts "Your post has been pulled."
106
+ end
107
+
108
+ def destroy(sel)
109
+ save = RestClient.delete @urlstring + "/posts/" + sel, :params=>{:api_key => @apikey}
110
+ puts "Your post has been deleted."
111
+ end
112
+
113
+ end
data/shabng.gemspec ADDED
@@ -0,0 +1,55 @@
1
+ Gem::Specification.new do |s|
2
+ s.specification_version = 2 if s.respond_to? :specification_version=
3
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
+ s.rubygems_version = '0.0.2'
5
+
6
+ ## Leave these as is they will be modified for you by the rake gemspec task.
7
+ ## If your rubyforge_project name is different, then edit it and comment out
8
+ ## the sub! line in the Rakefile
9
+ s.name = 'shabng'
10
+ s.version = '0.0.2'
11
+ s.date = '2010-11-10'
12
+ s.rubyforge_project = 'shabng'
13
+
14
+ ## Make sure your summary is short. The description may be as long
15
+ ## as you like.
16
+ s.summary = "Manage your blog from the command line."
17
+ s.description = "Shabng is a blogging service for those who prefer to blog from the command line. Sign up for a free account at http://shabng.com. Once you've created your account and picked a name for your blog, you'll get an API key to interact with that blog using this command line program."
18
+
19
+ ## List the primary authors. If there are a bunch of authors, it's probably
20
+ ## better to set the email to an email list or something. If you don't have
21
+ ## a custom homepage, consider using your GitHub URL or the like.
22
+ s.authors = ["Aaron Vegh"]
23
+ s.email = 'aaron@innoveghtive.com'
24
+ s.homepage = 'http://shabng.com'
25
+
26
+ s.require_paths = %w[lib bin]
27
+
28
+ s.rdoc_options = ["--charset=UTF-8"]
29
+ s.extra_rdoc_files = %w[README LICENSE DOC/CommandRef.rdoc]
30
+
31
+ s.add_dependency('parseconfig')
32
+ s.add_dependency('rest-client')
33
+ s.add_dependency('console_editor')
34
+ s.add_dependency('xml-simple', ">= 1.0.12")
35
+
36
+ s.executables << 'shabng'
37
+
38
+ ## Leave this section as-is. It will be automatically generated from the
39
+ ## contents of your Git repository via the gemspec task. DO NOT REMOVE
40
+ ## THE MANIFEST COMMENTS, they are used as delimiters by the task.
41
+ # = MANIFEST =
42
+ s.files = %w[
43
+ LICENSE
44
+ README
45
+ shabng.gemspec
46
+ bin/shabng
47
+ lib/post.rb
48
+ DOC/CommandRef.rdoc
49
+ ]
50
+ # = MANIFEST =
51
+
52
+ ## Test files will be grabbed from the file list. Make sure the path glob
53
+ ## matches what you actually use.
54
+ s.test_files = s.files.select { |path| path =~ /^test\/test_.*\.rb/ }
55
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shabng
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
11
+ platform: ruby
12
+ authors:
13
+ - Aaron Vegh
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-10 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: parseconfig
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rest-client
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: console_editor
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: xml-simple
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 15
72
+ segments:
73
+ - 1
74
+ - 0
75
+ - 12
76
+ version: 1.0.12
77
+ type: :runtime
78
+ version_requirements: *id004
79
+ description: Shabng is a blogging service for those who prefer to blog from the command line. Sign up for a free account at http://shabng.com. Once you've created your account and picked a name for your blog, you'll get an API key to interact with that blog using this command line program.
80
+ email: aaron@innoveghtive.com
81
+ executables:
82
+ - shabng
83
+ extensions: []
84
+
85
+ extra_rdoc_files:
86
+ - README
87
+ - LICENSE
88
+ - DOC/CommandRef.rdoc
89
+ files:
90
+ - LICENSE
91
+ - README
92
+ - shabng.gemspec
93
+ - bin/shabng
94
+ - lib/post.rb
95
+ - DOC/CommandRef.rdoc
96
+ has_rdoc: true
97
+ homepage: http://shabng.com
98
+ licenses: []
99
+
100
+ post_install_message:
101
+ rdoc_options:
102
+ - --charset=UTF-8
103
+ require_paths:
104
+ - lib
105
+ - bin
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ hash: 3
112
+ segments:
113
+ - 0
114
+ version: "0"
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ hash: 3
121
+ segments:
122
+ - 0
123
+ version: "0"
124
+ requirements: []
125
+
126
+ rubyforge_project: shabng
127
+ rubygems_version: 1.3.7
128
+ signing_key:
129
+ specification_version: 2
130
+ summary: Manage your blog from the command line.
131
+ test_files: []
132
+