hx 0.3.3 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.3
1
+ 0.4.1
data/lib/hx.rb CHANGED
@@ -28,6 +28,8 @@ require 'yaml'
28
28
 
29
29
  module Hx
30
30
 
31
+ VERSION = (Pathname.new(__FILE__).parent.parent + 'VERSION').read.strip
32
+
31
33
  class NoSuchEntryError < RuntimeError
32
34
  end
33
35
 
@@ -0,0 +1,132 @@
1
+ # hx/backend/couchdb - CouchDB backend for Hx
2
+ #
3
+ # Copyright (c) 2009-2010 MenTaLguY <mental@rydia.net>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ require 'rubygems'
25
+ require 'cgi'
26
+ require 'net/http'
27
+ require 'uri'
28
+ require 'json'
29
+ require 'time'
30
+ require 'hx'
31
+
32
+ module Hx
33
+ module Backend
34
+
35
+ class CouchDB
36
+ include Hx::Source
37
+
38
+ class HTTPError < RuntimeError
39
+ attr_reader :path
40
+ attr_reader :code
41
+ attr_reader :response
42
+
43
+ def initialize(path, code, response)
44
+ @path = path
45
+ @code = code
46
+ @response = response
47
+ end
48
+
49
+ def to_s
50
+ "HTTP Error #{@code} for #{path}"
51
+ end
52
+ end
53
+
54
+ def initialize(source, options)
55
+ couchdb_server = options.fetch(:couchdb_server, "http://localhost:5984/")
56
+ couchdb_database = options.fetch(:couchdb_database, "entries")
57
+ uri = URI.parse(couchdb_server)
58
+ if uri.scheme != "http"
59
+ raise RuntimeError, "Unsupported protocol #{uri.proto}"
60
+ end
61
+ @host = uri.host || "localhost"
62
+ @port = uri.port || 80
63
+ prefix = uri.path || "/"
64
+ prefix = "#{prefix}/" unless prefix =~ %r(/$)
65
+ @prefix = "#{prefix}#{couchdb_database}/"
66
+ end
67
+
68
+ def edit_entry(path, prototype=nil)
69
+ begin
70
+ text = get_document(path)
71
+ rescue HTTPError => e
72
+ raise e unless e.code == 404
73
+ raise Hx::NoSuchEntryError, "No such entry #{path}" unless prototype
74
+ text = prototype.to_json
75
+ end
76
+ text = yield text
77
+ entry = JSON.parse(text)
78
+ entry['updated'] = Time.now.xmlschema
79
+ entry['created'] ||= entry['updated']
80
+ put_document(path, entry.to_json)
81
+ self
82
+ end
83
+
84
+ def each_entry
85
+ listing = JSON.parse(get_document('_all_docs'))
86
+ for row in listing['rows']
87
+ path = row['id']
88
+ begin
89
+ entry = JSON.parse(get_document(path))
90
+ rescue HTTPError => e
91
+ raise e unless e.code == 404
92
+ # the document may have gone away since we requested the list
93
+ next
94
+ end
95
+ for field in %(created updated)
96
+ entry[field] = Time.parse(entry[field] || "")
97
+ end
98
+ yield path, entry
99
+ end
100
+ self
101
+ end
102
+
103
+ private
104
+ def request_path_for(id)
105
+ "#{@prefix}#{CGI.escape(id)}"
106
+ end
107
+
108
+ def get_document(id)
109
+ request = Net::HTTP::Get.new(request_path_for(id))
110
+ http_request(request)
111
+ end
112
+
113
+ def put_document(id, body)
114
+ request = Net::HTTP::Put.new(request_path_for(id),
115
+ 'Content-Type' => 'application/json')
116
+ request.body = body
117
+ http_request(request)
118
+ end
119
+
120
+ def http_request(request)
121
+ response = Net::HTTP.start(@host, @port) { |http| http.request(request) }
122
+ case response
123
+ when Net::HTTPSuccess
124
+ response.body
125
+ else
126
+ raise HTTPError.new(request.path, response.code.to_i, response)
127
+ end
128
+ end
129
+ end
130
+
131
+ end
132
+ end
@@ -48,7 +48,7 @@ class Hobix
48
48
  text = entry_filename.read
49
49
  previous_mtime = entry_filename.mtime
50
50
  rescue Errno::ENOENT
51
- raise NoSuchEntryError, path unless prototype
51
+ raise Hx::NoSuchEntryError, path unless prototype
52
52
  prototype = prototype.dup
53
53
  prototype['content'] = (prototype['content'] || "").dup
54
54
  content = prototype['content']
@@ -51,6 +51,11 @@ def self.main(*args)
51
51
  return
52
52
  end
53
53
 
54
+ opts.on_tail("-v", "--version", "Output the version (#{Hx::VERSION})") do
55
+ puts Hx::VERSION
56
+ return
57
+ end
58
+
54
59
  opts.parse!(args)
55
60
  end
56
61
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - MenTaLguY
@@ -41,6 +41,7 @@ files:
41
41
  - VERSION
42
42
  - bin/hx
43
43
  - lib/hx.rb
44
+ - lib/hx/backend/couchdb.rb
44
45
  - lib/hx/backend/hobix.rb
45
46
  - lib/hx/commandline.rb
46
47
  - lib/hx/listing/limit.rb