DotaNoobs main site.
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.

174 lines
11 KiB

  1. import operator
  2. import os
  3. import ts3
  4. import time
  5. import requests
  6. from xml.etree import ElementTree
  7. from flask import url_for
  8. from bs4 import BeautifulSoup
  9. from app import app
  10. def getTeamspeakWindow(window=605800):
  11. current_time = time.time()
  12. from models import TeamspeakData
  13. return TeamspeakData.query.filter(TeamspeakData.time < current_time, TeamspeakData.time > current_time-window).order_by(TeamspeakData.time).all()
  14. def create_teamspeak_viewer():
  15. try:
  16. server = ts3.TS3Server(app.config['TS3_HOST'], app.config['TS3_PORT'])
  17. server.login(app.config['TS3_USERNAME'], app.config['TS3_PASSWORD'])
  18. server.use(1)
  19. serverinfo = server.send_command('serverinfo').data
  20. channellist = server.send_command('channellist', opts=("limits", "flags", "voice", "icon")).data
  21. clientlist = server.send_command('clientlist', opts=("away", "voice", "info", "icon", "groups", "country")).data
  22. servergrouplist = server.send_command('servergrouplist').data
  23. channelgrouplist = server.send_command('channelgrouplist').data
  24. soup = BeautifulSoup()
  25. div_tag = soup.new_tag('div')
  26. div_tag['class'] ='devmx-webviewer'
  27. soup.append(div_tag)
  28. def construct_channels(parent_tag, cid):
  29. num_clients = 0
  30. for channel in channellist:
  31. if int(channel['pid']) == int(cid):
  32. # Construct the channel
  33. channel_tag = soup.new_tag('div')
  34. channel_tag['class'] = 'tswv-channel'
  35. # Channel image
  36. image_tag = soup.new_tag('span')
  37. image_tag['class'] = 'tswv-image tswv-image-right'
  38. if int(channel['channel_flag_password']) == 1:
  39. image_tag['class'] += ' tswv-channel-password-right'
  40. if int(channel['channel_flag_default']) == 1:
  41. image_tag['class'] += ' tswv-channel-home'
  42. if int(channel['channel_needed_talk_power']) > 0:
  43. image_tag['class'] += ' tswv-channel-moderated'
  44. if int(channel['channel_icon_id']) != 0:
  45. pass
  46. image_tag.append(' ')
  47. channel_tag.append(image_tag)
  48. # Status image
  49. status_tag = soup.new_tag('span')
  50. status_tag['class'] = 'tswv-image'
  51. if int(channel['channel_flag_password']) == 1:
  52. status_tag['class'] += ' tswv-channel-password'
  53. elif int(channel['total_clients']) == int(channel['channel_maxclients']):
  54. status_tag['class'] += ' tswv-channel-full'
  55. else:
  56. status_tag['class'] += ' tswv-channel-normal'
  57. status_tag.append(' ')
  58. channel_tag.append(status_tag)
  59. # Label
  60. label_tag = soup.new_tag('span')
  61. label_tag['class'] = 'tswv-label'
  62. label_tag.append(channel['channel_name'])
  63. channel_tag.append(label_tag)
  64. # Clients
  65. channel_tag, channel_clients = construct_clients(channel_tag, channel['cid'])
  66. # Recurse through sub-channels, collecting total number of clients as we go
  67. channel_tag, sub_clients = construct_channels(channel_tag, channel['cid'])
  68. channel_clients += sub_clients
  69. # Only show non-empty channels
  70. if channel_clients > 0:
  71. parent_tag.append(channel_tag)
  72. num_clients += channel_clients
  73. return parent_tag, num_clients
  74. def construct_clients(parent_tag, cid):
  75. num_clients = 0
  76. for client in clientlist:
  77. if int(client['cid']) == int(cid):
  78. # Skip ServerQuery clients
  79. if int(client['client_type']) == 1: continue
  80. num_clients += 1
  81. client_tag = soup.new_tag('div')
  82. client_tag['class'] = 'tswv-client'
  83. # Status image
  84. status_tag = soup.new_tag('span')
  85. status_tag['class'] = 'tswv-image'
  86. if int(client['client_type']) == 1:
  87. status_tag['class'] += ' tswv-client-query'
  88. elif int(client['client_away']) == 1:
  89. status_tag['class'] += " tswv-client-away"
  90. elif int(client['client_input_muted']) == 1:
  91. status_tag['class'] += " tswv-client-input-muted"
  92. elif int(client['client_output_muted']) == 1:
  93. status_tag['class'] += " tswv-client-output-muted"
  94. elif int(client['client_input_hardware']) == 0:
  95. status_tag['class'] += " tswv-client-input-muted-hardware"
  96. elif int(client['client_output_hardware']) == 0:
  97. status_tag['class'] += " tswv-client-output-muted-hardware"
  98. elif (int(client['client_flag_talking']) == 1) and (int(client['client_is_channel_commander']) == 1):
  99. status_tag['class'] += " tswv-client-channel-commander-talking"
  100. elif int(client['client_is_channel_commander']) == 1:
  101. status_tag['class'] += " tswv-client-channel-commander"
  102. elif int(client['client_flag_talking']) == 1:
  103. status_tag['class'] += " tswv-client-talking"
  104. else:
  105. status_tag['class'] += " tswv-client-normal"
  106. status_tag.append(' ')
  107. client_tag.append(status_tag)
  108. # Country image
  109. if client['client_country']:
  110. country_tag = soup.new_tag('span')
  111. country_tag['class'] = 'tswv-image tswv-image-right'
  112. country_tag['title'] = ' '.join([word.capitalize() for word in ISO3166_MAPPING[client['client_country']].split(' ')])
  113. country_tag['style'] = 'background: url("%s") center center no-repeat;' % url_for('static', filename='img/ts3_viewer/countries/%s.png' % client['client_country'].lower())
  114. country_tag.append(' ')
  115. client_tag.append(country_tag)
  116. # Server group images
  117. sgids = [int(sg) for sg in client['client_servergroups'].split(',')]
  118. servergroups = [servergroup for servergroup in servergrouplist if int(servergroup['sgid']) in sgids]
  119. servergroups.sort(key=operator.itemgetter('sortid'))
  120. for servergroup in servergroups:
  121. if not servergroup['iconid']: continue
  122. img_fname = 'img/ts3_viewer/%s.png' % servergroup['iconid']
  123. if not os.path.exists(os.path.join(app.static_folder, img_fname)):
  124. continue
  125. image_tag = soup.new_tag('span')
  126. image_tag['class'] = 'tswv-image tswv-image-right'
  127. image_tag['title'] = servergroup['name']
  128. image_tag['style'] = 'background-image: url("%s")' % url_for('static', filename=img_fname)
  129. image_tag.append(' ')
  130. client_tag.append(image_tag)
  131. # Check if client is in a moderated channel
  132. channel = [channel for channel in channellist if int(channel['cid']) == int(client['cid'])][0]
  133. if int(channel['channel_needed_talk_power']) > 0:
  134. status_tag = soup.new_tag('span')
  135. status_tag['class'] = 'tswv-image tswv-image-right'
  136. if int(client['client_is_talker']) == 0:
  137. status_tag['class'] += ' tswv-client-input-muted'
  138. else:
  139. status_tag['class'] += ' tswv-client-talkpower-granted'
  140. status_tag.append(' ')
  141. client_tag.append(status_tag)
  142. # Label
  143. label_tag = soup.new_tag('span')
  144. label_tag['class'] = 'tswv-label'
  145. label_tag.append(client['client_nickname'])
  146. client_tag.append(label_tag)
  147. parent_tag.append(client_tag)
  148. return parent_tag, num_clients
  149. div_tag, num_clients = construct_channels(div_tag, 0)
  150. return (soup.prettify(), num_clients)
  151. except Exception as inst:
  152. return "error: %s" % inst
  153. def get_ISO3166_mapping():
  154. #data = requests.get(url_for('static', filename='country_codes.xml'))
  155. #xml = ElementTree.fromstring(data.text.encode('utf-8'))
  156. with open('app/static/country_codes.xml', mode='r') as d:
  157. data = d.read()
  158. xml = ElementTree.fromstring(data)
  159. d = dict()
  160. for entry in xml.findall('ISO_3166-1_Entry'):
  161. d[entry.find('ISO_3166-1_Alpha-2_Code_element').text] = entry.find('ISO_3166-1_Country_name').text
  162. return d
  163. ISO3166_MAPPING = get_ISO3166_mapping()