erp_tech_svcs 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/GPL-3-LICENSE +674 -0
- data/README.rdoc +2 -0
- data/Rakefile +30 -0
- data/app/assets/javascripts/erp_tech_svcs/application.js +9 -0
- data/app/assets/stylesheets/erp_tech_svcs/application.css +7 -0
- data/app/controllers/erp_tech_svcs/session_controller.rb +19 -0
- data/app/controllers/erp_tech_svcs/user_controller.rb +40 -0
- data/app/helpers/erp_tech_svcs/application_helper.rb +4 -0
- data/app/mailers/user_mailer.rb +16 -0
- data/app/models/audit_log.rb +60 -0
- data/app/models/audit_log_item.rb +4 -0
- data/app/models/audit_log_item_type.rb +6 -0
- data/app/models/audit_log_type.rb +24 -0
- data/app/models/capability.rb +8 -0
- data/app/models/capability_type.rb +3 -0
- data/app/models/capable_model.rb +4 -0
- data/app/models/encryption_key.rb +9 -0
- data/app/models/extensions/contact_purpose.rb +3 -0
- data/app/models/extensions/contact_type.rb +3 -0
- data/app/models/extensions/note.rb +6 -0
- data/app/models/extensions/note_type.rb +3 -0
- data/app/models/extensions/party.rb +3 -0
- data/app/models/extensions/relationship_type.rb +3 -0
- data/app/models/extensions/role_type.rb +3 -0
- data/app/models/file_asset.rb +178 -0
- data/app/models/role.rb +17 -0
- data/app/models/secured_model.rb +13 -0
- data/app/models/user.rb +33 -0
- data/app/views/layouts/application.html.erb +14 -0
- data/app/views/layouts/erp_tech_svcs/application.html.erb +14 -0
- data/app/views/user_mailer/activation_needed_email.html.erb +14 -0
- data/app/views/user_mailer/reset_password_email.html.erb +14 -0
- data/config/initializers/erp_tech_svcs.rb +7 -0
- data/config/initializers/file_support.rb +1 -0
- data/config/initializers/pdfkit.rb +18 -0
- data/config/initializers/sorcery.rb +199 -0
- data/config/routes.rb +9 -0
- data/db/data_migrations/20110802200222_schedule_delete_expired_sessions_job.rb +15 -0
- data/db/data_migrations/20111111144706_setup_audit_log_types.rb +21 -0
- data/db/migrate/20080805000010_base_tech_services.rb +247 -0
- data/db/migrate/20111109161549_add_capabilites.rb +56 -0
- data/db/migrate/upgrade/20111109161550_update_roles.rb +33 -0
- data/db/migrate/upgrade/20111109161551_update_user.rb +88 -0
- data/lib/erp_tech_svcs/application_installer.rb +102 -0
- data/lib/erp_tech_svcs/config.rb +27 -0
- data/lib/erp_tech_svcs/engine.rb +14 -0
- data/lib/erp_tech_svcs/extensions/active_record/acts_as_versioned.rb +494 -0
- data/lib/erp_tech_svcs/extensions/active_record/has_capabilities.rb +139 -0
- data/lib/erp_tech_svcs/extensions/active_record/has_file_assets.rb +40 -0
- data/lib/erp_tech_svcs/extensions/active_record/has_roles.rb +126 -0
- data/lib/erp_tech_svcs/extensions.rb +5 -0
- data/lib/erp_tech_svcs/file_support/aws_s3_patch.rb +3 -0
- data/lib/erp_tech_svcs/file_support/base.rb +30 -0
- data/lib/erp_tech_svcs/file_support/file_manipulator.rb +37 -0
- data/lib/erp_tech_svcs/file_support/file_system_manager.rb +167 -0
- data/lib/erp_tech_svcs/file_support/manager.rb +147 -0
- data/lib/erp_tech_svcs/file_support/paperclip_patch.rb +28 -0
- data/lib/erp_tech_svcs/file_support/railties/s3_resolver.rb +79 -0
- data/lib/erp_tech_svcs/file_support/s3_manager.rb +211 -0
- data/lib/erp_tech_svcs/file_support.rb +10 -0
- data/lib/erp_tech_svcs/sessions/delete_expired_sessions_job.rb +40 -0
- data/lib/erp_tech_svcs/sessions/delete_expired_sessions_service.rb +15 -0
- data/lib/erp_tech_svcs/utils/attachment_fu_patch.rb +15 -0
- data/lib/erp_tech_svcs/utils/compass_access_negotiator.rb +57 -0
- data/lib/erp_tech_svcs/utils/compass_logger.rb +94 -0
- data/lib/erp_tech_svcs/utils/compass_pdf.rb +72 -0
- data/lib/erp_tech_svcs/utils/default_nested_set_methods.rb +33 -0
- data/lib/erp_tech_svcs/utils/pdf_processor.rb +106 -0
- data/lib/erp_tech_svcs/version.rb +3 -0
- data/lib/erp_tech_svcs.rb +20 -0
- data/lib/tasks/erp_tech_svcs_tasks.rake +42 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +9 -0
- data/spec/dummy/app/assets/stylesheets/application.css +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config/application.rb +43 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +8 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/spec.rb +27 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/schema.rb +571 -0
- data/spec/dummy/db/spec.sqlite3 +0 -0
- data/spec/dummy/log/spec.log +2862 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/factories/capability_type.rb +5 -0
- data/spec/factories/role.rb +5 -0
- data/spec/factories/users.rb +9 -0
- data/spec/lib/erp_tech_svcs/extensions/active_record/has_roles_spec.rb +68 -0
- data/spec/models/audit_log_spec.rb +48 -0
- data/spec/models/audit_log_type_spec.rb +9 -0
- data/spec/models/role_spec.rb +17 -0
- data/spec/models/user_spec.rb +27 -0
- data/spec/spec_helper.rb +61 -0
- 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,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
|