shimatta_kenkyusho_print_label.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #!/bin/python
  2. import shimatta_label.storage_label
  3. import shimatta_label.component_label
  4. import shimatta_label.brother_ql_wrapper as ql_wrapper
  5. import sys
  6. import requests
  7. import urllib.parse
  8. import getpass
  9. import json
  10. import re
  11. MICE_TOILET_TEMPLATE = 'https://parts.shimatta.net/api/v1/parts/storages/075acbaf-ed60-47b9-9bd5-98bfbc3a79ea/'
  12. def get_component_print_name(comp):
  13. '''
  14. Generates a human readeable string from the parameters depending on the type
  15. '''
  16. param_dict = {param['ro_parameter_type']: param for param in comp['ro_parameters']}
  17. if comp['ro_component_type'] in ['Resistor', 'Resistor NTC']:
  18. resistor_value = param_dict['Resistance']['value']
  19. if resistor_value >= 10e8:
  20. comp_name = f'{int(resistor_value / 10e8)}G{str(int(resistor_value % 10e8)).rstrip('0')}'
  21. elif resistor_value >= 10e5:
  22. comp_name = f'{int(resistor_value / 10e5)}M{str(int(resistor_value % 10e5)).rstrip('0')}'
  23. elif resistor_value >= 10e2:
  24. comp_name = f'{int(resistor_value / 10e2)}K{str(int(resistor_value % 10e2)).rstrip('0')}'
  25. elif resistor_value >= 1.0:
  26. comp_name = f'{int(resistor_value)}R{str(round(resistor_value % 1, 6))[2:].rstrip('0')}'
  27. elif resistor_value == 0.0:
  28. comp_name = '0R'
  29. else:
  30. comp_name = f'R{str(round(resistor_value % 1, 6))[2:]}'
  31. if comp['ro_component_type'] == 'Resistor NTC':
  32. comp_name += ' NTC'
  33. if param_dict['Resistor technology']['text_value'] == 'laser trim':
  34. comp_name += ' L'
  35. else:
  36. print(f'Unknown component type: {comp['ro_component_type']}')
  37. return None
  38. return comp_name
  39. def char_range(c1, c2):
  40. """Generates the characters from `c1` to `c2`, exclusive."""
  41. for c in range(ord(c1), ord(c2)):
  42. yield chr(c)
  43. def handle_storage_qr_code(base_url, token, uuid):
  44. storage_query_url = urllib.parse.urljoin(base_url, 'api/v1/parts/storages/')
  45. query_res = requests.get(storage_query_url, headers={'Authorization': f'Token {token}'}, params={'id':uuid})
  46. if query_res.status_code != 200:
  47. print('Request unsuccessful')
  48. sys.exit(-3)
  49. print('Storage found: ')
  50. storage_json = query_res.json()
  51. if storage_json['count'] != 1:
  52. print('Storage json does not contain correct amount of storage entries')
  53. sys.exit(-1)
  54. storage = storage_json['results'][0]
  55. print(f'ID: {storage["id"]}')
  56. print(f'Path: {storage["full_path"]}')
  57. labels = []
  58. if storage['template'] == MICE_TOILET_TEMPLATE:
  59. side = input('Select type to be printed (top, bottom, storage) [t,b,s]:')
  60. if side not in ['t', 'b', 's']:
  61. print('Error - invalid side')
  62. return None
  63. if side == 's':
  64. label = shimatta_label.storage_label.StorageLabelSmdMiceToilet()
  65. storage = storage_json['results'][0]
  66. label.put_content(f'[stor_uuid]{storage["id"]}',
  67. storage['full_path'],
  68. storage['verbose_name'])
  69. return [label]
  70. row = input('Select which row shall be printed [1..3]:')
  71. if row not in char_range('1', '4'):
  72. print('Error - invalid row')
  73. return None
  74. row = int(row)
  75. # get children
  76. query_res = requests.get(storage_query_url, headers={'Authorization': f'Token {token}'}, params={'parent_storage':uuid, 'expand_stocks': True})
  77. if query_res.status_code != 200:
  78. print('Request for children unsuccessful')
  79. sys.exit(-3)
  80. storage_json = query_res.json()
  81. if storage_json['count'] != 24:
  82. print('Storage json does not contain correct amount of storage entries')
  83. sys.exit(-1)
  84. # pagination
  85. storage_list = storage_json['results']
  86. while storage_json['next']:
  87. query_res = requests.get(storage_json['next'], headers={'Authorization': f'Token {token}'}, params={'parent_storage':uuid})
  88. storage_json = query_res.json()
  89. storage_list.extend(storage_json['results'])
  90. storage_dict = {storage['name']: storage for storage in storage_list}
  91. if side == 'b':
  92. for column in char_range('a','i'):
  93. label = shimatta_label.storage_label.StorageLabelSmdMiceToiletBottomQR()
  94. field_uuid = storage_dict[f'{column}{row}']['id']
  95. label.put_content(f'[stor_uuid]{field_uuid}')
  96. labels.append(label)
  97. elif side == 't':
  98. for column in char_range('a','i'):
  99. label = shimatta_label.storage_label.StorageLabelSmdMiceToiletTop()
  100. if not storage_dict[f'{column}{row}']['ro_stocks']:
  101. print("Only printing start of row!!!")
  102. break
  103. comp = storage_dict[f'{column}{row}']['ro_stocks'][0]['ro_component']
  104. param_dict = {param['ro_parameter_type']: param for param in comp['ro_parameters']}
  105. comp_name = get_component_print_name(comp)
  106. if not comp_name:
  107. return[]
  108. label.put_content(comp_name,
  109. f"{param_dict['Tolerance']['value']}% {comp['package_data']['name']}",
  110. comp['ro_manufacturer_name'])
  111. labels.append(label)
  112. else:
  113. label = shimatta_label.storage_label.StorageLabel()
  114. label.put_content(f'[stor_uuid]{uuid}', storage['full_path'], storage['verbose_name'])
  115. labels.append(label)
  116. return labels
  117. def handle_component_qr_code(base_url, token, uuid):
  118. query_url = urllib.parse.urljoin(base_url, 'api/v1/parts/components/')
  119. query_res = requests.get(query_url, headers={'Authorization': f'Token {token}'}, params={'id': uuid})
  120. if query_res.status_code != 200:
  121. print('Request unsuccessful')
  122. sys.exit(-3)
  123. component = json.loads(query_res.content)
  124. if component['count'] != 1:
  125. sys.exit(-1)
  126. component = component['results'][0]
  127. pkg = ''
  128. name = component['name']
  129. if component.get('package_data') is not None:
  130. pkg = component['package_data']['name']
  131. manufacturer = component.get('ro_manufacturer_name')
  132. if manufacturer is None:
  133. manufacturer = ''
  134. print(f'Component found: Name: {name}, Package: {pkg}, Manufacturer: {manufacturer}')
  135. labels = []
  136. label = shimatta_label.component_label.ComponentLabelSmall()
  137. comp_name = get_component_print_name(component)
  138. if not comp_name:
  139. return[]
  140. label.put_content(f'[comp_uuid]{uuid}', comp_name, manufacturer, pkg)
  141. labels.append(label)
  142. return labels
  143. if len(sys.argv) < 2:
  144. print(f'Usage: {sys.argv[0]} <shimatta kenkyusho url>')
  145. sys.exit(-1)
  146. qr_re = re.compile(r'^\[(?P<prefix>[a-zA-Z_]+)\](?P<uuid>[a-fA-F0-9\-]+)')
  147. kenkyusho_url = sys.argv[1]
  148. print(f"Shimatta Kenkyusho instance: {kenkyusho_url}")
  149. login_url = urllib.parse.urljoin(kenkyusho_url, 'api/v1/token-auth/')
  150. print(f'Token auth url: {login_url}')
  151. username = input('Username: ')
  152. password = getpass.getpass()
  153. ans = requests.post(login_url, data= {'username': username, 'password': password})
  154. if ans.status_code != 200:
  155. print(f'Got status code {ans.status_code}')
  156. sys.exit(-1)
  157. login_token = json.loads(ans.content)['token']
  158. while True:
  159. qr = input('Please scan Storage or Component QR: ')
  160. matches = qr_re.match(qr)
  161. if matches.group('prefix') == 'stor_uuid' :
  162. labels = handle_storage_qr_code(kenkyusho_url, login_token, matches.group('uuid'))
  163. elif matches.group('prefix') == 'comp_uuid':
  164. labels = handle_component_qr_code(kenkyusho_url, login_token, matches.group('uuid'))
  165. else:
  166. print('Invalid QR code!')
  167. continue
  168. if labels:
  169. ql_wrapper.print_labels(labels)