Difference between revisions of "YouTube parser"

From Scriptwiki
Jump to: navigation, search
m (updated second regex to support ...&v= youtube links)
(Bugfix: script didn't produce output on unrated videos)
Line 5: Line 5:
 
  /*
 
  /*
 
  ********************************************************************************************************
 
  ********************************************************************************************************
  *  
+
  *
 
  *  youtube.mrc by Jay2k1 @ QuakeNet, 2013
 
  *  youtube.mrc by Jay2k1 @ QuakeNet, 2013
  *  
+
  *
 
  *  Whenever a youtube link is posted in the channels #foo or #bar, this script retrieves the video's details
 
  *  Whenever a youtube link is posted in the channels #foo or #bar, this script retrieves the video's details
 
  *  from the youtube API and post them to the channel. It looks like this:
 
  *  from the youtube API and post them to the channel. It looks like this:
  *  
+
  *
 
  *  <Jay2k1> http://www.youtube.com/watch?v=oHg5SJYRHA0
 
  *  <Jay2k1> http://www.youtube.com/watch?v=oHg5SJYRHA0
 
  *  <Bot> 'RickRoll' by cotter548, 00:03:34, 68213084 views, rating: 87% (259236/38751)
 
  *  <Bot> 'RickRoll' by cotter548, 00:03:34, 68213084 views, rating: 87% (259236/38751)
  *  
+
  *
 
  *********************************************************************************************************
 
  *********************************************************************************************************
 
  */
 
  */
 
   
 
   
 
  ; on text event: regex check for messages containing youtube.com or youtu.be, match the URL
 
  ; on text event: regex check for messages containing youtube.com or youtu.be, match the URL
  on $*:TEXT:/(youtu\.be\/.*?(\s|$)|youtube\.com\/.*?(\s|$))/:#foo,#bar:{
+
  on $*:TEXT:/(youtu\.be\/.*?(\s|$)|youtube\.com\/.*?(\s|$))/:#pda:{
 
   
 
   
 
   ; use another regex to extract the video ID from the matched URL
 
   ; use another regex to extract the video ID from the matched URL
Line 24: Line 24:
 
   
 
   
 
   ; call the youtube script with the channel and the video ID, if there is one
 
   ; call the youtube script with the channel and the video ID, if there is one
   youtube [[$$]][[$regml|regml]](2) [[$chan_(remote)|$chan]]
+
   youtube [[$$]][[regml]](2) [[$chan_(remote)|$chan]]
 
  }
 
  }
 
   
 
   
Line 35: Line 35:
 
   [[sockopen]] %sock gdata.youtube.com 80
 
   [[sockopen]] %sock gdata.youtube.com 80
 
   ; store video ID and channel in socket mark
 
   ; store video ID and channel in socket mark
   [[sockmark]] %sock [[$1-]]
+
   [[sockmark]] %sock [[$1-|$1-]]
 
  }
 
  }
 
   
 
   
Line 52: Line 52:
 
   
 
   
 
   ; receive answer to the request into a variable
 
   ; receive answer to the request into a variable
   [[Local_Variables|var]] %data | [[Sockread|sockread]] %data
+
   [[Local_Variables|var]] %t = [[$sockname]], %data
 +
  [[Sockread|sockread]] %data
 
   
 
   
 
   ; while there's bytes in the sockread buffer...
 
   ; while there's bytes in the sockread buffer...
Line 58: Line 59:
 
   
 
   
 
     ; extract things of interest out of the source code into a hash table
 
     ; extract things of interest out of the source code into a hash table
     [[If-Then-Else|if]] (*<title>*</title>* iswm %data) { [[hadd]] -m [[$sockname]] title [[$regsubex]](%data,/(.*<title>|</title>.*)/g,) }
+
     [[If-Then-Else|if]] (*<title>*</title>* iswm %data) { ylog found title! | [[hadd]] -m %t title [[$regsubex]](%data,/(.*<title>|</title>.*)/g,) }
     [[If-Then-Else|if]] (*<yt:duration seconds='*'/>* iswm %data) { [[hadd]] -m [[$sockname]] dur [[$duration]]([[$regsubex]](%data,/(.*seconds='|'/>.*)/g,),3) }
+
     [[If-Then-Else|if]] (*<yt:duration seconds='*'/>* iswm %data) { ylog found duration! | [[hadd]] -m %t dur [[$duration]]([[$regsubex]](%data,/(.*seconds='|'/>.*)/g,),3) }
     [[If-Then-Else|if]] (*<yt:statistics favoriteCount='*' viewCount='*'/>* iswm %data) { [[hadd]] -m [[$sockname]] views [[$regsubex]](%data,/(.*viewCount='|'/>)/g,) }
+
     [[If-Then-Else|if]] (*<yt:statistics favoriteCount='*' viewCount='*'/>* iswm %data) { ylog found views! | [[hadd]] -m %t views [[$regsubex]](%data,/(.*viewCount='|'/>)/g,) }
     [[If-Then-Else|if]] (*<yt:rating numDislikes='*' numLikes='*'/>* iswm %data) { [[hadd]] -m [[$sockname]] likes [[$regsubex]](%data,/(.*numLikes='|'/>.*)/g,) | [[hadd]] -m [[$sockname]] dislikes [[$regsubex]](%data,/(.*numDislikes='|'.*)/g,) }
+
     [[If-Then-Else|if]] (*<yt:rating numDislikes='*' numLikes='*'/>* iswm %data) { ylog found rating! | [[hadd]] -m %t likes [[$regsubex]](%data,/(.*numLikes='|'/>.*)/g,) | [[hadd]] -m %t dislikes [[$regsubex]](%data,/(.*numDislikes='|'.*)/g,) }
     [[If-Then-Else|if]] (*<name>*</name>* iswm %data) { [[hadd]] -m [[$sockname]] uploader [[$regsubex]](%data,/(.*<name>|</name>.*)/g,) }
+
     [[If-Then-Else|if]] (*<name>*</name>* iswm %data) { ylog found uploader name! | [[hadd]] -m %t uploader [[$regsubex]](%data,/(.*<name>|</name>.*)/g,) }
     [[If-Then-Else|if]] (*<yt:uploaded>*</yt:uploaded>* iswm %data) { [[hadd]] -m [[$sockname]] uploaded [[$left]]([[$regsubex]](%data,/(.*<yt:uploaded>|</yt:uploaded>.*)/g,),10) }
+
     [[If-Then-Else|if]] (*<yt:uploaded>*</yt:uploaded>* iswm %data) { ylog found upload date! | [[hadd]] -m %t uploaded [[$left]]([[$regsubex]](%data,/(.*<yt:uploaded>|</yt:uploaded>.*)/g,),10) }
 +
    [[If-Then-Else|if]] (*accessControl action='rate' permission='denied'* iswm %data)  { ylog found rating disabled | [[hadd]] -m %t rating disabled or no votes }
 +
 +
    ; the </entry> tag marks the end of the data.
 +
    [[If-Then-Else|if]] (*</entry>* iswm %data) || ([[$hget]](%t,0).item == 7)  || (([[$hget]](%t,0).item == 7) && ([[$hget]](%t,rating) == disabled)) {
 +
      [[Local_Variables|var]] %ytmsg = ' [[DollarPlus|$+]] [[$hget]](%t,title) [[DollarPlus|$+]] ' by [[$hget]](%t,uploader) [[DollarPlus|$+]] [[$chr]](44) [[$hget]](%t,dur) [[DollarPlus|$+]] [[$chr]](44) [[$hget]](%t,views) views
 +
      [[Local_Variables|var]] %ytmsg = %ytmsg [[DollarPlus|$+]] , [[$iif]]([[$hget]](%t,likes),rating: [[$round]]([[$calc]]([[$hget]](%t,likes) / ([[$hget]](%t,likes) + [[$hget]](%t,dislikes)) * 100),1) [[DollarPlus|$+]] % ( [[DollarPlus|$+]] [[$hget]](%t,likes) [[DollarPlus|$+]] / [[DollarPlus|$+]] [[$hget]](%t,dislikes) [[DollarPlus|$+]] ),rating disabled or not rated yet)
 +
      [[Local_Variables|var]] %ytmsg = [[$replace]](%ytmsg,&nbsp;,[[$chr]](160),&quot;,",&#39;,',&lt;,<,&gt;,>,&amp;,&, &pound;,[[$chr]](163), &euro;, [[$chr]](8364), &copy;, [[$chr]](169), &trade, [[$chr]](8482), &reg;, [[$chr]](174))                 
 +
      [[msg]] [[$gettok]]([[$sock]](%t).mark,2,32) %ytmsg
 
   
 
   
    ; if we have seven items in our hash table, we have all data we need
 
    [[If-Then-Else|if]] [[$hget]]([[$sockname]],0).item == 7 {
 
      [[Local_Variables|var]] %t = [[$sockname]]
 
      [[msg]] [[$gettok]]([[$sock]]([[$sockname]]).mark,2,32) ' [[DollarPlus|$+]] [[$hget]](%t,title) [[DollarPlus|$+]] ' by [[$hget]](%t,uploader) [[DollarPlus|$+]] , [[$hget]](%t,dur) [[DollarPlus|$+]] , [[$hget]](%t,views) views, rating: [[$round]]([[$calc]]([[$hget]](%t,likes) / ([[$hget]](%t,likes) + [[$hget]](%t,dislikes)) * 100),1) [[DollarPlus|$+]] % ( [[DollarPlus|$+]] [[$hget]](%t,likes) [[DollarPlus|$+]] / [[DollarPlus|$+]] [[$hget]](%t,dislikes) [[DollarPlus|$+]] )
 
 
       [[sockclose]] %t
 
       [[sockclose]] %t
 
       [[hfree]] %t
 
       [[hfree]] %t
Line 76: Line 81:
 
   }
 
   }
 
  }
 
  }
 +
 +
  
 
[[Category:Script Archive]]
 
[[Category:Script Archive]]
  
 
{{Author|Jay2k1}}
 
{{Author|Jay2k1}}

Revision as of 14:45, 24 September 2014

As the description says, this script retrieves information about youtube videos from the YouTube API and posts them to the channel whenever a youtube link is posted. You can install it by opening the script editor (Alt+R), creating a new script file (File -> New) and then copy paste the script into it.

Note: Make sure to replace the channels (#foo,#bar) in the on TEXT event line with the channels you want the script to be active in.

/*
********************************************************************************************************
*
*  youtube.mrc by Jay2k1 @ QuakeNet, 2013
*
*  Whenever a youtube link is posted in the channels #foo or #bar, this script retrieves the video's details
*  from the youtube API and post them to the channel. It looks like this:
*
*  <Jay2k1> http://www.youtube.com/watch?v=oHg5SJYRHA0
*  <Bot> 'RickRoll' by cotter548, 00:03:34, 68213084 views, rating: 87% (259236/38751)
*
*********************************************************************************************************
*/

; on text event: regex check for messages containing youtube.com or youtu.be, match the URL
on $*:TEXT:/(youtu\.be\/.*?(\s|$)|youtube\.com\/.*?(\s|$))/:#pda:{

  ; use another regex to extract the video ID from the matched URL
  noop $regex($regml(1),/(\?v=|&v=|\/\d\/|\/embed\/|\/v\/|\.be\/)([a-zA-Z0-9\-\_]{11})/)

  ; call the youtube script with the channel and the video ID, if there is one
  youtube $$regml(2) $chan
}

; alias youtube: opens a socket connection to youtube
; expects: youtube video ID as $1, #channel as $2
; returns: -
alias -l youtube {
  ; create a unique socket name to allow for multiple connections at a time
  var %sock = youtube. $+ $ticks
  sockopen %sock gdata.youtube.com 80
  ; store video ID and channel in socket mark
  sockmark %sock $1-
}

on *:SOCKOPEN:youtube.*:{
  ; obligatory error check
  if $sockerr { return }

  ; send our request
  sockwrite -n $sockname GET /feeds/mobile/videos/ $+ $gettok($sock($sockname).mark,1,32) $+ ?v=2&prettyprint=true HTTP/1.1
  sockwrite -n $sockname Host: $sock($sockname).addr
  sockwrite -n $sockname $crlf
}

on *:SOCKREAD:youtube.*:{
  if $sockerr { return }

  ; receive answer to the request into a variable
  var %t = $sockname, %data
  sockread %data

  ; while there's bytes in the sockread buffer...
  while $sockbr {

    ; extract things of interest out of the source code into a hash table
    if (*<title>*</title>* iswm %data) { ylog found title! | hadd -m %t title $regsubex(%data,/(.*<title>|</title>.*)/g,) }
    if (*<yt:duration seconds='*'/>* iswm %data) { ylog found duration! | hadd -m %t dur $duration($regsubex(%data,/(.*seconds='|'/>.*)/g,),3) }
    if (*<yt:statistics favoriteCount='*' viewCount='*'/>* iswm %data) { ylog found views! | hadd -m %t views $regsubex(%data,/(.*viewCount='|'/>)/g,) }
    if (*<yt:rating numDislikes='*' numLikes='*'/>* iswm %data) { ylog found rating! | hadd -m %t likes $regsubex(%data,/(.*numLikes='|'/>.*)/g,) | hadd -m %t dislikes $regsubex(%data,/(.*numDislikes='|'.*)/g,) }
    if (*<name>*</name>* iswm %data) { ylog found uploader name! | hadd -m %t uploader $regsubex(%data,/(.*<name>|</name>.*)/g,) }
    if (*<yt:uploaded>*</yt:uploaded>* iswm %data) { ylog found upload date! | hadd -m %t uploaded $left($regsubex(%data,/(.*<yt:uploaded>|</yt:uploaded>.*)/g,),10) }
    if (*accessControl action='rate' permission='denied'* iswm %data)  { ylog found rating disabled | hadd -m %t rating disabled or no votes }

    ; the </entry> tag marks the end of the data.
    if (*</entry>* iswm %data) || ($hget(%t,0).item == 7)  || (($hget(%t,0).item == 7) && ($hget(%t,rating) == disabled)) {
      var %ytmsg = ' $+ $hget(%t,title) $+ ' by $hget(%t,uploader) $+ $chr(44) $hget(%t,dur) $+ $chr(44) $hget(%t,views) views
      var %ytmsg = %ytmsg $+ , $iif($hget(%t,likes),rating: $round($calc($hget(%t,likes) / ($hget(%t,likes) + $hget(%t,dislikes)) * 100),1) $+ % ( $+ $hget(%t,likes) $+ / $+ $hget(%t,dislikes) $+ ),rating disabled or not rated yet)
      var %ytmsg = $replace(%ytmsg, ,$chr(160),",",',',<,<,>,>,&,&, £,$chr(163), €, $chr(8364), ©, $chr(169), &trade, $chr(8482), ®, $chr(174))                  
      msg $gettok($sock(%t).mark,2,32) %ytmsg

      sockclose %t
      hfree %t
      return
    }
    sockread %data
  }
}
Contributed by Jay2k1