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 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
@@ -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,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'vortex_utils'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -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