<commit_before>#
# Copyright (C) 2011 - 2012 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#

require 'zip/zip'

module Canvas::AccountReports
  class AvailableReports
    @reports = {}
    @module_names = {}
    class << self
      attr_reader :reports, :module_names
      private :new
    end
  end

  def self.add_account_reports(account_id, module_name, reports)
    AvailableReports.reports[account_id] = reports
    AvailableReports.module_names[account_id] = module_name
  end

  def self.for_account(id)
    (AvailableReports.reports['default'] || {}).merge(AvailableReports.reports[id] || {})
  end

  def self.generate_report(account_report)
    account_report.update_attribute(:workflow_state, 'running')
    account_report.start_at ||= 2.months.ago
    account_report.end_at ||= Time.now
    begin
      module_name = AvailableReports.module_names[account_report.root_account.id]
      if module_name && Canvas::AccountReports.const_defined?(module_name) &&
              Canvas::AccountReports.const_get(module_name).respond_to?(account_report.report_type)
        Canvas::AccountReports.const_get(module_name).send(account_report.report_type, account_report)
      elsif Canvas::AccountReports.const_defined?('Default') &&
              Canvas::AccountReports.const_get('Default').respond_to?(account_report.report_type)
        Canvas::AccountReports.const_get('Default').send(account_report.report_type, account_report)
      else
        nil
      end
    rescue => e
      account_report.logger.error e
      er = ErrorReport.log_exception(:default, e, :user => account_report.user)
      self.message_recipient(account_report, "Generating the report, #{account_report.report_type.to_s.titleize}, failed.  Please report the following error code to your system administrator: ErrorReport:#{er.id}")
    end
  end

  def self.message_recipient(account_report, message, csv=nil)
    user = account_report.user
    account = account_report.account
    notification = Notification.by_name("Report Generated")
    notification = Notification.by_name("Report Generation Failed") if !csv
    attachment = nil
    if csv.is_a? Hash
      filename = "#{account_report.report_type}_#{Time.now.strftime('%d_%b_%Y')}_#{account_report.id}_.zip"
      temp = Tempfile.open(filename)
      filepath = temp.path
      temp.close
      FileUtils::rm temp.path

      Zip::ZipFile.open(filepath, Zip::ZipFile::CREATE) do |zipfile|
        csv.each do |(report_name, contents)|
          zipfile.get_output_stream(report_name) { |f| f << contents }
        end
        zipfile<commit_msg>fixes account reports zip export to have .csv on files<commit_after>#
# Copyright (C) 2011 - 2012 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#

require 'zip/zip'

module Canvas::AccountReports
  class AvailableReports
    @reports = {}
    @module_names = {}
    class << self
      attr_reader :reports, :module_names
      private :new
    end
  end

  def self.add_account_reports(account_id, module_name, reports)
    AvailableReports.reports[account_id] = reports
    AvailableReports.module_names[account_id] = module_name
  end

  def self.for_account(id)
    (AvailableReports.reports['default'] || {}).merge(AvailableReports.reports[id] || {})
  end

  def self.generate_report(account_report)
    account_report.update_attribute(:workflow_state, 'running')
    account_report.start_at ||= 2.months.ago
    account_report.end_at ||= Time.now
    begin
      module_name = AvailableReports.module_names[account_report.root_account.id]
      if module_name && Canvas::AccountReports.const_defined?(module_name) &&
              Canvas::AccountReports.const_get(module_name).respond_to?(account_report.report_type)
        Canvas::AccountReports.const_get(module_name).send(account_report.report_type, account_report)
      elsif Canvas::AccountReports.const_defined?('Default') &&
              Canvas::AccountReports.const_get('Default').respond_to?(account_report.report_type)
        Canvas::AccountReports.const_get('Default').send(account_report.report_type, account_report)
      else
        nil
      end
    rescue => e
      account_report.logger.error e
      er = ErrorReport.log_exception(:default, e, :user => account_report.user)
      self.message_recipient(account_report, "Generating the report, #{account_report.report_type.to_s.titleize}, failed.  Please report the following error code to your system administrator: ErrorReport:#{er.id}")
    end
  end

  def self.message_recipient(account_report, message, csv=nil)
    user = account_report.user
    account = account_report.account
    notification = Notification.by_name("Report Generated")
    notification = Notification.by_name("Report Generation Failed") if !csv
    attachment = nil
    if csv.is_a? Hash
      filename = "#{account_report.report_type}_#{Time.now.strftime('%d_%b_%Y')}_#{account_report.id}_.zip"
      temp = Tempfile.open(filename)
      filepath = temp.path
      temp.close
      FileUtils::rm temp.path

      Zip::ZipFile.open(filepath, Zip::ZipFile::CREATE) do |zipfile|
        csv.each do |(report_name, contents)|
          zipfile.get_output_stream(report_name + ".csv") { |f| f << contents }
        end
        zipfile
{'fraction_non_alphanumeric': 0.09915940224159402, 'fraction_numerical': 0.00311332503113325, 'mean_word_length': 3.972910216718266, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6861399', 'n_tokens_mistral': 1937, 'n_tokens_neox': 1868, 'n_words': 477}