!For edits:\nUsername: <<option txtUserName>>\n!For upload:\nUsername: <<option txtUploadUserName>>\nPassword: <<option pasUploadPassword>>\n
From time to time I get creative and make electronic music which could be described as Trance, Psychedelic, Progressive or various other words. Some of it's pretty good. Some of it isn't. I've tried to be honest in my descriptions:\n\n|>| !Newer stuff ~ 2004 |\n|RockSolo | Melodic psy-trance |\n|CryBaby | Old School Goa-style trance |\n|ChakChak | Progressive Trance |\n|>|Experimental |\n|[[Epithelium]] | rising canon. psy-trance |\n\nThe newer stuff was done on a dual-processor Opteron workstation with Windows XP and Cubase ~SX2.0 using a Yamaha ~CS1x as the controller keyboard, All sounds or effects are VST instruments within Cubase.\n\n\n|>| !Older stuff ~ 1997 |\n| [[Track1]]| Nice ~TB-303! |\n| [[Track2]]| Clangy! |\n| [[Track3]]| Another repetitive experiment |\n\n\nAll the older stuff is done using Cubase VST 3.1 on a ~PowerMac 8500, A Yamaha ~CS1x, Roland ~MC-303 (as a patch bank) and a Zoom 9001 guitar effects processor. All sound is played by Cubase via the synths, recorded, and in many cases manipulated afterwards.\n
I am an Audiophile. To me, that means I am quite finnicky about sound quality, and as some have said, Yes... I do spend a fair amount of time listening to my audio setup, rather than listening to the music.\n\nThat said, I reached the point on my own curve of diminishing returns with my current setup where I am happy with the sound. Or at least happy enough not to want to change it or spend more money on it.\n\nAlso, and this is important, I don't believe in any audio 'tweak' that I can't hear blind. This means no $5000 cables, no 'tuning dots', no red markers, no 'quantum purifiers' or other snake-oil. I'm not even particularly finnicky about the transport, as most mid-to-high range transports have very low error rates these days, and in any case most of my playing is done over my home network.\n\nI have two systems. One is the ''living-room system'' consisting of:\n\n[[Denon AVC-A1SR|http://www.homecinemachoice.com/reviews/hccreviews/Amplifiers/Denon/DenonAVC-A1SR.php]] A/V Amplifier.\n2x [[Gallo Nucleus Solo|http://www.audiophilia.com/hardware/gallons.htm]] speakers.\n2x [[Gallo Due speakers|http://www.anthonygallo.co.uk/due/due.php]] (surrounds)\n1x [[Gallo MPS150 subwoofer|http://www.anthonygallo.co.uk/subs/mps-150-subwoofer.php]]\nSome big fat cables\nA variety of digital sources.\n\n\nThe other is my ''hobby room system'' consisting of:\n\n[[Audiophile 24/96|http://www.m-audio.com/products/en_us/Audiophile2496-main.html]] sound card\n[[Benchmark DAC-1|http://www.benchmarkmedia.com/dac1/]] Digital to Analogue converter\n[[Decware Zen Triode SE34I|http://www.decware.com/integrated/zint.htm]] Integrated valve amp.\n2x [[Gallo Nucleus Reference II|http://cgi.audiogon.com/cgi-bin/srch_fs.pl?gallo]] speakers\n\n\n
I made this in December 2004 after listening to [[Axis Flip - Man With No Name|http://saikosounds.com/english/display_release.asp?id=3510]]. I was intrigued by the relative simplicity but perfect structure in that tune which tends to get everyone going bonkers on the dance floor without seeming to try too hard. I don't claim to be anywhere near the capability of Martin Freeland a.k.a MWNN, but I was pleasantly surprised at the results. People who don't like Goa tend to prefer this one, it's relatively easy listening.\n\n ''[[Link to ChakChak - mp3|http://lindsey.jp/audio/chakchak.mp3]]''\n\nClick to open, right-click to download and save, or drag-drop to Winamp or your favourite mp3 player software.
Background: #eee\nForeground: #000\nPrimaryPale: #8cf\nPrimaryLight: #18f\nPrimaryMid: #04b\nPrimaryDark: #014\nSecondaryPale: #ffc\nSecondaryLight: #fe8\nSecondaryMid: #db4\nSecondaryDark: #841\nTertiaryPale: #ddd\nTertiaryLight: #ccc\nTertiaryMid: #999\nTertiaryDark: #555\nError: #988\n
This was done in January 2005. The idea was to recreate the old Goa rasping sawtooth and get a good keyboard solo feel to it. This track got a great reception when I released it, but with the overwhelming prevalence of the comment "Great, just 7 years too late"\n\n ''[[Link to CryBaby mp3|http://lindsey.jp/audio/crybabyx.mp3]]''\n\nClick to open, right-click to download and save, or drag-drop to Winamp or your favourite mp3 player software.
As discussed in [[this thread|http://groups.google.com/group/TiddlyWikiDev/browse_thread/thread/9c0a4a9e989fce4f]] it could be a valuable improvement if the ''engine'' (aka the ''core'') could be put in a separate file. Especially for those of us that access their TiddlyWiki by majority on the web (TiddlySpot users for example).\n\nBramChen maintains a distribution on this base (empty.html and TiddlyWiki.js in PrinceTiddlyWiki distribution). And everything go right when accessed from the web and saved to web using UploadPlugin. And we could save 220Ko on each download and upload (the size of the actual core).\n\nBut the challenge is to maintain the single file paradigm of TiddlyWiki and be able to detach it from the web. To do that :\n*DownloadService is a script [[download.cgi]] that includes the javascript files that are referenced in the html file. Try the command: [[download.cgi|download.cgi?]]\n*UploadService [[store.cgi]] has been modified to do the reverse (ie replace a previously inserted content by its corresponding filename).\n\nDownloadService and new version of [[ store.cgi]] are backward compatible with UploadPlugin.\n
This was my last attempt at knocking something together in Spring 2005, then I got caught up in the summer and ended up getting a job.\n\nThe premise was to make a rising [[canon|http://en.wikipedia.org/wiki/Canon_%28music%29]]. I got the idea after reading [[Godel, Escher and Bach|http://en.wikipedia.org/wiki/G%C3%B6del,_Escher,_Bach]], a book by [[Douglas Hofstadter|http://en.wikipedia.org/wiki/Douglas_Hofstadter]]. Geeky, I know. The music is very repetitive and unpolished. Many people find it quite painful to listen to, but I have gotten away with playing it for up to 2 minutes as part of a psy-trance set.\n\n ''[[Link to the mp3|http://lindsey.jp/audio/chakchak.mp3]]''\n\nClick to open, right-click to download and save, or drag-drop to Winamp or your favourite mp3 player software.
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>>
Whilst at University I learned to juggle 3 balls, and a couple of tricks. Then in 2003 my neigbour Marcello was juggling on the street outside our house, prompting me to start practicing and take it up a bit more enthusiastically.\n\nI can of course juggle 3 balls with a few different tricks, I can do a 4 ball fountain, 4 ball half-shower, and a 4 ball cascade (actually a 5 ball pattern with a ball missing)\n\nI'm trying to juggle 5 balls, but it's been over a year and I still can't get past the magic 15-catch limit, although I tend to get 11-15 catch runs much more often these days, so I'm still hopeful.\n\nI can juggle 3 clubs and a number of tricks, which I may get round to documenting at some point.\n\nI can also do a little bit of contact juggling, Most of the contact juggling I see on the web is either pure performance (nice to look at) or incredibly difficult.\n\nI used to be able to ride a unicycle. Maybe I'll get round to buying one at some point :)\n\n\n
/***\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
/***\n|Author:|Simon Baird|\n|URL:|http://linktomemacro.tiddlyspot.com/|\nAs suggested by Peter Lindsey on 17-Nov-2006. Example usage:\n{{{<<linkToMe>>, <<linkToMe 'right click here'>>}}}\n<<linkToMe>>, <<linkToMe 'right click here'>>\n***/\n//{{{\nmerge(config.macros,{\n linkToMe: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n wikify('<html><a href="'+window.location.href+'">'+(params[0]?params[0]:window.location.href)+'</a></html>',place,null,tiddler);\n }}\n});\n//}}}
\nMusic: [[Audio]]\n[[Photography]]\n[[Photos]]\n[[Juggling]]\n\n\nAdminOptions\n
Peter was born and raised in a small town in South Yorkshire, right through the time of Thatcher and the mining strikes. He enjoyed going to school, even if homework was never his priority, and somehow did well enough to go to a decent university.\n\nHe started playing guitar at the age of 7. \n\nHe obtained a scolarship and sponsorship from [[GCHQ|http://www.gchq.gov.uk/]] to [[UMIST|http://en.wikipedia.org/wiki/UMIST]] where, true to form, he did just enough work to be begrudgingly granted an [[IEEE|http://www.ieee.org/portal/site]] accredited [[BEng(hons)|http://en.wikipedia.org/wiki/BEng]] in Software Engineering.\n\nExtracurricular activities were always numerous, including a bit of juggling, playing guitar, a brief attempt at hang-gliding, and participation in various societies.\n\nHe didn't bother sticking around for the [[MEng|http://en.wikipedia.org/wiki/MEng]], which seemed like far too much work, so he upped and offed to Japan, where he thought he'd be able to absorb the local language, with the hope that it may prove useful in his future career.\n\nHe was right. He bombarded the financial industry with his CV until they finally let him have a job, and it was all uphill from there.\n\nPeter diverted his musical talent from guitar playing to making electronic [[Audio]], and later started [[Juggling]] a little more enthusiastically. He considers himself an [[Audiophile]], and has been interested from time to time in geeky related things such as [[SignalTheory]]. He spent a number of years getting increasingly interested in [[Photography]] before realising that his camera bag was now too heavy to take to all but the most special occasions.\n\nPeter speaks Japanese fluently, and is not at all bad at reading/writing. He enjoys long walks on the beach, "loves to laugh" and detests people who write about themselves in the third person.\n\n\n
[<img[TC1 picture|http://lindsey.jp/images/tc1.jpg]]I had a Zenit 12 SLR as a boy, and learned a little about the technicals of photography at this time, although for me film was a little expensive so I didn't really get much use out of it.\n\nI got interested again in the 90s, when I used to loan Minolta SLR cameras. I bought a [[Minolta TC-1|http://www.photoethnography.com/ClassicCameras/index-frameset.html?MinoltaTC1.html~mainFrame]] as an excellent quality compact camera, which gave me years of great service. \n\nLater I invested in a Canon EOS3, and started to accumulate lenses and various kit. Next came a Canon D30 digital SLR, followed a couple of years later by a Canon EOS 1Ds. I now have a big bag of stuff which is far too heavy to just pick up and take out wherever I go.\n\nI did, however, manage to take very many [[Photos]], a lot of which are on display on this site.\n\n\n
[<img[Ayers Rock / Uluru|http://lindsey.jp/images/thumbnails/rock.jpg][http://lindsey.jp/images/rock.jpg]]I took this one whilst on our honeymoon trip to Australia. 17mm on the EOS3, the rainbow didn't last very long.\n\n\n\n\n[>img[A surfer in Bali|http://lindsey.jp/images/thumbnails/flysurfer3.jpg][http://lindsey.jp/images/flysurfer3.jpg]]Here's one I took of a surfer practicing on the waves of Kuta Beach in Bali.\n\n\n\n\n[<img[Place San Ferdinand Picture|http://lindsey.jp/images/thumbnails/ferdinand_small.jpg][http://lindsey.jp/images/ferdinand_small.jpg]]Here's a pic I took from my balcony on a cold december morning whilst living in Paris.\n\n\n\n\n[>img[Rainbow in Paris|http://lindsey.jp/images/thumbnails/rb.jpg][http://lindsey.jp/images/rb.jpg]]Another rainbow opportunity, this time over the same place in Paris as the photo above.\n\n\n\n\n[<img[All downhill from here|http://lindsey.jp/spain2002/thumbnails/IMG_6925x.jpg][http://lindsey.jp/spain2002/IMG_6925x.jpg]]Here is the inside of a conch shell. Oh alright not really, it's a staircase inside the Sagrada de Familia in Barcelona.\n\n\n\n\n[>img[Waves on the beach|http://lindsey.jp/vegas/thumbnails/zhawaii22.jpg][http://lindsey.jp/vegas/zhawaii22.jpg]]A moody pic of some waves at Pupukea Beach Park in Hawaii.\n\n\n\n\n[<img[The Olgars|http://lindsey.jp/images/thumbnails/olgars1.jpg][http://lindsey.jp/images/olgars1.jpg]]This is a real photo, I know it looks like a cartoon or something but it's real. This is a view of the Olgars which are quite close to Ayers rock in Australia.\n\n\n\n\nI have a load of photo pages are outside of this blog page, so here are links to all of them:\n\n\n[[LucyHana's newborn pics|http://lindseyjp/surprise/]] When Lucy was born\n[[LucyHana's gallery|http://lindsey.jp/gallery2/]] A gallery of pics for my daughter LucyHana\n\n[[Bali|http://lindsey.jp/bali/]]\n[[Olympics, Sydney|http://lindsey.jp/olympics/]]\n[[Vegas, Grand Canyon and Hawaii 2000|http://lindsey.jp/vegas/]]\n[[SG BT Seminar|http://lindsey.jp/btseminar]] Another business trip!\n[[New Year 2000/2001|http://lindsey.jp/newyear/]]\n[[Mum's Wedding|http://lindsey.jp/wedding/]] Login is mum's first name, Password is her new last name.\n[[Cebu Island|http://lindsey.jp/cebu]] A huge offsite jaunt with the company for making so much money the previous year. Woohoo.\n[[Japan springtime 2001|http://lindsey.jp/haru]]\n[[Hawaii 2001|http://lindsey.jp/hawaii2001]] I just can't keep away from the place.\n[[Muffin the dog|http://lindsey.jp/muffin/]] Our (sanae's) dog muffin. Aww.\n[[Thai Food Festival|http://lindsey.jp/thepark/]] September 2000.\n[[Sanae in the sun|http://lindsey.jp/sanaesun/]] One of my wife's early modelling attempts. Sexay!\n[[Yen Bar, Shibuya|http://lindsey.jp/yenbar/]] I just happened to have my camera on a night out in this cool bar in Shibuya back in 2001.\n[[Shibuya again|http://lindsey.jp/shibuya/]] Just a walk around town.\n[[Sandy's visit|http://lindsey.jp/sandyvisit]] My sister came to visit with her friend, Sarah.\n[[Barcelona 2001|http://lindsey.jp/barcelona/]] I spent all day taking photos here! Some nice ones.\n[[Australia 2002|http://lindsey.jp/australia/]] This was our 'honeymoon' trip. Covering the Gold Coast, Uluru, Cairns, Barrer Reef and Hamilton Island. Lots of great photos here.\n[[Spain 2002|http://lindsey.jp/spain2002/]] Just a holiday in Barcelona and Cadaques\n[[Firenze and Pisa|http://lindsey.jp/italia/]] Yet another holiday weekend!\n[[Tokyo with 1Ds|http://lindsey.jp/Tokyo1ds/]] Just a walk round town with my new camera.\n[[Hajime and Ken's birthday|http://lindsey.jp/hajimeken/]] December 2002.\n\n''[[Fark|http://www.fark.com/]] related stuff: ''\n\n[[London Fark Party 2002|http://lindsey.jp/londonfark/]] \n[[Tokyo Fark Party 2003|http://lindsey.jp/tokyofark/]] \n[[David Blaine|http://lindsey.jp/david/]] David Blaine zapped by [[Fark|http://www.fark.com/]] lasers.\n\n\n\n\n\n\n
The theme for this was the long and heady solos of the old 70s glam-rock era, pinned down with a monotonous bass. I wanted to get something really melodic that just kept going. It worked pretty well, this track tends to get a good reception on the dance floor.\n\n ''[[Link to RockSolo - mp3|http://lindsey.jp/audio/rocksolofark.mp3]]''\n\nClick to open, right-click to download and save, or drag-drop to Winamp or your favourite mp3 player software.
<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal 'DD MMM YYYY'>><<upload>><<saveChanges>>----\n<<linkToMe 'right click to save offline'>>\n\n----\n<<slider chkSliderOptionsPanel OptionsPanel 'options »' 'Change TiddlyWiki advanced options'>>
I have spent many hours discussing with Audiophiles the merits and demerits of CD audio over vinyl. A common argument heard against CDs is that the sample rate causes increasing distortion to the original sound wave as the frequency approaches the [[nyquist frequency|http://en.wikipedia.org/wiki/Nyquist_frequency]] i.e. half the sample rate, which is the theoretical maximum (non-inclusive).\n\nThis is indeed true, but the only 'distortion' is that higher frequency components are filtered out. The higher frequency components being the ones you can't hear anyway.\n\nIt is a common misconception that to sample a sound, for example a sine wave, at close to the nyquist frequency, the recorded sound will exhibit 'beating', i.e. get louder and quieter as the sampled points move from being the top of the original wave to the middle, where the value would be around zero.\n\nIt is true that the list of sampled data will show values which vary from loud to quiet and vice versa, in waves, which is intuitive.\n\nWhat is not intuitive, and takes a bit of signal theory to understand, is that the reconstruction of the original wave from the samples given is not done simply by drawing a line from sample to sample, but by taking a number of samples before and after each point, and adding the [[sinc function|http://mathworld.wolfram.com/SincFunction.html]] for each sample together to recreate the total wave. \n\nWhat happens when you do this, is that even a sample list which appears to 'beat' due to the varying amplitude of samples, will be reconstructed to show the original sine wave at unvarying amplitude!\n\nI knocked together a quick [[Mathematica|http://www.wolfram.com/]] page on the [[sample theorem|http://lindsey.jp/samplingtheorem/]] to demonstrate this. In my example, the reconstructed wave is not //exactly// the sampled one, but that's because of the low number of samples I used to reconstruct it. A good DAC will use many more than my example.\n\n
's repository of stuff on the web
Peter Lindsey
My first test over the web\n
This is my firstest everest track. Banged out in September 1997 barely a week after buying my ~PowerMac and first synth, the Yamaha ~CS1x. It's well layered with lots of melodies, the structure the only thing letting it down.\n\n''[[Link to Track1 - mp3|http://lindsey.jp/audio/track1.mp3]]''\n\nAs with all the older tracks, the sound quality is pretty poor on this one. \n\nClick to open, right-click to download and save, or drag-drop to Winamp or your favourite mp3 player software.
The bells! The bells!\n\nI used a good old nasty sawtooth for the main melody and structured the song fairly well. Friends of mine don't seem to like the bells much. Heh. The tune is pretty good, though.\n\n ''[[Link to Track2 - mp3|http://lindsey.jp/audio/track2.mp3]]''\n\nAs with all the older tracks, the sound quality is pretty poor on this one. Though it's relatively well produced considering (I mean it was 1997 and all I had was a ~PowerMac 8500 with Cubase VST 3.1). \n\nClick to open, right-click to download and save, or drag-drop to Winamp or your favourite mp3 player software.
This was a decent attempt at something fast and furious, making good use of a good solo melody, repeated and modulated to decent effect. It's very abrasive, though, I don't think I could get away with playing this at a club without some serious reengineering. It sounded better in the early stages but I messed with it too much, and in the old days I didn't have disk space to do this non-distructively.\n\n ''[[Link to Track3 - mp3|http://lindsey.jp/audio/track3.mp3]]''\n\nAs with all the older tracks, the sound quality is pretty poor on this one.\n\nClick to open, right-click to download and save, or drag-drop to Winamp or your favourite mp3 player software.
//last update: UploadPlugin v 3.4.5//\n\n!Description\nUploadPlugin with <<tag UploadService>> extend TiddlyWiki with @@upload@@ and @@save to web@@ commands. \nUploadPlugin uses Username and Password from UploadOptions stored in cookies to authenticate itself to [[store.php]] or [[store.cgi]].\nFrench translation available as a separate tiddler UploadPluginMsgFR\n\n!!UploadPlugin\n*If the TiddlyWiki is viewed from @@local disk@@ :\n**{{{<<saveChanges>>}}} \n***display as ''save to disk''\n***work as usual\n**{{{<<upload>>}}}\n***display as ''upload''\n***after saving to disk, upload in the storeUrl directory.\n*If the TiddlyWiki is viewed from @@website@@ and is @@readOnly@@ (in core TiddlyWiki since 2.0.6) :\n**{{{<<saveChanges>>}}} \n***print nothing\n***has been disabled\n**{{{<<upload>>}}}\n***display as '''save to web''\n***save in the uploadDir directory.\n*If GenerateAnRssFeed in AdvancedOptions is set :\n**generate the content of the RSSFeed \n**upload the RssFile in uploadDir directory\n**Caution : use the SiteUrl tiddler to specify the right url of the TiddlyWiki in the generated RssFile\n*DisplayMessage\n*Log upload action in UploadLog\nhint : if UploadLog is the first tiddler in the Timeline Tab, no tiddler has been updated since last upload.\n\n!![[store.php]]\n*UserVariables to set :\n//{{{\n$AUTHENTICATE_USER = true; // true | false\n$USERS = array(\n 'UserName1'=>'Password1', \n 'UserName2'=>'Password2', \n 'UserName3'=>'Password3'); // set usernames and strong passwords\n$DEBUG = false; // true | false\n//}}}\n*method GET\n**display an information page\n*method POST\n**if $~AUTHENTICATE_USER is ''true''\n***presence and value of user and password are checked with $USER and $PASSWORD \n**if toFilename already exists and backDir parameter specified\n***rename toFilename to backupDir/toFilename.AAAAMMDD.HHSS.html\n**copy temporaryUploadedFile to toFilename\n** return status\n\n!![[store.cgi]]\n*UserVariables to set :\n//{{{\nCONFIG = {\n :users => {\n 'UserName1'=>'Password1', \n 'UserName2'=>'Password2', \n 'UserName3'=>'Password3')\n },\n :authenticateUser => true,\n :backupExistingFile => true,\n :withUploadDir => true\n}\n//}}}\n*same processing as store.php above\n\n!Usage : \n{{{\n<<upload>>\n uses UploadOptions saved in cookies :\n txtUploadUserName: username\n pasUploadPassword : password\n txtUploadStoreUrl : store script\n txtUploadDir : relative path for upload directory\n txtUploadFilename : upload filename\n txtUploadBackupDir : relative path for backup directory\n\n<<upload [storeUrl [toFilename [backupDir [uploadDir [username]]]]]>>\n Optional positional parameters can be passed to overwrite \n UploadOptions. \n}}}\n\nInstall the {{{<<upload ... >>}}} macro in SideBarOptions just below {{{<<saveChanges>>}}} macro.\n\n\n!User manual\nSee HowToUpload\n\n!Installation :\n*Install the UploadPlugin as usual\n*Upload the [[store.php]] file on your php aware webserver in your TiddlyWiki directory\n*Protect your server against malicious upload. Two approaches :\n**set $~AUTHENTICATE_USER to true in the [[store.php]] script\n***configure $USER and $PASSWORD in the [[store.php]] script on your webserver\n***set UploadOptions in conformity with [[store.php]]\n**Use server protection :\n***for Apache web server ([[for detail see Apache documentation|http://httpd.apache.org/docs/1.3/howto/htaccess.html]]) : \n****configure and upload the [[.htaccess]] [[.passwd]]\n***for other web servers see the appropriate documentation\n*Configure an upload button, for example in the SideBarOptions\n!Suppported Browser\n*Firefox and Gecko based browser: tested Ok\n*Internet Explorer : tested Ok\n*Safari : tested ok on OS X\n*Others : Not tested, please report status.\n\n!Revision history\n*V 3.4.5 (2006/10/15)\n**Force checkAutoSave to false for http protocol only (thanks to SimonBaird)\n*V 3.4.4 (30/09/2006)\n**PasswordTweak V 1.0.3\n***add class attribute specific on each option input (thanks to ClintChecketts)\n**UploadOptions width set by styleSheet\n*V 3.4.3 (19/09/2006)\n**Add classname to input for options (thanks to ClintChecketts)\n**Force checkAutoSave to false\n**Alert if password is empty before Uploading\n*V 3.4.2 (04/09/2006)\n**add functions to format displayMessages (thanks to LucDeschenaux)\n**take return values from store.cgi of destfile and backupfile for displayMessages \n*V 3.4.1 (19/08/2006)\n**Error management improvement\n*V 3.4.0 (25/07/2006)\n**Manage Lock parameters for GroupAuthoring\n**Small code refactoring for new PluginFormat in TW 2.1\n+++[previous revisions]\n*V 3.3.3 (30/06/2006)\n**reinstall saveChanges Hijacking\n*V 3.3.2 (26/06/2006)\n** make "save to disk" disappear when TiddlyWiki is located on the web\n** small reformatting of post headers for store.cgi compatibility\n*V 3.3.1 (30/03/2006)\n**bug in backup folder when uploading rssfile fixed\n*V 3.3.0 (12/03/2006)\n**Code refactoring\n**suppress saveChanges hijacking\n*V3.2.2 (25/02/2006)\n**Use PasswordTweak 1.0.1\n**uploaddir is a relative path\n**backupdir is a relative path\n*V3.2.1 (13/02/2006)\n**name and password added to open.request (Thanks to TedPavlic)\n*V3.2.0 (14/02/2006)\n**Use PassworDTweak (http://tiddlyWiki.bidix.info/#PasswordTweak) for password\n*V3.1.0 (12/02/2006)\n**UploadOptions in Cookies\n**Username and password from UploadOptions pass to store.php script for authentification check\n*V3.0.3 (03/02/2006)\n**Firefox crashes due to global var fixed\n*V3.0.2 (25-Jan-2006)\n**HTTPS compatible\n*V3.0.1 (18-Jan-2006)\n**UTF8toUnicode conversion problem in Firefox\n*V3.0.0 (15-Jan-2006)\n**Asynchronous upload\n**Synchronous upload before unload of the page\n**All strings extracted in macro config\n**Compatibility checked with TW 2.0.2 & TW 1.2.39 for both FF 1.5 and IE 6\n*V2.0.2 (8-Jan-2006)\n**conversion of SiteTitle and SiteSubtitle in web page Title\n*V2.0.1 (8-Jan-2006)\n**Compatibilty with TiddlyWiki 2.0.1\n*V2.0.0 (3-Jan-2006)\n**Save to web\n**Compatibilty with TiddlyWiki 1.2.39 and TiddlyWiki 2.0.0 Beta 6\n*v1.1.0 (27-Dec-2005)\n**Upload RSS File\n*v1.0.3 (26-Dec-2005)\n**UploadLog tiddler\n*v1.0.2 (24-Dec-2005)\n**Optional parameter toFilename\n**Optional parameter backupDir\n*v1.0.1 (23-Dec-2005)\n**reformatting code\n* v1.0.0 (17-Dec-2005)\n** first public working version\n===\n\n
This form upload any file with an UploadService describe in [[Upload]]\n----\n<html><center>\n<form enctype="multipart/form-data" action="store.cgi" method="post" target="_blank">\n <input type="hidden" name="MAX_FILE_SIZE" value="3000000" />\nThis file : <input name="userfile" type="file" /><p>\nOptions* : <input type="text" name="UploadPlugin" size=70 value="backupDir=BACKUP_DIR;user=UPLOAD_USER;password=UPLOAD_PASSWORD;" /><p>\n <input type="submit" value="Upload" />\n</form></center>\n</html>\n----\n * Substitute BACKUP_DIR, UPLOAD_USER and UPLOAD_PASSWORD with your values. See UploadPlugin for option details. \nFor security reason, don't save your password in a tiddler.
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |\n| 17/11/2006 14:3:9 | PeterLindsey | [[empty.htm|file:///H:/Tools/TiddlyWiki/empty.htm]] | [[store.php|http://lindsey.jp/wiki/store.php]] | | empty.htm | |\n| 17/11/2006 14:23:7 | PeterLindsey | [[empty.htm|http://lindsey.jp/wiki/empty.htm]] | [[store.php|http://lindsey.jp/wiki/store.php]] | | empty.htm | | Ok |\n| 17/11/2006 14:31:19 | PeterLindsey | [[empty.htm|http://lindsey.jp/wiki/empty.htm]] | [[store.php|http://lindsey.jp/wiki/store.php]] | | empty.htm | |\n| 17/11/2006 14:32:16 | PeterLindsey | [[empty.htm|http://lindsey.jp/wiki/empty.htm]] | [[store.php|http://lindsey.jp/wiki/store.php]] | | empty.htm | |\n| 20/11/2006 13:36:30 | PeterLindsey | [[empty.htm|http://lindsey.jp/wiki/empty.htm]] | [[store.php|http://lindsey.jp/wiki/store.php]] | | empty.htm | |\n| 20/11/2006 13:42:56 | PeterLindsey | [[empty.htm|http://lindsey.jp/wiki/empty.htm]] | [[store.php|http://lindsey.jp/wiki/store.php]] | | empty.htm | |\n| 20/11/2006 15:49:20 | PeterLindsey | [[empty.htm|http://lindsey.jp/wiki/empty.htm]] | [[store.php|http://lindsey.jp/wiki/store.php]] | | empty.htm | |\n| 20/11/2006 16:0:31 | PeterLindsey | [[empty.htm|http://lindsey.jp/wiki/empty.htm]] | [[store.php|http://lindsey.jp/wiki/store.php]] | .. | index2.html | | Ok |\n| 20/11/2006 16:1:14 | PeterLindsey | [[empty.htm|http://lindsey.jp/wiki/empty.htm]] | [[store.php|http://lindsey.jp/wiki/store.php]] | | ../index2.html | | Ok |\n| 20/11/2006 16:1:44 | PeterLindsey | [[empty.htm|http://lindsey.jp/wiki/empty.htm]] | [[store.php|http://lindsey.jp/wiki/store.php]] | .. | ../index2.html | |\n| 20/11/2006 17:4:40 | PeterLindsey | [[index2.html|http://lindsey.jp/wiki/index2.html]] | [[store.php|http://lindsey.jp/wiki/store.php]] | .. | ../index2.html | | Ok |\n| 20/11/2006 17:13:40 | PeterLindsey | [[index2.html|http://lindsey.jp/wiki/index2.html]] | [[store.php|http://lindsey.jp/wiki/store.php]] | .. | ../index2.html | | Ok |\n| 20/11/2006 17:17:23 | PeterLindsey | [[index2.html|http://lindsey.jp/wiki/index2.html]] | [[store.php|http://lindsey.jp/wiki/store.php]] | .. | ../index2.html | |\n| 21/11/2006 9:1:27 | PeterLindsey | [[7F64461Dd01|file:///C:/Documents%20and%20Settings/Peter%20Lindsey/Local%20Settings/Application%20Data/Mozilla/Firefox/Profiles/ntt0usf7.default/Cache/7F64461Dd01]] | [[store.php|http://lindsey.jp/wiki/store.php]] | | index2.html | |\n| 21/11/2006 9:45:4 | PeterLindsey | [[index2.html|http://lindsey.jp/wiki/index2.html]] | [[store.php|http://lindsey.jp/wiki/store.php]] | | index2.html | | Ok |\n| 21/11/2006 10:1:6 | PeterLindsey | [[index2.html|http://lindsey.jp/wiki/index2.html]] | [[store.php|http://lindsey.jp/wiki/store.php]] | | index2.html | | Ok |\n| 21/11/2006 10:16:57 | PeterLindsey | [[index2.html|http://lindsey.jp/wiki/index2.html]] | [[store.php|http://lindsey.jp/wiki/store.php]] | | index2.html | | Ok |\n| 21/11/2006 10:33:23 | PeterLindsey | [[index2.html|http://lindsey.jp/wiki/index2.html]] | [[store.php|http://lindsey.jp/wiki/store.php]] | | index2.html | | Ok |\n| 21/11/2006 10:53:29 | PeterLindsey | [[index2.html|http://lindsey.jp/wiki/index2.html]] | [[store.php|http://lindsey.jp/wiki/store.php]] | | index2.html | | Ok |\n| 21/11/2006 11:10:50 | PeterLindsey | [[index2.html|http://lindsey.jp/wiki/index2.html]] | [[store.php|http://lindsey.jp/wiki/store.php]] | | index2.html | | Ok |\n| 21/11/2006 12:52:14 | PeterLindsey | [[index2.html|http://lindsey.jp/wiki/index2.html]] | [[store.php|http://lindsey.jp/wiki/store.php]] | | index2.html | |\n| 21/11/2006 18:3:9 | PeterLindsey | [[index2.html|http://www.lindsey.jp/wiki/index2.html]] | [[store.php|http://www.lindsey.jp/wiki/store.php]] | | index2.html | | Ok |\n| 21/11/2006 18:6:7 | PeterLindsey | [[index2.html|http://www.lindsey.jp/wiki/index2.html]] | [[store.php|http://www.lindsey.jp/wiki/store.php]] | | index2.html | |\n| 21/11/2006 18:6:51 | PeterLindsey | [[index2.html|http://www.lindsey.jp/wiki/index2.html]] | [[store.php|http://www.lindsey.jp/wiki/store.php]] | | index2.html | |\n| 21/11/2006 18:14:58 | PeterLindsey | [[index2.html|http://www.lindsey.jp/wiki/index2.html]] | [[store.php|http://www.lindsey.jp/wiki/store.php]] | | index2.html | | Ok |\n| 21/11/2006 18:16:48 | PeterLindsey | [[index2.html|http://www.lindsey.jp/wiki/index2.html]] | [[store.php|http://www.lindsey.jp/wiki/store.php]] | | index2.html | | Ok |\n| 21/11/2006 18:17:28 | PeterLindsey | [[index2.html|http://www.lindsey.jp/wiki/index2.html]] | [[store.php|http://www.lindsey.jp/wiki/store.php]] | | index2.html | | Ok |\n| 21/11/2006 18:50:21 | PeterLindsey | [[index2.html|http://www.lindsey.jp/wiki/index2.html]] | [[store.php|http://www.lindsey.jp/wiki/store.php]] | | index2.html | |
!Options used by UploadPlugin\nUsername: <<option txtUploadUserName>>\nPassword: <<option pasUploadPassword>>\n\nUrl of the UploadService script^^(1)^^: <<option txtUploadStoreUrl 50>>\nRelative Directory where to store the file^^(2)^^: <<option txtUploadDir 50>>\nFilename of the uploaded file^^(3)^^: <<option txtUploadFilename 40>>\nDirectory to backup file on webserver^^(4)^^: <<option txtUploadBackupDir>>\n\n^^(1)^^Mandatory either in UploadOptions or in macro parameter\n^^(2)^^If empty stores in the script directory\n^^(3)^^If empty takes the actual filename\n^^(4)^^If empty existing file with same name on webserver will be overwritten\n\n<<upload>> with these options.\n\n!Upload Macro parameters\n{{{\n<<upload [storeUrl [toFilename [backupDir [uploadDir [username]]]]]>>\n Optional positional parameters can be passed to overwrite \n UploadOptions. \n}}}\n\n
/***\n|''Name:''|UploadPlugin|\n|''Description:''|Save to web a TiddlyWiki|\n|''Version:''|3.4.5|\n|''Date:''|Oct 15, 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: 5, \n date: new Date(2006,9,15),\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");\nif (document.location.toString().substr(0,4) == "http") {\n config.options.chkAutoSave = false; \n saveOptionCookie('chkAutoSave');\n}\nconfig.shadowTiddlers.UploadDoc = "[[Full Documentation|http://tiddlywiki.bidix.info/l#UploadDoc ]]\sn"; \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
<<tiddler UploadDoc>>
/***\n|''Name:''|UploadPluginMsgEN|\n|''Description:''|English Translation|\n|''Date:''|Sep 20, 2006|\n|''Source:''|http://tiddlywiki.bidix.info/#UploadPluginMsgEN|\n|''Author:''|BidiX (BidiX (at) bidix (dot) info) with modifications by YannPerrin|\n|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|\n|''Include:''|none|\n|''Require:''|UploadPlugin 3.4.3|\n***/\n/***\n!Usage : \nFor an english translation of UploadPlugin Message when using PolyGlotPlugin, import this tiddler in the TiddlyWiki. Make sure it is tagged with {{{en}}} and {{{linguo}}}. \nComments and suggestions are welcome.\n***/\n//{{{\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 issue: 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.saveChanges.label = config.macros.upload.label.saveToDisk;\n//}}}\n
/***\n|''Name:''|UploadPluginMsgFR|\n|''Description:''|French Translation|\n|''Date:''|Sep 20, 2006|\n|''Source:''|http://tiddlywiki.bidix.info/#UploadPluginMsgEN|\n|''Author:''|BidiX (BidiX (at) bidix (dot) info) with modifications by YannPerrin|\n|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|\n|''Include:''|none|\n|''Require:''|UploadPlugin 3.4.3|\n***/\n/***\n!Usage : \nFor a french translation of UploadPlugin Message when using PolyGlotPlugin, import this tiddler in the TiddlyWiki. Make sure it is tagged with {{{fr}}} and {{{linguo}}}. \nComments and suggestions are welcome.\n***/\n//{{{\nconfig.macros.upload.messages = {\n aboutToUpload: "Préparation du téléchargement le TiddlyWiki vers %0",\n backupFileStored: "Fichier précedent sauvegardé dans %0",\n crossDomain: "Certainement un problème d'accès cross-domaine: l'accès à un autre site n'est pas autorisé",\n errorDownloading: "Erreur de téléchargement de %0 depuis le serveur",\n errorUploadingContent: "Erreur de téléchargement vers le serveur du contenu",\n fileLocked: "Fichier est réservé: vous n'êtes pas autorisé à le mettre à jour",\n fileNotFound: "Fichier à télécharger vers le serveur non trouvé",\n fileNotUploaded: "Le fichier %0 N'A PAS été téléchargé vers le serveur",\n mainFileUploaded: "Le fichier TiddlyWiki a été téléchargé vers le serveur %0",\n passwordEmpty: "Impossible de télécharger, vous n'avez pas fourni de mot de passe.",\n urlParamMissing: "Paramètre URL manquant",\n rssFileNotUploaded: "Le fichier Rss %0 N'A PAS été téléchargé vers le serveur",\n rssFileUploaded: "Le fichier RSS a été téléchargé vers %0"\n};\n\nconfig.macros.upload.label = { \n promptOption: "Sauvegarde et télécharge ce TiddlyWiki avec les UploadOptions",\n promptParamMacro: "Sauvegarde et télécharge ce TiddlyWiki vers %0",\n saveLabel: "sauvegarde sur le web", \n saveToDisk: "sauvegarde sur le disque",\n uploadLabel: "Télécharge vers le web"\n};\n\nconfig.macros.saveChanges.label = config.macros.upload.label.saveToDisk;\n//}}}\n
Hi there. This is the web site of PeterLindsey, where you can find all manner of ravings, music, pictures and stuff related to my hobbies.\n
# config.rb - configuration du site\n# version : 1.0.0 - 02/08/2006 - BidiX@BidiX.info\n# Copyright (c) BidiX@BidiX.info 2006\n\nCONFIG = {\n :users => {\n 'UserName1'=>'Password1',\n 'UserName2'=>'Password2',\n 'UserName3'=>'Password3'\n },\n :authenticateUser => true,\n :backupExistingFile => true,\n :withUploadDir => true,\n :checkLock => true,\n :permittedFileNames => false # %w[index.html index.xml], # false means any filename\n}\n
#!/usr/bin/ruby\n# store.cgi - store command\n# version : 1.1.3 - 2006/11/1 - BidiX@BidiX.info\n# Copyright (c) BidiX@BidiX.info 2006\n#\n# this file provides the full UploadService as a single ruby cgi file\n# CONFIGs must be adjust, especially Users. \n# \n# Comments and suggestions are welcome.\n#---------------------------------------\n#$LOAD_PATH\n$: << '../lib'\n# require 'config'\n# config.rb could be a separate file\n#---------------------------------------\n#\n# config.rb - configuration du site\n# version : 1.0.0 - 02/08/2006 - BidiX@BidiX.info\n# Copyright (c) BidiX@BidiX.info 2006\n\nCONFIG = {\n :users => {\n 'UserName1'=>'Password1',\n 'UserName2'=>'Password2',\n 'UserName3'=>'Password3'\n },\n :authenticateUser => true,\n :backupExistingFile => true,\n :withUploadDir => true,\n :checkLock => true,\n :permittedFileNames => false # %w[index.html index.xml], # false means any filename\n}\n#---------------------------------------\n# require 'lock' \n# lock.rb could be a separate file\n#---------------------------------------\n#\n\nLOCK_CONFIG = {\n :defaultFile => 'index.html',\n :lockSuffix => '.lock'\n}\n\nrequire 'cgi'\n\nclass Lock\n attr_reader :username, :mtime, :locktime\n def initialize(file, lockSuffix)\n @file = file\n @lockfile = @file + lockSuffix\n @username = ''\n @mtime = 0\n @locktime = 0\n begin\n @mtime = File.new(@file).mtime.to_i\n rescue\n @mtime = 0\n end\n _readLockfile\n end\n \n def _readLockfile\n @username = ''\n @locktime = 0\n if File.exists?(@lockfile)\n line = ''\n File.open(@lockfile, 'r') do |f|\n @locktime = f.mtime.to_i\n line = f.read()\n end\n @username = line.split(':')[0]\n end\n end\n \n def isLock?()\n ! (@username == '')\n end\n \n def lock(username)\n File.open(@lockfile, 'w') do |f|\n f.write("#{username}:#{@mtime}")\n end\n @username = username\n @locktime = File.new(@lockfile).mtime.to_i\n end \n\n def unlock()\n File.delete(@lockfile)\n @username = ''\n @locktime = 0\n end\n\n def status()\n @username\n end\n\n def _display()\n @username+':'+@mtime.to_s+":"+@locktime.to_s\n end \n \nend\n\nclass Locker < CGI\n \n def initialize(siteConfig)\n super\n file = @params['file'].first || LOCK_CONFIG[:defaultFile]\n @username = @params['username'].first\n @uploadUsername = @params['uploadUsername'].first\n @uploadPassword = @params['uploadPassword'].first\n @action = @params['action'].first || 'status'\n @lock = Lock.new(file, LOCK_CONFIG[:lockSuffix])\n @siteConfig = siteConfig # for siteConfig[:users][@uploadUsername] == \n end\n \n def authenticateUser() \n if @siteConfig[:users][@uploadUsername] != @uploadPassword\n out() {"Error : Username or Password do not match \snUser: #{@uploadUsername} Password: #{@uploadPassword}"}\n return false\n else \n return true\n end\n end\n\n def display()\n if @lock.isLock?\n "File locked by: #{@lock.username}<br>\sn\s\n File modified at: #{Time.at(@lock.mtime.to_i)} (#{@lock.mtime})<br>\sn\s\n File locked at: #{Time.at(@lock.locktime.to_i)} (#{@lock.locktime})"\n else\n "Not locked"\n end\n end\n\n def respond\n begin\n case @action \n \n when 'lock'\n if authenticateUser\n if @lock.isLock? \n out() {"This file is already locked by #{@lock.status}.<br>status:#{@lock.status}"}\n elsif @lock.mtime.to_s != @params['mtime'].first\n out() {"This file has changed since you accessed it. You can't lock it."}\n else\n @lock.lock(@username)\n out() {"File locked. Now, only #{@lock.status} can upload it.<br>lock:#{@lock._display}<br>status:#{@lock.status}"}\n end\n end\n when 'display'\n out() {"#{display}"}\n \n when 'status'\n if @lock.isLock?\n out() {"This file is locked by #{@lock.status}.<br>status:#{@lock.status}"}\n else\n out() {"This file is not locked.<br>status:"}\n end\n \n when 'unlock'\n if authenticateUser\n if ! @lock.isLock?\n out() {"This file is not locked.<br>status:"}\n else\n if (@lock.username == @params['username'].first) && (@lock.mtime.to_s == @params['mtime'].first) && (@lock.locktime.to_s == @params['locktime'].first)\n @lock.unlock()\n out() {"This file is now unlocked.<br>status:"}\n else\n out() {"You are not allowed to unlock the file.<br>status:#{@lock.status}"}\n end\n end\n end\n \n when 'forceUnlock'\n if authenticateUser\n if ! @lock.isLock?\n out() {"This file is not locked.<br>status:"}\n else\n @lock.unlock()\n out() {"This file is now unlocked.<br>status:"}\n end\n end \n # when 'help'\n # outputPage\n else\n out() {"action #{@params['action'].first} not found"}\n end\n rescue Exception => e\n out() {"Error in lock : " + e}\n end\n end\nend\n\n#---------------------------------------\n# require 'storer' \n# storer.rb could be a separate file\n#---------------------------------------\n#\n# storer.rb - store a file on a webserver\n# version : 1.1.3 - 2006/10/30- BidiX@BidiX.info\n# \n# see : \n# http://tiddlywiki.bidi.info/#UploadPlugin for details on uploading files\n# usage : \n# POST \n# UploadPlugin[backupDir=<backupdir>;user=<user>;password=<password>;[lockuser=<lockUser>;mtime=<mtime>;locktime=<locktime>]]\n# userfile <file>\n# GET\n# \n# Revision history\n\n# V 1.1.3 - 2006/10/30 :\n# control of empty uploaded file\n# saveFile function that can be overwritten (SimonBaird's request)\n# V 1.1.2 - 02/09/2006 :\n# return mtime, destfile and backupfile after the message line\n# v 1.1.1 - 17/08/2006 :\n# Merge avec DownloadService\n# v 1.1.0 - 28/06/2006 :\n# lock control\n# v 1.0.3 - 08/08/2006 :\n# no backup file if backupDir option is empty\n# V 1.0.2 - 15/08/2006 (DownloadService) :\n# substitue javascript included by download.cgi by filename\n# v 1.0.2 tiddlyspot - 28/06/2006 :\n# added DEFAULT_CONFIG (SimonBaird)\n# V 1.0.1 - 27/06/2006 : \n# improvements by SimonBaird\n# :permittedFileNames\n# rescue clause improvement\n# v 1.0.0 - 26/06/2006 : \n# version compatible with UploadPlugin V 3.3.2\n#\n# Copyright (c) BidiX@BidiX.info 2006\n\n# adjust defaults as required\nDEFAULT_CONFIG = {\n :users => {},\n :authenticateUser => true,\n :backupExistingFile => true,\n :withUploadDir => true,\n :checkLock => true,\n :permittedFileNames => %w[index.html index.xml], # false means any file\n}\n\nrequire 'cgi'\nrequire 'fileutils'\nrequire 'date'\nrequire 'lock'\n\n\nclass Storer < CGI\n \n Storer::PAGE = \n <<-EOP\n <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> \n <html>\n <head>\n <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >\n <title>BidiX.info - TiddlyWiki UploadService - Store script</title>\n </head>\n <body>\n <p>\n <p>store.cgi V 1.1.3\n <p>BidiX@BidiX.info\n <p>&nbsp;</p>\n <p>&nbsp;</p>\n <p>&nbsp;</p>\n <p align="center">This page is designed to upload a <a href="http://www.tiddlywiki.com/">TiddlyWiki<a>.</p>\n <p align="center">for details see : <a href="http://tiddlywiki.bidix.info/#HowToUpload">TiddlyWiki.BidiX.info/#HowToUpload<a>.</p> \n </body>\n </html>\n EOP\n \n def backup()\n @userfile.original_filename.sub(/([^\s.]+).(.*)/, ' ')\n @backupfile = @options['backupDir']+$1+DateTime.now.strftime('.%Y%m%d.%H%M%S0000.')+$2\n FileUtils.mv(@destfile, @backupfile)\n end\n \n def getOptions()\n @userfile = params['userfile'].first \n @destfile = @userfile.original_filename\n uploadOptions = params['UploadPlugin'].first\n @options = {}\n if uploadOptions \n uploadOptions.read.split(';').each do |element| \n (key,value) = element.split('=') \n @options[key] = value\n end\n end\n # puts "Content-Type: text/plain\sn\sn"\n # @options.each_key { |key| puts("#{key}=#{@options[key]}") }\n # @config.each_key { |key| puts("#{key}=#{@config[key]}") }\n # @config[:users].each_key { |key| puts("#{key}=#{@config[:users][key]}") }\n end\n\n def initialize(config)\n super('')\n @config = DEFAULT_CONFIG\n @config.update(config)\n end\n \n def mkDir(dirType)\n if dir = @options[dirType]\n FileUtils.mkdir_p(dir, :mode => 0755)\n if dir.rindex('/') != dir.length-1 # dir end with / \n @options[dirType] += '/'\n end\n else\n @options[dirType] = './'\n end\n end\n\n def outputPage()\n out() {Storer::PAGE}\n end\n \n def respond()\n if (request_method == 'POST')\n getOptions()\n # Autenticate User ?\n if @config[:authenticateUser] && ! (@options['user'] && @options['password'] && (@config[:users][@options['user']] == @options['password']))\n #out() {"Error : Username or Password do not match \snUser: #{@options['user']} Password: #{@options['password']}"}\n out() {"Error : Username or Password do not match \snUser: #{@options['user']}"}\n return\n end\n # File permitted ?\n if @config[:permittedFileNames] && !@config[:permittedFileNames].include?(@destfile)\n raise "filename '#{@destfile}' not permitted" \n end\n # File locked ?\n lock = false\n if @config[:checkLock]\n # Check the lock\n lock = Lock.new(@destfile, '.lock')\n if lock.isLock? && !((@options['lockuser'] == lock.username) && (@options['mtime'] == lock.mtime.to_s) && (@options['locktime'] == lock.locktime.to_s))\n out() {"You are not allowed to upload. The file #{@destfile} is locked by #{lock.username}.\sn"}\n return\n end\n end\n store()\n if lock && lock.isLock?\n lock.unlock\n end\n else\n outputPage()\n end\n end \n \n # recursively replace:\n # <!--DOWNLOAD-INSERT-FILE: "aFile.js"--><script type="text/javascript">aFile.js content</script>\n # with:\n # <script type="text/javascript" src="aFile.js"></script>\n\n def recursiveReplaceJS(content)\n #if content =~ /<!--DOWNLOAD-INSERT-FILE:\s"(.*)\s"--><script\ss+type=\s"text\s/javascript\s">\sn.*\sn<\s/script>/\n if content =~ /<!--DOWNLOAD-INSERT-FILE:\s"([^"]*)\s"--><script\ss+type=\s"text\s/javascript\s">.*?<\s/script>/m\n contentTail = recursiveReplaceJS($')\n #out() {"Found #{$&}"}\n content = $` + "<script type=\s"text/javascript\s" src=\s"#{$1}\s"></script>" + contentTail\n end\n return content\n end\n \n def saveFile(content)\n f = File.open(@destfile,'w')\n f.write(content)\n mtime = f.mtime.to_i\n f.close\n return mtime\n end\n \n \n def store()\n begin\n if @config[:withUploadDir] \n mkDir('uploaddir') \n @destfile = @options['uploaddir'] + @destfile\n end\n if @config[:backupExistingFile] && @options['backupDir']\n mkDir('backupDir')\n if File.exists?(@destfile)\n backup()\n end\n end\n saveThisContent = @userfile.read\n if (!saveThisContent)\n raise "Null content"\n end\n if ( saveThisContent.length == 0)\n raise "Zero length content"\n end\n saveThisContent = recursiveReplaceJS(saveThisContent)\n mtime = saveFile(saveThisContent)\n backupMsg = if @backupfile then "backupfile:#{@backupfile}\sn" else '' end\n out() {"0 - File successfully loaded in #{@destfile}\sndestfile:#{@destfile.sub(/^.\s//,'')}\sn#{backupMsg}mtime:#{mtime}"}\n rescue Exception => e\n out() {"Error in UploadService-storer.rb : " + e}\n end\n end\nend\n#---------------------------------------\n\nstorer = Storer.new(CONFIG)\nstorer.respond\n
<?php\n/***\n! User settings\nEdit these lines according to your need\n***/\n//{{{\n$AUTHENTICATE_USER = true; // true | false\n$USERS = array(\n 'UserName1'=>'Password1', \n 'UserName2'=>'Password2', \n 'UserName3'=>'Password3'); // set usernames and strong passwords\n$DEBUG = false; // true | false\nerror_reporting(E_ERROR | E_WARNING | E_PARSE);\n//}}}\n/***\n!Code\nNo change needed under\n***/\n//{{{\n\n/***\n * store.php - upload a file in this directory\n * version :1.4.3 - 2006/10/17 - BidiX@BidiX.info\n * \n * see : \n * http://tiddlywiki.bidi.info/#UploadPlugin for usage\n * http://www.php.net/manual/en/features.file-upload.php \n * for détails on uploading files\n * usage : \n * POST \n * UploadPlugin[backupDir=<backupdir>;user=<user>;password=<password>;uploadir=<uploaddir>]\n * userfile <file>\n * GET\n *\n * Revision history\n * V 1.4.3 - 2006/10/17 \n * Test if $filename.lock exists for GroupAuthoring compatibility\n * return mtime, destfile and backupfile after the message line\n * V 1.4.2 - 2006/10/12\n * add error_reporting(E_PARSE);\n * v 1.4.1 - 15/03/2006\n * add chmo 0664 on the uploadedFile\n * v 1.4 - 23/02/2006 :\n * add uploaddir option : a path for the uploaded file relative to the current directory\n * backupdir is a relative path\n * make recusively directories if necessary for backupDir and uploadDir\n * v 1.3 - 17/02/2006 :\n * presence and value of user are checked with $USERS Array (thanks to PauloSoares)\n * v 1.2 - 12/02/2006 : \n * POST \n * UploadPlugin[backupDir=<backupdir>;user=<user>;password=<password>;]\n * userfile <file>\n* if $AUTHENTICATE_USER\n * presence and value of user and password are checked with \n * $USER and $PASSWORD\n * v 1.1 - 23/12/2005 : \n * POST UploadPlugin[backupDir=<backupdir>] userfile <file>\n * v 1.0 - 12/12/2005 : \n * POST userfile <file>\n *\n * Copyright (c) BidiX@BidiX.info 2005-2006\n ***/\n//}}}\n\n//{{{\n\nif ($_SERVER['REQUEST_METHOD'] == 'GET') {\n /*\n * GET Request\n */\n ?>\n <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\n <html>\n <head>\n <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >\n <title>BidiX.info - TiddlyWiki UploadPlugin - Store script</title>\n </head>\n <body>\n <p>\n <p>store.php V 1.4.3\n <p>BidiX@BidiX.info\n <p>&nbsp;</p>\n <p>&nbsp;</p>\n <p>&nbsp;</p>\n <p align="center">This page is designed to upload a <a href="http://www.tiddlywiki.com/">TiddlyWiki<a>.</p>\n <p align="center">for details see : <a href="http://TiddlyWiki.bidix.info/#HowToUpload">TiddlyWiki.bidix.info/#HowToUpload<a>.</p> \n </body>\n </html>\n <?php\n}\nelse {\n /*\n * POST Request\n */\n \n // Recursive mkdir\n function mkdirs($dir) {\n if( is_null($dir) || $dir === "" ){\n return false;\n }\n if( is_dir($dir) || $dir === "/" ){\n return true;\n }\n if( mkdirs(dirname($dir)) ){\n return mkdir($dir);\n }\n return false;\n }\n \n // var definitions\n $uploadDir = './';\n $uploadDirError = false;\n $backupError = false;\n $optionStr = $_POST['UploadPlugin'];\n $optionArr=explode(';',$optionStr);\n $options = array();\n $backupFilename = '';\n $filename = $_FILES['userfile']['name'];\n \n // get options\n foreach($optionArr as $o) {\n list($key, $value) = split('=', $o);\n $options[$key] = $value;\n }\n \n // authenticate User\n if ((!$AUTHENTICATE_USER) \n || (($options['user']) && ($options['password']) && ($USERS[$options['user']] == $options['password']))) {\n if (file_exists($filename . ".lock")) {\n echo "LockError : $filename is locked(see: http://tiddlywiki.bidix.info/#GroupAuthoring). \sn";\n exit;\n }\n // make uploadDir\n if ($options['uploaddir']) {\n if (! is_dir($options['uploaddir'])) {\n mkdirs($options['uploaddir']);\n }\n if (! is_dir($options['uploaddir'])) {\n $uploadDirError = "uploadDir mkdir error";\n }\n $uploadDir = $uploadDir . $options['uploaddir'];\n if ($uploadDir{strlen($uploadDir)-1} != '/') {\n $uploadDir = $uploadDir . '/';\n }\n } \n if ($filename)\n if (!$uploadDirError) {\n // backup existing file\n if (file_exists($filename) && ($options['backupDir'])) {\n if (! is_dir($options['backupDir'])) {\n mkdirs($options['backupDir']);\n if (! is_dir($options['backupDir'])) {\n $backupError = "backup mkdir error";\n }\n }\n $backupFilename = $options['backupDir'].'/'.substr($filename, 0, strpos($filename, '.'))\n .date('.Ymd.His').substr($filename,strpos($filename,'.'));\n rename($filename, $backupFilename) or ($backupError = "rename error");\n }\n // move uploaded file to uploadDir\n if (move_uploaded_file($_FILES['userfile']['tmp_name'], $filename)) {\n chmod($filename, 0644);\n if (!$backupError) {\n if($DEBUG) {\n echo "debug mode \sn\sn";\n }\n echo "0 - File successfully loaded in " .$filename. "\sn";\n echo("destfile:$filename \sn");\n if ($backupFilename)\n echo "backupfile:$backupFilename;\sn";\n $mtime = filemtime($filename);\n echo("mtime:$mtime");\n } else {\n echo "BackupError : $backupError - File successfully loaded in " .$filename. "\sn";\n }\n } \n else {\n echo "Error : " . $_FILES['error']." - File NOT uploaded !\sn";\n }\n }\n else {\n echo "UploadDirError : $uploadDirError - File NOT uploaded !\sn";\n }\n }\n else {\n echo "Error : UserName or Password do not match \sn";\n echo "UserName : [".$options['user']. "] Password : [". $options['password'] . "]\sn";\n }\n if ($DEBUG) {\n echo ("\snHere is some debugging info : \sn");\n echo("\s$filename : $filename \sn");\n echo("\s$backupFilename : $backupFilename \sn");\n print ("\s$_FILES : \sn");\n print_r($_FILES);\n print ("\s$options : \sn");\n print_r($options);\n }\n}\n//}}}\n?>