Advertisement
Guest User

Untitled

a guest
Nov 12th, 2019
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.38 KB | None | 0 0
  1. class Worksheet(object):
  2. errors = ''
  3. rows_inserted_count = 0
  4. rows_updated_count = 0
  5. reversed_data_map = {}
  6.  
  7.  
  8.  
  9. def __init__(self, file_contents, DATA_MAP, data_range, required_fields):
  10. self.ws = self.get_worksheet(file_contents)
  11.  
  12. self.required_fields = required_fields
  13.  
  14. self.DATA_MAP = DATA_MAP
  15. self.reverse_data_map()
  16.  
  17. self.data = self.get_data(data_range)
  18.  
  19.  
  20. def add_custom_error(self, error, cell):
  21. self.errors += error + ' Пустая ячейка %s \n\r' % (cell)
  22.  
  23. def add_error(self, cell):
  24. self.errors += 'Пустая ячейка %s \n\r' % (cell)
  25.  
  26. def validate_fields(self, row):
  27. ''' Отдает список проблемных ячеек типа А, В, С, Е'''
  28. return [self.reversed_data_map[field] for field in self.required_fields if not row[field]]
  29.  
  30.  
  31. def make_error(self, problem_columns, row):
  32. ''' Записывает координаты проблемных мест на основе перебора всей строчки по ячейке'''
  33. for x in row:
  34. [self.add_error(x.column+str(x.row)) for column in problem_columns if column == x.column]
  35.  
  36. def get_data(self, data_range):
  37. assert len(data_range) == 2, 'Неправильный формат диапазона'
  38. start, end = data_range
  39. raw_data = self.ws[start:end]
  40.  
  41. data = []
  42. for row in raw_data:
  43. raw_dict = {}
  44. row_cells = {}
  45. for cell in row:
  46. raw_dict[cell.coordinate[0]] = cell.value
  47.  
  48. # Переименование словаря в удобный для работы и чтения
  49. for x, y in zip(raw_dict, self.DATA_MAP): row_cells[self.DATA_MAP[y]] = raw_dict[x]
  50.  
  51. problem_columns = self.validate_fields(row_cells)
  52. if problem_columns:
  53. self.make_error(problem_columns, row)
  54.  
  55. if self.errors:
  56. break
  57.  
  58. data.append(row_cells)
  59.  
  60. return data
  61.  
  62.  
  63. @staticmethod
  64. def get_worksheet(file_contents):
  65. assert file_contents, 'Файл не найден'
  66. str_io = StringIO.StringIO()
  67. str_io.write(file_contents)
  68. str_io.seek(0)
  69.  
  70. wb = openpyxl.load_workbook(str_io)
  71. return wb.worksheets[0]
  72.  
  73.  
  74. def reverse_data_map(self):
  75. ''' Зеркалит DATA_MAP чтобы по имени найти ячейку'''
  76. for key, val in self.DATA_MAP.iteritems():
  77. self.reversed_data_map[val] = key
  78.  
  79.  
  80. def import_devices(session, file_contents=None):
  81. '''Абонентские терминалы'''
  82.  
  83. search_in_db_fields = ['device_type_id', 'organization_id']
  84. required_fields = ['number', 'imei', ] + search_in_db_fields # Обязательные поля
  85.  
  86. # Буква ячеек и их имя в экселе
  87. DATA_MAP = {
  88. 'B': 'device_fullname', # Полное наименование и модель прибора
  89. 'C': 'imei', # Номер IMEI прибора
  90. 'D': 'sim_card', # № SIM карты установленной в прибор
  91. 'E': 'number', # Номер прибора, с которым он шлет данные напрямую (id)
  92. 'F': 'rnic_number', # Номер прибора, если данные ретранслируются
  93. 'G': 'ip_addr', # IP адрес и порт локального оператора при ретрансляции
  94. 'H': 'support_device_type_LO', # Протоколы, в которых могут ретранслировать с сервера ЛО
  95. 'I': 'support_device_type', # Протоколы, в которых может отправлять данные прибор
  96. 'J': 'device_type_id', # Протокол, в котором отправляет данные прибор
  97. 'K': 'organization_id', # Организация - владелец прибора
  98. 'L': 'mounter_organization_id', # Организация, обслуживающая прибор
  99. 'M': 'comment', # Особенности подключения прибора и его заведения в АИС УТ
  100. 'N': 'date_import' # Дата создания
  101. }
  102.  
  103. data_range = ('B2', 'N2')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement