; #-> Allgemeine Informationen <-#
; Name: YouTube Announcer
; Author: Kylar
; Date: 25.09.2020
; Version: 1.0.0 - Erster Release
; Beschreibung: YouTube Announcer tut genau das, was der Name vermuten/befürchten lässt.
; Das Script sucht aktiv in allen Channels (die nicht ignoriert werden sollen) nach YouTube Links und liefert, über die Google API, Informationen zum Video.
; Dabei kann die Ausgabe für sich selbst (über Echo) oder als MSG im Channel erfolgen.
;
; Voraussetzungen: AdiIRC in der Version 3.8 oder höher oder mIRC in der Version 7.62 oder höher.
; Einen Google API-Key für die YouTube Data API v3 (siehe https://developers.google.com/youtube/v3/getting-started)
;
; #-> Installation <-#
; Script entsprechend in AdiIRC/mIRC laden und den Befehl /youtube_announcer aufrufen, um das Script einzustellen.
; Nachdem die Einstellungen vorgenommen wurden, reagiert das Script entsprechend auf Nachrichten.
;
; #-> Deinstallation <-#
; Einfach den Befehl /youtube_announcer deinstall eingeben und das Script entfernt alle globalen Variablen.
; ACHTUNG: Die aktuellen Einstellungen werden in der yta_settings.ini gespeichert und beim erneuten aufrufen von /youtube_announcer geladen.
; Für eine vollständige Deinstallation den Befehl /youtube_announcer deinstall aufrufen, das Script und die yta_settings.ini löschen.
;; ##############
;; # Dialog/GUI #
;; ##############
alias youtube_announcer {
if ( $0 == 0 ) {
dialog -m yta_d_main yta_d_main
}
else {
if ( $lower($1) == deinstall || $lower($1) == uninstall || $lower($1) == deinstallation ) {
yta_uninstall
}
}
}
; TODO Unter Nachricht einstellen, dass die Vorschau auch per Echo erfolgen kann (für Farbe usw.)
; Haupt Dialog zum einstellen des Scripts
Dialog yta_d_main {
;; Main
title "YouTube Announcer"
; -1 -1 setzt den Dialog in die Mitte vom Hauptfenster
size -1 -1 200 150
option dbu
menu "About", 100
; menu "Hilfe", 101
;; Tab Allgemeine Einstellen
tab "Allgemeine Einstellungen", 1, 0 0 200 150
box "Parsing", 10, 5 15 190 70, tab 1
; Abstand in der Höhe bei Check muss mindestens 8 sein
check "Channel Nachrichten Parsen", 11, 10 24 76 8, tab 1
check "Privat Nachrichten Parsen", 12, 10 32 70 8, tab 1
check "YT-Infos nur über Echo ausgeben", 22, 95 24 88 8, tab 1
text "Anbieter die geparst werden sollen", 13, 10 43 180 8, tab 1
list 14, 10 52 180 28, tab 1 size extsel check multse vsbar
box "API", 15, 5 90 190 50, tab 1
text "Damit das Script Informationen über YouTube Videos abrufen kann,", 16, 10 99 180 8, nowrap tab 1
text "wird ein API-Key von "17, 10 107 50 8, nowrap tab 1
link "Google", 18, 62 107 18 8, tab 1
text "benötigt. Der Key wird auschließlich zum ", 19, 80 107 100 8, tab 1
text "Abrufen der Videoinformationen verwendet." 20, 10 115 180 12, tab 1
edit "", 21, 20 125 150 10, tab 1
;; Anpassen der Nachricht die ausgegeben wird
tab "Nachrichten-Formatierung", 3, 0 0 200 150
box "Nachricht", 30, 5 15 190 57, tab 3
edit "", 31, 10 24 180 10, tab 3 autohs
text "Vorschau", 32, 10 36 100 8, tab 3
edit "", 33, 10 44 180 10, tab 3 rich read autohs
check "Vorschau als Echo ausgeben?", 38, 10 58 80 8, tab 3
box "Platzhalter", 34, 5 75 190 40 , tab 3
text "Die folgenden aufgelisteten Zeichenfolgen werden automatisch ersetzt.", 35, 10 84 180 8, tab 3
text "<duration>, <title>, <channeltitle>, <publishedat>, <favoritecount>", 36, 10 94 180 8, tab 3
text "<viewcount>, <likecount>, <dislikecount>, <commentcount>", 37, 10 102 180 8, tab 3
;; Channels/Nicks die ignoriert werden sollen
tab "Ignorieren", 4, 0 0 200 150
text "Server, Channel und Nicknames eintragen, die ignoriert werden sollen.", 40, 5 15 190 12, tab 4
box "Eingabe", 41, 5 30 190 37, tab 4
text "Format: [network:][#]Ziel.", 42, 10 40 75 8, tab 4
edit "", 43, 10 50 150 10, tab 4
button "Hinzfügen", 44, 163 50 30 10, tab 4
box "Liste der zu ignorierenden Objekte", 45, 5 72 190 70, tab 4
list 46, 10 82 153 55, tab 4 size extsel vsbar
button "Entfernen", 47, 165 82 27 55, tab 4 multi
}
; About Dialog (zeigt momentan nur Basic-Informationen an)
dialog yta_d_about {
title "About - YouTube Announcer"
size -1 -1 100 70
option dbu
text "Script Name: YouTube Announcer", 1, 5 5 100 8
text "Author: Kylar", 2 , 5 13 100 8
text "Date: September 2020", 3, 5 21 100 8
text "Kurzbeschreibung: Liefert Informationen zu erkannten YouTube Links", 4, 5 29 190 20
text "Voraussetzung: YouTube/Goole API-Key", 5, 5 50 100 14
}
;;#
;; Dialog Events
;;#
; Settings laden und die Tabs mit Inhalt befüllen
on *:DIALOG:yta_d_main:init:0: {
did -a yta_d_main 14 youtube.com
did -a yta_d_main 14 yu2.be
did -a yta_d_main 14 youtu.be
; Wenn keine Settings vorhanden sind, entsprechend die settings ini laden oder erstellen
if ( !$var(%yta/settings/*)) {
yta_load_config
}
var %i = 1
while ( %i <= $var(%yta/settings/*) ) {
var %j = 1, %fp = $var(%yta/settings/*, %i) ,%sec = $token(%fp, $calc($numtok(%fp, 47) - 1), 47), %item = $token(%fp, $numtok(%fp, 47), 47)
var %val = $var(%yta/settings/*, %i).value
; Liste der zu ignorierenden Ziele befüllen
if (%item == list ) {
$iif(%val != $chr(7), yta_fill_ignorelist, noop)
}
; Die Nachricht, die ausgegeben werden soll, befüllen
elseif ( %item == msg ) {
$iif(%val != $chr(7), yta_fill_msg, noop )
}
; API-Key Feld befüllen
elseif ( %item == apikey ) {
$iif(%val != $chr(7), yta_fill_apikey, noop )
}
; URLS in der Liste markieren
elseif ( %item == urls ) {
if ( %val != $chr(7) ) {
var %j = 1
while ( %j <= $numtok(%val, 44) ) {
var %k = 1, %val1 = $token(%val, %j, 44)
while ( %k <= $did(14).lines ) {
if ($did(14, %k).text == %val1) {
did -s yta_d_main 14 %k
}
inc %k
}
inc %j
}
}
}
; Checkbox für die Ausgabe der über Echo
elseif ( %sec == General && %item == echo ) {
if ( %val == 1 ) {
did -c $dname 22
}
}
; Checkbox, ob Channel-Nachrichten geparst werden sollen
elseif ( %item == cmsg ) {
if ( %val == 1 ) {
did -c $dname 11
}
}
; Checkbox, ob Private-Nachrichten geparst werden sollen
elseif ( %item == pmsg ) {
if ( %val == 1 ) {
did -c $dname 12
}
}
; Einstellung für die Ausgabe der Vorschau
elseif ( %sec == Message && %item == echo ) {
if ( %val == 1 ) {
did -c $dname 38
}
}
inc %i
}
}
; Einstellungen beim Verlassen des Dialogs in die ini schreiben
on *:DIALOG:yta_d_main:close:0: {
yta_save_config
}
; API-Key in Variable speichern
on *:DIALOG:yta_d_main:edit:21: {
set %yta/settings/General/apikey $did(21).text
}
; Verarbeitung der Click-Events
; Im Tab IgnoreList: Multiselektion kann nicht als ganzes entfernt werden, nur einzelne Ziele können entfernt werden.
on *:DIALOG:yta_d_main:sclick:*: {
if ( $did == 11 ) {
; channel nachricht
set %yta/settings/General/cmsg $did(11).state
}
elseif ( $did == 12 ) {
; private nachricht
set %yta/settings/General/pmsg $did(12).state
}
elseif ( $did == 22 ) {
set %yta/settings/General/echo $did(22).state
}
elseif ( $did == 14 ) {
;listbox mit urls
if ( $did(14, $did(14).sel ).cstate == 1 ) {
set %yta/settings/General/urls $addtok($did(14, $did(14).sel).text, %yta/settings/General/urls, 44)
}
else {
set %yta/settings/General/urls $remtok(%yta/settings/General/urls, $did(14, $did(14).sel).text, 0, 44)
}
}
elseif ($did == 44) { ; Tab Ignorelist
; Hinzufügen
if ($len($did(43).text) > 0) {
if ( (, !isin $did(43).text) && $regex($did(43).text, /^(?:\w+:)?#?[a-zA-Z0-9:#\|]+/) ) {
set %yta/settings/IgnoreList/list $addtok($did(43).text, %yta/settings/IgnoreList/list, 44)
did -r yta_d_main 43
yta_fill_ignorelist
}
}
}
elseif ( $did == 47 ) { ; Tab Ignorelist
; Entfernen
if ( $len($did(46).seltext) > 0 ) {
set %yta/settings/IgnoreList/list $remtok(%yta/settings/IgnoreList/list, $did(46).seltext, 0,44)
did -r yta_d_main 46
didtok yta_d_main 46 44 %yta/settings/IgnoreList/list
}
}
elseif ( $did == 38 ) {
set %yta/settings/Message/echo $did(38).state
}
elseif ( $did == 18 ) {
.url https://developers.google.com/youtube/v3/getting-started
}
}
; Das Textfeld "Vorschau" mit den Inhalt aus "Nachricht" befüllen und
; Platzhalter durch Dummy-Daten ersetzen
on *:DIALOG:yta_d_main:edit:31: {
if ($len($did(31).text) > 0) {
var %t1 = publishedAt $+ $chr(7) $+ title $+ $chr(7) $+ channelTitle $+ $chr(7) $+ duration $+ $chr(7) $+favoritecount $+ $chr(7) $+ viewcount $+ $chr(7) $+ likecount $+ $chr(7) $+ dislikecount $+ $chr(7) $+ commentcount
var %t2 = 2012-10-01T15:27:35Z $+ $chr(7) $+ A very special Title $+ $chr(7) $+ TheChan Nel $+ $chr(7) $+ PT7H3M33S $+ $chr(7) $+ 60 $+ $chr(7) $+ 1250 $+ $chr(7) $+ 1000 $+ $chr(7) $+ 250 $+ $chr(7) $+ 450
; Vorschau soll auch per Echo erfolgen
if ( %yta/settings/Message/echo == 1 ) {
echo -ga $yta_replace_placeholder($did(31).text, %t1, %t2)
}
did -ri yta_d_main 33 1 $yta_replace_placeholder($did(31).text, %t1, %t2)
}
else {
did -r yta_d_main 33
}
set %yta/settings/Message/msg $did(31).text
}
; About Dialog öffnen
on *:DIALOG:yta_d_main:menu:100 {
; Diese Operation blockt die UI und das Fenster MUSS geschlossen werden
noop $dialog(yta_d_about, yta_d_about)
}
;;#
;; Helfer-Funktionen
;;#
; Liste der zu ignorierenden Ziele füllen
alias yta_fill_ignorelist {
did -r yta_d_main 46
var %i = 1
while ( %i <= $numtok(%yta/settings/IgnoreList/list, 44) ) {
var %val = $token(%yta/settings/IgnoreList/list, %i, 44)
did -a yta_d_main 46 %val
inc %i
}
}
; Wird beim Dialog-Start aufgerufen, um "Vorschau" und "Nachricht" zu befüllen
alias yta_fill_msg {
if ( $len(%yta/settings/Message/msg) > 0 ) {
did -r yta_d_main 31
did -a yta_d_main 31 %yta/settings/Message/msg
var %t1 = publishedAt $+ $chr(7) $+ title $+ $chr(7) $+ channelTitle $+ $chr(7) $+ duration $+ $chr(7) $+favoritecount $+ $chr(7) $+ viewcount $+ $chr(7) $+ likecount $+ $chr(7) $+ dislikecount $+ $chr(7) $+ commentcount
var %t2 = 2012-10-01T15:27:35Z $+ $chr(7) $+ A very special Title $+ $chr(7) $+ TheChan Nel $+ $chr(7) $+ PT7H3M33S $+ $chr(7) $+ 60 $+ $chr(7) $+ 1250 $+ $chr(7) $+ 1000 $+ $chr(7) $+ 250 $+ $chr(7) $+ 450
did -ri yta_d_main 33 1 $yta_replace_placeholder($did(31).text, %t1, %t2)
}
}
; Wird beim Dialog-Start aufgerufen, um das Feld "APIKEY" zu befüllen
alias yta_fill_apikey {
if ( $len(%yta/settings/General/apikey) > 0 ) {
did -r yta_d_main 21
did -a yta_d_main 21 %yta/settings/General/apikey
}
}
; Ersetzt im Text ($1) alle Platzhalter ($2) mit den enstprechenden Werten ($3)
; Die Funktion erwartet 3 Token
; $1 = Text in dem ersetzt werden soll
; $2 = Eine Tokenliste (Trennzeichen $chr(7)) mit Wörtern die Ersetzt werden sollen (ohne < und >)
; $3 = Eine Tokenliste (Trennzeichen $chr(7)) mit der gleichen Länge wie $2 und den entrechpenden Werten die eingesetzt werden sollen.
; Rückgabe: Der übergebene Text ($1) mit den ersetzten Platzhaltern oder bei Fehler den gleichen Text
; Beispiel: //echo -ag $yta_replace_placeholder(Der <title> ist von <channeltitle>., title $+ $chr(7) $+ channeltitle, TESTTITLE $+ $chr(7) $+ Channel Title ist Super!)
alias yta_replace_placeholder {
var %msg = $1
if ($isid && $0 == 3) {
if ( $numtok($2, 7) == $numtok($2, 7) ) {
var %i = 1
while ( %i <= $numtok($2, 7) ) {
var %key = $lower($token($2, %i, 7)), %val = $token($3, %i, 7)
if ( (%key != title) && (%key != channelTitle) ) {
var %val $yt_placeholder_format(%val)
}
noop $regsub(%msg, /< $+ %key $+ >/gi, %val, %msg)
inc %i
}
}
return %msg
}
}
; Helferfunktion die Zahlen (1000 wird zu 1 Tsd), Published-Datum (2012-10-01T15:27:35Z zu 01.10.2012) und Lauflänge (PT3D1H5M30S zu 03:01:05:30) umwandelt
; Zahlen werden nur bis Mrd umgewandelt, alles was größer ist, wird normal ausgegeben
; Zeit wird, bei Fehler und so weiter, als 00:00:00 ausgegeben
; TODO Funktion mathematisch aufarbeiten und nicht so einen Quark nutzen :P aber so lange es funktioniert?
alias yt_placeholder_format {
if ($isid && $0 == 1) {
if ( $1 isnum ) {
var %i = 3, %j = 1, %suff = Tsd.Mio.Mrd
while ( %i <= 9 ) {
var %v = $round($calc($1 / (10^%i)), 2)
if ( $len($int(%v)) <= 3 && $int(%v) > 0 ) {
return %v $token(%suff, %j, 46)
}
inc %i 3
inc %j
}
}
elseif ( $lower($left($1, 2)) == $lower(PT) ) {
var %t = $lower($mid($1, 3, $len($1)))
var %d = 00, %h = 00, %m = 00, %s = 00
while ( $len(%t) >= 1 ) {
if ( $left(%t, 1) isnum ) {
var %tmp = %tmp $+ $left(%t, 1)
}
else {
var % $+ $left(%t, 1) $iif($len(%tmp) == 1, 0) $+ %tmp
unset %tmp
}
var %t = $mid(%t, 2, $len(%t))
}
return $iif(%d != 00, %d $+ :) $+ $iif(%h != 00, %h $+ :, 00:) $+ $iif(%m != 00, %m $+ :, 00:) $+ %s
}
elseif ( $numtok($1, 84) == 2 ) {
var %date = $token($1, 1, 84)
return $token(%date, 3, 45) $+ . $+ $token(%date, 2, 45) $+ . $+ $token(%date, 1, 45)
}
}
return $1
}
; Überprüft, ob eines der angegebenen Argumente in der Ignorelist ist
; Folgende Angaben sind möglich:
; Wenn nur $1: $1 = Channel/Nickname/Server der geprüft wird
; Wenn $1 und $2: $1 = Server, $2 = Nickname/Channel der in Kombination geprüft werden soll
; Wenn $1, $2, und $3: $1 = Server, $2 = Channel und $3 = Nickname
; Rückgabe: $true wenn eins der übergebenen Argumente in der Liste gefunden wird, ansonsten $false
alias yta_is_in_ignorelist {
if ( $isid ) {
if ( $0 >= 1 ) {
var %i = 1, %1 = $lower($1), %2 = $lower($2), %3 = $lower($3)
while ( %i <= $numtok(%yta/settings/IgnoreList/list, 44) ) {
var %target = $lower($token(%yta/settings/IgnoreList/list, %i, 44))
if ( %1 $+ : == %target || %1 == %target ) {
return $true
}
elseif ( %2 != $null && ( %2 == %target || %1 $+ : $+ %2 == %target ) ) {
return $true
}
elseif ( %3 != $null && (%3 == %target || %1 $+ : $+ %3 == %target) ) {
return $true
}
inc %i
}
}
return $false
}
}
; Testet, ob in $1 der Text nach möglichen URLS geparst werden soll.
; $1 muss entweder chan oder priv sein
; Rückgabe: $true wenn parsing aktiv sein soll, ansonsten $false
alias yta_is_parsing_active {
if ( $isid ) {
if ( ($1 == chan && %yta/settings/General/cmsg == 1) || ($1 == priv && %yta/settings/General/pmsg == 1) ) {
return $true
}
return $false
}
}
; Testet, ob $1 eine URL ist die aktiv abgefragt werden soll
; Rückgabe: $true wenn sie aktiv ist, ansonsten $false
alias yta_is_active_url {
if ( $isid ) {
var %i 1
while ( %i <= $numtok(%yta/settings/General/urls, 44) ) {
if ( $1 == $token(%yta/settings/General/urls, %i, 44) ) {
return $true
}
inc %i
}
return $false
}
}
;; #
;; Konfiguration laden/speichern
;; Nur über das Dialog Event Init aufrufen!
;; #
alias yta_load_config {
var %settings/General = cmsg pmsg echo urls apikey
var %settings/Message = msg echo
var %settings/IgnoreList = list
var %i = 1
while (%i <= $var(%settings/*)) {
var %tmpk = $token($var(%settings/*, %i), 2, 47)
var %tmpv = %settings/ [ $+ [ %tmpk ] ]
var %j = 1
while (%j <= $numtok(%tmpv, 32)) {
var %item = $token(%tmpv, %j, 32)
var %val = $readini($mircdir $+ yta_settings.ini, n, %tmpk, %item)
set %yta/settings/ $+ %tmpk $+ / $+ %item $iif(%val == $chr(7), $null, %val)
inc %j
}
inc %i
}
}
alias yta_save_config {
var %i = 1
while ( %i <= $var(%yta/settings/*) ) {
var %fp = $var(%yta/settings/*, %i)
var %val = $var(%yta/settings/*, %i).value
var %key = $token(%fp, $calc($numtok(%fp, 47) - 1), 47)
var %item = $token(%fp, $numtok(%fp, 47), 47)
; Damit kein Fehler geworfen wird, representiert 7 (BEL) keinen Inhalt
writeini $mircdir $+ yta_settings.ini %key %item $iif(%val == $null, $chr(7), %val)
inc %i
}
}
;; ######################################
;; # Nachrichtenverarbeitung und Socket #
;; ######################################
;; <# Haupt-Event
; Reagiert auf Texte (Channel/Privat) die
; https?://(www)?youtu(.be|be.com) oder https?://(www)?yu2.be beinhalten
; Abbruch des Events passiert in mehreren Stufen, weil nicht Daten
; sofort vorhanden sind (z.B. der tatsächliche URL wird erst im Regex ermittelt).
;; #>
on $*:TEXT:$(/https? $+ $chr(58) $+ \/{2}(w{3}\.)?(youtu\.?be(\.com)?|yu2.be)/Si):*: {
; Überprüfen, ob überhaupt parsing erlaubt ist
if ( $chan != $null && !$yta_is_parsing_active(chan) ) {
return $false
}
elseif ( $chan == $null && !$yta_is_parsing_active(priv) ) {
return $false
}
; Wenn das bearbeiten erlaubt ist, überprüfen dass auch kein Ziel (Server, Chan, Nick) ingoriert werden soll
if ( !$yta_is_in_ignorelist($network, $iif($chan != $null, $chan, $nick), $iif($chan != $null, $nick)) ) {
; Folgendes regex soll die Video-ID suchen und das 1. Ergebnis speichern
; Den Regex kann man bestimmt schöner machen, aber er hat in meinen Tests funktioniert
var %re = https?:\/{2}(?:w{3}\.)?((?:youtu\.?be(?:\.com)?|yu2.be))\/(?=watch\?v\=([a-zA-Z0-9_-]+)|([a-zA-Z0-9_-]+))
if ( $regex(yta_re_match, $1-, / $+ %re $+ /Si) > 0 ) {
var %vid = $regml(yta_re_match, 2), %host = $regml(yta_re_match, 1)
; Host/URL kann erst ab hier geprüft werden
; Ist die URL nicht Aktiv (Checkbox im UI) dann wird das Event hier beendet
if ( !$yta_is_active_url(%host) ) {
return $false
}
; Ticks sind ms seit systemstart
var %tick $ticks
; Um Spam zu verhindern, nur alle 30 Sekunden ein Video für Chan/Nick abfragen
if ( $calc(%tick - [ % $+ yta/spamprot/ $+ [ $network ] $+ [ $iif($chan != $null, $chan, $nick) ] $+ /tick ] ) >= 30000 ) {
set %yta/spamprot/ $+ $network $+ $iif($chan != $null, $chan, $nick) $+ /tick %tick
; Spamprot und request Variablen nach 30 Sekunden entfernen
.timer $+ yta/timers/ $+ $network $+ $iif($chan != $null, $chan, $nick) 1 30 yta_request_cleanup $network $+ $iif($chan != $null, $chan, $nick)
; Socket öffnen und Informationen als mark speichern
sockopen -e yta/sockets/ $+ %tick googleapis.com 443
sockmark yta/sockets/ $+ %tick $network $+ , $+ $iif($chan != $null, $chan, $nick) $+ , $+ %vid
}
}
}
}
;; <# Socket Logik
; Im folgendem Abschnitt befindet sich die Logik für den Umgang mit den geöffneten Sockets.
; Dabei gibt es zwei Hauptevents die bearbeitet werden.
; Beim öffnen wird eine HTTP Anfrage an den googleapis Server geschickt und die Markierung vom Socket in die Request-Variable geschrieben.
; Im Lesevorgang werden die erhaltenen Daten verarbeitet, in die Request-Variable geschrieben und die Ticknummer an die Funktion yta_send_message übergeben
;; #>
on *:SOCKOPEN:yta/sockets/*: {
; Daten für das GET Request zusammen tragen
var %apikey %yta/settings/General/apikey
var %vid $token($sock($sockname, 1).mark, 3, 44)
var %tick $token($sockname, $numtok($sockname, 47), 47)
; Wenn eines von beiden nicht abgerufen werden kann, socket schließen
if ( %apikey == $null || %vid == $null) {
unset %yta/ytrequests/ $+ %tick $+ /*
sockclose $sockname
return $false
}
; GET Request zusammensetzen
var %get /youtube/v3/videos?part=snippet%2CcontentDetails%2Cstatistics $+ &id= $+ %vid $+ &key= $+ %apikey
; HTTP Anfrage senden
sockwrite -n $sockname GET %get HTTP/1.1
sockwrite -n $sockname Host: www.googleapis.com
sockwrite -n $sockname User-Agent: mSL YouTube Announcer
sockwrite -n $sockname Accept: application/json
sockwrite -n $sockname
set %yta/ytrequests/ $+ %tick $+ / $+ network $token($sock($sockname, 1).mark, 1, 44)
set %yta/ytrequests/ $+ %tick $+ / $+ dest $token($sock($sockname, 1).mark, 2, 44)
set %yta/ytrequests/ $+ %tick $+ / $+ vid $token($sock($sockname, 1).mark, 3, 44)
}
; TODO Eventlogik umschreiben, so das Hashtables verwendet werde
; Durch filtern von Elementen die ersetzt werden, ensteht ein Chaos aus IF/ELSIF Verzweigungen.
; Deswegen wäre ein Rewrite mit Hashtables vielleicht sinnvoll, um alle Elemente vom JSON zu speichern.
on *:SOCKREAD:yta/sockets/*: {
var %tick $token($sockname, $numtok($sockname, 47), 47)
var %line
sockread %line
; HTTP Status-Code abfragen und entsprechend fortfahren oder abbrechen
if ( HTTP/1.1 isin %line ) {
if ( $token(%line, 2, 32) != 200 ) {
unset %yta/ytrequests/ $+ %tick $+ /*
sockclose $sockname
return $false
}
}
elseif ( "publishedAt" isin %line ) {
var %val $token($yta_json_keyval_token(%line), 2, 7)
set %yta/ytrequests/ $+ %tick $+ / $+ publishedat %val
}
elseif ( "title" isin %line && %yta/ytrequests/ [ $+ [ %tick ] $+ /title ] == $null ) {
var %val $token($yta_json_keyval_token(%line), 2, 7)
set %yta/ytrequests/ $+ %tick $+ / $+ title %val
}
elseif ( "channeltitle" isin %line ) {
var %val $token($yta_json_keyval_token(%line), 2, 7)
set %yta/ytrequests/ $+ %tick $+ / $+ channeltitle %val
}
elseif ( "duration" isin %line ) {
var %val $token($yta_json_keyval_token(%line), 2, 7)
set %yta/ytrequests/ $+ %tick $+ / $+ duration %val
}
elseif ( "viewcount" isin %line ) {
var %val $token($yta_json_keyval_token(%line), 2, 7)
set %yta/ytrequests/ $+ %tick $+ / $+ viewcount %val
}
elseif ( "likecount" isin %line ) {
var %val $token($yta_json_keyval_token(%line), 2, 7)
set %yta/ytrequests/ $+ %tick $+ / $+ likecount %val
}
elseif ( "dislikecount" isin %line ) {
var %val $token($yta_json_keyval_token(%line), 2, 7)
set %yta/ytrequests/ $+ %tick $+ / $+ dislikecount %val
}
elseif ( "favoritecount" isin %line ) {
var %val $token($yta_json_keyval_token(%line), 2, 7)
set %yta/ytrequests/ $+ %tick $+ / $+ favoritecount %val
}
elseif ( "commentCount" isin %line ) {
; Quick and Dirty: Einfach ein Komma am Ende hinzufügen, weil sonst das Regex nicht greift
var %val $token($yta_json_keyval_token(%line $+ $chr(44)), 2, 7)
set %yta/ytrequests/ $+ %tick $+ / $+ commentcount %val
; Comment Count ist das letzte Element das interessant ist für dieses Script
sockclose $sockname
yta_send_msg %tick
}
}
; Wird ausgeführt, wenn die Gegenseite ein Socket beendet
; Entsprechend, damit sich nicht zu viele globale Variablen ansammeln, ein unset versuchen
on *:SOCKCLOSE:yta/sockets/*: {
var %tick $token($sockname, $numtok($sockname, 47), 47)
unset %yta/ytrequests/ $+ %tick $+ /*
}
;; <#
;; Helfer Funktionen und Events
;; #>
; Parst die Zeichenfolge und teilt diese in Key:Val auf (Token, Trennzeichen 7) (Quick and Dirty Version)
; Argument $1: Zeichenfolge im Format \s+"<Key>":\s"<Val>",
; Rückgabe: Key und Val als Token oder nichts bei Fehler
; TODO Regex umschreiben, so das es auch greift, wenn kein Komma am Ende ist (letzte Element in einer Liste in JSON)
alias yta_json_keyval_token {
if ( $isid ) {
if ( $regex(yta_test, $1, /^\s+"(.*?)": "(.*?)" $+ $chr(44)$/) == 1 ) {
var %key $regml(yta_test,1)
var %val $regml(yta_test,2)
return %key $+ $chr(7) $+ %val
}
return $null
}
}
; Wraper, um einfacher auf die Request-Variable zugreifen zu können
; Argument $1: Tick Nummer vom Request
; Rückgabe: Inhalt der Request-Variable oder $null
; Beispiel: echo -ga Title: $yta_request_result(<tick>).title
alias yta_request_result {
if ( $isid ) {
if ( $var(%yta/ytrequests/ [ $+ [ $1 ] $+ ] /*) > 0 ) {
return %yta/ytrequests/ [ $+ [ $1 ] $+ / $+ [ $prop ] ]
}
return $null
}
}
; Gibt die eingestellte Nachricht am Abfrageort aus oder per Echo im aktiven Fenster
; Argument $1: yta request Tick Nummer
; Die Funktion erwartet als 1. Argument den Namen der globalen Variable
; für den Request der ausgegeben werden soll
alias yta_send_msg {
var %placeholders publishedAt $+ $chr(7) $+ title $+ $chr(7) $+ channelTitle $+ $chr(7) $+ duration $+ $chr(7) $+ favoritecount
var %placeholders %placeholders $+ $chr(7) $+ viewcount $+ $chr(7) $+ likecount $+ $chr(7) $+ dislikecount $+ $chr(7) $+ commentcount
; Replace mit dem Wraper befüllen
var %replace $yta_request_result($1).publishedat $+ $chr(7) $+ $yta_request_result($1).title $+ $chr(7) $+ $yta_request_result($1).channeltitle
var %replace %replace $+ $chr(7) $+ $yta_request_result($1).duration $+ $chr(7) $+ $yta_request_result($1).favoritecount $+ $chr(7) $+ $yta_request_result($1).viewcount
var %replace %replace $+ $chr(7) $+ $yta_request_result($1).likecount $+ $chr(7) $+ $yta_request_result($1).dislikecount $+ $chr(7) $+ $yta_request_result($1).commentcount
var %dst $yta_request_result($1).dest
var %net $yta_request_result($1).network
if ( %yta/settings/General/echo == 1 ) {
echo -gf %dst $yta_replace_placeholder(%yta/settings/Message/msg, %placeholders, %replace)
}
else {
.msg %dst $yta_replace_placeholder(%yta/settings/Message/msg, %placeholders, %replace)
}
}
; Entfernt die Spamprotect Variable und Request Variable
; Spamprotect ist fest auf 30 Sekunden einprogrammiert und wenn in der Zeit keine Rückmeldung gekommen ist,
; kann auch die requests Variable verworfen werden
; Argument $1: Spamprotect Variable Identifikation
alias yta_request_cleanup {
var %tick %yta/spamprot/ [ $+ [ $1 ] $+ /tick ]
unset %yta/spamprot/ [ $+ [ $1 ] $+ /* ]
unset %yta/ytrequests/ [ $+ [ %tick ] $+ /* ]
}
; Settings in die INI schreiben, Timer und Sockets anhalten und globale Variables löschen
alias yta_uninstall {
yta_save_config
sockclose yta/sockets/*
var %i 1
while ( %i <= $timer(0) ) {
var %tname $timer(%i)
if ( yta/timers/ isin %tname ) {
.timer $+ %tname off
}
inc %i
}
unset %yta/*
echo -ag - YouTube Announcer - Das Script ist nun deaktiviert und sollte auf keine YouTube Links mehr reagieren.
}
; Wenn das Script entladen wird, uninstall ausführen
on *:UNLOAD: {
yta_uninstall
}
Expand