Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
|''Type:''|file|
|''URL:''|http://tiddlywiki.bidix.info/|
|''Workspace:''|(default)|
This tiddler was automatically created to record the details of this server
PasswordOptionPlugin extends the core Options with a non encrypted password type.
Notice:
*How a style can be specified for a specific option in StyleSheet
----
Test Password: <<option pasPassword myPasOptionInput >>
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
major: 1, minor: 0, revision: 2,
date: new Date("Apr 19, 2007"),
source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
coreVersion: '2.2.0 (Beta 5)'
};
config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");
merge(config.macros.option.types, {
'pas': {
elementType: "input",
valueField: "value",
eventName: "onkeyup",
className: "pasOptionInput",
typeValue: config.macros.option.passwordInputType,
create: function(place,type,opt,className,desc) {
// password field
config.macros.option.genericCreate(place,'pas',opt,className,desc);
// checkbox linked with this password "save this password on this computer"
config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);
// text savePasswordCheckboxLabel
place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
},
onChange: config.macros.option.genericOnChange
}
});
merge(config.optionHandlers['chk'], {
get: function(name) {
// is there an option linked with this chk ?
var opt = name.substr(3);
if (config.options[opt])
saveOptionCookie(opt);
return config.options[name] ? "true" : "false";
}
});
merge(config.optionHandlers, {
'pas': {
get: function(name) {
if (config.options["chk"+name]) {
return encodeCookie(config.options[name].toString());
} else {
return "";
}
},
set: function(name,value) {config.options[name] = decodeCookie(value);}
}
});
// need to reload options to load passwordOptions
loadOptionsCookie();
/*
if (!config.options['pasPassword'])
config.options['pasPassword'] = '';
merge(config.optionsDesc,{
pasPassword: "Test password"
});
*/
//}}}
// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too
<<tiddler UploadPluginDoc>>
This form upload any file with an UploadService describe in [[Upload]]
----
<html><center>
<form enctype="multipart/form-data" action="store.php" method="post" target="_blank">
<input type="hidden" name="MAX_FILE_SIZE" value="3000000" />
This file : <input name="userfile" type="file" /><p>
Options* : <input type="text" name="UploadPlugin" size=80 value="backupDir=BACKUP_DIR;uploaddir=UPLOAD_DIR;user=UPLOAD_USER;password=UPLOAD_PASSWORD;debug=0;" /><p>
<input type="submit" value="Upload" />
</form></center>
</html>
----
* Substitute BACKUP_DIR, UPLOAD_DIR, UPLOAD_USER and UPLOAD_PASSWORD with your values. See UploadPlugin for option details.
For security reason, don't save your password in a tiddler.
UploadPlugin uses the following sequence for finding parameters :
#''macro'' parameters
#''Options'' saved in cookies
#''Plugin'' default values
!Options used by UploadPlugin
| Option | Value | Default |
|Upload Username: |<<option txtUploadUserName>>| |
|Upload Password: |<<option pasUploadPassword>>| |
|Url of the UploadService script: |<<option txtUploadStoreUrl urlInput>>| store.php |
|Relative Directory where to store the file: |<<option txtUploadDir urlInput>>| . (the script directory) |
|Filename of the uploaded file: |<<option txtUploadFilename urlInput>>| index.html |
|Directory to backup file on webserver^^(1)^^: |<<option txtUploadBackupDir urlInput>>| //null// (none/no backup) |
|Log in UploadLog |<<option chkUploadLog>> Trace Upload| true |
|Maximum of lines in UploadLog |<<option txtUploadLogMaxLine>>| 10 |
^^(1)^^No backup if Backup Directory is empty, the previous file will be overwritten. Use a '.' to backup in the script directory.
<<upload>> with these options.
!Upload Macro parameters
{{{
<<upload [storeUrl [toFilename [backupDir [uploadDir [username]]]]]>>
Optional positional parameters can be passed to overwrite UploadOptions.
}}}
!UploadToFile Macro Macro parameters
{{{
<<uploadTofile [filename [tiddlerTitle]]>>
tiddlerTitle, filename: if omitted the title of the current tiddler
}}}
<<uploadToFile allowedsites.txt allowedsites.txt>>
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.4|
|''Date:''|2008-08-11|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
major: 4, minor: 1, revision: 4,
date: new Date("2008-08-11"),
source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0'
};
//
// Environment
//
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false; // true to activate both in Plugin and UploadService
//
// Upload Macro
//
config.macros.upload = {
// default values
defaultBackupDir: '', //no backup
defaultStoreScript: "store.php",
defaultToFilename: "index.html",
defaultUploadDir: ".",
authenticateUser: true // UploadService Authenticate User
};
config.macros.upload.label = {
promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
promptParamMacro: "Save and Upload this TiddlyWiki in %0",
saveLabel: "save to web",
saveToDisk: "save to disk",
uploadLabel: "upload"
};
config.macros.upload.messages = {
noStoreUrl: "No store URL in parmeters or options",
usernameOrPasswordMissing: "Username or password missing"
};
config.macros.upload.handler = function(place,macroName,params) {
if (readOnly)
return;
var label;
if (document.location.toString().substr(0,4) == "http")
label = this.label.saveLabel;
else
label = this.label.uploadLabel;
var prompt;
if (params[0]) {
prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0],
(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
} else {
prompt = this.label.promptOption;
}
createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};
config.macros.upload.action = function(params)
{
// for missing macro parameter set value from options
if (!params) params = {};
var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
var username = params[4] ? params[4] : config.options.txtUploadUserName;
var password = config.options.pasUploadPassword; // for security reason no password as macro parameter
// for still missing parameter set default value
if ((!storeUrl) && (document.location.toString().substr(0,4) == "http"))
storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
if (storeUrl.substr(0,4) != "http")
storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
if (!toFilename)
toFilename = bidix.basename(window.location.toString());
if (!toFilename)
toFilename = config.macros.upload.defaultToFilename;
if (!uploadDir)
uploadDir = config.macros.upload.defaultUploadDir;
if (!backupDir)
backupDir = config.macros.upload.defaultBackupDir;
// report error if still missing
if (!storeUrl) {
alert(config.macros.upload.messages.noStoreUrl);
clearMessage();
return false;
}
if (config.macros.upload.authenticateUser && (!username || !password)) {
alert(config.macros.upload.messages.usernameOrPasswordMissing);
clearMessage();
return false;
}
bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password);
return false;
};
config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir)
{
if (!storeUrl)
return null;
var dest = bidix.dirname(storeUrl);
if (uploadDir && uploadDir != '.')
dest = dest + '/' + uploadDir;
dest = dest + '/' + toFilename;
return dest;
};
//
// uploadOptions Macro
//
config.macros.uploadOptions = {
handler: function(place,macroName,params) {
var wizard = new Wizard();
wizard.createWizard(place,this.wizardTitle);
wizard.addStep(this.step1Title,this.step1Html);
var markList = wizard.getElement("markList");
var listWrapper = document.createElement("div");
markList.parentNode.insertBefore(listWrapper,markList);
wizard.setValue("listWrapper",listWrapper);
this.refreshOptions(listWrapper,false);
var uploadCaption;
if (document.location.toString().substr(0,4) == "http")
uploadCaption = config.macros.upload.label.saveLabel;
else
uploadCaption = config.macros.upload.label.uploadLabel;
wizard.setButtons([
{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption,
onClick: config.macros.upload.action},
{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
]);
},
options: [
"txtUploadUserName",
"pasUploadPassword",
"txtUploadStoreUrl",
"txtUploadDir",
"txtUploadFilename",
"txtUploadBackupDir",
"chkUploadLog",
"txtUploadLogMaxLine"
],
refreshOptions: function(listWrapper) {
var opts = [];
for(i=0; i<this.options.length; i++) {
var opt = {};
opts.push();
opt.option = "";
n = this.options[i];
opt.name = n;
opt.lowlight = !config.optionsDesc[n];
opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
opts.push(opt);
}
var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
for(n=0; n<opts.length; n++) {
var type = opts[n].name.substr(0,3);
var h = config.macros.option.types[type];
if (h && h.create) {
h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
}
}
},
onCancel: function(e)
{
backstage.switchTab(null);
return false;
},
wizardTitle: "Upload with options",
step1Title: "These options are saved in cookies in your browser",
step1Html: "<input type='hidden' name='markList'></input><br>",
cancelButton: "Cancel",
cancelButtonPrompt: "Cancel prompt",
listViewTemplate: {
columns: [
{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
{name: 'Option', field: 'option', title: "Option", type: 'String'},
{name: 'Name', field: 'name', title: "Name", type: 'String'}
],
rowClasses: [
{className: 'lowlight', field: 'lowlight'}
]}
};
//
// upload functions
//
if (!bidix.upload) bidix.upload = {};
if (!bidix.upload.messages) bidix.upload.messages = {
//from saving
invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
backupSaved: "Backup saved",
backupFailed: "Failed to upload backup file",
rssSaved: "RSS feed uploaded",
rssFailed: "Failed to upload RSS feed file",
emptySaved: "Empty template uploaded",
emptyFailed: "Failed to upload empty template file",
mainSaved: "Main TiddlyWiki file uploaded",
mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
//specific upload
loadOriginalHttpPostError: "Can't get original file",
aboutToSaveOnHttpPost: 'About to upload on %0 ...',
storePhpNotFound: "The store script '%0' was not found."
};
bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
var callback = function(status,uploadParams,original,url,xhr) {
if (!status) {
displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
return;
}
if (bidix.debugMode)
alert(original.substr(0,500)+"\n...");
// Locate the storeArea div's
var posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
bidix.upload.uploadRss(uploadParams,original,posDiv);
};
if(onlyIfDirty && !store.isDirty())
return;
clearMessage();
// save on localdisk ?
if (document.location.toString().substr(0,4) == "file") {
var path = document.location.toString();
var localPath = getLocalPath(path);
saveChanges();
}
// get original
var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
var originalPath = document.location.toString();
// If url is a directory : add index.html
if (originalPath.charAt(originalPath.length-1) == "/")
originalPath = originalPath + "index.html";
var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
var log = new bidix.UploadLog();
log.startUpload(storeUrl, dest, uploadDir, backupDir);
displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
if (bidix.debugMode)
alert("about to execute Http - GET on "+originalPath);
var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
bidix.upload.uploadRss = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
if(status) {
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
bidix.upload.uploadMain(params[0],params[1],params[2]);
} else {
displayMessage(bidix.upload.messages.rssFailed);
}
};
// do uploadRss
if(config.options.chkGenerateAnRssFeed) {
var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
var rssString = generateRss();
// no UnicodeToUTF8 conversion needed when location is "file" !!!
if (document.location.toString().substr(0,4) != "file")
rssString = convertUnicodeToUTF8(rssString);
bidix.upload.httpUpload(rssUploadParams,rssString,callback,Array(uploadParams,original,posDiv));
} else {
bidix.upload.uploadMain(uploadParams,original,posDiv);
}
};
bidix.upload.uploadMain = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
var log = new bidix.UploadLog();
if(status) {
// if backupDir specified
if ((params[3]) && (responseText.indexOf("backupfile:") > -1)) {
var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
}
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
store.setDirty(false);
log.endUpload("ok");
} else {
alert(bidix.upload.messages.mainFailed);
displayMessage(bidix.upload.messages.mainFailed);
log.endUpload("failed");
}
};
// do uploadMain
var revised = bidix.upload.updateOriginal(original,posDiv);
bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};
bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
var localCallback = function(status,params,responseText,url,xhr) {
url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
if (xhr.status == 404)
alert(bidix.upload.messages.storePhpNotFound.format([url]));
if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
alert(responseText);
if (responseText.indexOf("Debug mode") >= 0 )
responseText = responseText.substring(responseText.indexOf("\n\n")+2);
} else if (responseText.charAt(0) != '0')
alert(responseText);
if (responseText.charAt(0) != '0')
status = null;
callback(status,params,responseText,url,xhr);
};
// do httpUpload
var boundary = "---------------------------"+"AaB03x";
var uploadFormName = "UploadPlugin";
// compose headers data
var sheader = "";
sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
sheader += uploadFormName +"\"\r\n\r\n";
sheader += "backupDir="+uploadParams[3] +
";user=" + uploadParams[4] +
";password=" + uploadParams[5] +
";uploaddir=" + uploadParams[2];
if (bidix.debugMode)
sheader += ";debug=1";
sheader += ";;\r\n";
sheader += "\r\n" + "--" + boundary + "\r\n";
sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
sheader += "Content-Length: " + data.length + "\r\n\r\n";
// compose trailer data
var strailer = new String();
strailer = "\r\n--" + boundary + "--\r\n";
data = sheader + data + strailer;
if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
if (!posDiv)
posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
store.allTiddlersAsHtml() + "\n" +
original.substr(posDiv[1]);
var newSiteTitle = getPageTitle().htmlEncode();
revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
return revised;
};
//
// UploadLog
//
// config.options.chkUploadLog :
// false : no logging
// true : logging
// config.options.txtUploadLogMaxLine :
// -1 : no limit
// 0 : no Log lines but UploadLog is still in place
// n : the last n lines are only kept
// NaN : no limit (-1)
bidix.UploadLog = function() {
if (!config.options.chkUploadLog)
return; // this.tiddler = null
this.tiddler = store.getTiddler("UploadLog");
if (!this.tiddler) {
this.tiddler = new Tiddler();
this.tiddler.title = "UploadLog";
this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
this.tiddler.created = new Date();
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
}
return this;
};
bidix.UploadLog.prototype.addText = function(text) {
if (!this.tiddler)
return;
// retrieve maxLine when we need it
var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
if (isNaN(maxLine))
maxLine = -1;
// add text
if (maxLine != 0)
this.tiddler.text = this.tiddler.text + text;
// Trunck to maxLine
if (maxLine >= 0) {
var textArray = this.tiddler.text.split('\n');
if (textArray.length > maxLine + 1)
textArray.splice(1,textArray.length-1-maxLine);
this.tiddler.text = textArray.join('\n');
}
// update tiddler fields
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
// refresh and notifiy for immediate update
story.refreshTiddler(this.tiddler.title);
store.notify(this.tiddler.title, true);
};
bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {
if (!this.tiddler)
return;
var now = new Date();
var text = "\n| ";
var filename = bidix.basename(document.location.toString());
if (!filename) filename = '/';
text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
text += config.options.txtUserName + " | ";
text += "[["+filename+"|"+location + "]] |";
text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
text += uploadDir + " | ";
text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
text += backupDir + " |";
this.addText(text);
};
bidix.UploadLog.prototype.endUpload = function(status) {
if (!this.tiddler)
return;
this.addText(" "+status+" |");
};
//
// Utilities
//
bidix.checkPlugin = function(plugin, major, minor, revision) {
var ext = version.extensions[plugin];
if (!
(ext &&
((ext.major > major) ||
((ext.major == major) && (ext.minor > minor)) ||
((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
// write error in PluginManager
if (pluginInfo)
pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
}
};
bidix.dirname = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(0, lastpos);
} else {
return filePath.substring(0, filePath.lastIndexOf("\\"));
}
};
bidix.basename = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("#")) != -1)
filePath = filePath.substring(0, lastpos);
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(lastpos + 1);
} else
return filePath.substring(filePath.lastIndexOf("\\")+1);
};
bidix.initOption = function(name,value) {
if (!config.options[name])
config.options[name] = value;
};
//
// Initializations
//
// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);
// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");
//optionsDesc
merge(config.optionsDesc,{
txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
txtUploadUserName: "Upload Username",
pasUploadPassword: "Upload Password",
chkUploadLog: "do Logging in UploadLog (default: true)",
txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});
// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');
// Backstage
merge(config.tasks,{
uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");
//}}}
//last update: UploadPlugin v 4.1.3//
!Description
UploadPlugin with <<tag UploadService>> extend TiddlyWiki with @@upload@@ and @@save to web@@ commands.
UploadPlugin uses Username and Password from UploadOptions stored in cookies to authenticate itself to [[store.php]] or [[store.cgi]].
UploadPlugin requires PasswordOptionPlugin.
French translation available as a separate tiddler UploadPluginMsgFR
!!UploadPlugin
*If the TiddlyWiki is viewed @@from local disk@@ :
**{{{<<upload ...>>}}}
***display as '''upload'''
***after saving to disk, upload to a website.
*If the TiddlyWiki is viewed @@from a website@@ :
**{{{<<upload ...>>}}}
***display as '''save to web'''
***save to the same website.
*If GenerateAnRssFeed in AdvancedOptions is set :
**generate the content of the RSSFeed
**upload the RssFile
**Caution : use the SiteUrl tiddler to specify the right url of the TiddlyWiki in the generated RssFile
*DisplayMessage
*If a backupDir is specified
**and if a file already exists in the uploadDir withe the same fielname, move it in the backup dir and rename it with a timestamp
*if UploadLog is activated every upload action is logged in UploadLog
**only the last maxLines are stored
**if maxLine = -1 no truncation will occured
hint : if UploadLog is the first tiddler in the TimelineTab, no tiddler has been changed since last upload.
!![[store.php]]
*UserVariables to set :
//{{{
$AUTHENTICATE_USER = true; // true | false
$USERS = array(
'UserName1'=>'Password1',
'UserName2'=>'Password2',
'UserName3'=>'Password3'); // set usernames and strong passwords
$DEBUG = false; // true | false
//}}}
*method GET
**display an information page
*method POST
**if $~AUTHENTICATE_USER is ''true''
***presence and value of user and password are checked with $USER and $PASSWORD
**if toFilename already exists and backDir parameter specified
***rename toFilename to backupDir/toFilename.AAAAMMDD.HHSS.html
**copy temporaryUploadedFile toFilename
**return status
!![[store.cgi]]
*UserVariables to set :
//{{{
CONFIG = {
:users => {
'UserName1'=>'Password1',
'UserName2'=>'Password2',
'UserName3'=>'Password3')
},
:authenticateUser => true,
:backupExistingFile => true,
:withUploadDir => true
}
//}}}
*same processing as store.php above
!Usage :
{{{
<<upload>>
uses UploadOptions saved in cookies :
txtUploadUserName: username
pasUploadPassword : password
txtUploadStoreUrl : store script
txtUploadDir : relative path for upload directory
txtUploadFilename : upload filename
txtUploadBackupDir : relative path for backup directory
<<upload [storeUrl [toFilename [backupDir [uploadDir [username]]]]]>>
Optional positional parameters can be passed to overwrite
UploadOptions.
}}}
Suggestion: Install the {{{<<upload ... >>}}} macro in SideBarOptions just below {{{<<saveChanges>>}}} macro.
!User manual
See HowToUpload
!Installation :
*Install the UploadPlugin as usual
*[[Upload]] the [[store.php]] file on your php aware webserver in your TiddlyWiki directory
*Protect your server against malicious upload. Two approaches :
**set $~AUTHENTICATE_USER to true in the [[store.php]] script
***configure $USER and $PASSWORD in the [[store.php]] script on your webserver
***set UploadOptions in conformity with [[store.php]]
**Use server protection :
***for Apache web server ([[for detail see Apache documentation|http://httpd.apache.org/docs/1.3/howto/htaccess.html]]) :
****configure and upload the [[.htaccess]] [[.passwd]]
***for other web servers see the appropriate documentation
*Configure an upload button, for example in the SideBarOptions
!Suppported Browser
*Firefox and Gecko based browser: tested Ok
*Internet Explorer : tested Ok
*Safari : tested ok on OS X
*Others : Not tested, please report status.
!Revision history
<<tiddler UploadPluginRevisionHistory>>
UploadTiddlerPlugin and [[storeTiddler.php]] "upload" or "save to web" a single tiddler by updating, inserting or deleting a single tiddler in a TiddlyWiki file located on the web.
@@Now UploadTiddlerPlugin is able to Upload a Tiddler even if TiddlyWiki is located on a local file.@@
![[UploadTiddlerPlugin]]
*is activated by @@chkUploadTiddler option: <<option chkUploadTiddler>>@@
* to be abe to Upload a Tiddler even if the TiddlyWiki is located on local file@@chkUploadTiddlerFromFile option: <<option chkUploadTiddlerFromFile>>@@
*uses @@txtUploadTiddlerStoreUrl: <<option txtUploadTiddlerStoreUrl>>@@
*override TiddlyWiki.prototype.saveTiddler and deleteTiddler core functions
*uses the same options as UploadPlugin.
*do an XmlHttpRequest POST to storeTiddler.php only with the corresponding tiddler in storeArea format.
![[storeTiddler.php]]
*Username and password are checked
*[[storeTiddler.php]] parses TiddlyWiki file
*tiddler is updated, inserted or deleted in the tiddler array
*optionally create and clean backup file
*write updated TiddlyWiki file
!UploadTiddlerPlugin and UploadPlugin
*The paradigm of UploadTiddlerPlugin and [[storeTiddler.php]] is exactly the same as UploadPlugin and [[store.php]]
*No concurrency managed
*Full compatible with UploadPlugin
*[[storeTiddler.php]] can be use to remotly update a TiddlyWiki. storeTiddler.php
*a GET to [[storeTiddler.php]] display a form to upload a tiddler in a TiddlyWiki
/***
|''Name:''|UploadTiddlerMacro|
|''Description:''|Define a macro to upload a tiddler using UploadTiddlerPlugin (see UploadTiddlerPlugin for details).|
|''Version:''|1.0.0|
|''Date:''|2008-09-30|
|''Source:''|http://tiddlywiki.bidix.info/#UploadTiddlerMacro|
|''Usage:''|{{{<<uploadTiddler [tiddlerTitle]>>}}}<br>{{{tiddlerTitle: if omitted the title of the current tiddler}}}|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''CoreVersion:''|2.2.0|
|''Requires:''|UploadTiddlerPlugin|
***/
//{{{
version.extensions.UploadTiddlerMacro = {
major: 1, minor: 0, revision: 0,
date: new Date("2008-09-30"),
source: 'http://tiddlywiki.bidix.info/#UploadTiddlerMacro',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0'
};
config.macros.uploadTiddler = {
label: "uploadTiddler",
prompt: "upload tiddler '%0' using UploadTiddlerOptions ",
warning: "Are you sure you want to upload '%0'?",
messages: {
fileUploaded: "tiddler '%0' uploaded to file '%1'",
fileNotUploaded: "tiddler '%0' NOT uploaded"
},
handler: function(place, macroName, params, wikifier,paramString, tiddler) {
var tiddlerTitle = params[0];
if (!tiddlerTitle) {
tiddlerTitle = tiddler.title;
} else {
tiddler = store.getTiddler(tiddlerTitle);
}
createTiddlyButton(place, this.label, this.prompt.format([tiddlerTitle]),
function () {
config.macros.uploadTiddler.upload(tiddlerTitle, tiddler);
return false;},
null, null, null);
},
upload: function(tiddlerTitle, tiddler) {
var saved_chkUploadTiddler = config.options.chkUploadTiddler;
config.options.chkUploadTiddler = true;
bidix.uploadTiddler.upload(tiddlerTitle, tiddler,tiddlerTitle);
config.options.chkUploadTiddler = saved_chkUploadTiddler;
}
};
//
// Utilities
//
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.checkPlugin = function(plugin, major, minor, revision) {
var ext = version.extensions[plugin];
if (!
(ext &&
((ext.major > major) ||
((ext.major == major) && (ext.minor > minor)) ||
((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
// write error in PluginManager
if (pluginInfo)
pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
}
};
//
// Initializations
//
// require UploadTiddlerPlugin 1.2.2 or better
bidix.checkPlugin("UploadTiddlerPlugin", 1, 2, 2);
//}}}
/***
|''Name:''|UploadTiddlerPlugin|
|''Description:''|Upload a tiddler and Update a remote TiddlyWiki |
|''Version:''|1.2.2|
|''Date:''|2008-09-13|
|''Source:''|http://tiddlywiki.bidix.info/#UploadTiddlerPlugin|
|''Usage:''|Uses {{{<<uploadOptions>>}}}<br>with those UploadTiddler Options : <br>chkUploadTiddler: <<option chkUploadTiddler>><br>txtUploadTiddlerStoreUrl: <<option txtUploadTiddlerStoreUrl>><br>chkUploadTiddlerFromFile: <<option chkUploadTiddlerFromFile>>|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''[[License]]:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''CoreVersion:''|2.3.0|
***/
//{{{
version.extensions.UploadTiddlerPlugin = {
major: 1, minor: 2, revision: 2,
date: new Date("2008-09-13"),
source: 'http://tiddlywiki.bidix.info/#UploadTiddlerPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.3.0'
};
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false;
bidix.uploadTiddler = {
messages: {
aboutToSaveTiddler: "About to update tiddler '%0'...",
aboutToRemotelySaveTiddler: "About to REMOTELY update tiddler '%0'...",
storeTiddlerNotFound: "Script store tiddler '%0' not found",
tiddlerSaved: "Tiddler '%0' updated in '%1' using '%2' "
},
upload: function(title,tiddler,oldTitle) {
var callback = function(status,params,responseText,url,xhr) {
if (xhr.status == 404) {
alert(bidix.uploadTiddler.messages.storeTiddlerNotFound.format([url]));
return;
}
if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
alert(responseText);
if (responseText.indexOf("Debug mode") >= 0 )
responseText = responseText.substring(responseText.indexOf("\n\n")+2);
} else if (responseText.charAt(0) != '0')
alert(responseText);
else
displayMessage(bidix.uploadTiddler.messages.tiddlerSaved.format([params[0], params[1], params[2]]));
store.setDirty(false);
}
if ((config.options['chkUploadTiddler']) &&
((document.location.toString().substr(0,4) == "http") || config.options['chkUploadTiddlerFromFile'])) {
clearMessage();
if (document.location.toString().substr(0,4) != "http")
displayMessage(bidix.uploadTiddler.messages.aboutToRemotelySaveTiddler.format([title]));
else
displayMessage(bidix.uploadTiddler.messages.aboutToSaveTiddler.format([title]));
var ExtTiddler = null;
var html = null;
if (tiddler) {
ExtTiddler = store.getSaver().externalizeTiddler(store,tiddler);
html = wikifyStatic(tiddler.text,null,tiddler).htmlEncode();
}
var form = "title="+encodeURIComponent(title);
form = form + "&tiddler="+(ExtTiddler?encodeURIComponent(ExtTiddler):'');
form = form + "&html="+(html?encodeURIComponent(html):'');
var filename = (config.options['txtUploadFilename']?config.options['txtUploadFilename']:'index.html');
form = form +"&oldTitle="+encodeURIComponent(oldTitle);
form = form +"&fileName="+encodeURIComponent(filename);
form = form +"&backupDir="+encodeURIComponent(config.options['txtUploadBackupDir']);
form = form +"&user="+encodeURIComponent(config.options['txtUploadUserName']);
form = form +"&password="+encodeURIComponent(config.options['pasUploadPassword']);
form = form +"&uploadir="+encodeURIComponent(config.options['txtUploadDir']);
form = form +"&debug="+encodeURIComponent(0);
var storeScript = (config.options.txtUploadTiddlerStoreUrl
? config.options.txtUploadTiddlerStoreUrl : 'storeTiddler.php');
var r = doHttp("POST",storeScript,form+"\n",'application/x-www-form-urlencoded',
config.options['txtUploadUserName'],config.options['pasUploadPassword'],callback,Array(title,filename, storeScript),null);
}
}
}
TiddlyWiki.prototype.saveTiddler_bidix = TiddlyWiki.prototype.saveTiddler;
TiddlyWiki.prototype.saveTiddler = function(oldTitle,newTitle,newBody,modifier,modified,tags,fields,clearChangeCount,created) {
var tiddler = TiddlyWiki.prototype.saveTiddler_bidix.apply(this,arguments);
var title = (newTitle?newTitle:oldTitle);
if (oldTitle == title)
oldTitle = '';
bidix.uploadTiddler.upload(title, tiddler, oldTitle);
}
TiddlyWiki.prototype.removeTiddler_bidix =TiddlyWiki.prototype.removeTiddler;
TiddlyWiki.prototype.removeTiddler = function(title) {
TiddlyWiki.prototype.removeTiddler_bidix.apply(this,arguments);
bidix.uploadTiddler.upload(title, null);
}
//
// Initializations
//
bidix.initOption = function(name,value) {
if (!config.options[name])
config.options[name] = value;
};
// styleSheet
setStylesheet('.txtUploadTiddlerStoreUrl {width: 22em;}',"uploadTiddlerPluginStyles");
//optionsDesc
merge(config.optionsDesc,{
txtUploadTiddlerStoreUrl: "Url of the UploadTiddlerService script (default: storeTiddler.php)",
chkUploadTiddler: "Do per Tiddler upload using txtUploadTiddlerStoreUrl (default: false)",
chkUploadTiddlerFromFile: "Upload tiddler even if TiddlyWiki is located on local file (default: false)"
});
// Options Initializations
bidix.initOption('txtUploadTiddlerStoreUrl','');
bidix.initOption('chkUploadTiddler','');
bidix.initOption('chkUploadTiddlerFromFile','');
// add options in backstage UploadOptions
if (config.macros.uploadOptions) {
if (config.macros.uploadOptions.options) {
config.macros.uploadOptions.options.push("txtUploadTiddlerStoreUrl","chkUploadTiddler", "chkUploadTiddlerFromFile");
}
}
//}}}
/***
|''Name:''|UploadToFileMacro|
|''Description:''|Upload a tiddler as a file using UploadPlugin context. Used with the SimonBaird's HideWhenPlugin ViewTemplate provides a new command in the tiddler toolbar.|
|''Version:''|2.0.1|
|''Date:''|Apr 21, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#UploadToFileMacro|
|''Usage:''|{{{<<uploadTofile [filename [tiddlerTitle]]>>}}}<br>{{{tiddlerTitle, filename: if omitted the title of the current tiddler}}}|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''CoreVersion:''|2.2.0|
|''Requires:''|UploadPlugin|
***/
//{{{
version.extensions.UploadToFileMacro = {
major: 2, minor: 0, revision: 1,
date: new Date("Apr 21, 2007"),
source: 'http://tiddlywiki.bidix.info/#UploadToFilePlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0'
};
// require UploadPlugin 4.0.0 or better
config.macros.uploadToFile = {
label: "upload %0 to file %1",
prompt: "upload tiddler '%0' to file '%1' ",
warning: "Are you sure you want to upload '%0'?",
messages: {
fileUploaded: "tiddler '%0' uploaded to file '%1'",
fileNotUploaded: "tiddler '%0' NOT uploaded"
},
handler: function(place, macroName, params, wikifier,paramString, tiddler) {
// parameters initialization
var toFilename = params[0];
var tiddlerTitle = params[1];
if (!tiddlerTitle) {
tiddlerTitle = tiddler.title;
} else {
tiddler = store.getTiddler(tiddlerTitle);
}
if (!toFilename) {
toFilename = tiddlerTitle;
}
var prompt = this.prompt.format([tiddlerTitle, toFilename]);
createTiddlyButton(place, this.label.format([params[1], params[0]]), this.prompt.format([tiddlerTitle, toFilename]),
function () {
config.macros.uploadToFile.upload(tiddler, null, toFilename);
return false;},
null, null, null);
},
upload: function(tiddler, storeUrl, toFilename, uploadDir, backupDir, username, password) {
if (!tiddler) {
alert("Tiddler not found.");
return false;
}
var uploadIt = true;
if ((this.warning) && (!confirm(this.warning.format([tiddler.title]))))
return false;
// parameters initialization
storeUrl = (storeUrl ? storeUrl : config.options.txtUploadStoreUrl);
toFilename = (toFilename ? toFilename : tiddler.title);
backupDir = (backupDir ? backupDir : config.options.txtUploadBackupDir);
uploadDir = (uploadDir ? uploadDir : config.options.txtUploadDir);
username = (username ? username : config.options.txtUploadUserName);
password = (password ? password :config.options.pasUploadPassword);
var callback = function(status,params,responseText,url,xhr) {
if (status) {
if (responseText.substring(0,1) == '0') {
// if backupDir specified
if ((params[3]) && (responseText.indexOf("backupfile:") > -1)) {
var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,
responseText.indexOf("\n", responseText.indexOf("backupfile:")));
displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
}
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,
responseText.indexOf("\n", responseText.indexOf("destfile:")));
if (destfile.substring(0,2) == './')
destfile = destfile.substring(2);
displayMessage(config.macros.uploadToFile.messages.fileUploaded.format([params[6],destfile]),
bidix.dirname(url)+'/'+destfile);
} else {
alert(responseText);
displayMessage(config.macros.uploadToFile.messages.fileNotUploaded.format([params[1]]));
}
} else {
displayMessage("HTTP Error " + xhr.status + " in accessing " + url);
}
};
var uploadParams = Array(storeUrl,toFilename,uploadDir,backupDir,username,password, tiddler.title);
return bidix.upload.httpUpload(uploadParams,tiddler.text,callback,uploadParams);
}
};
bidix.checkPlugin = function(plugin, major, minor, revision) {
var ext = version.extensions[plugin];
if (!
(ext &&
((ext.major > major) ||
((ext.major == major) && (ext.minor > minor)) ||
((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
// write error in PluginManager
if (pluginInfo)
pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
}
};
//
// Initializations
//
// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("UploadPlugin", 4, 0, 0);
//}}}
/***
|''Name:''|UploadToHomeMacro|
|''Description:''|Save TiddlyWiki using HomeParameters tiddler|
|''Version:''|0.0.2|
|''Date:''|May 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#UploadToHomeMacro|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (#2125)|
|''Requires:''|UploadPlugin|
|''Usage:''|{{{<<uploadToHome [HomeParameters]>>}}}<br>{{{HomeParameters:}}} optional - Tiddler with upload parameters in slices (see HomeParameters).|
***/
//{{{
version.extensions.UploadToHomeMacro = {
major: 0, minor: 0, revision: 2,
date: new Date("May 19, 2007"),
source: 'http://tiddlywiki.bidix.info/#UploadToHomeMacro',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0 (#3125)'
};
//
// Environment
//
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false; // true to activate both in Plugin and UploadService
bidix.checkPlugin("UploadPlugin", 4, 1, 0);
//
// uploadUsing Macro
//
config.macros.uploadToHome = {
handler: function(place,macroName,params) {
if (readOnly)
return;
var label;
if (document.location.toString().substr(0,4) == "http")
label = config.macros.upload.label.saveLabel;
else
label = config.macros.upload.label.uploadLabel;
var prompt;
var homeParams = (params[0] ? params[0]:this.messages.homeParamsTiddler);
if (store.tiddlerExists(homeParams) || store.isShadowTiddler(homeParams)) {
prompt = this.messages.prompt.toString().format([homeParams]);
} else {
throw(this.messages.tiddlerNotFound.toString().format([homeParams]));
}
var prompt = this.messages.prompt.toString().format([homeParams]);
createTiddlyButton(place, label, prompt, function() {config.macros.uploadToHome.action(homeParams);}, null, null, this.accessKey);
},
action: function(homeParams) {
homeParams = (homeParams ? homeParams : config.macros.uploadToHome.messages.homeParamsTiddler);
if (!store.tiddlerExists(homeParams) && !store.isShadowTiddler(homeParams)) {
throw(config.macros.uploadToHome.messages.tiddlerNotFound.toString().format([homeParams]));
}
config.macros.upload.action(config.macros.uploadToHome.getParamsFromTiddler(homeParams));
},
getParamsFromTiddler: function(tiddlerTitle) {
tiddlerTitle = (tiddlerTitle ? tiddlerTitle:this.messages.homeParamsTiddler);
if (!store.tiddlerExists(tiddlerTitle) && !store.isShadowTiddler(tiddlerTitle)) {
throw(config.macros.uploadToHome.messages.tiddlerNotFound.toString().format([tiddlerTitle]));
}
var sliceNames = [
"UploadStoreUrl",
"UploadFilename",
"UploadBackupDir",
"UploadDir",
"UploadUserName"
//"UploadPassword", // no password in tiddlers
];
var sliceValues = store.getTiddlerSlices(tiddlerTitle,sliceNames);
var parameters = [];
for(var i=0; i<sliceNames.length; i++) {
parameters.push(sliceValues[sliceNames[i]]);
}
return parameters;
},
messages: {
homeParamsTiddler: "HomeParameters",
prompt: "Save and Upload this TiddlyWiki using parameters in '%0' tiddler",
tiddlerNotFound: "Tiddler %0 not found"
},
initAtLoad: function () {
// install Shadowed HomeParameters
var storeUrl;
if ((document.location.toString().substr(0,4) == "http"))
storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
else
storeUrl = config.macros.upload.defaultStoreScript;
var shadowedHomeParameters = (config.shadowTiddlers['HomeParameters']?config.shadowTiddlers['HomeParameters']:'');
shadowedHomeParameters += [
"|UploadUserName:|"+config.options['txtUploadUserName']+"|",
"|UploadStoreUrl:|"+storeUrl+"|",
"|UploadDir:|.|",
"|UploadFilename:|index.html|",
"|UploadBackupDir:||"
].join("\n");
merge(config.shadowTiddlers,{'HomeParameters': shadowedHomeParameters});
// install Backstage uploadToHome
merge(config.tasks,{
uploadToHome: {text: "uploadToHome", tooltip: "Upload using '" + this.messages.homeParamsTiddler + "' tiddler", action: this.action}
});
config.backstageTasks.push("uploadToHome");
}
};
config.macros.uploadToHome.initAtLoad();
//}}}
<?php
//{{{
/***
* download.php - download an html file as an attachement.
* version:1.1.1 - 2008/08/22 - BidiX@BidiX.info
* source: http://tiddlywiki.bidix.info/#download.php
* license: BSD open source license (http://tiddlywiki.bidix.info/#[[BSD open source license]])
*
* Simply put [[download|download.php?]] in your TiddlyWiki viewed over http to download it in one click*.
* * If it is named index.html
* usage :
* http://host/path/to/download.php[?file=afile.html|?help]
* afile.html : for security reason, must be a file with an .html suffix
* ?file=afile.html : if not specified index.html is used
* ?help : display the "usage" message
*
* each external javascript file is included in the downloaded file
***/
function display($msg) {
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>BidiX.info - TiddlyWiki - download script</title>
</head>
<body>
<p>
<p>download.php V 1.1.0
<p>BidiX@BidiX.info
<p> </p>
<p> </p>
<p> </p>
<p align="center"><?=$msg?></p>
<p align="center">Usage : http://<?=$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']?>[?file=<i>afile.html</i>]. If no file is specified uses index.html</p>
<p align="center">for details see : <a href="http://TiddlyWiki.bidix.info/#download.php">TiddlyWiki.bidix.info/#download.php<a>.</p>
</body>
</html>
<?php
return;
}
/*
* Recusrsively for each external javascript
* - Insert a comment : DOWNLOAD-INSERT-FILE
* - insert the content of the file
*/
function insertJSFileIn($content) {
// if (preg_match ('<script\s+type=\"text\/javascript\"\s+src=\"')) {
if (preg_match ('/<script\s+type=\"text\/javascript\"\s+src=\"/ms', $content)) {
if (preg_match ('/^(.*?)<script\s+type=\"text\/javascript\"\s+src=\"(.+?)\"\s*>\s*<\/script>(.*)$/ms', $content,$matches)) {
$front = $matches[1];
$js = $matches[2];
$tail = $matches[3];
$jsContent = "<!--DOWNLOAD-INSERT-FILE:\"$js\"--><script type=\"text/javascript\">" .
file_get_contents ($js) .
"\n</script>";
$tail = insertJSFileIn($tail);
return($front.$jsContent.$tail);
}
}
return $content;
}
/*
* Main
*/
// help command
if (array_key_exists('help',$_GET)) {
display('');
exit;
}
// file command
$filename = $_GET['file'];
if ($filename == "") {
$filename='index.html';
}
if (!preg_match('/\.html$/',$filename )) {
display("The file $filename could not be downloaded. Only .html file are allowed.");
exit;
}if (!is_file($filename)) {
display("The file $filename could not be found.");
exit;
}
$content = insertJSFileIn(file_get_contents ($filename));
//return the file
header('Pragma: private');
header('Cache-control: private, must-revalidate');
header('Content-type: text/html');
header('Content-Disposition: attachment; filename='.$filename);
echo($content);
//}}}
?>
<?php
//{{{
/***
* [[proxy.php]] - access an url if the target host is allowed
* version: 2.2.0 - 2007/08/03 - BidiX@BidiX.info
* source: http://tiddlywiki.bidix.info/#proxy.php
* license: BSD open source license (http://tiddlywiki.bidix.info/#[[BSD open source license]])
* Copyright (c) BidiX@BidiX.info 2006-2007
*
* usage:
* proxy.php?url=<hostAndParameters>
* return the corresponding url if the host is included in the <ALLOWED_SITE_FILENAME> file
* or is in the same domain
* proxy.php?list
* list all allowedHosts
* proxy.cgi[?help]
* Display an help page
*
* require:
* <ALLOWED_SITE_FILENAME> a file located on the server containing a list af allowed hosts
* each host on a separate line.
* example :
* www.tiddlywiki.com
* tiddliwiki.bidix.info
* tiddlyspot.com
***/
$ALLOWED_SITE_FILENAME = '[[allowedsites.txt]]';
error_reporting(E_ERROR | E_PARSE);
function display($msg) {
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>BidiX.info - TiddlyWiki - proxy script</title>
</head>
<body>
<p>
<p>proxy.php V 2.2.0
<p>BidiX@BidiX.info
<p> </p>
<p> </p>
<p> </p>
<p align="center"><?=$msg?></p>
<p align="center">Usage : http://<?=$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']?>[?url=<i>URL</i>|help|list].</p>
<p align="center">for details see : <a href="http://TiddlyWiki.bidix.info/#proxy.php">TiddlyWiki.bidix.info/#proxy.php<a>.</p>
</body>
</html>
<?php
return;
}
function domain($host) {
// get last two segments of host name
// See : http://fr2.php.net/manual/en/function.preg-match.php#id5827438
preg_match('/[^.]+\.[^.]+$/', $host, $matches);
return $matches[0];
}
function inMyDomain($host) {
return (domain($_SERVER['HTTP_HOST']) == domain($host));
}
function isAllowed($host) {
global $ALLOWED_SITE_FILENAME;
// load allowed hosts
$allowedHosts = array_map('rtrim',file($ALLOWED_SITE_FILENAME));
if (!$allowedHosts) {
echo("allowedSites file '$ALLOWED_SITE_FILENAME' is not found or empty.");
exit;
}
return in_array($host, $allowedHosts);
}
/*
* Main
*/
// help command
if (array_key_exists('help',$_GET)) {
display('');
exit;
}
// list command
if (array_key_exists('list',$_GET)) {
echo "<h3>Hosts allowed through this proxy :</h3>\n<ul>\n";
$allowedHosts = array_map('rtrim',file($ALLOWED_SITE_FILENAME));
foreach ($allowedHosts as $host)
echo("<li>$host</li>\n");
echo "</ul>\n";
exit;
}
// url command
//control url
$url = $_GET['url'];
if (!$url) {
display('');
exit;
}
if (substr($url, 0, 4) != 'http')
$url = 'http://'.$url;
$urlArray = parse_url($url);
if (!$urlArray) {
echo("URL '$url' is not well formed");
exit;
}
$host = strtolower($urlArray['host']);
if (isset($urlArray['port']))
$port = $urlArray['port'];
else
$port = '80';
$file = $urlArray['path'];
if (isset($urlArray['query']))
$file = $file.'?'.$urlArray['query'];
if (isset($urlArray['fragment']))
$file = $file.'#'.$urlArray['fragment'];
// is $host allowed ?
if (!inMyDomain($host) && !isAllowed($host)) {
echo("Host '$host' is not allowed.");
exit;
}
// GET $file at $host:$port
// grab $headers and $content
$fp = fsockopen($host, $port, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)\n";
} else {
$out = "GET $file HTTP/1.1\r\n";
$out .= "Host: $host\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
$fheader = 1;
$headers = "";
$content_type = "";
$content = "";
while (!feof($fp)) {
$line = fgets($fp, 128);
//Grab the headers
if ($fheader == 1) {
if ($line == "\r\n") {
$fheader = 0;
} else {
//Assemble the headers
$headers .= $line;
//grab content_type
if (preg_match("/Content-Type: (\w+\/\w+)(.*)/i", $line, $matches)) {
$content_type = $line;
}
}
} else {
//Grab the page content
$content .= $line;
}
}
fclose($fp);
}
header($content_type);
echo ($content);
//}}}
<?php
/***
! User settings
Edit these lines according to your need
***/
//{{{
$AUTHENTICATE_USER = true; // true | false
$USERS = array(
'UserName1'=>'Password1',
'UserName2'=>'Password2',
'UserName3'=>'Password3'); // set usernames and strong passwords
$DEBUG = false; // true | false
$CLEAN_BACKUP = true; // during backuping a file, remove overmuch backups
$FOLD_JS = true; // if javascript files have been expanded during download the fold them
error_reporting(E_ERROR | E_WARNING | E_PARSE);
//}}}
/***
!Code
No change needed under
***/
//{{{
/***
* store.php - upload a file in this directory
* version :1.6.1 - 2007/08/01 - BidiX@BidiX.info
*
* see :
* http://tiddlywiki.bidi.info/#UploadPlugin for usage
* http://www.php.net/manual/en/features.file-upload.php
* for details on uploading files
* usage :
* POST
* UploadPlugin[backupDir=<backupdir>;user=<user>;password=<password>;uploadir=<uploaddir>;[debug=1];;]
* userfile <file>
* GET
*
* each external javascript file included by download.php is change by a reference (src=...)
*
* Revision history
* V1.6.1 - 2007/08/01
* Enhancement: Add javascript folding
* V1.6.0 - 2007/05/17
* Enhancement: Add backup management
* V1.5.2 - 2007/02/13
* Enhancement: Add optional debug option in client parameters
* V1.5.1 - 2007/02/01
* Enhancement: Check value of file_uploads in php.ini. Thanks to Didier Corbière
* V1.5.0 - 2007/01/15
* Correct: a bug in moving uploadFile in uploadDir thanks to DaniGutiérrez for reporting
* Refactoring
* V 1.4.3 - 2006/10/17
* Test if $filename.lock exists for GroupAuthoring compatibility
* return mtime, destfile and backupfile after the message line
* V 1.4.2 - 2006/10/12
* add error_reporting(E_PARSE);
* v 1.4.1 - 2006/03/15
* add chmo 0664 on the uploadedFile
* v 1.4 - 2006/02/23
* add uploaddir option : a path for the uploaded file relative to the current directory
* backupdir is a relative path
* make recusively directories if necessary for backupDir and uploadDir
* v 1.3 - 2006/02/17
* presence and value of user are checked with $USERS Array (thanks to PauloSoares)
* v 1.2 - 2006/02/12
* POST
* UploadPlugin[backupDir=<backupdir>;user=<user>;password=<password>;]
* userfile <file>
* if $AUTHENTICATE_USER
* presence and value of user and password are checked with
* $USER and $PASSWORD
* v 1.1 - 2005/12/23
* POST UploadPlugin[backupDir=<backupdir>] userfile <file>
* v 1.0 - 2005/12/12
* POST userfile <file>
*
* Copyright (c) BidiX@BidiX.info 2005-2007
***/
//}}}
//{{{
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
/*
* GET Request
*/
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>BidiX.info - TiddlyWiki UploadPlugin - Store script</title>
</head>
<body>
<p>
<p>store.php V 1.6.1
<p>BidiX@BidiX.info
<p> </p>
<p> </p>
<p> </p>
<p align="center">This page is designed to upload a <a href="http://www.tiddlywiki.com/">TiddlyWiki<a>.</p>
<p align="center">for details see : <a href="http://TiddlyWiki.bidix.info/#HowToUpload">TiddlyWiki.bidix.info/#HowToUpload<a>.</p>
</body>
</html>
<?php
exit;
}
/*
* POST Request
*/
// Recursive mkdir
function mkdirs($dir) {
if( is_null($dir) || $dir === "" ){
return false;
}
if( is_dir($dir) || $dir === "/" ){
return true;
}
if( mkdirs(dirname($dir)) ){
return mkdir($dir);
}
return false;
}
function toExit() {
global $DEBUG, $filename, $backupFilename, $options;
if ($DEBUG) {
echo ("\nHere is some debugging info : \n");
echo("\$filename : $filename \n");
echo("\$backupFilename : $backupFilename \n");
print ("\$_FILES : \n");
print_r($_FILES);
print ("\$options : \n");
print_r($options);
}
exit;
}
function ParseTWFileDate($s) {
// parse date element
preg_match ( '/^(\d\d\d\d)(\d\d)(\d\d)\.(\d\d)(\d\d)(\d\d)/', $s , $m );
// make a date object
$d = mktime($m[4], $m[5], $m[6], $m[2], $m[3], $m[1]);
// get the week number
$w = date("W",$d);
return array(
'year' => $m[1],
'mon' => $m[2],
'mday' => $m[3],
'hours' => $m[4],
'minutes' => $m[5],
'seconds' => $m[6],
'week' => $w);
}
function cleanFiles($dirname, $prefix) {
$now = getdate();
$now['week'] = date("W");
$hours = Array();
$mday = Array();
$year = Array();
$toDelete = Array();
// need files recent first
$files = Array();
($dir = opendir($dirname)) || die ("can't open dir '$dirname'");
while (false !== ($file = readdir($dir))) {
if (preg_match("/^$prefix/", $file))
array_push($files, $file);
}
$files = array_reverse($files);
// decides for each file
foreach ($files as $file) {
$fileTime = ParseTWFileDate(substr($file,strpos($file, '.')+1,strrpos($file,'.') - strpos($file, '.') -1));
if (($now['year'] == $fileTime['year']) &&
($now['mon'] == $fileTime['mon']) &&
($now['mday'] == $fileTime['mday']) &&
($now['hours'] == $fileTime['hours']))
continue;
elseif (($now['year'] == $fileTime['year']) &&
($now['mon'] == $fileTime['mon']) &&
($now['mday'] == $fileTime['mday'])) {
if (isset($hours[$fileTime['hours']]))
array_push($toDelete, $file);
else
$hours[$fileTime['hours']] = true;
}
elseif (($now['year'] == $fileTime['year']) &&
($now['mon'] == $fileTime['mon'])) {
if (isset($mday[$fileTime['mday']]))
array_push($toDelete, $file);
else
$mday[$fileTime['mday']] = true;
}
else {
if (isset($year[$fileTime['year']][$fileTime['mon']]))
array_push($toDelete, $file);
else
$year[$fileTime['year']][$fileTime['mon']] = true;
}
}
return $toDelete;
}
function replaceJSContentIn($content) {
if (preg_match ("/(.*?)<!--DOWNLOAD-INSERT-FILE:\"(.*?)\"--><script\s+type=\"text\/javascript\">(.*)/ms", $content,$matches)) {
$front = $matches[1];
$js = $matches[2];
$tail = $matches[3];
if (preg_match ("/<\/script>(.*)/ms", $tail,$matches2)) {
$tail = $matches2[1];
}
$jsContent = "<script type=\"text/javascript\" src=\"$js\"></script>";
$tail = replaceJSContentIn($tail);
return($front.$jsContent.$tail);
}
else
return $content;
}
// Check if file_uploads is active in php config
if (ini_get('file_uploads') != '1') {
echo "Error : File upload is not active in php.ini\n";
toExit();
}
// var definitions
$uploadDir = './';
$uploadDirError = false;
$backupError = false;
$optionStr = $_POST['UploadPlugin'];
$optionArr=explode(';',$optionStr);
$options = array();
$backupFilename = '';
$filename = $_FILES['userfile']['name'];
$destfile = $filename;
// get options
foreach($optionArr as $o) {
list($key, $value) = split('=', $o);
$options[$key] = $value;
}
// debug activated by client
if ($options['debug'] == 1) {
$DEBUG = true;
}
// authenticate User
if (($AUTHENTICATE_USER)
&& ((!$options['user']) || (!$options['password']) || ($USERS[$options['user']] != $options['password']))) {
echo "Error : UserName or Password do not match \n";
echo "UserName : [".$options['user']. "] Password : [". $options['password'] . "]\n";
toExit();
}
// make uploadDir
if ($options['uploaddir']) {
$uploadDir = $options['uploaddir'];
// path control for uploadDir
if (!(strpos($uploadDir, "../") === false)) {
echo "Error: directory to upload specifies a parent folder";
toExit();
}
if (! is_dir($uploadDir)) {
mkdirs($uploadDir);
}
if (! is_dir($uploadDir)) {
echo "UploadDirError : $uploadDirError - File NOT uploaded !\n";
toExit();
}
if ($uploadDir{strlen($uploadDir)-1} != '/') {
$uploadDir = $uploadDir . '/';
}
}
$destfile = $uploadDir . $filename;
// backup existing file
if (file_exists($destfile) && ($options['backupDir'])) {
if (! is_dir($options['backupDir'])) {
mkdirs($options['backupDir']);
if (! is_dir($options['backupDir'])) {
$backupError = "backup mkdir error";
}
}
$backupFilename = $options['backupDir'].'/'.substr($filename, 0, strrpos($filename, '.'))
.date('.Ymd.His').substr($filename,strrpos($filename,'.'));
rename($destfile, $backupFilename) or ($backupError = "rename error");
// remove overmuch backup
if ($CLEAN_BACKUP) {
$toDelete = cleanFiles($options['backupDir'], substr($filename, 0, strrpos($filename, '.')));
foreach ($toDelete as $file) {
$f = $options['backupDir'].'/'.$file;
if($DEBUG) {
echo "delete : ".$options['backupDir'].'/'.$file."\n";
}
unlink($options['backupDir'].'/'.$file);
}
}
}
// move uploaded file to uploadDir
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $destfile)) {
if ($FOLD_JS) {
// rewrite the file to replace JS content
$fileContent = file_get_contents ($destfile);
$fileContent = replaceJSContentIn($fileContent);
if (!$handle = fopen($destfile, 'w')) {
echo "Cannot open file ($destfile)";
exit;
}
if (fwrite($handle, $fileContent) === FALSE) {
echo "Cannot write to file ($destfile)";
exit;
}
fclose($handle);
}
chmod($destfile, 0644);
if($DEBUG) {
echo "Debug mode \n\n";
}
if (!$backupError) {
echo "0 - File successfully loaded in " .$destfile. "\n";
} else {
echo "BackupError : $backupError - File successfully loaded in " .$destfile. "\n";
}
echo("destfile:$destfile \n");
if (($backupFilename) && (!$backupError)) {
echo "backupfile:$backupFilename\n";
}
$mtime = filemtime($destfile);
echo("mtime:$mtime");
}
else {
echo "Error : " . $_FILES['error']." - File NOT uploaded !\n";
}
toExit();
//}}}
?>
<?php
/***
! User settings
Edit these lines according to your need
***/
//{{{
$AUTHENTICATE_USER = true; // true | false
$USERS = array(
'UserName1'=>'Password1',
'UserName2'=>'Password2',
'UserName3'=>'Password3'); // set usernames and strong passwords
$DEBUG = false; // true | false
$CLEAN_BACKUP = true; // during backuping a file, remove overmuch backups
error_reporting(E_ERROR | E_WARNING | E_PARSE);
//}}}
/***
!Code
No change needed under
***/
//{{{
/***
* storeTiddler.php - upload a tiddler to a TiddlyWiki file in this directory
* version: 1.2.1 - 2008-05-06 - BidiX@BidiX.info
*
* tiddler is POST as <FORM> with :
* FORM =
* title=<the title of the tiddler>
* tiddler=<result of externalizeTiddler() : the div in StoreArea format>
* [oldTitle=<the previous title of the tiddler>]
* [fileName=<tiddlyWiki filename>] (default: index.html)
* [backupDir=<backupdir>] (default: .)
* [user=<user>] (no default)
* [password=<password>] (no default)
* [uploadir=<uploaddir>] (default: .)
* [debug=1]] (default: false)
* see :
* http://tiddlywiki.bidi.info/#UploadTiddlerPlugin for usage
* http://tiddlywiki.bidi.info/#UploadPlugin for parameter descriptions
* usage :
* POST FORM
* Update <tiddler> in <fileName> TiddlyWiki
* GET
* Display a form for
*
* Revision history
* V1.2.1 - 2008-05-06
* bug correction : Filename is always 'index.html'. The fileName variable isn't used to initialize tiddlyWiki filename.
* V1.2.0 - 2008-03-23
* Exclusive lock to serialize rewrite of file
* V1.1.0 - 2008/03/05
* Delete tiddler with oldTitle
* V1.0.0 - 2008/02/24
* First public Version
* V0.3.0 - 2008/02/23
* minor adjustments
* V0.2.0 - 2008/02/23
* Correction bug on large regex
* V0.1.0 - 2008/02/09
* Initial: First working version
* V0.0.1 - 2008/02/02
* Initial: Proof Of Concept
*
* Copyright (c) BidiX@BidiX.info 2005-2008
***/
//}}}
//{{{
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
/*
* GET Request
*/
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>BidiX.info - TiddlyWiki UploadTiddlerPlugin - Store script</title>
</head>
<body>
<p>
<p>storeTiddler.php V 1.2.0
<p>BidiX@BidiX.info
<p> </p>
<p> </p>
<p> </p>
<p align="center">This page is designed to upload a <a href="http://www.tiddlywiki.com/#Tiddler">Tiddler<a>.</p>
<p align="center">for details see : <a href="http://TiddlyWiki.bidix.info/#HowToUpload">TiddlyWiki.bidix.info/#HowToUpload<a>.</p>
<hr>
<form action="storeTiddler.php" method=POST>
<center>
<table>
<tr>
<td align=RIGHT>Title:</td>
<td><input type=TEXT name="title" size=80></td>
</tr>
<tr>
<td align=RIGHT>Tiddler (in StoreArea format):</td>
<td><TEXTAREA NAME="tiddler" COLS=80 ROWS=10>
<div title="New Tiddler" modifier="BidiX" created="200802161401" tags="test" changecount="1">
<pre>Type the text for 'New Tiddler'</pre>
</div>
</TEXTAREA></td>
</tr>
<tr>
<td align=RIGHT>Old Title:</td>
<td><input type=TEXT name="oldTitle" size=80 value=''></td>
</tr>
<tr>
<td align=RIGHT>fileName:</td>
<td><input type=TEXT name="fileName" size=80></td>
</tr>
<tr>
<td align=RIGHT>backupDir:</td>
<td><input type=TEXT name="backupDir" size=80></td>
</tr>
<tr>
<td align=RIGHT>user:</td>
<td><input type=TEXT name="user" size=80></td>
</tr>
<tr>
<td align=RIGHT>password:</td>
<td><input type=TEXT name="password" size=80></td>
</tr>
<tr>
<td align=RIGHT>uploadir:</td>
<td><input type=TEXT name="uploadir" size=80></td>
</tr>
<tr>
<td align=RIGHT>debug:</td>
<td><input type=TEXT name="debug" size=80 value=1></td>
</tr>
</table>
<input type=SUBMIT align="CENTER" value="Upload tiddler">
</center>
</form>
</body>
</html>
<?php
exit;
}
/*
* POST Request
*/
/*
* Functions included from store.php
*/
// Recursive mkdir
function mkdirs($dir) {
if( is_null($dir) || $dir === "" ){
return false;
}
if( is_dir($dir) || $dir === "/" ){
return true;
}
if( mkdirs(dirname($dir)) ){
return mkdir($dir);
}
return false;
}
function toExit() {
global $DEBUG, $filename, $backupFilename, $options;
if ($DEBUG) {
echo ("\nHere is some debugging info : \n");
echo("\$filename : $filename \n");
echo("\$backupFilename : $backupFilename \n");
print ("\$_FILES : \n");
print_r($_FILES);
print ("\$options : \n");
print_r($options);
}
exit;
}
function ParseTWFileDate($s) {
// parse date element
preg_match ( '/^(\d\d\d\d)(\d\d)(\d\d)\.(\d\d)(\d\d)(\d\d)/', $s , $m );
// make a date object
$d = mktime($m[4], $m[5], $m[6], $m[2], $m[3], $m[1]);
// get the week number
$w = date("W",$d);
return array(
'year' => $m[1],
'mon' => $m[2],
'mday' => $m[3],
'hours' => $m[4],
'minutes' => $m[5],
'seconds' => $m[6],
'week' => $w);
}
function cleanFiles($dirname, $prefix) {
$now = getdate();
$now['week'] = date("W");
$hours = Array();
$mday = Array();
$year = Array();
$toDelete = Array();
// need files recent first
$files = Array();
($dir = opendir($dirname)) || die ("can't open dir '$dirname'");
while (false !== ($file = readdir($dir))) {
if (preg_match("/^$prefix/", $file))
array_push($files, $file);
}
$files = array_reverse($files);
// decides for each file
foreach ($files as $file) {
$fileTime = ParseTWFileDate(substr($file,strpos($file, '.')+1,strrpos($file,'.') - strpos($file, '.') -1));
if (($now['year'] == $fileTime['year']) &&
($now['mon'] == $fileTime['mon']) &&
($now['mday'] == $fileTime['mday']) &&
($now['hours'] == $fileTime['hours']))
continue;
elseif (($now['year'] == $fileTime['year']) &&
($now['mon'] == $fileTime['mon']) &&
($now['mday'] == $fileTime['mday'])) {
if (isset($hours[$fileTime['hours']]))
array_push($toDelete, $file);
else
$hours[$fileTime['hours']] = true;
}
elseif (($now['year'] == $fileTime['year']) &&
($now['mon'] == $fileTime['mon'])) {
if (isset($mday[$fileTime['mday']]))
array_push($toDelete, $file);
else
$mday[$fileTime['mday']] = true;
}
else {
if (isset($year[$fileTime['year']][$fileTime['mon']]))
array_push($toDelete, $file);
else
$year[$fileTime['year']][$fileTime['mon']] = true;
}
}
return $toDelete;
}
/*
* End Functions included from store.php
*/
/*
* parse and print a TiddlyWiki file
*/
Function readTiddlyWiki($tw) {
if (preg_match ("/(.*?<div id=\"storeArea\">.*?)(<div.*)/ms", $tw,$matches)) {
$head = $matches[1];
$h = $matches[2];
$tiddlers = array();
while (preg_match ("/(.*?)(<div title=\"(.*?)\".*?<\/div>)(.*)/ms", $h,$matches)) {
$h=$matches[4];
$tiddlers[$matches[3]] = $matches[2];
}
$tail = ltrim($h);
}
else {
echo("The file '$file' isn't a valid TiddlyWiki");
toExit();
}
return array($head, $tiddlers ,$tail);
}
Function writeTiddlyWiki($head,$tiddlers,$tail) {
$content = $head;
sort($tiddlers);
foreach ($tiddlers as $t => $c) {
$content .= $c . "\n";
}
$content .= $tail;
return $content;
}
// var definitions
$uploadDir = './';
$uploadDirError = false;
$backupError = false;
$backupFilename = '';
$filename = "index.html";
$destfile = $filename;
$options = $_POST; // for store.php name compatibility
// debug activated by client
if ($options['debug'] == 1) {
$DEBUG = true;
}
// authenticate User
if (($AUTHENTICATE_USER)
&& ((!$options['user']) || (!$options['password']) || ($USERS[$options['user']] != $options['password']))) {
echo "Error : UserName or Password do not match \n";
echo "UserName : [".$options['user']. "] Password : [". $options['password'] . "]\n";
toExit();
}
if ($options['fileName'])
$filename = $options['fileName'];
// make uploadDir
if ($options['uploaddir']) {
$uploadDir = $options['uploaddir'];
// path control for uploadDir
if (!(strpos($uploadDir, "../") === false)) {
echo "Error: directory to upload specifies a parent folder";
toExit();
}
if (! is_dir($uploadDir)) {
mkdirs($uploadDir);
}
if (! is_dir($uploadDir)) {
echo "UploadDirError : $uploadDirError - File NOT uploaded !\n";
toExit();
}
if ($uploadDir{strlen($uploadDir)-1} != '/') {
$uploadDir = $uploadDir . '/';
}
}
$destfile = $uploadDir . $filename;
// backup existing file
if (file_exists($destfile) && ($options['backupDir'])) {
if (! is_dir($options['backupDir'])) {
mkdirs($options['backupDir']);
if (! is_dir($options['backupDir'])) {
$backupError = "backup mkdir error";
}
}
$backupFilename = $options['backupDir'].'/'.substr($filename, 0, strrpos($filename, '.'))
.date('.Ymd.His').substr($filename,strrpos($filename,'.'));
copy($destfile, $backupFilename) or ($backupError = "rename error");
// remove overmuch backup
if ($CLEAN_BACKUP) {
$toDelete = cleanFiles($options['backupDir'], substr($filename, 0, strrpos($filename, '.')));
foreach ($toDelete as $file) {
$f = $options['backupDir'].'/'.$file;
if($DEBUG) {
echo "delete : ".$options['backupDir'].'/'.$file."\n";
}
unlink($options['backupDir'].'/'.$file);
}
}
}
if (file_exists($destfile)) {
$f = fopen($destfile,'r+');
if (flock($f, LOCK_EX)) {
while (!feof($f)) {
$contents .= fread($f, 8192);
}
list($head,$tiddlers,$tail) = readTiddlyWiki($contents);
$title = $_POST['title'];
$oldTitle = $_POST['oldTitle'];
if ($oldTitle && ($title != $oldTitle)) {
unset($tiddlers[$oldTitle]);
}
$tiddlers[$title] = stripslashes($_POST['tiddler']);
$contents = writeTiddlyWiki($head,$tiddlers,$tail);
if (!rewind($f)) {
echo("rewind error");
toExit();
}
if (!ftruncate($f, 0)) {
echo("ftruncate error");
toExit();
};
if (!fwrite($f, $contents)) {
echo("fwrite error");
toExit();
}
fclose($f); // fclose also unlock the file
if($DEBUG) {
echo "Debug mode \n\n";
}
if (!$backupError) {
echo "0 - Tiddler successfully updated in " .$destfile. "\n";
} else {
echo "BackupError : $backupError - Tiddler successfully updated in " .$destfile. "\n";
}
echo("destfile:$destfile \n");
if (($backupFilename) && (!$backupError)) {
echo "backupfile:$backupFilename\n";
}
$mtime = filemtime($destfile);
echo("mtime:$mtime");
}
else {
echo "Error : '" . $filename . "' couldn't be locked - File NOT updated !\n";
}
}
else {
echo "Error : '" . $filename . "' doesn't exist - File NOT updated !\n";
}
toExit();
?>
UploadPlugin uses the following sequence for finding parameters :
#''macro'' parameters
#''Options'' saved in cookies
#''Plugin'' default values
!Options used by UploadPlugin
| Option | Value | Default |
|Upload Username: |<<option txtUploadUserName>>| |
|Upload Password: |<<option pasUploadPassword>>| |
|Url of the UploadService script: |<<option txtUploadStoreUrl urlInput>>| store.php |
|Relative Directory where to store the file: |<<option txtUploadDir urlInput>>| . (the script directory) |
|Filename of the uploaded file: |<<option txtUploadFilename urlInput>>| index.html |
|Directory to backup file on webserver^^(1)^^: |<<option txtUploadBackupDir urlInput>>| //null// (none/no backup) |
|Log in UploadLog |<<option chkUploadLog>> Trace Upload| true |
|Maximum of lines in UploadLog |<<option txtUploadLogMaxLine>>| 10 |
^^(1)^^No backup if Backup Directory is empty, the previous file will be overwritten. Use a '.' to backup in the script directory.
<<upload>> with these options.
!Upload Macro parameters
{{{
<<upload [storeUrl [toFilename [backupDir [uploadDir [username]]]]]>>
Optional positional parameters can be passed to overwrite UploadOptions.
}}}
!UploadToFile Macro Macro parameters
{{{
<<uploadTofile [filename [tiddlerTitle]]>>
tiddlerTitle, filename: if omitted the title of the current tiddler
}}}
<<uploadToFile allowedsites.txt allowedsites.txt>>