mongo_suppor.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. from contracts import contract
  2. import datetime
  3. import getpass
  4. import shelve
  5. import socket
  6. from duckietown_utils import is_internet_connected, logger, raise_wrapped
  7. from duckietown_utils import on_duckiebot, on_laptop, on_circle
  8. from what_the_duck import what_the_duck_version
  9. from .constant import Result
  10. from .geolocation import get_geolocation_data
  11. mongo_db = 'wtd01'
  12. mongo_collection = 'uploads'
  13. try:
  14. import pymongo # @UnresolvedImport @UnusedImport
  15. except ImportError as e:
  16. msg = 'pymongo not installed.'
  17. msg += '\n\nTry the following:'
  18. msg += '\n\n pip install --user pymongo'
  19. raise_wrapped(Exception, e, msg)
  20. def get_connection_string():
  21. username = 'upload'
  22. password = 'quackquack'
  23. s = ("mongodb://<USERNAME>:<PASSWORD>@dt0-shard-00-00-npkyt.mongodb.net:27017,"
  24. "dt0-shard-00-01-npkyt.mongodb.net:27017,dt0-shard-00-02-npkyt.mongodb.net"
  25. ":27017/test?ssl=true&replicaSet=dt0-shard-0&authSource=admin")
  26. s = s.replace("<PASSWORD>", password)
  27. s = s.replace("<USERNAME>", username)
  28. return s
  29. def get_local_keys():
  30. username = getpass.getuser()
  31. hostname = socket.gethostname()
  32. d = {}
  33. if on_duckiebot():
  34. stype = 'duckiebot'
  35. elif on_laptop():
  36. stype = 'laptop'
  37. elif on_circle():
  38. stype = 'cloud'
  39. else:
  40. stype = 'unknown'
  41. d['type'] = stype
  42. d['what_the_duck_version'] = what_the_duck_version
  43. d['username'] = username
  44. d['hostname'] = hostname
  45. now = datetime.datetime.now()
  46. date_s = now.isoformat('_')
  47. upload_event_id = hostname + '-' + date_s
  48. d['upload_event_id'] = upload_event_id
  49. d['upload_event_date'] = now
  50. location = get_geolocation_data()
  51. d.update(location)
  52. return d
  53. @contract(result=Result)
  54. def json_from_result(result):
  55. d = {}
  56. d['test_name'] = result.entry.get_test_id()
  57. d['status'] = result.status
  58. d['out_short'] = result.out_short
  59. d['out_long'] = result.out_long
  60. return d
  61. def get_upload_collection():
  62. s = get_connection_string()
  63. logger.info('Opening connection to MongoDB...')
  64. client = pymongo.MongoClient(s)
  65. db = client[mongo_db]
  66. collection = db[mongo_collection]
  67. return collection
  68. def upload_results(results):
  69. to_upload = json_from_results(results)
  70. upload(to_upload)
  71. def upload(to_upload):
  72. filename = '/tmp/what_the_duck'
  73. S = shelve.open(filename)
  74. try:
  75. # logger.debug('New records: %s previous: %s' % (len(to_upload), len(S)))
  76. for u in to_upload:
  77. S[u['_id']] = u
  78. if not is_internet_connected():
  79. msg = 'Internet is not connected: cannot upload results.'
  80. logger.warning(msg)
  81. else:
  82. remaining = []
  83. for k in S:
  84. remaining.append(S[k])
  85. collection = get_upload_collection()
  86. logger.info('Uploading %s test results' % len(remaining))
  87. collection.insert_many(remaining)
  88. logger.info('done')
  89. for r in remaining:
  90. del S[r['_id']]
  91. finally:
  92. # logger.info('Remaining %s' % (len(S)))
  93. S.close()
  94. def json_from_results(results):
  95. to_upload = []
  96. d0 = get_local_keys()
  97. for i, result in enumerate(results):
  98. d1 = json_from_result(result)
  99. d1['_id'] = d0['upload_event_id'] + '-%d' % i
  100. d1.update(d0)
  101. to_upload.append(d1)
  102. return to_upload