Revision [1022]

This is an old revision of WikiPing made by DreckFehler on 2004-08-18 17:04:52.

 

WikiPing is a mechanism similar to the weblogsUpdate.ping used by the blogger-community to promote their new posts. any wiki can contact a wikiping-server to announce changes that have been made to that wiki. the ping-server uses that pings to compile a kind of "global" recentchanges-list. for that reason the first wikiping-server which is in service now is called


the whole wikiping-specification is still beta and any suggestion how to improve this idea is welcomed!

the function-call below will stay inactive unless you have defined one or more wikiping-servers in your configs.

<? "wikiping_server" => "http://recentchanges.net/wikiping/rpc.xml", ?>


to debug a client implementation a second wikiping-server http://sandbox.recentchanges.net is available. the url to the rpc-interface is located at


this sandbox-server logs the entire xml communication into a wikipage that has the client name as page title. just visit http://sandbox.recentchanges.net/ after a ping and click onto the site name of your last ping. the page history provides a history of your pings.

to get in touch with the wikiping-server you need to implement a little xml-rpc-engine which is called at the end of the $wakka->SavePage()-function just after saving a page to the database:

<?
    if ($this->HasAccess("read", $tag, "WikiPingAgent") && $pingdata = $this->GetPingParams($this->config["wikiping_server"], $tag, $user, $note))
        $this->WikiPing($pingdata);
?>


and here is the ping-mechanism itself, which has to be added to the wakka-class:

<?
    function HTTPpost($host, $data, $contenttype="application/x-www-form-urlencoded", $maxAttempts = 5) {
        $attempt =0; $status = 300; $result = "";
        while ($status >= 300 && $status < 400 && $attempt++ <= $maxAttempts) {
            $url = parse_url($host);
            if (isset($url["path"]) == false) $url["path"] = "/";
            if (isset($url["port"]) == false) $url["port"] = 80;

            if ($socket = fsockopen ($url["host"], $url["port"], $errno, $errstr, 15)) {
                $strQuery = "POST ".$url["path"]." HTTP/1.1\n";
                $strQuery .= "Host: ".$url["host"]."\n";
                $strQuery .= "Content-Length: ".strlen($data)."\n";
                $strQuery .= "Content-Type: ".$contenttype."\n";
                $strQuery .= "Connection: close\n\n";
                $strQuery .= $data;

                // send request & get response
                fputs($socket, $strQuery);
                $bHeader = true;
                while (!feof($socket)) {
                    $strLine = trim(fgets($socket, 512));
                    if (strlen($strLine) == 0) $bHeader = false; // first empty line ends header-info
                    if ($bHeader) {
                        if (!$status) $status = $strLine;
                        if (preg_match("/^Location:\s(.*)/", $strLine, $matches)) $location = $matches[1];
                    } else $result .= trim($strLine)."\n";
                }
                fclose ($socket);
            } else $status = "999 timeout";

            if ($status) {
                if(preg_match("/(\d){3}/", $status, $matches)) $status = $matches[1];
            } else $status = 999;
            $host = $location;
        }
        if (preg_match("/^[\da-fA-F]+(.*)$/", $result, $matches)) $result = $matches[1];
        return $result;
    }
    function WikiPing($ping, $debug = false) {
        if ($ping) {
            $rpcRequest .= "<methodCall>\n";
            $rpcRequest .= "<methodName>wiki.ping</methodName>\n";
            $rpcRequest .= "<params>\n";
            $rpcRequest .= "<param>\n<value>\n<struct>\n";
            $rpcRequest .= "<member>\n<name>tag</name>\n<value>".$ping["tag"]."</value>\n</member>\n";
            $rpcRequest .= "<member>\n<name>url</name>\n<value>".$ping["taglink"]."</value>\n</member>\n";
            $rpcRequest .= "<member>\n<name>wiki</name>\n<value>".$ping["wiki"]."</value>\n</member>\n";
            if ($ping["author"]) {
                $rpcRequest .= "<member>\n<name>author</name>\n<value>".$ping["author"]."</value>\n</member>\n";
                if ($ping["authorpage"]) $rpcRequest .= "<member>\n<name>authorpage</name>\n<value>".$ping["authorpage"]."</value>\n</member>\n";
            }
            if ($ping["history"]) $rpcRequest .= "<member>\n<name>history</name>\n<value>".$ping["history"]."</value>\n</member>\n";
            if ($ping["changelog"]) $rpcRequest .= "<member>\n<name>changelog</name>\n<value>".$ping["changelog"]."</value>\n</member>\n";
            if ($ping["callback"]) $rpcRequest .= "<member>\n<name>callback</name>\n<value>".$ping["callback"]."</value>\n</member>\n";
            $rpcRequest .= "</struct>\n</value>\n</param>\n";
            $rpcRequest .= "</params>\n";
            $rpcRequest .= "</methodCall>\n";

            foreach (explode(" ", $ping["server"]) as $server) {
                $response = $this->HTTPpost($server, $rpcRequest, "text/xml");
                if ($debug) print $response;
            }
        }
    }
    function GetPingParams($server, $tag, $user, $changelog = "") {
        $ping = array();
        if ($server) {
            $ping["server"] = $server;
            if ($tag) $ping["tag"] = $tag; else return false; // set page-title
            if (!$ping["taglink"] = $this->href("", $tag)) return false; // set page-url
            if (!$ping["wiki"] = $this->config["wakka_name"]) return false; // set site-name
            $ping["history"] = $this->href("revisions", $tag); // set url to history

            if ($this->LoadUser($user)) {
                $ping["author"] = $user; // set username
                if ($this->LoadPage($user)) $ping["authorpage"] = $this->href("", $user); // set link to user page
            }
            if ($changelog) $ping["changelog"] = $changelog;
            if ($this->config["callback"]) $ping["changelog"] = $this->config["changelog"];
            return $ping;
        } else return false;
    }

?>


Testing WikiPing .... nice idea! -- JsnX
Nope.... I implemented as described above, and it didn't work. I'll have to check into it tonight when I have more time.

got the error! i didn't change the variable $this->config["mind_name"] to $this->config["wakka_name"] in the wikiping()-function (now in the getpingparams()-function). this causes the ping to be dropped, while the sitename is one of the three mandatory fields. sorry!

i have improved the ping-mechanism a bit to ease the migration to other wiki-engines. the functions httppost() and wikiping() now don't contain any stuff related to the wiki-engine. this is done completely in the function getpingparams() which returns an associative array with all nessecary parameters (or false if the parameter-record is incomplete). that should (hopefully) limit the debugging-efforts to this single function.

Testing WikiPing, take 2.....
Yup, working fine. Now, the question is, do you want me to turn this on to point to your server in the release version? Or would you prefer that it be an option that admins will have to toggle on? -- JsnX

don't ask me difficult questions! ;)

i think it's up to the wikimaster to determine how publik a wiki should be. i don't want the wikiping to become a kind of spyware. it merely should be a utility that allows to promote new wikis at the will of those who run it. it may be also helpful for someone, who runs more than one wiki to track them all at once with a "private" wikiping-server, since the config-variable can be set to any url desired. even more than one wikiping-server can be configured and the interface will ping all of 'em.

additionally i'm not sure yet, if there should be an option in the usersettings or in the editor itself that allows a user to determine wether his name should be included in a ping to address any privacy-concerns. but maybe i am thinking too german in this point ;)



DreckFehler, there seems to be a small bug with WikiPing and edit notes.

For a demonstration of the bug, look on your site at this page http://recentchanges.net/index.php?mind=RecentChanges

Now notice that it says the last comment for the sandbox was 'The apex note', but in reality, there was no comment with the last edit. You can check this by viewing the history for the sandbox....

http://wikka.jsnx.com/SandBox/history

Summary of bug: Your site seems to hold onto the previous edit comment for a page until a new edit comment is entered, regardless of how many times a page might be edited.

-- JsnX

acknowledged. same applied to the authorpage, if s/o without such a page has sent a ping. both fixed. -- DreckFehler

now it's really fixed ;) pings were dropped completely due to an sql-bug

changelog:

2004-08-14

some more words on the rpc-handler:

the handler seems to work fine with mindwiki but isn't testet with wikka. it gives the wiki server functionality which is needed for callback (the client needs to serve mind.getProfile requests. that requests asks for detailed information about a wiki, as they will be defined in the config array).

there is no chance yet to change the profile. recentchanges will only callback once, when a client provides the callback-url for the first time in it's ping. this will be the job of one or two other functions (mind.putProfile and perhaps mind.dropProfile with a subsequent ping that triggers again a callback) but this functionality has to be checked against security issues.

the integrated rpc-server will also play a central role in a concept named PlogPing. when wikiping is considered as a kind of global recentchanges list, then plog (personal log) is a global mychanges. the user should be able to define a plog server in his usersettings and thus demand the wiki to act as a client and drop a ping at the plog server specified. this allows a list, which isn't compiled for the public but for each user individually. those plogpings can be triggered by the users activity (that's the "global mychanges") by any changes to pages that this user ownes or by changes that a user has set onto a watchlist. plogpings are not only limited to page changes. it could be a comprehensive messaging system that allows anyone to use a ping-form for dropping a short note to the plog list of a user. it also may allow an user to use a textfield in the footer to send himself a reminder about an interesting page. plogping will support several types of pings to reflect these different services and distinguish them in the ploglist.

primary goal of plogping will be that an user doesn't have to check dozens of wikis for changes but has one personal plogserver (or a personal plogbox at this server as other users will have a plogbox of their own) where he can track activity on every wiki that is able to send plogpings. the rpc-server will be the part that makes recentchanges.net (and perhaps wikka) a plog server. plog clients don't need it so far. an additional function like wikiping() would do it together with changes in the user table and a modified action UserSettings. future versions will add a subscription process when a user changes the plog url. the client should ask the plog server for user preferences (and thus again will act as a client, i.e. it doesn't need the rpc-handler but may need changes directly in the wiki engine, at least in the usersettings action.

this concept was first developed by lion kimbro on OneBigSoup. i'm not sure if recentchanges.net will adopt the obs-concept exactly or if there will be it's own implementation. but in general i think this modification of wikiping will be useful.

but these things should be evaluated first and to my understanding this (especially the client stuff that will touch the wikka kernel) should not be hooked into the next few releases. in fact the complete plog-thingie is dreams of the future yet but even preparation should be done carefully.
There are 10 comments on this page. [Show comments]
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki