Skip to content

Instantly share code, notes, and snippets.

@antonyfairport
Last active October 27, 2019 14:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antonyfairport/1303437 to your computer and use it in GitHub Desktop.
Save antonyfairport/1303437 to your computer and use it in GitHub Desktop.
Grid Status Notifier
//////////////////////////////////////////////////////////////////////
// Grid status notifier, by Antony Fairport
//
// Inspired by a similar script by Dermot Core / DigitaL Scribe.
// The original script didn't quite work as I'd like, so I took the
// core idea and made it work as I do like.
//
// To use simply create a prim and drop this inside it. Every 5mins
// the grid status is checked and, if it changes, an IM is sent to you
// Also, if anyone touches the prim the latest status (no matter if
// it has changed or not) will be spoken in local.
//////////////////////////////////////////////////////////////////////
// Constants
string STATUS_FEED = "http://status.secondlifegrid.net/history.rss";
integer CHECK_EVERY = 300;
//////////////////////////////////////////////////////////////////////
// Globals.
key g_kRequest;
integer g_bSpecialRequest;
string g_sLastItem = "";
//////////////////////////////////////////////////////////////////////
// Refresh the grid status.
RefreshStatus( integer bSpecialRequest )
{
// Was this a special request by someone close by?
g_bSpecialRequest = bSpecialRequest;
// Kick off the request.
g_kRequest = llHTTPRequest( STATUS_FEED, [], "" );
}
//////////////////////////////////////////////////////////////////////
// String search and replace.
// Via http://wiki.secondlife.com/wiki/Library_Combined_Library#str_replace
string StrReplace( string str, string search, string replace )
{
return llDumpList2String( llParseStringKeepNulls( ( str = "" ) + str, [ search ], [] ), replace );
}
//////////////////////////////////////////////////////////////////////
// Find the first element in the given XML document.
string GetFirstElement( string sTag, string sData )
{
integer iStart = llSubStringIndex( sData, "<" + sTag + ">" ) + llStringLength( sTag ) + 2;
integer iEnd = llSubStringIndex( sData, "</" + sTag + ">" ) - 1;
if ( ( iStart != -1 ) && ( iEnd != -1 ) )
{
return llGetSubString( sData, iStart, iEnd );
}
else
{
return "";
}
}
//////////////////////////////////////////////////////////////////////
// Find the first <item> in the given document.
string GetFirstItem( string sData )
{
return GetFirstElement( "item", sData );
}
//////////////////////////////////////////////////////////////////////
// Find the first <title> in the given document.
string GetTitle( string sItem )
{
return GetFirstElement( "title", sItem );
}
//////////////////////////////////////////////////////////////////////
// Find the first <time> in the given document.
string GetTime( string sItem )
{
return GetFirstElement( "pubDate", sItem );
}
//////////////////////////////////////////////////////////////////////
// Find the first <link> in the given document.
string GetLink( string sItem )
{
return GetFirstElement( "link", sItem );
}
//////////////////////////////////////////////////////////////////////
// Find the first <description> in the given document.
string GetDescription( string sItem )
{
return GetFirstElement( "description", sItem );
}
//////////////////////////////////////////////////////////////////////
// Have a stab at removing any <![CDATA[[...]]> markers.
string CleanCDATA( string s )
{
// Does it look like it's wrapped as CDATA?
if ( ( llGetSubString( s, 0, 9 ) == "<![CDATA[[" ) && ( llGetSubString( s, -3, -1 ) == "]]>" ) )
{
// Yup, top and tail it.
return llGetSubString( s, 9, -4 );
}
else
{
// No, just go with that we've got.
return s;
}
}
//////////////////////////////////////////////////////////////////////
// Strip HTML tags from the given string.
// Via http://wiki.secondlife.com/wiki/RemoveHTMLTags
string StripTags( string s )
{
integer bInTag;
string sStripped;
integer i;
integer iMax = llStringLength( s );
do
{
string sChar = llGetSubString( s, i, i );
if ( sChar == "<" )
{
bInTag = TRUE;
}
if ( !bInTag )
{
sStripped += sChar;
}
if ( sChar == ">" )
{
bInTag = FALSE;
}
}
while ( ++i < iMax );
return sStripped;
}
//////////////////////////////////////////////////////////////////////
// Some final cleanup hacks.
string CleanupHack( string s )
{
// This is a bit horrible, but given LSL lacks the normal tools for
// dealing with HTML...
s = StrReplace( s, "&#8217;", "'" );
s = StrReplace( s, "&lt;", "<" );
s = StrReplace( s, "&gt;", ">" );
s = StrReplace( s, "&apos;", "'" );
s = StrReplace( s, "</p>", "\n\n");
return StripTags( s );
}
//////////////////////////////////////////////////////////////////////
// Format the given grid status.
string FormatStatus( string sItem )
{
return
"Title: " + GetTitle( sItem ) + "\n" +
"Time: " + GetTime( sItem ) + "\n" +
"Link: " + GetLink( sItem ) + "\n" +
"Description:\n" + CleanupHack( CleanCDATA( GetDescription( sItem ) ) );
}
//////////////////////////////////////////////////////////////////////
// Default state.
default
{
//////////////////////////////////////////////////////////////////
// Set things up on state entry.
state_entry()
{
// Set up the timer.
llSetTimerEvent( CHECK_EVERY );
// Do an initial check.
RefreshStatus( FALSE );
}
//////////////////////////////////////////////////////////////////
// Recact to a timer event.
timer()
{
// Refresh the status.
RefreshStatus( FALSE );
}
//////////////////////////////////////////////////////////////////
// Recact to a touch event.
touch_start( integer total_number )
{
// Refresh the status.
RefreshStatus( TRUE );
}
//////////////////////////////////////////////////////////////////
// Handle a HTTP response.
http_response( key request_id, integer status, list metadata, string body )
{
// If the response is ours...
if ( request_id == g_kRequest )
{
// Pull out the first item in the feed.
string sItem = GetFirstItem( body );
// If we got something
if ( sItem != "" )
{
// If this was a special request...
if ( g_bSpecialRequest )
{
// ...just say what we've got in local.
llSay( 0, "Current Grid Status:\n" + FormatStatus( sItem ) );
}
else
{
// ...otherwise this is a timer check. In which case
// we check to see if the latest status is different from
// the last time we looked.
if ( sItem != g_sLastItem )
{
// It is. Remember it.
g_sLastItem = sItem;
// And IM the owner it.
llInstantMessage( llGetOwner(), "New grid status message detected:\n\n" + FormatStatus( sItem ) );
}
}
}
else
{
// Have a moan.
llSay( 0, "Problem getting grid status information." );
}
}
}
}
@RayZopf
Copy link

RayZopf commented Dec 17, 2016

ty for the script :)
modified it and replaced the older no longer nicely working one

@freddii
Copy link

freddii commented Oct 27, 2019

For Opensim just remove in line 40 ' ( str = "" ) +' then it works like a charm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment