vrtx 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 (5) hide show
  1. data/README.rdoc +62 -0
  2. data/bin/vrtx +8 -0
  3. data/lib/vrtx/article.rb +206 -0
  4. data/lib/vrtx.rb +262 -0
  5. metadata +88 -0
data/README.rdoc ADDED
@@ -0,0 +1,62 @@
1
+ = Vrtx
2
+
3
+ == DESCRIPTION:
4
+
5
+ Command line utility for managing content in the open source content management system Vortex.
6
+
7
+ Vortex is fully manageable via the WebDAV server extensions. The
8
+ vrtx command line utility is a subproject of the general WebDAV client
9
+ davclient.rubyforge.org.
10
+
11
+ == Requirements
12
+
13
+ The command line utility curl installed. Available from
14
+ http://curl.haxx.se/ or on linux:
15
+
16
+ sudo apt-get install curl
17
+
18
+ == LIRBRARY SYNOPSIS:
19
+
20
+ require 'rubygems'
21
+ require 'vrtx'
22
+
23
+ url = 'http://test.webdav.org/dav/'
24
+ Vortex.cd(url)
25
+ Vortex.publish("Title", "Introducion")
26
+
27
+
28
+ == COMMAND LINE UTILITES:
29
+
30
+ Vortex inlcudes the command line utility 'vrtx'. Use 'vrx cd url' to set current working url
31
+ and 'vrtx ls' to list content of a collection (directory).
32
+
33
+ == COMMAND LINE SYNOPSIS:
34
+
35
+ >vrtx cd http://test.webdav.org/dav/
36
+ http://test.webdav.org/dav/
37
+ >vrtx ls
38
+ images/
39
+ index.html
40
+ >vrtx pwd
41
+ http://test.webdav.org/dav/
42
+ >vrtx publish --title "Title" --introduction "Intro"
43
+ Published "Title" to: http://test.webdav.org/dav/title.html
44
+
45
+ == INSTALL:
46
+
47
+ [sudo] gem install vrxt
48
+
49
+ or
50
+
51
+ git clone git://github.com/thomasfl/vrtx.git
52
+ cd vrtx
53
+ gem build Rakefile
54
+ sudo gem install vrxt-x.x.x.gem
55
+
56
+ == Background:
57
+
58
+ The library is suitable for creating scripts that update content on webservers
59
+ with the CMS Vortex and WebDAV http extions installed.
60
+
61
+ See also "DavClient":http://github.com/thomasfl/davclient/tree/master
62
+
data/bin/vrtx ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'davclient'
4
+ require 'davclient/davcli'
5
+ require 'vrtx'
6
+
7
+ args = VrtxCLI.substitute_urls(ARGV
8
+ DavCLI.dav(args)
@@ -0,0 +1,206 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Article
4
+
5
+ attr_accessor :url, :hpricotItem, :content
6
+ attr_reader :vortexResourceType
7
+
8
+ def initialize(*args)
9
+ @url = args[0]
10
+
11
+ if(@url =~ /:\/\/[^\/]*dav\./)then
12
+ item = WebDAV.propfind(url)
13
+ @vortexResourceType = item.property("v:resourceType")
14
+ if(vortexResourceType)then
15
+
16
+ if(@vortexResourceType == "article")then
17
+ # do nothing. no conversion necessary
18
+ @hpricotElem = item
19
+ @content = WebDAV.get(@url)
20
+ end
21
+
22
+ if(@vortexResourceType == "nyhet")then
23
+ puts "TODO: Manipulate xml of propierties so it becomes an article instead"
24
+ @hpricotElem = item
25
+ @hpricotElem.search("v:resourceType").remove
26
+
27
+ puts "class" + @hpricotElem.class.to_s
28
+
29
+ element = @hpricotElem.search("d:displayname")
30
+ element.after "<v:resourceType xmlns:v=\"vrtx\">article</v:resourceType>"
31
+
32
+ title = item.property("v:title")
33
+ element.after "<v:userTitle xmlns:v=\"vrtx\">#{title}</v:userTitle>"
34
+ @hpricotElem.search("tittel").remove
35
+
36
+ publishedDate = @hpricotElem.at("dato").inner_text
37
+
38
+
39
+ puts "TODO: Scrape url"
40
+
41
+ end
42
+
43
+ if(@vortexResourceType == "managed-xml")then
44
+ @hpricotElem = item
45
+ # HTML must be scraped off
46
+ publicUrl = Vortex.davUrl2webUrl(@url)
47
+ require 'open-uri'
48
+ puts "DEBUG: scraping content..."
49
+ content = ""
50
+ open(publicUrl) { |f| content=f.read }
51
+
52
+ puts content
53
+ puts "---------"
54
+ doc = Hpricot(open(publicUrl))
55
+ # Make sure we can scrape content, even if content is password protected...
56
+ # Må logge inn
57
+ curl_get_cmd = "curl ..."
58
+ # @content = doc.searchWebDAV.get(@url)
59
+ end
60
+
61
+ # TODO If @vortexResourceType is not recognized, read content
62
+ end
63
+ if(item.collection)then
64
+ @hpricotElem = item
65
+ @collection = true
66
+ end
67
+ else
68
+ puts "Warning: Not WebDAV url: " + @url
69
+ end
70
+
71
+ end
72
+
73
+ def method_missing(method_name, *args)
74
+ # TODO Detect attribute writers: article.createdBy = thomasfl
75
+ # puts "DEBUG: Article." + method_name.to_s + "() method missing"
76
+
77
+ if(@hpricotElem)then
78
+ result = @hpricotElem.method_missing(method_name, *args)
79
+ end
80
+ if(result == nil)then
81
+ puts "Warning: Article." + method_name.to_s + "() method missing returns nil"
82
+ end
83
+ if(result == "false")then
84
+ return false
85
+ end
86
+ return result
87
+ end
88
+
89
+ # Returns basename of the url for article
90
+ def basename
91
+ return File.basename(@url)
92
+ end
93
+
94
+ # Returns url without filname for articles
95
+ def dirname
96
+ return File.dirname(@url) + "/"
97
+ end
98
+
99
+
100
+ # Boolean method that returns true if visualProfile is enabled.
101
+ def visualProfile
102
+ # Vortex default behaviour is visualProfile is always turned on
103
+ # and propfind only return the property <disabled ...> if
104
+ # visualProfile is disabled.
105
+ return (not @hpricotElem.property("disabled") == "true")
106
+ end
107
+
108
+ # Set the visualProfile. Value must be boolean
109
+ def visualProfile=(value)
110
+ # Sets the visualProfile property by modifying the xml properties
111
+ if(value.class == TrueClass or value.class == FalseClass ) then
112
+ if(value == true)then
113
+ if(@hpricotElem.search("disabled"))then
114
+ @hpricotElem.search("disabled").remove
115
+ end
116
+ end
117
+ if(value == false)then
118
+ element = @hpricotElem.search("d:displayname")
119
+ element.after "<disabled xmlns=\"http://www.uio.no/visual-profile\">true</disabled>"
120
+ end
121
+ end
122
+ end
123
+
124
+ # Puts the article to the server
125
+ def put!()
126
+ # Publiser en artikkel med eventuelle justeringen.
127
+ puts "put!: @vortexResourceType: '" + @vortexResourceType + "'"
128
+ item = @hpricotElem
129
+
130
+ if(@vortexResourceType == "nyhet")then
131
+ # This conversion should be done when article is read!!!
132
+
133
+ end
134
+
135
+ if(@vortexResourceType == "managed-xml")then
136
+ # This conversion should be done when article is read!!!
137
+
138
+ options = {
139
+ # :authors => item.authors.strip!, # FIXME: Support multiple authors
140
+ :characterEncoding => item.characterEncoding.downcase,
141
+ :creationDate => item.creationDate,
142
+ :contentLastModified => item.contentLastModified,
143
+ :propertiesLastModified => item.propertiesLastModified,
144
+ :owner => item.owner,
145
+ :propertiesModifiedBy => item.propertiesModifiedBy,
146
+ :createdBy => item.createdBy,
147
+ :contentModifiedBy => item.contentModifiedBy }
148
+
149
+ require 'pp'
150
+
151
+ end
152
+
153
+ if(@vortexResourceType == "article")then
154
+ options = {
155
+ :authors => item.authors.strip!, # FIXME: Support multiple authors
156
+ :characterEncoding => item.characterEncoding,
157
+ :creationDate => item.creationDate,
158
+ :contentLastModified => item.contentLastModified,
159
+ :propertiesLastModified => item.propertiesLastModified,
160
+ :owner => item.owner,
161
+ :propertiesModifiedBy => item.propertiesModifiedBy,
162
+ :createdBy => item.createdBy,
163
+ :contentModifiedBy => item.contentModifiedBy }
164
+
165
+ end
166
+
167
+ begin
168
+
169
+ visualProfile = (not item.property("disabled") == "true")
170
+ # puts "item.visualProfile: '" + item.visualProfile.to_s + "'"
171
+ if(not(visualProfile ))
172
+ options.merge!(:visualProfile => false)
173
+ end
174
+
175
+ # require 'pp'
176
+ # pp options
177
+
178
+ url = @url
179
+ title = item.title
180
+ introduction = item.introduction
181
+ content = @content
182
+ published_date = item.property("published-date")
183
+
184
+ puts "PUT url:" + url
185
+ # puts "title:"+ title
186
+ # puts "introduction:" + introduction.strip!
187
+ # puts "content:\n------------\n:" + content + "\n--end------"
188
+ # puts "pbulished-date:" + published_date # , options)
189
+
190
+ # Vortex.publish_article(url, title, introduction, content, published_date, options)
191
+
192
+ end
193
+
194
+
195
+
196
+ end
197
+
198
+ def update()
199
+ # Proppatch
200
+ end
201
+
202
+ def inspect
203
+ "Article. URL: " + @url
204
+ end
205
+
206
+ end
data/lib/vrtx.rb ADDED
@@ -0,0 +1,262 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'davclient'
3
+ require 'time'
4
+
5
+ # Command line utility for Vortex CMS
6
+ #
7
+ # Library for communicating with Vortex CMS server via WebDAV protocol.
8
+ #
9
+ # Documentation for vortex specific properties, see "Resource type tree":
10
+ # http://www.usit.uio.no/it/vortex/arbeidsomrader/metadata/ressurstypetre-2009-06-15.txt
11
+
12
+ ARTICLE_HTML = <<EOF
13
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
14
+ <html xmlns="http://www.w3.org/1999/xhtml">
15
+ <head>
16
+ <title>##title##</title>
17
+ </head>
18
+ <body>
19
+ <p>##content##</p>
20
+ </body>
21
+ </html>
22
+ EOF
23
+
24
+ article_props = <<EOF
25
+ <v:resourceType xmlns:v="vrtx">article</v:resourceType>
26
+ <v:xhtml10-type xmlns:v="vrtx">article</v:xhtml10-type>
27
+ <v:published-date xmlns:v="vrtx">##published-date##</v:published-date>
28
+ <v:userSpecifiedCharacterEncoding xmlns:v="vrtx">##characterEncoding##</v:userSpecifiedCharacterEncoding>
29
+ <v:userTitle xmlns:v="vrtx">##usertitle##</v:userTitle>
30
+ EOF
31
+
32
+ ARTICLE_PROPERTIES = article_props.gsub("\n","").gsub(/ +/," ")
33
+
34
+ authors_props = <<EOF
35
+ <v:authors xmlns:v="vrtx">
36
+ <vrtx:values xmlns:vrtx="http://vortikal.org/xml-value-list">
37
+ <vrtx:value>##realname##</vrtx:value>
38
+ </vrtx:values>
39
+ </v:authors>
40
+ EOF
41
+ AUTHORS = authors_props.gsub("\n","").gsub(/ +/," ")
42
+
43
+ INTRODUCTION = "<introduction>##introduction##</introduction>"
44
+
45
+ # Command line utilities
46
+ module VrtxCLI
47
+
48
+
49
+ def self.substitute_urls(args)
50
+ if(args.grep(/^http:/) or args.grep(/[a-z]*\.[a-z]*\.[a-z]*[\/a-z]*$/) )then
51
+ new_args = []
52
+ args.each do |arg|
53
+ if(arg =~ /^http:/)then
54
+ arg = Vortex.url2davUrl(arg)
55
+ puts "Warning: changing url to webdav url: " + arg
56
+ new_args += [arg]
57
+ elsif(arg =~ /[a-z]*\.[a-z]*\.[a-z]*[\/a-z]*$/)
58
+ arg = Vortex.url2davUrl("http://" + arg)
59
+ new_args += [arg]
60
+ else
61
+ new_args += [arg]
62
+ end
63
+ end
64
+ args = new_args
65
+ end
66
+ return args
67
+ end
68
+
69
+ end
70
+
71
+ # Utilities for communicating with the Vortex CMS through
72
+ # the WebDAV server interface
73
+ module Vortex
74
+
75
+ # TODO: Set a list of default priority xml namespace prefixes
76
+ # Can be done by monkey patching WebDAV module
77
+
78
+ $defaultCharacterEncoding = 'utf-8'
79
+
80
+
81
+ # Convert WebDAV URL to public web URL
82
+ # Examples:
83
+ # davUrl2webUrl("https://www-dav.uio.no/faq/it/basware.xml") => "http://www.uio.no/faq/it/basware.xml"
84
+ def self.davUrl2webUrl(url)
85
+ if(url =~ /^https:\/\/([^\/]*)-dav(\..*)/)then
86
+ return "http://" + $1 + $2
87
+ end
88
+ end
89
+
90
+ # Convert public/non-webdav url's to vortex-webdav-url's
91
+ def self.url2davUrl(url)
92
+ if(url =~ /^http:\/\/([^.]*)(\..*)/) then
93
+ return "https://" + $1 + "-dav" + $2
94
+ end
95
+ end
96
+
97
+
98
+ # Parse datestring
99
+ # Example:
100
+ # Recognizes "19.04.2009 12:00"
101
+ def self.parse_datestring(datestring)
102
+ # puts "DEBUG:" + datestring.class.to_s
103
+
104
+ if(datestring =~ /\d\d\.\d\d\.\d\d\d\d \d\d:\d\d/)then
105
+ date = DateTime.strptime(datestring, "%d.%m.%Y %H:%M")
106
+ # Regexp'en er et hack for å unngå at kl. 12:00 som input returnerer kl.14:00.
107
+ # Denne koden virker bare i norge. Trenger en måte å få lest ut tidssone på.
108
+ time = Time.parse(date.to_s.gsub(/\+00:00/,"+02:00"))
109
+ return time
110
+ end
111
+
112
+ return Time.parse(datestring)
113
+ end
114
+
115
+ # Publish article to Vortex CMS through WebDAV server.
116
+ def self.publish_article(url, title, introduction, content, published_date, *args)
117
+
118
+ if(not published_date)then
119
+ published_date = Time.now
120
+ end
121
+ if(published_date.class == String )
122
+ published_date = self.parse_datestring(published_date)
123
+ end
124
+ if(not title)then
125
+ title = ""
126
+ end
127
+
128
+ if(content =~ /\<html/ ) then
129
+ html = content
130
+ else
131
+ html = ARTICLE_HTML.gsub(/##title##/, title).gsub(/##content##/, content)
132
+ end
133
+
134
+ properties = ARTICLE_PROPERTIES.gsub(/##published-date##/, published_date.httpdate.to_s)
135
+ properties = properties.gsub(/##usertitle##/, title)
136
+
137
+ characterEncoding = $defaultCharacterEncoding
138
+
139
+ if(args)then
140
+ options = args[0]
141
+
142
+ if(options[:visualProfile] != nil and options[:visualProfile]== false)
143
+ # Default is true
144
+ properties += "<disabled xmlns=\"http://www.uio.no/visual-profile\">true</disabled>"
145
+ end
146
+
147
+ if(options[:authors])then
148
+ properties += AUTHORS.gsub(/##realname##/, options[:authors])
149
+ end
150
+
151
+ if(options[:owner])then
152
+ owner = options[:owner]
153
+ if(not owner =~ /@/)then
154
+ owner = owner + "@uio.no"
155
+ end
156
+ properties += "<v:owner xmlns:v=\"vrtx\">#{owner}</v:owner>"
157
+ end
158
+
159
+ if(options[:createdBy])then
160
+ createdBy = options[:createdBy]
161
+ if(not createdBy =~ /@/)then
162
+ createdBy = createdBy + "@uio.no"
163
+ end
164
+ properties += "<v:createdBy xmlns:v=\"vrtx\">#{createdBy}</v:createdBy>"
165
+ end
166
+
167
+ if(options[:contentModifiedBy])then
168
+ contentModifiedBy = options[:contentModifiedBy]
169
+ if(not contentModifiedBy =~ /@/)then
170
+ contentModifiedBy = contentModifiedBy + "@uio.no"
171
+ end
172
+ properties += "<v:contentModifiedBy xmlns:v=\"vrtx\">#{contentModifiedBy}</v:contentModifiedBy>"
173
+ end
174
+
175
+ if(options[:propertiesModifiedBy])then
176
+ propertiesModifiedBy = options[:propertiesModifiedBy]
177
+ if(not propertiesModifiedBy =~ /@/)then
178
+ propertiesModifiedBy = propertiesModifiedBy + "@uio.no"
179
+ end
180
+ properties += "<v:propertiesModifiedBy xmlns:v=\"vrtx\">#{propertiesModifiedBy}</v:propertiesModifiedBy>"
181
+ end
182
+
183
+ if(options[:modifiedBy])then
184
+ modifiedBy = options[:modifiedBy]
185
+ if(not modifiedBy =~ /@/)then
186
+ modifiedBy = modifiedBy + "@uio.no"
187
+ end
188
+ properties += "<v:contentModifiedBy xmlns:v=\"vrtx\">#{modifiedBy}</v:contentModifiedBy>"
189
+ properties += "<v:propertiesModifiedBy xmlns:v=\"vrtx\">#{modifiedBy}</v:propertiesModifiedBy>"
190
+ end
191
+
192
+ if(options[:characterEncoding])then
193
+ characterEncoding = options[:characterEncoding]
194
+ end
195
+
196
+ if(options[:contentLastModified])then
197
+ contentLastModified = options[:contentLastModified]
198
+ if(contentLastModified.class == String )
199
+ contentLastModified = self.parse_datestring(contentLastModified)
200
+ end
201
+ properties += "<v:contentLastModified xmlns:v=\"vrtx\">#{contentLastModified.httpdate.to_s}</v:contentLastModified>"
202
+ end
203
+
204
+
205
+ if(options[:propertiesLastModified])then
206
+ propertiesLastModified = options[:propertiesLastModified]
207
+ if(propertiesLastModified.class == String )
208
+ propertiesLastModified = self.parse_datestring(propertiesLastModified)
209
+ end
210
+ properties += "<v:propertiesLastModified xmlns:v=\"vrtx\">#{propertiesLastModified.httpdate.to_s}</v:propertiesLastModified>"
211
+ end
212
+
213
+ if(options[:creationDate])then
214
+ creationDate = options[:creationDate]
215
+
216
+ if(creationDate.class == Time)then
217
+ creationDateString = creationDate.httpdate.to_s ## xmlschema.to_s
218
+ end
219
+
220
+ if(creationDate.class == String)then
221
+ creationDateString = parse_datestring(creationDate).httpdate.to_s
222
+ end
223
+
224
+ properties += "<v:creationTime>#{creationDateString}</v:creationTime>"
225
+ end
226
+
227
+ end
228
+
229
+ properties = properties.gsub(/##characterEncoding##/, characterEncoding )
230
+
231
+ if(introduction) then
232
+ if(not introduction =~ /^<p>/)then
233
+ introduction = "<p>" + introduction + "</p>"
234
+ end
235
+ introduction = introduction.gsub(/</,"&lt;").gsub(/>/,"&gt;")
236
+ properties = properties + INTRODUCTION.gsub(/##introduction##/, introduction)
237
+ properties = properties.gsub("\n","").gsub(/ +/," ")
238
+ end
239
+
240
+ properties = properties.gsub("&amp;","&amp;&amp;")
241
+ # puts "Properties: " + properties
242
+
243
+ WebDAV.publish(url, html, properties )
244
+ return true
245
+ end
246
+
247
+ class Article
248
+
249
+ def initalize(url, *args)
250
+ end
251
+
252
+ def method_missing(method_name, *args)
253
+ # Detect article.createdBy = thomasfl
254
+ end
255
+
256
+ def update()
257
+ # Proppatch
258
+ end
259
+
260
+ end
261
+
262
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vrtx
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Thomas Flemming
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-09-18 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: davclient
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.5
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hpricot
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0.6"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: ZenTest
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "3.5"
44
+ version:
45
+ description: Client library and command line tool for managing content on webservers with WebDAV and the open source Vortex CMS.
46
+ email: thomas.flemming@gmail.com
47
+ executables:
48
+ - vrtx
49
+ extensions: []
50
+
51
+ extra_rdoc_files:
52
+ - README.rdoc
53
+ files:
54
+ - lib/vrtx.rb
55
+ - bin/vrtx
56
+ - lib/vrtx/article.rb
57
+ - README.rdoc
58
+ has_rdoc: true
59
+ homepage: http://folk.uio.no/thomasfl
60
+ licenses: []
61
+
62
+ post_install_message:
63
+ rdoc_options: []
64
+
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ requirements:
80
+ - cURL command line tool available from http://curl.haxx.se/
81
+ - Servername, username and password must be supplied in ~/.netrc file.
82
+ rubyforge_project: vrtx
83
+ rubygems_version: 1.3.5
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: Command line utility for Vortex CMS.
87
+ test_files: []
88
+