vortex_utils 0.0.1
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.
- data/VERSION +1 -0
- data/lib/vortex_utils/string_extensions.rb +83 -0
- data/lib/vortex_utils.rb +138 -0
- data/test/helper.rb +10 -0
- data/test/test_net_dav_extensions.rb +67 -0
- data/test/test_string_extensions.rb +18 -0
- metadata +88 -0
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'iconv'
|
3
|
+
|
4
|
+
# Utilities useful for adding content to Content Management Systems
|
5
|
+
|
6
|
+
class String
|
7
|
+
|
8
|
+
# Turn a normal sentence into a valid, readable filename.
|
9
|
+
#
|
10
|
+
# Example:
|
11
|
+
#
|
12
|
+
# "A small test".to_readable_url
|
13
|
+
# => "a-small-test"
|
14
|
+
def to_readable_url
|
15
|
+
sentence = self
|
16
|
+
if(sentence.size > 10)then
|
17
|
+
truncated_title = sentence.sub(/:.*/,"").sub(/;/,"").sub(/&/,"").sub(/\(/,"").sub(/\)/,"")
|
18
|
+
html_filename = truncated_title.snake_case
|
19
|
+
else
|
20
|
+
html_filename = sentence.snake_case
|
21
|
+
end
|
22
|
+
|
23
|
+
# Just keep the 100 first chars, to nearest word.
|
24
|
+
if(html_filename.size > 100)then
|
25
|
+
html_filename = html_filename.gsub(/\.html$/,"")
|
26
|
+
html_filename = html_filename[0..100]
|
27
|
+
html_filename = html_filename.gsub(/_[^_]*$/,"") + ".html"
|
28
|
+
end
|
29
|
+
return html_filename
|
30
|
+
end
|
31
|
+
|
32
|
+
def snake_case
|
33
|
+
camel_cased_word_input = self
|
34
|
+
camel_cased_word = camel_cased_word_input + "" # create local copy of string
|
35
|
+
camel_cased_word = camel_cased_word.transliterate_accents
|
36
|
+
camel_cased_word = camel_cased_word.to_s.gsub(/::/, '/').
|
37
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1\2').
|
38
|
+
gsub(/([a-z\d])([A-Z])/,'\1\2').downcase
|
39
|
+
|
40
|
+
camel_cased_word = camel_cased_word.to_s.gsub(/ /,'-')
|
41
|
+
camel_cased_word = camel_cased_word.to_s.gsub(/^_/,'')
|
42
|
+
camel_cased_word = camel_cased_word.gsub("__","_")
|
43
|
+
|
44
|
+
# sanitize the string
|
45
|
+
camel_cased_word = camel_cased_word.gsub(/[^a-z._0-9 -]/i, "").
|
46
|
+
tr(".", "_").gsub(/(\s+)/, "_").gsub(/_/, '-').downcase
|
47
|
+
camel_cased_word = camel_cased_word.to_s.gsub(/--*/,'-')
|
48
|
+
return camel_cased_word
|
49
|
+
end
|
50
|
+
|
51
|
+
# Filter accents and some special characters
|
52
|
+
def transliterate_accents
|
53
|
+
str = self
|
54
|
+
accents = {
|
55
|
+
['á','à','â','ä','ã','Ã','Ä','Â','À'] => 'a',
|
56
|
+
['é','è','ê','ë','Ë','É','È','Ê'] => 'e',
|
57
|
+
['í','ì','î','ï','I','Î','Ì'] => 'i',
|
58
|
+
['ó','ò','ô','ö','õ','Õ','Ö','Ô','Ò'] => 'o',
|
59
|
+
['ñ'] => 'n',
|
60
|
+
['œ'] => 'e',
|
61
|
+
['ß'] => 'ss',
|
62
|
+
['ú','ù','û','ü','U','Û','Ù'] => 'u',
|
63
|
+
['æ'] => 'ae',
|
64
|
+
['ø'] => 'o',
|
65
|
+
['å'] => 'a',
|
66
|
+
['Æ'] => 'ae',
|
67
|
+
['Ø'] => 'o',
|
68
|
+
['Å'] => 'a',
|
69
|
+
['§'] => ''
|
70
|
+
}
|
71
|
+
accents.each do |ac,rep|
|
72
|
+
ac.each do |s|
|
73
|
+
str.gsub!(s, rep)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Remove the rest of the accents and special characters
|
78
|
+
conv = Iconv.new("ASCII//TRANSLIT//IGNORE", "UTF-8")
|
79
|
+
str = conv.iconv(str)
|
80
|
+
return str
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
data/lib/vortex_utils.rb
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
require_relative 'vortex_utils/string_extensions'
|
2
|
+
|
3
|
+
# Utilites used to access the Vortex CMS from the WebDAV protocol and do common tasks
|
4
|
+
|
5
|
+
require 'net/dav'
|
6
|
+
require 'uri'
|
7
|
+
require 'highline/import'
|
8
|
+
require 'time'
|
9
|
+
require 'json'
|
10
|
+
|
11
|
+
module Net
|
12
|
+
|
13
|
+
class DAV
|
14
|
+
|
15
|
+
def initialize(uri, *args)
|
16
|
+
@uri = uri
|
17
|
+
@uri = URI.parse(@uri) if @uri.is_a? String
|
18
|
+
@have_curl = false # This defaults to true in Net::DAV
|
19
|
+
@handler = NetHttpHandler.new(@uri)
|
20
|
+
@handler.verify_server = false # This defaults to true in Net::DAV
|
21
|
+
if(args != [])
|
22
|
+
if(args[0][:use_osx_keychain] or args[0][:osx_keychain])then
|
23
|
+
|
24
|
+
# Retrieve password from OS X KeyChain.
|
25
|
+
osx = (RUBY_PLATFORM =~ /darwin/)
|
26
|
+
if(osx)then
|
27
|
+
require 'osx_keychain'
|
28
|
+
keychain = OSXKeychain.new
|
29
|
+
user = ENV['USER']
|
30
|
+
|
31
|
+
if(args[0][:prompt_for_password])
|
32
|
+
response = `security delete-generic-password -s #{@uri.host}`
|
33
|
+
require 'pry'
|
34
|
+
binding.pry
|
35
|
+
end
|
36
|
+
|
37
|
+
pass = keychain[@uri.host, user ]
|
38
|
+
|
39
|
+
if(pass == nil) then
|
40
|
+
puts "Password not found on OS X KeyChain. "
|
41
|
+
puts "Enter password to store new password on OS X KeyChain."
|
42
|
+
## @handler.user = ask("Username: ") {|q| q.echo = true}
|
43
|
+
## Todo: store username in a config file so we can have
|
44
|
+
## different username locally and on server
|
45
|
+
pass = ask("Password: ") {|q| q.echo = "*"} # false => no echo
|
46
|
+
keychain[@uri.host, user] = pass
|
47
|
+
puts "Password for '#{user}' on '#{@uri.host}' stored on OS X KeyChain."
|
48
|
+
@handler.user = user
|
49
|
+
@handler.pass = pass
|
50
|
+
else
|
51
|
+
@handler.user = user
|
52
|
+
@handler.pass = pass
|
53
|
+
end
|
54
|
+
return @handler
|
55
|
+
|
56
|
+
else
|
57
|
+
puts "Warning: Not running on OS X."
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
@handler.user = args[0]
|
62
|
+
@handler.pass = args[1]
|
63
|
+
else
|
64
|
+
@handler.user = ask("Username: ") {|q| q.echo = true}
|
65
|
+
@handler.pass = ask("Password: ") {|q| q.echo = "*"} # false => no echo
|
66
|
+
end
|
67
|
+
return @handler
|
68
|
+
end
|
69
|
+
|
70
|
+
# Set the publish date to current timestamp
|
71
|
+
def vortex_publish!(uri)
|
72
|
+
proppatch(uri, '<v:publish-date xmlns:v="vrtx">' + Time.now.httpdate.to_s + '</v:publish-date>')
|
73
|
+
end
|
74
|
+
|
75
|
+
def vortex_publish(uri,time)
|
76
|
+
proppatch(uri, '<v:publish-date xmlns:v="vrtx">' + time.httpdate.to_s + '</v:publish-date>')
|
77
|
+
end
|
78
|
+
|
79
|
+
def vortex_unpublish!(uri)
|
80
|
+
proppatch(uri, '<v:unpublish-date xmlns:v="vrtx">' +Time.now.httpdate.to_s + '</v:unpublish-date>')
|
81
|
+
end
|
82
|
+
|
83
|
+
def vortex_unpublish(uri, time)
|
84
|
+
proppatch(uri, '<v:unpublish-date xmlns:v="vrtx">' + time.httpdate.to_s + '</v:unpublish-date>')
|
85
|
+
end
|
86
|
+
|
87
|
+
# Create path - create all folders in the given path if they do not exist.
|
88
|
+
#
|
89
|
+
# Default is article-listing folder and the foldername used as title.
|
90
|
+
#
|
91
|
+
# Example:
|
92
|
+
#
|
93
|
+
# create_path('/folders/to/be/created/')
|
94
|
+
# create_path('/folders/to/be/created/', :type => "event-listing", :title => "Testing")
|
95
|
+
def create_path(dest_path, *args)
|
96
|
+
title = nil
|
97
|
+
if(args.size > 0)then
|
98
|
+
type = args[0][:type]
|
99
|
+
title = args[0][:title]
|
100
|
+
end
|
101
|
+
if(not(type))then
|
102
|
+
type = "article-listing"
|
103
|
+
end
|
104
|
+
|
105
|
+
destination_path = "/"
|
106
|
+
dest_path.split("/").each do |folder|
|
107
|
+
if(folder != "")then
|
108
|
+
folder = folder.downcase
|
109
|
+
destination_path = destination_path + folder + "/"
|
110
|
+
if( not(exists?(destination_path)) )then
|
111
|
+
mkdir(destination_path)
|
112
|
+
proppatch(destination_path,'<v:collection-type xmlns:v="vrtx">' + type + '</v:collection-type>')
|
113
|
+
if(title)then
|
114
|
+
proppatch(destination_path,'<v:userTitle xmlns:v="vrtx">' + title.to_s + '</v:userTitle>')
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
return destination_path
|
120
|
+
end
|
121
|
+
|
122
|
+
def set_vortex_collection_title(uri, title)
|
123
|
+
proppatch(uri,'<v:userTitle xmlns:v="vrtx">' + title.to_s + '</v:userTitle>')
|
124
|
+
end
|
125
|
+
|
126
|
+
def set_vortex_collection_type(uri, type)
|
127
|
+
proppatch(uri,'<v:collection-type xmlns:v="vrtx">' + type + '</v:collection-type>')
|
128
|
+
end
|
129
|
+
|
130
|
+
def hide_vortex_collection(uri)
|
131
|
+
proppatch(uri, '<hidden xmlns="http://www.uio.no/navigation">true</hidden>')
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
end
|
138
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require_relative 'helper'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
class NetDAVExtensions < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
uri = 'https://www-dav.usit.uio.no/om/organisasjon/web/wapp/ansatte/thomasfl/vortex-script/test/'
|
9
|
+
@dav = Net::DAV.new(uri,:osx_keychain => true)
|
10
|
+
end
|
11
|
+
|
12
|
+
should "delete password from keychain and prompt for password" do
|
13
|
+
# dav = Net::DAV.new("https://www-dav.usit.uio.no/om/organisasjon/web/wapp/ansatte/thomasfl/vortex-script/test/",
|
14
|
+
# :osx_keychain => true, :prompt_for_password => true)
|
15
|
+
end
|
16
|
+
|
17
|
+
should "publish article" do
|
18
|
+
tittel = "My little testing article ÆØÅ"
|
19
|
+
|
20
|
+
article = {
|
21
|
+
"resourcetype" => "structured-article",
|
22
|
+
"properties" => {
|
23
|
+
"title" => tittel,
|
24
|
+
"introduction" => "Dette er innledningen til artikkelen",
|
25
|
+
"content" => "<p>Her er innholdet i artikkelen</p>"
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
filename = tittel.to_readable_url + '.html'
|
30
|
+
@dav.put_string(filename, article.to_json)
|
31
|
+
@dav.vortex_publish!(filename)
|
32
|
+
assert @dav.exists?(filename)
|
33
|
+
end
|
34
|
+
|
35
|
+
should "set publish date to 2 days ahead and unpublish date to 3 days" do
|
36
|
+
article = {
|
37
|
+
"resourcetype" => "structured-article",
|
38
|
+
"properties" => {
|
39
|
+
"title" => "Test article",
|
40
|
+
"introduction" => "Dette er innledningen til artikkelen",
|
41
|
+
"content" => "<p>Her er innholdet i artikkelen</p>"
|
42
|
+
}
|
43
|
+
}
|
44
|
+
@dav.put_string('test-article.html', article.to_json)
|
45
|
+
@dav.vortex_publish('test-article.html', Time.now + (2*24*60*60))
|
46
|
+
@dav.vortex_unpublish('test-article.html', Time.now + (3*24*60*60))
|
47
|
+
end
|
48
|
+
|
49
|
+
should "create paths and set type" do
|
50
|
+
path = '/om/organisasjon/web/wapp/ansatte/thomasfl/vortex-script/test/'
|
51
|
+
@dav.create_path(path + 'folders/to/be/created', :type => "article-listing")
|
52
|
+
assert(@dav.exists?(path + 'folders/to/be/created'))
|
53
|
+
@dav.delete(path + 'folders')
|
54
|
+
assert( !@dav.exists?(path + 'folders') )
|
55
|
+
|
56
|
+
folder_path = path + 'test_folder'
|
57
|
+
if(@dav.exists?(folder_path))
|
58
|
+
@dav.delete(folder_path)
|
59
|
+
end
|
60
|
+
@dav.mkdir(folder_path)
|
61
|
+
@dav.set_vortex_collection_title(folder_path,'En tittel')
|
62
|
+
@dav.set_vortex_collection_type(folder_path,'article-listing')
|
63
|
+
@dav.hide_vortex_collection(folder_path)
|
64
|
+
@dav.delete(folder_path)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require_relative 'helper'
|
3
|
+
|
4
|
+
class TestStringExtensions < Test::Unit::TestCase
|
5
|
+
|
6
|
+
should "transliterate accents nicesly" do
|
7
|
+
assert "ñâñôñä".transliterate_accents == "nanona"
|
8
|
+
end
|
9
|
+
|
10
|
+
should "snake case sentences" do
|
11
|
+
assert "one two three".snake_case == "one-two-three"
|
12
|
+
end
|
13
|
+
|
14
|
+
should "make sentences into strings usable for readable urls" do
|
15
|
+
assert "this is a çircûmflexed senteñce".to_readable_url == "this-is-a-circumflexed-sentence"
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vortex_utils
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Thomas Flemming
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-01 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: net_dav
|
16
|
+
requirement: &2156218200 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.5.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2156218200
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: highline
|
27
|
+
requirement: &2156217040 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.6.9
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2156217040
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: thoughtbot-shoulda
|
38
|
+
requirement: &2156215100 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.11.1
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2156215100
|
47
|
+
description: Utilities for managing content on Vortex web content management system
|
48
|
+
through webdav
|
49
|
+
email: thomas.flemming@usit.uio.no
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- VERSION
|
55
|
+
- lib/vortex_utils.rb
|
56
|
+
- lib/vortex_utils/string_extensions.rb
|
57
|
+
- test/helper.rb
|
58
|
+
- test/test_net_dav_extensions.rb
|
59
|
+
- test/test_string_extensions.rb
|
60
|
+
homepage: http://github.com/thomasfl/vortex_utils
|
61
|
+
licenses: []
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options:
|
64
|
+
- --charset=UTF-8
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ! '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubyforge_project:
|
81
|
+
rubygems_version: 1.8.10
|
82
|
+
signing_key:
|
83
|
+
specification_version: 3
|
84
|
+
summary: Vortex CMS utilites
|
85
|
+
test_files:
|
86
|
+
- test/helper.rb
|
87
|
+
- test/test_net_dav_extensions.rb
|
88
|
+
- test/test_string_extensions.rb
|