parent
5d6632455d
commit
463b59a098
10 changed files with 102 additions and 41 deletions
|
|
@ -3,6 +3,7 @@ import select
|
||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
import requests
|
import requests
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
class DiscordConnector:
|
class DiscordConnector:
|
||||||
|
|
@ -57,7 +58,8 @@ class DiscordConnector:
|
||||||
return
|
return
|
||||||
if channel != self.current_voice:
|
if channel != self.current_voice:
|
||||||
cn = self.channels[channel]['name']
|
cn = self.channels[channel]['name']
|
||||||
print("Joined room: %s" % (cn))
|
logging.info(
|
||||||
|
"Joined room: %s" % (cn))
|
||||||
self.current_voice = channel
|
self.current_voice = channel
|
||||||
if need_req:
|
if need_req:
|
||||||
self.req_channel_details(channel)
|
self.req_channel_details(channel)
|
||||||
|
|
@ -68,7 +70,8 @@ class DiscordConnector:
|
||||||
return
|
return
|
||||||
if channel != self.current_text:
|
if channel != self.current_text:
|
||||||
self.current_text = channel
|
self.current_text = channel
|
||||||
print("Changing text room: %s" % (channel))
|
logging.info(
|
||||||
|
"Changing text room: %s" % (channel))
|
||||||
if need_req:
|
if need_req:
|
||||||
self.req_channel_details(channel)
|
self.req_channel_details(channel)
|
||||||
|
|
||||||
|
|
@ -137,6 +140,8 @@ class DiscordConnector:
|
||||||
user["deaf"] = self.userlist[user["id"]]["deaf"]
|
user["deaf"] = self.userlist[user["id"]]["deaf"]
|
||||||
if not "speaking" in user and "speaking" in self.userlist[user["id"]]:
|
if not "speaking" in user and "speaking" in self.userlist[user["id"]]:
|
||||||
user["speaking"] = self.userlist[user["id"]]["speaking"]
|
user["speaking"] = self.userlist[user["id"]]["speaking"]
|
||||||
|
if self.userlist[user["id"]]["avatar"] != user["avatar"]:
|
||||||
|
self.voice_overlay.delete_avatar(user["id"])
|
||||||
self.userlist[user["id"]] = user
|
self.userlist[user["id"]] = user
|
||||||
|
|
||||||
def on_message(self, message):
|
def on_message(self, message):
|
||||||
|
|
@ -200,7 +205,7 @@ class DiscordConnector:
|
||||||
if self.current_text == j["data"]["channel_id"]:
|
if self.current_text == j["data"]["channel_id"]:
|
||||||
self.delete_text(j["data"]["message"])
|
self.delete_text(j["data"]["message"])
|
||||||
else:
|
else:
|
||||||
print(j)
|
logging.info(j)
|
||||||
return
|
return
|
||||||
elif j["cmd"] == "AUTHENTICATE":
|
elif j["cmd"] == "AUTHENTICATE":
|
||||||
if j["evt"] == "ERROR":
|
if j["evt"] == "ERROR":
|
||||||
|
|
@ -209,8 +214,10 @@ class DiscordConnector:
|
||||||
else:
|
else:
|
||||||
self.req_guilds()
|
self.req_guilds()
|
||||||
self.user = j["data"]["user"]
|
self.user = j["data"]["user"]
|
||||||
print("ID is %s" % (self.user["id"]))
|
logging.info(
|
||||||
print("Logged in as %s" % (self.user["username"]))
|
"ID is %s" % (self.user["id"]))
|
||||||
|
logging.info(
|
||||||
|
"Logged in as %s" % (self.user["username"]))
|
||||||
self.authed = True
|
self.authed = True
|
||||||
return
|
return
|
||||||
elif j["cmd"] == "GET_GUILDS":
|
elif j["cmd"] == "GET_GUILDS":
|
||||||
|
|
@ -234,7 +241,8 @@ class DiscordConnector:
|
||||||
return
|
return
|
||||||
elif j["cmd"] == "GET_CHANNEL":
|
elif j["cmd"] == "GET_CHANNEL":
|
||||||
if j["evt"] == "ERROR":
|
if j["evt"] == "ERROR":
|
||||||
print("Could not get room")
|
logging.info(
|
||||||
|
"Could not get room")
|
||||||
return
|
return
|
||||||
for voice in j["data"]["voice_states"]:
|
for voice in j["data"]["voice_states"]:
|
||||||
if voice["user"]["id"] == self.user["id"]:
|
if voice["user"]["id"] == self.user["id"]:
|
||||||
|
|
@ -250,7 +258,7 @@ class DiscordConnector:
|
||||||
for message in j["data"]["messages"]:
|
for message in j["data"]["messages"]:
|
||||||
self.add_text(message)
|
self.add_text(message)
|
||||||
return
|
return
|
||||||
print(j)
|
logging.info(j)
|
||||||
|
|
||||||
def check_guilds(self):
|
def check_guilds(self):
|
||||||
# Check if all of the guilds contain a channel
|
# Check if all of the guilds contain a channel
|
||||||
|
|
@ -265,15 +273,16 @@ class DiscordConnector:
|
||||||
channels = ""
|
channels = ""
|
||||||
for channel in guild["channels"]:
|
for channel in guild["channels"]:
|
||||||
channels = channels + " " + channel["name"]
|
channels = channels + " " + channel["name"]
|
||||||
print("%s: %s" % (guild["name"], channels))
|
logging.info(
|
||||||
|
"%s: %s" % (guild["name"], channels))
|
||||||
self.sub_server()
|
self.sub_server()
|
||||||
self.find_user()
|
self.find_user()
|
||||||
|
|
||||||
def on_error(self, error):
|
def on_error(self, error):
|
||||||
print("ERROR : %s" % (error))
|
logging.error("ERROR : %s" % (error))
|
||||||
|
|
||||||
def on_close(self):
|
def on_close(self):
|
||||||
print("Connection closed")
|
logging.info("Connection closed")
|
||||||
self.ws = None
|
self.ws = None
|
||||||
|
|
||||||
def req_auth(self):
|
def req_auth(self):
|
||||||
|
|
@ -351,7 +360,8 @@ class DiscordConnector:
|
||||||
if not self.ws:
|
if not self.ws:
|
||||||
self.connect()
|
self.connect()
|
||||||
if self.warn_connection:
|
if self.warn_connection:
|
||||||
print("Unable to connect to Discord client")
|
logging.info(
|
||||||
|
"Unable to connect to Discord client")
|
||||||
self.warn_connection = False
|
self.warn_connection = False
|
||||||
return True
|
return True
|
||||||
# Recreate a list of users in current room
|
# Recreate a list of users in current room
|
||||||
|
|
@ -392,6 +402,6 @@ class DiscordConnector:
|
||||||
origin="https://streamkit.discord.com")
|
origin="https://streamkit.discord.com")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if self.error_connection:
|
if self.error_connection:
|
||||||
print(e)
|
logging.error(e)
|
||||||
self.error_connection = False
|
self.error_connection = False
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ from .text_settings import TextSettingsWindow
|
||||||
from .voice_overlay import VoiceOverlayWindow
|
from .voice_overlay import VoiceOverlayWindow
|
||||||
from .text_overlay import TextOverlayWindow
|
from .text_overlay import TextOverlayWindow
|
||||||
from .discord_connector import DiscordConnector
|
from .discord_connector import DiscordConnector
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
class Discover:
|
class Discover:
|
||||||
|
|
@ -58,7 +59,8 @@ class Discover:
|
||||||
self.ind.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
|
self.ind.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
|
||||||
self.ind.set_menu(menu)
|
self.ind.set_menu(menu)
|
||||||
except:
|
except:
|
||||||
|
logging.info(
|
||||||
|
"Falling back to Sys tray")
|
||||||
# Create System Tray
|
# Create System Tray
|
||||||
self.tray = Gtk.StatusIcon.new_from_icon_name("discover_overlay")
|
self.tray = Gtk.StatusIcon.new_from_icon_name("discover_overlay")
|
||||||
self.tray.connect('popup-menu', self.show_menu)
|
self.tray.connect('popup-menu', self.show_menu)
|
||||||
|
|
@ -109,5 +111,6 @@ class Discover:
|
||||||
|
|
||||||
|
|
||||||
def entrypoint():
|
def entrypoint():
|
||||||
|
logging.getLogger().setLevel(logging.INFO)
|
||||||
discover = Discover()
|
discover = Discover()
|
||||||
discover.main()
|
discover.main()
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ gi.require_version('GdkPixbuf', '2.0')
|
||||||
import cairo
|
import cairo
|
||||||
from gi.repository.GdkPixbuf import Pixbuf
|
from gi.repository.GdkPixbuf import Pixbuf
|
||||||
from gi.repository import Gtk, GLib, Gio, GdkPixbuf, Gdk, Pango, PangoCairo
|
from gi.repository import Gtk, GLib, Gio, GdkPixbuf, Gdk, Pango, PangoCairo
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
class DraggableWindow(Gtk.Window):
|
class DraggableWindow(Gtk.Window):
|
||||||
|
|
|
||||||
41
discover_overlay/image_getter.py
Normal file
41
discover_overlay/image_getter.py
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
import gi
|
||||||
|
gi.require_version("Gtk", "3.0")
|
||||||
|
gi.require_version('PangoCairo', '1.0')
|
||||||
|
gi.require_version('GdkPixbuf', '2.0')
|
||||||
|
import urllib
|
||||||
|
import threading
|
||||||
|
from gi.repository.GdkPixbuf import Pixbuf
|
||||||
|
from gi.repository import Gtk, GLib, Gio, GdkPixbuf, Gdk, Pango, PangoCairo
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
class Image_Getter():
|
||||||
|
def __init__(self, func, url, id, size):
|
||||||
|
self.func = func
|
||||||
|
self.id = id
|
||||||
|
self.url = url
|
||||||
|
self.size = size
|
||||||
|
|
||||||
|
def get_url(self):
|
||||||
|
req = urllib.request.Request(self.url)
|
||||||
|
req.add_header(
|
||||||
|
'Referer', 'https://streamkit.discord.com/overlay/voice')
|
||||||
|
req.add_header('User-Agent', 'Mozilla/5.0')
|
||||||
|
try:
|
||||||
|
response = urllib.request.urlopen(req)
|
||||||
|
input_stream = Gio.MemoryInputStream.new_from_data(
|
||||||
|
response.read(), None)
|
||||||
|
pixbuf = Pixbuf.new_from_stream(input_stream, None)
|
||||||
|
pixbuf = pixbuf.scale_simple(self.size, self.size,
|
||||||
|
GdkPixbuf.InterpType.BILINEAR)
|
||||||
|
self.func(self.id, pixbuf)
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(
|
||||||
|
"Could not access : %s" % (url))
|
||||||
|
logging.error(e)
|
||||||
|
|
||||||
|
|
||||||
|
def get_image(func, id, ava, size):
|
||||||
|
image_getter = Image_Getter(func, id, ava, size)
|
||||||
|
t = threading.Thread(target=image_getter.get_url, args=())
|
||||||
|
t.start()
|
||||||
|
|
@ -5,6 +5,7 @@ gi.require_version('GdkPixbuf', '2.0')
|
||||||
from gi.repository.GdkPixbuf import Pixbuf
|
from gi.repository.GdkPixbuf import Pixbuf
|
||||||
from gi.repository import Gtk, GLib, Gio, GdkPixbuf, Gdk, Pango, PangoCairo
|
from gi.repository import Gtk, GLib, Gio, GdkPixbuf, Gdk, Pango, PangoCairo
|
||||||
import cairo
|
import cairo
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
class OverlayWindow(Gtk.Window):
|
class OverlayWindow(Gtk.Window):
|
||||||
|
|
@ -19,7 +20,8 @@ class OverlayWindow(Gtk.Window):
|
||||||
screen = self.get_screen()
|
screen = self.get_screen()
|
||||||
visual = screen.get_rgba_visual()
|
visual = screen.get_rgba_visual()
|
||||||
if not self.get_display().supports_input_shapes():
|
if not self.get_display().supports_input_shapes():
|
||||||
print("Input shapes not available. Quitting")
|
logging.info(
|
||||||
|
"Input shapes not available. Quitting")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
if visual:
|
if visual:
|
||||||
# Set the visual even if we can't use it right now
|
# Set the visual even if we can't use it right now
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import sys
|
||||||
import os
|
import os
|
||||||
from gi.repository.GdkPixbuf import Pixbuf
|
from gi.repository.GdkPixbuf import Pixbuf
|
||||||
from gi.repository import Gtk, GLib, Gio, GdkPixbuf, Gdk, Pango, PangoCairo
|
from gi.repository import Gtk, GLib, Gio, GdkPixbuf, Gdk, Pango, PangoCairo
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -42,7 +43,8 @@ class SettingsWindow(Gtk.Window):
|
||||||
for i in range(0, display.get_n_monitors()):
|
for i in range(0, display.get_n_monitors()):
|
||||||
if display.get_monitor(i).get_model() == name:
|
if display.get_monitor(i).get_model() == name:
|
||||||
return i
|
return i
|
||||||
print("Could not find monitor : %s" % (name))
|
logging.info(
|
||||||
|
"Could not find monitor : %s" % (name))
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def present(self):
|
def present(self):
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ from .overlay import OverlayWindow
|
||||||
from gi.repository.GdkPixbuf import Pixbuf
|
from gi.repository.GdkPixbuf import Pixbuf
|
||||||
from gi.repository import Gtk, GLib, Gio, GdkPixbuf, Gdk, Pango, PangoCairo
|
from gi.repository import Gtk, GLib, Gio, GdkPixbuf, Gdk, Pango, PangoCairo
|
||||||
import cairo
|
import cairo
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
class TextOverlayWindow(OverlayWindow):
|
class TextOverlayWindow(OverlayWindow):
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from .draggable_window import DraggableWindow
|
||||||
from .settings import SettingsWindow
|
from .settings import SettingsWindow
|
||||||
from gi.repository.GdkPixbuf import Pixbuf
|
from gi.repository.GdkPixbuf import Pixbuf
|
||||||
from gi.repository import Gtk, GLib, Gio, GdkPixbuf, Gdk, Pango, PangoCairo
|
from gi.repository import Gtk, GLib, Gio, GdkPixbuf, Gdk, Pango, PangoCairo
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
class TextSettingsWindow(SettingsWindow):
|
class TextSettingsWindow(SettingsWindow):
|
||||||
|
|
@ -98,7 +99,8 @@ class TextSettingsWindow(SettingsWindow):
|
||||||
self.fg_col = json.loads(config.get(
|
self.fg_col = json.loads(config.get(
|
||||||
"text", "fg_col", fallback="[1.0,1.0,1.0,1.0]"))
|
"text", "fg_col", fallback="[1.0,1.0,1.0,1.0]"))
|
||||||
|
|
||||||
print("Loading saved channel %s" % (self.channel))
|
logging.info(
|
||||||
|
"Loading saved channel %s" % (self.channel))
|
||||||
|
|
||||||
# Pass all of our config over to the overlay
|
# Pass all of our config over to the overlay
|
||||||
self.overlay.set_enabled(self.enabled)
|
self.overlay.set_enabled(self.enabled)
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,11 @@ gi.require_version('PangoCairo', '1.0')
|
||||||
gi.require_version('GdkPixbuf', '2.0')
|
gi.require_version('GdkPixbuf', '2.0')
|
||||||
import math
|
import math
|
||||||
from .overlay import OverlayWindow
|
from .overlay import OverlayWindow
|
||||||
|
from .image_getter import get_image
|
||||||
from gi.repository.GdkPixbuf import Pixbuf
|
from gi.repository.GdkPixbuf import Pixbuf
|
||||||
from gi.repository import Gtk, GLib, Gio, GdkPixbuf, Gdk, Pango, PangoCairo
|
from gi.repository import Gtk, GLib, Gio, GdkPixbuf, Gdk, Pango, PangoCairo
|
||||||
import cairo
|
import cairo
|
||||||
import urllib
|
import logging
|
||||||
|
|
||||||
|
|
||||||
class VoiceOverlayWindow(OverlayWindow):
|
class VoiceOverlayWindow(OverlayWindow):
|
||||||
|
|
@ -32,8 +33,9 @@ class VoiceOverlayWindow(OverlayWindow):
|
||||||
self.userlist = []
|
self.userlist = []
|
||||||
self.connected = False
|
self.connected = False
|
||||||
self.force_location()
|
self.force_location()
|
||||||
self.def_avatar = self.get_img(
|
self.def_avatar = get_image(self.recv_avatar,
|
||||||
"https://cdn.discordapp.com/embed/avatars/3.png")
|
"https://cdn.discordapp.com/embed/avatars/3.png",
|
||||||
|
'def', self.avatar_size)
|
||||||
|
|
||||||
self.first_draw = True
|
self.first_draw = True
|
||||||
|
|
||||||
|
|
@ -91,8 +93,9 @@ class VoiceOverlayWindow(OverlayWindow):
|
||||||
|
|
||||||
def reset_avatar(self):
|
def reset_avatar(self):
|
||||||
self.avatars = {}
|
self.avatars = {}
|
||||||
self.def_avatar = self.get_img(
|
self.def_avatar = get_image(self.recv_avatar,
|
||||||
"https://cdn.discordapp.com/embed/avatars/3.png")
|
"https://cdn.discordapp.com/embed/avatars/3.png",
|
||||||
|
'def', self.avatar_size)
|
||||||
|
|
||||||
def set_user_list(self, userlist, alt):
|
def set_user_list(self, userlist, alt):
|
||||||
self.userlist = userlist
|
self.userlist = userlist
|
||||||
|
|
@ -150,31 +153,26 @@ class VoiceOverlayWindow(OverlayWindow):
|
||||||
# Don't hold a ref
|
# Don't hold a ref
|
||||||
self.context = None
|
self.context = None
|
||||||
|
|
||||||
def get_img(self, url):
|
def recv_avatar(self, id, pix):
|
||||||
req = urllib.request.Request(url)
|
if(id == 'def'):
|
||||||
req.add_header(
|
self.def_avatar = pix
|
||||||
'Referer', 'https://streamkit.discord.com/overlay/voice')
|
else:
|
||||||
req.add_header('User-Agent', 'Mozilla/5.0')
|
self.avatars[id] = pix
|
||||||
try:
|
|
||||||
response = urllib.request.urlopen(req)
|
def delete_avatar(self, id):
|
||||||
input_stream = Gio.MemoryInputStream.new_from_data(
|
if id in self.avatars:
|
||||||
response.read(), None)
|
del self.avatars[id]
|
||||||
pixbuf = Pixbuf.new_from_stream(input_stream, None)
|
|
||||||
pixbuf = pixbuf.scale_simple(self.avatar_size, self.avatar_size,
|
|
||||||
GdkPixbuf.InterpType.BILINEAR)
|
|
||||||
return pixbuf
|
|
||||||
except:
|
|
||||||
print("Could not access : %s" % (url))
|
|
||||||
return none
|
|
||||||
|
|
||||||
def draw_avatar(self, context, user, y):
|
def draw_avatar(self, context, user, y):
|
||||||
# Ensure pixbuf for avatar
|
# Ensure pixbuf for avatar
|
||||||
if user["id"] not in self.avatars and user["avatar"]:
|
if user["id"] not in self.avatars and user["avatar"]:
|
||||||
url = "https://cdn.discordapp.com/avatars/%s/%s.jpg" % (
|
url = "https://cdn.discordapp.com/avatars/%s/%s.jpg" % (
|
||||||
user["id"], user["avatar"])
|
user['id'], user['avatar'])
|
||||||
p = self.get_img(url)
|
get_image(self.recv_avatar, url, user["id"],
|
||||||
if p:
|
self.avatar_size)
|
||||||
self.avatars[user["id"]] = p
|
|
||||||
|
# Set the key with no value to avoid spamming requests
|
||||||
|
self.avatars[user["id"]] = None
|
||||||
|
|
||||||
(w, h) = self.get_size()
|
(w, h) = self.get_size()
|
||||||
c = None
|
c = None
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from .draggable_window import DraggableWindow
|
||||||
from .settings import SettingsWindow
|
from .settings import SettingsWindow
|
||||||
from gi.repository.GdkPixbuf import Pixbuf
|
from gi.repository.GdkPixbuf import Pixbuf
|
||||||
from gi.repository import Gtk, GLib, Gio, GdkPixbuf, Gdk, Pango, PangoCairo
|
from gi.repository import Gtk, GLib, Gio, GdkPixbuf, Gdk, Pango, PangoCairo
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
class VoiceSettingsWindow(SettingsWindow):
|
class VoiceSettingsWindow(SettingsWindow):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue