config.options.chkHttpReadOnly = false;\n
!Creating a group member\n\nBefore a group can be joined the group member has to be created. The following example shows how a group member can be created:\n\n{{{\nInitializer init = new Initializer();\ninit.GroupAddress = "224.100.0.1";\ninit.GroupPort = 9050;\ninit.GroupName = "group1"\ninit.ListenerAddress = "127.0.0.1";\ninit.ListenerPort = 9011;\ninit.MemberName = "ernie";\n\nGroupMember gm = new GroupMember( init );\n}}}\n\nFirst of all a Initializer object has to be created. The Initializer object encapsulates following data:\n\n* Group address: The IP address of the multicast group the group member belongs to.\n* Group port: The port number of the multicast group the group member belongs to.\n* Group name: A human readable description of the group.\n* Listener address: The IP address the group member listens for incoming requests.\n* Listener port: The port number the group member listens for incoming requests.\n* Member name: The name of the group member.\n\nAll data must be set. If one of these is not set the group member can not be created.
[[GROF#]]
* Using GROF#\n** [[Creating a group member]]\n** [[Joining the group]]\n** [[Leaving the group]]\n** [[Sending messages]]\n** [[Receiving messages]]\n* Design of GROF#\n** [[Overview]]\n** [[The protocol stack]]\n** [[The UDP membership protocol]]\n
The //GROF# Console// is a tool located in the //bin// directory of the release (//grof.exe//) which gives the user the possibility to test the basic functionalities of //GROF#// without any programming.\nWhen //grof.exe// starts it creates and starts a group member by joining the specified group.\nFor usage the //grof.exe// file has to be called with following parameters:\n* group name\n* member name\n* multicast IP address\n* multicast port\n* IP address of machine where the .exe is running\n* port number of the group member process\n\n[img[http://farm1.static.flickr.com/135/333691380_d298ff4ac9_o.gif]]\n\nImmediately after starting the //grof.exe// the received messages of the //JOIN// process are printed out.\nThe prompt '>' tells the user that commands can be entered. The //help// command informs the user about all possible commands.\nFor further testing start another //GROF# Console// and see what happens:\n{{{\ngrof.exe group bert 224.100.0.1 9050 127.0.0.1 9012\n}}}\n
GROF# stands for ''G''roup ''O''riented ''F''ramework for C''#''. It provides a flexible and extensible API written in C# which allows processes of a group to communicate with each other.\n\nThe Framework provides following basic features:\n\n* Joining a group\n* Leaving a group\n* Sending messages to group members\n\nTry following example:\n\n{{{\nusing System;\nusing System.Diagnostics;\nusing System.Threading;\n\nusing grof;\n\npublic class TestGrof\n{ \n public TestGrof()\n {\n\n Initializer init = new Initializer();\n init.GroupAddress = "224.100.0.1";\n init.GroupName = "group";\n init.GroupPort = 9050;\n init.ListenerAddress = "127.0.0.1";\n init.ListenerPort = 9011;\n init.MemberName = "ernie";\n \n GroupMember member1 = new GroupMember( init );\n \n init = new Initializer();\n init.GroupAddress = "224.100.0.1";\n init.GroupName = "group";\n init.GroupPort = 9050;\n init.ListenerAddress = "127.0.0.1";\n init.ListenerPort = 9012;\n init.MemberName = "bert";\n \n GroupMember member2 = new GroupMember( init );\n \n this.member1.SetMessageReceiver( new MessageReceivedDelegate( this.Received ) );\n this.member2.SetMessageReceiver( new MessageReceivedDelegate( this.Received ) );\n \n this.member1.JoinGroup(); \n this.member2.JoinGroup();\n \n \n Thread.Sleep( 10000 ); \n }\n \n public void Received( Message msg )\n {\n Console.WriteLine( "message received: " + msg );\n }\n \n public static void Main( string[] args )\n {\n new TestGrof();\n } \n}\n\n}}}
To get started with this blank TiddlyWiki, you'll need to modify the following tiddlers:\n* SiteTitle & SiteSubtitle: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)\n* MainMenu: The menu (usually on the left)\n* DefaultTiddlers: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened\nYou'll also need to enter your username for signing your edits: <<option txtUserName>>
[[GROF#]]
After creating the group member\n{{{\n...\nGroupMember gm = new GroupMember( init );\n}}}\n\nthe group can be joined:\n{{{\ngm.JoinGroup();\n}}}\nAfter {{{JoinGroup}}} was called the group member sends a UDP multicast message of type JOIN to the multicast group (defined with {{{Initializer}}} object). If the group has no group members yet, only the group member which wants to join receives the JOIN message (message 1 in diagram). Each group member (in this case only one) answers the JOIN message with a ALIVE message (message 2).\n\nMessages hold information about the sender of the message, such like IP address and port number the sender listens for incoming messages. Everytime when a group member receives a JOIN or ALIVE message it reads the IP address and the port number of the sender and caches them. Consequently each member builds an internally registry about living group members.\n\nIf a second group member joins the group it sends also a JOIN message like first group member. Both group members receive the JOIN message (message calls 3 and 5) and each group member sends an ALIVE message to all group members it knows.\n\n[img[http://static.flickr.com/141/321948323_676fe77060_o.gif]]
For leaving the group \n{{{\ngm.LeaveGroup();\n}}}\nhas to be called.\nThe group member sends a LEAVE message to all group member it knows. When a group member receives a LEAVE message it removes the group member from its internal cache in order that the left group member receives no further messages.\nAfter a group member left the group it is able to join the group again.\n\n[img[http://static.flickr.com/142/325749247_0d262cc5f9_o.gif]]
/***\n|''Name:''|LegacyStrikeThroughPlugin|\n|''Description:''|Support for legacy (pre 2.1) strike through formatting|\n|''Version:''|1.0.1|\n|''Date:''|Jul 21, 2006|\n|''Source:''|http://www.tiddlywiki.com/#LegacyStrikeThroughPlugin|\n|''Author:''|MartinBudden (mjbudden (at) gmail (dot) com)|\n|''License:''|[[BSD open source license]]|\n|''CoreVersion:''|2.1.0|\n|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|\n\n***/\n\n//{{{\n\n// Ensure that the LegacyStrikeThrough Plugin is only installed once.\nif(!version.extensions.LegacyStrikeThroughPlugin)\n {\n version.extensions.LegacyStrikeThroughPlugin = true;\n\nconfig.formatters.push(\n{\n name: "legacyStrikeByChar",\n match: "==",\n termRegExp: /(==)/mg,\n element: "strike",\n handler: config.formatterHelpers.createElementAndWikify\n});\n\n} // end of "install only once"\n//}}}\n
* [[The Spread Toolkit|http://www.spread.org/index.html]]\n* [[JGroups|http://www.jgroups.org/javagroupsnew/docs/index.html]]\n* [[GCT|http://www.smartlab.cis.strath.ac.uk/Projects/GCTProject/GCTProject.html]]
[img[netzwerk|http://static.flickr.com/127/321287594_baa38787f6_o.gif]]\n[[Home|GROF#]]\n[[Documentation|Documentation]]\n[[GROF Console|GROF Console]]\n[[API|http://grofcs.sourceforge.net/doc/api/]]\n[[SF Project Page|http://sourceforge.net/projects/grofcs]]\n[[Download|http://sourceforge.net/project/showfiles.php?group_id=162894]]\n[[Links|Links]]\n
!Group member\nThe {{{GroupMember}}} class represents the central class or entry point of GROF#. For joing/leaving a group or sending messages to other group members a {{{GroupMember}}} instance is necessary.\n\n!Initializing\nFor creating a {{{GroupMember}}} object a {{{Initializer}}} instance which holds data like IP address of the group, member name etc. must be created.\n\n!Group member information\nEach group member holds a {{{GroupMemberInfo}}} object which provides following information:\n* Name of the group member\n* IP address of the group member\n* Port number where the group member listens for incoming calls\nThe {{{GroupMemberInfo}}} object can be asked for from the group member instance:\n{{{\nGroupMemberInfo info = groupMember.GetGroupMemberInfo();\n}}}\nEach message which is sent from a group member to other group members contains the {{{GroupMemberInfo}}} object from the sender. \n[img[http://farm1.static.flickr.com/145/361315173_22e91a6d48_o.gif]]\n\n!Protocol stack\nThe {{{GroupMember}}} object has a stack instance as member which holds one or more objects of type {{{AbstractProtocol}}}. All the message processing (sending and receiving messages) is managed by this protocol stack. Comparable with the OSI layer model each protocol instance of the stack is responsible for a certain task. \nThere is one protocol ({{{UdpMembershipProtocol}}} class, the only at the moment) which is responsible for sending and receiving the messages by writing and reading byte streams over sockets. Another protocol implementation could implement a failover feature when messages must be sent again due to network problems for example.\nThe following diagram shows how the protocol stack works. If the group member sends a message it takes the message to the topmost protocol instances. After processing the message the topmost protocol takes the message to the next lower protocol and so on. The lowest protocol (the {{{UdpMembershipProtocol}}} in current GROF# implementation) sends the message via socket to the other group members. The same procedure is executed in opposite direction when a message is received.\n\n[img[http://farm1.static.flickr.com/157/358110178_4ab617838f_o.gif]]\n\n!Message creator\nThe {{{MessageCreator}}} class represents a helper class and provides methods for creating JOIN, LEAVE, ALIVE and application messages.
For receiving messages from other group members the group member has to set following delegate on the group member instance:\n{{{\npublic delegate void MessageReceivedDelegate( Message msg );\n}}}\n\n''Example:''\n{{{\n...\npublic void MessageReceived( Message message )\n{\n Console.WriteLine( "received message: " + message.ToString()) ;\n} \n...\nGroupMember gm = new GroupMember(init);\ngm.SetMessageReceiver( new MessageReceivedDelegate( this.MessageReceived ) );\ngm.JoinGroup();\n}}}\n\nThe {{{Message}}} object holds following properties which can be accessed:\n* {{{Type}}}: The type of the message\n** JOIN: Indicates that another process wants to join the group.\n** LEAVE: Indicates that a group member wants to leave the group.\n** ALIVE: Indicates that a group member still belongs to the group.\n** APP: Indicates a application logic message. The first three message types are reserved for //GROF#// internal usage. An application programmer which uses //GROF#// sends only messages of type APP. \n* {{{MessageCounter}}}: Each group member numbers the sent messages consecutively.\n* {{{TimeStamp}}}: The time the message was created (specific to each group member process).\n* {{{GroupMemberInfo}}}: Holds data about the group member where the message comes:\n** {{{Name}}}: The name of the group member.\n** {{{HostAddress}}}: The IP address of the host where the group member lives.\n** {{{PortNumber}}}: The port number where the group member listens for incoming messages.\n
For sending messages the group member has to call the {{{Send(object obj)}}} method.\n\n''Example:''\n{{{\n...\ngm.Send( "Hello World!" );\n}}}\n\nThe message 'Hello World!' is sent to all members of the group. The sent object has to be of type {{{Serializable}}}.
A Group Oriented Framework for C#
grof#
The {{{UdpMembershipProtocol}}} is currently the only implementation of the abstract protocol class and is responsible for sending and receiving messages via TCP and UDP protocol.\n[img[http://farm1.static.flickr.com/160/361315181_672be57855_o.gif]]
The protocol stack holds instances of type {{{AbstractProtocol}}}. When messages are sent or received the messages are handed over from the topmost procotol to the lowest protocol and vice versa.\nThe following class diagram shows the {{{AbstractProtocol}}} and all depending classes.\n\n[img[http://farm1.static.flickr.com/163/361315178_806683eb9b_o.gif]]\n\n!Queues and worker threads\nThe following picture shows an example where three protocol instances of a protocol stack are shown. Each protocol instance consists of two queues of type {{{IBlockingQueue}}}, one for the incoming and one for the outgoing messages and two worker threads. \n\n[img[http://farm1.static.flickr.com/166/359348946_13e7ae02e1_o.gif]]\n\nBlocking queue means that the queue blocks the accessing thread (in this case the worker thread) if the queue is empty. As soon as a new message is put into the queue, the queue wakes up the blocked thread and the message is retrieved.\nEach worker thread is responsible for one queue. The worker thread for the incoming queue of a protocol instance retrieves messages from the next lower protocol and puts them into its incoming queue. The worker thread of the outgoing queue of a protocol instance retrieves messages from the next upper protocol and puts them into its outgoing queue.\nBefore a worker thread puts a message into its queue, the message is passed to the {{{ProcessMessageDelegate( Message msg )}}}. The respective protocol acts as a {{{ProcessMessageDelegate( Message msg )}}} by their {{{ProcessIncomingMessage}}} and {{{ProcessOutgoingMessage}}} methods.\n\n\n
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |\n| 13/12/2006 10:29:54 | YourName | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 13/12/2006 10:30:45 | magro | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 13/12/2006 10:31:41 | magro | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 13/12/2006 10:36:32 | magro | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 13/12/2006 10:37:46 | magro | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 13/12/2006 10:38:59 | magro | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 13/12/2006 12:33:14 | magr | [[/|http://grofcs.tiddlyspot.com/#Documentation]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 13/12/2006 14:56:10 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 13/12/2006 14:56:17 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 14/12/2006 7:2:11 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 14/12/2006 7:7:6 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 14/12/2006 7:7:57 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 14/12/2006 10:56:38 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 14/12/2006 12:9:57 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 14/12/2006 12:45:11 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 14/12/2006 12:46:27 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 14/12/2006 12:47:49 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 15/12/2006 7:22:41 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 16/12/2006 11:26:28 | YourName | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 16/12/2006 11:35:58 | YourName | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 16/12/2006 11:43:12 | magro | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 18/12/2006 7:14:10 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 18/12/2006 7:24:4 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 19/12/2006 7:15:28 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 19/12/2006 7:26:10 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 19/12/2006 7:26:56 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 19/12/2006 7:34:2 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 21/12/2006 0:16:59 | magro | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 22/12/2006 16:35:27 | magro | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 25/12/2006 11:9:5 | magro | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 26/12/2006 9:17:41 | magro | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 26/12/2006 9:29:42 | magro | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 26/12/2006 9:34:23 | magro | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 9/1/2007 12:5:38 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 10/1/2007 6:51:25 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 10/1/2007 7:6:28 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 10/1/2007 7:7:4 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 10/1/2007 7:7:13 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 10/1/2007 7:11:0 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 11/1/2007 7:29:56 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 15/1/2007 7:13:39 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 15/1/2007 7:16:15 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 15/1/2007 7:18:4 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 15/1/2007 12:30:55 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 15/1/2007 12:32:8 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 15/1/2007 12:32:24 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 16/1/2007 7:23:2 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 16/1/2007 11:55:23 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 16/1/2007 11:58:59 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 16/1/2007 12:22:58 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 17/1/2007 7:11:13 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 17/1/2007 7:16:42 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 17/1/2007 7:17:37 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 17/1/2007 7:32:51 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 18/1/2007 7:16:53 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 18/1/2007 7:18:1 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 18/1/2007 7:18:45 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 18/1/2007 7:25:38 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 18/1/2007 12:19:25 | magr | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 8/2/2008 20:9:50 | magr74 | [[/|http://grofcs.tiddlyspot.com/]] | [[store.cgi|http://grofcs.tiddlyspot.com/store.cgi]] | . | index.html | . |
/***\n|''Name:''|UploadPlugin|\n|''Description:''|Save to web a TiddlyWiki|\n|''Version:''|3.4.4|\n|''Date:''|Sep 30, 2006|\n|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|\n|''Documentation:''|http://tiddlywiki.bidix.info/#UploadDoc|\n|''Author:''|BidiX (BidiX (at) bidix (dot) info)|\n|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|\n|''~CoreVersion:''|2.0.0|\n|''Browser:''|Firefox 1.5; InternetExplorer 6.0; Safari|\n|''Include:''|config.lib.file; config.lib.log; config.lib.options; PasswordTweak|\n|''Require:''|[[UploadService|http://tiddlywiki.bidix.info/#UploadService]]|\n***/\n//{{{\nversion.extensions.UploadPlugin = {\n major: 3, minor: 4, revision: 4, \n date: new Date(2006,8,30),\n source: 'http://tiddlywiki.bidix.info/#UploadPlugin',\n documentation: 'http://tiddlywiki.bidix.info/#UploadDoc',\n author: 'BidiX (BidiX (at) bidix (dot) info',\n license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',\n coreVersion: '2.0.0',\n browser: 'Firefox 1.5; InternetExplorer 6.0; Safari'\n};\n//}}}\n\n////+++!![config.lib.file]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.file) config.lib.file= {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\nconfig.lib.file.dirname = function (filePath) {\n var lastpos;\n if ((lastpos = filePath.lastIndexOf("/")) != -1) {\n return filePath.substring(0, lastpos);\n } else {\n return filePath.substring(0, filePath.lastIndexOf("\s\s"));\n }\n};\nconfig.lib.file.basename = function (filePath) {\n var lastpos;\n if ((lastpos = filePath.lastIndexOf("#")) != -1) \n filePath = filePath.substring(0, lastpos);\n if ((lastpos = filePath.lastIndexOf("/")) != -1) {\n return filePath.substring(lastpos + 1);\n } else\n return filePath.substring(filePath.lastIndexOf("\s\s")+1);\n};\nwindow.basename = function() {return "@@deprecated@@";};\n//}}}\n////===\n\n////+++!![config.lib.log]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.log) config.lib.log= {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 1}, \n date: new Date(2006,8,19)\n};\nconfig.lib.Log = function(tiddlerTitle, logHeader) {\n if (version.major < 2)\n this.tiddler = store.tiddlers[tiddlerTitle];\n else\n this.tiddler = store.getTiddler(tiddlerTitle);\n if (!this.tiddler) {\n this.tiddler = new Tiddler();\n this.tiddler.title = tiddlerTitle;\n this.tiddler.text = "| !date | !user | !location |" + logHeader;\n this.tiddler.created = new Date();\n this.tiddler.modifier = config.options.txtUserName;\n this.tiddler.modified = new Date();\n if (version.major < 2)\n store.tiddlers[tiddlerTitle] = this.tiddler;\n else\n store.addTiddler(this.tiddler);\n }\n return this;\n};\n\nconfig.lib.Log.prototype.newLine = function (line) {\n var now = new Date();\n var newText = "| ";\n newText += now.getDate()+"/"+(now.getMonth()+1)+"/"+now.getFullYear() + " ";\n newText += now.getHours()+":"+now.getMinutes()+":"+now.getSeconds()+" | ";\n newText += config.options.txtUserName + " | ";\n var location = document.location.toString();\n var filename = config.lib.file.basename(location);\n if (!filename) filename = '/';\n newText += "[["+filename+"|"+location + "]] |";\n this.tiddler.text = this.tiddler.text + "\sn" + newText;\n this.addToLine(line);\n};\n\nconfig.lib.Log.prototype.addToLine = function (text) {\n this.tiddler.text = this.tiddler.text + text;\n this.tiddler.modifier = config.options.txtUserName;\n this.tiddler.modified = new Date();\n if (version.major < 2)\n store.tiddlers[this.tiddler.tittle] = this.tiddler;\n else {\n store.addTiddler(this.tiddler);\n story.refreshTiddler(this.tiddler.title);\n store.notify(this.tiddler.title, true);\n }\n if (version.major < 2)\n store.notifyAll(); \n};\n//}}}\n////===\n\n////+++!![config.lib.options]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.options) config.lib.options = {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\n\nconfig.lib.options.init = function (name, defaultValue) {\n if (!config.options[name]) {\n config.options[name] = defaultValue;\n saveOptionCookie(name);\n }\n};\n//}}}\n////===\n\n////+++!![PasswordTweak]\n\n//{{{\nversion.extensions.PasswordTweak = {\n major: 1, minor: 0, revision: 3, date: new Date(2006,8,30),\n type: 'tweak',\n source: 'http://tiddlywiki.bidix.info/#PasswordTweak'\n};\n//}}}\n/***\n!!config.macros.option\n***/\n//{{{\nconfig.macros.option.passwordCheckboxLabel = "Save this password on this computer";\nconfig.macros.option.passwordType = "password"; // password | text\n\nconfig.macros.option.onChangeOption = function(e)\n{\n var opt = this.getAttribute("option");\n var elementType,valueField;\n if(opt) {\n switch(opt.substr(0,3)) {\n case "txt":\n elementType = "input";\n valueField = "value";\n break;\n case "pas":\n elementType = "input";\n valueField = "value";\n break;\n case "chk":\n elementType = "input";\n valueField = "checked";\n break;\n }\n config.options[opt] = this[valueField];\n saveOptionCookie(opt);\n var nodes = document.getElementsByTagName(elementType);\n for(var t=0; t<nodes.length; t++) \n {\n var optNode = nodes[t].getAttribute("option");\n if (opt == optNode) \n nodes[t][valueField] = this[valueField];\n }\n }\n return(true);\n};\n\nconfig.macros.option.handler = function(place,macroName,params)\n{\n var opt = params[0];\n if(config.options[opt] === undefined) {\n return;}\n var c;\n switch(opt.substr(0,3)) {\n case "txt":\n c = document.createElement("input");\n c.onkeyup = this.onChangeOption;\n c.setAttribute ("option",opt);\n c.className = "txtOptionInput "+opt;\n place.appendChild(c);\n c.value = config.options[opt];\n break;\n case "pas":\n // input password\n c = document.createElement ("input");\n c.setAttribute("type",config.macros.option.passwordType);\n c.onkeyup = this.onChangeOption;\n c.setAttribute("option",opt);\n c.className = "pasOptionInput "+opt;\n place.appendChild(c);\n c.value = config.options[opt];\n // checkbox link with this password "save this password on this computer"\n c = document.createElement("input");\n c.setAttribute("type","checkbox");\n c.onclick = this.onChangeOption;\n c.setAttribute("option","chk"+opt);\n c.className = "chkOptionInput "+opt;\n place.appendChild(c);\n c.checked = config.options["chk"+opt];\n // text savePasswordCheckboxLabel\n place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));\n break;\n case "chk":\n c = document.createElement("input");\n c.setAttribute("type","checkbox");\n c.onclick = this.onChangeOption;\n c.setAttribute("option",opt);\n c.className = "chkOptionInput "+opt;\n place.appendChild(c);\n c.checked = config.options[opt];\n break;\n }\n};\n//}}}\n/***\n!! Option cookie stuff\n***/\n//{{{\nwindow.loadOptionsCookie_orig_PasswordTweak = window.loadOptionsCookie;\nwindow.loadOptionsCookie = function()\n{\n var cookies = document.cookie.split(";");\n for(var c=0; c<cookies.length; c++) {\n var p = cookies[c].indexOf("=");\n if(p != -1) {\n var name = cookies[c].substr(0,p).trim();\n var value = cookies[c].substr(p+1).trim();\n switch(name.substr(0,3)) {\n case "txt":\n config.options[name] = unescape(value);\n break;\n case "pas":\n config.options[name] = unescape(value);\n break;\n case "chk":\n config.options[name] = value == "true";\n break;\n }\n }\n }\n};\n\nwindow.saveOptionCookie_orig_PasswordTweak = window.saveOptionCookie;\nwindow.saveOptionCookie = function(name)\n{\n var c = name + "=";\n switch(name.substr(0,3)) {\n case "txt":\n c += escape(config.options[name].toString());\n break;\n case "chk":\n c += config.options[name] ? "true" : "false";\n // is there an option link with this chk ?\n if (config.options[name.substr(3)]) {\n saveOptionCookie(name.substr(3));\n }\n break;\n case "pas":\n if (config.options["chk"+name]) {\n c += escape(config.options[name].toString());\n } else {\n c += "";\n }\n break;\n }\n c += "; expires=Fri, 1 Jan 2038 12:00:00 UTC; path=/";\n document.cookie = c;\n};\n//}}}\n/***\n!! Initializations\n***/\n//{{{\n// define config.options.pasPassword\nif (!config.options.pasPassword) {\n config.options.pasPassword = 'defaultPassword';\n window.saveOptionCookie('pasPassword');\n}\n// since loadCookies is first called befor password definition\n// we need to reload cookies\nwindow.loadOptionsCookie();\n//}}}\n////===\n\n////+++!![config.macros.upload]\n\n//{{{\nconfig.macros.upload = {\n accessKey: "U",\n formName: "UploadPlugin",\n contentType: "text/html;charset=UTF-8",\n defaultStoreScript: "store.php"\n};\n\n// only this two configs need to be translated\nconfig.macros.upload.messages = {\n aboutToUpload: "About to upload TiddlyWiki to %0",\n backupFileStored: "Previous file backuped in %0",\n crossDomain: "Certainly a cross-domain isue: access to an other site isn't allowed",\n errorDownloading: "Error downloading",\n errorUploadingContent: "Error uploading content",\n fileLocked: "Files is locked: You are not allowed to Upload",\n fileNotFound: "file to upload not found",\n fileNotUploaded: "File %0 NOT uploaded",\n mainFileUploaded: "Main TiddlyWiki file uploaded to %0",\n passwordEmpty: "Unable to upload, your password is empty",\n urlParamMissing: "url param missing",\n rssFileNotUploaded: "RssFile %0 NOT uploaded",\n rssFileUploaded: "Rss File uploaded to %0"\n};\n\nconfig.macros.upload.label = {\n promptOption: "Save and Upload this TiddlyWiki with UploadOptions",\n promptParamMacro: "Save and Upload this TiddlyWiki in %0",\n saveLabel: "save to web", \n saveToDisk: "save to disk",\n uploadLabel: "upload" \n};\n\nconfig.macros.upload.handler = function(place,macroName,params){\n // parameters initialization\n var storeUrl = params[0];\n var toFilename = params[1];\n var backupDir = params[2];\n var uploadDir = params[3];\n var username = params[4];\n var password; // for security reason no password as macro parameter\n var label;\n if (document.location.toString().substr(0,4) == "http")\n label = this.label.saveLabel;\n else\n label = this.label.uploadLabel;\n var prompt;\n if (storeUrl) {\n prompt = this.label.promptParamMacro.toString().format([this.toDirUrl(storeUrl, uploadDir, username)]);\n }\n else {\n prompt = this.label.promptOption;\n }\n createTiddlyButton(place, label, prompt, \n function () {\n config.macros.upload.upload(storeUrl, toFilename, uploadDir, backupDir, username, password); \n return false;}, \n null, null, this.accessKey);\n};\nconfig.macros.upload.UploadLog = function() {\n return new config.lib.Log('UploadLog', " !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |" );\n};\nconfig.macros.upload.UploadLog.prototype = config.lib.Log.prototype;\nconfig.macros.upload.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {\n var line = " [[" + config.lib.file.basename(storeUrl) + "|" + storeUrl + "]] | ";\n line += uploadDir + " | " + toFilename + " | " + backupDir + " |";\n this.newLine(line);\n};\nconfig.macros.upload.UploadLog.prototype.endUpload = function() {\n this.addToLine(" Ok |");\n};\nconfig.macros.upload.basename = config.lib.file.basename;\nconfig.macros.upload.dirname = config.lib.file.dirname;\nconfig.macros.upload.toRootUrl = function (storeUrl, username)\n{\n return root = (this.dirname(storeUrl)?this.dirname(storeUrl):this.dirname(document.location.toString()));\n}\nconfig.macros.upload.toDirUrl = function (storeUrl, uploadDir, username)\n{\n var root = this.toRootUrl(storeUrl, username);\n if (uploadDir && uploadDir != '.')\n root = root + '/' + uploadDir;\n return root;\n}\nconfig.macros.upload.toFileUrl = function (storeUrl, toFilename, uploadDir, username)\n{\n return this.toDirUrl(storeUrl, uploadDir, username) + '/' + toFilename;\n}\nconfig.macros.upload.upload = function(storeUrl, toFilename, uploadDir, backupDir, username, password)\n{\n // parameters initialization\n storeUrl = (storeUrl ? storeUrl : config.options.txtUploadStoreUrl);\n toFilename = (toFilename ? toFilename : config.options.txtUploadFilename);\n backupDir = (backupDir ? backupDir : config.options.txtUploadBackupDir);\n uploadDir = (uploadDir ? uploadDir : config.options.txtUploadDir);\n username = (username ? username : config.options.txtUploadUserName);\n password = config.options.pasUploadPassword; // for security reason no password as macro parameter\n if (!password || password === '') {\n alert(config.macros.upload.messages.passwordEmpty);\n return;\n }\n if (storeUrl === '') {\n storeUrl = config.macros.upload.defaultStoreScript;\n }\n if (config.lib.file.dirname(storeUrl) === '') {\n storeUrl = config.lib.file.dirname(document.location.toString())+'/'+storeUrl;\n }\n if (toFilename === '') {\n toFilename = config.lib.file.basename(document.location.toString());\n }\n\n clearMessage();\n // only for forcing the message to display\n if (version.major < 2)\n store.notifyAll();\n if (!storeUrl) {\n alert(config.macros.upload.messages.urlParamMissing);\n return;\n }\n // Check that file is not locked\n if (window.BidiX && BidiX.GroupAuthoring && BidiX.GroupAuthoring.lock) {\n if (BidiX.GroupAuthoring.lock.isLocked() && !BidiX.GroupAuthoring.lock.isMyLock()) {\n alert(config.macros.upload.messages.fileLocked);\n return;\n }\n }\n \n var log = new this.UploadLog();\n log.startUpload(storeUrl, toFilename, uploadDir, backupDir);\n if (document.location.toString().substr(0,5) == "file:") {\n saveChanges();\n }\n var toDir = config.macros.upload.toDirUrl(storeUrl, toFilename, uploadDir, username);\n displayMessage(config.macros.upload.messages.aboutToUpload.format([toDir]), toDir);\n this.uploadChanges(storeUrl, toFilename, uploadDir, backupDir, username, password);\n if(config.options.chkGenerateAnRssFeed) {\n //var rssContent = convertUnicodeToUTF8(generateRss());\n var rssContent = generateRss();\n var rssPath = toFilename.substr(0,toFilename.lastIndexOf(".")) + ".xml";\n this.uploadContent(rssContent, storeUrl, rssPath, uploadDir, '', username, password, \n function (responseText) {\n if (responseText.substring(0,1) != '0') {\n displayMessage(config.macros.upload.messages.rssFileNotUploaded.format([rssPath]));\n }\n else {\n var toFileUrl = config.macros.upload.toFileUrl(storeUrl, rssPath, uploadDir, username);\n displayMessage(config.macros.upload.messages.rssFileUploaded.format(\n [toFileUrl]), toFileUrl);\n }\n // for debugging store.php uncomment last line\n //DEBUG alert(responseText);\n });\n }\n return;\n};\n\nconfig.macros.upload.uploadChanges = function(storeUrl, toFilename, uploadDir, backupDir, \n username, password) {\n var original;\n if (document.location.toString().substr(0,4) == "http") {\n original = this.download(storeUrl, toFilename, uploadDir, backupDir, username, password);\n return;\n }\n else {\n // standard way : Local file\n \n original = loadFile(getLocalPath(document.location.toString()));\n if(window.Components) {\n // it's a mozilla browser\n try {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]\n .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);\n converter.charset = "UTF-8";\n original = converter.ConvertToUnicode(original);\n }\n catch(e) {\n }\n }\n }\n //DEBUG alert(original);\n this.uploadChangesFrom(original, storeUrl, toFilename, uploadDir, backupDir, \n username, password);\n};\n\nconfig.macros.upload.uploadChangesFrom = function(original, storeUrl, toFilename, uploadDir, backupDir, \n username, password) {\n var startSaveArea = '<div id="' + 'storeArea">'; // Split up into two so that indexOf() of this source doesn't find it\n var endSaveArea = '</d' + 'iv>';\n // Locate the storeArea div's\n var posOpeningDiv = original.indexOf(startSaveArea);\n var posClosingDiv = original.lastIndexOf(endSaveArea);\n if((posOpeningDiv == -1) || (posClosingDiv == -1))\n {\n alert(config.messages.invalidFileError.format([document.location.toString()]));\n return;\n }\n var revised = original.substr(0,posOpeningDiv + startSaveArea.length) + \n allTiddlersAsHtml() + "\sn\st\st" +\n original.substr(posClosingDiv);\n var newSiteTitle;\n if(version.major < 2){\n newSiteTitle = (getElementText("siteTitle") + " - " + getElementText("siteSubtitle")).htmlEncode();\n } else {\n newSiteTitle = (wikifyPlain ("SiteTitle") + " - " + wikifyPlain ("SiteSubtitle")).htmlEncode();\n }\n\n revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");\n revised = revised.replaceChunk("<!--PRE-HEAD-START--"+">","<!--PRE-HEAD-END--"+">","\sn" + store.getTiddlerText("MarkupPreHead","") + "\sn");\n revised = revised.replaceChunk("<!--POST-HEAD-START--"+">","<!--POST-HEAD-END--"+">","\sn" + store.getTiddlerText("MarkupPostHead","") + "\sn");\n revised = revised.replaceChunk("<!--PRE-BODY-START--"+">","<!--PRE-BODY-END--"+">","\sn" + store.getTiddlerText("MarkupPreBody","") + "\sn");\n revised = revised.replaceChunk("<!--POST-BODY-START--"+">","<!--POST-BODY-END--"+">","\sn" + store.getTiddlerText("MarkupPostBody","") + "\sn");\n\n var response = this.uploadContent(revised, storeUrl, toFilename, uploadDir, backupDir, \n username, password, function (responseText) {\n if (responseText.substring(0,1) != '0') {\n alert(responseText);\n displayMessage(config.macros.upload.messages.fileNotUploaded.format([getLocalPath(document.location.toString())]));\n }\n else {\n if (uploadDir !== '') {\n toFilename = uploadDir + "/" + config.macros.upload.basename(toFilename);\n } else {\n toFilename = config.macros.upload.basename(toFilename);\n }\n var toFileUrl = config.macros.upload.toFileUrl(storeUrl, toFilename, uploadDir, username);\n if (responseText.indexOf("destfile:") > 0) {\n var destfile = responseText.substring(responseText.indexOf("destfile:")+9, \n responseText.indexOf("\sn", responseText.indexOf("destfile:")));\n toFileUrl = config.macros.upload.toRootUrl(storeUrl, username) + '/' + destfile;\n }\n else {\n toFileUrl = config.macros.upload.toFileUrl(storeUrl, toFilename, uploadDir, username);\n }\n displayMessage(config.macros.upload.messages.mainFileUploaded.format(\n [toFileUrl]), toFileUrl);\n if (backupDir && responseText.indexOf("backupfile:") > 0) {\n var backupFile = responseText.substring(responseText.indexOf("backupfile:")+11, \n responseText.indexOf("\sn", responseText.indexOf("backupfile:")));\n toBackupUrl = config.macros.upload.toRootUrl(storeUrl, username) + '/' + backupFile;\n displayMessage(config.macros.upload.messages.backupFileStored.format(\n [toBackupUrl]), toBackupUrl);\n }\n var log = new config.macros.upload.UploadLog();\n log.endUpload();\n store.setDirty(false);\n // erase local lock\n if (window.BidiX && BidiX.GroupAuthoring && BidiX.GroupAuthoring.lock) {\n BidiX.GroupAuthoring.lock.eraseLock();\n // change mtime with new mtime after upload\n var mtime = responseText.substr(responseText.indexOf("mtime:")+6);\n BidiX.GroupAuthoring.lock.mtime = mtime;\n }\n \n \n }\n // for debugging store.php uncomment last line\n //DEBUG alert(responseText);\n }\n );\n};\n\nconfig.macros.upload.uploadContent = function(content, storeUrl, toFilename, uploadDir, backupDir, \n username, password, callbackFn) {\n var boundary = "---------------------------"+"AaB03x"; \n var request;\n try {\n request = new XMLHttpRequest();\n } \n catch (e) { \n request = new ActiveXObject("Msxml2.XMLHTTP"); \n }\n if (window.netscape){\n try {\n if (document.location.toString().substr(0,4) != "http") {\n netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');}\n }\n catch (e) {}\n } \n //DEBUG alert("user["+config.options.txtUploadUserName+"] password[" + config.options.pasUploadPassword + "]");\n // compose headers data\n var sheader = "";\n sheader += "--" + boundary + "\sr\snContent-disposition: form-data; name=\s"";\n sheader += config.macros.upload.formName +"\s"\sr\sn\sr\sn";\n sheader += "backupDir="+backupDir\n +";user=" + username \n +";password=" + password\n +";uploaddir=" + uploadDir;\n // add lock attributes to sheader\n if (window.BidiX && BidiX.GroupAuthoring && BidiX.GroupAuthoring.lock) {\n var l = BidiX.GroupAuthoring.lock.myLock;\n sheader += ";lockuser=" + l.user\n + ";mtime=" + l.mtime\n + ";locktime=" + l.locktime;\n }\n sheader += ";;\sr\sn"; \n sheader += "\sr\sn" + "--" + boundary + "\sr\sn";\n sheader += "Content-disposition: form-data; name=\s"userfile\s"; filename=\s""+toFilename+"\s"\sr\sn";\n sheader += "Content-Type: " + config.macros.upload.contentType + "\sr\sn";\n sheader += "Content-Length: " + content.length + "\sr\sn\sr\sn";\n // compose trailer data\n var strailer = new String();\n strailer = "\sr\sn--" + boundary + "--\sr\sn";\n //strailer = "--" + boundary + "--\sr\sn";\n var data;\n data = sheader + content + strailer;\n //request.open("POST", storeUrl, true, username, password);\n try {\n request.open("POST", storeUrl, true); \n }\n catch(e) {\n alert(config.macros.upload.messages.crossDomain + "\snError:" +e);\n exit;\n }\n request.onreadystatechange = function () {\n if (request.readyState == 4) {\n if (request.status == 200)\n callbackFn(request.responseText);\n else\n alert(config.macros.upload.messages.errorUploadingContent + "\snStatus: "+request.status.statusText);\n }\n };\n request.setRequestHeader("Content-Length",data.length);\n request.setRequestHeader("Content-Type","multipart/form-data; boundary="+boundary);\n request.send(data); \n};\n\n\nconfig.macros.upload.download = function(uploadUrl, uploadToFilename, uploadDir, uploadBackupDir, \n username, password) {\n var request;\n try {\n request = new XMLHttpRequest();\n } \n catch (e) { \n request = new ActiveXObject("Msxml2.XMLHTTP"); \n }\n try {\n if (uploadUrl.substr(0,4) == "http") {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");\n }\n else {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n }\n } catch (e) { }\n //request.open("GET", document.location.toString(), true, username, password);\n try {\n request.open("GET", document.location.toString(), true);\n }\n catch(e) {\n alert(config.macros.upload.messages.crossDomain + "\snError:" +e);\n exit;\n }\n \n request.onreadystatechange = function () {\n if (request.readyState == 4) {\n if(request.status == 200) {\n config.macros.upload.uploadChangesFrom(request.responseText, uploadUrl, \n uploadToFilename, uploadDir, uploadBackupDir, username, password);\n }\n else\n alert(config.macros.upload.messages.errorDownloading.format(\n [document.location.toString()]) + "\snStatus: "+request.status.statusText);\n }\n };\n request.send(null);\n};\n\n//}}}\n////===\n\n////+++!![Initializations]\n\n//{{{\nconfig.lib.options.init('txtUploadStoreUrl','store.php');\nconfig.lib.options.init('txtUploadFilename','');\nconfig.lib.options.init('txtUploadDir','');\nconfig.lib.options.init('txtUploadBackupDir','');\nconfig.lib.options.init('txtUploadUserName',config.options.txtUserName);\nconfig.lib.options.init('pasUploadPassword','');\nsetStylesheet(\n ".pasOptionInput {width: 11em;}\sn"+\n ".txtOptionInput.txtUploadStoreUrl {width: 25em;}\sn"+\n ".txtOptionInput.txtUploadFilename {width: 25em;}\sn"+\n ".txtOptionInput.txtUploadDir {width: 25em;}\sn"+\n ".txtOptionInput.txtUploadBackupDir {width: 25em;}\sn"+\n "",\n "UploadOptionsStyles");\nconfig.shadowTiddlers.UploadDoc = "[[Full Documentation|http://tiddlywiki.bidix.info/l#UploadDoc ]]\sn"; \nconfig.options.chkAutoSave = false; saveOptionCookie('chkAutoSave');\n\n//}}}\n////===\n\n////+++!![Core Hijacking]\n\n//{{{\nconfig.macros.saveChanges.label_orig_UploadPlugin = config.macros.saveChanges.label;\nconfig.macros.saveChanges.label = config.macros.upload.label.saveToDisk;\n\nconfig.macros.saveChanges.handler_orig_UploadPlugin = config.macros.saveChanges.handler;\n\nconfig.macros.saveChanges.handler = function(place)\n{\n if ((!readOnly) && (document.location.toString().substr(0,4) != "http"))\n createTiddlyButton(place,this.label,this.prompt,this.onClick,null,null,this.accessKey);\n};\n\n//}}}\n////===\n
This document is a ~TiddlyWiki from tiddlyspot.com. A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.\n\n@@font-weight:bold;font-size:1.3em;color:#444; //What now?// &nbsp;&nbsp;@@ Before you can save any changes, you need to enter your password in the form below. Then configure privacy and other site settings at your [[control panel|http://grofcs.tiddlyspot.com/controlpanel]] (your control panel username is //grofcs//).\n<<tiddler tiddlyspotControls>>\n@@font-weight:bold;font-size:1.3em;color:#444; //Working online// &nbsp;&nbsp;@@ You can edit this ~TiddlyWiki right now, and save your changes using the "save to web" button in the column on the right.\n\n@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// &nbsp;&nbsp;@@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick. You can make changes and save them locally without being connected to the Internet. When you're ready to sync up again, just click "upload" and your ~TiddlyWiki will be saved back to tiddlyspot.com.\n\n@@font-weight:bold;font-size:1.3em;color:#444; //Help!// &nbsp;&nbsp;@@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]]. Also visit [[TiddlyWiki Guides|http://tiddlywikiguides.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help. If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].\n\n@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// &nbsp;&nbsp;@@ We hope you like using your tiddlyspot.com site. Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions.
My TiddlyWiki
| tiddlyspot password:|<<option pasUploadPassword>>|\n| site management:|<<upload http://grofcs.tiddlyspot.com/store.cgi index.html . . grofcs>>//(requires tiddlyspot password)//<<br>>[[control panel|http://grofcs.tiddlyspot.com/controlpanel]], [[download (go offline)|http://grofcs.tiddlyspot.com/download]]|\n| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[announcements|http://announce.tiddlyspot.com/]], [[blog|http://tiddlyspot.com/blog/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|