Пример #1
0
class Report(object):
    """
        PDF report for plots generated on the basis of raw eye-tracking data.
    """
    def __init__(self, file_handler, report_file_name,
                 open_after_download_flag, properties):
        self.file_handler = file_handler
        self.open_after_download = open_after_download_flag
        self.properties = properties
        self.font_path = join(self.file_handler.fonts_dir,
                              'DejaVuSans.ttf')  # unicode font
        self.pdf = FPDF(orientation='P', unit='mm', format='A4')
        fpdf.set_global("FPDF_CACHE_MODE", 1)

        # get date & time
        current_date = datetime.now().strftime("%d.%m.%Y  %H:%M")
        current_timestamp = str(time.time()).replace('.', '')

        self.title = properties.report_title
        self.subtitle = properties.report_subtitle
        self.subtitle_date = properties.subtitle_with_date.format(current_date)
        self.subtitle_rec_dir = properties.subtitle_with_rec_dir_path.format(
            self.file_handler.recording_dir)
        self.subtitle_export_dir = properties.subtitle_with_exported_dir_path.format(
            self.file_handler.exports_dir)
        self.pdf_file_name = properties.pdf_report_file_name.format(
            current_timestamp
        ) if report_file_name == "" else report_file_name + ".pdf"

        # table with fixation_report.csv data
        self.fixation_detector_table_description = properties.fixation_detector_table_description
        self.parameter_table_header_name = properties.fixation_detector_settings_values_param
        self.value_table_header_name = properties.fixation_detector_settings_values_val

        self.target_file_path = join(self.file_handler.downloads_dir,
                                     self.pdf_file_name)

        self.title_font_size = 25
        self.subtitle_font_size = 20
        self.subsection_title_fontsize = 25
        self.paragraph_fontsize = 14

    def add_first_page(self):
        """
           Creates report first page with:
             title,
             date,
             # recording_directory
             # and exports_directory
        """

        title_line_break_value = 90
        self.pdf.add_page()  # add first report page
        self.pdf.ln(title_line_break_value)
        self.pdf.alias_nb_pages()  # Create the special value {nb}
        self.pdf.set_margins(left=10.00, top=10.00, right=10.00)

        self.pdf.set_font("Courier", 'B', size=self.title_font_size)
        self.pdf.cell(w=190, h=15, txt=self.title, ln=1, align="C")

        self.pdf.set_font("Courier", 'B', size=self.subtitle_font_size)
        self.pdf.cell(w=190, h=10, txt=self.subtitle, ln=1, align="C")

        self.pdf.set_font("Arial", size=10)
        self.pdf.cell(w=190, h=10, txt=self.subtitle_date, ln=1, align="C")

        left = self.pdf.l_margin
        right = self.pdf.r_margin
        top = self.pdf.t_margin
        bottom = self.pdf.b_margin
        # Effective page width and height
        epw = self.pdf.w - left - right
        eph = self.pdf.h - top - bottom
        self.pdf.rect(left, top, w=epw, h=eph)  # draw margins

    def add_subsection(self, title, description):
        self.pdf.add_page()
        self.pdf.set_font("Courier", 'B', size=self.subsection_title_fontsize)
        self.pdf.cell(w=190, h=15, txt=title, ln=1, align="L")
        self.add_unicode_font(14)
        self.pdf.multi_cell(w=190,
                            h=10,
                            txt=self.pdf.normalize_text(description))

    def add_fixation_report(self, fixation_report_obj):
        self.add_unicode_font(14)
        epw = self.pdf.w - 2 * self.pdf.l_margin  # effective page width, or just epw
        col_width = epw / 2  # distribute columns content evenly across table and page

        data = {
            self.parameter_table_header_name: self.value_table_header_name,
            "max_dispersion": fixation_report_obj.max_dispersion,
            "min_duration": fixation_report_obj.min_duration,
            "max_duration": fixation_report_obj.max_duration,
            "fixation_count": fixation_report_obj.fixation_count
        }

        th = self.pdf.font_size
        self.pdf.multi_cell(w=190,
                            h=8,
                            txt=self.fixation_detector_table_description,
                            align="L")
        counter = 0
        for key, value in data.items():
            counter += 1
            if counter == 1:
                self.pdf.cell(w=col_width,
                              h=(2 * th),
                              txt=self.pdf.normalize_text(str(key)),
                              border=1,
                              align="C")
                self.pdf.cell(w=col_width,
                              h=(2 * th),
                              txt=self.pdf.normalize_text(str(value)),
                              border=1,
                              align="C")
                self.pdf.set_font(family="font", size=10)
            else:
                self.pdf.cell(col_width,
                              2 * th,
                              self.pdf.normalize_text(str(key)),
                              border=1,
                              align="C")
                self.pdf.cell(col_width,
                              2 * th,
                              self.pdf.normalize_text(str(value)),
                              border=1,
                              align="C")
            self.pdf.ln(2 * th)

    def add_plot(self, plot):
        self.pdf.add_page()
        try:
            self.pdf.image(plot.image_path, w=190)
        except FileNotFoundError as exception:
            logger.error(f"NOT FOUND file {plot.image_path}")
            print(exception)

        self.add_unicode_font(plot.fontsize)
        self.pdf.multi_cell(w=190,
                            h=10,
                            txt=self.pdf.normalize_text(plot.description))

    def save_report(self):
        """
            Saves report in /exports/../downloads directory
        """
        logger.info(f'Save report into {self.target_file_path}')
        self.pdf.output(self.target_file_path)

        logger.info(f"Report '{self.pdf_file_name}' saved")
        logger.info(f"Report directory: {self.file_handler.downloads_dir}")

        if self.open_after_download:
            try:
                startfile(self.target_file_path)
            except:
                system("xdg-open \"%s\"" % self.target_file_path)

    def add_unicode_font(self, fontsize):
        print("FONT PATH: \n", self.font_path)
        self.pdf.add_font(family="font", fname=self.font_path, uni=True)
        self.pdf.set_font(family="font", size=fontsize)
Пример #2
0
class PdfHandler:
    def __init__(self, orientation='P', unit='pt', format='A4'):
        self.pdf_handler = FPDF(orientation=orientation, unit=unit, format=format)
    
    def _set_margins(self, left, top, right=-1):
        return self.pdf_handler.set_margins(left, top, right=right)

    def _set_title(self, title):
        return self.pdf_handler.set_title(title)

    def _set_subject(self, subject):
        return self.pdf_handler.set_subject(subject)

    def _set_author(self, author):
        return self.pdf_handler.set_author(author)

    def _set_keywords(self, keywords):
        return self.pdf_handler.set_keywords(keywords)

    def _set_creator(self, creator):
        return self.pdf_handler.set_creator(creator)

    def _add_page(self, orientation=''):
        return self.pdf_handler.add_page(orientation=orientation)

    def _set_draw_color(self, r, g=-1, b=-1):
        return self.pdf_handler.set_draw_color(r, g=g, b=b)

    def _set_fill_color(self, r, g=-1, b=-1):
        return self.pdf_handler.set_fill_color(g=g, b=b)

    def _set_text_color(self, r, g=-1, b=-1):
        return self.pdf_handler.set_text_color(r, g=-g, b=b)

    def _get_string_width(self, s):
        return self.pdf_handler.get_string_width(s)

    def _set_line_width(self, width):
        return self.pdf_handler.set_line_width(width)

    def _line(self, x1, y1, x2, y2):
        return self.pdf_handler.line(x1, y1, x2, y2)

    def _dashed_line(self, x1, y1, x2, y2, dash_length=1, space_length=1):
        return self.pdf_handler.dashed_line(x1, y1, x2, y2, dash_length=dash_length, space_length=space_length)

    def _rect(self, x, y, w, h, style=''):
        return self.pdf_handler.rect(x, y, w, h, style=style)

    def _ellipse(self, x, y, w, h, style=''):
        return self.pdf_handler.ellipse(x, y, w, h, style=style)

    def _set_font(self, family, style='', size=0):
        return self.pdf_handler.set_font(family, style=style, size=size)

    def _set_font_size(self, size):
        return self.pdf_handler.set_font_size(size)

    def _text(self, x, y, txt=''):
        return self.pdf_handler.text(x, y, txt=txt)

    def _multi_cell(self, w, h, txt='', border=0, align='J', fill=0, split_only=False):
        return self.pdf_handler.multi_cell(w, h, txt=txt, border=border, align=align, fill=fill, split_only=split_only)

    def _write(self, h, txt='', link=''):
        return self.pdf_handler.write(h, txt=txt, link=link)

    def _image(self, name, x=None, y=None, w=0, h=0, image_type='', link=''):
        return self.pdf_handler.image(name, x=x, y=y, w=w,h=h,type=image_type,link=link)

    def _normalize_text(self, txt):
        return self.pdf_handler.normalize_text(txt)

    def _output(self, name='', dest=''):
        return self.pdf_handler.output(name, dest)