erp_tech_svcs 3.0.0

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 (109) hide show
  1. data/GPL-3-LICENSE +674 -0
  2. data/README.rdoc +2 -0
  3. data/Rakefile +30 -0
  4. data/app/assets/javascripts/erp_tech_svcs/application.js +9 -0
  5. data/app/assets/stylesheets/erp_tech_svcs/application.css +7 -0
  6. data/app/controllers/erp_tech_svcs/session_controller.rb +19 -0
  7. data/app/controllers/erp_tech_svcs/user_controller.rb +40 -0
  8. data/app/helpers/erp_tech_svcs/application_helper.rb +4 -0
  9. data/app/mailers/user_mailer.rb +16 -0
  10. data/app/models/audit_log.rb +60 -0
  11. data/app/models/audit_log_item.rb +4 -0
  12. data/app/models/audit_log_item_type.rb +6 -0
  13. data/app/models/audit_log_type.rb +24 -0
  14. data/app/models/capability.rb +8 -0
  15. data/app/models/capability_type.rb +3 -0
  16. data/app/models/capable_model.rb +4 -0
  17. data/app/models/encryption_key.rb +9 -0
  18. data/app/models/extensions/contact_purpose.rb +3 -0
  19. data/app/models/extensions/contact_type.rb +3 -0
  20. data/app/models/extensions/note.rb +6 -0
  21. data/app/models/extensions/note_type.rb +3 -0
  22. data/app/models/extensions/party.rb +3 -0
  23. data/app/models/extensions/relationship_type.rb +3 -0
  24. data/app/models/extensions/role_type.rb +3 -0
  25. data/app/models/file_asset.rb +178 -0
  26. data/app/models/role.rb +17 -0
  27. data/app/models/secured_model.rb +13 -0
  28. data/app/models/user.rb +33 -0
  29. data/app/views/layouts/application.html.erb +14 -0
  30. data/app/views/layouts/erp_tech_svcs/application.html.erb +14 -0
  31. data/app/views/user_mailer/activation_needed_email.html.erb +14 -0
  32. data/app/views/user_mailer/reset_password_email.html.erb +14 -0
  33. data/config/initializers/erp_tech_svcs.rb +7 -0
  34. data/config/initializers/file_support.rb +1 -0
  35. data/config/initializers/pdfkit.rb +18 -0
  36. data/config/initializers/sorcery.rb +199 -0
  37. data/config/routes.rb +9 -0
  38. data/db/data_migrations/20110802200222_schedule_delete_expired_sessions_job.rb +15 -0
  39. data/db/data_migrations/20111111144706_setup_audit_log_types.rb +21 -0
  40. data/db/migrate/20080805000010_base_tech_services.rb +247 -0
  41. data/db/migrate/20111109161549_add_capabilites.rb +56 -0
  42. data/db/migrate/upgrade/20111109161550_update_roles.rb +33 -0
  43. data/db/migrate/upgrade/20111109161551_update_user.rb +88 -0
  44. data/lib/erp_tech_svcs/application_installer.rb +102 -0
  45. data/lib/erp_tech_svcs/config.rb +27 -0
  46. data/lib/erp_tech_svcs/engine.rb +14 -0
  47. data/lib/erp_tech_svcs/extensions/active_record/acts_as_versioned.rb +494 -0
  48. data/lib/erp_tech_svcs/extensions/active_record/has_capabilities.rb +139 -0
  49. data/lib/erp_tech_svcs/extensions/active_record/has_file_assets.rb +40 -0
  50. data/lib/erp_tech_svcs/extensions/active_record/has_roles.rb +126 -0
  51. data/lib/erp_tech_svcs/extensions.rb +5 -0
  52. data/lib/erp_tech_svcs/file_support/aws_s3_patch.rb +3 -0
  53. data/lib/erp_tech_svcs/file_support/base.rb +30 -0
  54. data/lib/erp_tech_svcs/file_support/file_manipulator.rb +37 -0
  55. data/lib/erp_tech_svcs/file_support/file_system_manager.rb +167 -0
  56. data/lib/erp_tech_svcs/file_support/manager.rb +147 -0
  57. data/lib/erp_tech_svcs/file_support/paperclip_patch.rb +28 -0
  58. data/lib/erp_tech_svcs/file_support/railties/s3_resolver.rb +79 -0
  59. data/lib/erp_tech_svcs/file_support/s3_manager.rb +211 -0
  60. data/lib/erp_tech_svcs/file_support.rb +10 -0
  61. data/lib/erp_tech_svcs/sessions/delete_expired_sessions_job.rb +40 -0
  62. data/lib/erp_tech_svcs/sessions/delete_expired_sessions_service.rb +15 -0
  63. data/lib/erp_tech_svcs/utils/attachment_fu_patch.rb +15 -0
  64. data/lib/erp_tech_svcs/utils/compass_access_negotiator.rb +57 -0
  65. data/lib/erp_tech_svcs/utils/compass_logger.rb +94 -0
  66. data/lib/erp_tech_svcs/utils/compass_pdf.rb +72 -0
  67. data/lib/erp_tech_svcs/utils/default_nested_set_methods.rb +33 -0
  68. data/lib/erp_tech_svcs/utils/pdf_processor.rb +106 -0
  69. data/lib/erp_tech_svcs/version.rb +3 -0
  70. data/lib/erp_tech_svcs.rb +20 -0
  71. data/lib/tasks/erp_tech_svcs_tasks.rake +42 -0
  72. data/spec/dummy/Rakefile +7 -0
  73. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  74. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  75. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  76. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  77. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  78. data/spec/dummy/config/application.rb +43 -0
  79. data/spec/dummy/config/boot.rb +10 -0
  80. data/spec/dummy/config/database.yml +8 -0
  81. data/spec/dummy/config/environment.rb +5 -0
  82. data/spec/dummy/config/environments/spec.rb +27 -0
  83. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  84. data/spec/dummy/config/initializers/inflections.rb +10 -0
  85. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  86. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  87. data/spec/dummy/config/initializers/session_store.rb +8 -0
  88. data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
  89. data/spec/dummy/config/locales/en.yml +5 -0
  90. data/spec/dummy/config/routes.rb +3 -0
  91. data/spec/dummy/config.ru +4 -0
  92. data/spec/dummy/db/schema.rb +571 -0
  93. data/spec/dummy/db/spec.sqlite3 +0 -0
  94. data/spec/dummy/log/spec.log +2862 -0
  95. data/spec/dummy/public/404.html +26 -0
  96. data/spec/dummy/public/422.html +26 -0
  97. data/spec/dummy/public/500.html +26 -0
  98. data/spec/dummy/public/favicon.ico +0 -0
  99. data/spec/dummy/script/rails +6 -0
  100. data/spec/factories/capability_type.rb +5 -0
  101. data/spec/factories/role.rb +5 -0
  102. data/spec/factories/users.rb +9 -0
  103. data/spec/lib/erp_tech_svcs/extensions/active_record/has_roles_spec.rb +68 -0
  104. data/spec/models/audit_log_spec.rb +48 -0
  105. data/spec/models/audit_log_type_spec.rb +9 -0
  106. data/spec/models/role_spec.rb +17 -0
  107. data/spec/models/user_spec.rb +27 -0
  108. data/spec/spec_helper.rb +61 -0
  109. metadata +273 -0
@@ -0,0 +1,139 @@
1
+ module ErpTechSvcs
2
+ module Extensions
3
+ module ActiveRecord
4
+ module HasCapabilities
5
+
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+
12
+ def has_capabilities
13
+ extend HasCapabilities::SingletonMethods
14
+ include HasCapabilities::InstanceMethods
15
+
16
+ after_initialize :initialize_capable_model
17
+ after_update :save_capable_model
18
+ after_create :save_capable_model
19
+ after_destroy :destroy_capable_model
20
+
21
+ has_one :capable_model, :as => :capable_model_record
22
+ end
23
+ end
24
+
25
+ module SingletonMethods
26
+ end
27
+
28
+ module InstanceMethods
29
+ def capabilities
30
+ capable_model.capabilities
31
+ end
32
+
33
+ def available_capability_resources
34
+ capabilities.collect{|capability| capability.resource}.uniq
35
+ end
36
+
37
+ def capabilites_by_resource(resource)
38
+ self.capabilities.where('resource = ?', resource)
39
+ end
40
+
41
+ def user_has_capability?(capability_type, resource, user)
42
+ capability_type = convert_capability_type(capability_type)
43
+ raise ErpTechSvcs::Utils::CompassAccessNegotiator::Errors::CapabilityTypeDoesNotExist if capability_type.nil?
44
+
45
+ capability = self.capabilities.where('capability_type_id = ? and resource = ?', capability_type.id, resource).first
46
+ unless capability.nil?
47
+ capability.has_access?(user)
48
+ else
49
+ raise ErpTechSvcs::Utils::CompassAccessNegotiator::Errors::CapabilityDoesNotExist
50
+ end
51
+ end
52
+
53
+ def add_capability(capability_type, resource, *roles)
54
+ capability_type = convert_capability_type(capability_type)
55
+ raise ErpTechSvcs::Utils::CompassAccessNegotiator::Errors::CapabilityTypeDoesNotExist if capability_type.nil?
56
+
57
+ capability = self.capabilities.where('capability_type_id = ? and resource = ?', capability_type.id, resource).first
58
+ if capability.nil?
59
+ capability = Capability.create(:capability_type => capability_type, :resource => resource)
60
+ capability.add_roles(roles)
61
+ self.capable_model.capabilities << capability
62
+ self.capable_model.save
63
+ else
64
+ raise ErpTechSvcs::Utils::CompassAccessNegotiator::Errors::CapabilityAlreadytExists
65
+ end
66
+
67
+ capability
68
+ end
69
+
70
+ def update_capability(capability_type, resource, *roles)
71
+ capability_type = convert_capability_type(capability_type)
72
+ raise ErpTechSvcs::Utils::CompassAccessNegotiator::Errors::CapabilityTypeDoesNotExist if capability_type.nil?
73
+
74
+ capability = self.capabilities.where('capability_type_id = ? and resource = ?', capability_type.id, resource).first
75
+ unless capability.nil?
76
+ capability.remove_all_roles
77
+ capability.add_roles(roles)
78
+ else
79
+ raise ErpTechSvcs::Utils::CompassAccessNegotiator::Errors::CapabilityDoesNotExist
80
+ end
81
+ end
82
+
83
+ def remove_all_capabilities
84
+ self.capabilities.each do |capability|
85
+ remove_capability(capability.type, capability.resource)
86
+ end
87
+ end
88
+
89
+ def remove_capability(capability_type, resource)
90
+ capability_type = convert_capability_type(capability_type)
91
+ raise ErpTechSvcs::Utils::CompassAccessNegotiator::Errors::CapabilityTypeDoesNotExist if capability_type.nil?
92
+
93
+ capability = self.capabilities.where('capability_type_id = ? and resource = ?', capability_type.id, resource).first
94
+ unless capability.nil?
95
+ capability.destroy
96
+ else
97
+ raise ErpTechSvcs::Utils::CompassAccessNegotiator::Errors::CapabilityDoesNotExist
98
+ end
99
+ end
100
+
101
+ def capabilites_to_hash
102
+ self.capabilities.map do|capability|
103
+ {
104
+ :capability_type_iid => capability.type.internal_identifier,
105
+ :resource => capability.resource,
106
+ :roles => capability.roles.collect{|role| role.internal_identifier}
107
+ }
108
+ end
109
+ end
110
+
111
+ def initialize_capable_model
112
+ if self.capable_model.nil?
113
+ capable_model = CapableModel.new
114
+ self.capable_model = capable_model
115
+ capable_model.capable_model_record = self
116
+ end
117
+ end
118
+
119
+ def save_capable_model
120
+ capable_model.save
121
+ end
122
+
123
+ def destroy_capable_model
124
+ if self.capable_model && !self.capable_model.frozen?
125
+ self.capable_model.destroy
126
+ end
127
+ end
128
+
129
+ private
130
+
131
+ def convert_capability_type(type)
132
+ CapabilityType.find_by_internal_identifier(type.to_s) if (type.is_a?(String) || type.is_a?(Symbol))
133
+ end
134
+
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,40 @@
1
+ module ErpTechSvcs
2
+ module Extensions
3
+ module ActiveRecord
4
+ module HasFileAssets
5
+
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+ def has_file_assets
12
+ extend HasFileAssets::SingletonMethods
13
+ include HasFileAssets::InstanceMethods
14
+
15
+ has_many :files, :as => :file_asset_holder, :class_name => 'FileAsset', :dependent => :delete_all
16
+ end
17
+ end
18
+
19
+ module SingletonMethods
20
+ end
21
+
22
+ module InstanceMethods
23
+
24
+ def add_file(data, path=nil)
25
+ FileAsset.create!(:file_asset_holder => self, :base_path => path, :data => data)
26
+ end
27
+
28
+ def images
29
+ self.files.where('type = ?', 'Image')
30
+ end
31
+
32
+ def templates
33
+ self.files.where('type = ?', 'Template')
34
+ end
35
+
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,126 @@
1
+ module ErpTechSvcs
2
+ module Extensions
3
+ module ActiveRecord
4
+ module HasRoles
5
+
6
+ module Errors
7
+ exceptions = %w[UserDoesNotHaveAccess]
8
+ exceptions.each { |e| const_set(e, Class.new(StandardError)) }
9
+ end
10
+
11
+ def self.included(base)
12
+ base.extend(ClassMethods)
13
+ end
14
+
15
+ module ClassMethods
16
+ def has_roles
17
+ extend HasRoles::SingletonMethods
18
+ include HasRoles::InstanceMethods
19
+
20
+ after_initialize :initialize_secured_model
21
+ after_update :save_secured_model
22
+ after_create :save_secured_model
23
+ after_destroy :destroy_secured_model
24
+
25
+ has_one :secured_model, :as => :secured_record
26
+ end
27
+ end
28
+
29
+ module SingletonMethods
30
+ end
31
+
32
+ module InstanceMethods
33
+ def roles
34
+ self.secured_model.roles
35
+ end
36
+
37
+ def has_access?(user)
38
+ has_access = true
39
+ unless self.secured_model.roles.empty?
40
+ has_access = if user.nil?
41
+ false
42
+ else
43
+ user.has_role?(self.secured_model.roles.collect{|item| item.internal_identifier})
44
+ end
45
+ end
46
+ has_access
47
+ end
48
+
49
+ def with_access(user, &block)
50
+ if has_access?(user)
51
+ yield
52
+ else
53
+ raise ErpTechSvcs::Extensions::ActiveRecord::HasRoles::UserDoesNotHaveAccess
54
+ end
55
+ end
56
+
57
+ def add_role(role)
58
+ role = Role.find_by_internal_identifier(role) if role.is_a? String
59
+ unless self.has_role?(role)
60
+ self.secured_model.roles << role
61
+ self.secured_model.save
62
+ end
63
+ end
64
+
65
+ def add_roles(*roles)
66
+ roles.flatten!
67
+ roles = roles[0] if roles[0].is_a? Array
68
+ roles.each do |role|
69
+ self.add_role(role)
70
+ end
71
+ end
72
+
73
+ def remove_role(role)
74
+ role = Role.find_by_internal_identifier(role) if role.is_a? String
75
+ self.secured_model.roles.delete(role) if has_role?(role)
76
+ end
77
+
78
+ def remove_roles(*roles)
79
+ roles.flatten!
80
+ roles.each do |role|
81
+ self.remove_role(role)
82
+ end
83
+ end
84
+
85
+ def remove_all_roles
86
+ self.roles.delete_all
87
+ end
88
+
89
+ def has_role?(*passed_roles)
90
+ result = false
91
+ passed_roles.flatten!
92
+ passed_roles.each do |role|
93
+ role_iid = (role.is_a?(String)) ? role : role.internal_identifier
94
+ self.roles.each do |this_role|
95
+ result = true if (this_role.internal_identifier == role_iid)
96
+ break if result
97
+ end
98
+ break if result
99
+ end
100
+ result
101
+ end
102
+
103
+ def initialize_secured_model
104
+ if self.new_record? && self.secured_model.nil?
105
+ secured_model = SecuredModel.new
106
+ self.secured_model = secured_model
107
+ secured_model.secured_record = self
108
+ end
109
+ end
110
+
111
+ def save_secured_model
112
+ secured_model.save
113
+ end
114
+
115
+ def destroy_secured_model
116
+ if self.secured_model && !self.secured_model.frozen?
117
+ self.secured_model.destroy
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+
@@ -0,0 +1,5 @@
1
+ #active record extensions
2
+ require 'erp_tech_svcs/extensions/active_record/has_file_assets'
3
+ require 'erp_tech_svcs/extensions/active_record/has_roles'
4
+ require 'erp_tech_svcs/extensions/active_record/has_capabilities'
5
+ require 'erp_tech_svcs/extensions/active_record/acts_as_versioned'
@@ -0,0 +1,3 @@
1
+ Module.class_eval do
2
+ alias_method :const_missing, :const_missing_not_from_s3_library
3
+ end
@@ -0,0 +1,30 @@
1
+ module ErpTechSvcs
2
+ module FileSupport
3
+ DEFAULT_OPTIONS = {
4
+ :storage => :filesystem
5
+ }
6
+
7
+ mattr_accessor :options
8
+ @@options = HashWithIndifferentAccess.new(DEFAULT_OPTIONS)
9
+
10
+ class Base
11
+ attr_accessor :storage
12
+
13
+ def initialize(options={})
14
+ @storage = options[:storage].nil? ? :filesystem : options[:storage]
15
+
16
+ case @storage
17
+ when :s3
18
+ @manager = S3Manager.new
19
+ when :filesystem
20
+ @manager = FileSystemManager.new
21
+ end
22
+ end
23
+
24
+ def method_missing(m, *args, &block)
25
+ @manager.respond_to?(m) ? @manager.send(m, *args) : super
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,37 @@
1
+ module ErpTechSvcs
2
+ class FileManipulator
3
+ class << self
4
+
5
+ def patch_file(path, current, insert, options = {})
6
+ options = {
7
+ :patch_mode => :insert_after
8
+ }.merge(options)
9
+
10
+ old_text = current
11
+ new_text = patch_string(current, insert, options[:patch_mode])
12
+
13
+ content = File.open(path) { |f| f.read }
14
+ content.gsub!(old_text, new_text) unless content =~ /#{Regexp.escape(insert)}/mi
15
+ File.open(path, 'w') { |f| f.puts(content) }
16
+ end
17
+
18
+ def append_file(path, content)
19
+ File.open(path, 'a') { |f| f.puts(content) }
20
+ end
21
+
22
+ def patch_string(current, insert, mode = :insert_after)
23
+ case mode
24
+ when :change
25
+ "#{insert}"
26
+ when :insert_after
27
+ "#{current}\n#{insert}"
28
+ when :insert_before
29
+ "#{insert}\n#{current}"
30
+ else
31
+ patch_string(current, insert, :insert_after)
32
+ end
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,167 @@
1
+ module ErpTechSvcs
2
+ module FileSupport
3
+ class FileSystemManager < Manager
4
+ REMOVE_FILES_REGEX = /^\./
5
+
6
+ def root
7
+ File.join(Rails.root,'public')
8
+ end
9
+
10
+ def update_file(path, content)
11
+ File.open(path, 'w+') {|f| f.puts(content) }
12
+ end
13
+
14
+ def create_file(path, name, contents)
15
+ FileUtils.mkdir_p path unless File.exists? path
16
+ File.open(File.join(path,name), 'w+') {|f| f.puts(contents) }
17
+ end
18
+
19
+ def create_folder(path, name)
20
+ FileUtils.mkdir_p File.join(path,name) unless File.directory? File.join(path,name)
21
+ end
22
+
23
+ def save_move(path, new_parent_path)
24
+ result = nil
25
+ unless File.exists? path
26
+ message = 'File does not exists'
27
+ else
28
+ name = File.basename(path)
29
+ #make sure path is there.
30
+ FileUtils.mkdir_p new_parent_path unless File.directory? new_parent_path
31
+ FileUtils.mv(path, new_parent_path + '/' + name)
32
+ message = "#{name} was moved to #{new_parent_path} successfully"
33
+ result = true
34
+ end
35
+
36
+ return result, message
37
+ end
38
+
39
+ def exists?(path)
40
+ File.exists? path
41
+ end
42
+
43
+ def rename_file(path, name)
44
+ result = nil
45
+ unless File.exists? path
46
+ message = 'File does not exists'
47
+ else
48
+ old_name = File.basename(path)
49
+ path_pieces = path.split('/')
50
+ path_pieces.delete(path_pieces.last)
51
+ path_pieces.push(name)
52
+ new_path = path_pieces.join('/')
53
+ File.rename(path, new_path)
54
+ message = "#{old_name} was renamed to #{name} successfully"
55
+ result = true
56
+ end
57
+
58
+ return result, message
59
+ end
60
+
61
+ def delete_file(path, options={})
62
+ result = nil
63
+ name = File.basename(path)
64
+ is_directory = false
65
+ if !File.exists? path and !File.directory? path
66
+ message = 'File / Folder does not exist'
67
+ else
68
+ if File.directory? path
69
+ is_directory = true
70
+ entries = Dir.entries(path)
71
+ entries.delete_if{|entry| entry =~ REMOVE_FILES_REGEX}
72
+ if entries.count > 0 && !options[:force]
73
+ message = "Folder is not empty"
74
+ result = false;
75
+ else
76
+ FileUtils.rm_rf(path)
77
+ message = "Folder #{name} was deleted #{name} successfully"
78
+ result = true
79
+ end
80
+ else
81
+ FileUtils.rm_rf(path)
82
+ message = "File #{name} was deleted #{name} successfully"
83
+ result = true
84
+ end
85
+ end
86
+
87
+ return result, message, is_directory
88
+ end
89
+
90
+ def get_contents(path)
91
+ contents = nil
92
+ message = nil
93
+ unless File.exists? path
94
+ message = 'File does not exists'
95
+ else
96
+ contents = IO.read(path)
97
+ end
98
+ return contents, message
99
+ end
100
+
101
+ def build_tree(starting_path, options={})
102
+ find_node(starting_path, options)
103
+ end
104
+
105
+ def find_node(path, options={})
106
+ parent = if options[:file_asset_holder]
107
+ super
108
+ else
109
+ path_pieces = path.split('/')
110
+ parent = build_tree_for_directory(path, options)
111
+ unless parent[:id] == path
112
+ path_pieces.each do |path_piece|
113
+ next if path_piece.blank?
114
+ parent[:children].each do |child_node|
115
+ if child_node[:text] == path_piece
116
+ parent = child_node
117
+ break
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ parent = nil if parent[:id] != path
124
+ parent
125
+ end
126
+
127
+ parent
128
+ end
129
+
130
+ private
131
+
132
+ def build_tree_for_directory(directory, options)
133
+ keep_full_path = nil
134
+ if directory.index(Rails.root.to_s).nil?
135
+ tree_data = {:text => directory.split('/').last, :id => directory, :leaf => false, :children => []}
136
+ else
137
+ keep_full_path = true
138
+ tree_data = {:text => directory.split('/').last, :id => directory, :leaf => false, :children => []}
139
+ end
140
+
141
+ Dir.entries(directory).each do |entry|
142
+ #ignore .svn folders and any other folders starting with .
143
+ next if entry =~ REMOVE_FILES_REGEX
144
+
145
+ path = File.join(directory, entry)
146
+ path.gsub!(root,'') unless keep_full_path
147
+
148
+ if File.directory?(File.join(directory,entry))
149
+ tree_data[:children] << if options[:preload]
150
+ build_tree_for_directory(path, options) if options[:preload]
151
+ else
152
+ {:text => entry, :id => path}
153
+ end
154
+ elsif !options[:included_file_extensions_regex].nil? && entry =~ options[:included_file_extensions_regex]
155
+ tree_data[:children] << {:text => entry, :leaf => true, :downloadPath => path, :id => path}
156
+ elsif options[:included_file_extensions_regex].nil?
157
+ tree_data[:children] << {:text => entry, :leaf => true, :downloadPath => path, :id => path}
158
+ end
159
+ end if File.directory?(directory)
160
+
161
+ tree_data[:children].sort_by{|item| [item[:id]]}
162
+ tree_data
163
+ end
164
+
165
+ end#FileSystemManager
166
+ end#FileSupport
167
+ end#ErpTechSvcs
@@ -0,0 +1,147 @@
1
+ module ErpTechSvcs
2
+ module FileSupport
3
+ class Manager
4
+
5
+ class << self
6
+ def find_parent(item, parents)
7
+ parents.find do |parent|
8
+ path = item[:path].gsub(item[:text],'').split('/').join('/')
9
+ parent[:id] == path
10
+ end
11
+ end
12
+ end
13
+
14
+ def sync(path, model)
15
+ result = nil
16
+ message = nil
17
+
18
+ node = find_node(path)
19
+ if node.nil?
20
+ message = "Nothing to sync"
21
+ else
22
+ sync_node(node, model)
23
+ message = "Sync successful"
24
+ result = true
25
+ end
26
+
27
+ return result, message
28
+ end
29
+
30
+ def find_node(path, options={})
31
+ node_tree = build_file_assets_tree_for_model(options[:file_asset_holder], path.gsub(root, ''))
32
+
33
+ path_pieces = path.split('/')
34
+ parent = node_tree.first
35
+ path_pieces.each do |path_piece|
36
+ next if path_piece.blank?
37
+ parent[:children].each do |child_node|
38
+ if child_node[:text] == path_piece
39
+ parent = child_node
40
+ break
41
+ end
42
+ end
43
+ end
44
+
45
+ path.sub!(self.root,'') if parent[:id].scan(self.root).empty?
46
+ path = File.join(self.root, path) if !parent[:id].scan(self.root).empty? and path.scan(self.root).empty?
47
+
48
+ parent = [] if parent[:id] != path
49
+ parent
50
+ end
51
+
52
+ def build_file_assets_tree_for_model(model, starting_path)
53
+ node_tree = [{:text => root, :leaf => false, :id => root, :children => []}]
54
+
55
+ paths = model.files.collect{|file| File.join(file.directory,file.name)}
56
+
57
+ node_tree.first[:children] << {:id => starting_path, :text => starting_path.split('/').last, :children => []} if paths.select{|path| path.split('/')[1] == starting_path.split('/')[1]}.empty?
58
+
59
+ nesting_depth = paths.collect{|item| item.split('/').count}.max
60
+ unless nesting_depth.nil?
61
+ levels = []
62
+ (1..nesting_depth).each do |i|
63
+ current_items = []
64
+ objects_this_depth = paths.collect{|item|
65
+ text = item.split('/')[i - 1]
66
+ path = item.split('/')[0..(i-1)].join('/')
67
+ if item.split('/').count >= i && current_items.select{|item| item[:text] == text and item[:path] == path}.empty?
68
+ item_hash = {:text => text, :path => path}
69
+ current_items << item_hash
70
+ item_hash
71
+ end
72
+ }
73
+ objects_this_depth.delete_if{|item| (item.nil? or item[:text].blank?)}
74
+ levels << objects_this_depth unless objects_this_depth.empty?
75
+ end
76
+
77
+ old_parents = []
78
+ new_parents = [node_tree[0]]
79
+ levels.each do |level|
80
+ old_parents = new_parents
81
+ new_parents = []
82
+ level.each do |item|
83
+ parent = old_parents.count == 1 ? old_parents.first : self.class.find_parent(item, old_parents)
84
+ path = File.join(parent[:id], item[:text]).gsub(root, '')
85
+ child_hash = {:text => item[:text], :downloadPath => path, :leaf => !File.extname(item[:text]).blank?, :id => path, :children => []}
86
+ new_parents << child_hash
87
+ parent[:children] << child_hash
88
+ end
89
+ end
90
+ end
91
+
92
+ insert_folders(node_tree.first[:children])
93
+
94
+ node_tree
95
+ end
96
+
97
+ def insert_folders(file_asset_nodes)
98
+ file_asset_nodes.each do |child_asset_node|
99
+ node = find_node(File.join(self.root,child_asset_node[:id]))
100
+ folders = node[:children].select{|item| !item[:leaf]}
101
+ child_asset_node[:children] = [] if child_asset_node[:children].nil? && !folders.empty?
102
+ folders.each do |folder|
103
+ folder[:id].gsub!(self.root,'')
104
+ child_asset_node[:children] << folder unless child_asset_node[:children].collect{|child_node| child_node[:text] }.include?(folder[:text])
105
+ end
106
+ insert_folders(child_asset_node[:children])
107
+ end unless file_asset_nodes.nil?
108
+ end
109
+
110
+ private
111
+
112
+ def sync_node(node, model)
113
+ leaves = get_all_leaves(node)
114
+ leaves.each do |leaf|
115
+ create_file_asset_for_node(leaf, model)
116
+ end
117
+
118
+ model.files.find(:all, :conditions => "directory like '#{node[:id].sub(self.root, '')}%'").each do |file_asset|
119
+ unless self.exists? File.join(self.root, file_asset.directory, file_asset.name)
120
+ puts "File #{File.join(self.root, file_asset.directory, file_asset.name)} does not exists removing"
121
+ file_asset.destroy
122
+ end
123
+ end
124
+ end
125
+
126
+ def get_all_leaves(node)
127
+ node[:children].map{|child_node| child_node[:leaf] ? child_node : get_all_leaves(child_node) }.flatten
128
+ end
129
+
130
+ def create_file_asset_for_node(node, model)
131
+ name = File.basename(node[:id])
132
+ directory = File.dirname(node[:id])
133
+ file_asset = model.files.find(:first, :conditions => ['directory = ? and name = ?', directory, name])
134
+
135
+ if file_asset.nil?
136
+ contents = get_contents(node[:id]).to_s
137
+ begin
138
+ model.add_file(contents, node[:id])
139
+ rescue Exception=>ex
140
+ #the file might already exist if it is in the file system.
141
+ end
142
+ end
143
+ end
144
+
145
+ end#Manager
146
+ end#FileSupport
147
+ end#ErpTechSvcs