asana_exception_notifier 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +26 -0
  3. data/.reek +11 -0
  4. data/.rubocop.yml +76 -0
  5. data/.travis.yml +16 -0
  6. data/CONTRIBUTING.md +46 -0
  7. data/Gemfile +3 -0
  8. data/Gemfile.lock +180 -0
  9. data/LICENSE +20 -0
  10. data/README.md +225 -0
  11. data/Rakefile +37 -0
  12. data/asana_exception_notifier.gemspec +48 -0
  13. data/examples/sinatra/Gemfile +7 -0
  14. data/examples/sinatra/Gemfile.lock +124 -0
  15. data/examples/sinatra/Procfile +1 -0
  16. data/examples/sinatra/README.md +14 -0
  17. data/examples/sinatra/config.ru +3 -0
  18. data/examples/sinatra/sinatra_app.rb +46 -0
  19. data/init.rb +1 -0
  20. data/lib/asana_exception_notifier/classes/asana.rb +95 -0
  21. data/lib/asana_exception_notifier/classes/error_page.rb +134 -0
  22. data/lib/asana_exception_notifier/helpers/application_helper.rb +286 -0
  23. data/lib/asana_exception_notifier/initializers/zip.rb +14 -0
  24. data/lib/asana_exception_notifier/note_templates/asana_exception_notifier.html.erb +82 -0
  25. data/lib/asana_exception_notifier/note_templates/asana_exception_notifier.text.erb +24 -0
  26. data/lib/asana_exception_notifier/request/client.rb +85 -0
  27. data/lib/asana_exception_notifier/request/core.rb +132 -0
  28. data/lib/asana_exception_notifier/request/middleware.rb +41 -0
  29. data/lib/asana_exception_notifier/version.rb +27 -0
  30. data/lib/asana_exception_notifier.rb +45 -0
  31. data/lib/generators/asana_exception_notifier/install_generator.rb +14 -0
  32. data/lib/generators/asana_exception_notifier/templates/asana_exception_notifier.rb +20 -0
  33. data/spec/lib/asana_exception_notifier/classes/asana_spec.rb +23 -0
  34. data/spec/spec_helper.rb +45 -0
  35. data/spec/test_notification.rb +20 -0
  36. metadata +467 -0
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ require 'bundler/setup'
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+ require 'coveralls/rake/task'
5
+ require 'yard'
6
+ Coveralls::RakeTask.new
7
+
8
+ RSpec::Core::RakeTask.new(:spec) do |spec|
9
+ default_options = ['--colour']
10
+ default_options.concat(['--backtrace', '--fail-fast']) if ENV['DEBUG']
11
+ spec.rspec_opts = default_options
12
+ end
13
+
14
+ YARD::Config.options[:load_plugins] = true
15
+ YARD::Config.load_plugins
16
+
17
+ YARD::Rake::YardocTask.new do |t|
18
+ t.files = ['lib/**/*.rb', 'spec/**/*_spec.rb'] # optional
19
+ t.options = ['--any', '--extra', '--opts', '--markup-provider=redcarpet', '--markup=markdown', '--debug'] # optional
20
+ t.stats_options = ['--list-undoc'] # optional
21
+ end
22
+
23
+ desc 'Default: run the unit tests.'
24
+ task default: [:all]
25
+
26
+ desc 'Test the plugin under all supported Rails versions.'
27
+ task :all do |_t|
28
+ if ENV['TRAVIS']
29
+ exec('bundle exec rake spec && bundle exec rake coveralls:push')
30
+ else
31
+ exec('bundle exec rake spec')
32
+ end
33
+ end
34
+
35
+ task :docs do
36
+ exec('bundle exec inch --pedantic && bundle exec yard --list-undoc')
37
+ end
@@ -0,0 +1,48 @@
1
+ require File.expand_path('../lib/asana_exception_notifier/version', __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'asana_exception_notifier'
5
+ s.version = AsanaExceptionNotifier.gem_version
6
+ s.platform = Gem::Platform::RUBY
7
+ s.summary = 'Simple ruby implementation to send notifications to Asana
8
+ when a exception happens in Rails or Rack-based apps by creating a task and uploading exception details to the task'
9
+ s.email = 'raoul_ice@yahoo.com'
10
+ s.homepage = 'http://github.com/bogdanRada/asana_exception_notifier'
11
+ s.description = 'Simple ruby implementation to send notifications to Asana
12
+ when a exception happens in Rails or Rack-based apps by creating a task and uploading exception details to the task using zip archives'
13
+ s.authors = ['bogdanRada']
14
+ s.date = Date.today
15
+
16
+ s.licenses = ['MIT']
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = s.files.grep(/^(spec)/)
19
+ s.require_paths = ['lib']
20
+
21
+ s.required_ruby_version = '>= 2.0'
22
+ s.required_rubygems_version = '>= 2.5'
23
+ s.metadata = {
24
+ 'source_code' => s.homepage,
25
+ 'bug_tracker' => "#{s.homepage}/issues"
26
+ }
27
+
28
+ s.add_runtime_dependency 'activesupport', '>= 4.0', '< 5'
29
+ s.add_runtime_dependency 'em-http-request', '~> 1.1', '>= 1.1.2'
30
+ s.add_runtime_dependency 'eventmachine', '~> 1.0', '>= 1.0.7'
31
+ s.add_runtime_dependency 'exception_notification', '~> 4.1', '>= 4.1.4'
32
+ s.add_runtime_dependency 'multipart_body', '~> 0.2', '>= 0.2.1'
33
+ s.add_runtime_dependency 'tilt', '>= 1.4', '< 3'
34
+ s.add_runtime_dependency 'rack', '~> 1.6', '>= 1.6'
35
+ s.add_runtime_dependency 'rubyzip', '~> 1.0', '>= 1.0.0' # will load new rubyzip version
36
+ s.add_runtime_dependency 'zip-zip', '~> 0.3', '>= 0.3' # will load compatibility for old rubyzip API
37
+ s.add_runtime_dependency 'sys-uname', '~> 1.0', '>= 1.0.2'
38
+
39
+ s.add_development_dependency 'rspec', '~> 3.4', '>= 3.4'
40
+ s.add_development_dependency 'simplecov', '~> 0.10', '>= 0.10'
41
+ s.add_development_dependency 'simplecov-summary', '~> 0.0.4', '>= 0.0.4'
42
+ s.add_development_dependency 'coveralls', '~> 0.7', '>= 0.7'
43
+ s.add_development_dependency 'rake', '~> 10.5', '>= 10.5'
44
+ s.add_development_dependency 'yard', '~> 0.8', '>= 0.8.7'
45
+ s.add_development_dependency 'redcarpet', '~> 3.3', '>= 3.3'
46
+ s.add_development_dependency 'github-markup', '~> 1.3', '>= 1.3.3'
47
+ s.add_development_dependency 'inch', '~> 0.6', '>= 0.6'
48
+ end
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "asana_exception_notifier", path: "../../"
4
+
5
+ gem "thin", "~> 1.5.1"
6
+ gem "sinatra", "~> 1.4"
7
+ gem "foreman"
@@ -0,0 +1,124 @@
1
+ PATH
2
+ remote: ../../
3
+ specs:
4
+ asana_exception_notifier (0.0.1)
5
+ activesupport (>= 4.0, < 5)
6
+ em-http-request (~> 1.1, >= 1.1.2)
7
+ eventmachine (~> 1.0, >= 1.0.7)
8
+ exception_notification (~> 4.1, >= 4.1.4)
9
+ multipart_body (~> 0.2, >= 0.2.1)
10
+ rack (~> 1.6, >= 1.6)
11
+ rubyzip (~> 1.0, >= 1.0.0)
12
+ sys-uname (~> 1.0, >= 1.0.2)
13
+ tilt (>= 1.4, < 3)
14
+ zip-zip (~> 0.3, >= 0.3)
15
+
16
+ GEM
17
+ remote: https://rubygems.org/
18
+ specs:
19
+ actionmailer (4.2.5.1)
20
+ actionpack (= 4.2.5.1)
21
+ actionview (= 4.2.5.1)
22
+ activejob (= 4.2.5.1)
23
+ mail (~> 2.5, >= 2.5.4)
24
+ rails-dom-testing (~> 1.0, >= 1.0.5)
25
+ actionpack (4.2.5.1)
26
+ actionview (= 4.2.5.1)
27
+ activesupport (= 4.2.5.1)
28
+ rack (~> 1.6)
29
+ rack-test (~> 0.6.2)
30
+ rails-dom-testing (~> 1.0, >= 1.0.5)
31
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
32
+ actionview (4.2.5.1)
33
+ activesupport (= 4.2.5.1)
34
+ builder (~> 3.1)
35
+ erubis (~> 2.7.0)
36
+ rails-dom-testing (~> 1.0, >= 1.0.5)
37
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
38
+ activejob (4.2.5.1)
39
+ activesupport (= 4.2.5.1)
40
+ globalid (>= 0.3.0)
41
+ activesupport (4.2.5.1)
42
+ i18n (~> 0.7)
43
+ json (~> 1.7, >= 1.7.7)
44
+ minitest (~> 5.1)
45
+ thread_safe (~> 0.3, >= 0.3.4)
46
+ tzinfo (~> 1.1)
47
+ addressable (2.4.0)
48
+ builder (3.2.2)
49
+ cookiejar (0.3.0)
50
+ daemons (1.2.3)
51
+ em-http-request (1.1.3)
52
+ addressable (>= 2.3.4)
53
+ cookiejar (<= 0.3.0)
54
+ em-socksify (>= 0.3)
55
+ eventmachine (>= 1.0.3)
56
+ http_parser.rb (>= 0.6.0)
57
+ em-socksify (0.3.1)
58
+ eventmachine (>= 1.0.0.beta.4)
59
+ erubis (2.7.0)
60
+ eventmachine (1.0.9.1)
61
+ exception_notification (4.1.4)
62
+ actionmailer (~> 4.0)
63
+ activesupport (~> 4.0)
64
+ ffi (1.9.10)
65
+ foreman (0.78.0)
66
+ thor (~> 0.19.1)
67
+ globalid (0.3.6)
68
+ activesupport (>= 4.1.0)
69
+ http_parser.rb (0.6.0)
70
+ i18n (0.7.0)
71
+ json (1.8.3)
72
+ loofah (2.0.3)
73
+ nokogiri (>= 1.5.9)
74
+ mail (2.6.3)
75
+ mime-types (>= 1.16, < 3)
76
+ mime-types (2.99)
77
+ mini_portile2 (2.0.0)
78
+ minitest (5.8.4)
79
+ multipart_body (0.2.1)
80
+ nokogiri (1.6.7.2)
81
+ mini_portile2 (~> 2.0.0.rc2)
82
+ rack (1.6.4)
83
+ rack-protection (1.5.3)
84
+ rack
85
+ rack-test (0.6.3)
86
+ rack (>= 1.0)
87
+ rails-deprecated_sanitizer (1.0.3)
88
+ activesupport (>= 4.2.0.alpha)
89
+ rails-dom-testing (1.0.7)
90
+ activesupport (>= 4.2.0.beta, < 5.0)
91
+ nokogiri (~> 1.6.0)
92
+ rails-deprecated_sanitizer (>= 1.0.1)
93
+ rails-html-sanitizer (1.0.3)
94
+ loofah (~> 2.0)
95
+ rubyzip (1.1.7)
96
+ sinatra (1.4.7)
97
+ rack (~> 1.5)
98
+ rack-protection (~> 1.4)
99
+ tilt (>= 1.3, < 3)
100
+ sys-uname (1.0.2)
101
+ ffi (>= 1.0.0)
102
+ thin (1.5.1)
103
+ daemons (>= 1.0.9)
104
+ eventmachine (>= 0.12.6)
105
+ rack (>= 1.0.0)
106
+ thor (0.19.1)
107
+ thread_safe (0.3.5)
108
+ tilt (2.0.2)
109
+ tzinfo (1.2.2)
110
+ thread_safe (~> 0.1)
111
+ zip-zip (0.3)
112
+ rubyzip (>= 1.0.0)
113
+
114
+ PLATFORMS
115
+ ruby
116
+
117
+ DEPENDENCIES
118
+ asana_exception_notifier!
119
+ foreman
120
+ sinatra (~> 1.4)
121
+ thin (~> 1.5.1)
122
+
123
+ BUNDLED WITH
124
+ 1.11.2
@@ -0,0 +1 @@
1
+ web: bundle exec thin start --port 3000
@@ -0,0 +1,14 @@
1
+ Using Exception Notification with Sinatra
2
+ =========================================
3
+
4
+ Quick start
5
+ -----------
6
+
7
+ ```
8
+ git clone git@github.com:bogdanRada/asana_exception_notifier.git
9
+ cd exception_notification/examples/sinatra
10
+ bundle install
11
+ bundle exec foreman start
12
+ ```
13
+
14
+ The last command starts the sinatra app itself. Thus, visit [http://localhost:1080/](http://localhost:1080/) to check the asana notification is sent and, in a separated tab, visit [Asana.com](http://asana.com) and cause some errors. For more info, use the [source](https://github.com/bogdanRada/asana_exception_notifier/blob/master/examples/sinatra/sinatra_app.rb).
@@ -0,0 +1,3 @@
1
+ require ::File.expand_path('../sinatra_app', __FILE__)
2
+
3
+ run SinatraApp
@@ -0,0 +1,46 @@
1
+ $stdout.sync = true
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ require 'bundler/setup'
5
+ ENV['RACK_ENV'] ||= ENV['RAILS_ENV'].present? ? ENV['RAILS_ENV'] : 'development'
6
+ Bundler.require :default, (ENV['RACK_ENV'] || 'development').to_sym
7
+
8
+
9
+ class SinatraApp < Sinatra::Base
10
+ use Rack::Config do |env|
11
+ env["action_dispatch.parameter_filter"] = [:password] # This is highly recommended. It will prevent the ExceptionNotification email from including your users' passwords
12
+ end
13
+
14
+ use ExceptionNotification::Rack,
15
+ :asana => {
16
+ asana_api_key: ENV['ASANA_API_KEY'],
17
+ workspace: ENV['ASANA_WORKSPACE_ID'],
18
+ assignee: 'me',
19
+ assignee_status: 'today', # 'today'
20
+ due_at: Time.now.iso8601,
21
+ due_on: nil,
22
+ hearted: false,
23
+ hearts: [],
24
+ projects: [],
25
+ followers: [],
26
+ memberships: [],
27
+ tags: [],
28
+ name: nil,
29
+ notes: '',
30
+ template_path: nil
31
+ }
32
+
33
+ get '/' do
34
+ raise StandardError, "ERROR: #{params[:error]}" unless params[:error].blank?
35
+ 'Everything is fine! Now, lets break things clicking <a href="/?error=ops"> here </a>. Dont forget to see the asana tasks at <a href="http://asana.com">Asana</a> !'
36
+ end
37
+
38
+ get '/background_notification' do
39
+ begin
40
+ 1/0
41
+ rescue Exception => e
42
+ ExceptionNotifier.notify_exception(e, :data => {:msg => "Cannot divide by zero!"})
43
+ end
44
+ 'Check notification at <a href="http://asana.com">Asana</a>.'
45
+ end
46
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'asana_exception_notifier'
@@ -0,0 +1,95 @@
1
+ require_relative '../helpers/application_helper'
2
+ require_relative '../request/client'
3
+ require_relative '../request/middleware'
4
+ # class used for connecting to github api and retrieves information about repository
5
+ #
6
+ # @!attribute callback
7
+ # @return [Proc] The callback that is executed after the info is fetched from Github API
8
+ module ExceptionNotifier
9
+ # module that is used for formatting numbers using metrics
10
+ class AsanaNotifier < ExceptionNotifier::BaseNotifier
11
+ include AsanaExceptionNotifier::ApplicationHelper
12
+ # the base url to which the API will connect for fetching information about gems
13
+ attr_reader :initial_options, :default_options
14
+
15
+ def initialize(options)
16
+ execute_with_rescue do
17
+ super
18
+ @initial_options = options.symbolize_keys
19
+ options = @initial_options.reject { |_key, value| value.blank? }
20
+ parse_options(options)
21
+ end
22
+ end
23
+
24
+ def call(exception, options = {})
25
+ execute_with_rescue do
26
+ ensure_eventmachine_running do
27
+ EM::HttpRequest.use AsanaExceptionNotifier::Request::Middleware if ENV['DEBUG_ASANA_EXCEPTION_NOTIFIER']
28
+ error_page = AsanaExceptionNotifier::ErrorPage.new(template_path, exception, options)
29
+ create_asana_task(error_page) if active?
30
+ end
31
+ end
32
+ end
33
+
34
+ def active?
35
+ @default_options.fetch(:asana_api_key, nil).present? && @default_options.fetch(:workspace, nil).present?
36
+ end
37
+
38
+ private
39
+
40
+ def parse_options(options)
41
+ options = options.symbolize_keys.reject { |key, _value| !permitted_options.key?(key) }
42
+ @default_options = permitted_options.merge(options).reject { |_key, value| value.blank? }
43
+ end
44
+
45
+ def template_path
46
+ template_path = @default_options.fetch(:template_path, nil)
47
+ template_path.blank? ? default_template_path : template_path_exist(File.expand_path(template_path))
48
+ end
49
+
50
+ def build_request_options(error_page)
51
+ @default_options.except(:asana_api_key, :template_path).merge(
52
+ name: @default_options.fetch(:name, nil) || "[AsanaExceptionNotifier] #{error_page.exception_data[:message]}",
53
+ notes: @default_options.fetch(:notes, nil) || error_page.render_template(File.join(template_dir, 'asana_exception_notifier.text.erb')),
54
+ workspace: @default_options.fetch(:workspace, nil).to_i
55
+ ).symbolize_keys!
56
+ end
57
+
58
+ # This method fetches data from Github api and returns the size in
59
+ #
60
+ # @return [void]
61
+ def create_asana_task(error_page)
62
+ AsanaExceptionNotifier::Request::Client.new(@default_options.fetch(:asana_api_key, nil),
63
+ 'https://app.asana.com/api/1.0/tasks',
64
+ 'http_method' => 'post',
65
+ 'em_request' => { body: build_request_options(error_page) },
66
+ 'action' => 'creation'
67
+ ) do |http_response|
68
+ ensure_eventmachine_running do
69
+ upload_log_file_to_task(error_page, http_response.fetch('data', {}))
70
+ end
71
+ end
72
+ end
73
+
74
+ def upload_log_file_to_task(error_page, task_data)
75
+ archives = error_page.fetch_archives
76
+ archives.each do |zip|
77
+ upload_archive(zip, task_data)
78
+ end
79
+ end
80
+
81
+ def upload_archive(zip, task_data)
82
+ return if task_data.blank?
83
+ body = multipart_file_upload_details(zip)
84
+ AsanaExceptionNotifier::Request::Client.new(@default_options.fetch(:asana_api_key, nil),
85
+ "https://app.asana.com/api/1.0/tasks/#{task_data['id']}/attachments",
86
+ 'http_method' => 'post',
87
+ 'em_request' => body,
88
+ 'request_name' => zip,
89
+ 'action' => 'upload'
90
+ ) do |_http_response|
91
+ FileUtils.rm_rf([zip])
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,134 @@
1
+ require_relative '../helpers/application_helper'
2
+ module AsanaExceptionNotifier
3
+ # class used for rendering the template for exception
4
+ class ErrorPage
5
+ include AsanaExceptionNotifier::ApplicationHelper
6
+
7
+ attr_reader :template_path, :exception, :options, :boundary, :template_details, :env, :request, :tempfile, :template_params, :content
8
+
9
+ def initialize(template_path, exception, options)
10
+ @template_path = template_path
11
+ @exception = exception
12
+ @options = options.symbolize_keys
13
+ @template_details = setup_template_details
14
+ @env = (@options[:env] || ENV.to_h).stringify_keys
15
+ @request = action_dispatch? ? ActionDispatch::Request.new(@env) : Rack::Request.new(@env)
16
+ @timestamp = Time.now
17
+ parse_exception_options
18
+ end
19
+
20
+ def action_dispatch?
21
+ defined?(ActionDispatch::Request)
22
+ end
23
+
24
+ def setup_template_details
25
+ template_extension = @template_path.scan(/\.(\w+)\.?(.*)?/)[0][0]
26
+ get_extension_and_name_from_file(@template_path).merge(
27
+ template_extension: template_extension
28
+ )
29
+ end
30
+
31
+ def parse_exception_options
32
+ @template_params ||= {
33
+ server: Socket.gethostname,
34
+ exception: @exception,
35
+ request: @request,
36
+ environment: action_dispatch? ? @request.filtered_env : @env,
37
+ rails_root: defined?(Rails) ? Rails.root : nil,
38
+ process: $PROCESS_ID,
39
+ data: (@env.blank? ? {} : @env.fetch(:'exception_notifier.exception_data', {})).merge(@options[:data] || {}),
40
+ exception_data: exception_data,
41
+ request_data: setup_env_params,
42
+ uname: Sys::Uname.uname,
43
+ timestamp: @timestamp,
44
+ pwd: File.expand_path($PROGRAM_NAME)
45
+ }.merge(@options).reject { |_key, value| value.blank? }
46
+ end
47
+
48
+ def exception_data
49
+ {
50
+ error_class: @exception.class.to_s,
51
+ message: @exception.respond_to?(:message) ? @exception.message : exception.inspect,
52
+ backtrace: @exception.respond_to?(:backtrace) ? @exception.backtrace : '',
53
+ cause: @exception.respond_to?(:cause) ? @exception.cause : ''
54
+ }
55
+ end
56
+
57
+ def setup_env_params
58
+ {
59
+ url: action_dispatch? ? @request.original_url : @request.path_info,
60
+ referrer: @request.referer,
61
+ http_method: action_dispatch? ? @request.method : @request.request_method,
62
+ ip_address: action_dispatch? ? @request.remote_ip : @request.ip,
63
+ parameters: action_dispatch? ? @request.filtered_parameters : request_params,
64
+ session: @request.session,
65
+ cookies: @request.cookies,
66
+ user_agent: @request.user_agent
67
+ }
68
+ end
69
+
70
+ def request_params
71
+ @request.params
72
+ rescue
73
+ {}
74
+ end
75
+
76
+ def fieldsets_links
77
+ fieldsets.map { |key, _value| link_helper(key.to_s) }.join(' | ')
78
+ end
79
+
80
+ def fetch_fieldsets(hash, links = {}, prefix = nil)
81
+ return unless hash.is_a?(Hash)
82
+ hash.each do |key, value|
83
+ if value.is_a?(Hash)
84
+ fetch_fieldsets(value, links, key)
85
+ else
86
+ add_to_links(links, prefix, key: key, value: value)
87
+ end
88
+ end
89
+ links
90
+ end
91
+
92
+ def add_to_links(links, prefix, options = {})
93
+ expected_value = parse_fieldset_value(options)
94
+ return unless expected_value.present?
95
+ prefix_name = set_fieldset_key(links, prefix || 'basic_info')
96
+ links[prefix_name][options[:key]] = expected_value
97
+ end
98
+
99
+ def fieldsets
100
+ @fieldsets ||= fetch_fieldsets(parse_exception_options).except(:env)
101
+ end
102
+
103
+ def render_template(template = nil)
104
+ execute_with_rescue do
105
+ current_template = template.present? ? template : @template_path
106
+ Tilt.new(current_template).render(self, @template_params.stringify_keys)
107
+ end
108
+ end
109
+
110
+ def create_tempfile(output = render_template)
111
+ tempfile = Tempfile.new([SecureRandom.uuid, ".#{@template_details[:template_extension]}"], encoding: 'utf-8')
112
+ tempfile.write(output)
113
+ tempfile.close
114
+ details = tempfile_details(tempfile)
115
+ [details[:filename], details[:path]]
116
+ end
117
+
118
+ def fetch_archives(output = render_template)
119
+ return [] if output.blank?
120
+ filename, path = create_tempfile(output)
121
+ archive = compress_files(File.dirname(path), filename, [path])
122
+ remove_tempfile(path)
123
+ split_archive(archive, "part_#{filename}", 1024 * 1024 * 100)
124
+ end
125
+
126
+ def remove_tempfile(path)
127
+ if ENV['DEBUG_ASANA_TEMPLATE']
128
+ logger.debug(path)
129
+ else
130
+ FileUtils.rm_rf([path])
131
+ end
132
+ end
133
+ end
134
+ end