add export for panel
This commit is contained in:
parent
71fb3249b0
commit
f010c97433
|
|
@ -481,6 +481,19 @@ class Panel(ProjectBaseMixin):
|
|||
columns = [col[0] for col in cursor.description]
|
||||
return columns
|
||||
|
||||
def get_headers(self):
|
||||
with connections['default'].cursor() as cursor:
|
||||
try:
|
||||
cursor.execute(self.query)
|
||||
except Exception as er:
|
||||
raise UnprocessableEntityError()
|
||||
return self._raw_columns(cursor)
|
||||
|
||||
def get_data(self):
|
||||
with connections['default'].cursor() as cursor:
|
||||
cursor.execute(self.query)
|
||||
return cursor.fetchall()
|
||||
|
||||
def _raw_page(self, raw, request):
|
||||
page = request.query_params.get('page', 0)
|
||||
page_size = request.query_params.get('page_size', 0)
|
||||
|
|
|
|||
14
apps/main/tasks.py
Normal file
14
apps/main/tasks.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
"""Task methods for main app."""
|
||||
|
||||
from celery import shared_task
|
||||
|
||||
from account.models import User
|
||||
from main.models import Panel
|
||||
from utils.export import SendExport
|
||||
|
||||
|
||||
@shared_task
|
||||
def send_export_to_email(panel_id, user_id, file_type='csv'):
|
||||
panel = Panel.objects.get(id=panel_id)
|
||||
user = User.objects.get(id=user_id)
|
||||
SendExport(user, panel, file_type).send()
|
||||
|
|
@ -24,8 +24,9 @@ urlpatterns = [
|
|||
name='page-types-list-create'),
|
||||
path('panels/', views.PanelsListCreateView.as_view(), name='panels'),
|
||||
path('panels/<int:pk>/', views.PanelsRUDView.as_view(), name='panels-rud'),
|
||||
path('panels/<int:pk>/execute/', views.PanelsExecuteView.as_view(), name='panels-execute')
|
||||
|
||||
path('panels/<int:pk>/execute/', views.PanelsExecuteView.as_view(), name='panels-execute'),
|
||||
path('panels/<int:pk>/csv/', views.PanelsExportCSVView.as_view(), name='panels-csv'),
|
||||
path('panels/<int:pk>/xls/', views.PanelsExecuteXLSView.as_view(), name='panels-xls')
|
||||
]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from rest_framework import generics, permissions
|
||||
from rest_framework import generics, permissions, status
|
||||
from rest_framework.generics import get_object_or_404
|
||||
from rest_framework.response import Response
|
||||
|
||||
from main import serializers
|
||||
from main import tasks
|
||||
from main.filters import AwardFilter
|
||||
from main.models import Award, Footer, PageType, Panel
|
||||
from main.views import SiteSettingsView, SiteListView
|
||||
|
|
@ -121,3 +123,35 @@ class PanelsExecuteView(generics.ListAPIView):
|
|||
def list(self, request, *args, **kwargs):
|
||||
panel = get_object_or_404(Panel, id=self.kwargs['pk'])
|
||||
return Response(panel.execute_query(request))
|
||||
|
||||
|
||||
class PanelsExportCSVView(PanelsExecuteView):
|
||||
"""Export panels via csv view."""
|
||||
permission_classes = (permissions.IsAdminUser,)
|
||||
queryset = Panel.objects.all()
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
panel = get_object_or_404(Panel, id=self.kwargs['pk'])
|
||||
# make task for celery
|
||||
tasks.send_export_to_email.delay(
|
||||
panel_id=panel.id, user_id=request.user.id)
|
||||
return Response(
|
||||
{"success": _('The file will be sent to your email.')},
|
||||
status=status.HTTP_200_OK
|
||||
)
|
||||
|
||||
|
||||
class PanelsExecuteXLSView(PanelsExecuteView):
|
||||
"""Export panels via xlsx view."""
|
||||
permission_classes = (permissions.IsAdminUser,)
|
||||
queryset = Panel.objects.all()
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
panel = get_object_or_404(Panel, id=self.kwargs['pk'])
|
||||
# make task for celery
|
||||
tasks.send_export_to_email.delay(
|
||||
panel_id=panel.id, user_id=request.user.id, file_type='xls')
|
||||
return Response(
|
||||
{"success": _('The file will be sent to your email.')},
|
||||
status=status.HTTP_200_OK
|
||||
)
|
||||
|
|
|
|||
115
apps/utils/export.py
Normal file
115
apps/utils/export.py
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
import csv
|
||||
import xlsxwriter
|
||||
import logging
|
||||
import os
|
||||
import tempfile
|
||||
from smtplib import SMTPException
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.mail import EmailMultiAlternatives
|
||||
|
||||
logging.basicConfig(format='[%(levelname)s] %(message)s', level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SendExport:
|
||||
|
||||
def __init__(self, user, panel, file_type='csv'):
|
||||
self.type_mapper = {
|
||||
"csv": self.make_csv_file,
|
||||
"xls": self.make_xls_file
|
||||
}
|
||||
self.file_type = file_type
|
||||
self.user = user
|
||||
self.panel = panel
|
||||
self.email_from = settings.EMAIL_HOST_USER
|
||||
self.email_subject = f'Export panel: {self.get_file_name()}'
|
||||
self.email_body = 'Exported panel data'
|
||||
self.get_file_method = self.type_mapper[file_type]
|
||||
self.file_path = os.path.join(
|
||||
settings.STATIC_ROOT,
|
||||
'email', tempfile.gettempdir(),
|
||||
self.get_file_name()
|
||||
)
|
||||
self.success = False
|
||||
|
||||
def get_file_name(self):
|
||||
name = '_'.join(self.panel.name.split(' '))
|
||||
return f'export_{name.lower()}.{self.file_type}'
|
||||
|
||||
def get_data(self):
|
||||
return self.panel.get_data()
|
||||
|
||||
def get_headers(self):
|
||||
try:
|
||||
header = self.panel.get_headers()
|
||||
self.success = True
|
||||
return header
|
||||
except Exception as err:
|
||||
logger.info(f'HEADER:{err}')
|
||||
|
||||
def make_csv_file(self):
|
||||
file_header = self.get_headers()
|
||||
if not self.success:
|
||||
return
|
||||
with open(self.file_path, 'w') as f:
|
||||
file_writer = csv.writer(f, quotechar='"', quoting=csv.QUOTE_MINIMAL)
|
||||
# Write headers to CSV file
|
||||
file_writer.writerow(file_header)
|
||||
for row in self.get_data():
|
||||
file_writer.writerow(row)
|
||||
|
||||
def make_xls_file(self):
|
||||
headings = self.get_headers()
|
||||
if not self.success:
|
||||
return
|
||||
with xlsxwriter.Workbook(self.file_path) as workbook:
|
||||
worksheet = workbook.add_worksheet()
|
||||
|
||||
# Add a bold format to use to highlight cells.
|
||||
bold = workbook.add_format({'bold': True})
|
||||
|
||||
# Add the worksheet data that the charts will refer to.
|
||||
data = self.get_data()
|
||||
|
||||
worksheet.write_row('A1', headings, bold)
|
||||
for n, row in enumerate(data):
|
||||
worksheet.write_row(f'A{n+2}', [str(i) for i in row])
|
||||
workbook.close()
|
||||
|
||||
def send(self):
|
||||
self.get_file_method()
|
||||
print(f'ok: {self.file_path}')
|
||||
self.send_email()
|
||||
|
||||
def get_file(self):
|
||||
if os.path.exists(self.file_path) and os.path.isfile(self.file_path):
|
||||
with open(self.file_path, 'rb') as export_file:
|
||||
return export_file
|
||||
else:
|
||||
logger.info('COMMUTATOR:image file not found dir: {path}')
|
||||
|
||||
def send_email(self):
|
||||
|
||||
msg = EmailMultiAlternatives(
|
||||
subject=self.email_subject,
|
||||
body=self.email_body,
|
||||
from_email=self.email_from,
|
||||
to=[
|
||||
self.user.email,
|
||||
'kuzmenko.da@gmail.com',
|
||||
'sinapsit@yandex.ru'
|
||||
]
|
||||
)
|
||||
|
||||
# Create an inline attachment
|
||||
if self.file_path and self.success:
|
||||
msg.attach_file(self.file_path)
|
||||
else:
|
||||
msg.body = 'An error occurred while executing the request.'
|
||||
|
||||
try:
|
||||
msg.send()
|
||||
logger.debug(f"COMMUTATOR:Email successfully sent")
|
||||
except SMTPException as e:
|
||||
logger.error(f"COMMUTATOR:Email connector: {e}")
|
||||
|
|
@ -63,3 +63,6 @@ pycountry==19.8.18
|
|||
|
||||
# sql-tree
|
||||
django-mptt==0.9.1
|
||||
|
||||
# Export to Excel
|
||||
XlsxWriter==1.2.6
|
||||
Loading…
Reference in New Issue
Block a user