URL-logger

From Scriptwiki
Revision as of 12:08, 22 June 2013 by Cail (talk | contribs) (Added <nowiki>'s for links.)

Jump to: navigation, search

A picture is worth 1000 words:
Screenshot 1: Colored links
Screenshot 2: Links search

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
; 
; URL-logger with colored and underlined links by Cail at Quakenet -> #help.script
;
; $urlc -alias will color and underline links from the input, and log them into a file for later searching
; Tested and works on mIRC 6.2 and above (i recommend using >6.21 for $regsubex to work correctly)
; 
; This script uses spopup.dll (OPTIONAL! you only need this if you want a new popup with info and some new features.),
; to replace mirc's builtin url-popup
; spopup.dll is made by Saturn, and you can get it from http://www.xise.nl/mirc/
; NOTE! Depeding on how your mIRC is set up, your working path might be mirc's root dir, or Users/AppData folder
; For example in Windows 7 the AppData folder would be: C:\Users\HappyUser\AppData\Roaming\mIRC
; Note this when placing the .dll somewhere and not giving full path in the script.
;
; Formats recognized links like:
;   - "http://google.com" -> http://google.com
;   - url('www.google.com'); -> www.google.com
;   - (www.google.com/ahihi(kiaa)) -> www.google.com/ahihi(kiaa)
;   
;   And some more cleanups, and adds 'http://' in front of 'www.' for storing.
;   so that www.google.com and <nowiki>http://www.google.com are treated as a same link, and stored only once
;
; Uses 3 different colors for coloring links:
;   1) new link - not found from the file
;   2) opened link - is found from the file, and you have opened it via mirc
;   3) old link - is found from the file, but you haven't opened it
;
; Fetches title of youtube video's
;   - Gets title of the video and stores it into the links.db (for searching)
;   - Echo's the title under the link in chat
;   - Hold down ctrl key when pressing enter if you post a link, to /msg the title into the channel
;   - Fill %sendYTtitleChans with channels separated by spaces (eg. %sendYTtitleChans #chan1 #chan2) to automatically
;     send the title into the channel when ever a youtube link is posted.
;
; Thanks to:
;   - Saturn for the spopup.dll
;   - Msmo for the cleanup regex
;
; 
; UPDATE 14/06/2013: Added support for fetching and storing title from youtube links
;                     - fetches youtube video's title, stores it into the logfile, echoes the title on the channel
;                     - hold down ctrl key when pressing enter, when you post a link, to send the title as /msg to the channel (overrides %sendYTtitleChans variable)
;                     - set %sendYTtitleChans variable for channels you want to /msg the title automatically when a link is posted
;                       (for example: %sendYTtitleChans #channel1 #channel2 #channel3) would send the title into the channel on those 3 channel
; UPDATE 17/06/2007: Updated regex (fixed 'www.someurl.com/something's_here' to show correctly), added a timer with 200ms delay
;                    into the on keyup event (to prevent filtering while writing fast).
; UPDATE 23/03/2007: Changed on keydown -> on keyup, much more efficient now, won't need so much checks, and allows you to
;                    insert text infront/into the middle of the line.
; UPDATE 29/01/2007: added a regex into on keydown event to halt the script if something else than \S was pressed
;                    (now holding down shift/alt/ctrl doesn't affect it), and optimized the on keydown event a bit.
; UPDATE 18/01/2007: added on input event for the search (optional), rearranged the dll-stuff into same place, 
;                    fixed a bug that didn't color some opened links without http:// (only www.)
;                    fixed if (!$exists($spopupdll)) { return } from linkpopup to 'halt' (now shows the original popup)
;                    added a $db alias to return the filename, users can choose their own path/filename for the file.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 

; $db returns the name of the database file, change this to whatever you want
alias -l db { return $qt(links.db) }

; alias to open the links window, and filter all of the urls into it
alias urllog { 
 ; if the window isn't open, create it, -ea to create an editbox and activate the window
 ; filter will copy the lines from the file by a matchtext (* = everything), -fw = from File to Window, and -p = wrap the text
 if (!$window(@links)) { 
   window -ea @links 
   filter -fwp $db @links * 
 } 

 ; else the window is already open, so activate it
 else { window -a @links } 
}

; alias to return colorcodes for the script, change these values to whatever you like.
; new, old and opened are for echo text, log_link and log_info are for the @links window
alias -l url_color {
 if ($1 == new) { return 12 }
 elseif ($1 == old) { return 6 }
 elseif ($1 == opened) { return 10 }
 elseif ($1 == log_link) { return 10 }
 elseif ($1 == log_info) { return 14 }
}

; $clr alias to return $chr(3) and formatted color code, ie. $clr(3) == $+($chr(3),03) == ctrl+k 03
alias -l clr { if ($isid) { return $+($chr(3),$base($1,10,10,2)) $+ $iif($2,$+($chr(44),$base($2,10,10,2)),) } }

; this alias handles checking the input for links, looping through tokens (words in this case), and replacing links with colored ones
alias urlc {
 if (!$isid) { return }
 var %string = $1-

 ; if the line even has links, useless to loop through it if there are no links
 if ($regex(%string,/(?:\b(?:www.?\.|https?:\/\/|s?ftp:\/\/).)/i)) {

   ; so the line has links, loop through tokens then
   var %x = 1 
   while (%x <= $numtok(%string,32)) { 

     ; we'll assign the current token into a variable %tok, for easier use later
     ; and we'll run it through $url_parse, and assign the result into a variable %url 
     ; (it'll be checked if it's a 'valid' url, and useless stuff be removed around it, if it's not an url the alias will return $null
     var %tok = $gettok(%string,%x,32)
     var %url = $url_parse(%tok)

     ; check if there is an url in variable %url
     if (%url) {

       ; $url_log will take care of storing the url into a database file, and return appropriate color (in $1) to use in coloring the link
       ; also returns the linenumber of newly added link (in $2) if we want to store the title for it
       ; and if we already have the title in the log, return that too in %titleLine
       var %indb = $url_log(%url)
       var %linkColor = $gettok(%indb,1,32)
       var %titleLine = $gettok(%indb,2-,32)

       ; now we color and underline the url and assign it into %newurl, (%indb will be holding the color code number)
       ; then we replace the url part of the token, so that from "url('www.something.com');" only the "www.something.com" part will be colored and underlined
       var %newurl = $+($clr(%linkColor),$chr(31),%url,$chr(31),$clr)
       var %newurl = $replace(%tok,%url,%newurl)

       ; and finally, we put the modified token back to the original string
       %string = $puttok(%string,%newurl,%x,32)

       ; this part is for checking if it's a youtube link, and initiates the fetching of the video's title
       ; this can be commented out or removed if you don't want this functionality
       ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; OPTIONAL: GET TITLE
       if (*youtube* iswm %url) || (*youtu.be* iswm %url) {
         getTitle youtube %url $chan %titleLine
       }
       ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;        
     }
     inc %x 
   }
 }

 ; modified or not, return the string
 return %string
}

; alias to trim the given url, returns $null if input isn't an url
; big thanks to Msmo on Quakenet for this regex
alias -l url_parse {
 var %p = /(?:^|[][()<>{}'"\s])((?:(?:irc|s?ftp|https?:)\/\/|www\d*\.)[^\s./]+\.(?:\[\S*?]|\(\S*?\)|\{\S*?}|[^][()<>{}'"\s]|['"](?!\s|$|[()\[\]<>]))++)/iS
 noop $regex($1,%p)
 return $regml(1)
}

; alias to store the given url into database file, and return color according to whether it's new, opened, or unopened in database
alias -l url_log {
 ; this first $iif is to append "http://" in front of "www.", so "www.google.com" and "http://www.google.com" will be a same link, and not to be written twice
 ; we'll assign the target channel/query into variable %t
 ; the $read will search the database file for the given url  
 var %url = $iif(www* iswm $1,$+(http://,$1),$1)
 var %t = $iif($left($target,1) != $chr(35),query,$target)
 var %isOld = $read($db,w,$+(*,$chr(31),%url,$chr(31),*))

 ; if %isOld is empty (the link wasn't found from the file), write it in there and return color of "new link" & the line number the link was added to
 if (!%isOld) { 
   write $db $asctime(yyyy.mm.dd HH:nn:ss) $+($clr($url_color(log_link)),$chr(31),%url,$chr(31),$clr()) $+($clr($url_color(log_info)),$iif($nick,$nick,$me),@,%t,$clr()) 
   return $url_color(new) $lines($db)
 }

 ; otherwise, if the link was found, check if it has been opened via mirc (4th word will be !), return color of "opened link"
 elseif ($gettok(%isOld,4,32) == !) { 
   return $url_color(opened) __old %isOld
 }

 ; and if none of above, it's in the database, but you haven't opened it, return color of "old link"
 else { 
   return $url_color(old) __old %isOld
 }
}

; this on keydown event triggers every time you press a key in @links window, 
; and filters the database file into the window with the text in editbox
; so, performs a new search everytime you write something in that window, i like this kind of search, but you can make it with on input
; if you wish to use search with on input (searches when you press enter), disable #onKEYsearch -group (change 'on' -> 'off')

#onKEYsearch on
on *:KEYUP:@links:*:{
 ; filter with the content of editbox
 ; timer to give a little delay for the filter (not filtering if writing fast), change the 200 (in milliseconds) to
 ; a bit higher value, if you're a slower writer.
 .timerURL -m 1 200 filter -cpfw $db @links $+(*,$editbox(@links),*)
}
#onKEYsearch end

; on input search for the @links window, if you want to use this instead of the on keydown, enable #onINPUTsearch -group (change 'off' -> 'on')
#onINPUTsearch off
on *:INPUT:@links: {
 filter -cpfw $db @links $+(*,$1-,*)
}
#onINPUTsearch end

; on hotlink to trigger on links, this first one is for doubleclick
on *$:HOTLINK:/((www.?\.|https?:\/\/|ftp:\/\/).)/i:*:{ 
 ; clean up the triggered url with $url_parse and append "http://" in front of "www." 
 ; read the url info from database file, and if it doesn't have '!' as fourth token, add the '!' in there and write it back
 ; then open the url with url -n %url (change this, if you have your own alias for opening urls)
 var %url = $url_parse($1)
 var %url = $iif(www* iswm %url,$+(http://,%url),%url)
 var %oldurl = $read($db,w,$+(*,$chr(31),%url,$chr(31),*))

 if ($gettok(%oldurl,4,32) != !) { write $+(-l,$readn) $db $instok(%oldurl,!,4,32) }
 url -n %url 
}

; this second on hotlink is for the right click, shows the popup
on ^*$:HOTLINK:/((www.?\.|https?:\/\/|ftp:\/\/).)/i:*:{ 
 ; check if the spopup.dll file is in the right place, if not, halt so it'll show the default popup
 if (!$exists($spopupdll)) { halt }

 ; check mouse position for popup to show in the right place (this part is from chanlinks.mrc by Saturn)
 if ($mouse.key & 16) { set -eu60 %cl.coords $mouse.x $mouse.y | popup_url $url_parse($1) }
 elseif (%cl.coords == $mouse.x $mouse.y) { popup_url $url_parse($1) }
 else unset %cl.coords
}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; here starts the functionality with the spopup.dll
; you won't need this part if you don't want to use the dll
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


; the path to spopup.dll
alias -l spopupdll { return $qt(spopup.dll) }

; the new popup to replace the original one with a dll
alias -l popup_url {

 ; strip colors etc. from given url ($1), and find the url info from the database file
 var %url = $strip($1)
 var %url2 = $read($db,w,$+(*,$chr(31),%url,$chr(31),*))

 ; assign the info variables
 var %datetime = $strip($gettok(%url2,1-2,32))
 var %nickchan = $strip($gettok(%url2,4-,32))
 var %nickchan = $iif($left(%nickchan,1) == !,$right(%nickchan,-2),%nickchan)

 ; show the popup
 dll $spopupdll clear
 dll $spopupdll add 1 0 0 open
 dll $spopupdll add 2 0 0 copy url
 dll $spopupdll add 3 0 0 copy info
 dll $spopupdll add 4 0 0 %datetime %nickchan

 ; show additional "remove item" if you are in the linklist
 if ($active == @links) {
   dll $spopupdll add 5 0 0 -
   dll $spopupdll add 6 0 16 remove url from db
   dll $spopupdll add 7 1 0 ok
 }

 ; assign the popup selection into a variable
 var %c =  $dll($spopupdll,popup,$mouse.dx $mouse.dy 1)

 ; check what the selection was
 ; these are the ID's from the popup, 2) copy url 3) copy info 4) the info (echo's the info into active) 7) remove link (only in @links window) 
 if (%c == 1) { url -n %url }
 elseif (%c == 2) { clipboard %url }
 elseif (%c == 3) { clipboard %datetime %nickchan %url }
 elseif (%c == 4) { echo -agi30 url info: %datetime %nickchan %url }
 elseif (%c == 7) { write $+(-dl,$readn) $db }
}


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; this section is for the title fetching (youtube only at this time)
; you won't need this part if you don't want to use the title fetching funcitonality
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; this is the output handler alias that gets called from different parts of the script, depending on if we're dealing with an old title or new
alias titleOutput {
 ; format the title, we'll need timers here to output text _after_ the link has been processed and is echoed
 var %title = $replace($gettok($remtok($iif($4 == __new,$1-,$5-),!,1,32),5-,32),|,$!chr(124))

 ; %inputSendLink will be true if you pressed enter holding down ctrl key, and it will message the title to the channel
 if (%inputSendLink) { 
   .timerYTTitle $+ _msg_ $+ $2 -m 1 1 msg $3 Youtube: %title 
 }

 ; checking if the channel where the link was posted, is in %sendYTtitleChans variable, if so, sends the title to the channel
 else if ($istok(%sendYTtitleChans,$3,32)) { 
   .timerYTTitle $+ _msg_ $+ $2 -m 1 1 msg $3 Youtube: %title 
 }

 ; echo the title of the link in the channel for you to see it
 .timerYTTitle $+ _echo_ $+ $2 -m 1 1 echo -t $3 Youtube: %title 

 unset %inputSendLink
 unset %ytchan 
 unset %yturl
}

; a helper alias to clean HTML entities from the titles
alias stripHTMLEntities { 
 return $replace($1, ,$chr(160),",",<,<,>,>,&,&, $&
   £, $chr(163), €, $chr(8364), ©, $chr(169), &trade, $chr(8482), ®, $chr(174))
}

; alias to handle different possible sources for the title (youtube only for now)
alias getTitle {
 ; first we check if we already have the title in the log, if so, use a quick timer to echo it out after the link
 if ($4 == __old) { 
   titleOutput $1-
   return 
 }

 ; get the title from youtube links
 else if ($1 == youtube) {
   ; initialise the variables, 
   ; %yturl = link to youtube 
   ; %ytchan = the channel where the link was posted on
   ; %logFileLine = line in the DB file where the link was originally written, so we can update it with the title

   set %yturl $2
   set %ytchan $3
   set %logFileLine $4

   sockclose yttitle
   sockopen yttitle youtube.com 80
 }
}

; socket events for youtube - sockopen
on *:sockopen:yttitle:{ 
 ; add "watch?v=" to the link if it's not there (for youtu.be links)
 var %uri = $gettok(%yturl,3,47)
 var %uri = $iif($left(%uri,5) == watch,%uri,$+(watch?v=,%uri))
 var %ytt sockwrite -nt $sockname
 %ytt GET / $+ %uri HTTP/1.1
 %ytt Host: www.youtube.com
 %ytt Content-Type: application/x-www-form-urlencoded
 %ytt User-Agent: WhereBeMeGrog
 %ytt Connection: Close
 %ytt $crlf
} 

; socket events for youtube - sockread
on *:sockread:yttitle:{ 
 var %t
 sockread %t 

 ; finding the title inside the HTML
 if (*<meta name="title"* iswm %t) { 
   var %title = $stripHTMLEntities($gettok(%t,-2,34))

   ; if the %logFileLine is true (is a number), then update that line with the youtube title
   if (%logFileLine) {
     var %oldurl = $read($db,%logFileLine)
     write $+(-l,$readn) $db %oldurl %title
     unset %logFileLine      
   }

   ; pass the chan and the title to the output handler alias
   titleOutput youtube %yturl %ytchan __new %title
 }
}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; the rest of the script is a part of my how to make your own theme, and is only for an example usage of $urlc()
; basically you just need to run a line through $urlc() to color the links and log them
; you can add this into whatever event you like, ie. var %line = $urlc($1-) | echo %line
; this example also holds the if ($ctrlenter) { set %inputSendLink 1 } part, which is used in the title fetcher
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


on *:INPUT:*: {
 ; we will check that ctrl wasn't pressed while pressing enter, and that it's not a command
 if ($left($1,1) === $readini(mirc.ini,text,commandchar)) && (!$ctrlenter) { return }

 ; check if ctrl was pressed while pressing enter, and store it in a variable (for sending title to the channel in case of a youtube link)
 unset %inputSendLink
 if ($ctrlenter) { set %inputSendLink 1 }

 ; halt the default actions
 haltdef

 ; we'll put the line into a variable, using $urlc() to store & color links if there are any
 var %line = $urlc($1-)

 ; here is the part what we send as msg, we want to send $1- and not the modified variable
 .msg $target $1-

 ; then we have the echo
 echo $color(own text) -at $+(<,$iif($chan,$nick($chan,$me).pnick,$me),>) %line 
}

on ^*:TEXT:*:#: {
 ; halt the default actions and assign $1- into a variable, and run it through $urlc() to color the links and log them
 haltdef
 var %line = $urlc($1-)

 ; echo the text into a right channel, -m highlights the switchbar button with "message color", -t adds timestamp
 echo $color(normal) -mt $chan $+(<,$nick($chan,$nick).pnick,>) %line
} 

on ^*:TEXT:*:?: {
 ; halt default actions, and set $1- into a variable, and run it through $urlc()
 haltdef
 var %line = $urlc($1-) 

 ; echo the text into a right query 
 echo $color(normal) -mt $nick $+(<,$nick,>) %line
}
Contributed by Cail