vrtx 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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
+