Difference between revisions of "User:Void Singer/Red Tea"
Void Singer (talk | contribs) m (transition message) |
Void Singer (talk | contribs) (v0.3 Upgrade) |
||
Line 7: | Line 7: | ||
|title=Red Tea | |title=Red Tea | ||
|content= | |content= | ||
=== What is it? === | === What is it? === | ||
Red Tea is an open source | Red Tea is an open source File Service custom built for [[User:Void Singer/Teacup|Teacup/Saucer]] | ||
=== How does it work? === | === How does it work? === | ||
When Red Tea starts, it looks for any notecards in the prim, reads them, converting and wrapping any notecards | When Red Tea starts, it looks for any notecards in the prim, reads them, converting and wrapping any notecards with names ending with {{HoverText|".tsp"|Teacup Server Page}}, then storing them in memory, waiting for a request from the Teacup server. If the number of notecards changes it waits 3 seconds then restarts. | ||
=== Format Requirments? === | === Format Requirments? === | ||
Red Tea reads a modified html page from a notecard | Red Tea reads a modified html page from a notecard | ||
* For html content, the notecard name should end with ".tsp" | * For html content, the notecard name should end with {{HoverText|".tsp"|Teacup Server Page}} | ||
* For html content, the notecard contents are limited to what's valid ''inside'' a normal html "body" tag. | * For html content, the notecard contents are limited to what's valid ''inside'' a normal html "body" tag. | ||
* no more than 255 bytes per line in the notecard (this is an LSL limitation) | * no more than 255 bytes per line in the notecard (this is an LSL limitation) | ||
:[[User:Void Singer/Red_Tea#Return_to_Void_Singers_user_page|Return to top]] | |||
}} | |||
... | {{void-box | ||
|title=Quick Start | |||
|content= | |||
So you don't want to read a bunch of tech babble, you just want to make a website in a prim right? Well I can sympathize so here are some (mostly) easy steps to get you up and running fast... | |||
# Rez a box and name it something creative, like "My website"#Sample_Index.tsp | |||
# Copy the text in the grey box below [[User:Void Singer/Teacup#teacup.js|Code: teacup.js]] into a notecard named "teacup.js", save it, and drop it in your rezzed box | |||
#* You May want to Edit this file to your liking first... You can ''add'' most valid javascript functions that do not rely on body onload behavior. | |||
# Copy the text in the grey box below [[User:Void Singer/Teacup#teacup.css|Code: teacup.css]] into a notecard named "teacup.css", save it, and drop it in your rezzed box | |||
#* You May want to Edit this file to your liking first... You can use any valid css. | |||
# Copy the text in the grey box below [[User:Void Singer/Red_Tea#Sample_Index.tsp|Code: Sample Index.tsp]] into a notecard named "index.tsp", save it, and drop it in your rezzed box | |||
#* You May want to Edit this file to your liking first... You can use any html that is valid inside of a body tag. | |||
# Copy the text in the grey box below [[User:Void Singer/Red_Tea#Sample_Page1.tsp|Code: Sample Page1.js]] into a notecard named "page1.tsp", save it, and drop it in your rezzed box | |||
#* You May want to Edit this file to your liking first... You can use any html that is valid inside of a body tag. | |||
# Copy the text in the grey box below [[User:Void Singer/Red_Tea#Red_Tea|Code: Red Tea]] into a script named "Red Tea v0.3", save it, and drop it in your rezzed box | |||
# Go [[User:Void Singer/Teacup#Quick_Start|here]] and start at step 2... | |||
}} | }} | ||
Line 28: | Line 39: | ||
|title=Code | |title=Code | ||
|content= | |content= | ||
<lsl>/*( Red Tea v0. | === Red Tea === | ||
---- | |||
* Save in a script named "Red Tea v0.3" | |||
<lsl>/*( Red Tea v0.3 )*/ | |||
//-- Master Handling lists | //-- Master Handling lists | ||
Line 62: | Line 76: | ||
changed( integer vBitChg ){ | changed( integer vBitChg ){ | ||
if (CHANGED_INVENTORY & vBitChg){ | if (CHANGED_INVENTORY & vBitChg){ | ||
//-- when inventory changes, | //-- when inventory changes, only restart if the notecard count changed | ||
llSetTimerEvent( 3.0 ); | if (llGetInventoryNumber( INVENTORY_NOTECARD ) != (gLstNom != [])){ | ||
llSetTimerEvent( 3.0 ); | |||
} | |||
} | } | ||
} | } | ||
Line 79: | Line 95: | ||
gLstTxt += [(gStrTmp = "") + gStrTmp]; //-- save it | gLstTxt += [(gStrTmp = "") + gStrTmp]; //-- save it | ||
llWhisper( 0, gStrNcd + " successfully loaded"); | llWhisper( 0, gStrNcd + " successfully loaded"); | ||
llMessageLinked( LINK_SET, 22, gStrNcd, NULL_KEY ); | |||
if ((integer)(vStrDta = (string)(gIntCap - llGetFreeMemory())) > gIntBfr){ | if ((integer)(vStrDta = (string)(gIntCap - llGetFreeMemory())) > gIntBfr){ | ||
gIntBfr = (integer)vStrDta; //-- adjust buffer if needed | gIntBfr = (integer)vStrDta; //-- adjust buffer if needed | ||
Line 99: | Line 116: | ||
//-- tweak for javascript wrapper compatibility | //-- tweak for javascript wrapper compatibility | ||
vStrDta = llDumpList2String( llParseStringKeepNulls( vStrDta, ["\\"], [] ), "\\\\" ); | vStrDta = llDumpList2String( llParseStringKeepNulls( vStrDta, ["\\"], [] ), "\\\\" ); | ||
vStrDta = llDumpList2String( llParseStringKeepNulls( vStrDta, ["'"], [] ), "\\'" ); | vStrDta = llDumpList2String( llParseStringKeepNulls( vStrDta, ["'"], [] ), "\\'" ) + "\\n"; | ||
}else{ | |||
vStrDta += "\n"; | |||
} | } | ||
gStrTmp += vStrDta | gStrTmp += vStrDta; //-- accumulate to variable | ||
if ((integer)(vStrDta = (string)(gIntCap - llGetFreeMemory())) > gIntBfr){ | if ((integer)(vStrDta = (string)(gIntCap - llGetFreeMemory())) > gIntBfr){ | ||
gIntBfr = (integer)vStrDta; //-- adjust buffer if needed | gIntBfr = (integer)vStrDta; //-- adjust buffer if needed | ||
Line 120: | Line 139: | ||
link_message( integer vIntSrc, integer vIntDta, string vStrDta, key vKeyDta ){ | link_message( integer vIntSrc, integer vIntDta, string vStrDta, key vKeyDta ){ | ||
if (418 == vIntDta | if (vKeyDta){ //-- valid key? | ||
if (418 == vIntDta){ //-- server request? | |||
if (~vIntDta = llListFindList( gLstNom, [vStrDta] )){ //-- do we have that? | |||
llMessageLinked( vIntSrc, 200, llList2String( gLstTxt, vIntDta ), vKeyDta ); | |||
} | |||
} | } | ||
} | }//-- we serve pages fast, so we don't report loaded pages on server startup message and instead rely on lazy detection | ||
} | } | ||
} | } | ||
Line 135: | Line 154: | ||
/*// All usages must contain a plain text copy of the previous 2 lines. //*/ | /*// All usages must contain a plain text copy of the previous 2 lines. //*/ | ||
/*//-- --//*/</lsl> | /*//-- --//*/</lsl> | ||
^ [[User:Void Singer/Teacup#Return_to_Void_Singers_user_page|Return to top]] | |||
=== Sample Index.tsp === | |||
---- | |||
* Save in a notecard named "index.tsp" | |||
<nowiki><h1>This is a sample Index Page</h1> | |||
<p>would you like to <a href="page1.tsp">go to page 1</a>?</nowiki> | |||
^ [[User:Void Singer/Teacup#Return_to_Void_Singers_user_page|Return to top]] | |||
=== Sample Page1.tsp === | |||
---- | |||
* Save in a notecard named "page1.tsp" | |||
<nowiki><h1>This is a sample linked page</h1> | |||
<p>would you like to <a href="index.tsp">go to the index</a>?</nowiki> | |||
:[[User:Void Singer/Teacup#Return_to_Void_Singers_user_page|Return to top]] | :[[User:Void Singer/Teacup#Return_to_Void_Singers_user_page|Return to top]] | ||
}} | }} | ||
Line 142: | Line 175: | ||
|content= | |content= | ||
=== Compatible Servers and Extensions === | === Compatible Servers and Extensions === | ||
[[User:Void_Singer/Teacup|Teacup]] - Server front end | [[User:Void_Singer/Teacup|Teacup/Saucer]] - Server front end | ||
=== Known Bugs === | === Known Bugs === | ||
* Extra line break inserted at the end of every file | ---- | ||
* Extra line break inserted at the end of every {{HoverText|".tsp"|Teacup Server Page}} or text file | |||
* If the server request a file that has a notecard, before that notecard is finished loading, a 200 "Success" response will be generated and an empty file will be served. | * If the server request a file that has a notecard, before that notecard is finished loading, a 200 "Success" response will be generated and an empty file will be served. | ||
* Loading large files before small ones may lock them out if the buffer limit is reached. Try to read small files first. (they are read in alphabetic order) | * Loading large files before small ones may lock them out if the buffer limit is reached. Try to read small files first. (they are read in alphabetic order) | ||
=== Planned Upgrades === | === Planned Upgrades === | ||
* | ---- | ||
* None really, the intent is to be an example. other "flavors" can use different methods. but it may get minor updates as time passes | |||
* <s>"Red Tea" is going to be transitioned to "Saucer", once saucer is complete, the name "Red Tea" will be release for other developers to use.</s> | |||
** Originally this made sense, but upon further consideration, there still needs to be a simple basic File Service system until others are developed. | |||
=== ChangeLog / Old Versions === | |||
---- | |||
* v0.3 | |||
** No longer sends 404 messages of it's own | |||
** No longer restarts on every inventory change, only if the notecard count changes from what it has already read. | |||
* [https://wiki.secondlife.com/w/index.php?title=User:Void_Singer/Red_Tea&oldid=1140507 v0.2] | |||
** Initial Public Release | |||
=== NOTE TO WIKI EDITORS === | === NOTE TO WIKI EDITORS === | ||
---- | |||
I have kept this page as a sub page of my user page to denote that it should NOT be edited except to correct errors, add confirmed bugs, or add related resources.<br> | I have kept this page as a sub page of my user page to denote that it should NOT be edited except to correct errors, add confirmed bugs, or add related resources.<br> | ||
The intent is to ensure executive control is in one person's hands to retain a cohesive vision of it's development.<br> | The intent is to ensure executive control is in one person's hands to retain a cohesive vision of it's development.<br> | ||
If you have an improvement suggestion, or request, please use the [ | If you have an improvement suggestion, or request, please use the [https://wiki.secondlife.com/w/index.php?title=User_talk:Void_Singer/Red_Tea&action=edit§ion=new discussion] page. | ||
:[[User:Void Singer/Teacup#Return_to_Void_Singers_user_page|Return to top]] | :[[User:Void Singer/Teacup#Return_to_Void_Singers_user_page|Return to top]] | ||
}} | }} | ||
Line 160: | Line 207: | ||
|title=Questions or Comments? | |title=Questions or Comments? | ||
|content= | |content= | ||
Feel free to leave me a note on the [ | Feel free to leave me a note on the [https://wiki.secondlife.com/w/index.php?title=User_talk:Void_Singer/Red_Tea&action=edit§ion=new discussion] page. | ||
}} | }} |
Revision as of 10:19, 19 April 2011
Red Tea
What is it?
Red Tea is an open source File Service custom built for Teacup/Saucer
How does it work?
When Red Tea starts, it looks for any notecards in the prim, reads them, converting and wrapping any notecards with names ending with ".tsp", then storing them in memory, waiting for a request from the Teacup server. If the number of notecards changes it waits 3 seconds then restarts.
Format Requirments?
Red Tea reads a modified html page from a notecard
- For html content, the notecard name should end with ".tsp"
- For html content, the notecard contents are limited to what's valid inside a normal html "body" tag.
- no more than 255 bytes per line in the notecard (this is an LSL limitation)
Quick Start
So you don't want to read a bunch of tech babble, you just want to make a website in a prim right? Well I can sympathize so here are some (mostly) easy steps to get you up and running fast...
- Rez a box and name it something creative, like "My website"#Sample_Index.tsp
- Copy the text in the grey box below Code: teacup.js into a notecard named "teacup.js", save it, and drop it in your rezzed box
- You May want to Edit this file to your liking first... You can add most valid javascript functions that do not rely on body onload behavior.
- Copy the text in the grey box below Code: teacup.css into a notecard named "teacup.css", save it, and drop it in your rezzed box
- You May want to Edit this file to your liking first... You can use any valid css.
- Copy the text in the grey box below Code: Sample Index.tsp into a notecard named "index.tsp", save it, and drop it in your rezzed box
- You May want to Edit this file to your liking first... You can use any html that is valid inside of a body tag.
- Copy the text in the grey box below Code: Sample Page1.js into a notecard named "page1.tsp", save it, and drop it in your rezzed box
- You May want to Edit this file to your liking first... You can use any html that is valid inside of a body tag.
- Copy the text in the grey box below Code: Red Tea into a script named "Red Tea v0.3", save it, and drop it in your rezzed box
- Go here and start at step 2...
Code
Red Tea
- Save in a script named "Red Tea v0.3"
<lsl>/*( Red Tea v0.3 )*/
//-- Master Handling lists list gLstNom; list gLstTxt;
//-- These track memory while loading integer gIntCap; integer gIntBfr;
//-- these handle the notecard loading key gKeyQry; string gStrNcd; integer gIntNcd; string gStrTmp;
default{
state_entry(){ //-- grab all possible notecard names if (gIntCap = llGetInventoryNumber( INVENTORY_NOTECARD )){ llWhisper( 0, "Attempting to load " + (string)gIntCap + " notecards" ); do{ gLstNom += [llGetInventoryName( INVENTORY_NOTECARD, gIntNcd )]; }while (++gIntNcd < gIntCap); //-- work on the firs one. gKeyQry = llGetNotecardLine( gStrNcd = llList2String( gLstNom, 0 ), gIntNcd = 0 ); gIntCap = llGetFreeMemory(); }else{ llWhisper( 0, "No content to load" ); } } changed( integer vBitChg ){ if (CHANGED_INVENTORY & vBitChg){ //-- when inventory changes, only restart if the notecard count changed if (llGetInventoryNumber( INVENTORY_NOTECARD ) != (gLstNom != [])){ llSetTimerEvent( 3.0 ); } } } timer(){ llResetScript(); } dataserver( key vKeyQID, string vStrDta ){ if (gKeyQry == vKeyQID){ //-- is this our dataserver event? if (EOF == vStrDta){ //-- did we finish the notecard? if (~llSubStringIndex( gStrNcd, ".tsp" )){ //-- is this a html page? gStrTmp = "vTea='" + gStrTmp + "';"; //-- wrap it } gLstTxt += [(gStrTmp = "") + gStrTmp]; //-- save it llWhisper( 0, gStrNcd + " successfully loaded"); llMessageLinked( LINK_SET, 22, gStrNcd, NULL_KEY ); if ((integer)(vStrDta = (string)(gIntCap - llGetFreeMemory())) > gIntBfr){ gIntBfr = (integer)vStrDta; //-- adjust buffer if needed } //-- test if we have more cards to read and room to spare if ((gIntNcd = -~llListFindList( gLstNom, [gStrNcd] )) < (gLstNom != []) && (gIntCap = llGetFreeMemory()) > gIntBfr){ gKeyQry = llGetNotecardLine( gStrNcd = llList2String( gLstNom, gIntNcd ), gIntNcd = 0 ); //-- get next card }else{ //-- out of cards or space gStrTmp = gKeyQry = ""; //-- clear vars //-- save totals and set conditional failure message if ((gIntCap = (gLstNom != [])) > (gIntNcd = (gLstTxt != []))){ gStrNcd = "\nFailed to read " + gStrNcd; }else{ gStrNcd = gStrTmp; }//-- report load llWhisper( 0, "Loaded " + (string)gIntNcd + " of " + (string)gIntCap + " pages" + (gStrNcd = "") + gStrNcd + "\n~" + (string)(llGetFreeMemory() - gIntBfr) + " bytes free" ); } }else{ //-- notecard read if (~llSubStringIndex( gStrNcd, ".tsp" )){ //-- is this a html page? //-- tweak for javascript wrapper compatibility vStrDta = llDumpList2String( llParseStringKeepNulls( vStrDta, ["\\"], [] ), "\\\\" ); vStrDta = llDumpList2String( llParseStringKeepNulls( vStrDta, ["'"], [] ), "\\'" ) + "\\n"; }else{ vStrDta += "\n"; } gStrTmp += vStrDta; //-- accumulate to variable if ((integer)(vStrDta = (string)(gIntCap - llGetFreeMemory())) > gIntBfr){ gIntBfr = (integer)vStrDta; //-- adjust buffer if needed } if ((gIntCap >> 1) > gIntBfr){ //-- test free space against buffer gKeyQry = llGetNotecardLine( gStrNcd, ++gIntNcd ); //-- get next line }else{ //-- our saftey cap was exceeded, stop and report what we have gLstNom = llDeleteSubList( gLstNom, gIntNcd, -1 ); gIntCap = (gLstNom != []); gIntNcd = (gLstTxt != []); gStrTmp = gKeyQry = ""; llWhisper( 0, "Loaded " + (string)gIntNcd + " of " + (string)gIntCap + " page(s)\nFailed while reading " + gStrNcd + "\n~" + (string)(llGetFreeMemory() - gIntBfr) + " bytes free" ); } } } } link_message( integer vIntSrc, integer vIntDta, string vStrDta, key vKeyDta ){ if (vKeyDta){ //-- valid key? if (418 == vIntDta){ //-- server request? if (~vIntDta = llListFindList( gLstNom, [vStrDta] )){ //-- do we have that? llMessageLinked( vIntSrc, 200, llList2String( gLstTxt, vIntDta ), vKeyDta ); } } }//-- we serve pages fast, so we don't report loaded pages on server startup message and instead rely on lazy detection }
} /*//-- License Text --//*/ /*// Free to copy, use, modify, distribute, or sell, with attribution. //*/ /*// (C)2011 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ] //*/ /*// Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ] //*/ /*// All usages must contain a plain text copy of the previous 2 lines. //*/ /*//-- --//*/</lsl> ^ Return to top
Sample Index.tsp
- Save in a notecard named "index.tsp"
<h1>This is a sample Index Page</h1> <p>would you like to <a href="page1.tsp">go to page 1</a>?
Sample Page1.tsp
- Save in a notecard named "page1.tsp"
<h1>This is a sample linked page</h1> <p>would you like to <a href="index.tsp">go to the index</a>?
Notes
Compatible Servers and Extensions
Teacup/Saucer - Server front end
Known Bugs
- Extra line break inserted at the end of every ".tsp" or text file
- If the server request a file that has a notecard, before that notecard is finished loading, a 200 "Success" response will be generated and an empty file will be served.
- Loading large files before small ones may lock them out if the buffer limit is reached. Try to read small files first. (they are read in alphabetic order)
Planned Upgrades
- None really, the intent is to be an example. other "flavors" can use different methods. but it may get minor updates as time passes
"Red Tea" is going to be transitioned to "Saucer", once saucer is complete, the name "Red Tea" will be release for other developers to use.- Originally this made sense, but upon further consideration, there still needs to be a simple basic File Service system until others are developed.
ChangeLog / Old Versions
- v0.3
- No longer sends 404 messages of it's own
- No longer restarts on every inventory change, only if the notecard count changes from what it has already read.
- v0.2
- Initial Public Release
NOTE TO WIKI EDITORS
I have kept this page as a sub page of my user page to denote that it should NOT be edited except to correct errors, add confirmed bugs, or add related resources.
The intent is to ensure executive control is in one person's hands to retain a cohesive vision of it's development.
If you have an improvement suggestion, or request, please use the discussion page.