自定义公告板

原创 2013年12月03日 17:07:44

公告板,我理解的是不是门岗大爷旁边的那个,通知我们最近需要我们注意的事情,我想除了检查卫生没别的了,而且好久也不见更新,还有一个就是电子公告板,流水字那个,就是很多二极管组成的数码管来显示字的那种(而且需要流动的),当然这个项目不是这个,公告板就是显示信息来通知别人的,那么这些信息是存储在那的呢?进入公告标题,里面应该是其内容或者还有一些其他的信息,这篇是把信息存在数据库里。

先看看数据库中建的一个表吧:

create table messages(
id int not null auto_increment,
subject varchar(100) not null,
sender varchar(15) not null,
reply_to int,
text mediumtext not null,
primary key(id));
如代码所示,只是建了 id ,subject,sender,reply_to,text,等5个字段和各自的类型及最大字符串长度。其中主键是id.

作为一个公告板,一定能显示信息和编辑信息吧。

先看看公告板的主页代码,所有通知的信息都应该在主页显示,不然该去哪看。

print 'Content-type:text/html\n'
print
#import cgitb:cgitb.enable()

import MySQLdb

conn = MySQLdb.connect(db='hu',user='root')

curs = conn.cursor()

print '''
<html>
  <head>
    <title>The hu yiyang</title>
  </head>
  <body>
    <h1>The hu yiyang </h1>
'''

curs.execute('SELECT * FROM messages')
rows = curs.fetchall()
toplevel = []
children = {}

for row in rows:
    parent_id = row[3]
    if parent_id is None:
        toplevel.append(row)
    else:
        children.setdefault(parent_id,[]).append(row)

    def format(row):
            print '<p><a href="view.cgi?id=%i">%s<a>' % 

(row[0],row[1])
            try:
                    kids = children[row[0]]
            except KeyError:
                    pass
	    else:
                    print '<blockquote>'
                    for kid in kids:
                            format(kid)

                    print '</blockquote>'

    print '<p>'

    for row in toplevel:
                format(row)

print '''
</p>
<hr/>
<p><a href="edit.cgi">Post Messages</a></p>
</body>
</html>
'''
刚开始与数据库进行连接,‘hu’是数据库名,‘root’是用户名。conn.cursor()是用来获取连接数据库的浮标,用于使用sql语句,下面就是打印一些信息,curs.execute()就是执行里面的sql语句,检索messages表中的所有字段信息,下面的curs.fetchall()就是把检索的信息按序列输出显示,下面这个for是处理有没有回复的消息,如果该主题没有人回复就把该行记录存储 在toplevel列表中,否则就吧该行记录记录到chilren字典中,其中setdefault函数的意思是如果parent_id有值(不是None),也就是有人回复信息,就把该行记录存储在children字典中(当然可以很多人回复消息,所以采用字典来存储),最终就是说没人回复的主题放在toplevel中,有人回复的放在children中。接着是format函数,主要进行对每一条记录显示的问题,     print '<p><a href="view.cgi?id=%i">%s<a>' % (row[0],row[1])的意思就是只要你点击某个主题,就会连接到其对应的内容里,然后又是捕捉异常的了,如果children[row['0']]有值,也就是说有回复信息,就会在该主题里显示出该回复信息,否则会引发一个KeyError异常,不过这个异常的执行是pass.,对应没人回复的信息也会执行一次format来链接显示这个主题。最后还有一个链接是Post messages,用于链接到编辑页面,edit.cgi.


下面看edit.cgi代码:

print 'Content-type: text/html\n'

#import cgitb: cgitb.enable()

import MySQLdb
conn = MySQLdb.connect(db='hu',user='root')
curs = conn.cursor()
import cgi,sys

form = cgi.FieldStorage()
reply_to = form.getvalue('reply_to')
print """
<html>
    <head>
        <title>Compose Messages</title>
    </head>
    <body>
        <h1>Compose Messages</h1>

        <form action='/cgi-bin/save.cgi' method='POST'>
        """
subject = ''
if reply_to is not None:
    print '<input type="hidden" name="reply_to" 

value="%s"/>'% reply_to
    curs.execute('SELECT subject FROM messages WHERE 

id=%s'% reply_to)
    subject = curs.fetchone()[0]
    if not subject.startswith('Re: '):
        subject = 'Re: '+subject

print '''
    <b>Subject:</b><br/>
    <input type='text' size='40' name='subject' 

value='%s' /><br/>
    <b>Sender:</b><br />
    <input type='text' size='40' name='sender' /><br/>
    <b>Message:</b><br/>
    <textarea name='text' cols='40' 

rows='20'></textarea><br/>
    <input type='submit' value='Save'/>
    </form>
    <hr/>
    <a href='main.cgi'>back to the main page</a>
    </body>
    </html>
    ''' % subject



刚开始都一样,都是链接存储信息的数据库,并且获取连接数据库的游标,以用于使用sql语句。cgi.FieldStorage()在上个项目就有,是用来获取上个页面提交过来的信息(也就是main.cgi),先获取字段名为‘reply_to’的信息(他中存储的是被回复那个主题的ID),存储到reply_to中,下面也是一个打印本页标题的html,   <form action='/cgi-bin/save.cgi' method='POST'>就是一个提交表单,要跳转的页面,action的值可以是本站点的url地址,也可以是其他站点的。如果有回复的信息,就把名为‘reply_to’,值为‘ 被回复主题的ID ’的信息隐藏起来(编辑该主题的时候并不需要看该主题的回复情况吧),接着是执行一条sql语句,意思是检索 messages表中id为reply_to的值的主题(就是查找被回复的那个主题),如果主题的开始不为‘Re : ’,则在回复的时候,主题前面自动加上‘Re:’,最后就是html了,各自的标题及文本框,还有个提交按钮‘Save’,用于跳转到save.cgi,还有个链接 back to the main page,用以回到主页。

下面看 save.cgi代码:

print 'Content-type:text/html\n'

import cgitb;cgitb.enable()

def quote(string):
        if string:
                return string.replace("'","\\'")
        else:
                return string

import MySQLdb
conn = MySQLdb.connect(db='hu',user='root')
curs = conn.cursor()

import cgi, sys
form = cgi.FieldStorage()

sender = quote(form.getvalue('sender'))
subject = quote(form.getvalue('subject'))
text = quote(form.getvalue('text'))
reply_to = form.getvalue('reply_to')

if not (sender and subject and text):
        print 'Please supply sender,subject,text'
        sys.exit()

if reply_to is not None:
        query = """
        INSERT INTO messages

(reply_to,sender,subject,text)
        VALUES(%d,'%s','%s','%s')""" % (int

(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()

print '''
<html>
  <head>
    <title>Messages Saved</title>
  </head>
  <body>
    <h1>Messages Saved</h1>
    <hr/>
    <a href='main.cgi'>Back to the main page</a>
  </body>
</html>s
'''

刚开始就定义一个quote函数,如果字符串存在,就把‘ ‘ ’换成’  \' ‘,否则返回本身。下面都是把获取到的值经过quote函数再赋给一个变量,而字段’reply_to‘就不需要,因为他是个整型,就直接获取了。下面意思是如果sender ,subject,text中有一个不存在(必须三个都存在才可以不执行下面的打印),就会打印需要你输入的信息,然后退出代码。

如果回复不为空,就往messages表中插入一条回复信息的记录,包括(reply_to,sender,subject,text),如果回复为空,就往messages表中插入一条不含有reply_to的记录,就是该条信息没人回复。commit()是把提交给数据库的信息更新。最后还是HTML,一个链接,back to the main page.


最后是 view.cgi:

print 'Content-type:text/html\n'
#import cgitb:cgitb.enable()
import MySQLdb
conn = MySQLdb.connect(db='hu',user='root')
curs = conn.cursor()

import cgi,sys
form = cgi.FieldStorage()
id = form.getvalue('id')

print """
<html>
    <head>
        <title>View Messages</title>
    </head>
    <body>
        <h1>View Messages</h1>
        """
try:
    id = int(id)
except:
    print 'Invalid messages ID'
    sys.exit()

curs.execute('SELECT * FROM messages WHERE id=%d'%id )
rows = curs.fetchall()
if not rows:
    print 'Unknown message ID'
    sys.exit()

row = rows[0]

print '''
<p><b>Subject:</b> %s<br/>
<b>Sender:</b>%s<br/>
<pre>%s</pre>
</p>
<hr/>
<a href='main.cgi'>Back to the main page</a>
|<a href="edit.cgi?reply_to=%s">Reply</a>
</body>
</html>
''' % (row[1],row[2],row[4],row[0])

前面一样,不过这个获取上页传来的id的值,主要是用于显示id为某个值的那条记录,一个捕捉id类型的异常。然后是一个数据库查询,查找传过来的那个id的所有记录,如果没有记录则打印未知的id,最后是一个html,比较不同的是这个里面加了个、Reply的链接,用于回复信息跳转到edit.cgi页面。


python项目练习七:自定义公告板

这依然是一个cgi的项目,有了前面的一个项目作为基础,这个里面没有什么难点。不过,和书上不同的是,我这里使用的数据库是mysql,所以有兴趣的童鞋,可以参考一下。 首先建立一张mysql的数据表...
  • tommyjsj
  • tommyjsj
  • 2013年11月14日 20:54
  • 1755

Direct-X学习笔记--公告板

// D3DDemo.cpp : 定义应用程序的入口点。 // #include "stdafx.h" #include "D3DDemo.h" #include "DirectInput.h" ...
  • puppet_master
  • puppet_master
  • 2015年08月13日 00:57
  • 895

【Visual C++】游戏开发五十四 浅墨DirectX教程二十一 视觉的诡计:公告板(Billboard)技术

I'm back~,这段时间大家久等了~ 现在大家看到的,就是【Visual C++】游戏开发系列文章第三季中作为正式回归的第一篇文章了。 在这篇文章中,我们一起详细探讨了游戏编程中公告板技术的方...
  • true11false
  • true11false
  • 2014年07月25日 22:58
  • 1001

【Visual C++】游戏开发五十四 浅墨DirectX教程二十一 视觉的诡计:公告板(Billboard)技术

现在大家看到的,就是【Visual C++】游戏开发系列文章第三季中作为正式回归的第一篇文章了。 在这篇文章中,我们一起详细探讨了游戏编程中公告板技术的方方面面,有“深入”的过程分析,也有“浅出”的大...
  • zhmxy555
  • zhmxy555
  • 2013年10月28日 00:05
  • 20116

cocos2d-x学习日志(15) --公告栏的实现(文字左右移动)

公告栏用的是CClayer(层)或者node节点,锚点位置是(0,0),文字信息使用CCLabelTTF保存,锚点位置是(0,0),使用的时候将它加入到node里面就好了 文字移动的思路是: ...
  • my183100521
  • my183100521
  • 2014年03月11日 17:36
  • 2405

XNA Billboard(公告板技术)

XNA Billboard(公告板技术)   公告板技术是3D游戏中用的非常多的一种技术,主要是用于控制场景中的Texture的方向,让他始终以一定的角度对着我们的镜头(一般是垂...
  • luyuncsd123
  • luyuncsd123
  • 2014年03月20日 09:58
  • 1063

【Android之垂直翻页公告】

源码github地址是:https://github.com/sfsheng0322/MarqueeView 该源码是android studio版本,本文最后提供的是eclipse版本,以...
  • bear_huangzhen
  • bear_huangzhen
  • 2016年06月14日 11:41
  • 1420

billboard公告板技术与perlin噪声的实现

一、billboard公告板技术1.简介在游戏中经常会遇到使用一张2D贴图来代替3D物体的情况,比如我们可以绘制一个2D的太阳贴图来代替3D的太阳模型,再比如使用2D的灌木、花草贴图来代替其复杂的3D...
  • xiewenzhao123
  • xiewenzhao123
  • 2017年04月04日 09:21
  • 186

【一步步学OpenGL 27】 -《公告牌技术与几何着色器》

教程 27公告牌技术与几何着色器原文: http://ogldev.atspace.co.uk/www/tutorial27/tutorial27.htmlCSDN完整版专栏: http://blog...
  • cordova
  • cordova
  • 2017年05月01日 16:56
  • 1943

Python项目7:自定义公告板

Python版本:3.4.3 操作系统:win7 此项目是分析python基础教程(第二版)的项目7:自定义公告板。改为适合于win7和python3的版本。 运用cgi,在项目六中有介绍。 准备工作...
  • ranky2009
  • ranky2009
  • 2015年07月25日 19:04
  • 766
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:自定义公告板
举报原因:
原因补充:

(最多只允许输入30个字)