text: # Copyright 2013 Sascha Peilicke
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #   http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  from __future__ import print_function
  
  import datetime
  import glob
  import os
  import shutil
  import subprocess
  import sys
  if sys.version_info > (3, 3):
      import concurrent.futures as futures
  else:
      import futures
  import traceback
  
  import jinja2
  
  import rapport.config
  import rapport.template
  import rapport.util
  
  
  def _get_reports_path(report=None):
      path_parts = ["~", ".rapport", "reports"]
      if report:
          path_parts.append(report)
      return os.path.expanduser(os.path.join(*path_parts))
  
  
  def list_reports():
      """Returns a list of created reports.
      """
      return sorted(os.listdir(_get_reports_path()))
  
  
  def get_report(report=None):
      """Returns details of a specific report
      """
      if not report:
          report = list_reports()[-1:][0]
      report_path = _get_reports_path(report)
      report_dict = {"report": report}
      for filename in os.listdir(report_path):
          with open(os.path.join(report_path, filename), "r") as f:
              report_dict[filename] = f.read()
      return report_dict
  
  
  def edit_report(report=None, type="email", email_part="body"):
      if not report:
          report = list_reports()[-1:][0]
      report_path = _get_reports_path(report)
      editor = os.getenv("EDITOR", "vi")
      if type == "email":
          report_file = "{0}.{1}.text".format(type, email_part)
      elif type == "html":
          report_file = "index.html"
      subprocess.call([editor, os.path.join(report_path, report_file)])
  
  
  def create_report(plugins, timeframe):
      report_date_string = timeframe.end.strftime(rapport.util.ISO8610_FORMAT)
      report_path = _get_reports_path(report_date_string)
      if not os.path.exists(report_path):
          os.makedirs(report_path)
  
      # Execute all plugins in parallel and join on results:
      results = {}
      with futures.ThreadPoolExecutor(max_workers=4) as executor:
          plugin_futures = dict((executor.submit(p.collect, timeframe), p) for p in plugins)
          for future in futures.as_completed(plugin_futures):
              plugin = plugin_futures[future]
              try:
                  if rapport.config.get_int("rapport", "verbosity") >= 2:
                      print("Result for {0}: {1}".format(plugin.alias, future.result()))
                  tmpl = rapport.template.get_template(plugin, "text")
                  if tmpl:
                      results[plugin] = tmpl.render(future.result())
              except jinja2.TemplateSyntaxError as e:
                  print >>sys.stderr, "Syntax error in plugin {0} at {1} line {2}: {3}".format(plugin, e.name, e.lineno, e.message)
              except Exception as e:
                  print("Failed plugin {0}:{1}: {2}!".format(plugin, plugin.alias, e), file=sys.stderr)
                  print(traceback.format_exc(), file=sys.stderr)
  
      results_dict = {"login": rapport.config.get("user", "login"),
                      "date": report_date_string,
                      "plugins": plugins,
                      "results": results}
  
      # Render mail body template:
      template_email_body = rapport.template.get_template("body", type="email")
      email_body = template_email_body.render(results_dict)
      email_body_file = os.path.join(report_path, "email.body.text")
      with open(email_body_file, "w") as report:
          report.write(email_body)
  
      # We can re-use the e-mail body as the general report body:
      results_dict["body"] = email_body
  
      # Render mail subject template:
      template_email_subject = rapport.template.get_template("subject", type="email")
      email_subject = template_email_subject.render(results_dict)
      email_subject_file = os.path.join(report_path, "email.subject.text")
      with open(email_subject_file, "w") as report:
          report.write(email_subject)
  
      #TODO: Maybe even create a Result class and return that instead of a dict?
      return results_dict
  
  
  def delete_report(report):
      """Delete report(s), supports globbing.
      """
      for path in glob.glob(os.path.join(_get_reports_path(), report)):
          shutil.rmtree(path)
  