User:Alex Smotrov/ExtEdit.vbs.css
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:Alex Smotrov/ExtEdit.vbs. |
'<nowiki>
option explicit
'settings
const wikiExt = "wiki"
const defaultDraftURL = "http://en.wikipedia.org/wiki/Wikipedia:Sandbox"
const workingDir = "" 'where .wiki files are saved; by default - script path
const backupSubDir = "backup\" 'where old .wiki files are moved if they are to be overwritten
const useIEpreview = true
'common objects
dim WShell: Set WShell = CreateObject("WScript.Shell")
dim FSO: Set FSO = CreateObject("Scripting.FileSystemObject")
dim XML: Set XML = CreateObject("Microsoft.XMLHTTP")
dim objStream: Set objStream = CreateObject("ADODB.Stream")
objStream.Type = 2: objStream.CharSet = "UTF-8" '2 means adTypeText
dim path, articleURL, editURL, wpEdittime, wikiText, HTML 'some global vars
'set working folder (path variable)
if workingDir<>"" then
path = workingDir
if not FSO.FolderExists(path) then QuitWith "Please set correct 'workingDir'"
else
path = Left(WScript.ScriptFullName, InstrRev(WScript.ScriptFullName, "\"))
end if
'if no arguments - ask to assciate with .php
if WScript.Arguments.Count = 0 then
if msgbox("Associate .php files with this script?", vbYesNo, WScript.ScriptName) = vbYes then
dim ws: ws = WScript.Path & "\wscript.exe"
if not FSO.FileExists(ws) then QuitWith "Sorry, cannot find your file " & ws
ws = ws & " """ & WScript.ScriptFullName & """ ""%1"""
saveRegVal "HKCR\.php\shell\wikiedit\command\", ws
saveRegVal "HKCR\.php\shell\", "wikiedit"
msgbox "Done"
end if
WScript.Quit
end if
'check that argument is a valid file
dim arg: arg = WScript.Arguments(0)
if not FSO.FileExists(arg) then QuitWith "Input file not found: " & arg
'decide what to do
Select Case getFileExt(arg)
Case "php" processControlFile(arg)
Case wikiExt processWikiFile(arg)
Case else QuitWith "Input file extension not recognized"
End Select
Set objStream = Nothing
WScript.quit
'------------------------------------ Open .php Control File ------------------------------
function processControlFile(ctrlFile)
dim articleName, wikiFile
dim p1, p2, ch, fobj, controlText
'load Control File and get article URL
controlText = FSO.OpenTextFile(ctrlFile, 1).ReadAll
p1 = InStr(1, controlText, "URL=", vbTextCompare) + 4
p2 = InStr(p1, controlText, "&", vbTextCompare)
articleURL = Mid(controlText, p1, p2-p1)
'get article name, decode it and remove disallowed chars in order to create wiki file name
p1 = InStr(1, articleURL, "=", vbTextCompare) + 1
articleName = decodeURL(Mid(articleURL, p1))
for each ch in Array ("\", "/", ":", "*", "?")
articleName = replace (articleName, ch, "_")
next
wikiFile = path & articleName & "." & wikiExt
'backup old wiki file if it exists
if FSO.FileExists (wikiFile) and backupSubDir <>"" then
if not FSO.FolderExists(path & backupSubDir) then
on Error Resume Next
FSO.CreateFolder(path & backupSubDir)
if Err then QuitWith "Unable to create backup subfolder"
on Error Goto 0
end if
dim dd, backupName
dd = FSO.GetFile(wikiFile).DateLastModified
backupName = articleName &"."& year(dd)&"."&z(month(dd))&"."&z(day(dd))&"_"&z(hour(dd))&"."&z(minute(dd))&"."&z(second(dd))
on Error Resume Next
FSO.MoveFile wikiFile, path & backupSubDir & backupName & "." & wikiExt
if Err then QuitWith "Unable to backup existing ." & wikiExt & " file" & vbCrLf & "(" & Err.Description & ")"
on Error Goto 0
end if
'retreive article wiki code
XML.Open "GET", articleURL + "&action=raw", False
XML.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT" 'to prevent caching
XML.Send
wikiText = XML.responseText
wpEdittime = CompactDate(XML.getResponseHeader("Last-Modified"))
'save wiki code into a file
'Set fobj = FSO.CreateTextFile(wikiFile, true, true) 'overwrite, unicode - creates non-UTF-8 file
'on Error Resume Next
objStream.Open
objStream.WriteText wikiText
objStream.SaveToFile wikiFile, 2 ' adSaveCreateOverWrite
'create info file
Set fobj = FSO.CreateTextFile(wikiFile & ".info", true, false) 'overwrite, ascii
fobj.WriteLine (articleURL)
fobj.WriteLine (wpEdittime)
fobj.Close
'start wiki file in editor
on Error Resume Next
WShell.Run wikiFile, 1, true
if Err then QuitWith "Created file '" & wikiFile & "'" & vbCrLf & vbCrLf & "Cannot start the file." & vbCrLf & "Please check that extension ." & wikiExt & " is associated with your text editor."
on Error Goto 0
end function
'------------------------------------ Open Wiki File ------------------------------
Function processWikiFile(wikiFile)
dim infoFile, htmlFile, fobj, isNewArticle
'read wiki file
objStream.Open
objStream.LoadFromFile wikiFile
wikiText = objStream.ReadText
objStream.Close
'get article URL
isNewArticle = true
infoFile = wikiFile & ".info"
if FSO.FileExists(infoFile) then 'from info file
set fobj = FSO.OpenTextFile(infoFile, 1) 'for reading
articleURL = fobj.ReadLine
wpEdittime = fobj.ReadLine
fobj.Close
isNewArticle = false
elseif left(wikiText,11) = "<!--http://" then 'from comment in article code
articleURL = mid(wikiText, 5, InStr(wikiText, "-->")-5)
articleURL = replace (trim(articleURL), " ", "_")
else 'new article with unknown url
articleURL = defaultDraftURL
end if
editURL = articleURL
if isNewArticle then
editURL = replace (editURL, "/wiki/","/w/index.php?title=")
wpEdittime = "20000101000000" 'if article in fact exists then make sure there's gonna be an edit conflict
end if
'create form HTML code
editURL = editURL & "&action=submit&wpPreview"
HTML = "<html><body><form method=post action='" & editURL & "' enctype='multipart/form-data'><input type=hidden name=wpEdittime value=" & wpEdittime & "><textarea name=wpTextbox1 style='display:none'>" & wikiText & "</textarea></form>"
if useIEpreview then
if not previewIE_TrySameWindow() then previewIE_NewWindow()
else
previewDefaultBrowser()
end if
'check article last-modified now
if not isNewArticle then
XML.Open "GET", articleURL & "&action=raw", False '!!! would use HEAD but it takes ages to get the answer...
XML.Send
if wpEdittime <> CompactDate(XML.getResponseHeader("Last-Modified")) then msgbox "Alert! Article has been changed on WikiMedia server"
end if
end function
'---------------------------------------------
function previewIE_TrySameWindow()
dim Boundary: Boundary = "--------p1415"
dim divPreview, PostData, Response
dim win, winurl, isFound, oldColor, oldBgColor
'find our IE window
isFound = false
for each win in CreateObject("shell.application").Windows
if typename(win.document) = "HTMLDocument" then
winurl = win.locationUrl
if InStr(winurl,"#") > 0 then winurl = left(winurl, InStr(winurl,"#") - 1) 'remove #
if winurl = editURL then 'found our window
set divPreview = win.document.all("wikiPreview")
if typename (divPreview) <> "Nothing" then isFound = true: exit for
end if
end if
next
if not isFound then previewIE_TrySameWindow = false: exit function
'kind of hide old preview
oldColor = divPreview.style.color: oldBgColor = divPreview.style.backgroundColor
divPreview.style.color = "#d0d0d0": divPreview.style.backgroundColor = "#d0d0d0"
'submit new preview
XML.Open "POST", editURL & "&live", False
XML.setRequestHeader "Content-Type", "multipart/form-data; boundary=" & Boundary
PostData = "--" & Boundary & vbCRLf _
& "Content-Disposition: form-data; name='wpTextbox1'" & vbCRLf & vbCRLf _
& wikiText & vbCRLf & "--" & Boundary
XML.Send Postdata
WShell.AppActivate win.document.title
Response = XML.responseText 'Response = mid(Response, InStr(Response, "<h2>"))
'decode XML to HTML
Response = replace (Response, ">", ">")
Response = replace (Response, "<", "<")
Response = replace (Response, """, """")
Response = replace (Response, "'", "'")
Response = replace (Response, "&", "&")
divPreview.innerHTML = Response
'restore colors
divPreview.style.color = oldColor
divPreview.style.backgroundColor = oldBgColor
'renew wiki text in a form
win.document.editform.wpTextbox1.value = wikiText
'done
previewIE_TrySameWindow = true
end function
'---------------------------------------------
function previewIE_NewWindow() ' submit preview in new IE window
dim IE: set IE = CreateObject("InternetExplorer.Application")
IE.navigate "about:blank"
do while IE.busy: loop
'write html and submit
IE.document.Open
IE.document.write HTML & "</html>"
IE.document.Close
IE.document.forms(0).submit()
IE.visible = 1
do while IE.busy: wscript.sleep 100: loop
WShell.AppActivate IE.document.title
'hide the edit form
if typename(IE.document.editform) = "Nothing" then exit function
IE.document.editform.style.display = "none"
'slightly move toolbar to hide it as well
dim obj: set obj = IE.document.getElementById("toolbar")
if typename(obj) <> "Nothing" then
IE.document.editform.insertBefore obj, IE.document.editform.firstChild
end if
' obj.style.display = "none"
'add a link to restore
IE.document.editform.parentNode.appendChild(IE.document.createElement("hr"))
set obj = IE.document.CreateElement("a")
obj.InnerHTML = "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/"
obj.href = "javascript:document.editform.style.display='block';alert('If you edit text here, do not forget to close your editor');void 0"
IE.document.editform.parentNode.appendChild(obj)
end function
sub previewDefaultBrowser ()'save and launch submit file
objStream.Open
objStream.WriteText HTML & "<script>document.forms[0].submit()</script></body></html>"
objStream.SaveToFile path + "temp.htm" , 2 ' adSaveCreateNotExist
WShell.Run path + "temp.htm"
objStream.Close
end sub
'=========================== Misc Functions ===========================
Sub QuitWith (msg)
WShell.Popup msg, 0, WScript.ScriptName & ": Error", 48
WScript.Quit
End sub
Function getFileExt (fname) 'returns file extension
dim pos: pos = InStrRev(fname, ".")
getFileExt = ""
if pos > 0 then getFileExt = right(fname, len(fname) - pos)
end function
sub saveRegVal (regName, regVal)
on Error Resume Next
WShell.RegWrite regName, regval
if Err or (regval <> WShell.RegRead(regName)) then QuitWith "Unable to edit registry"
on Error Goto 0
end sub
function CompactDate (aDate) ' Sun, 04 Feb 2007 21:25:18 GMT => 20070204212518
dim arr, mm
arr = Split(aDate)
if UBound(arr)<>5 then QuitWith "Last-Modified not recognized"
mm = InStr("JanFebMarAprMayJunJulAugSepOctNovDec", arr(2))
if mm<=0 then QuitWith "Last-Modified not recognized (month)"
mm = Cstr((mm-1)/3 + 1): if len(mm)<2 then mm = "0" & mm
CompactDate = arr(3) & mm & arr(1) & replace(arr(4),":","")
end function
Function decodeURL(str) 'decode %D0%A3%... (1 or 2-byte UTF-8)
dim result, ii, byte1, byte2: result = "": ii=1
do while ii <= len(str)
if mid(str, ii, 1) = "%" then
byte1 = hex2dec(mid(str,ii,3))
byte2 = hex2dec(mid(str,ii+3,3))
if byte1 = null then
result = result & "%" 'starts with % but cannot decode....weird...just skip
ii = ii + 1
elseif byte1 < 128 then 'one-byte UTF
result = result & chrW(byte1)
ii = ii + 3
elseif byte2=null then 'cannot decode 2nd byte...just skip
result = result & mid(str,ii,4)
ii = ii + 4
else 'two-byte UTF
result = result & chrW( (byte1 and &H1F) * 64 or (byte2 and &H3F) )
ii = ii + 6
end if
else 'normal ascii char
result = result & mid(str,ii,1)
ii = ii + 1
end if
loop
decodeURL = result
end function
function hex2dec(hh) ' %D0 -> 208
dim jj, digit, result: result = 0
hex2dec = null
if len(hh)<>3 or left(hh,1)<>"%" then exit function
for jj = 2 to 3
digit = instr("0123456789ABCDEF", ucase(mid(hh, jj, 1))) - 1
if digit < 0 then exit function
result = result * 16 + digit
next
hex2dec = result
end function
function z(n) ' 7 -> 07
if len(CStr(n)) > 1 then z = CStr(n) else z = "0" & CStr(n)
end function
'</nowiki>