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.

190 lines
12 KiB

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