Now available on the home server too.
My hobbyist coding updates and releases as the mysterious "Mr. Tines"
Friday, 29 June 2007
Wednesday, 27 June 2007
PassiveFTP 1.10
As promised…
PassiveFTP 1.10 — build 1.10.2734.38706 — squeezes in an up-one-level button into the remote site list, for FTP sites that manage to conceal their ".." directories. Or for people who'd prefer it anyway.
From the GeoCities Windows page at the moment. I need to do a physical rather than a remote logon to my home server before I can upload to that, so in a day or two.
Tuesday, 26 June 2007
PassiveFTP -- new revision
As the revised Demon homepages site doesn't provide ".." as a directory in the default ls
response, I shall have to add an explicit "go up one level" button to the server side.
Expect version 1.10 soonish.
Sunday, 24 June 2007
Current directions
CTClib/Angerona is taking a strange turn.
I want to use IronPython for .Net and Mono UI; but for the core library keep it as pure Python as feasible. But to get there, I'm porting via C++/CLI.
I have most of it building (I have not ported I/O, or deflate as yet), and I'm separating out the test code into a more formal set of unit tests.
The plan goes get it into "managed 'C'" with test coverage (side release 1); refactor to provide CLR interfaces at suitable places (side release 2); then pull code through the language barrier, one module at a time, to achieve a pyCTC library (library release 1), followed by a WinForms GUI on top. Or maybe Jython for the GUI.
No promises, as usual.
Friday, 27 April 2007
Drophash in Python dialects
Iron Python 1.1
Now for IronPython 1.1 — annoyingly the WebBrowser control doesn't accept normal DnD, nor does it let you paint it to a bitmap to blit on another control, so this one uses a ListView.
import clr clr.AddReferenceByPartialName("System.Windows.Forms") clr.AddReferenceByPartialName("System.Drawing") from System.Windows.Forms import * from System.Drawing import * from md5 import * from sha import * pane = None hashes = [md5, sha] nbsp = list(" ") def getHash(file, hashOp, delimiter) : try : reader = open(file, 'rb') except : return "" try : digest = hashOp() while True : chunk = reader.read(1024) if not chunk : break digest.update(chunk) finally: reader.close() raw = digest.hexdigest() work = [] i = 0 while i < len(raw) : work.append(raw[i]) i += 1 if 0 == (i%8) : work = work + delimiter return ''.join(work) def dragOver(sender, evt): evt.Effect = DragDropEffects.Link def dragDrop(sender, evt): global pane data = evt.Data data = data.GetData(DataFormats.FileDrop) num = pane.Items.Count for file in data: pane.Items.Add(file) for hashOp in hashes : anHash = getHash(file, hashOp, nbsp) pane.Items[num].SubItems.Add(anHash) num += 1 def decorate(frame): global pane frame.Text = "IronPython - Drophash" ## optional icon ## ico = Image.FromFile("drophash.ico") ## frame.Icon = Icon.FromHandle(ico.GetHicon()); pane = ListView() pane.Dock = DockStyle.Fill; frame.Controls.Add(pane) pane.AllowDrop = True pane.DragOver += dragOver pane.DragEnter += dragOver pane.DragDrop += dragDrop pane.View = View.Details pane.Columns.Add("File name", 100, HorizontalAlignment.Left) pane.Columns.Add("MD5", 200, HorizontalAlignment.Left) pane.Columns.Add("SHA-1", 200, HorizontalAlignment.Left) if __name__ == "__main__": frame = Form() decorate(frame) Application.Run(frame)
Jython 2.2
Jython next; but rather than coding the messy .ico to image transformation again, use a PNG icon (save as drophash.png) instead:—

import sys import os.path sys.packageManager.makeJavaPackage("javax.swing", "JWindow", None) sys.packageManager.makeJavaPackage("java.awt", "Window", None) sys.packageManager.makeJavaPackage("java.awt.dnd", "DropTargetListener", None) sys.packageManager.makeJavaPackage("java.awt.datatransfer", "DataFlavor", None) import javax.swing import java.lang import java.awt.dnd import java.awt.datatransfer from md5 import * from sha import * pane = None hashes = [md5, sha] nbsp = list(" ") target = None def getHash(file, hashOp, delimiter) : try : reader = open(file, 'rb') except : return "" try : digest = hashOp() while True : chunk = reader.read(1024) if not chunk : break digest.update(chunk) finally: reader.close() raw = digest.hexdigest() work = [] i = 0 while i < len(raw) : work.append(raw[i]) i += 1 if 0 == (i%8) : work = work + delimiter return ''.join(work) def OnDropFiles(filenames) : global pane, nbsp, hashes pane.text += "<table border=1><tr><th>File</th><th>MD5</th><th>SHA-1</th></tr>" for file in filenames : pane.text += "<tr><td>%s</td>" % file for hashOp in hashes : anHash = getHash(str(file), hashOp, nbsp) pane.text += "<td><pre>%s</pre></td>" % anHash pane.text +="</tr>" pane.text +="</table>" class dropHandler(java.awt.dnd.DropTargetAdapter): def __init__(self): java.awt.dnd.DropTargetAdapter.__init__(self) def drop(self, evt): if not evt.transferable.isDataFlavorSupported(java.awt.datatransfer.DataFlavor.javaFileListFlavor): return evt.acceptDrop(-1) names = evt.transferable.getTransferData(java.awt.datatransfer.DataFlavor.javaFileListFlavor) OnDropFiles(names) def decorate(frame): global pane frame.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE) frame.title = "Jython - Drophash" frame.layout = java.awt.BorderLayout() pane = javax.swing.JLabel() pane.border = javax.swing.BorderFactory.createEmptyBorder(5,5,5,5) frame.contentPane.add(javax.swing.JScrollPane(pane), java.awt.BorderLayout.CENTER) pane.text = "<html>" icon = java.awt.Toolkit.getDefaultToolkit().createImage("drophash.png") frame.setIconImage(icon) target = java.awt.dnd.DropTarget(pane, dropHandler()) width = 800 height = 600 frame.setSize(width, height); screenDim = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); frame.setLocation( (screenDim.width - width) / 2, (screenDim.height - height) / 2 ) if __name__ == "__main__": frame = javax.swing.JFrame() decorate(frame) frame.visible = True Made with Cascading Style Sheets
Saturday, 3 March 2007
Drophash in Python
First little Python project, a little utility to take the MD5 and SHA hashes of a bunch of files dragged and dropped onto it. Same function as but better presentation that a Win32 version (on the Windows page) I wrote back in late '00 (and which I have still been making regular use of for checking MD5s of file downloads).
WxPython UI
This one is neater than the Win32 version since I can use the nifty HTML window widget and place the results for each new batch of files in a table, with the files and hashes cross-indexed. Simply cut, paste and save the text of the section below as drophash.py.
#!/usr/bin/env python # -*- coding: ISO-8859-1 -*- #MD5 test suite: #MD5 ("") = d41d8cd98f00b204e9800998ecf8427e #MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661 #MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72 #MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0 #MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b #MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = d174ab98d277d9f5a5611c2c9f419d9f #MD5 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = 57edf4a22be3c955ac49da2e2107b67a #SHA test suite: #SHA ("abc") = A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D #SHA ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 #SHA (A million repetitions of "a") = 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F import wx import wx.html as html from md5 import * from sha import * def getHash(file, hashOp, delimiter) : try : reader = open(file, 'rb') except : return "" try : digest = hashOp() while True : chunk = reader.read(1024) if not chunk : break digest.update(chunk) finally: reader.close() raw = digest.hexdigest() work = [] i = 0 while i < len(raw) : work.append(raw[i]) i += 1 if 0 == (i%8) : work = work + delimiter return ''.join(work) class FileDropTarget(wx.FileDropTarget): def __init__(self, window): wx.FileDropTarget.__init__(self) self.window = window hashes = (md5, sha) nbsp = list(" ") def OnDropFiles(self, x, y, filenames) : self.window.AppendToPage("<table border=1><tr><th>File</th><th>MD5</th><th>SHA-1</th></tr>") for file in filenames : self.window.AppendToPage("<tr><td>%s</td>" % file) for hashOp in self.hashes : anHash = getHash(file, hashOp, self.nbsp) self.window.AppendToPage("<td><pre>%s</pre></td>" % anHash) self.window.AppendToPage("</tr>") self.window.AppendToPage("</table>") def decorate(frame): frame.SetTitle("wxPython - Drophash") ## optionally, an icon ## _icon = wx.EmptyIcon() ## _icon.CopyFromBitmap(wx.Bitmap("drophash.ico", wx.BITMAP_TYPE_ANY)) ## frame.SetIcon(_icon) frame.style = wx.DEFAULT_FRAME_STYLE pane = html.HtmlWindow(frame, -1) dt = FileDropTarget(pane) pane.SetDropTarget(dt) if __name__ == "__main__": theApp = wx.App(False) frame = wx.Frame(None, -1) decorate(frame) theApp.SetTopWindow(frame) frame.Show() theApp.MainLoop()
Python + Tk UI
As an alternative, a pure Tk version. Not so fancy; you have to select the files you want (or put them on the command line). Just extract this section as tkhash.py and double click…
#!/usr/bin/env python # -*- coding: ISO-8859-1 -*- #MD5 test suite: #MD5 ("") = d41d8cd98f00b204e9800998ecf8427e #MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661 #MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72 #MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0 #MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b #MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = d174ab98d277d9f5a5611c2c9f419d9f #MD5 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = 57edf4a22be3c955ac49da2e2107b67a #SHA test suite: #SHA ("abc") = A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D #SHA ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 #SHA (A million repetitions of "a") = 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F import Tkinter import ScrolledText import tkFileDialog import sys import tkFont from md5 import * from sha import * hashes = {"MD5" : md5, "SHA" : sha} nbsp = list(" ") def getHash(file, hashOp, delimiter) : try : reader = open(file, 'rb') except : return "" try : digest = hashOp() while True : chunk = reader.read(1024) if not chunk : break digest.update(chunk) finally: reader.close() raw = digest.hexdigest() work = [] i = 0 while i < len(raw) : work.append(raw[i]) i += 1 if 0 == (i%8) : work = work + delimiter return ''.join(work) def doGetHashes() : filenames = tkFileDialog.askopenfilenames() updateCanvas(filenames) def updateCanvas(filenames): textarea.config(state=Tkinter.NORMAL) for file in filenames : textarea.insert(Tkinter.END, ("%s\n" % file)) for hashOp in hashes : anHash = getHash(file, hashes[hashOp], nbsp) textarea.insert(Tkinter.END, ("%s " % hashOp) ) textarea.insert(Tkinter.END, ("%s\n" % anHash), 'mono' ) textarea.insert(Tkinter.END, "-------------------------\n") textarea.tag_config('mono', font='courier') textarea.config(state=Tkinter.DISABLED) if __name__ == "__main__": root = Tkinter.Tk() root.title("tkFileHasher") textarea = ScrolledText.ScrolledText() textarea.pack() textarea.config(state=Tkinter.DISABLED) Tkinter.Button(text="Select files to hash...", command=doGetHashes).pack() updateCanvas(sys.argv[1:]) Tkinter.mainloop()
Wednesday, 14 February 2007
Fun with JavaScript
“E”-ddress encoder script 1.0 — a utility based on the the old Hiveware “Enkoder”, only this time done entirely in JavaScript. Because you can.
Also the same thing for Acrete script 1.0
This sort of thing doesn't need heavyweight stuff like a Java applet; though Acrete currently uses the <canvas> element which isn't supported in IE (though I'm investigating alternatives for that). And, besides, I might as well do something useful, rather than just playing, with dynamic languages like JavaScript, Ruby and Python. Java projects (at least, those not for work) have probably reached the end of the road as a result.