Пример #1
0
    def test_file_creator08(self):
        "Secure filename"
        dir_path = self.dir_path

        fcreator = FileCreator(dir_path, 'foo bar.txt', generators=[IncrFileNameSuffixGenerator])
        path1 = fcreator.create()
        self.assertEqual(join(dir_path, 'foo_bar.txt'), path1)
Пример #2
0
    def test_file_creator07(self):
        "Max length (length too short for extension...)"
        dir_path = self.dir_path

        fcreator = FileCreator(dir_path, 'foobar.txt', generators=[DateFileNameSuffixGenerator], max_length=3)

        with self.assertRaises(FileCreator.Error):
            fcreator.create()
Пример #3
0
    def test_file_creator09(self):
        "Default 'generators' argument"
        dir_path = self.dir_path

        fcreator = FileCreator(dir_path, 'foobar.txt')
        path1 = fcreator.create()

        with self.assertNoException():
            path2 = fcreator.create()

        self.assertNotEqual(path1, path2)
Пример #4
0
    def test_file_creator01(self):
        "With 1 generator (IncrFileNameGenerator)"
        dir_path = self.dir_path

        name1 = 'foobar.txt'
        fcreator = FileCreator(dir_path, name1, generators=[IncrFileNameSuffixGenerator])
        path1 = fcreator.create()
        self.assertTrue(exists(dir_path))
        self.assertEqual([name1], listdir(dir_path))
        self.assertEqual(join(dir_path, name1), path1)

        path2 = fcreator.create()
        name2 = 'foobar_1.txt'
        self.assertEqual({name1, name2}, set(listdir(dir_path)))
        self.assertEqual(join(dir_path, name2), path2)
Пример #5
0
    def test_create(self):
        "Auto-fill title if empty."
        from creme.creme_core.utils.file_handling import FileCreator

        filename = 'DocTestCreate001.txt'
        final_path = FileCreator(
            dir_path=join(settings.MEDIA_ROOT, 'upload', 'documents'),
            name=filename,
            max_length=Document._meta.get_field('filedata').max_length,
        ).create()

        user = self.create_user()
        folder = Folder.objects.all()[0]

        title = 'Test doc'
        doc1 = Document.objects.create(
            user=user,
            title=title,
            linked_folder=folder,
            filedata=final_path,
        )
        self.assertEqual(title, doc1.title)

        doc2 = Document.objects.create(
            user=user,
            linked_folder=folder,
            filedata=final_path,
        )
        self.assertEqual(filename, doc2.title)
Пример #6
0
def _create_file(name):
    rel_media_dir_path = join('upload', 'creme_core-tests', 'models')
    final_path = FileCreator(join(settings.MEDIA_ROOT, rel_media_dir_path),
                             name).create()

    with open(final_path, 'w') as f:
        f.write('I am the content')

    return join(rel_media_dir_path, basename(final_path))
Пример #7
0
    def _create_file_for_tempfile(self, name):
        rel_media_dir_path = join('upload', 'creme_core-tests')
        abs_path = FileCreator(
            dir_path=join(settings.MEDIA_ROOT, rel_media_dir_path),
            name=name,
        ).create()

        with open(abs_path, 'w') as f:
            f.write('I am the content')

        return abs_path, join(rel_media_dir_path, basename(abs_path))
Пример #8
0
    def test_file_creator02(self):
        "With 1 generator (DateFileNameGenerator)."
        dir_path = self.dir_path

        name1 = 'stuff.txt'
        fcreator = FileCreator(
            dir_path, name1, generators=[DateFileNameSuffixGenerator],
        )
        fcreator.create()
        self.assertEqual([name1], listdir(dir_path))

        fcreator.create()
        name2 = 'stuff_{}.txt'.format(date.today().strftime('%d%m%Y'))
        self.assertSetEqual({name1, name2}, {*listdir(dir_path)})

        with self.assertRaises(FileCreator.Error):
            fcreator.create()
Пример #9
0
    def test_file_creator06(self):
        "Max length (suffix is too long even alone)"
        dir_path = self.dir_path

        name = 'foobar.txt'  # len == 10
        fcreator = FileCreator(dir_path, name, generators=[DateFileNameSuffixGenerator], max_length=12)
        fcreator.create()

        with self.assertRaises(FileCreator.Error):
            fcreator.create()
Пример #10
0
    def test_file_creator02(self):
        "With 1 generator (DateFileNameGenerator)"
        dir_path = self.dir_path

        name1 = 'stuff.txt'
        fcreator = FileCreator(dir_path, name1,
                               generators=[DateFileNameSuffixGenerator],
                              )
        fcreator.create()
        self.assertEqual([name1], listdir(dir_path))

        fcreator.create()
        date_str = date.today().strftime('%d%m%Y')
        name2 = 'stuff_%s.txt' % date_str
        self.assertEqual({name1, name2}, set(listdir(dir_path)))

        with self.assertRaises(FileCreator.Error):
            fcreator.create()
Пример #11
0
    def test_file_creator04(self):
        "Max trials"
        dir_path = self.dir_path

        name1 = 'foobar.txt'
        fcreator = FileCreator(dir_path, name1, generators=[IncrFileNameSuffixGenerator], max_trials=2)
        fcreator.create()
        fcreator.create()

        with self.assertRaises(FileCreator.Error):
            fcreator.create()
Пример #12
0
    def test_file_creator05(self):
        "Max length"
        dir_path = self.dir_path

        name = 'foobar.txt'  # len == 10
        fcreator = FileCreator(dir_path, name, generators=[DateFileNameSuffixGenerator], max_length=15)
        fcreator.create()

        fcreator.create()
        self.assertEqual({name,
                          'fo_{}.txt'.format(date.today().strftime('%d%m%Y'))
                         },
                         set(listdir(dir_path))
                        )
Пример #13
0
    def test_file_creator03(self):
        "2 generators"
        dir_path = self.dir_path

        name1 = 'stuff.txt'
        fcreator = FileCreator(dir_path, name1,
                               generators=(DateFileNameSuffixGenerator,
                                           IncrFileNameSuffixGenerator,
                                          ),
                              )

        fcreator.create()
        self.assertEqual([name1], listdir(dir_path))

        fcreator.create()
        date_str = date.today().strftime('%d%m%Y')
        name2 = 'stuff_%s.txt' % date_str
        self.assertEqual({name1, name2}, set(listdir(dir_path)))

        fcreator.create()
        name3 = 'stuff_%s_1.txt' % date_str
        self.assertEqual({name1, name2, name3}, set(listdir(dir_path)))
Пример #14
0
    def export(self, entity, user):
        html_template = get_template(self.html_template_path)
        css_template = get_template(self.css_template_path)
        context = self.get_context_data(object=entity)

        with override(language=self.flavour.language):
            html_content = html_template.render(context)
            css_content = css_template.render(context)

        # NB: before creating file to raise error as soon a possible
        #     & avoid junk files.
        html = HTML(string=html_content)
        css = CSS(string=css_content)

        basename = secure_filename(
            f'{entity._meta.verbose_name}_{entity.id}.pdf')
        final_path = FileCreator(
            dir_path=path.join(settings.MEDIA_ROOT, 'upload', 'billing'),
            name=basename,
        ).create()

        # NB: we create the FileRef instance as soon as possible to get the
        #     smallest duration when a crash causes a file which have to be
        #     removed by hand (not cleaned by the Cleaner job).
        file_ref = FileRef.objects.create(
            user=user,
            filedata=f'upload/billing/{path.basename(final_path)}',
            basename=basename,
        )

        # TODO ?
        # from weasyprint.fonts import FontConfiguration
        # font_config = FontConfiguration()
        html.write_pdf(
            final_path,
            stylesheets=[css],
            # TODO: ???
            # font_config=font_config
        )

        return file_ref
Пример #15
0
    def export(self, entity, user):
        writer = self.get_writer(entity, user)

        basename = secure_filename(
            f'{entity._meta.verbose_name}_{entity.id}.xls')
        final_path = FileCreator(
            dir_path=path.join(settings.MEDIA_ROOT, 'upload', 'billing'),
            name=basename,
        ).create()

        # NB: we create the FileRef instance as soon as possible to get the
        #     smallest duration when a crash causes a file which have to be
        #     removed by hand (not cleaned by the Cleaner job).
        file_ref = FileRef.objects.create(
            user=user,
            filedata='upload/billing/' + path.basename(final_path),
            basename=basename,
        )

        writer.save(final_path)

        return file_ref
Пример #16
0
    def generate_pdf(self, *, content, dir_path, basename):
        latex_file_path = path.join(dir_path, f'{basename}.tex')

        # NB: we precise the encoding or it oddly crashes on some systems...
        with open(latex_file_path, 'w', encoding='utf-8') as f:
            f.write(smart_str(content))

        # NB: return code seems always 1 even when there is no error...
        subprocess.call([
            'pdflatex',
            '-interaction=batchmode',
            '-output-directory',
            dir_path,
            latex_file_path,
        ])

        pdf_basename = f'{basename}.pdf'
        temp_pdf_file_path = path.join(dir_path, pdf_basename)

        if not path.exists(temp_pdf_file_path):
            logger.critical(
                'It seems the PDF generation has failed. '
                'The temporary directory has not been removed, '
                'so you can inspect the *.log file in "%s"',
                dir_path,
            )
            # TODO: use a better exception class ?
            raise ConflictError(
                _('The generation of the PDF file has failed ; '
                  'please contact your administrator.'))

        final_path = FileCreator(
            dir_path=path.join(settings.MEDIA_ROOT, 'upload', 'billing'),
            name=pdf_basename,
        ).create()
        copy(temp_pdf_file_path, final_path)

        return final_path, pdf_basename
Пример #17
0
    def create_uploaded_file(*,
                             file_name: str,
                             dir_name: str,
                             content: Union[str,
                                            List[str]] = 'I am the content'):
        from os import path as os_path
        from shutil import copy

        from creme.creme_core.utils.file_handling import FileCreator

        rel_media_dir_path = os_path.join('upload', 'creme_core-tests',
                                          dir_name)
        final_path = FileCreator(
            os_path.join(settings.MEDIA_ROOT, rel_media_dir_path),
            file_name,
        ).create()

        if isinstance(content, list):
            copy(os_path.join(*content), final_path)
        elif isinstance(content, str):
            with open(final_path, 'w') as f:
                f.write(content)

        return os_path.join(rel_media_dir_path, os_path.basename(final_path))
Пример #18
0
def export_as_pdf(request, base_id):
    entity = get_object_or_404(CremeEntity, pk=base_id).get_real_entity()

    has_perm = request.user.has_perm_to_view_or_die
    has_perm(entity)

    template_path = TEMPLATE_PATHS.get(entity.__class__)
    if template_path is None:
        raise ConflictError('This type of entity cannot be exported as pdf')

    source = entity.get_source().get_real_entity()
    has_perm(source)

    target = entity.get_target().get_real_entity()
    has_perm(target)

    document_name = str(entity._meta.verbose_name)

    template = loader.get_template(template_path)
    context = {
        'plines': entity.get_lines(billing.get_product_line_model()),
        'slines': entity.get_lines(billing.get_service_line_model()),
        'source': source,
        'target': target,
        'object': entity,
        'document_name': document_name,
    }

    basename = secure_filename('{}_{}'.format(document_name, entity.id))
    tmp_dir_path = mkdtemp(prefix='creme_billing_latex')
    latex_file_path = path.join(tmp_dir_path, '{}.tex'.format(basename))

    # NB: we precise the encoding or it oddly crashes on some systems...
    with open(latex_file_path, 'w', encoding='utf-8') as f:
        f.write(smart_str(template.render(context)))

    # NB: return code seems always 1 even when there is no error...
    subprocess.call([
        'pdflatex',
        '-interaction=batchmode',
        '-output-directory',
        tmp_dir_path,
        latex_file_path,
    ])

    pdf_basename = '{}.pdf'.format(basename)
    temp_pdf_file_path = path.join(tmp_dir_path, pdf_basename)

    if not path.exists(temp_pdf_file_path):
        logger.critical(
            'It seems the PDF generation has failed. '
            'The temporary directory has not been removed, '
            'so you can inspect the *.log file in "%s"', tmp_dir_path)
        # TODO: use a better exception class ?
        raise ConflictError(
            _('The generation of the PDF file has failed ; please contact your administrator.'
              ))

    final_path = FileCreator(
        dir_path=path.join(settings.MEDIA_ROOT, 'upload', 'billing'),
        name=pdf_basename,
    ).create()
    copy(temp_pdf_file_path, final_path)

    rmtree(tmp_dir_path)

    fileref = FileRef.objects.create(  # user=request.user, TODO
        filedata='upload/billing/' + path.basename(final_path),
        basename=pdf_basename,
    )

    return HttpResponseRedirect(
        reverse(
            'creme_core__dl_file',
            args=(fileref.filedata, ),
        ))
Пример #19
0
    def generate_png(self, user):
        from os.path import join

        import pygraphviz as pgv

        # NB: to work with utf8 label in node: all node must be added explicitly with
        #     unicode label, and when edges are a created, nodes identified by their
        #     labels encoded as string

        graph = pgv.AGraph(directed=True)

        # NB: "self.roots.all()" causes a strange additional query (retrieving of the base CremeEntity !)....
        has_perm_to_view = user.has_perm_to_view
        roots = [
            root for root in RootNode.objects.filter(
                graph=self.id).select_related('entity')
            if not root.entity.is_deleted and has_perm_to_view(root.entity)
        ]

        add_node = graph.add_node
        add_edge = graph.add_edge

        # TODO: entity cache ? regroups relations by type ? ...

        CremeEntity.populate_real_entities([root.entity for root in roots
                                            ])  #small optimisation

        for root in roots:
            add_node(str(root.entity), shape='box')
            # add_node('filled box',    shape='box', style='filled', color='#FF00FF')
            # add_node('filled box v2', shape='box', style='filled', fillcolor='#FF0000', color='#0000FF', penwidth='2.0') #default pensize="1.0"

        orbital_nodes = {}  #cache

        for root in roots:
            subject = root.entity
            str_subject = str(subject)
            relations   = subject.relations.filter(type__in=root.relation_types.all())\
                                           .select_related('object_entity', 'type')

            Relation.populate_real_object_entities(
                relations)  # Small optimisation

            for relation in relations:
                object_ = relation.object_entity
                if not user.has_perm_to_view(object_):
                    continue

                uni_object = str(object_)
                str_object = uni_object

                orbital_node = orbital_nodes.get(object_.id)
                if not orbital_node:
                    add_node(uni_object)
                    orbital_nodes[object_.id] = str_object

                add_edge(str_subject,
                         str_object,
                         label=str(relation.type.predicate))
                # add_edge('b', 'd', color='#FF0000', fontcolor='#00FF00', label='foobar', style='dashed')

        orbital_rtypes = self.orbital_relation_types.all()

        if orbital_rtypes:
            orbital_ids = orbital_nodes.keys()

            for relation in Relation.objects.filter(
                    subject_entity__in=orbital_ids,
                    object_entity__in=orbital_ids,
                    type__in=orbital_rtypes).select_related('type'):
                add_edge(orbital_nodes[relation.subject_entity_id],
                         orbital_nodes[relation.object_entity_id],
                         label=str(relation.type.predicate),
                         style='dashed')

        # print graph.string()

        graph.layout(prog='dot')  # Algo: neato dot twopi circo fdp nop

        img_format = 'png'  # Format: pdf svg
        img_basename = 'graph_{}.{}'.format(self.id, img_format)

        try:
            path = FileCreator(join(settings.MEDIA_ROOT, 'upload', 'graphs'),
                               img_basename).create()
        except FileCreator.Error as e:
            raise self.GraphException(e) from e

        try:
            # graph.draw(join(dir_path, filename), format='png')  # Format: pdf svg
            graph.draw(path, format=img_format)  # Format: pdf svg
        except IOError as e:
            delete_file(path)

            raise self.GraphException(str(e)) from e

        fileref = FileRef.objects.create(  # user=request.user, TODO
            filedata='upload/graphs/' + basename(path),
            basename=img_basename,
        )

        return HttpResponseRedirect(
            reverse('creme_core__dl_file', args=(fileref.filedata, )))