... simply edit $HOME/Library/Spelling/LocalDictionary with your favourite editor.
Easy!
If you use Emacs, note that Aquamacs these days (v2.0+) uses the same native dictionary as well!
Friday, July 30, 2010
Managing Your Personal Dictionary on MacOSX
Monday, July 12, 2010
Converting Perforce repositories to Mercurial using the convert extension
The help from "hg help convert" isn't very clear because it does not mention the fact that you need to set the environment variable P4PORT to the host:port of your Perforce server.
So for example if you want to covert your project from //depot/projectA on server perforce:1666 and store the resulting Mercurial repo to a directory called projectA.hg you should do the following:
So for example if you want to covert your project from //depot/projectA on server perforce:1666 and store the resulting Mercurial repo to a directory called projectA.hg you should do the following:
- export P4PORT=perforce:1666
- hg convert //depot/projectA/... projectA.hg
Neat.
Labels:
scm mercurial perforce
| Reactions: |
Saturday, July 03, 2010
Less is more
So I was looking for a laptop that I can use daily during my daily commute between work and home. My beloved 15" MBP has a nice screen but it's a little bit too big and heavy to carry around so I was looking for alternatives.
13" Macbooks are nice however I could not justify the cost for a typing pad. At the end I picked up a ASUS eeepc (model 1001px) instead.
The good:
- Cost about one-third of an entry level Macbook.
- A non-glossy, matte LCD that I can read from.
- Good battery life - thanks to the new Atom chipset/process combo.
- A keyboard that isn't too painful to type on.
- Easy RAM upgrade.
The bad:
- Keyboard: right control key is a bit off and arrow keys are too cramped.
- Small, unresponsive trackpoint with awkward buttons.
- No bluetooth - fixed with a tiny USB dongle.
- Hard to replace hard drive.
And the worse part is: it came with Windows...
According to my research putting Linux on this lappy would kill battery life and I am not spending any time dealing with driver/power management issues. Instead, I put Cygwin and CoLinux on it.
Cygwin is great if you simply want to do something quickly and CoLinux is good if you require a more complete Linux environment IMO.
One thing you will need for both is a decent terminal program. For that, I use PuttyCyg
With the bluetooth dongle plugged in I now tether with my iphone whenever and wherever I want. Happy days...
| Reactions: |
Friday, April 16, 2010
Enabling NFS Server on MacOSX 10.6.3 (should work for 10.5+)
If you created /etc/exports and your NFS mounts are not working, it's possible that you don't have the launchd plist loaded. Fix it by:
sudo launchctl load /System/Library/LaunchDaemons/com.apple.nfsd.plist
Thursday, March 18, 2010
Sorting photos from your digital camera
#!/usr/bin/env python
'''
A simple Python script to sort image files into different directories
according to its EXIF tags.
lestercheung AT gmail.com
'''
import os, sys
import datetime
if '__file__' in dir(): # Put EXIF.py on the same directory
sys.path.append(os.path.dirname(__file__))
import EXIF
from exceptions import Exception
def getctime(filename):
dt = datetime.datetime.fromtimestamp(os.stat(filename).st_ctime)
try:
tags = EXIF.process_file(file(filename, 'rb'))
dtstr = tags.get('EXIF DateTimeOriginal').printable
subsecstr = tags.get('EXIF SubSecTimeOriginal').printable
usec = 0 # microsecond portion of timestamp
for i in range(len(subsecstr)):
if 5-i < 1:
break
j = subsecstr[i]
usec += int(j) * 10**(5-i)
if dtstr:
dt = datetime.datetime.strptime(dtstr+str(usec), '%Y:%m:%d %H:%M:%S%f')
except Exception, e:
sys.stderr.write('error parsing date tag, using file timestamp for %s' % filename)
sys.stderr.write(str(e))
sys.stderr.write('\n')
return dt
def getdstfname(src, dstdir=''):
dt = getctime(src)
ext = os.path.basename(src)
x = src.split('.')
if len(x) > 1:
ext = x[-1]
# fname = dt.strftime('%Y%m%d_%H%M%S%f')
fname = os.path.basename(src)
pathname = os.path.join(dstdir, str(dt.year), dt.strftime('%m'), dt.strftime('%d'), fname)
if os.path.exists(pathname):
i = 1
while os.path.exists(pathname):
pathname = os.path.join(dstdir, str(dt.year), dt.strftime('%m'), dt.strftime('%d'), fname.split()[0]+'-%03d.'%i+ext)
i+=1
return pathname
def link_or_copy(src, dst):
print "link_or_copy(%s, %s)" % (src, dst)
if os.path.exists(dst):
print '%s exists! Aborting' % dst
return
dstdir = os.path.dirname(dst)
if not os.path.exists(dstdir):
os.makedirs(dstdir)
try:
os.link(src, dst)
except OSError, e: # copy and reset timestamp
fd = file(dst, 'w')
fd.write(file(src).read())
fd.close()
ctime = getctime(dst)
from time import mktime
# this is not precise - see: http://bugs.python.org/issue2736
atime = mtime = mktime(ctime.timetuple()) # setting all to DateTimeOriginal
os.utime(dst, (atime, mtime))
if __name__ == '__main__':
srcdir, dstdir = sys.argv[1:3]
failed_files = []
copied = 0
for base, dirs, files in os.walk(srcdir):
for f in files:
ff = os.path.join(base,f)
#print ff
from exceptions import Exception, OSError
try:
link_or_copy(ff, getdstfname(ff, dstdir=dstdir))
copied += 1
except OSError, e:
failed_files.append(ff)
except Exception, e:
raise
if failed_files:
print 'failed to link/copy %s files:\n' % len(failed_files)
for i in failed_files:
print ' %s' % i
print 'copied %s files.' % copied
Labels:
python photo script
| Reactions: |
Wednesday, March 10, 2010
Slow startup for Dictionary.app on MacOSX
... fixed by removing the following 2 directories: ~/Library/Caches/com.apple.DictionaryApp ~/Library/Caches/com.apple.DictionaryServices.
Wednesday, October 21, 2009
Sending UTF8 encoded vacation mail
It's simple! Just include the following headers in your $HOME/.vacation.msg:-
So a full .vacation.msg would look like this:
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
So a full .vacation.msg would look like this:
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Subject: Out of office: "$SUBJECT"
Your mail concerning "$SUBJECT" will be read when I return.
Friday, August 21, 2009
"resource temporarily unavailable" on the Mac
So if you are a power user you might hit resource limits on the Mac just like the old UNIX times.
So today I was unable to create new process on my Mac:
sh-3.2$ sh
sh-3.2$ sh
sh: fork: Resource temporarily unavailable
sh-3.2$ exit
sh-3.2$ ps ux|wc
sh: fork: Resource temporarily unavailable
So I killed a few process and ran ps and pipe it to wc:
sh-3.2$ exit
sh-3.2$ exit
sh-3.2$ ps ux|wc -l
266
266 processes isn't a huge number in today's standards right?
Guess Apple has a different view - 266 is a pre-defined limit of the maximum number of processes a single user (uid) can create on the Mac:
sh-3.2$ sudo sysctl -a |grep maxprocperuid
kern.exec: unknown type returned
kern.maxprocperuid = 266
kern.maxprocperuid: 266
Solution? Simple pump it up by:
$ sudo sysctl -w kern.maxprocperuid = 512
Wednesday, May 06, 2009
Lock your screen with quicksilver and from the shell
I have script called osx-lockscreen in my ~/bin that I use to lock my screen quickly:
#!/bin/sh
/System/Library/CoreServices/"Menu Extras"/User.menu/Contents/Resources/CGSession -suspend
Thursday, March 12, 2009
Die GPT die!
From time to time you move hard drive between systems that uses GPT by default (Solaris with ZFS, Apple MacOS etc) and system that don't (Windows, Linux, BSDs) you might get annoyed by your favourite partitioning tools in the later systems for not having GPT support. The solution? Kill the GPT signatures and continue to use your favourite tool!
Problem is that GPT records exists in both the beginning AND the end of a disk - so the usual dd if=/dev/zero of=/dev/yournewdisk count=100 trick won't work. Of course you can wipe the whole drive with dd - but that would be slow and unnecessary. So what to do? Python come to rescue! The following script will completely nuke your partition table on a given disk so that you can start from scratch - make sure you know what you are doing!
Problem is that GPT records exists in both the beginning AND the end of a disk - so the usual dd if=/dev/zero of=/dev/yournewdisk count=100 trick won't work. Of course you can wipe the whole drive with dd - but that would be slow and unnecessary. So what to do? Python come to rescue! The following script will completely nuke your partition table on a given disk so that you can start from scratch - make sure you know what you are doing!
#!/usr/bin/env python
import sys
'''
Nuke GPT on any given block device.
lestercheung <<<<<<<<<>>>>>>>>> gmail.com
'''
def ftell_test(d):
f = open(d, "r")
f.seek(0, 2) # SEEK_END is 2
return f.tell()
def clear_gpt(target):
'''
According to http://en.wikipedia.org/wiki/GUID_Partition_Table - GPT
stores partition data in the first and last 34 LBA blocks. A LBA sector
is normally 512 bytes.
'''
fd = open(target, "w+")
fd.seek(0)
fd.write('\0' * 34 * 512)
print "done nuking data at the beginning of disk", target
fd.seek(0, 2) # SEEK_END is 2
disk_size = fd.tell()
fd.seek(disk_size - 34*512)
fd.write('\0' * 34 * 512)
print "done nuking data at the end of disk", target
if __name__ == '__main__':
for x in sys.argv[1:]:
#print ftell_test(x)
clear_gpt(x)
| Reactions: |
Thursday, March 05, 2009
A handy applescript that I use to reclaim 15mins my time, everyday
This script turns a selection of text in Safari and turn it to a audiobook in iTunes, optionally sync it to your iphone/ipod.
-- -*- mode: applescript -*- --
-- My first applescript:
-- This script makes a text selection to speech and import to iTunes
-- much of it is a total rip off from other scripts you see online,
-- especially those from http://dougscripts.com/. Thanks Doug!
--
-- 13z73rch3un9 [at] gmail.com
-- configurables -------------
set tmpDir to (path to desktop folder as text)
set plName to "reading materials"
set myIpodName to "NAME OF YOUR IPHONE/IPOD"
---------------------------------
tell application "Safari"
set selecTxt to (do JavaScript "(getSelection())" in document 1)
-- set pgtitle to quoted form of (do JavaScript "document.title" in document 1)
set pgtitle to (do JavaScript "document.title" in document 1)
set pgurl to (do JavaScript "document.URL" in document 1)
end tell
set pgtitle to replace(pgtitle, ":", " -")
set aiffFile to tmpDir & pgtitle & ".aiff"
say selecTxt saving to aiffFile
-- import to iTunes and add ID3 tags
tell application "iTunes"
set rawTrack to (add aiffFile)
tell application "Finder" to delete aiffFile
-- metadata
set name of rawTrack to pgtitle
set ds to ((current date) as string)
set comment of rawTrack to "Imported from Safari on " & ds & return & "source: " & pgurl
set genre of rawTrack to "reading material"
set lyrics of rawTrack to selecTxt
-- I don't know why this doesn't work....
-- set y to ((year of (current date)) as string)
-- set year of myTrack to y
set year of rawTrack to (do shell script "/bin/date +%Y")
-- transcode
set defaultEncoder to current encoder
set aacEncoder to (item 1 of (every encoder whose format is "AAC"))
set current encoder to aacEncoder
set m4aTrack to item 1 of (convert rawTrack)
set current encoder to defaultEncoder
delete rawTrack
set m4aLocation to location of m4aTrack
tell application "Finder"
set m4aAlias to m4aLocation as alias
set file type of m4aAlias to "M4B "
if name extension of m4aAlias is not "m4b" then
set name of m4aAlias to ((text 1 thru -((length of (get name extension of m4aAlias)) + 1) of (name of m4aAlias as text)) & "m4b") as string
end if
end tell
delete m4aTrack
set m4bTrack to add m4aAlias
reveal m4bTrack
-- uncomment this to sync ipod/iphone connected, change your device name!
try
update (some source whose name is myIpodName)
on error
display alert "Your iPod is not connected, not syncing... (Have you defined your ipod name in the script?)"
end try
end tell
tell application "Safari" to activate
on replace(str, sstr, newstr)
set rtn to ""
repeat with i from 1 to (length of text of str) by 1
set c to text i of str
if c is equal to sstr then
set rtn to rtn & newstr
else
set rtn to rtn & c
end if
end repeat
return rtn
end replace
-- My first applescript:
-- This script makes a text selection to speech and import to iTunes
-- much of it is a total rip off from other scripts you see online,
-- especially those from http://dougscripts.com/. Thanks Doug!
--
-- 13z73rch3un9 [at] gmail.com
-- configurables -------------
set tmpDir to (path to desktop folder as text)
set plName to "reading materials"
set myIpodName to "NAME OF YOUR IPHONE/IPOD"
---------------------------------
tell application "Safari"
set selecTxt to (do JavaScript "(getSelection())" in document 1)
-- set pgtitle to quoted form of (do JavaScript "document.title" in document 1)
set pgtitle to (do JavaScript "document.title" in document 1)
set pgurl to (do JavaScript "document.URL" in document 1)
end tell
set pgtitle to replace(pgtitle, ":", " -")
set aiffFile to tmpDir & pgtitle & ".aiff"
say selecTxt saving to aiffFile
-- import to iTunes and add ID3 tags
tell application "iTunes"
set rawTrack to (add aiffFile)
tell application "Finder" to delete aiffFile
-- metadata
set name of rawTrack to pgtitle
set ds to ((current date) as string)
set comment of rawTrack to "Imported from Safari on " & ds & return & "source: " & pgurl
set genre of rawTrack to "reading material"
set lyrics of rawTrack to selecTxt
-- I don't know why this doesn't work....
-- set y to ((year of (current date)) as string)
-- set year of myTrack to y
set year of rawTrack to (do shell script "/bin/date +%Y")
-- transcode
set defaultEncoder to current encoder
set aacEncoder to (item 1 of (every encoder whose format is "AAC"))
set current encoder to aacEncoder
set m4aTrack to item 1 of (convert rawTrack)
set current encoder to defaultEncoder
delete rawTrack
set m4aLocation to location of m4aTrack
tell application "Finder"
set m4aAlias to m4aLocation as alias
set file type of m4aAlias to "M4B "
if name extension of m4aAlias is not "m4b" then
set name of m4aAlias to ((text 1 thru -((length of (get name extension of m4aAlias)) + 1) of (name of m4aAlias as text)) & "m4b") as string
end if
end tell
delete m4aTrack
set m4bTrack to add m4aAlias
reveal m4bTrack
-- uncomment this to sync ipod/iphone connected, change your device name!
try
update (some source whose name is myIpodName)
on error
display alert "Your iPod is not connected, not syncing... (Have you defined your ipod name in the script?)"
end try
end tell
tell application "Safari" to activate
on replace(str, sstr, newstr)
set rtn to ""
repeat with i from 1 to (length of text of str) by 1
set c to text i of str
if c is equal to sstr then
set rtn to rtn & newstr
else
set rtn to rtn & c
end if
end repeat
return rtn
end replace
| Reactions: |
Wednesday, October 15, 2008
The joy of cloud computing
This blog was created in a random afternoon as an exercise to find out what's the fuss about this "blog thing" - since then I have been working in the computing field and had my own blog hosted on little home server like many geeks out there. Many moons gone by and I have lost interest with the whole idea and stopped writing completely after a hard disk crash (it was my don't-care box).
4 years later I was trying to create a blog again simple to write down random notes I have during the day - and to my surprise I ran into this little blog when I tried to create a new blog with the same name. Thanks to the good work from Google I was able to quickly reset my credentials and linked this under my Google account. Don't you love cloud computing?
4 years later I was trying to create a blog again simple to write down random notes I have during the day - and to my surprise I ran into this little blog when I tried to create a new blog with the same name. Thanks to the good work from Google I was able to quickly reset my credentials and linked this under my Google account. Don't you love cloud computing?
Wednesday, July 21, 2004
really really old post
This was just a really old post that I did to test blogger ages ago...
Subscribe to:
Posts (Atom)