Django Doc Convert to HTML - django

I am looking for a HTML converter which allows me to convert .doc to HTML in my Django project.
In my project, .docx files can be converted but not .doc files.
.docx file processing was done as follows.
view.py:
#csrf_exempt
#api_view(['POST'])
def fileload(request):
if request.method == 'POST' and request.FILES['file']:
urls = settings.MEDIA_ROOT+'fileload/'
fs = FileSystemStorage(location=urls, base_url=urls)
filename = fs.save(file.name, file)
filepath = urls + file.name
ext = os.path.splitext(filepath)[1]
print(ext)
html=None
code = '0'
if ext == '.docx':
html = get_docx_html(filepath)
code = '1'
fs.delete(file.name)
data = {
'code': code,
'html': html
}
response = JsonResponse(data)
return response
def get_docx_html(path):
with open(path, "rb") as docx_file:
result = mammoth.convert_to_html(docx_file)
html = result.value
messages = result.messages
return html
In the same way, doc files are not converted.
I'd like to have the .doc file converted.
Any idea of approach that can be recommended or sample code? Thanks a lot.

Related

Cannot read csv files uploaded using pandas in Djnago

I have the following view defined in my Django views:-
def csv_file_upload(request):
if request.method == "POST" and request.FILES['file_upload']:
registry = request.POST.get('reg_select').lower()
csv_file = request.FILES['file_upload']
data = pd.read_csv(csv_file, delimiter="\|\|")
print(data.head())
return render(request, "csv_file_upload.html", {})
But the pd.read_csv part is giving me this error:-
cannot use a string pattern on a bytes-like object
The sample csv file that I have is like this:
Col_A||Col_B||Col_C
A0||B0||C0
A1||B1||C1
The same file I can read using pd.read_csv() without using Django and do no get this error.
Why is this error being caused when using Django?
Files are uploaded as bytes and not as string ( expected )
You should read file and decode its content to string
csv_bytes = request.FILES['file_upload'].read()
csv_text = csv_bytes.decode('utf-8')
string_buffer = io.StringIO(csv_text)
data = pd.read_csv(string_buffer , delimiter="\|\|")

In django, how can i upload file via url?

Hi i'm making my own webserver using django.
i just want to upload local file to django server.
i google every method but i can't get answer.
every method using form or html but i don't want to using form and html
example : from www.localfolder/example.txt to /media/examplefolder.
i don't know how to do.. any help?
this is my code.
#csrf_exempt
def download_file(request, file):
fl_path = 'media/'
filename = str(file)
fl = open(fl_path, 'r')
mime_type, _ = mimetypes.guess_type(fl_path)
response = HttpResponse(fl, content_type=mime_type)
response['Content-Disposition'] = "attachment; filename = %s" % filename
return response
What did you search for when you googled? These were the top 2 results for Django files
https://docs.djangoproject.com/en/3.0/topics/http/file-uploads/
https://docs.djangoproject.com/en/3.0/topics/files/
Seems to have everything you are looking for.

Generate multiple PDFs and zip them for download, all in a single view

I am using xhtml2pdf to generate PDFs in my Django View. The idea is to loop over all the instances that are there in the query, then for each instance create a PDF, then add all the generated PDFs to one zip File for download. The xtml2pdf logic is working okay but the looping logic is what gives me headache.
So this is my function so far:
def bulk_cover_letter(request, ward_id, school_cat_id, cheque_number):
school_type = SchoolType.objects.get(id=school_cat_id)
schools_in_school_type = Applicant.objects.filter(
school_type=school_type, ward_id=ward_id, award_status='awarded'
).order_by().values_list('school_name', flat=True).distinct()
for school in schools_in_school_type:
beneficiaries = Applicant.objects.filter(school_type=school_type, ward_id=ward_id, award_status='awarded', school_name=school)
total_amount_to_beneficiaries = Applicant.objects.filter(school_type=school_type, ward_id=ward_id, award_status='awarded', school_name=school).aggregate(total=Sum('school_type__amount_allocated'))
context = {
'school_name' : school,
'beneficiaries' : beneficiaries,
'total_amount_to_beneficiaries' : total_amount_to_beneficiaries,
'title' : school + ' Disbursement Details',
'cheque_number': cheque_number
}
response = HttpResponse('<title>Cover Letter</title>', content_type='application/pdf')
filename = "%s.pdf" %(cheque_number)
content = "inline; filename=%s" %(filename)
response['Content-Disposition'] = content
template = get_template('cover_letter.html')
html = template.render(context)
result = io.BytesIO()
pdf = pisa.CreatePDF(
html, dest=response, link_callback=link_callback)
if not pdf.error:
# At this point I can generate a single PDF.
# But no idea on what to do next.
# The zipping logic should follow here after looping all the instances - (schools)
From that Point I have no idea on what to do next. Any help will be highly appreciated.
Try this:
Utils.py
def render_to_pdf(template_src, context_dict={}):
template = get_template(template_src)
html = template.render(context_dict)
buffer = BytesIO()
p = pisa.pisaDocument(BytesIO(html.encode("ISO-8859-1")), buffer)
pdf = buffer.getvalue()
buffer.close()
if not p.err:
return pdf#HttpResponse(result.getvalue(), content_type='application/pdf')
return None
def generate_zip(files):
mem_zip = BytesIO()
with zipfile.ZipFile(mem_zip, mode="w",compression=zipfile.ZIP_DEFLATED) as zf:
for f in files:
zf.writestr(f[0], f[1])
return mem_zip.getvalue()
Views.py
def generate_attendance_pdf(modeladmin, request, queryset):
template_path = 'student/pdf_template.html'
files = []
for q in queryset:
context = {
'firstname': q.firstname,
'lastname': q.lastname,
'p_firstname': q.bceID.firstname
}
pdf = render_to_pdf(template_path, context)
files.append((q.firstname + ".pdf", pdf))
full_zip_in_memory = generate_zip(files)
response = HttpResponse(full_zip_in_memory, content_type='application/force-download')
response['Content-Disposition'] = 'attachment; filename="{}"'.format('attendnace.zip')
return response
Obviously, you have to modify the context/names to what you need.
Credit to -> Neil Grogan https://www.neilgrogan.com/py-bin-zip/
If you need to generate several PDF files and send them as a response in a zip file then you can store the reports in memory and set it as dest when you call pisa.CreatePDF. Then have a list of reports in memory, zip them, and send as a Django response specifying another content type.
For example:
reports = tempfile.TemporaryDirectory()
report_files = {}
for school in schools_in_school_type:
# ... same code that renerates `html`
mem_fp = BytesIO()
pisa.CreatePDF(html, dest=mem_fp)
report_files[filename] = mem_fp
mem_zip = BytesIO()
with zipfile.ZipFile(mem_zip, mode="w") as zf:
for filename, content in report_files.items():
zf.write(filename, content)
response = HttpResponse(mem_zip, content_type='application/force-download')
response['Content-Disposition'] = 'attachment; filename="{}"'.format('cover_letters.zip')
This still generates an error of [Errno 2] No such file or directory: 'cheque_number.pdf'.

Create download link file in django

I created a file in project, generation pdf from html. For this i have this method:
def generation_html_to_pdf(self):
path_pdf = None
with NamedTemporaryFile(delete=False, suffix=".pdf", dir='pdf_files') as tf:
path_pdf = tf.name
pdfkit.from_file('templates/first_page.html', tf.name)
return path_pdf
Then, in pdf_files folder i have the pdf file. I want to get a download link for this file:
my view
path_to_pdf = generation_html_to_pdf()
download_link = 'http://' + request.get_host() + path_to_pdf
json_inf_pdf = {'download_link': download_link}
return JsonResponse(json_inf_pdf, status=200)
i have json like this:
{"download_link": "http://127.0.0.1:8000/home/alex/projects/test_project/pdf_files/tmpe0nqbn01.pdf"}"
when i click in this link i have error:
Page not found (404)
You need to create download view and url. Function like this to create link:
def download_link(request):
''' Create download link '''
download_link = 'http://{}/{}'.format(request.get_host(), 'download/my_filename')
json_inf_pdf = {'download_link': download_link}
return JsonResponse(json_inf_pdf, status=200)
and to download pdf:
def download_file(request, my_filename):
''' Download file '''
# Open template
from django.conf import settings
template_url = os.path.join(settings.BASE_DIR, 'templates', 'first_page.html')
template_open = open(template_url, 'r')
# Read template
from django import template
t = template.Template(template_open.read())
c = template.Context({})
# Create pdf
pdf = pdfkit.from_string(t.render(c))
# Create and return response with created pdf
response = HttpResponse(pdf)
response['Content-Type'] = 'application/pdf'
response['Content-disposition'] = 'attachment ; filename = {}'.format(my_filename)
return response
and url:
path('/download/<str:my_filename>', views.download_file, name="download_pdf')
I can't guarantee that this will work in your case without modification, since I can't tell which html-to-pdf library you're using and without seeing your other code. It's just a basic implementation idea.

how to stream file to client in django

I want to know how can I stream data to client using django.
The Goal
The user submits a form, the form data is passed to a web service which returns a string. The string is tarballed (tar.gz) and the tarball is sent back to the user.
I don't know what's the way. I searched and I found this, but I just have a string and I don't know if it is the thing I want, I don't know what to use in place of filename = __file__ , because I don't have file - just a string. If I create a new file for each user, this won't be a good way. so please help me. (sorry I'm new in web programming).
EDIT:
$('#sendButton').click(function(e) {
e.preventDefault();
var temp = $("#mainForm").serialize();
$.ajax({
type: "POST",
data: temp,
url: 'main/',
success: function(data) {
$("#mainDiv").html(data.form);
????
}
});
});
I want to use ajax, so what should i do in success of ajac function and in return of view. really thanks.
my view.py:
def idsBackup(request):
if request.is_ajax():
if request.method == 'POST':
result = ""
form = mainForm(request.POST)
if form.is_valid():
form = mainForm(request.POST)
//do form processing and call web service
string_to_return = webserviceString._result
???
to_json = {}
to_json['form'] = render_to_string('main.html', {'form': form}, context_instance=RequestContext(request))
to_json['result'] = result
???return HttpResponse(json.dumps(to_json), mimetype='application/json')
else:
form = mainForm()
return render_to_response('main.html', RequestContext(request, {'form':form}))
else:
return render_to_response("ajax.html", {}, context_instance=RequestContext(request))
You can create a django file instance of ContentFile using a string content instead of actual file and then send it as a response.
Sample code:
from django.core.files.base import ContentFile
def your_view(request):
#your view code
string_to_return = get_the_string() # get the string you want to return.
file_to_send = ContentFile(string_to_return)
response = HttpResponse(file_to_send,'application/x-gzip')
response['Content-Length'] = file_to_send.size
response['Content-Disposition'] = 'attachment; filename="somefile.tar.gz"'
return response
You can modify send_zipfile from the snippet to suit your needs. Just use StringIO to turn your string into a file-like object which can be passed to FileWrapper.
import StringIO, tempfile, zipfile
...
# get your string from the webservice
string = webservice.get_response()
...
temp = tempfile.TemporaryFile()
# this creates a zip, not a tarball
archive = zipfile.ZipFile(temp, 'w', zipfile.ZIP_DEFLATED)
# this converts your string into a filelike object
fstring = StringIO.StringIO(string)
# writes the "file" to the zip archive
archive.write(fstring)
archive.close()
wrapper = FileWrapper(temp)
response = HttpResponse(wrapper, content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename=test.zip'
response['Content-Length'] = temp.tell()
temp.seek(0)
return response