You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
486 lines
19 KiB
486 lines
19 KiB
# -*- coding: utf-8 -*-
|
|
from django import forms
|
|
from django.conf import settings
|
|
from theme.models import Theme, Tag
|
|
from place_exposition.models import PlaceExposition
|
|
from place_conference.models import PlaceConference
|
|
from country.models import Country
|
|
from organiser.models import Organiser
|
|
from django.db.models.loading import get_model
|
|
import xlrd, xlwt
|
|
from excel_settings import import_settings
|
|
from functions.form_check import translit_with_separator
|
|
|
|
languages = [code for code in settings.LANGUAGES]
|
|
|
|
|
|
class ImportForm(forms.Form):
|
|
"""
|
|
abstract form for importing models from excel file to database
|
|
"""
|
|
model = None
|
|
excel_file = forms.FileField(label='Выберите файл')
|
|
language = forms.ChoiceField(label='Выберите язык', choices=languages)
|
|
def save_file(self):
|
|
data = self.cleaned_data
|
|
lang = data['language']
|
|
f = data['excel_file']
|
|
book = xlrd.open_workbook(file_contents=f.read())
|
|
sheet = book.sheet_by_index(0)
|
|
row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)]
|
|
# all field names in excel file (must be in second row)
|
|
field_names = [name for name in row_list[1]]
|
|
|
|
|
|
for row_number, row in enumerate(row_list):
|
|
# go through all rows in file
|
|
if row_number > 1:
|
|
# first two fields are verbose name and name
|
|
if row[0] != '':
|
|
# in first column ids
|
|
|
|
try:
|
|
object = self.model.objects.language(lang).get(id=int(row[0]))
|
|
except ValueError:
|
|
object = self.model()
|
|
object.translate(lang)
|
|
|
|
except self.model.DoesNotExist:
|
|
object = self.model(id= int(row[0]))
|
|
object.translate(lang)
|
|
else:
|
|
# if id blank - its a new event
|
|
object = self.model()
|
|
object.translate(lang)
|
|
|
|
|
|
for col_number, cell in enumerate(row):
|
|
# go through row cells
|
|
# field name current cell
|
|
field_name = field_names[col_number]
|
|
if field_name =='theme':
|
|
# need save object before saving manytomany field
|
|
object.save()
|
|
setting = import_settings.get(field_name)
|
|
if setting is not None:
|
|
# if setting exist for this field
|
|
func = setting.get('func')
|
|
if func is not None:
|
|
extra_value = setting.get('extra_values')
|
|
if extra_value is not None:
|
|
# if setting has extra value then
|
|
# it is some field like city, theme, tag
|
|
# that has relation and can be created
|
|
|
|
# in function we add language(need for relation fields)
|
|
# and extra value from object (like for city need country)
|
|
value = func(cell, lang, getattr(object, extra_value))
|
|
else:
|
|
value = func(cell)
|
|
|
|
setattr(object, field_name, value)
|
|
|
|
object.save()
|
|
|
|
class ImportOrganiserForm(ImportForm):
|
|
model = Organiser
|
|
|
|
|
|
class ImportThemeForm(ImportForm):
|
|
model = Theme
|
|
|
|
|
|
from excel_settings import place_exp_sett
|
|
from django.db import IntegrityError
|
|
import urllib, json
|
|
|
|
|
|
def google_address(address):
|
|
if address:
|
|
address = address.encode('utf')
|
|
params = urllib.urlencode({'sensor': 'false', 'address': address})
|
|
response = urllib.urlopen("http://maps.google.com/maps/api/geocode/json?%s" % params)
|
|
response = response.read()
|
|
results = json.loads(response).get('results')
|
|
if results:
|
|
response = {'address' : results[0].get('formatted_address'),
|
|
'lat' : results[0]['geometry']['location']['lat'],
|
|
'lng' : results[0]['geometry']['location']['lng']}
|
|
return json.dumps(response)
|
|
else:
|
|
return ''
|
|
return ''
|
|
|
|
from djutils.decorators import async
|
|
from djutils.queue.decorators import queue_command
|
|
|
|
class ImportPlaceExpositionForm(ImportForm):
|
|
model = PlaceExposition
|
|
settings = place_exp_sett
|
|
#@async
|
|
def save_file(self):
|
|
data = self.cleaned_data
|
|
lang = data['language']
|
|
f = data['excel_file']
|
|
book = xlrd.open_workbook(file_contents=f.read())
|
|
sheet = book.sheet_by_index(0)
|
|
row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)]
|
|
|
|
labels = [label for label in row_list[0]]
|
|
|
|
for row_number, row in enumerate(row_list):
|
|
# go through all rows in file
|
|
if row_number > 0:
|
|
# first field is label
|
|
if row[0] != '':
|
|
# in first column ids
|
|
|
|
try:
|
|
object = self.model.objects.language(lang).get(id=int(row[0]))
|
|
except ValueError:
|
|
object = self.model()
|
|
object.translate(lang)
|
|
|
|
except self.model.DoesNotExist:
|
|
object = self.model(id= int(row[0]))
|
|
object.translate(lang)
|
|
else:
|
|
# if id blank - its a new event
|
|
object = self.model()
|
|
object.translate(lang)
|
|
methods = []
|
|
for col_number, cell in enumerate(row):
|
|
# go through row cells
|
|
# field name current cell
|
|
label = labels[col_number]
|
|
setting = place_exp_sett.get(label)
|
|
|
|
if setting is None:
|
|
continue
|
|
|
|
if setting.get('method'):
|
|
if cell != "":
|
|
methods.append({'func': setting['func'], 'value': cell, 'purpose': setting.get('purpose')})
|
|
continue
|
|
|
|
field_name = setting['field']
|
|
|
|
|
|
func = setting.get('func')
|
|
if func is not None:
|
|
extra_value = setting.get('extra_values')
|
|
if extra_value is not None:
|
|
# if setting has extra value then
|
|
# it is some field like city, theme, tag
|
|
# that has relation and can be created
|
|
|
|
# in function we add language(need for relation fields)
|
|
# and extra value from object (like for city need country)
|
|
value = func(cell, lang, getattr(object, extra_value))
|
|
else:
|
|
value = func(cell)
|
|
if field_name =='adress':
|
|
setattr(object, 'address', google_address(value))
|
|
setattr(object, field_name, value)
|
|
|
|
|
|
try:
|
|
object.save()
|
|
|
|
except IntegrityError:
|
|
continue
|
|
#url = object.url + translit_with_separator(object.city.name)
|
|
#object.url = url
|
|
#object.save()
|
|
|
|
for method in methods:
|
|
func = method['func']
|
|
if method.get('purpose'):
|
|
try:
|
|
func(object, method['value'], method['purpose'])
|
|
except:
|
|
continue
|
|
else:
|
|
try:
|
|
func(object, method['value'])
|
|
except:
|
|
continue
|
|
|
|
|
|
class ImportPlaceConferenceForm(ImportForm):
|
|
model = PlaceConference
|
|
|
|
|
|
from import_xls.excel_settings import event_sett
|
|
typical_errors = {'(1048, "Column \'city_id\' cannot be null")':u'Неправильная страна или город',
|
|
'(1048, "Column \'country_id\' cannot be null")':u'Неправильная страна или город',
|
|
'(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата окончания',
|
|
'(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата начала'}
|
|
|
|
class ImportEventForm(ImportForm):
|
|
"""
|
|
extended form for importing one type of event
|
|
"""
|
|
|
|
event = forms.ChoiceField(label='Выберите тип события', choices=[('exposition.Exposition', 'Выставка'),
|
|
('conference.Conference', 'Конференция'),
|
|
('seminar.Seminar', 'Семинар'),
|
|
('webinar.Webinar', 'Вебинар')])
|
|
|
|
def save_file_debug(self):
|
|
data = self.cleaned_data
|
|
lang = data['language']
|
|
f = data['excel_file']
|
|
book = xlrd.open_workbook(file_contents=f.read())
|
|
sheet = book.sheet_by_index(0)
|
|
row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)]
|
|
field_names = [name for name in row_list[0]]
|
|
# model
|
|
model = get_model(data['event'].split('.')[0], data['event'].split('.')[1])
|
|
|
|
labels = [label for label in row_list[0]]
|
|
errors = []
|
|
|
|
for row_number, row in enumerate(row_list):
|
|
if row_number == 0:
|
|
continue
|
|
|
|
if row[0] != '':
|
|
# in first column id
|
|
try:
|
|
obj = self.model.objects.language(lang).get(id=int(row[0]))
|
|
except ValueError:
|
|
obj = self.model()
|
|
obj.translate(lang)
|
|
|
|
except self.model.DoesNotExist:
|
|
obj = self.model(id= int(row[0]))
|
|
obj.translate(lang)
|
|
else:
|
|
# if id blank - its a new event
|
|
obj = model()
|
|
obj.translate(lang)
|
|
|
|
methods = []
|
|
for col_number, cell in enumerate(row):
|
|
# go through row cells
|
|
# field name current cell
|
|
label = labels[col_number]
|
|
|
|
setting = event_sett.get(label)
|
|
|
|
if setting is None:
|
|
continue
|
|
|
|
|
|
if setting.get('method'):
|
|
# this cell contains data that must be written after creating object
|
|
if cell != "":
|
|
methods.append({'func': setting['func'], 'value': cell, 'purpose': setting.get('purpose')})
|
|
continue
|
|
|
|
field_name = setting['field']
|
|
func = setting.get('func')
|
|
if func is None:
|
|
continue
|
|
|
|
extra_value = setting.get('extra_values')
|
|
if extra_value is not None:
|
|
# if setting has extra value then
|
|
# it is some field like city, theme, tag
|
|
# that has relation and can be created
|
|
|
|
# in function we add language(need for relation fields)
|
|
# and extra value from object (like for city need country)
|
|
try:
|
|
extra = getattr(obj, extra_value)
|
|
except Exception:
|
|
continue
|
|
value = func(cell, 'ru', extra)
|
|
elif setting.get('bitfield'):
|
|
value = func(obj, cell, setting['label'])
|
|
|
|
else:
|
|
value = func(cell)
|
|
try:
|
|
setattr(obj, field_name, value)
|
|
except ValueError:
|
|
continue
|
|
if not obj.url:
|
|
obj.url = translit_with_separator(obj.name)
|
|
try:
|
|
obj.save()
|
|
|
|
except IntegrityError, e:
|
|
error = str(e)
|
|
if typical_errors.get(error):
|
|
error = typical_errors[error]
|
|
if error.startswith('(1062, "Duplicate entry') and error.endswith('for key \'url\'")'):
|
|
error = u'Событие с таким названием или урлом уже существует'
|
|
|
|
errors.append([obj.name, error])
|
|
continue
|
|
|
|
for method in methods:
|
|
func = method['func']
|
|
if method.get('purpose'):
|
|
try:
|
|
func(obj, method['value'], method['purpose'])
|
|
except:
|
|
continue
|
|
else:
|
|
func(obj, method['value'])
|
|
|
|
#-------------
|
|
|
|
return errors
|
|
|
|
def save_file(self):
|
|
"""
|
|
save events from excel file
|
|
in language from form
|
|
"""
|
|
data = self.cleaned_data
|
|
lang = data['language']
|
|
f = data['excel_file']
|
|
book = xlrd.open_workbook(file_contents=f.read())
|
|
sheet = book.sheet_by_index(0)
|
|
row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)]
|
|
# all field names in excel file (must be in second row)
|
|
field_names = [name for name in row_list[0]]
|
|
# model
|
|
model = get_model(data['event'].split('.')[0], data['event'].split('.')[1])
|
|
|
|
list_dicts = []
|
|
|
|
for row_number, row in enumerate(row_list):
|
|
# go through all rows in file
|
|
if row_number > 0:
|
|
# first two fields are verbose name and name
|
|
if row[0] != '':
|
|
# in first column ids
|
|
try:
|
|
object = self.model.objects.language(lang).get(id=int(row[0]))
|
|
except ValueError:
|
|
object = self.model()
|
|
object.translate(lang)
|
|
|
|
except self.model.DoesNotExist:
|
|
object = self.model(id= int(row[0]))
|
|
object.translate(lang)
|
|
else:
|
|
# if id blank - its a new event
|
|
object = model()
|
|
object.translate(lang)
|
|
|
|
d = {}
|
|
for col_number, cell in enumerate(row):
|
|
# through row
|
|
|
|
field_name = field_names[col_number]
|
|
setting = import_settings.get(field_name)
|
|
d[setting] = cell
|
|
|
|
list_dicts.append(d)
|
|
|
|
|
|
"""
|
|
# go through row cells
|
|
# field name current cell
|
|
field_name = field_names[col_number]
|
|
if field_name =='theme':
|
|
# need save object before saving manytomany field
|
|
#object.save()
|
|
setting = import_settings.get(field_name)
|
|
d[setting] = cell
|
|
|
|
if setting is not None:
|
|
# if setting exist for this field
|
|
func = setting.get('func')
|
|
if func is not None:
|
|
extra_value = setting.get('extra_values')
|
|
if extra_value is not None:
|
|
# if setting has extra value then
|
|
# it is some field like city, theme, tag
|
|
# that has relation and can be created
|
|
|
|
# in function we add language(need for relation fields)
|
|
# and extra value from object (like for city need country)
|
|
if cell:
|
|
value = func(cell, lang, getattr(object, extra_value))
|
|
else:
|
|
value = None
|
|
else:
|
|
value = func(cell)
|
|
if value:
|
|
setattr(object, field_name, value)
|
|
"""
|
|
|
|
#object.save()
|
|
|
|
|
|
|
|
|
|
|
|
class ImportTagForm(ImportForm):
|
|
"""
|
|
hacked problem with importing theme field in save_file method
|
|
"""
|
|
model = Tag
|
|
#@async
|
|
def save_file(self):
|
|
data = self.cleaned_data
|
|
lang = data['language']
|
|
f = data['excel_file']
|
|
book = xlrd.open_workbook(file_contents=f.read())
|
|
sheet = book.sheet_by_index(0)
|
|
row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)]
|
|
# all field names in excel file (must be in second row)
|
|
field_names = [name for name in row_list[1]]
|
|
for row_number, row in enumerate(row_list):
|
|
# go through all rows in file
|
|
if row_number > 1:
|
|
# first two fields are verbose name and name
|
|
if row[0] != '':
|
|
# in first column ids
|
|
try:
|
|
object = self.model.objects.language(lang).get(id=int(row[0]))
|
|
except ValueError:
|
|
object = self.model()
|
|
object.translate(lang)
|
|
|
|
except self.model.DoesNotExist:
|
|
object = self.model(id= int(row[0]))
|
|
object.translate(lang)
|
|
else:
|
|
# if id blank - its a new event
|
|
object = self.model()
|
|
object.translate(lang)
|
|
|
|
|
|
for col_number, cell in enumerate(row):
|
|
# go through row cells
|
|
# field name current cell
|
|
field_name = field_names[col_number]
|
|
setting = import_settings.get(field_name)
|
|
if setting is not None:
|
|
# if setting exist for this field
|
|
func = setting.get('func')
|
|
if func is not None:
|
|
extra_value = setting.get('extra_values')
|
|
if extra_value is not None:
|
|
# if setting has extra value then
|
|
# it is some field like city, theme, tag
|
|
# that has relation and can be created
|
|
|
|
# in function we add language(need for relation fields)
|
|
# and extra value from object (like for city need country)
|
|
value = func(cell, lang, getattr(object, extra_value))
|
|
else:
|
|
value = func(cell)
|
|
if field_name != 'theme':
|
|
setattr(object, field_name, value)
|
|
else:
|
|
setattr(object, field_name, value[0])
|
|
|
|
object.save() |