Beginning Python - From Novice to Professional
Beginning Python - From Novice to Professional Beginning Python - From Novice to Professional
CHAPTER 26 ■ PROJECT 7: YOUR OWN BULLETIN BOARD 487 curs.dictfetchall(): Fetches all result rows as a sequence (for example, a list) of dictionaries. (Not part of the standard, and therefore not available in all modules.) Here is a simple test (assuming psycopg)—retrieving all the messages in the database (which is currently empty, so you won’t get any): >>> import psycopg >>> conn = psycopg.connect('user=foo dbname=bar') >>> curs = conn.cursor() >>> curs.execute('SELECT * FROM messages') >>> curs.fetchall() [] Because you haven’t implemented the Web interface yet, you have to enter messages manually if you want to test the database. You can do that either through an administrative tool (such as mysql for MySQL or psql for PostgreSQL), or you can use the Python interpreter with your database module. Here is a useful piece of code you can use for testing purposes: # addmessage.py import psycopg conn = psycopg.connect('user=foo dbname=bar') curs = conn.cursor() reply_to = raw_input('Reply to: ') subject = raw_input('Subject: ') sender = raw_input('Sender: ') text = raw_input('Text: ') if reply_to: query = """ INSERT INTO messages(reply_to, sender, subject, text) VALUES(%s, '%s', '%s', '%s')""" % (reply_to, sender, subject, text) else: query = """ INSERT INTO messages(sender, subject, text) VALUES('%s', '%s', '%s')""" % (sender, subject, text) curs.execute(query) conn.commit() Note that this code is a bit crude—it doesn’t keep track of IDs for you (you’ll have to make sure that what you enter as reply_to, if anything, is a valid ID), and it doesn’t deal properly with text containing single quotes (this can be problematic because single quotes are used as string delimiters in SQL). These issues will be dealt with in the final system, of course. Try to add a few messages and examine the database at the interactive Python prompt— if everything seems okay, it’s time to write a CGI script that accesses the database.
488 CHAPTER 26 ■ PROJECT 7: YOUR OWN BULLETIN BOARD Now that you’ve got the database handling code figured out and some ready-made CGI code you can pinch from Chapter 25, writing a script for viewing the message subjects (a simple version of the “main page” of the forum) shouldn’t be too hard. You must do the standard CGI setup (in this case, mainly printing the Content-type string), do the standard database setup (get a connection and a cursor), execute a simple SQL select command to get all the messages, and then retrieve the resulting rows with curs.fetchall or curs.dictfetchall. Listing 26-3 shows a script that does these things. The only really new stuff in the listing is the formatting code, which is used to get the threaded look where replies are displayed below and to the right of the messages they are replies to. It basically works like this: 1. For each message, get the reply_to field. If it is None (not a reply), add the message to the list of top-level messages. Otherwise, append the message to the list of children kept in children[parent_id]. 2. For each top-level message, call format. The format function prints the subject of the message. Also, if the message has any children, it opens a blockquote element (HTML), calls format (recursively) for each child, and ends the blockquote element. If you open the script in your Web browser (see Chapter 15 for information on how to run CGI scripts), you should see a threaded view of all the messages you’ve added (or their subjects, anyway). For an idea of what the bulletin board looks like, see Figure 26-1 later in this chapter. Listing 26-3. The Main Bulletin Board (simple_main.cgi) #!/usr/bin/python print 'Content-type: text/html\n' import cgitb; cgitb.enable() import psycopg conn = psycopg.connect('dbname=foo user=bar') curs = conn.cursor() print """ The FooBar Bulletin Board The FooBar Bulletin Board """
- Page 468: CHAPTER 22 ■ PROJECT 3: XML FOR A
- Page 471 and 472: 440 CHAPTER 23 ■ PROJECT 4: IN TH
- Page 473 and 474: 442 CHAPTER 23 ■ PROJECT 4: IN TH
- Page 475 and 476: 444 CHAPTER 23 ■ PROJECT 4: IN TH
- Page 477 and 478: 446 CHAPTER 23 ■ PROJECT 4: IN TH
- Page 479 and 480: 448 CHAPTER 23 ■ PROJECT 4: IN TH
- Page 481 and 482: 450 CHAPTER 23 ■ PROJECT 4: IN TH
- Page 483 and 484: 452 CHAPTER 23 ■ PROJECT 4: IN TH
- Page 486 and 487: CHAPTER 24 ■ ■ ■ Project 5: A
- Page 488 and 489: CHAPTER 24 ■ PROJECT 5: A VIRTUAL
- Page 490 and 491: CHAPTER 24 ■ PROJECT 5: A VIRTUAL
- Page 492 and 493: CHAPTER 24 ■ PROJECT 5: A VIRTUAL
- Page 494 and 495: CHAPTER 24 ■ PROJECT 5: A VIRTUAL
- Page 496 and 497: CHAPTER 24 ■ PROJECT 5: A VIRTUAL
- Page 498 and 499: CHAPTER 24 ■ PROJECT 5: A VIRTUAL
- Page 500 and 501: CHAPTER 24 ■ PROJECT 5: A VIRTUAL
- Page 502 and 503: CHAPTER 24 ■ PROJECT 5: A VIRTUAL
- Page 504 and 505: CHAPTER 25 ■ ■ ■ Project 6: R
- Page 506 and 507: CHAPTER 25 ■ PROJECT 6: REMOTE ED
- Page 508 and 509: CHAPTER 25 ■ PROJECT 6: REMOTE ED
- Page 510 and 511: CHAPTER 25 ■ PROJECT 6: REMOTE ED
- Page 512: CHAPTER 25 ■ PROJECT 6: REMOTE ED
- Page 515 and 516: 484 CHAPTER 26 ■ PROJECT 7: YOUR
- Page 517: 486 CHAPTER 26 ■ PROJECT 7: YOUR
- Page 521 and 522: 490 CHAPTER 26 ■ PROJECT 7: YOUR
- Page 523 and 524: 492 CHAPTER 26 ■ PROJECT 7: YOUR
- Page 525 and 526: 494 CHAPTER 26 ■ PROJECT 7: YOUR
- Page 527 and 528: 496 CHAPTER 26 ■ PROJECT 7: YOUR
- Page 529 and 530: 498 CHAPTER 26 ■ PROJECT 7: YOUR
- Page 531 and 532: 500 CHAPTER 27 ■ PROJECT 8: FILE
- Page 533 and 534: 502 CHAPTER 27 ■ PROJECT 8: FILE
- Page 535 and 536: 504 CHAPTER 27 ■ PROJECT 8: FILE
- Page 537 and 538: 506 CHAPTER 27 ■ PROJECT 8: FILE
- Page 539 and 540: 508 CHAPTER 27 ■ PROJECT 8: FILE
- Page 541 and 542: 510 CHAPTER 27 ■ PROJECT 8: FILE
- Page 543 and 544: 512 CHAPTER 27 ■ PROJECT 8: FILE
- Page 545 and 546: 514 CHAPTER 27 ■ PROJECT 8: FILE
- Page 547 and 548: 516 CHAPTER 27 ■ PROJECT 8: FILE
- Page 549 and 550: 518 CHAPTER 28 ■ PROJECT 9: FILE
- Page 551 and 552: 520 CHAPTER 28 ■ PROJECT 9: FILE
- Page 553 and 554: 522 CHAPTER 28 ■ PROJECT 9: FILE
- Page 555 and 556: 524 CHAPTER 28 ■ PROJECT 9: FILE
- Page 558 and 559: CHAPTER 29 ■ ■ ■ Project 10:
- Page 560 and 561: CHAPTER 29 ■ PROJECT 10: DO-IT-YO
- Page 562 and 563: CHAPTER 29 ■ PROJECT 10: DO-IT-YO
- Page 564 and 565: CHAPTER 29 ■ PROJECT 10: DO-IT-YO
- Page 566 and 567: CHAPTER 29 ■ PROJECT 10: DO-IT-YO
488 CHAPTER 26 ■ PROJECT 7: YOUR OWN BULLETIN BOARD<br />
Now that you’ve got the database handling code figured out and some ready-made CGI<br />
code you can pinch from Chapter 25, writing a script for viewing the message subjects (a simple<br />
version of the “main page” of the forum) shouldn’t be <strong>to</strong>o hard. You must do the standard CGI<br />
setup (in this case, mainly printing the Content-type string), do the standard database setup<br />
(get a connection and a cursor), execute a simple SQL select command <strong>to</strong> get all the messages,<br />
and then retrieve the resulting rows with curs.fetchall or curs.dictfetchall.<br />
Listing 26-3 shows a script that does these things. The only really new stuff in the listing is<br />
the formatting code, which is used <strong>to</strong> get the threaded look where replies are displayed below<br />
and <strong>to</strong> the right of the messages they are replies <strong>to</strong>.<br />
It basically works like this:<br />
1. For each message, get the reply_<strong>to</strong> field. If it is None (not a reply), add the message <strong>to</strong> the<br />
list of <strong>to</strong>p-level messages. Otherwise, append the message <strong>to</strong> the list of children kept in<br />
children[parent_id].<br />
2. For each <strong>to</strong>p-level message, call format.<br />
The format function prints the subject of the message. Also, if the message has any children,<br />
it opens a blockquote element (HTML), calls format (recursively) for each child, and ends the<br />
blockquote element.<br />
If you open the script in your Web browser (see Chapter 15 for information on how <strong>to</strong> run<br />
CGI scripts), you should see a threaded view of all the messages you’ve added (or their subjects,<br />
anyway).<br />
For an idea of what the bulletin board looks like, see Figure 26-1 later in this chapter.<br />
Listing 26-3. The Main Bulletin Board (simple_main.cgi)<br />
#!/usr/bin/python<br />
print 'Content-type: text/html\n'<br />
import cgitb; cgitb.enable()<br />
import psycopg<br />
conn = psycopg.connect('dbname=foo user=bar')<br />
curs = conn.cursor()<br />
print """<br />
<br />
<br />
The FooBar Bulletin Board<br />
<br />
<br />
The FooBar Bulletin Board<br />
"""