Wednesday, November 24, 2004

watch

I just learned a new unix command -- one I could have used many times in the past... watch.

I've copied or removed large directories of files and have run 'df' many times in a row to either see how much was freed or see how close I was getting to a full disk. If I had done, 'watch df', it would have made it much easier. Now I know. :)

Monday, July 26, 2004

OSCON day 1

I'm going to try to blog my week at OSCON. Most of the tutorials or session I'll be attending will be on PHP, but I'll be attending a few others on MySQL, Subversion and Gentoo as well.

Object Oriented Programming with PHP5

OOP with PHP5 was a discussion on object oriented programming (OOP) and how PHP5 implements various OOP ideas. Topics covered were: Classes and objects, methods and data, constructors/destructors, public/private/protected members and data, inheritance, abstract classes, interfaces, exceptions, and a few other OOP topics.

While that was a nice overview of PHP5's object model, the tutorial ran long and we didn't cover some of what I thought would be the more interesting parts of the tutorial, such as:
  • Automated Tools for creating PHP from UML.
  • SimpleXML
  • SOAP
  • How the object models opens interoperability with other langauges (Java/Python).

In the end, the tutorial wasn't much more than what I've already read in this article on PHP5's new features. Maybe the topic list was a little too ambitious, but I left wishing I could have heard more about the other topics, and like other tutorials, there was no booklet to accompany the tutorial to read what we missed.

PHP Security

PHP Security was an excellent tutorial by Chris Shiflett. He gave a nice, thorough overview of various attacks against one's PHP applications, why they are a security concern, and how to program them in such a way as to defend against the various attacks.

I have read a few of his articles in PHP Architect and I felt I learned a lot from this tutorial. I went in with a vague idea of a few of the attacks and left with a more in-depth knowledge of how the attacks work and how to fix my code.

Tuesday, April 27, 2004

RSS delivered to your email

I recently found and setup rss2email.
Check out the screenshot. :)

I used to have different RSS feeds at work and home and found it hard to synchronize them, though I didn't try too hard. This is a nice solution since it is central, and I get new blog postings each morning (when I set up my cron job). Sweet!

Update: I recently switched to newspipe when I set up a new web/mail server. It saves its configuration file in an OPML format and has support for digests, HTML email, and many other feed options.

Wednesday, November 26, 2003

MySQL tips

I've been studying recently for the MySQL certification test and have discovered a few tricks along the way. One of my favorites is the combination of using pager and vertical output.

To set your pager to use less:

mysql> pager less
PAGER set to less

Now when you perform a select which returns more rows than rows on your screen, the pager will allow you to paginate through the results.

To get MySQL to display results vertically instead of in columns horizontally, end your SQL with "\G" instead of with the semicolon (or "\g")...

mysql> SELECT * FROM mails WHERE LENGTH(txt) < 300 lIMIT 300,1\G
*************************** 1. row ***************************
msg_nro: 3068
date: 2000-03-01 23:29:50
time_zone: +0200
mail_from: Monty
reply: monty@no.spam.com
mail_to: "Thimble Smith"
sbj: UTF-8
txt: >>>>> "Thimble" == Thimble Smith writes:

Thimble> Hi. I think this is a good idea. Is anyone familiar with UTF-8
Thimble> or Unicode? Otherwise, I'll put this on my TODO list and see what
Thimble> happens.

Yes, please do that.

Regards,
Monty
file: inbox-jani-1
hash: 190402944
1 row in set (0.09 sec)

Friday, July 18, 2003

PyNewbie on making cryptograms

I used to enjoy cryptograms a lot and wanted to generate some on my own. I originally wrote a script to do this in Perl. While learning Python, I rewrote it and learned a few things about the string library in the process. Here goes...

import sys, string, random

We're going to be using sys to catch arguments passed to our script, or to catch input from a pipe. We've got lots of string manipulation so we're importing the string module. The random module will give us a way to shuffle a list so we can match each letter with another random letter. More on all of these later in the script.

We'll jump to the bottom of the script and show something you'll see a lot in Python:

if __name__ == '__main__':
if len(sys.argv) == 2:
print encrypt(open(sys.argv[1], 'r'))
else:
print encrypt(sys.stdin)

The first line here tells Python to call the encrypt function if the name of the script is __main__; more technically, if the name of the module is __main__. Every Python script can be a module. If the module is imported from another Python script, the module's __name__ is set to the filename without the directory path or file extension. If the script is run directly from the command line as a standalone program, __name__ is set to __main__. In this way, Python makes it easy to make programs reusable, or debug parts of a module before integrating it into a larger program.

The rest of this segment checks the number of arguments passed in. The first argument is always the script name itself. If there is a 2nd argument, we open the file and pass the file object to the encrypt function. If there isn't a 2nd argument, we open sys.stdin which is intended to let this script run by piping the output of another program to this program. This allows for running it using fortune: fortune | ./cryptogram.py

1: def encrypt(file):
2: alphabet = string.uppercase
3: text = ''
4:
5: for line in file.readlines():
6: text += string.upper(line)
7:
8: mixed = list(string.uppercase)
9: random.shuffle(mixed)
10: mixed = string.join(mixed,'')
11:
12: return string.translate(text,string.maketrans(mixed,alphabet))

This segment defines a function encrypt and takes one parameter, a file object. Line 2 sets up our alphabet, which is preset in the string library, along with many others. Lines 5 and 6 read the file in one line at a time, converts it to all uppercase, and appends each line onto the text variable.

Now we get to the meat. Lines 8 through 10 set up a string of letters consisting of the alphabet in random order. Line 8 uses the uppercase variable of the string module like we used before, but puts each letter into a list. The shuffle method of the random module expects a list so we pass 'mixed' to that. It performs an in-place shuffle. Line 10 we convert the list of letters back into a string.

Line 12 calls the translate function. This would be similar to Perl's tr/// call. The first argument is the text file we want to translate. The second argument is the translation table, which is a 256 byte string of the mapping that needs to be done. The maketrans function helps us build that string and both arguments to maketrans need to be the same length.

With that, I'll leave you with the full script, and the output on a quote. Here's a hint, it's a Monty Python quote.

#!/usr/bin/env python
# cryptogram.py
import sys, string, random

def encrypt(file):
alphabet = string.uppercase
text = ''

for line in file.readlines():
text += string.upper(line)

mixed = list(string.uppercase) # list of letters in alphabet
random.shuffle(mixed) # randomize it
mixed = string.join(mixed,'') # convert back to string

return string.translate(text,string.maketrans(mixed,alphabet))

if __name__ == '__main__':
if len(sys.argv) == 2:
print encrypt(open(sys.argv[1], 'r'))
else:
print encrypt(sys.stdin)

Output...

R GTRAN GTDG DSS OYYI, BROTG GTRANRAO CMYCSM RA
GTRW ZYVAGBL DBM WRZN DAI GRBMI YF EMRAO GYSI
GTDG DSS OYYI, BROTG GTRANRAO CMYCSM RA GTRW
ZYVAGBL DBM FMI VC URGT EMRAO GYSI GTDG DSS OYYI,
BROTG GTRANRAO CMYCSM RA GTRW ZYVAGBL DBM FMI
VC URGT EMRAO WRZN DAI GRBMI. R'J ZMBGDRASL AYG,
DAI R'J WRZN DAI GRBMI YF EMRAO GYSI GTDG R DJ!
-- JYAGL CLGTYA