Create Button on existing model to download CSV data - csv

I have a function that generates a CSV report for survey.surveys to my employer's liking and I need a way to download that data. The issue I'm having is to get a button on the page to actually download the data, I've tried adding a controller but when I go to it, it says 404.
I'm using Odoo 13
Here's the controller I tried, but when i go to it, it returns a 404. Yes i checked my __init__.py for both my module and controllers folder
class MyExport(http.Controller):
#http.route(['/my_module/export/certs'], type='http', auth='user', methods=['GET'], website=True)
def csv_download(self, **kw):
csv = http.request.env['survey.survey'].generate_cert_report()
filename = 'Certification Report - {}.csv'.format(
datetime.now().strftime("%m/%d/%Y"))
headers = [
('Content-Type', 'application/octet-stream'),
('Content-Disposition', 'attachment; filename="%s"' % (filename))
]
return request.make_response(csv, headers=headers)

Related

Returning json from .csv asset in nuxt api

Using Nuxt 3, I am struggling to do something that appears simple: I would like to get a list of restaurants from an api served by nuxt/nitro in order to use it on the client side. My original file, is a .csv file stored under assets/: assets/list.csv.
Here is what I have in my component .vuefile:
//...
const { restaurants } = await useFetch('/api/restaurants')
//...
And the content of server/api/restaurants.js:
import csv from 'csvtojson'
export default defineEventHandler(async(event) => {
const data = await csv().fromFile('~/assets/list.csv')
return { data }
})
But I get an error "[500] File does not exist". I've tried many variants but always get an error here or there. Could you help me figure out the solution? Thanks.
Actually solved by realizing the following:
As the doc suggests, the assets/ directory is for assets that are processed by the bundler (Vite or Webpack). Nuxt won't serve files in the assets/ directory unless nuxt.config.ts is configured with the appropriate loader (e.g. a csv loader). Hence the 500 error.
Nuxt Content, on the other hand, is useful to automatically parse a .csv file located in the content/ directory:
In nuxt.config.ts:
modules: ["#nuxt/content"]
In the component .vue file, the following will expose the parsed csv in data.body:
const { data } = await useAsyncData("list", () => queryContent("/list").findOne())
The beauty of nuxt is that you don't need to import anything, it does it for you.

how to load data from a flask url and console log the data n react?

I want to load a json file that I get from a url generated in flask.
After d3.json(url, function) I'm trying to console log the json, but nothing happens and I dont know what's wrong. So maybe someone can help
This is basically my code:
Component where I want to display a graph (Display.js):
import React, { Component } from 'react';
import "./Display.css";
import * as d3 from "d3";
export default class Display extends Component {
componentWillReceiveProps() {
const url = "http://localhost:5000/company?company_name=" + this.props.inputDataFromParent //the url depends on the input the user made. InputDataFromParent is the passed value (from the parent) that the user typed in
d3.json(url, function (data) {
console.log(data)
})
}
when I type in an input (company name) that doesnt exist in the database I get an error: "Uncaught (in promise) SyntaxError: Unexpected token N in JSON at position 0"at (index):1
when I type in an input that does exist nothing happens in the console.
Here's my main.py:
import flask
from pandas import DataFrame
from models import company_search
from flask import request
from models import subsidiaries
app=flask.Flask("__main__")
#app.route("/company")
def result():
if request.method == 'GET':
company_name = request.args.get('company_name', None)
if company_name:
return subsidiaries(company_name)
return "No place information is given"
app.run(debug=True)
and this is models.py (neo4j is used as the database):
def subsidiaries(eingabe):
if regex_eingabe_kontrolle(eingabe):
namelistdf = graph.run("MATCH (c:Company)-[rel:Relation]->(d:Company) WHERE rel.relation_group='OWNERSHIP' AND rel.percent_share >= 50 AND c.company_name= $eingabe RETURN c, rel, d",eingabe=eingabe).to_data_frame()
if namelistdf.empty:
return "No company with this name exists"
namelistjson = namelistdf.to_json(orient="records",date_unit="s",default_handler=str)
return namelistjson
else:
return "Please enter a valid company name"
I get the data from a neo4j database.
It's not about to console log the data because I want to generate a graph from the data. The console log is only for testing if the data is right. But now it seems that the data isn't passed to d3.json(url, function (data) correctly
Your problem occurs in your main file when you return No place information is given. Since this is not in JSON format, JavaScript fails to parse it causing the error to be thrown. To fix this, you can change it to:
import json
#app.route("/company")
def result():
if request.method == 'GET':
company_name = request.args.get('company_name', None)
if company_name:
return subsidiaries(company_name)
return json.dumps("No place information is given")
If you do the same for No company with this name exists and Please enter a valid company name, you won't get anymore JSON deserialization errors. However, D3 may still throw errors because it does not know what to do with a string.
You may want to return HTTP status codes along with your error messages so you can control the error. To do this in Flask, you can return the text along with the status code. For example: return json.dumps("Error message"), 400 will return the JSON string Error message with the status code 400. Since d3.json makes an underlying call to the JavaScript fetch function, you should be able to access the status code by using data.status.

How to retrieve data from self-made restfull_api

I trying to retrieve the information from my API via Y/views.py from another app in the same project. I am receiving the following error ([WinError 10061]). Although, i am able to perform get/post/put via my json_main.js. Thanks to all who support me in this journey. Please read what is already working. And as additional question I would ask why it is not possible to retrieve the data directly via my model/sqlite db.
I already created the following:
X/Views + X/Template.html. X/Views renders information from the backend to the X/template.html. Within this template there is a JSON script(working) that performs a POST/GET/PUT to the API(working) on image click.
The function ultimately results in a new record in API/Bestellingen. The information stored via this JSON function (incl. token authentication; csrf) should now be retrieved in the views.py of Y/view. I already created an example dict. that is rendered to Y/template.html
I tried several JSON request methods (coreapi, urllib2, urllib3, requests), but keep receiving the error as mentioned before. As already stated: JSON.js script does work. Doing the same via POSTMAN also works.
Since i am performing the same via .js and postman, I am quite sure that the variables (token, header and the request) should be ok.
I will show some short snippets of already working code. Herafter i will show the code that doesn't seem to work.
Information from X/views.py -> X/template.html
return render(request, 'smaakjes/smaakjes.html', {'Drank': super_dict})
X/Template.html (see onclick ="")
{% for key, value_list in Drank.items %}
<img onclick="PostImageDetails(this)" style="margin: 0 auto;" src="{{ value }}" id="{{ value }}">
JSON.js (works), sends information to http:127:0:0:0:8000/api/bestellingen. I can see the stored information via the API view.
xmlhttp.send(JSON.stringify({'url':imageSrc, 'username': imageId}))
Y/views.py -> renders information to Y/template.html(works)
def BestellingenDashboard(request):
Data = {'iets': '1'}
return render(request, 'homepage.html', {'bestellingen' : Data})
Once information has been stored in the API/bestellingen, I would like to retrieve the whole json dict. via python Y/Views.py and store it in the above 'Data'(that's ofc easy :)). Does somebody know what i am doing wrong? Why is postman working? Am i Missing a header or something? In my opinion, retrieving data from your own API should be very easy :D
from django.http import HttpResponse
from django.shortcuts import render
from api.models import Bestellingen
import json
import secrets
import requests
URL = "http://127.0.0.1:8000/api/bestellingen/"
data_json = json.dumps(data)
payload = {'json_payload': data_json}
r = requests.get(url=URL, headers={'Content-Type': 'application/json', 'token' : secrets.token_hex(40)}, json=payload)
a = r.json()
print(a)
def BestellingenDashboard(request):
Data = {'iets': '1'}
return render(request, 'homepage.html', {'bestellingen' : Data})
As you can read, most is working (api, endpoints, apiviews, rendering info from X-X.html,X.html->API. I now want to get the information in Y.views, so that i can use this information in Y/template.html

HTML File link - force download always

I have a Django view that renders a list of uploaded files, and the user can click on them to begin the download.
When the project was deployed, we found there's one file that browsers open instead of download it. It seems related to the .dxf extension.
This is how the link is created:
...
As a result:
http://localhost:8003/media/folder/whatever.dxf
So, why the same browser behaves differently? if I run it on localhost, then it downloads the file. But accessing the real server, it'd open it. Can I prevent the server to open them in browsers?
You can try adding new Django view that will handle download.
urls.py
from django.conf.urls import url
import views
urlpatterns = [
url(r'^download/$', views.DownloadView.as_view(), name='download')
]
views.py
import urllib
from django.http import HttpResponse
from django.views.generic.base import View
class DownloadView(View):
def get(self, request):
location = request.GET.get('location')
file = urllib.urlretrieve(location)
contents = open(file[0], 'r')
content_type = '%s' % file[1].type
response = HttpResponse(contents, content_type=content_type)
response['Content-Disposition'] = 'attachment; filename="%s"' % location.split('/')[-1]
return response
template.html
...

Flask: how can a client download a created JSON file

I have a JSON string that I am reading from a web form that I would like to create a temporary file out of and allow the file to be downloaded to the local client machine. In other words my app.route reads the string, writes the string to a file and then sends the file to the client:
#app.route('/sendFile', methods=['POST'])
def sendFile():
content = str(request.form['jsonval'])
with open('zones.geojson', 'w') as f:
f.write(content)
return send_file(f)
What's the best way to make this work?
From this answer all that is needed is to specify the correct Response header:
From flask import Response
#app.route('/sendFile', methods=['POST'])
def sendFile():
content = str(request.form['jsonval'])
return Response(content,
mimetype='application/json',
headers={'Content-Disposition':'attachment;filename=zones.geojson'})