I have been stuck doing a lot of front-end web work lately and haven’t had a
chance to do much perl coding (I am planning on releasing an Mason based
renderer for Email::MIME::Kit
soon though). I’m very impressed
with the power of CSS in modern browsers. The last time I looked at it, browser
incompatibilities really made it difficult to use. It is much better still, I
find most of the work to be trial and error, so I have a couple of tips that
have saved me some time going back and forth…
I do all of my coding in vim and have ton of mappings (maybe I’ll share some in
future). One I really like right now it ,u
which saves the current
file then runs my xrefresh
perl script which finds my Firefox
window and refreshes the current page. It is a simple script that is based on
X11::GUITest
. It works particularly well when I am using two
monitors and can have the browser on in one of them. Here is the mapping, along
with the ,U
mapping which saves all files:
nmap <silent> ,u :w<cr>:! xrefresh 'Gran Paradiso'<cr>
nmap <silent> ,U :wa<cr>:! xrefresh 'Gran Paradiso'<cr>
I have been using the very nice Data::Pageset module
for a while now. It makes separating you data into multiple pages very simple,
and for very large datasets it has the slide
mode which helps keep
your pager small (rather than have links to 100 pages, you get links to the
first and last page and the five pages around your current page).
Eventually, I got tired of recreating the same html code for each new pager.
I first put together a simple Mason component, but
found myself copying it between projects and starting to write one for TT.
Eventually, I wrote Data::Pageset::Render.
The module (which is on CPAN) subclasses Data::Pageset and adds the
html
method, which returns the html code, complete with links, to
create your pager.
Just create your pager object as you would with Data::Pageset adding
link_format => '<a href="#">%a</a>'
to the
constructor, the html
method then eliminates all that redundant
paging html.
I am a big fan of CPANPLUS and minicpan. I like the plugin structure and
power of CPANPLUS. ([Warning: shameless plug follows] I have written a simple
plugin
that allows you to see/install the prereqs for an module with commands like
cpanp /prereqs show
or cpanp /prereqs install
.) And
minicpan is great for getting work done on an airplane or when I am away from
the net.
One thing I have struggle with in the past is getting cpanp to use either my local minicpan mirror or another mirror other than my default. Editing the config file is not that hard, but it is far to permanent for what I am trying to do. So I wrote two simple scripts (basically tweaked versions of /usr/bin/cpanp) that change the mirror to my local minicpan or a mirror passed on the command line: cpanp-local and cpanp-mirror. Both could be significantly improved, documented and they should probably be combined, but they get the job done.
When vim is shutdowns abnormally it leaves a bunch of .swp files
around.1 Given the way I program (very iterative and test focused)
those backups are rarely more current than the saved file. A great time saver
to help with recovery is the vim DiffOrig
command. After learning
about it on StackOverflow,
I put together the following bash script to find any swap files under the
current directory, open each in vim, run DiffOrig and prompt to delete after
you close vim.
I just recently came across the new facial detection features in Picasa, and I have to say I am very impressed. This is a very useful feature and well implemented; once again Google has set the bar. Unfortunately, it is only available in the web version, and I have way too many photos to upload. Further, there seem to be more privacy concerns with a web version of a tool like this.
So, I was very excited when I saw a brief mention of presentation about OpenCV from a Ruhr.pm meeting (thanks to Yanick’s blog). Maybe this was the tool to implement facial detection/recognition in my photos locally.
Tuesday night David Lowe gave a very interesting
talk
at SF.pm on pack/unpack
and some of the awful things you can do with
them.1 We ended the meeting talking about whether you could use the
pack format “P” (which packs and unpacks “a pointer to a structure
(fixed-length string)”) to force poor Perl to do C-like pointer arithmetic.
David is using unpack
to do a binary search of fixed width blobs of data in
order to avoid unserializing it. His current (minor) bottleneck is creating the
pack format string dynamically for each step in the binary search (ie, 'x' .
($record_size * $record + 1)
). The math is fast, the string concatenation is
relatively slow. I wondered if you could use the “P” format to avoid creating
the format string on each pass and stick with simple integer arithmetic.
After a bit of hacking, it turns out this can be done. Instead of David’s very complicated:
Outlook has the built in ability to export contacts as vCards, but it will only do it one at a time. With the following vba script and a few bash commands, you can batch export each contact as a vCard and then combine the individual files into one vcard file.
Again, I needed to find the path to particular folder. This one was deep and not under my Inbox. So, updated the folder list function. It is now recursive and (very simply) shows the structure.
' Copyright under GPL by Mark Grimes
' list folders by poping up msg box windows
Sub ListFolders()
Dim objNS As NameSpace
Dim objFolder
Set objNS = Application.GetNamespace("MAPI")
ListFromFolder objNS, ""
Set objNS = Nothing
End Sub
Sub ListFromFolder(objFolderRoot, spaces As String)
Dim objFolder As MAPIFolder
For Each objFolder In objFolderRoot.Folders
Debug.Print spaces + objFolder.Name
If objFolder.Folders.count > 0 Then
ListFromFolder objFolder, spaces + " "
End If
Next
End Sub
I recently needed to walk through all the events in an Outlook calendar and make a change. Here is the simple code:
' Copyright under GPL by Mark Grimes
' list folders by poping up msg box windows
Sub ResaveCalendarEntries()
Dim objNS As NameSpace
Dim objFolders, objFolder, objCalFolder
Dim objCalEntry As AppointmentItem
Dim count
count = 0
Set objNS = Application.GetNamespace("MAPI")
Set objCalFolder = objNS.Folders.item("Mailbox - MyMailBox").Folders.item("Calendar")
' This also works...
' Set objCalFolder = objNS.GetDefaultFolder(olFolderCalendar)
For Each objCalEntry In objCalFolder.Items
count = count + 1
Debug.Print count
Debug.Print objCalEntry.Subject
objCalEntry.Mileage = 1
objCalEntry.Save
' Exit Sub
Next
Set objNS = Nothing
End Sub
After spending a considerable amount of time trying to package a
Gtk2 app with pp
, I decided to try a different gui
toolkit, and was successful packaging a Wx
app.
Again, most of this kludge is based on bug reports from Marc Lehmann regarding Gtk. Thanks Marc!