User:Opensource Obscure/LSL/JIRA-Helper

From Second Life Wiki
Jump to navigation Jump to search

<lsl> // JIRA helper by Moon Metty - Version 11

// This script says the title of a JIRA-issue in open chat, each time someone mentions the full URL of that jira. // When somoene mentions just the JIRA-number, the script says the full URL plus the title. // To avoid spam, calling a JIRA by number is not handled, if the full URL and title already were mentioned recently. // The script keeps a list of the last mentioned JIRAs. This first-in/first-out queue is recycled in one hour, or after a number of other JIRAs have been mentioned.

integer fifo = 12; // number of JIRAs to remember integer max_category_length = 6; // the maximum length of the alphabetical part of a jira_name string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; string no_cookie = "?os_authType=none"; // the cookie bypass list escapes = ["&", """, "'", "<", ">"]; list unescapes = ["&", "\"", "'", "<", ">"]; string url_base1 = "http://jira.secondlife.com/browse/"; string url_base2 = "https://jira.secondlife.com/browse/"; list used_issues; list http_requests; string extended_title = " - Second Life Bug Tracker ";

default {

   state_entry()
   {
       llListen(0, "", "", ""); // listen to open chat
       if (fifo) llSetTimerEvent(3600 / fifo); // the total fifo is cleared in one hour
       fifo --; // adjust for indexing
   }
   listen(integer channel, string name, key id, string message)
   {
       integer idx = llSubStringIndex(message, "-"); // look if there's a dash in the message
       while (~idx)
       {   // a (new) dash is found
           string right_string = llGetSubString(message + "d", idx + 1, -1); // copy the string to the right of the dash, "d" is a dummy to avoid index-wrapping
           integer issue_number = (integer)right_string; // convert the right part into a number
           if (issue_number > 0)
           {   // the right part is a valid number
               integer category_idx = idx - 1; // point just before the dash
               integer category_num; // counter for the length of the category-string
               while ( (~llSubStringIndex(alphabet, llToUpper(llGetSubString(message, category_idx, category_idx)))) && // it's an alphabetical character
                       (category_idx >= 0) && // don't look beyond the start of the message
                       (category_num <= max_category_length)) // don't try strings that are too long
               {
                   category_idx --; // scan backwards
                   category_num ++; 
               } 
               if ((category_num > 1) && (category_num <= max_category_length))
               {   // the criteria for a valid jira-number have been met 
                   string jira_issue = llToUpper(llGetSubString(message, category_idx + 1, idx) + (string)(issue_number)); // assemble the title in a string
                   integer url_given; // presume a full url wasn't given
                   if (llGetSubString(message, category_idx - 33, category_idx) == url_base1) url_given = TRUE; // http url given
                   if (llGetSubString(message, category_idx - 34, category_idx) == url_base2) url_given = TRUE; // https url given
                   if (url_given || (llListFindList(used_issues, [jira_issue]) == -1)) 
                       // call a page when the full url was given, or the JIRA-number wasn't mentioned yet
                       http_requests +=    [llHTTPRequest(url_base1 + jira_issue + no_cookie, [], ""),  // request the page, add the handle to the list
                                           jira_issue, // add the issue-name
                                           url_given, // add the flag to see if the full url was given
                                           llGetAgentSize(id) != ZERO_VECTOR]; // add the flag to see if it was an agent
               }
           }
           message = right_string; // discard the left part of the message
           idx = llSubStringIndex(message, "-"); // look if there's another dash in the message
       }
   } // end listen
   http_response(key request_id, integer status, list metadata, string body)
   {
       integer request = llListFindList(http_requests, [request_id]); // search the request
       if (~request)
       {   // a page was called
           if (status == 200) 
           {   // a page was found
               string title = llList2String(llParseString2List(body, ["<title>", "</title>"], []), 1); // extract the title
               string jira_issue = llList2String(http_requests, request + 1); // store jira_issue for easy access
               if (~llSubStringIndex(title, jira_issue))
               {   // the jira_issue is found in the title, so the jira_issue exists, and can be accessed publicly
                   title = llGetSubString(title, 0, llSubStringIndex(title, extended_title)); // cut off the unnecessary part
                   integer idx = llGetListLength(escapes); // unescape the title
                   while (idx --) title = llDumpList2String(llParseString2List(title, [llList2String(escapes, idx)], []), llList2String(unescapes, idx));
                   if (llList2Integer(http_requests, request + 3)) 
                   {   // don't react to talking objects, only avatars
                       if (llList2Integer(http_requests, request + 2)) llSay(0, title); // say only the title if the full url was given
                       else llSay(0, url_base1 + jira_issue + "\n" + title); // say the url and the title
                       llMessageLinked(LINK_THIS, 0, jira_issue, NULL_KEY); // send the jira_issue to another script
                   }
                   if (fifo >= 0) used_issues = [jira_issue] + llDeleteSubList(used_issues, fifo, fifo); // add this to the list of used issues
               }
           }
           http_requests = llDeleteSubList(http_requests, request, request + 3); // remove this entry from the http-requests
       }
   } // end http_response
   timer() {used_issues = [FALSE] + llDeleteSubList(used_issues, fifo, fifo);} // push a dummy on the list of used issues
   on_rez(integer param) {llResetScript();}

} </lsl>

Version 05

-Davy Linden added a line so the helper only responds to avatars

Version 06

-Moved Davy's line deeper into the code, so issues that were mentioned by an object are treated as "used".

Version 07

-Give a short error message when JIRA is down, or when it returns an abnormal status.

Version 08

-Improved title extraction. After Sue changed the extended title, the jira-helper didn't know where to cut off the string. Sue changed the extended title back, and we made plans to allow a change later on.

Version 09

-Removed categories ARVD, EVT, MOZ, MU and CT. -Added category STORM -Added code to support 5-letter categories. -Added a new extended title, so the website can be changed later on. (" - Second Life Jira ") -Added "?os_authType=guest" to the URL, so the LSL-http request doesn't fail on Jira4.

Version 10

-An atlassian change for the cookie bypass: "?os_authType=guest" is now "?os_authType=none"

Version 11

-Removed all categories, the script now bluntly tries to access everything in the format "letters dash number". The number of letters can be 2 to 6. If a page doesn't exist, or isn't accessible by the public, the script fails silently. This big change suggested by Oz gives the script (and the jira) more work to do. But ultimately, it makes the jira-helper more robust as a tool.

-Added a linked message which sends a string containing the jira_issue to other scripts in the prim. This can be used to trigger a sound, for example.

Version 12

Sue decided the extended title should be " - Second Life Bug Tracker ". Removed the old extended title.