germinate-atompub 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 1.0.0 / 2009-07-20
2
+
3
+ * 1 major enhancement
4
+ * Birthday!
data/README.txt ADDED
@@ -0,0 +1,59 @@
1
+ germinate-atompub
2
+
3
+ by Avdi Grimm
4
+
5
+ http://github.com/devver/germinate-wordpress
6
+
7
+ == DESCRIPTION
8
+
9
+ An Atom Publishing Protocol (APP) plugin for Germinate.
10
+
11
+ == FEATURES
12
+
13
+ * User-friendly prompting helps with initial setup
14
+ * Will do updates on subsequent calls, rather than posting a new entry
15
+
16
+ == PROBLEMS
17
+
18
+ * No tests
19
+ * No configurability whatsoever
20
+
21
+ == SYNOPSIS
22
+
23
+ FIXME (code sample of usage)
24
+
25
+ == REQUIREMENTS
26
+
27
+ * fattr
28
+ * highline
29
+ * atom-tools
30
+ * ick
31
+
32
+ == INSTALL
33
+
34
+ * sudo gem install devver-germinate-atompub --source http://gems.github.com
35
+
36
+ == LICENSE
37
+
38
+ (The MIT License)
39
+
40
+ Copyright (c) 2009
41
+
42
+ Permission is hereby granted, free of charge, to any person obtaining
43
+ a copy of this software and associated documentation files (the
44
+ 'Software'), to deal in the Software without restriction, including
45
+ without limitation the rights to use, copy, modify, merge, publish,
46
+ distribute, sublicense, and/or sell copies of the Software, and to
47
+ permit persons to whom the Software is furnished to do so, subject to
48
+ the following conditions:
49
+
50
+ The above copyright notice and this permission notice shall be
51
+ included in all copies or substantial portions of the Software.
52
+
53
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
54
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
55
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
56
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
57
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
58
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
59
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ # Look in the tasks/setup.rb file for the various options that can be
2
+ # configured in this Rakefile. The .rake files in the tasks directory
3
+ # are where the options are used.
4
+
5
+ begin
6
+ require 'bones'
7
+ Bones.setup
8
+ rescue LoadError
9
+ begin
10
+ load 'tasks/setup.rb'
11
+ rescue LoadError
12
+ raise RuntimeError, '### please install the "bones" gem ###'
13
+ end
14
+ end
15
+
16
+ ensure_in_path 'lib'
17
+
18
+ require 'germinate'
19
+ require 'germinate/publisher'
20
+ require 'germinate-gist'
21
+
22
+ require 'germinate-atompub'
23
+
24
+ task :default => 'spec:run'
25
+
26
+ PROJ.name = 'germinate-atompub'
27
+ PROJ.authors = 'Avdi Grimm'
28
+ PROJ.email = 'avdi@avdi.org'
29
+ PROJ.url = 'http://github.com/devver/germinate-wordpress'
30
+ PROJ.version = GerminateAtompub::VERSION
31
+ PROJ.rubyforge.name = 'germinate-app'
32
+ PROJ.ignore_file = '.gitignore'
33
+
34
+ depend_on 'ick', '~> 0.3.0'
35
+ depend_on 'atom-tools', '~> 2.0.3'
36
+ depend_on 'highline', '~> 1.5.0'
37
+ depend_on 'fattr', '~> 1.0.3'
38
+
39
+ PROJ.spec.opts << '--color'
40
+
41
+ # EOF
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(
4
+ File.join(File.dirname(__FILE__), %w[.. lib germinate-atompub]))
5
+
6
+ # Put your code here
7
+
8
+ # EOF
data/examples/hello.rb ADDED
@@ -0,0 +1,9 @@
1
+ # :PUBLISHER: blog, atompub
2
+ #
3
+ # :TEXT:
4
+ # Hello, blog world 1 2 3
5
+
6
+ # :SET: 'ATOMPUB_COLLECTION_URL', 'http://germinatetest.wordpress.com/wp-app.php/posts'
7
+ # :SET: 'ATOMPUB_LOGIN', 'avdi'
8
+
9
+ # :SET: 'ATOMPUB_ENTRY_URL', 'http://germinatetest.wordpress.com/wp-app.php/post/13'
@@ -0,0 +1,49 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{germinate-atompub}
5
+ s.version = "1.0.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Avdi Grimm"]
9
+ s.date = %q{2009-07-21}
10
+ s.default_executable = %q{germinate-atompub}
11
+ s.description = %q{An Atom Publishing Protocol (APP) plugin for Germinate.}
12
+ s.email = %q{avdi@avdi.org}
13
+ s.executables = ["germinate-atompub"]
14
+ s.extra_rdoc_files = ["History.txt", "README.txt", "bin/germinate-atompub", "lib/text.yml"]
15
+ s.files = ["History.txt", "README.txt", "Rakefile", "bin/germinate-atompub", "examples/hello.rb", "germinate-atompub.gemspec", "lib/germinate-atompub.rb", "lib/germinate-atompub/atompub_publisher.rb", "lib/germinate_plugin_v0_init.rb", "lib/text.yml", "spec/germinate-atompub/atompub_publisher_spec.rb", "spec/germinate-atompub_spec.rb", "spec/spec_helper.rb", "test/test_germinate-atompub.rb"]
16
+ s.has_rdoc = true
17
+ s.homepage = %q{http://github.com/devver/germinate-wordpress}
18
+ s.rdoc_options = ["--main", "README.txt"]
19
+ s.require_paths = ["lib"]
20
+ s.rubyforge_project = %q{germinate-app}
21
+ s.rubygems_version = %q{1.3.1}
22
+ s.summary = %q{An Atom Publishing Protocol (APP) plugin for Germinate}
23
+ s.test_files = ["test/test_germinate-atompub.rb"]
24
+
25
+ if s.respond_to? :specification_version then
26
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
27
+ s.specification_version = 2
28
+
29
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
30
+ s.add_runtime_dependency(%q<ick>, ["~> 0.3.0"])
31
+ s.add_runtime_dependency(%q<atom-tools>, ["~> 2.0.3"])
32
+ s.add_runtime_dependency(%q<highline>, ["~> 1.5.0"])
33
+ s.add_runtime_dependency(%q<fattr>, ["~> 1.0.3"])
34
+ s.add_development_dependency(%q<bones>, [">= 2.5.1"])
35
+ else
36
+ s.add_dependency(%q<ick>, ["~> 0.3.0"])
37
+ s.add_dependency(%q<atom-tools>, ["~> 2.0.3"])
38
+ s.add_dependency(%q<highline>, ["~> 1.5.0"])
39
+ s.add_dependency(%q<fattr>, ["~> 1.0.3"])
40
+ s.add_dependency(%q<bones>, [">= 2.5.1"])
41
+ end
42
+ else
43
+ s.add_dependency(%q<ick>, ["~> 0.3.0"])
44
+ s.add_dependency(%q<atom-tools>, ["~> 2.0.3"])
45
+ s.add_dependency(%q<highline>, ["~> 1.5.0"])
46
+ s.add_dependency(%q<fattr>, ["~> 1.0.3"])
47
+ s.add_dependency(%q<bones>, [">= 2.5.1"])
48
+ end
49
+ end
@@ -0,0 +1,49 @@
1
+
2
+ module GerminateAtompub
3
+
4
+ # :stopdoc:
5
+ VERSION = '1.0.0'
6
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
7
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
8
+ # :startdoc:
9
+
10
+ # Returns the version string for the library.
11
+ #
12
+ def self.version
13
+ VERSION
14
+ end
15
+
16
+ # Returns the library path for the module. If any arguments are given,
17
+ # they will be joined to the end of the libray path using
18
+ # <tt>File.join</tt>.
19
+ #
20
+ def self.libpath( *args )
21
+ args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
22
+ end
23
+
24
+ # Returns the lpath for the module. If any arguments are given,
25
+ # they will be joined to the end of the path using
26
+ # <tt>File.join</tt>.
27
+ #
28
+ def self.path( *args )
29
+ args.empty? ? PATH : ::File.join(PATH, args.flatten)
30
+ end
31
+
32
+ # Utility method used to require all files ending in .rb that lie in the
33
+ # directory below this file that has the same name as the filename passed
34
+ # in. Optionally, a specific _directory_ name can be passed in such that
35
+ # the _filename_ does not have to be equivalent to the directory.
36
+ #
37
+ def self.require_all_libs_relative_to( fname, dir = nil )
38
+ dir ||= ::File.basename(fname, '.*')
39
+ search_me = ::File.expand_path(
40
+ ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
41
+
42
+ Dir.glob(search_me).sort.each {|rb| require rb}
43
+ end
44
+
45
+ end # module GerminateAtompub
46
+
47
+ GerminateAtompub.require_all_libs_relative_to(__FILE__)
48
+
49
+ # EOF
@@ -0,0 +1,108 @@
1
+ require 'fattr'
2
+ require 'highline'
3
+ require 'atom/service'
4
+ require 'ick'
5
+
6
+ class GerminateAtompub::AtompubPublisher < Germinate::Publisher
7
+ identifier "atompub"
8
+
9
+ Ick::Returning.belongs_to(self)
10
+
11
+ TEXT_PATH = File.expand_path('../text.yml', File.dirname(__FILE__))
12
+
13
+ Q_DEFAULTS = lambda {|q| q.readline = true}
14
+
15
+ fattr(:hl) { HighLine.new }
16
+ fattr(:text) { File.open(TEXT_PATH) {|f| YAML.load(f)} }
17
+ fattr(:http) {
18
+ returning(Atom::HTTP.new) { |http|
19
+ http.user = login
20
+ http.pass = password
21
+ http.always_auth = :basic
22
+ }
23
+ }
24
+ fattr(:login) {
25
+ librarian.variables.fetch('ATOMPUB_LOGIN') {
26
+ hl.ask(text[:login], &Q_DEFAULTS)
27
+ }
28
+ }
29
+ fattr(:password) {
30
+ hl.ask(text[:password]) {|q|
31
+ q.echo = "*"
32
+ q.readline = true
33
+ }
34
+ }
35
+ fattr(:service_url) {
36
+ hl.ask(text[:service_url]) {|q|
37
+ q.default = ENV['GERM_ATOM_SERVICE_URL']
38
+ }
39
+ }
40
+ fattr(:service) {
41
+ begin
42
+ Atom::Service.discover(service_url, http)
43
+ rescue Atom::Unauthorized
44
+ hl.say "Authorization failed; please try again:"
45
+ login!
46
+ password!
47
+ http!
48
+ retry
49
+ end
50
+ }
51
+ fattr(:collections) { service.collections }
52
+ fattr(:collection) {
53
+ if url = librarian.variables['ATOMPUB_COLLECTION_URL']
54
+ Atom::Collection.new(url, http)
55
+ else
56
+ hl.say text[:collection]
57
+ hl.choose { |m|
58
+ m.readline = true
59
+ collections.each do |c|
60
+ m.choice(c.title) {c}
61
+ end
62
+ }
63
+ end
64
+ }
65
+ fattr(:collection_url) {
66
+ librarian.variables.fetch('ATOMPUB_COLLECTION_URL') {
67
+ collection.href
68
+ }
69
+ }
70
+ fattr(:entry) {
71
+ if url = librarian.variables['ATOMPUB_ENTRY_URL']
72
+ http.get_atom_entry(url)
73
+ else
74
+ returning(Atom::Entry.new) do |entry|
75
+ entry.title = librarian.source_path.to_s
76
+ entry.draft = true
77
+ end
78
+ end
79
+ }
80
+
81
+ def initialize(name, librarian, options={})
82
+ super
83
+ end
84
+
85
+ def publish!(output=$stdout, extra_options = {})
86
+ entry.content = input.join
87
+ entry.content['type'] = 'html'
88
+ entry.updated!
89
+
90
+ response = if entry.edit_url
91
+ log.info "Updating entry at #{entry.edit_url}"
92
+ collection.put!(entry)
93
+ else
94
+ log.info "Posting entry to #{collection.href}"
95
+ response = collection.post!(entry)
96
+ end
97
+ log.debug "Response: #{response.inspect}"
98
+ log.debug "Response body:\n #{response.read_body}"
99
+
100
+ entry_url = entry.edit_url || response['Location']
101
+ log.info "Posted/updated article at #{entry_url}"
102
+
103
+ librarian.variables['ATOMPUB_ENTRY_URL'] = entry_url
104
+ librarian.variables['ATOMPUB_COLLECTION_URL'] = collection_url
105
+ librarian.variables['ATOMPUB_LOGIN'] = login
106
+ end
107
+ end
108
+
@@ -0,0 +1 @@
1
+ require 'germinate-atompub'
data/lib/text.yml ADDED
@@ -0,0 +1,5 @@
1
+ ---
2
+ :login: "Please enter your blog login: "
3
+ :password: "Please enter your blog password: "
4
+ :service_url: "Please enter the blog URL"
5
+ :collection: "Please choose a collection to post to:"
@@ -0,0 +1,14 @@
1
+ require File.join(File.dirname(__FILE__), %w[.. spec_helper])
2
+
3
+ module GerminateAtompub
4
+ describe AtompubPublisher do
5
+ before :each do
6
+ @librarian = stub("Librarian", :make_pipeline => lambda{|x| x})
7
+ @it = AtompubPublisher.new("article", @librarian)
8
+ end
9
+
10
+ it "should identify itself as 'atompub'" do
11
+ AtompubPublisher.identifier.should == "atompub"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+
2
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
3
+
4
+ describe GerminateAtompub do
5
+ end
6
+
7
+ # EOF
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'germinate'
3
+ require 'germinate/publisher'
4
+
5
+ require File.expand_path(
6
+ File.join(File.dirname(__FILE__), %w[.. lib germinate-atompub]))
7
+
8
+ Spec::Runner.configure do |config|
9
+ # == Mock Framework
10
+ #
11
+ # RSpec uses it's own mocking framework by default. If you prefer to
12
+ # use mocha, flexmock or RR, uncomment the appropriate line:
13
+ #
14
+ # config.mock_with :mocha
15
+ # config.mock_with :flexmock
16
+ # config.mock_with :rr
17
+ end
18
+
19
+ # EOF
data/tasks/ann.rake ADDED
@@ -0,0 +1,80 @@
1
+
2
+ begin
3
+ require 'bones/smtp_tls'
4
+ rescue LoadError
5
+ require 'net/smtp'
6
+ end
7
+ require 'time'
8
+
9
+ namespace :ann do
10
+
11
+ # A prerequisites task that all other tasks depend upon
12
+ task :prereqs
13
+
14
+ file PROJ.ann.file do
15
+ ann = PROJ.ann
16
+ puts "Generating #{ann.file}"
17
+ File.open(ann.file,'w') do |fd|
18
+ fd.puts("#{PROJ.name} version #{PROJ.version}")
19
+ fd.puts(" by #{Array(PROJ.authors).first}") if PROJ.authors
20
+ fd.puts(" #{PROJ.url}") if PROJ.url.valid?
21
+ fd.puts(" (the \"#{PROJ.release_name}\" release)") if PROJ.release_name
22
+ fd.puts
23
+ fd.puts("== DESCRIPTION")
24
+ fd.puts
25
+ fd.puts(PROJ.description)
26
+ fd.puts
27
+ fd.puts(PROJ.changes.sub(%r/^.*$/, '== CHANGES'))
28
+ fd.puts
29
+ ann.paragraphs.each do |p|
30
+ fd.puts "== #{p.upcase}"
31
+ fd.puts
32
+ fd.puts paragraphs_of(PROJ.readme_file, p).join("\n\n")
33
+ fd.puts
34
+ end
35
+ fd.puts ann.text if ann.text
36
+ end
37
+ end
38
+
39
+ desc "Create an announcement file"
40
+ task :announcement => ['ann:prereqs', PROJ.ann.file]
41
+
42
+ desc "Send an email announcement"
43
+ task :email => ['ann:prereqs', PROJ.ann.file] do
44
+ ann = PROJ.ann
45
+ from = ann.email[:from] || Array(PROJ.authors).first || PROJ.email
46
+ to = Array(ann.email[:to])
47
+
48
+ ### build a mail header for RFC 822
49
+ rfc822msg = "From: #{from}\n"
50
+ rfc822msg << "To: #{to.join(',')}\n"
51
+ rfc822msg << "Subject: [ANN] #{PROJ.name} #{PROJ.version}"
52
+ rfc822msg << " (#{PROJ.release_name})" if PROJ.release_name
53
+ rfc822msg << "\n"
54
+ rfc822msg << "Date: #{Time.new.rfc822}\n"
55
+ rfc822msg << "Message-Id: "
56
+ rfc822msg << "<#{"%.8f" % Time.now.to_f}@#{ann.email[:domain]}>\n\n"
57
+ rfc822msg << File.read(ann.file)
58
+
59
+ params = [:server, :port, :domain, :acct, :passwd, :authtype].map do |key|
60
+ ann.email[key]
61
+ end
62
+
63
+ params[3] = PROJ.email if params[3].nil?
64
+
65
+ if params[4].nil?
66
+ STDOUT.write "Please enter your e-mail password (#{params[3]}): "
67
+ params[4] = STDIN.gets.chomp
68
+ end
69
+
70
+ ### send email
71
+ Net::SMTP.start(*params) {|smtp| smtp.sendmail(rfc822msg, from, to)}
72
+ end
73
+ end # namespace :ann
74
+
75
+ desc 'Alias to ann:announcement'
76
+ task :ann => 'ann:announcement'
77
+
78
+ CLOBBER << PROJ.ann.file
79
+
80
+ # EOF