Module: ExportToSpreadsheet

Defined in:
lib/export_to_spreadsheet.rb

Overview

This is the module to include into an ActiveRecord model in order to make its data exportable. You will have to also define a compose_export method that tells the plug-in what data to export.

Examples:

class Foo < ActiveRecord::Base
  include ExportToSpreadsheet

  def compose_export
    @doc.write do |d|
      d.title_1('Export of foo')
      d.line("My foo is #{self.name}")
    end
  end

Constant Summary collapse

@@export_use_fork =

Whether we want to use fork to run the export or not

true

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.export_use_fork=(val) ⇒ Object



23
24
25
# File 'lib/export_to_spreadsheet.rb', line 23

def self.export_use_fork= val
  @@export_use_fork = val
end

Instance Method Details

#make_tokenObject

Generates a complex String to ensure that a filename is uniq



28
29
30
31
32
# File 'lib/export_to_spreadsheet.rb', line 28

def make_token
  # From the restful-authentication plug-in
  args = [ Time.now, (1..10).map{ rand.to_s } ]
  Digest::SHA1.hexdigest(args.flatten.join('--'))
end

#to_excel(*args) ⇒ Object

The actual export (starting the JVM and exporting) is done in a forked process that can be terminated once the file is written. This is to make sure that the (high amount of) memory used by the JVM is freed once its job is over. With MySQL this messes a little with database connections so we have to close the connection and reopen it in each process. On Windows, this does not work so when do a basic export then.

Parameters:

  • args (Hash)

    hash for export configuration

Options Hash (*args):

  • :filename (String)

    filename

  • :user_team_id (String)

    the id of the user that performs the export

  • :export_type (String)

    the id of the user that performs the export

  • :pipeline_date (String)

    the date that is used to view the pipeline

Returns:

Raises:

  • (RunTimeError)

    an exception is raised when an error occurs during the export. The log has to be checked to see what happened



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/export_to_spreadsheet.rb', line 47

def to_excel(*args)
  # Setting up a few variable so we can find the file once it has been written
  export = prepare_to_excel(*args)

  # Closing the DB connection before forking, we store the config to be able to reconnect easily
  dbconfig = ActiveRecord::Base.remove_connection

  # fork forks the process and returns
  #   the pid of the child process in the father process
  #   and the nil in the child process
  # so we know in which process we are depending on the returned value
  begin
    if @@export_use_fork
      if fork
        # This is the father process
        ActiveRecord::Base.establish_connection(dbconfig)
        # We just wait for the child process to have finished the export
        # wait2 returns [pid, exit_code] # exit_code has the class Process::Status
        exit_code = Process.wait2.last.to_i
      else
        begin
          # This is the child process
          ActiveRecord::Base.establish_connection(dbconfig)
          # Doing the actual export
          # This is what starts the JVM
          compute_to_excel(*args)
          exit!(0) # Terminating the process
        rescue Exception => e # need to make sure the child process finishes even if the export fails
          logger.error e.message
          logger.error e.backtrace.join("\n")
          exit!(1)
        end
      end
    else
      raise "not even trying"
    end

  # Handles at least the Windows case where the fork function is not implemented.
  # In this case do a simple export without forking the process
  rescue Exception => e
    ActiveRecord::Base.establish_connection(dbconfig)
    compute_to_excel(*args)
    exit_code = 0
  end

  # If the export did not finish normally, we raise an error
  raise "Unexpected error during export" if exit_code != 0

  # It worked, we return the export
  return export
end

#to_google_spreadsheets(oauth_token) ⇒ Object #to_google_spreadsheets(google_login, google_password) ⇒ Object

Overloads:

  • #to_google_spreadsheets(oauth_token) ⇒ Object

    Exports a model to a Google Spreadsheet doc using a OAuth token

  • #to_google_spreadsheets(google_login, google_password) ⇒ Object

    Exports a model to a Google Spreadsheet doc using a Google account credentials



103
104
105
106
# File 'lib/export_to_spreadsheet.rb', line 103

def to_google_spreadsheets(*args)
  prepare_export(:google_spreadsheets, *args)
  return compute_export(:google_spreadsheets, *args)
end