erp_tech_svcs 3.0.0

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