|
<!-- fotolife.wsf --> |
|
<job id="InputBoxInJS"> |
|
<!-- http://stackoverflow.com/questions/532138/prompt-dialog --> |
|
<script language="VBScript"> |
|
Function VBInputBox(promptText) |
|
VBInputBox = InputBox(promptText) |
|
End Function |
|
</script> |
|
|
|
<script language="JScript"> |
|
var shell = new ActiveXObject("WScript.Shell"); |
|
var env = shell.Environment("Process"); |
|
|
|
var watchFolder = { |
|
'drive' : 'C:', |
|
'path' : env.Item('HOMEPATH') + '\\Pictures\\screenshot\\' |
|
}; |
|
|
|
var hatena = { |
|
user: null, |
|
password: null, |
|
rkm : null |
|
}; |
|
|
|
hatena.login = function() { |
|
if (!this.name) this.name = VBInputBox('Hatena user name (leave blank to abort)'); |
|
if (!this.name) return false; |
|
if (!this.password) this.password = VBInputBox('Hatena password (leave blank to abort)'); |
|
if (!this.password) return false; |
|
|
|
var xhr = new ActiveXObject("Msxml2.XMLHTTP"); |
|
xhr.open('POST', 'https://www.hatena.ne.jp/login', false); |
|
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); |
|
xhr.send('persistent=1&name=' + encodeURIComponent(this.name) + '&password=' + encodeURIComponent(this.password)); |
|
|
|
return true; |
|
}; |
|
|
|
hatena.verifyLogin = function() { |
|
var xhr = new ActiveXObject("Msxml2.XMLHTTP"); |
|
xhr.open('GET', 'http://b.hatena.ne.jp/my.name', false); |
|
xhr.send(null); |
|
try { |
|
this.name = xhr.responseText.match(/"name":"(.*?)"/)[1]; |
|
this.rkm = xhr.responseText.match(/"rkm":"(.*?)"/)[1]; |
|
return true; |
|
} catch(e) { |
|
return null; |
|
} |
|
}; |
|
|
|
hatena.postImage = function(type, size, base64) { |
|
var xhr = new ActiveXObject("Msxml2.XMLHTTP"); |
|
xhr.open('POST', 'http://f.hatena.ne.jp/' + this.name + '/haiku', false); |
|
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); |
|
try { |
|
xhr.send( |
|
'name=' + encodeURIComponent(this.name) + |
|
'&rkm=' + encodeURIComponent(this.rkm) + |
|
'&ext=' + type + |
|
'&model=capture' + |
|
'&fotosize=' + size + |
|
'&folder=' + |
|
'&image=' + base64.replace(/\+/g, '%2B')); |
|
var m = xhr.responseText.match(/d:.*?:(\d+?)\w?:image/); |
|
return 'http://f.hatena.ne.jp/' + this.name + '/' + m[1]; |
|
} catch(e) { |
|
return null; |
|
} |
|
}; |
|
|
|
function base64Encode(data) { |
|
var xml_dom = new ActiveXObject("Microsoft.XMLDOM"); |
|
xml_dom.loadXML('<?xml version="1.0" ?> <root/>'); |
|
xml_dom.documentElement.setAttribute("xmlns:dt", "urn:schemas-microsoft-com:datatypes"); |
|
var node1 = xml_dom.createElement("file1"); |
|
node1.dataType = "bin.base64"; |
|
node1.nodeTypedValue = data; |
|
xml_dom.documentElement.appendChild(node1); |
|
return node1.text.replace(/\s/g, ''); |
|
} |
|
|
|
function getFileContentAsBase64(file) { |
|
var stream = new ActiveXObject('ADODB.Stream'); |
|
stream.Type = 1;//1=binary,2=text |
|
stream.Open(); |
|
stream.LoadFromFile(file); |
|
var bin = stream.Read(-1);//-1:read all , -2 : read line |
|
return base64Encode(bin); |
|
} |
|
|
|
function Base64Reader(base64str) { |
|
this.base64str = base64str; |
|
this.position = 0; |
|
this.buffer = []; |
|
this.base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
|
} |
|
// take at most "num" bytes from base64 encoded binary as integers, return them as an array |
|
Base64Reader.prototype.readBytes = function(num) { |
|
var str = this.base64str; |
|
var i = this.position; |
|
var buf = this.buffer; |
|
var b64 = this.base64; |
|
// if num is 28, then take 40 characters, convert them to 30 ints, then return the first 28 ints |
|
var n = Math.ceil(num / 3) * 4 - buf.length + i; |
|
var c1, c2, c3, c4; |
|
|
|
for (; i < n;) { |
|
if ((c1 = b64.indexOf(str.charAt(i++))) |
|
=== -1) { |
|
break; |
|
} else if ((c2 = b64.indexOf(str.charAt(i++))) |
|
=== -1) { |
|
buf.push((c1 << 2)); |
|
break; |
|
} else if ((c3 = b64.indexOf(str.charAt(i++))) |
|
=== -1) { |
|
buf.push( |
|
(c1 << 2) | (c2 >> 4), |
|
((c2 & 15) << 4) |
|
); |
|
break; |
|
} else if ((c4 = b64.indexOf(str.charAt(i++))) |
|
=== -1) { |
|
buf.push( |
|
(c1 << 2) | (c2 >> 4), |
|
((c2 & 15) << 4) | (c3 >> 2), |
|
((c3 & 3) << 6) |
|
); |
|
break; |
|
} else { |
|
buf.push( |
|
(c1 << 2) | (c2 >> 4), |
|
((c2 & 15) << 4) | (c3 >> 2), |
|
((c3 & 3) << 6) | c4 |
|
); |
|
} |
|
} |
|
|
|
this.position = i; |
|
return buf.splice(0, num); |
|
} |
|
|
|
function getPNGData(png) { |
|
var reader = new Base64Reader(png); |
|
var a = reader.readBytes(24); |
|
|
|
// eg. 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,144,0,0,0,114,8,6,0,0,0,118 |
|
if (a.slice(0,12).join() !== '137,80,78,71,13,10,26,10,0,0,0,13') |
|
return null; |
|
|
|
var width = (a[16] << 24) + (a[17] << 16) + (a[18] << 8) + a[19]; |
|
var height =(a[20] << 24) + (a[21] << 16) + (a[22] << 8) + a[23]; |
|
|
|
return {type:'png', width:width, height:height}; |
|
} |
|
|
|
function getGIFData(gif) { |
|
// http://www.64lines.com/gif-width-height |
|
var reader = new Base64Reader(gif); |
|
var a = reader.readBytes(10); |
|
|
|
var head = String.fromCharCode.apply(null, a.slice(0, 6)); |
|
if (head !== 'GIF87a' && head !== 'GIF89a') |
|
return null; |
|
|
|
var height = (a[7] << 8) + a[6]; |
|
var width = (a[9] << 8) + a[8]; |
|
|
|
return {type:'gif', width:width, height:height}; |
|
} |
|
|
|
function getJPGData(jpg) { |
|
var reader = new Base64Reader(jpg); |
|
|
|
// http://www.64lines.com/jpeg-width-height |
|
var a = reader.readBytes(4); |
|
if (a[0] === 0xFF && a[1] === 0xD8 && a[2] === 0xFF && a[3] === 0xE0) { |
|
a = reader.readBytes(7); |
|
if ( String.fromCharCode.apply(null, a.slice(2, 7)) === 'JFIF\0') { |
|
var block_length = (a[0] << 8) + a[1]; |
|
a = reader.readBytes(block_length - 7); |
|
while (a.length) { |
|
a = reader.readBytes(2); |
|
if (!a.length) return null; |
|
if (a[0] !== 0xFF) return null; // start of another block |
|
if (a[1] === 0xC0) { |
|
a = reader.readBytes(7); |
|
var height = (a[3] << 8) + a[4]; |
|
var width = (a[5] << 8) + a[6]; |
|
return {type:'jpg', width:width, height:height}; |
|
} else { |
|
a = reader.readBytes(2); |
|
var block_length = (a[0] << 8) + a[1]; |
|
a = reader.readBytes(block_length - 2); |
|
} |
|
} |
|
return null; // size not found |
|
} else { return null; } // Not JFIF |
|
} else { return null; } // Not JPG |
|
} |
|
|
|
function getImageData(img) { |
|
return getPNGData(img) || getGIFData(img) || getJPGData(img); // null if all failed |
|
} |
|
|
|
function observeFileCreation(drive, path, callback) { |
|
var computer = '.'; |
|
|
|
var wmi = GetObject("winmgmts:\\\\" + computer + "\\root\\CIMV2"); |
|
|
|
var wql = [ |
|
"SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE ", |
|
"Targetinstance ISA 'CIM_DataFile' AND ", |
|
"TargetInstance.Drive = '" + drive + "' AND ", |
|
"TargetInstance.Path = '" + path.split('\\').join('\\\\') + "'" |
|
].join(''); |
|
|
|
var eventSrc = wmi.ExecNotificationQuery(wql); |
|
|
|
while (true) { |
|
var eventObj = eventSrc.NextEvent(); |
|
// if callback returns true, then stop loop |
|
if (callback(eventObj.TargetInstance)) return; |
|
} |
|
} |
|
|
|
observeFileCreation(watchFolder.drive, watchFolder.path, function(objItem) { |
|
var img = getFileContentAsBase64(objItem.Name); |
|
var data = getImageData(img); |
|
|
|
if (data) { |
|
var retry = 3; |
|
while (retry--) { |
|
if (!hatena.rkm || !hatena.user) hatena.verifyLogin(); |
|
var url = hatena.postImage(data.type, Math.max(data.width, data.height), img); |
|
if (url) { |
|
|
|
var fs = new ActiveXObject( "Scripting.FileSystemObject" ); |
|
fs.MoveFile(objItem.Name, watchFolder.drive + watchFolder.path + 'old\\' + url.split('/').pop() + '.' + data.type); |
|
fs = null; |
|
|
|
shell.Run(url); |
|
shell = null; |
|
|
|
/* //http://dara-j.asablo.jp/blog/2007/10/14/1852018 (don't work) |
|
var html = new ActiveXObject("htmlfile"); |
|
html.parentWindow.clipboardData.setData("text", url); |
|
WScript.Echo(html.parentWindow.clipboardData.getData("text")); |
|
html = null; |
|
*/ |
|
|
|
break; |
|
} else { |
|
if (hatena.login()) { |
|
hatena.verifyLogin(); |
|
} else { |
|
return; |
|
} |
|
} |
|
} |
|
} |
|
|
|
//return true; // for debug |
|
}); |
|
|
|
</script> |
|
</job> |
|
|