export doc to pdf via HttpResponse
This commit is contained in:
parent
aa7e400b6f
commit
cf8ee787f7
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
|
@ -5,8 +5,10 @@ This module defines the structure and properties of documents and versions.
|
|||
from django.db import models
|
||||
from django.contrib.auth.models import Group, User
|
||||
|
||||
from markdown import Markdown
|
||||
from closuretree.models import ClosureModel
|
||||
import reversion
|
||||
import pdfkit
|
||||
|
||||
from process.models import Approval
|
||||
from process.exceptions import ActorException
|
||||
|
@ -142,6 +144,29 @@ class Document(models.Model):
|
|||
# todo : should create a default version based on the document type template.
|
||||
super().save()
|
||||
|
||||
def to_pdf(self):
|
||||
x = '# Tables des matières \n [TOC]\n'
|
||||
|
||||
for section in self.sections.all():
|
||||
x += '# ' + section.title
|
||||
x += '\n'
|
||||
x += section.content
|
||||
x += '\n'
|
||||
md = Markdown(extensions=['markdown.extensions.toc'])
|
||||
html = md.convert(x)
|
||||
|
||||
options = {
|
||||
'page-size': 'Letter',
|
||||
'encoding': "UTF-8",
|
||||
'custom-header': [
|
||||
('Accept-Encoding', 'gzip')
|
||||
],
|
||||
'no-outline': None,
|
||||
'footer-right': '[page]/[topage]'
|
||||
}
|
||||
|
||||
return pdfkit.from_string(html, False, options=options)
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
|
|
12
dms/urls.py
12
dms/urls.py
|
@ -1,11 +1,21 @@
|
|||
from django.conf.urls import url
|
||||
|
||||
from dms.views import document_details, filter_documents, node_documents, site_documents, home, standard_documents, keyword_documents
|
||||
from dms.views import (
|
||||
document_details,
|
||||
filter_documents,
|
||||
node_documents,
|
||||
site_documents,
|
||||
home,
|
||||
standard_documents,
|
||||
keyword_documents,
|
||||
document_to_pdf
|
||||
)
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'std/(?P<pk>\d+)', standard_documents, name='standard_documents'),
|
||||
url(r'kw/(?P<pk>\d+)', keyword_documents, name='kw_documents'),
|
||||
url(r'd/(?P<pk>\d+)/to_pdf', document_to_pdf, name='document_to_pdf'),
|
||||
url(r'd/(?P<pk>\d+)', document_details, name='document_details'),
|
||||
url(r'node/(?P<pk>\d+)', node_documents, name='node_documents'),
|
||||
url(r'site/(?P<pk>\d+)', site_documents, name='site_documents'),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from django.shortcuts import render
|
||||
from django.http import HttpResponse
|
||||
from .models import Document, Version, Node, Site
|
||||
from .filters import VersionFilter
|
||||
|
||||
|
@ -18,6 +19,14 @@ def document_details(request, pk):
|
|||
return render(request, 'dms/document_details.html', {'document': doc})
|
||||
|
||||
|
||||
def document_to_pdf(request, pk):
|
||||
doc = Document.objects.get(pk=pk)
|
||||
response = HttpResponse(doc.to_pdf(), content_type='application/pdf')
|
||||
response['Content-Disposition'] = 'attachment; filename="{}.pdf"'.format(doc.title)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def filter_documents(request):
|
||||
f = VersionFilter(request.GET, queryset=Version.objects.select_related('document').all())
|
||||
return render(request, 'dms/filters.html', {'filter': f})
|
||||
|
|
|
@ -63,7 +63,7 @@ TASK_STATUS = (
|
|||
|
||||
|
||||
class Task(models.Model):
|
||||
assigned_to = models.ForeignKey(User)
|
||||
assigned_to = models.ForeignKey(User, related_name='tasks')
|
||||
process = models.ForeignKey(Process, related_name='tasks')
|
||||
status = models.IntegerField(choices=TASK_STATUS)
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from django.shortcuts import render
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from .models import Process, Task
|
||||
|
||||
|
@ -9,5 +10,6 @@ def process_details(request, pk):
|
|||
|
||||
|
||||
def user_tasks(request):
|
||||
tasks = Task.objects.filter(user=request.user)
|
||||
return render(request, 'process/user_tasks.html', {'tasks':tasks})
|
||||
admin = User.objects.first()
|
||||
tasks = Task.objects.filter(user=admin)
|
||||
return render(request, 'process/user_tasks.html', {'tasks': tasks})
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<link rel="stylesheet" type="text/css" href="{% static 'semantic/components/icon.css' %}">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'semantic/components/card.css' %}">
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'semantic/components/progress.css' %}">
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css">
|
||||
{% block stylesheet %}{% endblock %}
|
||||
<style type="text/css">
|
||||
body {
|
||||
|
@ -29,7 +29,7 @@
|
|||
.ui.menu .item img.logo {
|
||||
margin-right: 1.5em;
|
||||
}
|
||||
.main.container {
|
||||
.main {
|
||||
margin-top: 7em;
|
||||
}
|
||||
.wireframe {
|
||||
|
@ -54,12 +54,14 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui two column stackable grid">
|
||||
<div class="three wide column">
|
||||
{% block "content_navigation" %}{% endblock %}
|
||||
</div>
|
||||
<div class="ten wide colum">
|
||||
{% block "content" %}{% endblock %}
|
||||
<div class="main">
|
||||
<div class="ui two column stackable grid">
|
||||
<div class="three wide column">
|
||||
{% block "content_navigation" %}{% endblock %}
|
||||
</div>
|
||||
<div class="ten wide colum">
|
||||
{% block "content" %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -19,65 +19,54 @@
|
|||
<div class="content">
|
||||
<a class="header">{{ document.title }}</a>
|
||||
|
||||
<div class="meta">
|
||||
<span class="date">{{ document.created_at }}</span>
|
||||
</div>
|
||||
<div class="description">
|
||||
{{ document.overview }}
|
||||
</div>
|
||||
<div class="meta">
|
||||
<span class="date">{{ document.created_at }}</span>
|
||||
</div>
|
||||
<div class="description">
|
||||
{{ document.overview }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="extra content">
|
||||
Type : {{ document.type }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if document.last_published_version %}
|
||||
<h3>Last published version: {{ document.last_published_version }}</h3>
|
||||
<ul>
|
||||
<li>Authors: {% for author in document.last_published_version.authors.all %}{{ author }}{% endfor %}</li>
|
||||
<li>Keywords: {% for keyword in document.last_published_version.keywords.all %}<a href="{% url 'kw_documents' keyword.pk %}">{{keyword}}</a>{% endfor %}</li>
|
||||
<li>Audiences: {% for audience in document.last_published_version.audiences.all %}{{ audience }}{% endfor %}</li>
|
||||
<li>Nodes: {% for node in document.last_published_version.nodes.all %}<a href="{% url 'node_documents' node.pk %}">{{ node }}</a>{% endfor %}</li>
|
||||
<li>Sites: {% for site in document.last_published_version.sites.all %}<a href="{% url 'site_documents' site.pk %}">{{ site }}</a>{% endfor %}</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if document.last_working_version %}
|
||||
<h3>Last working version: {{ document.last_working_version }}</h3>
|
||||
<h4>Properties</h4>
|
||||
<ul>
|
||||
<li>Authors: {% for author in document.last_working_version.authors.all %}{{ author }}{% endfor %}</li>
|
||||
<li>Keywords: {% for keyword in document.last_working_version.keywords.all %}<a href="{% url 'kw_documents' keyword.pk %}">{{keyword}}</a>{% endfor %}</li>
|
||||
<li>Audiences: {% for audience in document.last_working_version.audiences.all %}{{ audience }}{% endfor %}</li>
|
||||
<li>Nodes: {% for node in document.last_working_version.nodes.all %}<a href="{% url 'node_documents' node.pk %}">{{ node }}</a>{% endfor %}</li>
|
||||
<li>Sites: {% for site in document.last_working_version.sites.all %}<a href="{% url 'site_documents' site.pk %}">{{ site }}</a>{% endfor %}</li>
|
||||
</ul>
|
||||
<h4>Processes</h4>
|
||||
<ul>
|
||||
<div class="ui card">
|
||||
<div class="content">
|
||||
<div class="header">
|
||||
Rédaction
|
||||
</div>
|
||||
<div class="description">
|
||||
<a href="{% url 'document_to_pdf' document.pk %}">Convertir en PDF et créer une nouvelle version</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% for process in document.last_working_version.processes.all %}
|
||||
<li>{{ process }}
|
||||
<div class="ui card">
|
||||
<div class="content">
|
||||
<div class="header">
|
||||
{{ process }}
|
||||
</div>
|
||||
<div class="ui progress">
|
||||
<div class="bar" data-percent="{{ process.percentage_of_completion }}">
|
||||
<div class="label">{{ process.percentage_of_completion }}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<div class="bar" data-percent="{{ process.percentage_of_completion }}">
|
||||
<div class="label">{{ process.percentage_of_completion }}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<h4>Rédaction</h4>
|
||||
<ul>
|
||||
<li><a href="{% url 'document_sections' document.pk %}">Rédaction inline</a></li>
|
||||
<li><a href="#">Convertir en PDF et créer une nouvelle version</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block "content" %}
|
||||
<div class="segment">
|
||||
{% for section in document.sections.all %}
|
||||
<h1>{{ section }}</h1>
|
||||
<h1>{{ section }}
|
||||
<a href="{% url 'edit_document_section' document.pk section.pk %}">
|
||||
<i class="edit icon"></i>
|
||||
</a>
|
||||
</h1>
|
||||
{{ section.get_message_as_markdown | safe }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
{% load document_edition %}
|
||||
{% extends "../base.html" %}
|
||||
|
||||
{% block "navigation" %}
|
||||
{% display_sections %}
|
||||
{% block "stylesheet" %}
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
|
||||
{% block "content_navigation" %}
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
|
||||
{% block "content" %}
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -1,13 +1,24 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block "content" %}
|
||||
<h2>Edit section {{ section }}</h2>
|
||||
<textarea>
|
||||
{% block "stylesheet" %}
|
||||
|
||||
</textarea>
|
||||
{% endblock %}
|
||||
|
||||
{% block "navigation_content" %}
|
||||
<i class="ui icon angle double left"></i>
|
||||
{% endblock %}
|
||||
|
||||
{% block "content" %}
|
||||
<h1><a href="{% url 'document_details' section.document.pk %}">{{ section.document.title }}</a></h1>
|
||||
<h2>{{ section.title }}</h2>
|
||||
<form method="POST" class="post-form">{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit" class="save btn btn-default">Save</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{% block javascript %}
|
||||
<script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script>
|
||||
<script>
|
||||
var simplemde = new SimpleMDE();
|
||||
</script>
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block "content" %}
|
||||
Meh
|
||||
|
||||
{% endblock %}
|
|
@ -1 +0,0 @@
|
|||
https://letchap.github.io/2014/03/06/creer-un-fichier-pdf-avec-python-et-reportlab/
|
|
@ -0,0 +1,10 @@
|
|||
from django import forms
|
||||
|
||||
from .models import Section
|
||||
|
||||
|
||||
class SectionForm(forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = Section
|
||||
fields = ('content',)
|
|
@ -22,27 +22,3 @@ class Section(models.Model):
|
|||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
|
||||
def to_pdf():
|
||||
x = '# Tables des matières \n [TOC]\n'
|
||||
|
||||
for section in Section.objects.all():
|
||||
x += '# ' + section.title
|
||||
x += '\n'
|
||||
x += section.content
|
||||
x += '\n'
|
||||
md = Markdown(extensions=['markdown.extensions.toc'])
|
||||
html = md.convert(x)
|
||||
|
||||
options = {
|
||||
'page-size': 'Letter',
|
||||
'encoding': "UTF-8",
|
||||
'custom-header': [
|
||||
('Accept-Encoding', 'gzip')
|
||||
],
|
||||
'no-outline': None,
|
||||
'footer-right': '[page]/[topage]'
|
||||
}
|
||||
|
||||
pdfkit.from_string(html, 'out.pdf', options=options)
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
from django.conf.urls import url
|
||||
|
||||
from .views import list_sections, edit_section
|
||||
from .views import edit_section
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'doc/(?P<document_id>\d+)/section/(?P<section_id>\d+)', edit_section, name='edit_document_section'),
|
||||
url(r'doc/(?P<document_id>\d+)', list_sections, name='document_sections'),
|
||||
]
|
||||
|
|
|
@ -1,18 +1,29 @@
|
|||
from django.shortcuts import render
|
||||
from django.shortcuts import render, redirect
|
||||
from .models import Section
|
||||
from .forms import SectionForm
|
||||
|
||||
|
||||
def home(request):
|
||||
return render(request, 'writer/home.html', {})
|
||||
|
||||
|
||||
def list_sections(request, document_id):
|
||||
sections = Section.objects.filter(document=document_id)
|
||||
|
||||
return render(request, 'writer/sections_list.html', {'document_id': document_id, 'sections': sections})
|
||||
|
||||
|
||||
def edit_section(request, document_id, section_id):
|
||||
section = Section.objects.get(document=document_id, pk=section_id)
|
||||
|
||||
return render(request, 'writer/edit_section.html', {'document_id': document_id, 'section': section})
|
||||
if request.method == "POST":
|
||||
form = SectionForm(request.POST, instance=section)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return redirect('document_details', pk=document_id)
|
||||
else:
|
||||
form = SectionForm(instance=section)
|
||||
|
||||
return render(
|
||||
request,
|
||||
'writer/edit_section.html',
|
||||
{
|
||||
'document_id': document_id,
|
||||
'section': section,
|
||||
'form': form
|
||||
}
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue