vortex_utils 0.0.1

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