barkest_core 1.5.3.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.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/Gemfile +22 -0
- data/Gemfile.lock +254 -0
- data/MIT-LICENSE +20 -0
- data/README.md +364 -0
- data/Rakefile +37 -0
- data/app/assets/fonts/barkest_core/ArchivoNarrow-Bold.ttf +0 -0
- data/app/assets/fonts/barkest_core/ArchivoNarrow-BoldItalic.ttf +0 -0
- data/app/assets/fonts/barkest_core/ArchivoNarrow-Italic.ttf +0 -0
- data/app/assets/fonts/barkest_core/ArchivoNarrow-Regular.ttf +0 -0
- data/app/assets/images/barkest_core/.keep +0 -0
- data/app/assets/images/barkest_core/barcode-B.svg +181 -0
- data/app/assets/javascripts/barkest_core/.keep +0 -0
- data/app/assets/javascripts/barkest_core/application.js +22 -0
- data/app/assets/javascripts/barkest_core/bootstrap-datepicker.js +1800 -0
- data/app/assets/javascripts/barkest_core/field_init.js +7 -0
- data/app/assets/javascripts/barkest_core/jquery.doubleScroll.js +112 -0
- data/app/assets/javascripts/barkest_core/masked_edit.js +25 -0
- data/app/assets/javascripts/barkest_core/system_status.js.erb +201 -0
- data/app/assets/stylesheets/barkest_core/.keep +0 -0
- data/app/assets/stylesheets/barkest_core/application.css +17 -0
- data/app/assets/stylesheets/barkest_core/custom.css.scss +264 -0
- data/app/assets/stylesheets/barkest_core/datepicker3.css +790 -0
- data/app/controllers/.keep +0 -0
- data/app/controllers/access_groups_controller.rb +74 -0
- data/app/controllers/account_activations_controller.rb +29 -0
- data/app/controllers/application_controller.rb +5 -0
- data/app/controllers/barkest_core/application_controller_base.rb +113 -0
- data/app/controllers/barkest_core/engine_controller_base.rb +15 -0
- data/app/controllers/barkest_core/testsub_controller.rb +21 -0
- data/app/controllers/contact_controller.rb +32 -0
- data/app/controllers/log_view_controller.rb +31 -0
- data/app/controllers/password_resets_controller.rb +126 -0
- data/app/controllers/sessions_controller.rb +64 -0
- data/app/controllers/status_controller.rb +150 -0
- data/app/controllers/system_config_controller.rb +238 -0
- data/app/controllers/system_update_controller.rb +164 -0
- data/app/controllers/test_access_controller.rb +44 -0
- data/app/controllers/test_report_controller.rb +75 -0
- data/app/controllers/users_controller.rb +218 -0
- data/app/helpers/.keep +0 -0
- data/app/helpers/barkest_core/application_helper.rb +134 -0
- data/app/helpers/barkest_core/form_helper.rb +469 -0
- data/app/helpers/barkest_core/html_helper.rb +70 -0
- data/app/helpers/barkest_core/misc_helper.rb +68 -0
- data/app/helpers/barkest_core/pdf_helper.rb +180 -0
- data/app/helpers/barkest_core/recaptcha_helper.rb +115 -0
- data/app/helpers/barkest_core/sessions_helper.rb +94 -0
- data/app/helpers/barkest_core/status_helper.rb +118 -0
- data/app/helpers/barkest_core/users_helper.rb +32 -0
- data/app/mailers/.keep +0 -0
- data/app/mailers/application_mailer.rb +5 -0
- data/app/mailers/barkest_core/application_mailer_base.rb +30 -0
- data/app/mailers/barkest_core/contact_form.rb +20 -0
- data/app/mailers/barkest_core/user_mailer.rb +44 -0
- data/app/models/.keep +0 -0
- data/app/models/access_group.rb +121 -0
- data/app/models/access_group_group_member.rb +13 -0
- data/app/models/access_group_user_member.rb +11 -0
- data/app/models/barkest_core/auth_config.rb +95 -0
- data/app/models/barkest_core/authorize_failure.rb +7 -0
- data/app/models/barkest_core/contact_message.rb +37 -0
- data/app/models/barkest_core/database_config.rb +223 -0
- data/app/models/barkest_core/db_table.rb +21 -0
- data/app/models/barkest_core/email_config.rb +132 -0
- data/app/models/barkest_core/global_status.rb +267 -0
- data/app/models/barkest_core/log_entry.rb +101 -0
- data/app/models/barkest_core/log_view_options.rb +51 -0
- data/app/models/barkest_core/ms_sql_db_definition.rb +441 -0
- data/app/models/barkest_core/ms_sql_definition.rb +221 -0
- data/app/models/barkest_core/ms_sql_function.rb +423 -0
- data/app/models/barkest_core/not_logged_in.rb +7 -0
- data/app/models/barkest_core/pdf_table_builder.rb +407 -0
- data/app/models/barkest_core/self_update_config.rb +37 -0
- data/app/models/barkest_core/user_alert.rb +29 -0
- data/app/models/barkest_core/user_alert_generators.rb +58 -0
- data/app/models/barkest_core/user_manager.rb +404 -0
- data/app/models/barkest_core/work_path.rb +74 -0
- data/app/models/disable_user.rb +18 -0
- data/app/models/ldap_access_group.rb +15 -0
- data/app/models/system_config.rb +99 -0
- data/app/models/user.rb +405 -0
- data/app/models/user_login_history.rb +11 -0
- data/app/views/.keep +0 -0
- data/app/views/access_groups/_form.html.erb +19 -0
- data/app/views/access_groups/edit.html.erb +2 -0
- data/app/views/access_groups/index.html.erb +32 -0
- data/app/views/access_groups/new.html.erb +2 -0
- data/app/views/access_groups/show.html.erb +4 -0
- data/app/views/barkest_core/contact_form/contact.html.erb +16 -0
- data/app/views/barkest_core/contact_form/contact.text.erb +13 -0
- data/app/views/barkest_core/testsub/_links.html.erb +5 -0
- data/app/views/barkest_core/testsub/page1.html.erb +3 -0
- data/app/views/barkest_core/testsub/page2.html.erb +2 -0
- data/app/views/barkest_core/testsub/page3.html.erb +2 -0
- data/app/views/barkest_core/user_mailer/account_activation.html.erb +7 -0
- data/app/views/barkest_core/user_mailer/account_activation.text.erb +6 -0
- data/app/views/barkest_core/user_mailer/invalid_password_reset.html.erb +3 -0
- data/app/views/barkest_core/user_mailer/invalid_password_reset.text.erb +5 -0
- data/app/views/barkest_core/user_mailer/password_reset.html.erb +8 -0
- data/app/views/barkest_core/user_mailer/password_reset.text.erb +7 -0
- data/app/views/contact/index.html.erb +24 -0
- data/app/views/layouts/_footer_copyright.html.erb +1 -0
- data/app/views/layouts/_menu_admin.html.erb +5 -0
- data/app/views/layouts/_menu_anon.html.erb +0 -0
- data/app/views/layouts/_menu_auth.html.erb +3 -0
- data/app/views/layouts/_menu_footer.html.erb +1 -0
- data/app/views/layouts/_nav_logo.html.erb +1 -0
- data/app/views/layouts/application.html.erb +2 -0
- data/app/views/layouts/barkest_core/_application.html.erb +24 -0
- data/app/views/layouts/barkest_core/_footer.html.erb +18 -0
- data/app/views/layouts/barkest_core/_header.html.erb +38 -0
- data/app/views/layouts/barkest_core/_html_mailer.html.erb +11 -0
- data/app/views/layouts/barkest_core/_menu_account.html.erb +14 -0
- data/app/views/layouts/barkest_core/_menu_sample.html.erb +1 -0
- data/app/views/layouts/barkest_core/_messages.html.erb +4 -0
- data/app/views/layouts/barkest_core/_shim.html.erb +4 -0
- data/app/views/layouts/barkest_core/_subheader.html.erb +1 -0
- data/app/views/layouts/barkest_core/_text_mailer.text.erb +4 -0
- data/app/views/layouts/mailer.html.erb +1 -0
- data/app/views/layouts/mailer.text.erb +1 -0
- data/app/views/log_view/index.html.erb +100 -0
- data/app/views/password_resets/edit.html.erb +20 -0
- data/app/views/password_resets/new.html.erb +14 -0
- data/app/views/sessions/new.html.erb +27 -0
- data/app/views/shared/_error_messages.html.erb +29 -0
- data/app/views/shared/_generic_user_alert.html.erb +4 -0
- data/app/views/status/current.html.erb +34 -0
- data/app/views/status/test.html.erb +50 -0
- data/app/views/system_config/index.html.erb +25 -0
- data/app/views/system_config/show_auth.html.erb +28 -0
- data/app/views/system_config/show_database.html.erb +36 -0
- data/app/views/system_config/show_email.html.erb +21 -0
- data/app/views/system_config/show_self_update.html.erb +13 -0
- data/app/views/system_update/index.html.erb +31 -0
- data/app/views/system_update/new.html.erb +2 -0
- data/app/views/test_access/allow_anon.html.erb +2 -0
- data/app/views/test_access/require_admin.html.erb +2 -0
- data/app/views/test_access/require_group_x.html.erb +2 -0
- data/app/views/test_access/require_user.html.erb +2 -0
- data/app/views/test_report/index.csv.csvrb +23 -0
- data/app/views/test_report/index.html.erb +6 -0
- data/app/views/test_report/index.pdf.prawn +50 -0
- data/app/views/test_report/index.xlsx.axlsx +28 -0
- data/app/views/users/_user.html.erb +57 -0
- data/app/views/users/_user_details.html.erb +15 -0
- data/app/views/users/_user_details_for_list.html.erb +1 -0
- data/app/views/users/_user_form.html.erb +13 -0
- data/app/views/users/disable_confirm.html.erb +19 -0
- data/app/views/users/edit.html.erb +15 -0
- data/app/views/users/index.html.erb +9 -0
- data/app/views/users/new.html.erb +10 -0
- data/app/views/users/show.html.erb +46 -0
- data/bin/rails +12 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20160617172539_create_access_groups.rb +10 -0
- data/db/migrate/20160617172725_create_users.rb +26 -0
- data/db/migrate/20160617172833_create_user_login_histories.rb +12 -0
- data/db/migrate/20160622151720_create_access_group_user_members.rb +9 -0
- data/db/migrate/20160622151925_create_access_group_group_members.rb +9 -0
- data/db/migrate/20160701005706_create_ldap_access_groups.rb +11 -0
- data/db/migrate/20161108155029_create_system_configs.rb +11 -0
- data/db/seeds/barkest_core_01_create_users.rb +42 -0
- data/db/seeds.rb +53 -0
- data/lib/barkest_core/concerns/association_with_defaults.rb +55 -0
- data/lib/barkest_core/concerns/boolean_parser.rb +88 -0
- data/lib/barkest_core/concerns/date_parser.rb +181 -0
- data/lib/barkest_core/concerns/email_tester.rb +55 -0
- data/lib/barkest_core/concerns/encrypted_fields.rb +156 -0
- data/lib/barkest_core/concerns/named_model.rb +73 -0
- data/lib/barkest_core/concerns/number_parser.rb +145 -0
- data/lib/barkest_core/concerns/utc_conversion.rb +60 -0
- data/lib/barkest_core/engine.rb +105 -0
- data/lib/barkest_core/extensions/active_record_extensions.rb +120 -0
- data/lib/barkest_core/extensions/application_configuration_extensions.rb +38 -0
- data/lib/barkest_core/extensions/application_extensions.rb +50 -0
- data/lib/barkest_core/extensions/axlsx_extenstions.rb +157 -0
- data/lib/barkest_core/extensions/fixture_set_extensions.rb +107 -0
- data/lib/barkest_core/extensions/generator_extensions.rb +271 -0
- data/lib/barkest_core/extensions/main_app_extensions.rb +35 -0
- data/lib/barkest_core/extensions/prawn_document_extensions.rb +367 -0
- data/lib/barkest_core/extensions/prawn_table_extensions.rb +131 -0
- data/lib/barkest_core/extensions/router_extensions.rb +106 -0
- data/lib/barkest_core/extensions/simple_formatter_extensions.rb +66 -0
- data/lib/barkest_core/extensions/test_case_extensions.rb +348 -0
- data/lib/barkest_core/extensions/time_extensions.rb +164 -0
- data/lib/barkest_core/handlers/csv_handler.rb +30 -0
- data/lib/barkest_core/version.rb +3 -0
- data/lib/barkest_core.rb +324 -0
- data/lib/generators/barkest/install_generator.rb +102 -0
- data/lib/generators/barkest_core/actions/01_patch_application_controller.rb +55 -0
- data/lib/generators/barkest_core/actions/02_patch_application_mailer.rb +56 -0
- data/lib/generators/barkest_core/actions/03_patch_assets.rb +62 -0
- data/lib/generators/barkest_core/actions/04_patch_layouts.rb +36 -0
- data/lib/generators/barkest_core/actions/05_patch_routes.rb +93 -0
- data/lib/generators/barkest_core/actions/06_patch_seeds.rb +60 -0
- data/lib/generators/barkest_core/actions/07_copy_migrations.rb +51 -0
- data/lib/generators/barkest_core/actions/08_configure_database.rb +52 -0
- data/lib/generators/barkest_core/actions/09_configure_secrets.rb +29 -0
- data/lib/generators/barkest_core/actions/99_patch_gitignore.rb +57 -0
- data/lib/generators/barkest_core/install_generator.rb +17 -0
- data/test/barkest_core_test.rb +83 -0
- data/test/controllers/access_groups_controller_test.rb +53 -0
- data/test/controllers/contact_controller_test.rb +10 -0
- data/test/controllers/sessions_controller_test.rb +10 -0
- data/test/controllers/users_controller_test.rb +10 -0
- data/test/dummy/.gitignore +10 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/javascripts/application.js +14 -0
- data/test/dummy/app/assets/stylesheets/application.css +16 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/mailers/.keep +0 -0
- data/test/dummy/app/mailers/application_mailer.rb +3 -0
- data/test/dummy/app/models/.keep +0 -0
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +1 -0
- data/test/dummy/app/views/layouts/mailer.html.erb +1 -0
- data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/test/dummy/app/views/system_config/show_fake.html.erb +3 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config/application.rb +27 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +47 -0
- data/test/dummy/config/environments/production.rb +79 -0
- data/test/dummy/config/environments/test.rb +44 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/db_updater_ext.rb +33 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/sys_config_ext.rb +12 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +60 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/schema.rb +95 -0
- data/test/dummy/db/seeds/barkest_core_01_create_users.rb +42 -0
- data/test/dummy/db/seeds.rb +51 -0
- data/test/dummy/lib/assets/.keep +0 -0
- data/test/dummy/log/.keep +0 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/sql/my_test_view.sql +3 -0
- data/test/fixtures/access_groups.yml +21 -0
- data/test/fixtures/users.yml +71 -0
- data/test/helpers/barkest_core/sessions_helper_test.rb +22 -0
- data/test/integration/access_group_mgmt_test.rb +33 -0
- data/test/integration/access_test.rb +24 -0
- data/test/integration/account_activations_access_test.rb +12 -0
- data/test/integration/contact_test.rb +98 -0
- data/test/integration/extra_partial_test.rb +41 -0
- data/test/integration/log_view_access_test.rb +12 -0
- data/test/integration/password_resets_test.rb +101 -0
- data/test/integration/reports_test.rb +53 -0
- data/test/integration/status_access_test.rb +27 -0
- data/test/integration/system_config_access_test.rb +24 -0
- data/test/integration/system_update_access_test.rb +19 -0
- data/test/integration/users_access_test.rb +34 -0
- data/test/integration/users_edit_test.rb +178 -0
- data/test/integration/users_index_test.rb +62 -0
- data/test/integration/users_login_test.rb +67 -0
- data/test/integration/users_signup_test.rb +54 -0
- data/test/mailers/.keep +0 -0
- data/test/mailers/barkest_core/contact_form_test.rb +28 -0
- data/test/mailers/barkest_core/user_mailer_test.rb +43 -0
- data/test/mailers/previews/barkest_core/contact_form_preview.rb +17 -0
- data/test/mailers/previews/barkest_core/user_mailer_preview.rb +26 -0
- data/test/models/access_group_group_member_test.rb +28 -0
- data/test/models/access_group_test.rb +114 -0
- data/test/models/access_group_user_member_test.rb +28 -0
- data/test/models/barkest_core/auth_config_test.rb +57 -0
- data/test/models/barkest_core/bool_parser_test.rb +28 -0
- data/test/models/barkest_core/contact_message_test.rb +61 -0
- data/test/models/barkest_core/database_config_test.rb +33 -0
- data/test/models/barkest_core/date_parser_test.rb +110 -0
- data/test/models/barkest_core/email_config_test.rb +57 -0
- data/test/models/barkest_core/global_status_test.rb +50 -0
- data/test/models/barkest_core/ms_sql_db_updater_test.rb +115 -0
- data/test/models/barkest_core/ms_sql_definition_test.rb +102 -0
- data/test/models/barkest_core/ms_sql_function_test.rb +131 -0
- data/test/models/barkest_core/number_parser_test.rb +29 -0
- data/test/models/barkest_core/self_update_config_test.rb +29 -0
- data/test/models/barkest_core/user_alert_test.rb +19 -0
- data/test/models/barkest_core/user_manager_test.rb +34 -0
- data/test/models/barkest_core/work_path_test.rb +26 -0
- data/test/models/disable_user_test.rb +27 -0
- data/test/models/generic_time_test.rb +66 -0
- data/test/models/ldap_access_group_test.rb +31 -0
- data/test/models/pdf_table_builder_test.rb +6 -0
- data/test/models/system_config_test.rb +78 -0
- data/test/models/user_login_history_test.rb +37 -0
- data/test/models/user_test.rb +130 -0
- data/test/test_helper.rb +63 -0
- metadata +798 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module BarkestCore
|
|
2
|
+
##
|
|
3
|
+
# Defines the message generated by the generic contact form.
|
|
4
|
+
class ContactMessage
|
|
5
|
+
include ActiveModel::Model
|
|
6
|
+
include ActiveModel::Validations
|
|
7
|
+
include BarkestCore::EmailTester
|
|
8
|
+
|
|
9
|
+
attr_accessor :your_name, :your_email, :related_to, :subject, :body, :remote_ip
|
|
10
|
+
|
|
11
|
+
validates :your_name, presence: true
|
|
12
|
+
validates :your_email, presence: true, format: { with: VALID_EMAIL_REGEX }
|
|
13
|
+
validates :related_to, presence: true
|
|
14
|
+
validates :subject, presence: true, if: :need_subject?
|
|
15
|
+
validates :body, presence: true
|
|
16
|
+
|
|
17
|
+
##
|
|
18
|
+
# Gets the full subject for the message.
|
|
19
|
+
def full_subject
|
|
20
|
+
return related_to if subject.blank?
|
|
21
|
+
"#{related_to}: #{subject}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
##
|
|
25
|
+
# Sends the message.
|
|
26
|
+
def send_message
|
|
27
|
+
BarkestCore::ContactForm.contact(self).deliver_now
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def need_subject?
|
|
33
|
+
related_to.to_s.downcase == 'other'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
module BarkestCore
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# Defines a database configuration for a database other than the core database.
|
|
5
|
+
#
|
|
6
|
+
# The core database must be configurared in +database.yml+ since it defines the SystemConfig.
|
|
7
|
+
#
|
|
8
|
+
# Other databases (say for a 3rd party database) can easily be defined using SystemConfig
|
|
9
|
+
# and this class.
|
|
10
|
+
class DatabaseConfig
|
|
11
|
+
include ActiveModel::Model
|
|
12
|
+
include ActiveModel::Validations
|
|
13
|
+
|
|
14
|
+
attr_accessor :name, :adapter, :encoding, :reconnect, :database, :pool, :username, :password, :timeout, :host, :port
|
|
15
|
+
attr_accessor :extra_1_name, :extra_1_label, :extra_1_type
|
|
16
|
+
attr_accessor :extra_2_name, :extra_2_label, :extra_2_type
|
|
17
|
+
attr_accessor :extra_3_name, :extra_3_label, :extra_3_type
|
|
18
|
+
attr_accessor :extra_4_name, :extra_4_label, :extra_4_type
|
|
19
|
+
attr_accessor :extra_5_name, :extra_5_label, :extra_5_type
|
|
20
|
+
attr_writer :extra_1_value, :extra_2_value, :extra_3_value, :extra_4_value, :extra_5_value
|
|
21
|
+
attr_accessor :update_username, :update_password
|
|
22
|
+
|
|
23
|
+
VALID_ADAPTERS = %w(sqlite3 mysql2 postgresql sqlserver)
|
|
24
|
+
|
|
25
|
+
validates :adapter, inclusion: { in: VALID_ADAPTERS }
|
|
26
|
+
validates :name, presence: true, length: { maximum: 128 }
|
|
27
|
+
validates :database, presence: true
|
|
28
|
+
validates :pool, presence: true
|
|
29
|
+
validates :timeout, presence: true
|
|
30
|
+
|
|
31
|
+
EXTRA_REGEX = /^extra_(?<KEY>\d+)_(?<VAR>name|label|type|value)$/
|
|
32
|
+
VALID_EXTRA_KEY = (1..5)
|
|
33
|
+
private_constant :EXTRA_REGEX, :VALID_EXTRA_KEY
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# Initializes the configuration.
|
|
37
|
+
#
|
|
38
|
+
# Define the parameters as hash values. A string without a key will be used to set the name.
|
|
39
|
+
def initialize(*args)
|
|
40
|
+
@extra = []
|
|
41
|
+
args.each do |arg|
|
|
42
|
+
if arg.is_a?(String)
|
|
43
|
+
self.name = arg
|
|
44
|
+
elsif arg.is_a?(Hash)
|
|
45
|
+
arg.each do |k,v|
|
|
46
|
+
if respond_to?(:"#{k}?")
|
|
47
|
+
send :"#{k}=", ((v === true || v === '1') ? '1' : '0')
|
|
48
|
+
elsif respond_to?(:"#{k}")
|
|
49
|
+
send :"#{k}=", v.to_s
|
|
50
|
+
elsif (extra = EXTRA_REGEX.match(k.to_s))
|
|
51
|
+
key = extra['KEY'].to_i
|
|
52
|
+
if VALID_EXTRA_KEY.include?(key)
|
|
53
|
+
send :"extra_#{key}_#{extra['VAR']}=", v.to_s
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# :nodoc:
|
|
62
|
+
def method_missing(m,*a,&b)
|
|
63
|
+
m = m.to_s
|
|
64
|
+
|
|
65
|
+
if (key = EXTRA_REGEX.match(m))
|
|
66
|
+
if key['VAR'] == 'value'
|
|
67
|
+
key = key['KEY'].to_i
|
|
68
|
+
if VALID_EXTRA_KEY.include?(key)
|
|
69
|
+
ivar = :"@#{m}"
|
|
70
|
+
val = instance_variable_defined?(ivar) ? instance_variable_get(ivar) : nil
|
|
71
|
+
tp = send("extra_#{key}_type")
|
|
72
|
+
if tp == 'boolean'
|
|
73
|
+
val = ((val === true) || (val == '1')) ? '1' : '0'
|
|
74
|
+
end
|
|
75
|
+
return val
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
super m, *a, &b
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
##
|
|
84
|
+
# Is the database configured to reconnect?
|
|
85
|
+
def reconnect?
|
|
86
|
+
reconnect.to_s.to_i != 0
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
##
|
|
90
|
+
# Gets the name for an extra value.
|
|
91
|
+
def extra_name(index)
|
|
92
|
+
return nil if index < 1 || index > 5
|
|
93
|
+
send "extra_#{index}_name"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
##
|
|
97
|
+
# Gets the label for an extra value.
|
|
98
|
+
def extra_label(index)
|
|
99
|
+
return nil if index < 1 || index > 5
|
|
100
|
+
txt = send("extra_#{index}_label")
|
|
101
|
+
txt = extra_name(index).to_s.humanize.capitalize if txt.blank?
|
|
102
|
+
txt
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
##
|
|
106
|
+
# Gets the type for an extra value.
|
|
107
|
+
def extra_type(index)
|
|
108
|
+
return nil if index < 1 || index > 5
|
|
109
|
+
send "extra_#{index}_type"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
##
|
|
113
|
+
# Gets the field type for an extra value.
|
|
114
|
+
def extra_field_type(index)
|
|
115
|
+
t = extra_type(index).to_s
|
|
116
|
+
case t
|
|
117
|
+
when 'password'
|
|
118
|
+
'password'
|
|
119
|
+
when 'integer', 'float'
|
|
120
|
+
'number'
|
|
121
|
+
when 'boolean'
|
|
122
|
+
'checkbox'
|
|
123
|
+
else
|
|
124
|
+
if t.downcase.index('in:')
|
|
125
|
+
'select'
|
|
126
|
+
else
|
|
127
|
+
'text'
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
##
|
|
133
|
+
# Gets the options for a select field.
|
|
134
|
+
def extra_field_options(index)
|
|
135
|
+
if extra_field_type(index) == 'select'
|
|
136
|
+
eval extra_type(index).partition(':')[2]
|
|
137
|
+
else
|
|
138
|
+
nil
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
##
|
|
143
|
+
# Gets an extra value.
|
|
144
|
+
def extra_value(index, convert = false)
|
|
145
|
+
return nil if index < 1 || index > 5
|
|
146
|
+
val = send "extra_#{index}_value"
|
|
147
|
+
if convert
|
|
148
|
+
case extra_type(index)
|
|
149
|
+
when 'boolean'
|
|
150
|
+
BarkestCore::BooleanParser.parse_for_boolean_column(val)
|
|
151
|
+
when 'integer'
|
|
152
|
+
BarkestCore::NumberParser.parse_for_int_column(val)
|
|
153
|
+
when 'float'
|
|
154
|
+
BarkestCore::NumberParser.parse_for_float_column(val)
|
|
155
|
+
else
|
|
156
|
+
val.to_s
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
##
|
|
163
|
+
# Converts this configuration into a hash.
|
|
164
|
+
def to_h(convert_extra = true)
|
|
165
|
+
ret = {
|
|
166
|
+
adapter: adapter.to_s,
|
|
167
|
+
database: database.to_s,
|
|
168
|
+
pool: pool.to_s.to_i,
|
|
169
|
+
timeout: timeout.to_s.to_i,
|
|
170
|
+
reconnect: reconnect?,
|
|
171
|
+
encoding: encoding ? encoding.to_s : nil,
|
|
172
|
+
host: host.blank? ? nil : host.to_s,
|
|
173
|
+
port: port.blank? ? nil : port.to_s.to_i,
|
|
174
|
+
username: username.blank? ? nil : username.to_s,
|
|
175
|
+
password: password.blank? ? nil : password.to_s,
|
|
176
|
+
update_username: update_username.blank? ? nil : update_username.to_s,
|
|
177
|
+
update_password: update_password.blank? ? nil : update_password.to_s,
|
|
178
|
+
}
|
|
179
|
+
VALID_EXTRA_KEY.each do |idx|
|
|
180
|
+
if convert_extra
|
|
181
|
+
unless extra_name(idx).blank?
|
|
182
|
+
ret[extra_name(idx).to_sym] = extra_value(idx, true)
|
|
183
|
+
end
|
|
184
|
+
else
|
|
185
|
+
ret[:"extra_#{idx}_name"] = send(:"extra_#{idx}_name")
|
|
186
|
+
ret[:"extra_#{idx}_label"] = send(:"extra_#{idx}_label")
|
|
187
|
+
ret[:"extra_#{idx}_type"] = send(:"extra_#{idx}_type")
|
|
188
|
+
ret[:"extra_#{idx}_value"] = send(:"extra_#{idx}_value")
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
ret
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
##
|
|
195
|
+
# Saves this configuration (encrypted) to SystemConfig.
|
|
196
|
+
def save
|
|
197
|
+
SystemConfig.set name, to_h(false), true
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
##
|
|
201
|
+
# Loads the configuration for the specified database from SystemConfig.
|
|
202
|
+
def DatabaseConfig.load(name)
|
|
203
|
+
DatabaseConfig.new(name, SystemConfig.get(name))
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
##
|
|
207
|
+
# Gets a list of the registered databases for enumeration.
|
|
208
|
+
def DatabaseConfig.registered
|
|
209
|
+
@registered ||= []
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
##
|
|
213
|
+
# Registers a database for enumeration.
|
|
214
|
+
def DatabaseConfig.register(db_id)
|
|
215
|
+
db_id = db_id.to_s.downcase
|
|
216
|
+
unless db_id.blank?
|
|
217
|
+
registered << db_id unless registered.include?(db_id)
|
|
218
|
+
end
|
|
219
|
+
nil
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
end
|
|
223
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# this shouldn't be necessary, but engines seem to have a few weak spots.
|
|
2
|
+
require 'will_paginate/active_record'
|
|
3
|
+
|
|
4
|
+
module BarkestCore
|
|
5
|
+
|
|
6
|
+
##
|
|
7
|
+
# This class serves as a base class for other models.
|
|
8
|
+
#
|
|
9
|
+
# This way we can guarantee that all of our models can use an explicit configuration
|
|
10
|
+
# when desirable.
|
|
11
|
+
class DbTable < ActiveRecord::Base
|
|
12
|
+
self.abstract_class = true
|
|
13
|
+
|
|
14
|
+
# Ensure that we only establish a new connection if needed.
|
|
15
|
+
unless BarkestCore.db_config.symbolize_keys == ActiveRecord::Base.connection_config.symbolize_keys
|
|
16
|
+
establish_connection BarkestCore.db_config
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
module BarkestCore
|
|
2
|
+
##
|
|
3
|
+
# Defines the email configuration for the system.
|
|
4
|
+
class EmailConfig
|
|
5
|
+
include ActiveModel::Model
|
|
6
|
+
include ActiveModel::Validations
|
|
7
|
+
|
|
8
|
+
attr_accessor :config_mode, :default_sender, :default_recipient, :default_hostname
|
|
9
|
+
attr_accessor :address, :port, :authentication, :ssl, :enable_starttls_auto, :user_name, :password
|
|
10
|
+
|
|
11
|
+
VALID_CONFIG_MODES = %w(none smtp test)
|
|
12
|
+
VALID_AUTH_MODES = %w(none plain login cram_md5 ntlm)
|
|
13
|
+
|
|
14
|
+
validates :config_mode, inclusion: { in: VALID_CONFIG_MODES }
|
|
15
|
+
validates :default_sender, presence: true
|
|
16
|
+
validates :default_recipient, presence: true
|
|
17
|
+
validates :default_hostname, presence: true
|
|
18
|
+
|
|
19
|
+
with_options if: :smtp?, presence: true do
|
|
20
|
+
validates :address
|
|
21
|
+
validates :port
|
|
22
|
+
validates :authentication, inclusion: { in: VALID_AUTH_MODES }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
validate :smtp_validate, if: :smtp?
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# Initializes the configuration.
|
|
29
|
+
def initialize(*args)
|
|
30
|
+
args.each do |arg|
|
|
31
|
+
if arg.is_a?(Hash)
|
|
32
|
+
arg.each do |k,v|
|
|
33
|
+
if respond_to?(:"#{k}?")
|
|
34
|
+
send :"#{k}=", ((v === true || v === '1') ? '1' : '0')
|
|
35
|
+
elsif respond_to?(k)
|
|
36
|
+
send :"#{k}=", v.to_s
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
##
|
|
44
|
+
# Is SMTP enabled?
|
|
45
|
+
def smtp?
|
|
46
|
+
config_mode.to_s.downcase == 'smtp'
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
##
|
|
50
|
+
# Is SSL enabled for SMTP?
|
|
51
|
+
def ssl?
|
|
52
|
+
ssl.to_s.to_i != 0
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
##
|
|
56
|
+
# Is STARTTLS enabled for SMTP?
|
|
57
|
+
def enable_starttls_auto?
|
|
58
|
+
enable_starttls_auto.to_s.to_i != 0
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
##
|
|
62
|
+
# Converts this configuration into a hash.
|
|
63
|
+
def to_h
|
|
64
|
+
{
|
|
65
|
+
config_mode: config_mode.to_s.to_sym,
|
|
66
|
+
default_sender: default_sender.to_s,
|
|
67
|
+
default_recipient: default_recipient.to_s,
|
|
68
|
+
default_hostname: default_hostname.to_s,
|
|
69
|
+
address: address.to_s,
|
|
70
|
+
port: port.to_s.to_i,
|
|
71
|
+
authentication: authentication.to_s.to_sym,
|
|
72
|
+
ssl: ssl?,
|
|
73
|
+
enable_starttls_auto: enable_starttls_auto?,
|
|
74
|
+
user_name: user_name.to_s,
|
|
75
|
+
password: password.to_s,
|
|
76
|
+
}
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
##
|
|
80
|
+
# Saves this configuration (encrypted) to SystemConfig.
|
|
81
|
+
def save
|
|
82
|
+
SystemConfig.set :email, to_h, true
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
##
|
|
86
|
+
# Loads the configuration from SystemConfig.
|
|
87
|
+
def EmailConfig.load
|
|
88
|
+
EmailConfig.new SystemConfig.get(:email)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
92
|
+
|
|
93
|
+
def smtp_validate
|
|
94
|
+
return nil if Rails.env.test?
|
|
95
|
+
|
|
96
|
+
# no need to test unless we are configured for SMTP.
|
|
97
|
+
return nil unless smtp?
|
|
98
|
+
|
|
99
|
+
# already failed if these are missing.
|
|
100
|
+
return nil if address.blank? || port.blank? || authentication.blank?
|
|
101
|
+
|
|
102
|
+
# or these
|
|
103
|
+
return nil if default_sender.blank? || default_recipient.blank? || default_hostname.blank?
|
|
104
|
+
|
|
105
|
+
# send a test message.
|
|
106
|
+
begin
|
|
107
|
+
client = Net::SMTP.new(address, port)
|
|
108
|
+
begin
|
|
109
|
+
client.enable_ssl if ssl?
|
|
110
|
+
client.start(default_hostname, user_name, password, authentication.to_sym)
|
|
111
|
+
msgstr = <<-MESSAGE
|
|
112
|
+
From: #{default_sender}
|
|
113
|
+
To: #{default_recipient}
|
|
114
|
+
Subject: Test message
|
|
115
|
+
|
|
116
|
+
This is a test message sent with the new #{Rails.env} configuration for #{default_hostname}.
|
|
117
|
+
This message was sent at #{Time.zone.now}.
|
|
118
|
+
MESSAGE
|
|
119
|
+
client.send_message(msgstr, default_sender, default_recipient)
|
|
120
|
+
ensure
|
|
121
|
+
client.finish rescue nil
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
nil
|
|
125
|
+
rescue =>e
|
|
126
|
+
errors.add :base, "Failed to send test message. " + e.message
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
end
|
|
132
|
+
end
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
module BarkestCore
|
|
2
|
+
##
|
|
3
|
+
# An interface to a global status/lock file.
|
|
4
|
+
#
|
|
5
|
+
# The global status/lock file is a simple two line file.
|
|
6
|
+
# The first line is the global status message.
|
|
7
|
+
# The second line is the global status progress.
|
|
8
|
+
#
|
|
9
|
+
# The real magic comes when we take advantage of exclusive locks.
|
|
10
|
+
# The process that will be managing the status takes an exclusive lock on the status/lock file.
|
|
11
|
+
# This prevents any other process from taking an exclusive lock.
|
|
12
|
+
# It does not prevent other processes from reading from the file.
|
|
13
|
+
#
|
|
14
|
+
# So the main process can update the file at any time, until it releases the lock.
|
|
15
|
+
# The other processes can read the file at any time, and test for the lock state to determine if the main
|
|
16
|
+
# process is still busy.
|
|
17
|
+
#
|
|
18
|
+
#
|
|
19
|
+
class GlobalStatus
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
# The exception raised in the +lock_for+ method when +raise_on_failure+ is set.
|
|
23
|
+
FailureToLock = Class.new(StandardError)
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
# Creates a new GlobalStatus object.
|
|
27
|
+
#
|
|
28
|
+
# If you specify a status file, then that file will be used for the locking and status reporting.
|
|
29
|
+
# Otherwise, the "global_lock" file will be used.
|
|
30
|
+
def initialize(status_file = nil)
|
|
31
|
+
@lock_handle = nil
|
|
32
|
+
@stat_handle = nil
|
|
33
|
+
@status_file_path = status_file
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
# Gets the path to the global status file.
|
|
38
|
+
def status_file_path
|
|
39
|
+
@status_file_path ||= WorkPath.path_for('global_status')
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
##
|
|
43
|
+
# Gets the path to the global lock file.
|
|
44
|
+
def lock_file_path
|
|
45
|
+
@lock_file_path ||= WorkPath.path_for('global_lock')
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
##
|
|
49
|
+
# Determines if this instance has a lock on the status/lock file.
|
|
50
|
+
def have_lock?
|
|
51
|
+
!!@lock_handle
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
##
|
|
55
|
+
# Determines if any process has a lock on the status/lock file.
|
|
56
|
+
def is_locked?
|
|
57
|
+
begin
|
|
58
|
+
return true if have_lock?
|
|
59
|
+
return true unless acquire_lock
|
|
60
|
+
ensure
|
|
61
|
+
release_lock
|
|
62
|
+
end
|
|
63
|
+
false
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
##
|
|
67
|
+
# Gets the current status message from the status/lock file.
|
|
68
|
+
def get_message
|
|
69
|
+
get_status[:message]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
##
|
|
73
|
+
# Gets the current progress from the status/lock file.
|
|
74
|
+
def get_percentage
|
|
75
|
+
r = get_status[:percent]
|
|
76
|
+
r.blank? ? nil : r.to_i
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
##
|
|
80
|
+
# Gets the current status from the status/lock file.
|
|
81
|
+
#
|
|
82
|
+
# Returns a hash with three elements:
|
|
83
|
+
#
|
|
84
|
+
# message::
|
|
85
|
+
# The current status message.
|
|
86
|
+
#
|
|
87
|
+
# percent::
|
|
88
|
+
# The current status progress.
|
|
89
|
+
#
|
|
90
|
+
# locked::
|
|
91
|
+
# The current lock state of the status/lock file. (true for locked, false for unlocked)
|
|
92
|
+
#
|
|
93
|
+
def get_status
|
|
94
|
+
r = {}
|
|
95
|
+
if have_lock?
|
|
96
|
+
@stat_handle.rewind
|
|
97
|
+
r[:message] = (@stat_handle.eof? ? 'The current process is busy.' : @stat_handle.readline.strip)
|
|
98
|
+
r[:percent] = (@stat_handle.eof? ? '' : @stat_handle.readline.strip)
|
|
99
|
+
r[:locked] = true
|
|
100
|
+
elsif is_locked?
|
|
101
|
+
if File.exist?(status_file_path)
|
|
102
|
+
begin
|
|
103
|
+
File.open(status_file_path, 'r') do |f|
|
|
104
|
+
r[:message] = (f.eof? ? 'The system is busy.' : f.readline.strip)
|
|
105
|
+
r[:percent] = (f.eof? ? '' : f.readline.strip)
|
|
106
|
+
end
|
|
107
|
+
rescue
|
|
108
|
+
r[:message] = 'The system appears busy.'
|
|
109
|
+
r[:percent] = ''
|
|
110
|
+
end
|
|
111
|
+
else
|
|
112
|
+
r[:message] = 'No status file.'
|
|
113
|
+
r[:percent] = ''
|
|
114
|
+
end
|
|
115
|
+
r[:locked] = true
|
|
116
|
+
else
|
|
117
|
+
r[:message] = 'The system is no longer busy.'
|
|
118
|
+
r[:percent] = '-'
|
|
119
|
+
r[:locked] = false
|
|
120
|
+
end
|
|
121
|
+
r
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
##
|
|
125
|
+
# Sets the status message if this instance has a lock on the status/lock file.
|
|
126
|
+
#
|
|
127
|
+
# Returns true after successfully setting the message.
|
|
128
|
+
# Returns false if this instance does not currently hold the lock.
|
|
129
|
+
#
|
|
130
|
+
def set_message(value)
|
|
131
|
+
return false unless have_lock?
|
|
132
|
+
cur = get_status
|
|
133
|
+
set_status(value, cur[:percent])
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
##
|
|
137
|
+
# Sets the status progress if this instance has a lock on the status/lock file.
|
|
138
|
+
#
|
|
139
|
+
# Returns true after successfully setting the progress.
|
|
140
|
+
# Returns false if this instance does not currently hold the lock.
|
|
141
|
+
#
|
|
142
|
+
def set_percentage(value)
|
|
143
|
+
return false unless have_lock?
|
|
144
|
+
cur = get_status
|
|
145
|
+
set_status(cur[:message], value)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
##
|
|
149
|
+
# Sets the status message and progress if this instance has a lock on the status/lock file.
|
|
150
|
+
#
|
|
151
|
+
# Returns true after successfully setting the status.
|
|
152
|
+
# Returns false if this instance does not currently hold the lock.
|
|
153
|
+
#
|
|
154
|
+
def set_status(message, percentage)
|
|
155
|
+
return false unless have_lock?
|
|
156
|
+
@stat_handle.rewind
|
|
157
|
+
@stat_handle.truncate 0
|
|
158
|
+
@stat_handle.write(message.to_s.strip + "\n")
|
|
159
|
+
@stat_handle.write(percentage.to_s.strip + "\n")
|
|
160
|
+
@stat_handle.flush
|
|
161
|
+
true
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
##
|
|
165
|
+
# Releases the lock on the status/lock file if this instance holds the lock.
|
|
166
|
+
#
|
|
167
|
+
# Returns true.
|
|
168
|
+
#
|
|
169
|
+
def release_lock
|
|
170
|
+
return true unless @lock_handle
|
|
171
|
+
begin
|
|
172
|
+
set_message ''
|
|
173
|
+
@lock_handle.flock(File::LOCK_UN)
|
|
174
|
+
ensure
|
|
175
|
+
@stat_handle.close rescue nil
|
|
176
|
+
@lock_handle.close rescue nil
|
|
177
|
+
@stat_handle = @lock_handle = nil
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
true
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
##
|
|
184
|
+
# Acquires the lock on the status/lock file.
|
|
185
|
+
#
|
|
186
|
+
# Returns true on success or if this instance already holds the lock.
|
|
187
|
+
# Returns false if another process holds the lock.
|
|
188
|
+
#
|
|
189
|
+
def acquire_lock
|
|
190
|
+
return true if @lock_handle
|
|
191
|
+
begin
|
|
192
|
+
@lock_handle = File.open(lock_file_path, File::RDWR | File::CREAT)
|
|
193
|
+
raise StandardError.new('Already locked') unless @lock_handle.flock(File::LOCK_EX | File::LOCK_NB)
|
|
194
|
+
@lock_handle.rewind
|
|
195
|
+
@lock_handle.truncate 0
|
|
196
|
+
@stat_handle = File.open(status_file_path, File::RDWR | File::CREAT)
|
|
197
|
+
raise StandardError.new('Failed to open status') unless @stat_handle
|
|
198
|
+
@stat_handle.rewind
|
|
199
|
+
@stat_handle.truncate 0
|
|
200
|
+
rescue
|
|
201
|
+
if @stat_handle
|
|
202
|
+
@stat_handle.close rescue nil
|
|
203
|
+
end
|
|
204
|
+
if @lock_handle
|
|
205
|
+
@lock_handle.flock(File::LOCK_UN) rescue nil
|
|
206
|
+
@lock_handle.close rescue nil
|
|
207
|
+
end
|
|
208
|
+
@stat_handle = nil
|
|
209
|
+
@lock_handle = nil
|
|
210
|
+
end
|
|
211
|
+
!!@lock_handle
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
##
|
|
215
|
+
# Determines if any process currently holds the lock on the status/lock file.
|
|
216
|
+
#
|
|
217
|
+
# Returns true if the file is locked, otherwise returns false.
|
|
218
|
+
#
|
|
219
|
+
def self.locked?
|
|
220
|
+
global_instance.is_locked?
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
##
|
|
224
|
+
# Gets the current status from the status/lock file.
|
|
225
|
+
#
|
|
226
|
+
# See #get_status for a description of the returned hash.
|
|
227
|
+
#
|
|
228
|
+
def self.current
|
|
229
|
+
global_instance.get_status
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
##
|
|
233
|
+
# Runs the provided block with a lock on the status/lock file.
|
|
234
|
+
#
|
|
235
|
+
# If a lock can be acquired, a GlobalStatus object is yielded to the block.
|
|
236
|
+
# The lock will automatically be released when the block exits.
|
|
237
|
+
#
|
|
238
|
+
# If a lock cannot be acquire, then false is yielded to the block.
|
|
239
|
+
# The block needs to test for this case to ensure that the appropriate
|
|
240
|
+
# error handling is performed.
|
|
241
|
+
#
|
|
242
|
+
# The only time that the block is not called is if +raise_on_failure+ is set,
|
|
243
|
+
# in which case an exception is raised instead of yielding to the block.
|
|
244
|
+
#
|
|
245
|
+
def self.lock_for(raise_on_failure = false, &block)
|
|
246
|
+
return unless block_given?
|
|
247
|
+
status = GlobalStatus.new
|
|
248
|
+
if status.acquire_lock
|
|
249
|
+
begin
|
|
250
|
+
yield status
|
|
251
|
+
ensure
|
|
252
|
+
status.release_lock
|
|
253
|
+
end
|
|
254
|
+
else
|
|
255
|
+
raise BarkestCore::GlobalStatus::FailureToLock.new if raise_on_failure
|
|
256
|
+
yield false
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
private
|
|
261
|
+
|
|
262
|
+
def self.global_instance
|
|
263
|
+
@global_instance ||= GlobalStatus.new
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
end
|
|
267
|
+
end
|