summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Leitch <port001@gentoo.org>2004-06-04 06:38:44 +0000
committerIan Leitch <port001@gentoo.org>2004-06-04 06:38:44 +0000
commit5a270d700934ca5ea31afee1018d7885ce1b018b (patch)
tree490abf233a409839c564a8c2b7cc9db9596d663e
parent(no commit message) (diff)
downloadgentoo-import-1.1.1.tar.gz
gentoo-import-1.1.1.tar.bz2
gentoo-import-1.1.1.zip
Import of the GLSR source. This is its new home. import-1.1.1
-rw-r--r--src/glsr/src/AUTHORS10
-rw-r--r--src/glsr/src/COPYING7
-rw-r--r--src/glsr/src/LineCount.py37
-rw-r--r--src/glsr/src/Setup.py190
-rw-r--r--src/glsr/src/SiteModules/Admin/Page_Main.py44
-rw-r--r--src/glsr/src/SiteModules/Admin/Page_News.py109
-rw-r--r--src/glsr/src/SiteModules/Admin/Page_Script.py293
-rw-r--r--src/glsr/src/SiteModules/Admin/Page_User.py127
-rw-r--r--src/glsr/src/SiteModules/Admin/__init__.py1
-rw-r--r--src/glsr/src/SiteModules/Global/Page_Login.py38
-rw-r--r--src/glsr/src/SiteModules/Global/__init__.py1
-rw-r--r--src/glsr/src/SiteModules/__init__.py0
-rw-r--r--src/glsr/src/htdocs/admin/cookie.py27
-rw-r--r--src/glsr/src/htdocs/admin/cookieremove.py24
-rw-r--r--src/glsr/src/htdocs/admin/index.py114
-rw-r--r--src/glsr/src/htdocs/css/glsr.css236
-rw-r--r--src/glsr/src/htdocs/images/4star.pngbin0 -> 462 bytes
-rw-r--r--src/glsr/src/htdocs/images/PythonPoweredSmall.gifbin0 -> 361 bytes
-rw-r--r--src/glsr/src/htdocs/images/dialog-info.pngbin0 -> 3192 bytes
-rw-r--r--src/glsr/src/htdocs/images/favicon.icobin0 -> 1406 bytes
-rw-r--r--src/glsr/src/htdocs/images/glogo.pngbin0 -> 19611 bytes
-rw-r--r--src/glsr/src/htdocs/images/header-bk.pngbin0 -> 124 bytes
-rw-r--r--src/glsr/src/htdocs/images/news.pngbin0 -> 2147 bytes
-rw-r--r--src/glsr/src/htdocs/images/people.pngbin0 -> 3667 bytes
-rw-r--r--src/glsr/src/htdocs/images/splogo-beta.pngbin0 -> 10228 bytes
-rw-r--r--src/glsr/src/htdocs/images/splogo.pngbin0 -> 9266 bytes
-rw-r--r--src/glsr/src/htdocs/images/star.pngbin0 -> 320 bytes
-rw-r--r--src/glsr/src/htdocs/images/stock_notes.pngbin0 -> 2454 bytes
-rw-r--r--src/glsr/src/pym/Admin.py20
-rw-r--r--src/glsr/src/pym/Auth.py21
-rw-r--r--src/glsr/src/pym/Category.py67
-rw-r--r--src/glsr/src/pym/Comment.py37
-rw-r--r--src/glsr/src/pym/Config.py64
-rw-r--r--src/glsr/src/pym/Const.py93
-rw-r--r--src/glsr/src/pym/Function.py62
-rw-r--r--src/glsr/src/pym/GLSRBackend.py120
-rw-r--r--src/glsr/src/pym/Language.py29
-rw-r--r--src/glsr/src/pym/MySQL.py110
-rw-r--r--src/glsr/src/pym/News.py42
-rw-r--r--src/glsr/src/pym/Script.py135
-rw-r--r--src/glsr/src/pym/Session.py200
-rw-r--r--src/glsr/src/pym/Stat.py70
-rw-r--r--src/glsr/src/pym/Template.py285
-rw-r--r--src/glsr/src/pym/Template_ng.py285
-rw-r--r--src/glsr/src/pym/User.py127
-rw-r--r--src/glsr/src/pym/Validation.py37
-rw-r--r--src/glsr/src/templates/Footer.tpl21
-rw-r--r--src/glsr/src/templates/admin/Categories.tpl80
-rw-r--r--src/glsr/src/templates/admin/Header.tpl56
-rw-r--r--src/glsr/src/templates/admin/Languages.tpl67
-rw-r--r--src/glsr/src/templates/admin/Main.tpl36
-rw-r--r--src/glsr/src/templates/admin/News.tpl97
-rw-r--r--src/glsr/src/templates/admin/Script_Controls.tpl53
-rw-r--r--src/glsr/src/templates/admin/Script_Results.tpl41
-rw-r--r--src/glsr/src/templates/admin/Script_Search.tpl96
-rw-r--r--src/glsr/src/templates/admin/User.tpl2
-rw-r--r--src/glsr/src/templates/admin/User_Controls.tpl132
-rw-r--r--src/glsr/src/templates/test.tpl15
58 files changed, 3758 insertions, 0 deletions
diff --git a/src/glsr/src/AUTHORS b/src/glsr/src/AUTHORS
new file mode 100644
index 0000000000..43387dd8cb
--- /dev/null
+++ b/src/glsr/src/AUTHORS
@@ -0,0 +1,10 @@
+# $Id: AUTHORS,v 1.1.1.1 2004/06/04 06:38:33 port001 Exp $
+
+
+* Ian Leitch (port001)
+ Role: Project Lead / Coding / Site Design
+ Contact: port001@gentoo.org
+
+* Scott Hadfield (hadfield)
+ Role: Coding / Page Creation
+ Contact: shadfiel@sfu.ca
diff --git a/src/glsr/src/COPYING b/src/glsr/src/COPYING
new file mode 100644
index 0000000000..b417dfaf2b
--- /dev/null
+++ b/src/glsr/src/COPYING
@@ -0,0 +1,7 @@
+Copyright 2004 Ian Leitch
+Copyright 2004 Scott Hadfield
+Copyright 1999-2004 Gentoo Technologies, Inc.
+
+This code is provided as-is.
+
+THIS CODE IS NOT FOR PUBLIC RELEASE.
diff --git a/src/glsr/src/LineCount.py b/src/glsr/src/LineCount.py
new file mode 100644
index 0000000000..21946115c6
--- /dev/null
+++ b/src/glsr/src/LineCount.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+# $Id: LineCount.py,v 1.1.1.1 2004/06/04 06:38:32 port001 Exp $
+
+import os
+
+WWW_DIR = os.path.join(os.getcwd(), "htdocs")
+GLSR_DIR = os.getcwd()
+
+MyFiles = ("%s/Setup.py" % GLSR_DIR, "%s/admin/index.py" % WWW_DIR)
+MyDirs = ("%s/pym" % GLSR_DIR, "%s/SiteModules" % GLSR_DIR)
+
+FileList = []
+LineCount = 0
+
+for File in MyFiles:
+ FileList.append(File)
+
+for Dir in MyDirs:
+ for Dir, SubDir, Files in os.walk(Dir):
+ if not Dir.endswith("CVS"):
+ for File in Files:
+ FileList.append(os.path.join(Dir, File))
+
+for File in FileList:
+ fd = open(File, "r")
+ FileLineCount = 0
+ for line in fd.readlines():
+ if not line.strip(" ").startswith("#") and not line.strip(" ").startswith("\n"):
+ FileLineCount += 1
+ print "%d\t: %s" % (FileLineCount, File)
+ LineCount += FileLineCount
+ fd.close()
+
+print
+print "GLSR Line Count: %d" % LineCount
+
+
diff --git a/src/glsr/src/Setup.py b/src/glsr/src/Setup.py
new file mode 100644
index 0000000000..c469733932
--- /dev/null
+++ b/src/glsr/src/Setup.py
@@ -0,0 +1,190 @@
+#!/usr/bin/env python2
+#
+# Copyright 2004 Ian Leitch
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Setup.py,v 1.1.1.1 2004/06/04 06:38:33 port001 Exp $
+#
+
+import sys
+import operator
+import MySQLdb
+import getpass
+from time import strftime, gmtime
+
+sys.path.insert(0, "/usr/lib/glsr/pym")
+sys.path.insert(0, "/var/www/buffmuthers.com/htdocs/projects/glsr/pym")
+
+import Config
+import Const
+
+db = MySQLdb.connect(host=Config.MySQL["host"], user=Config.MySQL["user"], passwd=Config.MySQL["passwd"], db=Config.MySQL["db"])
+cursor = db.cursor()
+
+print "Creating MySQL tables:"
+
+print " >>> %s%s" % (Config.MySQL["prefix"], Config.MySQL["user_table"])
+user_table = ("CREATE TABLE " + Config.MySQL["prefix"] + """%s (
+ %s_id MEDIUMINT(5) unsigned NOT NULL auto_increment,
+ %s_alias VARCHAR(25) NOT NULL,
+ %s_fullname VARCHAR(40) NOT NULL,
+ %s_passwd VARCHAR(32) NOT NULL,
+ %s_email VARCHAR(50) NOT NULL,
+ %s_rank MEDIUMINT(5) NOT NULL default '0',
+ %s_type TINYINT(1) unsigned NOT NULL default '0',
+ %s_joined DATE NOT NULL,
+ %s_lastip VARCHAR(15) NULL,
+ PRIMARY KEY(%s_id),
+ KEY %s_id(%s_id));""" %
+ tuple(operator.repeat([Config.MySQL["user_table"]], 13)))
+
+cursor.execute(user_table)
+db.commit()
+
+print " >>> %s%s" % (Config.MySQL["prefix"], Config.MySQL["category_table"])
+category_table = ("CREATE TABLE " + Config.MySQL["prefix"] + """%s (
+ %s_id SMALLINT(3) unsigned NOT NULL auto_increment,
+ %s_name VARCHAR(50) NOT NULL,
+ %s_descr VARCHAR(100) NULL,
+ %s_parent_id SMALLINT(3) unsigned NOT NULL default '0',
+ PRIMARY KEY(%s_id),
+ KEY %s_id(%s_id));""" %
+ tuple(operator.repeat([Config.MySQL["category_table"]], 8)))
+
+cursor.execute(category_table)
+db.commit()
+
+print " >>> %s%s" % (Config.MySQL["prefix"], Config.MySQL["language_table"])
+category_table = ("CREATE TABLE " + Config.MySQL["prefix"] + """%s (
+ %s_id SMALLINT(3) unsigned NOT NULL auto_increment,
+ %s_name VARCHAR(50) NOT NULL,
+ %s_descr VARCHAR(100) NULL,
+ PRIMARY KEY(%s_id),
+ KEY %s_id(%s_id));""" %
+ tuple(operator.repeat([Config.MySQL["language_table"]], 7)))
+
+cursor.execute(category_table)
+db.commit()
+
+
+print " >>> %s%s" % (Config.MySQL["prefix"], Config.MySQL["comment_table"])
+comment_table = ("CREATE TABLE " + Config.MySQL["prefix"] + """%s (
+ %s_id MEDIUMINT(6) unsigned NOT NULL auto_increment,
+ %s_submitter_id MEDIUMINT(5) unsigned NOT NULL,
+ %s_date DATETIME NULL,
+ %s_subject VARCHAR(30) NULL,
+ %s_lastedited DATETIME NULL,
+ %s_body TEXT NOT NULL,
+ %s_ofscript MEDIUMINT(6) unsigned NOT NULL,
+ %s_ofversion INT(10) unsigned NULL,
+ PRIMARY KEY(%s_id),
+ KEY %s_id(%s_id));""" %
+ tuple(operator.repeat([Config.MySQL["comment_table"]], 12)))
+
+cursor.execute(comment_table)
+db.commit()
+
+print " >>> %s%s" % (Config.MySQL["prefix"], Config.MySQL["script_table"])
+script_table = ("CREATE TABLE " + Config.MySQL["prefix"] + """%s (
+ %s_id MEDIUMINT(7) unsigned NOT NULL auto_increment,
+ %s_submitter_id MEDIUMINT(5) unsigned NOT NULL,
+ %s_category_id SMALLINT(3) unsigned NOT NULL,
+ %s_language_id SMALLINT(3) unsigned NOT NULL,
+ %s_rank TINYINT(1) NOT NULL default '0',
+ %s_name VARCHAR(30) NOT NULL,
+ %s_descr VARCHAR(100) NOT NULL,
+ PRIMARY KEY(%s_id),
+ KEY %s_id(%s_id));""" %
+ tuple(operator.repeat([Config.MySQL["script_table"]], 11)))
+
+cursor.execute(script_table)
+db.commit()
+
+print " >>> %s%s" % (Config.MySQL["prefix"], Config.MySQL["subscript_table"])
+subscript_table = ("CREATE TABLE " + Config.MySQL["prefix"] + """%s (
+ %s_id INT(10) unsigned NOT NULL auto_increment,
+ %s_parent_id MEDIUMINT(7) unsigned NOT NULL,
+ %s_version VARCHAR(10) NOT NULL,
+ %s_body TEXT NOT NULL,
+ %s_changelog TEXT NOT NULL,
+ %s_date DATETIME NULL,
+ %s_approved TINYINT(1) NOT NULL default '-1',
+ %s_approvedby MEDIUMINT(5) unsigned NULL,
+ PRIMARY KEY(%s_id),
+ KEY %s_id(%s_id));""" %
+ tuple(operator.repeat([Config.MySQL["subscript_table"]],
+ 12)))
+
+cursor.execute(subscript_table)
+db.commit()
+
+print " >>> %s%s" % (Config.MySQL["prefix"], Config.MySQL["session_table"])
+session_table = ("CREATE TABLE " + Config.MySQL["prefix"] + """%s (
+ %s_id VARCHAR(30) NOT NULL,
+ %s_user_id MEDIUMINT(5) unsigned NOT NULL,
+ %s_time INT(10) NOT NULL,
+ PRIMARY KEY(%s_id),
+ KEY %s_id(%s_id));""" %
+ tuple(operator.repeat([Config.MySQL["session_table"]], 7)))
+
+cursor.execute(session_table)
+db.commit()
+
+# Error reporting turned out not to be practical, leave this here just incase we decide to use a file based system.
+#print " >>> %s" % Config.MySQL["error_table"]
+#error_table = """CREATE TABLE %s (
+# errid TINYINT(2) unsigned NOT NULL auto_increment,
+# errmsg TEXT NOT NULL,
+# date DATETIME NOT NULL,
+# PRIMARY KEY(errid),
+# KEY errid(errid));""" % Config.MySQL["error_table"]
+#
+#cursor.execute(error_table)
+#db.commit()
+
+print " >>> %s%s" % (Config.MySQL["prefix"], Config.MySQL["news_table"])
+news_table = ("CREATE TABLE " + Config.MySQL["prefix"] + """%s (
+ %s_id INT(10) unsigned NOT NULL auto_increment,
+ %s_author_id MEDIUMINT(5) unsigned NOT NULL,
+ %s_date DATETIME NOT NULL,
+ %s_subject VARCHAR(100) NOT NULL,
+ %s_body TEXT NOT NULL,
+ PRIMARY KEY(%s_id),
+ KEY %s_id(%s_id));""" %
+ tuple(operator.repeat([Config.MySQL["news_table"]], 9)))
+
+cursor.execute(news_table)
+db.commit()
+
+admin = raw_input("\nAdmin user: ")
+if len(admin) == 0:
+ print "ERROR: Zero length username"
+ sys.exit(1)
+
+passwd = getpass.getpass("Password: ")
+if len(passwd) == 0:
+ print "ERROR: Zero length password"
+ sys.exit(1)
+
+passwd2 = getpass.getpass("Re-type password: ")
+if passwd != passwd2:
+ print "ERROR: passwords do not match"
+ sys.exit(1)
+
+fullname = raw_input("Full Name: ")
+email = raw_input("Email: ")
+
+print "Creating admin user %s..." % (admin)
+
+cursor.execute("INSERT INTO %s%s " %
+ (Config.MySQL["prefix"], Config.MySQL["user_table"]) +
+ """(%s_alias, %s_fullname, %s_passwd, %s_email, %s_rank,
+ %s_type, %s_joined)""" %
+ tuple(operator.repeat([Config.MySQL["user_table"]], 7)) +
+ """ VALUES (%s, %s, PASSWORD(%s), %s, 0, %s, %s)""",
+ (admin, fullname, passwd, email, Const.TYPE["admin"],
+ strftime("%Y-%m-%d", gmtime())))
+db.commit()
+cursor.close()
+print "\nKeep me safe! You may need me later (if things go wrong ;)."
diff --git a/src/glsr/src/SiteModules/Admin/Page_Main.py b/src/glsr/src/SiteModules/Admin/Page_Main.py
new file mode 100644
index 0000000000..142be99eca
--- /dev/null
+++ b/src/glsr/src/SiteModules/Admin/Page_Main.py
@@ -0,0 +1,44 @@
+#!/usr/bin/python
+#
+# Copyright 2004 Ian Leitch
+# Copyright 2004 Scott Hadfield
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Page_Main.py,v 1.1.1.1 2004/06/04 06:38:38 port001 Exp $
+#
+
+MetaData = {"page" : ("main", None), "params" : ""}
+
+import Template as TemplateHandler
+import Session
+import Config
+import Stat
+from User import User
+
+def Display():
+
+ user_online_list = ""
+ sess_obj = Session.New()
+ sessions = sess_obj.ListSessionsOnline(Config.WhoIsOnlineOffset)
+
+ if len(sessions) == 0:
+ user_online_list = "No registered accounts active."
+ else:
+ for session in sessions:
+ user_obj = User(session["session_user_id"])
+ user_online_list = "%s %s" % (user_online_list,
+ user_obj.GetAlias())
+
+ AdminMainTemplate = TemplateHandler.New()
+ AdminMainTemplate.Compile(Config.Template["admin_main"],
+ {"GLSR_URL": Config.URL,
+ "USER_COUNT": Stat.UserCount(),
+ "SESSION_COUNT": Stat.SessionCount(),
+ "SCRIPT_COUNT": Stat.ScriptCount(),
+ "SUBSCRIPT_COUNT": Stat.SubScriptCount(),
+ "CATEGORY_COUNT": Stat.CategoryCount(),
+ "COMMENT_COUNT": Stat.CommentCount(),
+ "DBSIZE": Stat.DBSize(),
+ "USER_ONLINE_LIST": user_online_list})
+ AdminMainTemplate.Print()
diff --git a/src/glsr/src/SiteModules/Admin/Page_News.py b/src/glsr/src/SiteModules/Admin/Page_News.py
new file mode 100644
index 0000000000..5ffffff0d3
--- /dev/null
+++ b/src/glsr/src/SiteModules/Admin/Page_News.py
@@ -0,0 +1,109 @@
+#!/usr/bin/python
+#
+# Copyright 2004 Ian Leitch
+# Copyright 2004 Scott Hadfield
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Page_News.py,v 1.1.1.1 2004/06/04 06:38:37 port001 Exp $
+#
+
+MetaData = {"page" : ("news",), "params" : "form, uid"}
+
+import Template as TemplateHandler
+import Config
+from User import User
+from News import News
+
+def Display(form, uid):
+
+ aliases = []
+ message = ""
+ warn_message = ""
+ announce_mode = ""
+ add_announce = 0
+ add_modify_announce = 0
+ subject = ""
+ author = 0
+ announcement = ""
+ form_inputs = form.keys()
+
+ news_obj = News()
+
+ if "delete_announce" in form_inputs:
+
+ count = 0
+
+ for annid in form.getlist("delete"):
+ if news_obj.AnnidExists(annid):
+ news.obj.id = annid
+ news_obj.Remove()
+ count += 1
+
+ if count > 1:
+ message = "%s Announcements Successfully Deleted" % count
+ else:
+ message = "%s Announcement Successfully Deleted" % count
+
+ form_inputs.append("show_all_announce")
+
+ if "show_all_announce" in form_inputs:
+
+ row = "even"
+ for record in news_obj.List():
+ record.update({"row": row})
+ user_obj = User(record["news_author_id"])
+ record["news_author_id"] = user_obj.GetAlias()
+ aliases.append(record)
+ if row == "even":
+ row = "odd"
+ else:
+ row = "even"
+
+ if len(aliases) == 0:
+ warn_message = "No News Announcements Found"
+
+ elif "show_modify_announce" in form_inputs:
+
+ add_modify_announce = form.getvalue("show_modify_announce")
+ news_obj.SetID(add_modify_announce)
+ announce_info = news_obj.GetDetails()
+
+ subject = announce_info["subject"]
+ announcement = announce_info["body"]
+ announce_mode = "Modify Announcement"
+
+ elif "modify_announce" in form_inputs:
+
+ news_obj.SetID(form.getvalue("annid"))
+ news_obj.Modify(form.getvalue("subject"), uid,
+ form.getvalue("announcement"))
+ message = "Announcement Updated"
+
+ elif "show_add_new_announce" in form_inputs:
+
+ add_announce = 1
+ add_modify_announce = 1
+ announce_mode = "Make News Announcement"
+
+ elif "add_new_announce" in form_inputs:
+
+ subject = form.getvalue("subject")
+ announcement = form.getvalue("announcement")
+ news_obj.Create(subject, uid, announcement)
+ message = "Announcement Successfully Added"
+
+
+ AdminNewsTemplate = TemplateHandler.New()
+ AdminNewsTemplate.Compile(Config.Template["admin_news"],
+ {"GLSR_URL": Config.URL,
+ "MESSAGE": message,
+ "TOTAL_ANNOUNCE": len(aliases),
+ "WARN_MESSAGE": warn_message,
+ "ADD_MODIFY_ANNOUNCE": add_modify_announce,
+ "ADD_ANNOUNCE_FORM": add_announce,
+ "ANNOUNCE_MODE": announce_mode,
+ "SUBJECT": subject,
+ "ANNOUNCEMENT": announcement},
+ {"ANNOUNCE_LOOP": aliases})
+ AdminNewsTemplate.Print()
diff --git a/src/glsr/src/SiteModules/Admin/Page_Script.py b/src/glsr/src/SiteModules/Admin/Page_Script.py
new file mode 100644
index 0000000000..f04cf97303
--- /dev/null
+++ b/src/glsr/src/SiteModules/Admin/Page_Script.py
@@ -0,0 +1,293 @@
+#!/usr/bin/python
+#
+# Copyright 2004 Ian Leitch
+# Copyright 2004 Scott Hadfield
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Page_Script.py,v 1.1.1.1 2004/06/04 06:38:38 port001 Exp $
+#
+
+MetaData = {"page" : ("script",), "params" : "form"}
+
+import Template as TemplateHandler
+import Config
+
+from Script import Script
+from Category import Category
+from Language import Language
+
+def Display(form):
+
+ if "open_search_page" in form.keys():
+
+ displaySearchForm()
+
+ elif "list_all_scripts" in form.keys():
+
+ displayMainPage()
+ displaySearchResults(form)
+
+ elif (form.has_key("show_all_categories") or
+ form.has_key("show_add_new_cat") or
+ form.has_key("show_modify_cat") or
+ form.has_key("add_new_cat") or
+ form.has_key("modify_cat") or
+ form.has_key("delete_cats")):
+
+ displayMainPage()
+ displayCategories(form)
+
+ elif (form.has_key("show_all_languages") or
+ form.has_key("show_add_new_lang") or
+ form.has_key("show_modify_lang") or
+ form.has_key("add_new_lang") or
+ form.has_key("modify_lang") or
+ form.has_key("delete_langs")):
+
+ displayMainPage()
+ displayLanguages(form)
+
+ elif "search_script" in form.keys():
+
+ displaySearchResults(form)
+
+ else:
+
+ displayMainPage()
+
+def displayCategories(form):
+
+ cats = []
+ parents = []
+ add_cat = 0
+ modify_cat = 0
+ name = ""
+ descr = ""
+ parent = ""
+ message = ""
+ warn_message = 0
+ form_inputs = form.keys()
+
+ cat_obj = Category()
+
+ if "add_new_cat" in form.keys():
+
+ cat_obj.Create(form.getvalue("name"), form.getvalue("descr"),
+ form.getvalue("parent"))
+ message = "Category Successfully Added"
+ form_inputs.append("show_all_categories")
+
+ elif "modify_cat" in form.keys():
+
+ cat_obj.SetID(form.getvalue("catid"))
+ cat_obj.Modify(form.getvalue("name"), form.getvalue("descr"),
+ form.getvalue("parent"))
+ message = "Category Successfully Modified"
+ form_inputs.append("show_all_categories")
+
+ elif "delete_cats" in form.keys():
+
+ for catid in form.getlist("delete"):
+ if cat_obj.SetID(catid):
+ cat_obj.Remove()
+
+ message = "Categories Successfully Deleted"
+ form_inputs.append("show_all_categories")
+
+
+ if "show_all_categories" in form_inputs:
+
+ def listCats(parent_id, padding = 12):
+ list = []
+
+ for record in cat_obj.List(parent_id):
+ if record["category_parent_id"]:
+ cat_obj.SetID(record["category_parent_id"])
+ parent_details = cat_obj.GetDetails()
+ record["parent_name"] = parent_details["category_name"]
+ else:
+ record["parent_name"] = "None"
+
+ record["padding"] = padding
+ list.append(record)
+ list = list + listCats(record["category_id"], padding + 12)
+
+ return list
+
+ cats = listCats(0)
+ for i in range(len(cats)):
+ if i % 2:
+ cats[i].update({"row": "odd"})
+ else:
+ cats[i].update({"row": "even"})
+
+ if not len(cats):
+ warn_message = 1
+
+ elif "show_add_new_cat" in form_inputs:
+
+ add_cat = 1
+ modify_cat = 1
+ parents = cat_obj.List()
+
+ elif "show_modify_cat" in form_inputs:
+
+ modify_cat = form.getvalue("show_modify_cat")
+ cat_obj.SetID(form["show_modify_cat"].value)
+ cat_info = cat_obj.GetDetails()
+ name = cat_info["category_name"]
+ descr = cat_info["category_descr"]
+ parent = cat_info["category_parent_id"]
+ parents = cat_obj.List()
+
+
+ CategoriesTemplate = TemplateHandler.New()
+ CategoriesTemplate.Compile(Config.Template["admin_categories"],
+ {"GLSR_URL": Config.URL,
+ "TOTAL_CATS": len(cats),
+ "MODIFY_CAT": modify_cat,
+ "ADD_CAT_FORM": add_cat,
+ "NAME": name,
+ "DESCR": descr,
+ "PARENT": parent,
+ "MESSAGE": message,
+ "WARN_MESSAGE": warn_message},
+ {"CAT_LOOP": cats,
+ "PARENT_LOOP": parents})
+ CategoriesTemplate.Print()
+
+def displayLanguages(form):
+
+ langs = []
+ add_lang = 0
+ modify_lang = 0
+ name = ""
+ descr = ""
+ message = ""
+ warn_message = 0
+ form_inputs = form.keys()
+
+ lang_obj = Language()
+
+ if "add_new_lang" in form.keys():
+
+ name = form.getvalue("name")
+ descr = form.getvalue("descr")
+ lang_obj.Create(name, descr)
+ message = "Language Successfully Added"
+ form_inputs.append("show_all_languages")
+
+ elif "delete_langs" in form.keys():
+
+ for langid in form.getlist("delete"):
+ if lang_obj.SetID(langid):
+ lang_obj.Remove()
+
+ message = "Languages Successfully Deleted"
+ form_inputs.append("show_all_languages")
+
+ elif "modify_lang" in form.keys():
+
+ lang_obj.SetID(form.getvalue("langid"))
+ lang_obj.Modify(form.getvalue("name"), form.getvalue("descr"))
+
+ form_inputs.append("show_all_languages")
+
+
+ if "show_all_languages" in form_inputs:
+
+ row = "even"
+ for record in lang_obj.List():
+ record.update({"row": row})
+ langs.append(record)
+ if row == "even":
+ row = "odd"
+ else:
+ row = "even"
+
+ if not len(langs):
+ warn_message = 1
+
+ elif "show_add_new_lang" in form_inputs:
+
+ add_lang = 1
+ modify_lang = 1
+
+ elif "show_modify_lang" in form_inputs:
+
+ modify_lang = form.getvalue("show_modify_lang")
+ lang_obj.SetID(form["show_modify_lang"].value)
+ lang_info = lang_obj.GetDetails()
+ name = lang_info["language_name"]
+ descr = lang_info["language_descr"]
+
+
+ LanguagesTemplate = TemplateHandler.New()
+ LanguagesTemplate.Compile(Config.Template["admin_languages"],
+ {"GLSR_URL": Config.URL,
+ "TOTAL_LANGS": len(langs),
+ "MODIFY_LANG": modify_lang,
+ "ADD_LANG_FORM": add_lang,
+ "NAME": name,
+ "DESCR": descr,
+ "MESSAGE": message,
+ "WARN_MESSAGE": warn_message},
+ {"LANG_LOOP": langs})
+ LanguagesTemplate.Print()
+
+
+def displayMainPage():
+
+ AdminScriptTemplate = TemplateHandler.New()
+ AdminScriptTemplate.Compile(Config.Template["admin_script"],
+ {"GLSR_URL": Config.URL,
+ "MESSAGE": "",
+ "WARN_MESSAGE": 0,
+ "TOTAL_SCRIPTS": 0})
+ AdminScriptTemplate.Print()
+
+
+def displaySearchResults(form):
+
+ search_terms = {}
+ search_terms["language"] = []
+ search_terms["category"] = []
+ search_terms["status"] = []
+
+ for key in form.keys():
+
+ if key[:key.find('_')] == "lang":
+ search_terms["language"].append(key[key.find('_')+1:])
+
+ elif key[:key.find('_')] == "cat":
+ search_terms["category"].append(key[key.find('_')+1:])
+
+ elif key[:key.find('_')] == "stat":
+ search_terms["status"].append(key[key.find('_')+1:])
+
+ for key in ["name", "descr", "submitter", "most_recent"]:
+ if key in form.keys():
+ search_terms[key] = form[key].value
+
+ script_obj = Script()
+ results = script_obj.Search(search_terms)
+
+ warn_message = 0
+ if not len(results):
+ warn_message = 1
+
+ ScriptResultsTemplate = TemplateHandler.New()
+ ScriptResultsTemplate.Compile(Config.Template["admin_script_results"],
+ {"GLSR_URL": Config.URL,
+ "TOTAL_SCRIPTS": len(results),
+ "WARN_MESSAGE": warn_message},
+ {"SCRIPT_LOOP": results})
+ ScriptResultsTemplate.Print()
+
+def displaySearchForm():
+
+ ScriptSearchTemplate = TemplateHandler.New()
+ ScriptSearchTemplate.Compile(Config.Template["admin_script_search"],
+ {"GLSR_URL": Config.URL})
+ ScriptSearchTemplate.Print()
diff --git a/src/glsr/src/SiteModules/Admin/Page_User.py b/src/glsr/src/SiteModules/Admin/Page_User.py
new file mode 100644
index 0000000000..9cfc31a071
--- /dev/null
+++ b/src/glsr/src/SiteModules/Admin/Page_User.py
@@ -0,0 +1,127 @@
+#!/usr/bin/python
+#
+# Copyright 2004 Ian Leitch
+# Copyright 2004 Scott Hadfield
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Page_User.py,v 1.1.1.1 2004/06/04 06:38:37 port001 Exp $
+#
+
+MetaData = {"page" : ("user",), "params" : "form, uid"}
+
+import Template as TemplateHandler
+import Config
+import MySQL
+from User import User
+
+def Display(form, uid):
+
+ aliases = []
+ add_user = 0
+ modify_user = 0
+ alias = ""
+ fullname = ""
+ email = ""
+ rank = 0
+ type = 0
+ message = ""
+ warn_message = ""
+ form_inputs = form.keys()
+
+ user_obj = User()
+
+ if "add_new_user" in form.keys():
+
+ (alias,fullname,email,type,password) = (
+ MySQL.ValidateArgs(Config.MySQL["user_table"],
+ {"alias": form.getvalue("alias"),
+ "fullname": form.getvalue("fullname"),
+ "email": form.getvalue("email"),
+ "type": form.getvalue("type"),
+ "passwd": form.getvalue("password1")}))
+
+ user_obj.Create(alias, fullname, email, type, password)
+
+ message = "User Successfully Added"
+ form_inputs.append("show_add_new_user")
+
+ elif "delete_users" in form.keys():
+
+ for uid in form.getlist("delete"):
+ if user_obj.SetID(uid):
+ user_obj.Remove()
+
+ message = "Users Successfully Deleted"
+ form_inputs.append("show_all_users")
+
+ elif "modify_user" in form.keys():
+
+ password1 = form.getvalue("password1")
+ password2 = form.getvalue("password2")
+ if password1 != password2:
+ # An error should be displayed here.
+ pass
+
+ user_obj.SetID(form.getvalue("uid"))
+ user_obj.Modify(form.getvalue("alias"), form.getvalue("fullname"),
+ form.getvalue("email"), form.getvalue("type"),
+ form.getvalue("password1"))
+
+ message = "User's Personal Information Updated"
+ form_inputs.append("show_all_users")
+
+
+ if "show_all_users" in form_inputs:
+ """ Grab a list of all users """
+
+ row = "even"
+ for record in user_obj.List():
+ record.update({"row": row})
+ aliases.append(record)
+ if row == "even":
+ row = "odd"
+ else:
+ row = "even"
+
+ if len(aliases) == 0:
+ warn_message = "No Users Found"
+
+ elif "show_add_new_user" in form_inputs:
+
+ add_user = 1
+ modify_user = 1
+
+ elif "show_modify_user" in form_inputs:
+
+ modify_user = form.getvalue("show_modify_user")
+ user_obj.SetID(modify_user)
+ user_info = user_obj.GetDetails()
+ alias = user_info['user_alias']
+ fullname = user_info['user_fullname']
+ email = user_info['user_email']
+ rank = user_info['user_rank']
+ type = user_info['user_type']
+
+
+ AdminUserControlsTemplate = TemplateHandler.New()
+ AdminUserControlsTemplate.Compile(Config.Template["admin_user_controls"],
+ {"GLSR_URL": Config.URL,
+ "TOTAL_USERS": len(aliases),
+ "ADD_USER_FORM": add_user,
+ "MODIFY_USER": modify_user,
+ "ALIAS": alias,
+ "FULLNAME": fullname,
+ "EMAIL": email,
+ "RANK": rank,
+ "TYPE": type,
+ "MESSAGE": message,
+ "WARN_MESSAGE": warn_message},
+ {"USER_LOOP": aliases})
+ AdminUserControlsTemplate.Print()
+
+ AdminUserTemplate = TemplateHandler.New()
+ AdminUserTemplate.Compile(Config.Template["admin_user"],
+ {"GLSR_URL": Config.URL})
+ AdminUserTemplate.Print()
+
diff --git a/src/glsr/src/SiteModules/Admin/__init__.py b/src/glsr/src/SiteModules/Admin/__init__.py
new file mode 100644
index 0000000000..bdb72b52f9
--- /dev/null
+++ b/src/glsr/src/SiteModules/Admin/__init__.py
@@ -0,0 +1 @@
+__all__ = ["Page_Main", "Page_News", "Page_User", "Page_Script"]
diff --git a/src/glsr/src/SiteModules/Global/Page_Login.py b/src/glsr/src/SiteModules/Global/Page_Login.py
new file mode 100644
index 0000000000..ea91343354
--- /dev/null
+++ b/src/glsr/src/SiteModules/Global/Page_Login.py
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+#
+# Copyright 2004 Ian Leitch
+# Copyright 2004 Scott Hadfield
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Page_Login.py,v 1.1.1.1 2004/06/04 06:38:37 port001 Exp $
+#
+
+import os
+
+import Session as SessionHandler
+import Template as TemplateHandler
+from User import User
+
+MetaData = {"page" : ("login",), "params" : "username, password"}
+
+def Login_User(username, password):
+
+ user_obj = User()
+ user_obj.SetID(user_obj.GetUid(username))
+
+ if not user_obj.ValidateAlias(username, password):
+ return False
+
+ # Update IP address
+ user_obj.UpdateIP(os.environ['REMOTE_ADDR'])
+
+ # Setup Session Variables
+ sess = SessionHandler.New()
+ sessid = sess.GenerateSessionID()
+ sess.SetCookie(user_obj.id, sessid)
+
+ # Update session table in the db
+ sess.CreateSession(user_obj.id, sessid)
+
+ return True
diff --git a/src/glsr/src/SiteModules/Global/__init__.py b/src/glsr/src/SiteModules/Global/__init__.py
new file mode 100644
index 0000000000..b3f9d85523
--- /dev/null
+++ b/src/glsr/src/SiteModules/Global/__init__.py
@@ -0,0 +1 @@
+__all__ = ["Page_Login"]
diff --git a/src/glsr/src/SiteModules/__init__.py b/src/glsr/src/SiteModules/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/glsr/src/SiteModules/__init__.py
diff --git a/src/glsr/src/htdocs/admin/cookie.py b/src/glsr/src/htdocs/admin/cookie.py
new file mode 100644
index 0000000000..22f561e0e8
--- /dev/null
+++ b/src/glsr/src/htdocs/admin/cookie.py
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+
+import cgi
+import os
+import sys
+
+sys.path.insert(0, "/usr/lib/glsr/pym")
+
+import Auth
+import Session as SessionHandler
+
+ThisSession = SessionHandler.New()
+ThisSession.SetCookie(1, "0o36O6NFntO1GM1QIlJ6UGWB934XU1")
+
+print "Content-Type: text/html\n\n"
+
+print "<b>Sent Cookie Data:</b>\n<br>"
+ThisSession.SetCookie(1, "0o36O6NFntO1GM1QIlJ6UGWB934XU1")
+
+print "<br><br><b>Returned Cookie Data:</b>\n<br>"
+
+try:
+ parp = os.environ["HTTP_COOKIE"]
+except KeyError:
+ print "No cookie data returned!"
+else:
+ print parp
diff --git a/src/glsr/src/htdocs/admin/cookieremove.py b/src/glsr/src/htdocs/admin/cookieremove.py
new file mode 100644
index 0000000000..38a856abb7
--- /dev/null
+++ b/src/glsr/src/htdocs/admin/cookieremove.py
@@ -0,0 +1,24 @@
+#!/usr/bin/python
+
+import cgi
+import os
+import sys
+
+sys.path.insert(0, "/usr/lib/glsr/pym")
+
+import Auth
+import Session as SessionHandler
+ThisSession = SessionHandler.New()
+ThisSession.RemoveCookie()
+
+print "Content-Type: text/html\n\n"
+
+
+print "<br><br><b>Returned Cookie Data:</b>\n<br>"
+
+try:
+ parp = os.environ["HTTP_COOKIE"]
+except KeyError:
+ print "Cookie removed!"
+else:
+ print parp
diff --git a/src/glsr/src/htdocs/admin/index.py b/src/glsr/src/htdocs/admin/index.py
new file mode 100644
index 0000000000..3fd4a43d36
--- /dev/null
+++ b/src/glsr/src/htdocs/admin/index.py
@@ -0,0 +1,114 @@
+#!/usr/bin/python
+#
+# Copyright 2004 Ian Leitch
+# Copyright 2004 Scott Hadfield
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: index.py,v 1.1.1.1 2004/06/04 06:38:39 port001 Exp $
+#
+
+import os
+import sys
+import cgi
+
+sys.path.insert(0, "/usr/local/share/glsr/pym")
+sys.path.insert(0, "/usr/local/share/glsr/")
+sys.path.insert(0, "/var/www/buffmuthers.com/htdocs/projects/glsr/pym")
+sys.path.insert(0, "/var/www/buffmuthers.com/htdocs/projects/glsr/")
+
+import Config
+import Function
+import Session as SessionHandler
+import Template as TemplateHandler
+from User import User
+from Validation import CheckPageRequest
+
+import SiteModules
+from SiteModules.Global import *
+from SiteModules.Admin import *
+
+def main():
+
+ t_start = Function.start_timer()
+
+ form = cgi.FieldStorage()
+ page = form.getvalue("page")
+
+ ThisSession = SessionHandler.New()
+ user_obj = User()
+
+ uid = 0
+ sess = 0
+ alias = ""
+
+ if os.environ.has_key("HTTP_COOKIE"):
+
+ if ThisSession.ValidateCookie(os.environ["HTTP_COOKIE"]):
+ (uid, sess) = ThisSession.LoadCookieData(os.environ["HTTP_COOKIE"])
+
+ if not user_obj.SetID(uid):
+ uid = 0
+ else:
+ user_obj.UpdateIP(os.environ['REMOTE_ADDR'])
+ ThisSession.UpdateTS(uid, sess)
+ alias = user_obj.GetAlias()
+
+
+
+ if page == "login":
+
+ if SiteModules.Global.Page_Login.Login_User(form.getvalue("username"),
+ form.getvalue("password")):
+ alias = form.getvalue("username")
+ uid = user_obj.GetUid(alias)
+
+ page = "main"
+
+ elif page == "logout":
+ if ThisSession.ValidateSession(uid, sess):
+ ThisSession.RemoveCookie(sess)
+ uid = 0
+ alias = ""
+ page = "main"
+
+ print "Content-type:text/html\n\n"
+
+ AdminHeaderTemplate = TemplateHandler.New()
+ AdminHeaderTemplate.Compile(Config.Template["admin_header"],
+ {"GLSR_URL": Config.URL,
+ "USER_ALIAS": alias,
+ "USER_TYPE": user_obj.GetType()})
+ AdminHeaderTemplate.Print()
+
+ # Display the specified page
+ found = False
+ for Module in SiteModules.Admin.__all__:
+
+ MetaData = eval(Module + ".MetaData")
+ for p in MetaData["page"]:
+
+ if page == p:
+ exec "%s.Display(%s)" % (Module, MetaData["params"])
+ found = True
+
+ if CheckPageRequest(page) == "Invalid":
+ print "Invalid action!"
+ elif not found:
+ print "No such page."
+ #Page_404():
+
+ FooterTemplate = TemplateHandler.New()
+ FooterTemplate.Compile(Config.Template["footer"],
+ {"GLSR_VERSION": Config.Version,
+ "GLSR_URL": Config.URL,
+ "CONTACT": Config.Contact})
+ FooterTemplate.Print()
+
+ Function.logwrite("Request for page '%s' completed in %.5f(s)" %
+ (page, Function.eval_timer(t_start,
+ Function.stop_timer())),
+ "All")
+
+if __name__ == "__main__":
+ main()
diff --git a/src/glsr/src/htdocs/css/glsr.css b/src/glsr/src/htdocs/css/glsr.css
new file mode 100644
index 0000000000..b0227bebb8
--- /dev/null
+++ b/src/glsr/src/htdocs/css/glsr.css
@@ -0,0 +1,236 @@
+body {
+ margin-left: 0px;
+ margin-top: 0px;
+ margin-right: 0px;
+ margin-bottom: 0px;
+}
+
+input.text {
+ background-color: #eeecff;
+ border: 1px solid black;
+ text-align: left;
+ width: 175px;
+ padding-left: 5px;
+}
+
+input.text-long {
+ background-color: #eeecff;
+ border: 1px solid black;
+ text-align: left;
+ width: 300px;
+ padding-left: 5px;
+}
+
+input.button {
+ background-color: #a0a0d0;
+ border: 1px solid black;
+}
+
+textarea.text {
+ background-color: #eeecff;
+ border: 1px solid black;
+ text-align: left;
+ padding-left: 5px;
+}
+
+select.dropdown {
+ background-color: #eeecff;
+ text-align: left;
+ width: 175px;
+}
+
+td.standard_cell {
+ background-color: #dddaec;
+ padding-left: 12px;
+ height: 40px;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+}
+
+td.standard_row_even {
+ background-color: #dddaec;
+ padding-left: 12px;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ border-bottom: 1px solid black;
+}
+td.standard_row_odd {
+ background-color: #EFEDF7;
+ padding-left: 12px;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ border-bottom: 1px solid black;
+}
+
+
+td.header {
+ background-color: #46357C;
+ padding-left: 12px;
+ height: 50px;
+ color: #FFFFFF;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 13px;
+ font-weight: bold;
+}
+
+td.sub_header {
+ background-color: #7A5ADA;
+ padding-left: 12px;
+ border-top: 1px solid black;
+ border-bottom: 1px solid black;
+ height: 20px;
+ color: #FFFFFF;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 13px;
+ font-weight: bold;
+}
+
+table.standard_table {
+ padding: 0px;
+ border-spacing: 0px;
+ border: 1px solid black;
+}
+
+font.instructional {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ color: #46357C;
+ line-height: 15px;
+ text-align: justify;
+ font-weight: bold;
+}
+
+font.message {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ color: #007d00;
+ line-height: 15px;
+ text-align: justify;
+ font-weight: bold;
+}
+
+font.warn_message {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ color: #BB0C03;
+ line-height: 15px;
+ text-align: justify;
+ font-weight: bold;
+}
+
+a.menulink:link, a.menulink:visited {
+ color: #a0a0d0;
+ text-decoration: none;
+}
+a.menulink:hover, a.menulink:active {
+ color: #00ff00;
+ text-decoration: underline;
+}
+
+.menu {
+ font-size: 0.75em;
+ font-weight: bold;
+ font-family: Verdana, Arial, Helvetica;
+ color: #c0c0f0;
+ padding-left: 1.0em;
+ padding-right: 1.0em;
+ padding-top: 0.5em;
+ padding-bottom: 0.75em;
+}
+
+.login_form_element {
+ background-color: #dddaec;
+ border: 1px solid black;
+ text-align: left;
+ padding-left: 5px;
+}
+
+
+
+.style1 {
+ color: #a0a0d0;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-weight: bold;
+ font-size: 12px;
+}
+.section_table {
+ border: 1px solid black;
+}
+.section_header_text {
+ color: #FFFFFF;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-weight: bold;
+ font-size: 13px;
+}
+
+.style3 {
+ color: #a0a0d0;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-weight: bold;
+ font-size: 10px
+}
+
+.form_element {
+ background-color: #a0a0d0;
+ border: 1px solid black;
+}
+.inactive_text {
+ color: #AAAAAA;
+ font-size: 12px
+}
+.stats_row_1 {
+ background-color: #dddaec;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ border-top: 1px solid black;
+ border-bottom: 1px solid black
+}
+.stats_row_2 {
+ background-color: #EFEDF7;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ border-bottom: 1px solid black
+}
+.stats_row_3 {
+ background-color: #dddaec;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ border-bottom: 1px solid black
+}
+.stats_row_4 {
+ background-color: #EFEDF7;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 12px
+}
+.stats_row_4_1 {
+ background-color: #EFEDF7;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ color: #AAAAAA;
+ font-size: 12px
+}
+
+.user_row_even {
+ background-color: #dddaec;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ border-top: 1px solid black;
+ border-bottom: 1px solid black;
+}
+.user_row_odd {
+ background-color: #EFEDF7;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ border-bottom: 1px solid black;
+}
+
+.footer {
+ color: #a0a0d0;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-weight: bold;
+ font-size: 10px
+}
+.footer_copyright {
+ color: #AAAAAA;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 10px
+}
diff --git a/src/glsr/src/htdocs/images/4star.png b/src/glsr/src/htdocs/images/4star.png
new file mode 100644
index 0000000000..51af152945
--- /dev/null
+++ b/src/glsr/src/htdocs/images/4star.png
Binary files differ
diff --git a/src/glsr/src/htdocs/images/PythonPoweredSmall.gif b/src/glsr/src/htdocs/images/PythonPoweredSmall.gif
new file mode 100644
index 0000000000..268980706a
--- /dev/null
+++ b/src/glsr/src/htdocs/images/PythonPoweredSmall.gif
Binary files differ
diff --git a/src/glsr/src/htdocs/images/dialog-info.png b/src/glsr/src/htdocs/images/dialog-info.png
new file mode 100644
index 0000000000..502f53d4bd
--- /dev/null
+++ b/src/glsr/src/htdocs/images/dialog-info.png
Binary files differ
diff --git a/src/glsr/src/htdocs/images/favicon.ico b/src/glsr/src/htdocs/images/favicon.ico
new file mode 100644
index 0000000000..e26ba8856c
--- /dev/null
+++ b/src/glsr/src/htdocs/images/favicon.ico
Binary files differ
diff --git a/src/glsr/src/htdocs/images/glogo.png b/src/glsr/src/htdocs/images/glogo.png
new file mode 100644
index 0000000000..5dda23de73
--- /dev/null
+++ b/src/glsr/src/htdocs/images/glogo.png
Binary files differ
diff --git a/src/glsr/src/htdocs/images/header-bk.png b/src/glsr/src/htdocs/images/header-bk.png
new file mode 100644
index 0000000000..ec848ff6ad
--- /dev/null
+++ b/src/glsr/src/htdocs/images/header-bk.png
Binary files differ
diff --git a/src/glsr/src/htdocs/images/news.png b/src/glsr/src/htdocs/images/news.png
new file mode 100644
index 0000000000..dbdb2fc457
--- /dev/null
+++ b/src/glsr/src/htdocs/images/news.png
Binary files differ
diff --git a/src/glsr/src/htdocs/images/people.png b/src/glsr/src/htdocs/images/people.png
new file mode 100644
index 0000000000..95699ebd9f
--- /dev/null
+++ b/src/glsr/src/htdocs/images/people.png
Binary files differ
diff --git a/src/glsr/src/htdocs/images/splogo-beta.png b/src/glsr/src/htdocs/images/splogo-beta.png
new file mode 100644
index 0000000000..c8c3f2718f
--- /dev/null
+++ b/src/glsr/src/htdocs/images/splogo-beta.png
Binary files differ
diff --git a/src/glsr/src/htdocs/images/splogo.png b/src/glsr/src/htdocs/images/splogo.png
new file mode 100644
index 0000000000..6049662092
--- /dev/null
+++ b/src/glsr/src/htdocs/images/splogo.png
Binary files differ
diff --git a/src/glsr/src/htdocs/images/star.png b/src/glsr/src/htdocs/images/star.png
new file mode 100644
index 0000000000..d66bfd7b02
--- /dev/null
+++ b/src/glsr/src/htdocs/images/star.png
Binary files differ
diff --git a/src/glsr/src/htdocs/images/stock_notes.png b/src/glsr/src/htdocs/images/stock_notes.png
new file mode 100644
index 0000000000..0221d59e5d
--- /dev/null
+++ b/src/glsr/src/htdocs/images/stock_notes.png
Binary files differ
diff --git a/src/glsr/src/pym/Admin.py b/src/glsr/src/pym/Admin.py
new file mode 100644
index 0000000000..e93f96d78d
--- /dev/null
+++ b/src/glsr/src/pym/Admin.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python2
+#
+# Copyright 2004 Ian Leitch
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Header: /var/cvsroot/gentoo/src/glsr/src/pym/Admin.py,v 1.1.1.1 2004/06/04 06:38:34 port001 Exp $
+#
+
+#import MySQLdb
+import Function
+import Config
+from time import strftime, gmtime
+
+__modulename__ = "Admin"
+__productname__ = "glsr"
+
+
+
+def GetUser
diff --git a/src/glsr/src/pym/Auth.py b/src/glsr/src/pym/Auth.py
new file mode 100644
index 0000000000..3e6f75996b
--- /dev/null
+++ b/src/glsr/src/pym/Auth.py
@@ -0,0 +1,21 @@
+# Copyright 2004 Ian Leitch
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Auth.py,v 1.1.1.1 2004/06/04 06:38:34 port001 Exp $
+#
+
+__modulename__ = "Auth"
+
+def GenMd5(passwd):
+ """Generate hex md5 digest for given password"""
+
+ import md5
+
+ md5obj = md5.new()
+ md5obj.update(passwd)
+
+ return md5obj.hexdigest()
+
+
+
diff --git a/src/glsr/src/pym/Category.py b/src/glsr/src/pym/Category.py
new file mode 100644
index 0000000000..315dca4f5a
--- /dev/null
+++ b/src/glsr/src/pym/Category.py
@@ -0,0 +1,67 @@
+# Copyright 2004 Ian Leitch
+# Copyright 2004 Scott Hadfield
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Category.py,v 1.1.1.1 2004/06/04 06:38:35 port001 Exp $
+#
+
+__modulename__ = "Category"
+
+import MySQL
+import Config
+from GLSRBackend import GLSRBackend as Parent
+
+class Category(Parent):
+
+ tablename = Config.MySQL["category_table"]
+
+ def Create(self, name, descr, parent_id):
+
+ if parent_id > 0 and not self.Exists("parent_id", parent_id):
+ # We should throw an error here
+ return False
+
+ if not parent_id > 0:
+ parent_id = 0
+
+ return Parent.Create(self, {"name": name, "descr": descr,
+ "parent_id": parent_id}, ["name"])
+
+
+ def Remove(self):
+
+ # check for child cats and scripts that are under the cat and
+ # scripts under child cats of the parent.
+ # Note: I think that deleting scripts too might be a bit risky.
+
+ for child_id in self.Children():
+ child = Category(child_id)
+ child.Remove()
+
+ return Parent.Remove(self)
+
+
+ def Modify(self, name, descr, parent_id):
+
+ return Parent.Modify(self, ["name", "descr", "parent_id"],
+ {"name": name, "descr": descr,
+ "parent_id": parent_id})
+
+
+ def List(self, parent_id = -1):
+
+ if parent_id == -1:
+ return Parent.List(self)
+ else:
+ return Parent.List(self, {"parent_id": parent_id})
+
+
+ def Children(self):
+ " Return the id's for all of this categories children "
+
+ return (MySQL.Query("SELECT %s_id FROM %s%s " %
+ (self.tablename, Config.MySQL["prefix"],
+ self.tablename) +
+ "WHERE %s_parent_id = " % self.tablename + "%s",
+ self.id, fetch="all").values())
diff --git a/src/glsr/src/pym/Comment.py b/src/glsr/src/pym/Comment.py
new file mode 100644
index 0000000000..e028b3faa3
--- /dev/null
+++ b/src/glsr/src/pym/Comment.py
@@ -0,0 +1,37 @@
+# Copyright 2004 Ian Leitch
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Comment.py,v 1.1.1.1 2004/06/04 06:38:36 port001 Exp $
+#
+
+import User
+import MySQL
+import Config
+from time import strftime, gmtime
+
+__modulename__ = "Comment"
+
+def Add(submitter, subject, body, ofscript, ofversion):
+ """Add comment for script"""
+
+ MySQL.Query("INSERT INTO %s " % Config.MySQL["comment_table"] +
+ """(submitter, date, subject, body, ofscript, ofversion)
+ VALUES
+ (%s, %s, %s, %s, %s, %s)""", \
+ (submitter, strftime("%Y-%m-%d %H:%M:%S", gmtime()), subject, body, ofscript, ofversion), fetch="none")
+
+def Remove(comid):
+ """Remove comment by comid"""
+
+ MySQL.Query("DELETE FROM %s " % Config.MySQL["comment_table"] + "WHERE comid = %s", (comid), fetch="none")
+
+def Modify(comid, details):
+ """Modify comment"""
+
+ if "subject" in details:
+ MySQL.Query("UPDATE %s " % Config.MySQL["comment_table"] + "SET subject = %s WHERE comid = %s", (details["subject"], comid), fetch="none")
+ if "body" in details:
+ MySQL.Query("UPDATE %s " % Config.MySQL["comment_table"] + "SET body = %s WHERE comid = %s", (details["body"], comid), fetch="none")
+
+ MySQL.Query("UPDATE %s " % Config.MySQL["comment_table"] + "SET lastedited = %s WHERE comid = %s", (strftime("%Y-%m-%d %H:%M:%S", gmtime()), comid), fetch="none")
diff --git a/src/glsr/src/pym/Config.py b/src/glsr/src/pym/Config.py
new file mode 100644
index 0000000000..0741cdf739
--- /dev/null
+++ b/src/glsr/src/pym/Config.py
@@ -0,0 +1,64 @@
+# Copyright 2004 Ian Leitch
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Config.py,v 1.1.1.1 2004/06/04 06:38:36 port001 Exp $
+#
+
+__modulename__ = "Config"
+
+Version = "0.1"
+
+MySQL = {
+ "host": "localhost",
+ "user": "glsrusr",
+ "passwd": "glsrusr",
+ "db": "glsr",
+ "prefix": "glsr_",
+ "user_table": "user",
+ "category_table": "category",
+ "language_table": "language",
+ "comment_table": "comment",
+ "script_table": "script",
+ "subscript_table": "subscript",
+ "session_table": "session",
+ "news_table": "news"
+ }
+
+t_prefix = "/usr/local/share/glsr/templates/"
+
+Template = {
+ "test": t_prefix + "test.tpl",
+ "err": t_prefix + "err.tpl",
+ "msg": t_prefix + "msg.tpl",
+ "header": t_prefix + "Header.tpl",
+ "footer": t_prefix + "Footer.tpl",
+ "admin_header": t_prefix + "admin/Header.tpl",
+ "admin_main": t_prefix + "admin/Main.tpl",
+ "admin_user": t_prefix + "admin/User.tpl",
+ "admin_user_controls": t_prefix + "admin/User_Controls.tpl",
+ "admin_news": t_prefix + "admin/News.tpl",
+ "admin_script": t_prefix + "admin/Script_Controls.tpl",
+ "admin_script_search": t_prefix + "admin/Script_Search.tpl",
+ "admin_script_results": t_prefix + "admin/Script_Results.tpl",
+ "admin_categories": t_prefix + "admin/Categories.tpl",
+ "admin_languages": t_prefix + "admin/Languages.tpl"
+ }
+
+URL = "http://localhost/glsr/"
+Contact = "port001@gentoo.org"
+
+Memcache = "No" # Not supported yet
+
+Logging = "Yes" # Yes/No
+Logtype = "All" # All/Error
+LogFile = "/var/www/localhost/htdocs/glsr/glsr.log"
+Debug = "Yes" # Yes/No
+
+CookieDomain = "glsr.gentoo.org"
+CookiePath = "/"
+CookieSecure = "No"
+
+SessionTimeOut = 259200 # Time in seconds (1 day = 86400)
+
+WhoIsOnlineOffset = 300
diff --git a/src/glsr/src/pym/Const.py b/src/glsr/src/pym/Const.py
new file mode 100644
index 0000000000..6ebe06f15c
--- /dev/null
+++ b/src/glsr/src/pym/Const.py
@@ -0,0 +1,93 @@
+# Copyright 2004 Ian Leitch
+# Copyright 2004 Scott Hadfield
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Const.py,v 1.1.1.1 2004/06/04 06:38:34 port001 Exp $
+#
+
+__modulename__ = "Const"
+
+import Config
+
+TYPE = {
+ "user": 0,
+ "developer": 1,
+ "admin": 3
+ }
+
+_DATE_LEN = 20
+_TEXT_LEN = 65536
+_UID_LEN = 5
+
+FIELD_LEN = {
+ "categories": {
+ "catid": 3,
+ "name": 50,
+ "descr": 100,
+ "parent": 3
+ },
+
+ "comments": {
+ "comid": 6,
+ "submitter": _UID_LEN,
+ "date": _DATE_LEN,
+ "subject": 30,
+ "lastedited": _DATE_LEN,
+ "body": _TEXT_LEN,
+ "ofscript": 6,
+ "ofversion": 10
+ },
+
+ "languages": {
+ "langid": 3,
+ "name": 50,
+ "descr": 100
+ },
+
+ "news": {
+ "annid": 10,
+ "author": _UID_LEN,
+ "date": _DATE_LEN,
+ "subject": 100, # <= Table must be changed
+ "body": _TEXT_LEN
+ },
+
+ "scripts": {
+ "submitter": _UID_LEN,
+ "category": 3,
+ "rank": 1,
+ "name": 30,
+ "descr": 100,
+ "language": 3
+ },
+
+ "sessions": {
+ "sessid": 30,
+ "uid": _UID_LEN,
+ "time": 10
+ },
+
+ "subscripts": {
+ "subscid": 10,
+ "parent": 7,
+ "version": 10,
+ "body": _TEXT_LEN,
+ "changelog": _TEXT_LEN,
+ "date": _DATE_LEN,
+ "approved": 1,
+ "approvedby": _UID_LEN,
+ },
+
+ Config.MySQL["user_table"]: {
+ "uid": _UID_LEN,
+ "alias":25,
+ "fullname":40,
+ "passwd":32,
+ "email":50,
+ "rank":5,
+ "type":1,
+ "joined":_DATE_LEN,
+ "lastip":15
+ }
+}
diff --git a/src/glsr/src/pym/Function.py b/src/glsr/src/pym/Function.py
new file mode 100644
index 0000000000..ecaa3f5b0f
--- /dev/null
+++ b/src/glsr/src/pym/Function.py
@@ -0,0 +1,62 @@
+# Copyright 2004 Ian Leitch
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Function.py,v 1.1.1.1 2004/06/04 06:38:37 port001 Exp $
+#
+
+import Config
+from time import time, gmtime, strftime
+
+__modulename__ = "Function"
+__productname__ = "glsr"
+
+clockwatch = 0
+
+def err(msg):
+ """Send given error message to logwrite() then display error message to
+ user"""
+
+ logwrite(msg, "Error")
+ Template.err(msg)
+
+def logwrite(msg, type):
+ """Write Given message to a log file"""
+
+ if Config.Logging == "Yes":
+ if ((Config.Logtype == "All" and (type == "All" or type == "Error")) or
+ (Config.Logtype == "Error" and type == "Error")):
+
+ fd = open(Config.LogFile, "a")
+ fd.write("%s %s: %s\n" % (strftime("%d/%b/%Y %H:%M:%S", gmtime()),
+ __productname__, msg))
+ fd.close()
+
+def start_timer():
+
+ return time()
+
+def stop_timer():
+
+ return time()
+
+def eval_timer(start, end):
+
+ return float(end - start)
+
+def traceback():
+
+ import traceback
+
+ # Incase headers haven't been sent yet.
+ print "Content-type:text/html\n\n"
+
+ print "<b>Traceback:</b><br><br>"
+ print ("<table align=\"center\" width=\"80%\"><tr><td align=\"left\">" +
+ "<font size=\"3\">")
+ tb = traceback.format_stack(None)
+ for line in tb:
+ print line.replace("\n", "<br>")
+ print "</td></tr></table>"
+
+
diff --git a/src/glsr/src/pym/GLSRBackend.py b/src/glsr/src/pym/GLSRBackend.py
new file mode 100644
index 0000000000..a1fd41ab80
--- /dev/null
+++ b/src/glsr/src/pym/GLSRBackend.py
@@ -0,0 +1,120 @@
+# Copyright 2004 Ian Leitch
+# Copyright 2004 Scott Hadfield
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: GLSRBackend.py,v 1.1.1.1 2004/06/04 06:38:37 port001 Exp $
+#
+
+__modulename__ = "GLSRBackend"
+
+import string
+import operator
+
+import MySQL
+import Config
+
+class GLSRBackend:
+
+ def __init__(self, id = 0):
+
+ if id != 0:
+ self.SetID(id)
+ else:
+ self.id = 0
+
+ def Create(self, details, keys = ()):
+ """ Creates the row with 'details'. Keys contains a list of restraints.
+ So, if you can't have two identical 'name's then add 'name' to the list
+ of keys and it won't add the field. """
+
+ # Check restrictions
+ for field in keys:
+ if self.Exists(field, details[field]):
+ return True
+
+ fields = string.join(map(lambda x: "%s_%s" % (self.tablename, x),
+ details.keys()), ", ")
+ values = string.join(
+ operator.repeat(['%s'], len(details.keys())), ", ")
+
+ if fields == "" or values == "": # No fields to set?
+ return False
+
+ MySQL.Query("INSERT INTO %s%s" %
+ (Config.MySQL["prefix"], self.tablename) +
+ " (%s) VALUES (%s)", (fields, values),
+ details.values(), fetch="none")
+
+
+ def Remove(self):
+
+ if not self.id:
+ return False
+
+ MySQL.Query("DELETE FROM %s%s " %
+ (Config.MySQL["prefix"], self.tablename) +
+ "WHERE %s_id = " % self.tablename + "%s", self.id,
+ fetch="none")
+
+
+ def Modify(self, fields, details):
+ """ Modify the specified 'fields' if they were set in 'details' """
+
+ if not self.id:
+ return False
+
+ for key in fields:
+ if key in details:
+ MySQL.Query("UPDATE %s%s" %
+ (Config.MySQL["prefix"], self.tablename) +
+ " SET %s_%s = " % (self.tablename, key) +
+ "%%s WHERE %s_id = " % self.tablename +
+ "%s", (details[key], self.id), fetch="none")
+
+
+ def List(self, constraint = {}):
+ """ Return all rows from self.tablename.
+ constraint is a dictionary or {field: value} pairs that requires
+ a field == value in order to return that row """
+
+ where_str = string.join(map(lambda x: "%s_%s = %%s" %
+ (self.tablename, x),
+ constraint.keys()), " AND ")
+
+ if where_str != "":
+ where_str = "WHERE %s" % where_str
+
+ return MySQL.Query("SELECT * FROM %s%s %s" %
+ (Config.MySQL["prefix"], self.tablename,
+ where_str), constraint.values(), fetch="all")
+
+
+ def GetDetails(self):
+
+ if not self.id:
+ # An error should probably be thrown here.
+ return None
+
+ return MySQL.Query("SELECT * FROM %s%s" %
+ (Config.MySQL["prefix"], self.tablename) +
+ " WHERE %s_id = " % self.tablename + "%s", self.id,
+ fetch="one")
+
+
+ def Exists(self, field, value):
+
+ result = MySQL.Query("SELECT %s_%s FROM %s%s WHERE %s_%s = " %
+ (self.tablename, field, Config.MySQL["prefix"],
+ self.tablename, self.tablename, field) +
+ "%s", value, fetch = "one")
+
+ return (result != None)
+
+ def SetID(self, id):
+
+ if self.Exists("id", id):
+ self.id = id
+ return True
+ else:
+ return False
diff --git a/src/glsr/src/pym/Language.py b/src/glsr/src/pym/Language.py
new file mode 100644
index 0000000000..3225416702
--- /dev/null
+++ b/src/glsr/src/pym/Language.py
@@ -0,0 +1,29 @@
+# Copyright 2004 Ian Leitch
+# Copyright 2004 Scott Hadfield
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Language.py,v 1.1.1.1 2004/06/04 06:38:36 port001 Exp $
+#
+
+__modulename__ = "Language"
+
+import MySQL
+import Config
+from GLSRBackend import GLSRBackend as Parent
+
+class Language(Parent):
+
+ tablename = Config.MySQL["language_table"]
+
+ def Create(self, name, description):
+
+ return Parent.Create(self, {"name": name, "descr": description},
+ ["name"])
+
+
+ def Modify(self, name, descr):
+
+ return Parent.Modify(self, ["name", "descr"],
+ {"name": name, "descr": descr})
+
diff --git a/src/glsr/src/pym/MySQL.py b/src/glsr/src/pym/MySQL.py
new file mode 100644
index 0000000000..ffbd81e2f6
--- /dev/null
+++ b/src/glsr/src/pym/MySQL.py
@@ -0,0 +1,110 @@
+# Copyright 2004 Ian Leitch
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: MySQL.py,v 1.1.1.1 2004/06/04 06:38:34 port001 Exp $
+#
+
+import sys
+from time import strftime, gmtime
+from _mysql_exceptions import MySQLError, OperationalError
+
+import Config
+
+if Config.Memcache == "Yes":
+ import memcache
+
+import Const
+import MySQLdb
+import Function
+import Template as TemplateHandler
+
+__modulename__ = "MySQL"
+
+def Connect():
+ try:
+ db = MySQLdb.connect(host=Config.MySQL["host"],
+ user=Config.MySQL["user"],
+ passwd=Config.MySQL["passwd"],
+ db=Config.MySQL["db"])
+ except OperationalError, errmsg:
+ Function.logwrite("ERROR: %s: %s" % (__modulename__, errmsg), "Error")
+ if Config.Debug == "Yes":
+ print ("<font color=FF0000><b>Debug Mode</b></font><br><br><b>" +
+ "MySQL Error:</b><br><br>%s<br><br>" % errmsg)
+ Function.traceback()
+ else:
+ print "Unable to connect to database, fuck!"
+
+ # Print the footer, makes things looks nice and closes HTML tags
+ # opened by the header. Perfectionist?
+ FooterTemplate = TemplateHandler.New()
+ FooterTemplate.Compile(Config.Template["footer"],
+ {"GLSR_VERSION": Config.Version,
+ "CONTACT": Config.Contact})
+ FooterTemplate.Print()
+
+ sys.exit(1) # Hmm, best way?
+
+ return db.cursor(MySQLdb.cursors.DictCursor), db
+
+def ValidateArgs(table, args):
+ """ A last ditch effort to make sure that no database inputs are too
+ long. """
+ retval = []
+ for key,val in args.iteritems():
+ retval.append(val[:Const.FIELD_LEN[table][key]])
+ return retval
+
+def Query(query, args=None, fetch="all"):
+ """ Returns a list of dictionaries of {column: value} pairs.
+ Each dictionary in the list represents one record for the query.
+ e.g ({uid: 1043, name: Ian}, {uid: 3456, Scott})
+ """
+
+ return _Fetch(_InitQuery(query, args), query, args, fetch)
+
+
+def _InitQuery(query, args):
+ t_start = Function.start_timer()
+ cursor, db = Connect()
+
+ try:
+ cursor.execute(query, args)
+ except MySQLError, errmsg:
+ Function.logwrite("ERROR: %s: %s" % (__modulename__, errmsg), "Error")
+
+ # Incase headers haven't been sent yet.
+ print "Content-type:text/html\n\n"
+
+ if Config.Debug == "Yes":
+ print "<font color=FF0000><b>Debug Mode</b></font><br><br><b>MySQL Error:</b><br /><br />%s<br />Query = %s<br />Args = %s<br /><br />" % (errmsg, query, args)
+ Function.traceback()
+ else:
+ time = strftime("%d/%b/%Y %H:%M:%S", gmtime())
+ print "<b>Ooops!</b><br><br>It looks like you've encountered an error!<br><br>Please contact <b>%s</b> and quote the time '<b>%s</b>'" % (Config.Contact, time)
+
+ # Print the footer, makes things looks nice and closes HTML tags opened by the header. Perfectionist?
+ FooterTemplate = TemplateHandler.New()
+ FooterTemplate.Compile(Config.Template["footer"],
+ {"GLSR_VERSION": Config.Version,
+ "CONTACT": Config.Contact})
+ FooterTemplate.Print()
+
+ sys.exit(1)
+
+ db.commit()
+ return cursor, t_start
+
+def _Fetch((cursor, t_start), query, args, fetch):
+ if fetch == "one":
+ result = cursor.fetchone()
+ Function.logwrite("""Query: %s Args: %s Timing: %.5f(s)""" % (query, args, Function.eval_timer(t_start, Function.stop_timer())), "All")
+ elif fetch == "none":
+ Function.logwrite("""Query: %s Args: %s Timing: %.5f(s)""" % (query, args, Function.eval_timer(t_start, Function.stop_timer())), "All")
+ return
+ else:
+ result = cursor.fetchall()
+ Function.logwrite("""Query: %s Args: %s Timing: %.5f(s)""" % (query, args, Function.eval_timer(t_start, Function.stop_timer())), "All")
+
+ return result
diff --git a/src/glsr/src/pym/News.py b/src/glsr/src/pym/News.py
new file mode 100644
index 0000000000..db8337e789
--- /dev/null
+++ b/src/glsr/src/pym/News.py
@@ -0,0 +1,42 @@
+#
+# Copyright 2004 Ian Leitch
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: News.py,v 1.1.1.1 2004/06/04 06:38:36 port001 Exp $
+#
+
+__modulename__ = "News"
+
+from time import strftime, gmtime
+
+import MySQL
+import Config
+from GLSRBackend import GLSRBackend as Parent
+
+class News(Parent):
+
+ tablename = Config.MySQL["news_table"]
+
+ def Create(self, subject, author, body):
+ """Add a new announcement to the database"""
+
+ return Parent.Create(self,
+ {"subject": subject,
+ "author_id": author,
+ "date": strftime("%Y-%m-%d %H:%M:%S", gmtime()),
+ "body": body})
+
+
+ def Modify(self, subject, author, body):
+ """ Modify announcement details """
+
+ return Parent.Modify(self, ["subject", "author_id", "body"],
+ {"subject": subject, "author_id": author,
+ "body": body})
+
+
+ def AnnidExists(self, annid):
+ """ Check for existence of given AnnID """
+
+ return Parent.Exists(self, "id", annid)
diff --git a/src/glsr/src/pym/Script.py b/src/glsr/src/pym/Script.py
new file mode 100644
index 0000000000..a11aaaf206
--- /dev/null
+++ b/src/glsr/src/pym/Script.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python2
+#
+# Copyright 2004 Ian Leitch
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Script.py,v 1.1.1.1 2004/06/04 06:38:35 port001 Exp $
+#
+
+__modulename__ = "Script"
+
+import types
+import string
+
+import MySQL
+import Config
+from GLSRBackend import GLSRBackend as Parent
+
+class Script(Parent):
+
+ tablename = Config.MySQL["script_table"]
+
+ def Create(self, submitter, category, name, descr, body):
+ """Add a new script to the database"""
+
+ return Parent.Create(self,
+ {"submitter": submitter,
+ "category": category,
+ "rank": 0,
+ "name": name,
+ "descr": description,
+ "body": body})
+
+
+ def Approve(self, uid):
+ """Mark script as approved"""
+
+ return Parent.Modify(self, ["approved", "approvedby"],
+ {"approved": 1,
+ "approvedby": uid})
+
+
+ def Search(self, Terms):
+ """
+ Search for scripts in the DB.
+ Terms should be a dictionary of (field, value) pairs. If 'value' is a
+ ListType then they will be OR'd
+ (i.e. field = value[0] OR field = value[1]...)
+
+ Searchable values include: language, category, status, name, descr,
+ submitter
+ """
+
+ import operator
+
+ qStr = self.__mk_query(["language", "category"], Terms)
+ if qStr != "":
+ qStr = "WHERE " + qStr
+
+ scripts = MySQL.Query("SELECT * FROM %s%s %s" %
+ (Config.MySQL["prefix"], self.tablename, qStr))
+
+ found = []
+ for script in scripts:
+ for key in ["name", "descr", "submitter"]:
+ if key in Terms.keys():
+ if script[key].find(Terms[key]) != -1:
+ found.append(script)
+
+
+ # Get the subscripts
+ qStr = self.__mk_query(["status"], Terms)
+ if qStr != "":
+ qStr = "AND " + qStr
+
+ loop = len(found) # Since found will be modified, this is necessary.
+ for i in range(loop):
+
+ qStr = ("SELECT %s_version, %s_date, %s_status, %s_approvedby" %
+ tuple(operator.repeat(Config.MySQL["subscript_table"], 4))+
+ " FROM %s%s WHERE status != 'draft' AND parent = %s " %
+ (Config.MySQL["prefix"], Config.MySQL["subscript_table"],
+ found[i]["scid"]) + qStr)
+
+ if "most_recent" in Terms.keys():
+
+ subscript = MySQL.Query(qStr + " ORDER BY version",
+ fetch = "one")
+ found[i].update(subscript)
+
+ else:
+
+ subscripts = MySQL.Query(qStr, fetch = "all")
+
+ for subscript in subscripts[1:]:
+ found.append(found[i])
+ found[len(found)].update(subscript)
+
+ found[i].update(subscripts[0])
+
+ return found
+
+
+ def __mk_query_str(self, field, Terms):
+
+ qStr = field + " IN "
+ if type(Terms[field]) == types.ListType:
+
+ if not len(Terms[field]):
+ return ""
+
+ newlist = map(lambda x: "'%s'" % x, Terms[field])
+ value = string.join(newlist, "," % field)
+
+ else:
+ value = Terms[field]
+
+ return "%s (%s)" % (qStr, value)
+
+
+ def __mk_query(self, fields, Terms):
+
+ qStr = ""
+ for (key,value) in Terms.items():
+
+ if key in fields:
+
+ if qStr != "":
+ qStr = qStr + " AND "
+
+ qStr = qStr + self.__mk_query_str(key, Terms)
+
+ return qStr
+
+
diff --git a/src/glsr/src/pym/Session.py b/src/glsr/src/pym/Session.py
new file mode 100644
index 0000000000..c8497ed2ad
--- /dev/null
+++ b/src/glsr/src/pym/Session.py
@@ -0,0 +1,200 @@
+# Copyright 2004 Ian Leitch
+# Copyright 2004 Scott Hadfield
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Session.py,v 1.1.1.1 2004/06/04 06:38:36 port001 Exp $
+#
+
+__modulename__ = "Session"
+
+import MySQL
+import Config
+
+
+class New:
+
+ full_tablename = Config.MySQL["prefix"] + Config.MySQL["session_table"]
+ tablename = Config.MySQL["session_table"]
+
+ def GenerateSessionID(self):
+
+ # This could be done a lot faster, no need to fetch the whole table.
+
+ from random import Random, random
+
+ sessid = ""
+ i = 0
+ chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+
+ result = MySQL.Query("SELECT %s_id FROM %s " %
+ (self.tablename, self.full_tablename),
+ fetch="all")
+ ran = Random()
+
+ while 1:
+ num = ran.randint(0, 10000000000000000000000000)
+
+ while i < 30:
+ sessid = sessid + ran.choice(chars + str(num))
+ i += 1
+
+ if sessid not in result:
+ break
+
+ return sessid
+
+ def SessionIDExists(self, uid, sessid):
+
+ result = MySQL.Query("SELECT %s_id FROM %s WHERE %s_id = " %
+ (self.tablename, self.full_tablename,
+ self.tablename) +
+ "%s", sessid.value, fetch="one")
+
+ return result != None
+
+ def SetCookie(self, uid, sessid):
+
+ import Cookie
+ import Config
+
+ bourbon = Cookie.SimpleCookie()
+
+ bourbon["glsr_sessid"] = sessid
+ #bourbon["glsr_sessid"]["domain"] = Config.CookieDomain
+ #bourbon["glsr_sessid"]["path"] = Config.CookiePath
+ if Config.CookieSecure == "Yes":
+ bourbon["glsr_sessid"]["secure"] = 1
+
+ bourbon["glsr_uid"] = uid
+ #bourbon["glsr_uid"]["domain"] = Config.CookieDomain
+ #bourbon["glsr_uid"]["path"] = Config.CookiePath
+ if Config.CookieSecure == "Yes":
+ bourbon["glsr_uid"]["secure"] = 1
+
+ print bourbon
+
+ def RemoveCookie(self, sessid):
+
+ import Cookie
+
+ chocchip = Cookie.SimpleCookie()
+
+ self.DeleteSession(sessid)
+
+ # Who the fuck designed cookies? This is fucking stupid!
+ chocchip["glsr_sessid"] = None
+ chocchip["glsr_sessid"]["max-age"] = 0
+ chocchip["glsr_uid"] = None
+ chocchip["glsr_uid"]["max-age"] = 0
+
+ print chocchip
+
+ def DeleteSession(self, sessid):
+
+ MySQL.Query("DELETE FROM %s WHERE %s_id = " %
+ (self.full_tablename, self.tablename) + "%s", sessid,
+ fetch = "none")
+
+ return True
+
+
+ def ValidateCookie(self, HTTP_COOKIE):
+ """ Checks that the COOKIE matches valid glsr cookie data """
+
+ import Cookie, sys
+
+ fudge = Cookie.SimpleCookie(HTTP_COOKIE)
+
+ if (not fudge.has_key("glsr_uid") or not
+ fudge.has_key("glsr_sessid")):
+ return False
+
+ if (not self.ValidateCookieData(fudge["glsr_uid"].value,
+ fudge["glsr_sessid"].value)):
+ return False
+
+ if (not self.ValidateSession(fudge["glsr_uid"].value,
+ fudge["glsr_sessid"].value)):
+ return False
+
+ # Check the database for a matchine session
+ if not self.SessionIDExists(fudge["glsr_uid"], fudge["glsr_sessid"]):
+ return False
+
+ return True
+
+
+ def ValidateCookieData(self, uid, sessid):
+
+ import re
+
+ sessid_regex = "^[\da-zA-Z]{30}$"
+ uid_regex = "^[\d]{1,5}$"
+
+ p_sessid = re.compile(sessid_regex)
+ p_uid = re.compile(uid_regex)
+
+ o_sessid = p_sessid.match(sessid)
+ if not o_sessid:
+ return "Invalid"
+ o_uid = p_uid.match(str(uid))
+ if not o_uid:
+ return "Invalid"
+
+ return "Valid"
+
+ def LoadCookieData(self, HTTP_COOKIE):
+
+ import Cookie
+
+ custardcream = Cookie.SimpleCookie()
+ custardcream.load(HTTP_COOKIE)
+
+ return (custardcream["glsr_uid"].value,
+ custardcream["glsr_sessid"].value)
+
+ def ValidateSession(self, uid, sessid):
+
+ # Delete all old sessions
+ MySQL.Query("DELETE FROM %s WHERE " % self.full_tablename +
+ "(%s_user_id = %%s AND " % self.tablename +
+ "%s_id != %%s) OR " % self.tablename +
+ "%s_time < UNIX_TIMESTAMP() - %%s" % self.tablename,
+ (uid, sessid, Config.SessionTimeOut),
+ fetch = "none")
+
+ result = MySQL.Query("SELECT * FROM %s WHERE %s_user_id = " %
+ (self.full_tablename, self.tablename) + "%s", uid,
+ fetch="one")
+
+ return result != None
+
+ def CreateSession(self, uid, sessid):
+
+ # Check to see if the session is new, or just needs updating
+ if self.ValidateSession(uid, sessid):
+ self.UpdateTS(uid, sessid)
+ else:
+ MySQL.Query("INSERT INTO %s (%s_id, %s_user_id, %s_time) " %
+ (self.full_tablename, self.tablename, self.tablename,
+ self.tablename) +
+ "VALUES (%s, %s, UNIX_TIMESTAMP())", (sessid, uid),
+ fetch="none")
+
+ def UpdateTS(self, uid, sessid):
+ """ Update the sessions timestamp """
+
+ MySQL.Query("UPDATE %s SET %s_time = UNIX_TIMESTAMP() " %
+ (self.full_tablename, self.tablename) +
+ "WHERE %s_id = %%s AND %s_user_id = " %
+ (self.tablename, self.tablename) +
+ "%s", (sessid, uid), fetch="none")
+
+ def ListSessionsOnline(self, grace):
+
+ return MySQL.Query("SELECT %s_id, %s_user_id FROM %s " %
+ (self.tablename, self.tablename,
+ self.full_tablename) +
+ "WHERE (UNIX_TIMESTAMP() - %s_time) <= " %
+ self.tablename + "%s", grace, fetch="all")
diff --git a/src/glsr/src/pym/Stat.py b/src/glsr/src/pym/Stat.py
new file mode 100644
index 0000000000..4e8049623c
--- /dev/null
+++ b/src/glsr/src/pym/Stat.py
@@ -0,0 +1,70 @@
+# Copyright 2004 Ian Leitch
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Stat.py,v 1.1.1.1 2004/06/04 06:38:36 port001 Exp $
+#
+
+__modulename__ = "Stat"
+
+import MySQL
+import Config
+
+def DBSize():
+
+ dbsize = 0
+
+ result = MySQL.Query("SHOW TABLE STATUS", fetch="all")
+
+ for row in result:
+ dbsize += row["Data_length"] + row["Index_length"]
+
+ return str(dbsize)
+
+def UserCount():
+
+ result = MySQL.Query("SELECT count(*) FROM %s%s" %
+ (Config.MySQL["prefix"], Config.MySQL["user_table"]),
+ fetch="one")
+
+ return str(result["count(*)"])
+
+def ScriptCount():
+
+ result = MySQL.Query("SELECT count(*) FROM %s%s" %
+ (Config.MySQL["prefix"],
+ Config.MySQL["script_table"]), fetch="one")
+
+ return str(result["count(*)"])
+
+def SubScriptCount():
+
+ result = MySQL.Query("SELECT count(*) FROM %s%s" %
+ (Config.MySQL["prefix"],
+ Config.MySQL["subscript_table"]), fetch="one")
+
+ return str(result["count(*)"])
+
+def CommentCount():
+
+ result = MySQL.Query("SELECT count(*) FROM %s%s" %
+ (Config.MySQL["prefix"],
+ Config.MySQL["comment_table"]), fetch="one")
+
+ return str(result["count(*)"])
+
+def CategoryCount():
+
+ result = MySQL.Query("SELECT count(*) FROM %s%s" %
+ (Config.MySQL["prefix"],
+ Config.MySQL["category_table"]), fetch="one")
+
+ return str(result["count(*)"])
+
+def SessionCount():
+
+ result = MySQL.Query("SELECT count(*) FROM %s%s" %
+ (Config.MySQL["prefix"],
+ Config.MySQL["session_table"]), fetch="one")
+
+ return str(result["count(*)"])
diff --git a/src/glsr/src/pym/Template.py b/src/glsr/src/pym/Template.py
new file mode 100644
index 0000000000..52dcb0a33d
--- /dev/null
+++ b/src/glsr/src/pym/Template.py
@@ -0,0 +1,285 @@
+# Copyright 2004 Ian Leitch
+# Copyright 2004 Scott Hadfield
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Template.py,v 1.1.1.1 2004/06/04 06:38:34 port001 Exp $
+
+import sys
+import string
+import re
+import types
+
+import Config
+import Function
+
+__modulename__ = "Template"
+
+class New:
+
+ def __init__(self):
+
+ self.Template = ""
+ self.Contents = []
+ self.Output = []
+
+ def _Read(self):
+
+ try:
+ self.Contents = open(self.Template, "r").readlines()
+ except IOError, errmsg:
+ Function.logwrite("ERROR: %s: Failed to open %s for reading '%s'" % (__modulename__, self.Template, errmsg), "Error")
+ print "<html>\n<head>\n</head>\n<body>"
+ print "<font size=3><b>FATAL ERROR: Failed to open template '%s' for reading.</b><br>Please contact %s with the given error message.</font>" % (self.Template, Config.Contact)
+ print "</body>\n</html>"
+ sys.exit(1)
+
+ return self.Contents
+
+ def _Clear(self):
+
+ self.Template = ""
+ self.Contents = []
+ self.Output = []
+
+ def Compile(self, Template, Terms = {}, Loops = {}):
+ """
+ 'Terms' should be a dictionary of {TAG: value} pairs where value
+ will replace the text {TAG} in the specified template file.
+
+ 'Loops' should be a dictionary of {LOOPTAG: list} pairs. The template
+ file will have some text such as the following, but all that will be
+ displayed is "this is loop X" len(list) times.
+ {LOOP MYLOOP}
+ this is loop {MYLOOP}
+ {!LOOP}
+ Note: {MYLOOP} is replaced with list[i] where 'i' is the current
+ iteration
+
+ If statements are as follows:
+ {IF TAG == "value"}
+ {TAG} is equal to value
+ {!IF}
+ Note: The currently supported operators are
+ == != >
+
+ Note: Everything is case sensitive
+ """
+
+ def processLoops(file, Loops):
+ """Processes all top level loops. Returns 'file' with all loops
+ processed"""
+ return processTags(file, Loops, "LOOP",
+ lambda x,y: processLoop(x, y))
+
+ def processIfs(file, Terms):
+ return processTags(file, Terms, "IF",
+ lambda x,y: processIf(x, y))
+
+ def processTags(file, Terms, tag, function):
+ tag_open = "{%s " % tag
+ tag_close = "{!%s}" % tag
+
+ working_file = file
+ start = string.find(working_file, tag_open)
+ while (start != -1):
+ # Find the end of the tag
+ end = findTagClose(working_file[start + len(tag_open):], 0,
+ tag) + start + len(tag_open)
+
+ # Process that tag
+ tag_content = function(working_file[start + len(tag_open):end],
+ Terms)
+
+ working_file = (working_file[:start] + tag_content +
+ working_file[end + len(tag_close):])
+
+ # Find the beginning of the next loop
+ start = string.find(working_file, tag_open)
+
+
+ return working_file
+
+ def findTagClose(file, nest, tag):
+ "Recursively finds the location of the matching {!LOOP}"
+ tag_open = "{%s " % tag
+ tag_close = "{!%s}" % tag
+
+ next_open = string.find(file, tag_open)
+ next_close = string.find(file, tag_close)
+
+ if next_close < next_open or next_open == -1:
+ # No new loops were found
+ if nest == 0:
+ # Yay! We found the final loop closing tag
+ return next_close
+ else:
+ # A nested !loop found, decrement the nest count
+ start = next_close + len(tag_close)
+ return start + findTagClose(file[start:], nest - 1, tag)
+ else:
+ # A new nested loop found, increment the nest count.
+ start = next_open + len(tag_open)
+ return start + findTagClose(file[start:], nest + 1, tag)
+
+ def processLoop(file, Loops):
+ """Returns the content inside the loop (after it's been looped).
+ It expects 'file' to be the content between (exlusively) '{LOOP '
+ and {!LOOP}.
+ The nested-most loop is processed first"""
+
+ # loop_name is the loop tag name
+ loop_name = file[:string.find(file, "}")].strip()
+
+ # loop_text is the content within the {LOOP}{!LOOP} tags.
+ loop_text = file[string.find(file, "}") + 1:]
+
+ next_open = string.find(file, "{LOOP ")
+ if next_open != -1:
+ "A nested LOOP exists, so recurse futher"
+ loop_text = processLoops(loop_text, Loops)
+
+ # No more nested loops, so we can process this one
+ if loop_name not in Loops.keys():
+ raise TemplateError, "Loop %s is not defined." % loop_name
+
+ # The following four statements are used for finding and replacing
+ # tags within the IF tag (i.e. {IF TAG1 == TAG2}). It's not as
+ # fucked up as it looks, really ;-).
+ p = re.compile('({IF +)([\w\-_"\']+)( *[!=<>]+ *)([\w\-_"\']+)' +
+ '( *})')
+ p_index = re.compile('({IF +)([\w\-_"\']+.[\w\-_"\']+)' +
+ '( *[!=<>]+ *)([\w\-_"\']+.[\w\-_"\']+)( *})')
+
+ repl_func = lambda x: (re.sub('([ !=<>]+)%s|%s([ !=<>]+)' %
+ (loop_name, loop_name),
+ "\\1%s" % Loops[loop_name][i],
+ x.group()))
+ repl_func2 = lambda x: (re.sub('([ !=<>]+)%s.%s|%s.%s([ !=<>]+)' %
+ (loop_name, loop_index, loop_name,
+ loop_index), "\\1%s" %
+ Loops[loop_name][i][loop_index],
+ x.group()))
+
+ loop_str = ""
+ for i in range(0, len(Loops[loop_name])):
+ """ This loop does the actual tag replacement with the
+ appropriate values."""
+
+ tmp_text = loop_text
+ dot = tmp_text.find("{%s." % loop_name)
+ while dot != -1:
+ "Replace all multi-dimensional loop tags"
+ start = dot + len(loop_name) + 2
+ end = tmp_text.find("}", start)
+
+ loop_index = tmp_text[start:end].strip()
+ inner_val = Loops[loop_name][i][loop_index]
+
+ new_text = tmp_text.replace("{%s.%s}" %
+ (loop_name, loop_index),
+ "%s" % inner_val)
+
+ # Replace and tags.index within the {IF } tag
+ new_text = p_index.sub(repl_func2, new_text)
+
+ # Adjust the position accordingly
+ start = start - len(loop_name) - 1 + len("%s" % inner_val)
+ tmp_text = new_text
+
+ dot = tmp_text.find("{%s." % loop_name, start)
+
+ # Replace and tags within the {IF } tag
+ tmp_text = p.sub(repl_func, tmp_text)
+
+ loop_str = (loop_str +
+ tmp_text.replace("{%s}" % loop_name,
+ "%s" % Loops[loop_name][i]))
+ return loop_str
+
+ def processIf(file, Terms):
+ """File contains everything between {IF and {!IF}"""
+ next_open = string.find(file, "{IF ")
+
+ if_text = file[string.find(file, "}") + 1:]
+
+ if next_open != -1:
+ if_text = processIfs(if_text, Terms)
+
+ # Find any else's
+ else_text = ""
+ else_pos = if_text.find("{ELSE}")
+ if else_pos != -1:
+ else_text = if_text[else_pos + 6:]
+ if_text = if_text[:else_pos]
+
+
+ stmt = file[:file.find("}")].strip()
+ tag = stmt[:stmt.find(" ")]
+
+ # Set the operator
+ oper = stmt[stmt.find(" "):].strip(" ")
+ oper = oper[:oper.find(" ")].strip()
+
+ def setVal(val):
+ if val not in Terms.keys():
+ return val.strip("\"' ")
+ else:
+ return "%s" % Terms[val]
+
+ # Set the value to the right of the operator
+ valueR = setVal(stmt[string.rfind(stmt, " "):].strip())
+
+ # Set the value to the left of the operator
+ valueL = setVal(tag)
+
+ if ((oper == "==" and valueL == valueR) or
+ (oper == "!=" and valueL != valueR) or
+ (oper == "<" and int(valueL) < int(valueR)) or
+ (oper == ">" and int(valueL) > int(valueR))):
+ return if_text
+ else:
+ return else_text
+
+
+ self.Template = Template
+ del Template
+ self._Read()
+ inIF = 0
+
+ full_file = string.join(self.Contents);
+
+ # Process all non LOOP, non IF tags
+ for term in Terms.keys():
+ if type(Terms[term]) == types.DictType:
+ for index in Terms[term].keys():
+ full_file = string.replace(full_file, "{%s.%s}" %
+ (term, index),
+ "%s" % (Terms[term][index]))
+ else:
+ full_file = string.replace(full_file, "{%s}" % term,
+ "%s" % Terms[term])
+ for term in Terms.keys():
+ full_file = string.replace(full_file, "{%s}" % term,
+ "%s" % Terms[term])
+
+ # Process all LOOP tags
+ full_file = processLoops(full_file, Loops)
+
+ # Process all IF tags
+ Terms.update(Loops)
+ full_file = processIfs(full_file, Terms)
+
+ self.Output = string.split(full_file, "\n");
+
+
+ def Print(self):
+ if self.Template == "":
+ raise TemplateError, "No compiled template data found."
+
+ #print self.Output
+ print "\n".join(self.Output)
+
+ self._Clear()
+
+class TemplateError(Exception): pass
diff --git a/src/glsr/src/pym/Template_ng.py b/src/glsr/src/pym/Template_ng.py
new file mode 100644
index 0000000000..303c8bc667
--- /dev/null
+++ b/src/glsr/src/pym/Template_ng.py
@@ -0,0 +1,285 @@
+# Copyright 2004 Ian Leitch
+# Copyright 2004 Scott Hadfield
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Template_ng.py,v 1.1.1.1 2004/06/04 06:38:35 port001 Exp $
+
+import sys
+import string
+import re
+import types
+
+import Config
+import Function
+
+__modulename__ = "Template"
+
+class New:
+
+ def __init__(self):
+
+ self.Template = ""
+ self.Contents = []
+ self.Output = []
+
+ def _Read(self):
+
+ try:
+ self.Contents = open(self.Template, "r").readlines()
+ except IOError, errmsg:
+ Function.logwrite("ERROR: %s: Failed to open %s for reading '%s'" % (__modulename__, self.Template, errmsg), "Error")
+ print "<html>\n<head>\n</head>\n<body>"
+ print "<font size=3><b>FATAL ERROR: Failed to open template '%s' for reading.</b><br>Please contact %s with the given error message.</font>" % (self.Template, Config.Contact)
+ print "</body>\n</html>"
+ sys.exit(1)
+
+ return self.Contents
+
+ def _Clear(self):
+
+ self.Template = ""
+ self.Contents = []
+ self.Output = []
+
+ def Compile(self, Template, Terms = {}, Loops = {}):
+ """
+ 'Terms' should be a dictionary of {TAG: value} pairs where value
+ will replace the text {TAG} in the specified template file.
+
+ 'Loops' should be a dictionary of {LOOPTAG: list} pairs. The template
+ file will have some text such as the following, but all that will be
+ displayed is "this is loop X" len(list) times.
+ {LOOP MYLOOP}
+ this is loop {MYLOOP}
+ {!LOOP}
+ Note: {MYLOOP} is replaced with list[i] where 'i' is the current
+ iteration
+
+ If statements are as follows:
+ {IF TAG == "value"}
+ {TAG} is equal to value
+ {!IF}
+ Note: The currently supported operators are
+ == != >
+
+ Note: Everything is case sensitive
+ """
+
+ def processLoops(file, Loops):
+ """Processes all top level loops. Returns 'file' with all loops
+ processed"""
+ return processTags(file, Loops, "LOOP",
+ lambda x,y: processLoop(x, y))
+
+ def processIfs(file, Terms):
+ return processTags(file, Terms, "IF",
+ lambda x,y: processIf(x, y))
+
+ def processTags(file, Terms, tag, function):
+ tag_open = "{%s " % tag
+ tag_close = "{!%s}" % tag
+
+ working_file = file
+ start = string.find(working_file, tag_open)
+ while (start != -1):
+ # Find the end of the tag
+ end = findTagClose(working_file[start + len(tag_open):], 0,
+ tag) + start + len(tag_open)
+
+ # Process that tag
+ tag_content = function(working_file[start + len(tag_open):end],
+ Terms)
+
+ working_file = (working_file[:start] + tag_content +
+ working_file[end + len(tag_close):])
+
+ # Find the beginning of the next loop
+ start = string.find(working_file, tag_open)
+
+
+ return working_file
+
+ def findTagClose(file, nest, tag):
+ "Recursively finds the location of the matching {!LOOP}"
+ tag_open = "{%s " % tag
+ tag_close = "{!%s}" % tag
+
+ next_open = string.find(file, tag_open)
+ next_close = string.find(file, tag_close)
+
+ if next_close < next_open or next_open == -1:
+ # No new loops were found
+ if nest == 0:
+ # Yay! We found the final loop closing tag
+ return next_close
+ else:
+ # A nested !loop found, decrement the nest count
+ start = next_close + len(tag_close)
+ return start + findTagClose(file[start:], nest - 1, tag)
+ else:
+ # A new nested loop found, increment the nest count.
+ start = next_open + len(tag_open)
+ return start + findTagClose(file[start:], nest + 1, tag)
+
+ def processLoop(file, Loops):
+ """Returns the content inside the loop (after it's been looped).
+ It expects 'file' to be the content between (exlusively) '{LOOP '
+ and {!LOOP}.
+ The nested-most loop is processed first"""
+
+ # loop_name is the loop tag name
+ loop_name = file[:string.find(file, "}")].strip()
+
+ # loop_text is the content within the {LOOP}{!LOOP} tags.
+ loop_text = file[string.find(file, "}") + 1:]
+
+ next_open = string.find(file, "{LOOP ")
+ if next_open != -1:
+ "A nested LOOP exists, so recurse futher"
+ loop_text = processLoops(loop_text, Loops)
+
+ # No more nested loops, so we can process this one
+ if loop_name not in Loops.keys():
+ raise TemplateError, "Loop %s is not defined." % loop_name
+
+ # The following four statements are used for finding and replacing
+ # tags within the IF tag (i.e. {IF TAG1 == TAG2}). It's not as
+ # fucked up as it looks, really ;-).
+ p = re.compile('({IF +)([\w\-_"\']+)( *[!=<>]+ *)([\w\-_"\']+)' +
+ '( *})')
+ p_index = re.compile('({IF +)([\w\-_"\']+.[\w\-_"\']+)' +
+ '( *[!=<>]+ *)([\w\-_"\']+.[\w\-_"\']+)( *})')
+
+ repl_func = lambda x: (re.sub('([ !=<>]+)%s|%s([ !=<>]+)' %
+ (loop_name, loop_name),
+ "\\1%s" % Loops[loop_name][i],
+ x.group()))
+ repl_func2 = lambda x: (re.sub('([ !=<>]+)%s.%s|%s.%s([ !=<>]+)' %
+ (loop_name, loop_index, loop_name,
+ loop_index), "\\1%s" %
+ Loops[loop_name][i][loop_index],
+ x.group()))
+
+ loop_str = ""
+ for i in range(0, len(Loops[loop_name])):
+ """ This loop does the actual tag replacement with the
+ appropriate values."""
+
+ tmp_text = loop_text
+ dot = tmp_text.find("{%s." % loop_name)
+ while dot != -1:
+ "Replace all multi-dimensional loop tags"
+ start = dot + len(loop_name) + 2
+ end = tmp_text.find("}", start)
+
+ loop_index = tmp_text[start:end].strip()
+ inner_val = Loops[loop_name][i][loop_index]
+
+ new_text = tmp_text.replace("{%s.%s}" %
+ (loop_name, loop_index),
+ "%s" % inner_val)
+
+ # Replace and tags.index within the {IF } tag
+ new_text = p_index.sub(repl_func2, new_text)
+
+ # Adjust the position accordingly
+ start = start - len(loop_name) - 1 + len("%s" % inner_val)
+ tmp_text = new_text
+
+ dot = tmp_text.find("{%s." % loop_name, start)
+
+ # Replace and tags within the {IF } tag
+ tmp_text = p.sub(repl_func, tmp_text)
+
+ loop_str = (loop_str +
+ tmp_text.replace("{%s}" % loop_name,
+ "%s" % Loops[loop_name][i]))
+ return loop_str
+
+ def processIf(file, Terms):
+ """File contains everything between {IF and {!IF}"""
+ next_open = string.find(file, "{IF ")
+
+ if_text = file[string.find(file, "}") + 1:]
+
+ if next_open != -1:
+ if_text = processIfs(if_text, Terms)
+
+ # Find any else's
+ else_text = ""
+ else_pos = if_text.find("{ELSE}")
+ if else_pos != -1:
+ else_text = if_text[else_pos + 6:]
+ if_text = if_text[:else_pos]
+
+
+ stmt = file[:file.find("}")].strip()
+ tag = stmt[:stmt.find(" ")]
+
+ # Set the operator
+ oper = stmt[stmt.find(" "):].strip(" ")
+ oper = oper[:oper.find(" ")].strip()
+
+ def setVal(val):
+ if val not in Terms.keys():
+ return val.strip("\"' ")
+ else:
+ return "%s" % Terms[val]
+
+ # Set the value to the right of the operator
+ valueR = setVal(stmt[string.rfind(stmt, " "):].strip())
+
+ # Set the value to the left of the operator
+ valueL = setVal(tag)
+
+ if ((oper == "==" and valueL == valueR) or
+ (oper == "!=" and valueL != valueR) or
+ (oper == "<" and int(valueL) < int(valueR)) or
+ (oper == ">" and int(valueL) > int(valueR))):
+ return if_text
+ else:
+ return else_text
+
+
+ self.Template = Template
+ del Template
+ self._Read()
+ inIF = 0
+
+ full_file = string.join(self.Contents);
+
+ # Process all non LOOP, non IF tags
+ for term in Terms.keys():
+ if type(Terms[term]) == types.DictType:
+ for index in Terms[term].keys():
+ full_file = string.replace(full_file, "{%s.%s}" %
+ (term, index),
+ "%s" % (Terms[term][index]))
+ else:
+ full_file = string.replace(full_file, "{%s}" % term,
+ "%s" % Terms[term])
+ for term in Terms.keys():
+ full_file = string.replace(full_file, "{%s}" % term,
+ "%s" % Terms[term])
+
+ # Process all LOOP tags
+ full_file = processLoops(full_file, Loops)
+
+ # Process all IF tags
+ Terms.update(Loops)
+ full_file = processIfs(full_file, Terms)
+
+ self.Output = string.split(full_file, "\n");
+
+
+ def Print(self):
+ if self.Template == "":
+ raise TemplateError, "No compiled template data found."
+
+ #print self.Output
+ print "\n".join(self.Output)
+
+ self._Clear()
+
+class TemplateError(Exception): pass
diff --git a/src/glsr/src/pym/User.py b/src/glsr/src/pym/User.py
new file mode 100644
index 0000000000..22a4aa0143
--- /dev/null
+++ b/src/glsr/src/pym/User.py
@@ -0,0 +1,127 @@
+#!/usr/bin/env python2
+#
+# Copyright 2004 Ian Leitch
+# Copyright 2004 Scott Hadfield
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: User.py,v 1.1.1.1 2004/06/04 06:38:33 port001 Exp $
+#
+
+from time import strftime, gmtime
+
+__modulename__ = "User"
+__productname__ = "glsr"
+
+import MySQL
+import Config
+import Function
+from GLSRBackend import GLSRBackend as Parent
+
+class User(Parent):
+
+ tablename = Config.MySQL["user_table"]
+
+ def Create(self, fullname, alias, passwd, email, type):
+ """Add a new user to the database"""
+
+ return Parent.Create(self,
+ {"alias": alias,
+ "fullname": fullname,
+ "passwd": passwd,
+ "email": email,
+ "rank": 0,
+ "type": type,
+ "joined": strftime("%Y-%m-%d", gmtime())
+ })
+
+
+ def Modify(self, alias, fullname, email, type, password):
+ """Modify users details"""
+
+ details = {"alias": alias, "fullname": fullname,
+ "email": email, "type": type}
+
+ if password != None:
+ details.update({"passwd": password})
+
+ return Parent.Modify(self, ["alias", "fullname", "email", "type",
+ "passwd"], details)
+
+
+ def UpdateIP(self, ipaddr):
+ """Update lastip for given uid"""
+
+ return Parent.Modify(self, ["lastip"], {"lastip": ipaddr})
+
+
+ def AliasExists(self, alias):
+ """Check for existence of given user alias"""
+
+ return Parent.Exists(self, "alias", alias)
+
+
+ def GetUid(self, alias):
+ """Return UID for given alias"""
+
+ result = MySQL.Query("SELECT %s_id FROM %s%s" %
+ (self.tablename, Config.MySQL["prefix"],
+ self.tablename), fetch="one")
+
+ if result == None:
+ return False
+ else:
+ return result["%s_id" % self.tablename]
+
+
+ def GetAlias(self):
+ """Return alias for given uid"""
+
+ result = self.GetDetails()
+ if result == None:
+ return False
+ else:
+ return result["%s_alias" % self.tablename]
+
+
+ def GetType(self):
+
+ result = self.GetDetails()
+
+ if result == None:
+ return False
+ else:
+ return result["%s_type" % self.tablename]
+
+
+ def CalcRank(self):
+ """ Calculate user rank. A users rank is the total of sum of the
+ rank of their scripts. """
+
+ rank = 0
+
+ result = MySQL.Query("SELECT rank FROM %s%s WHERE %s_submitter_id = " %
+ (Config.MySQL["prefix"],
+ Config.MySQL["script_table"],
+ Config.MySQL["script_table"]) +
+ "%s", (self.id), fetch="all")
+
+ for tuple in result:
+ rank = rank + tuple[0]
+
+ return rank
+
+
+ def ValidateAlias(self, alias, password):
+
+ result = MySQL.Query("SELECT * FROM %s%s " %
+ (Config.MySQL["prefix"], self.tablename) +
+ "WHERE %s_alias = %%s AND " % self.tablename +
+ "%s_passwd = PASSWORD(%%s)" % self.tablename,
+ (alias, password))
+
+ if len(result) == 0:
+ return False
+ else:
+ return result[0]
+
diff --git a/src/glsr/src/pym/Validation.py b/src/glsr/src/pym/Validation.py
new file mode 100644
index 0000000000..412824aae9
--- /dev/null
+++ b/src/glsr/src/pym/Validation.py
@@ -0,0 +1,37 @@
+# Copyright 2004 Ian Leitch
+# Copyright 2004 Scott Hadfield
+# Copyright 1999-2004 Gentoo Technologies, Inc.
+# Distributed under the terms of the GNU General Public License v2
+#
+# $Id: Validation.py,v 1.1.1.1 2004/06/04 06:38:34 port001 Exp $
+#
+
+__modulename__ = "Validation"
+
+from Config import MySQL
+from MySQL import Query
+from Auth import GenMd5
+from re import compile,match
+
+def CheckPageRequest(page):
+
+ if page:
+ page_regex = "^[a-z]{1,6}$"
+
+ p_page = compile(page_regex)
+ o_page = p_page.match(page)
+
+ if not o_page:
+ return "Invalid"
+
+ return "Valid"
+
+def ValidatePasswd(uid, passwd):
+
+ unknownmd5 = GenMd5(passwd)
+ correctmd5 = Query("SELECT passwd FROM %s " % MySQL["user_table"] + "WHERE uid = %s", uid, fetch="one")
+ if unknownmd5 != correctmd5[0]:
+ return "Invalid"
+ else:
+ return "Valid"
+
diff --git a/src/glsr/src/templates/Footer.tpl b/src/glsr/src/templates/Footer.tpl
new file mode 100644
index 0000000000..660df42a98
--- /dev/null
+++ b/src/glsr/src/templates/Footer.tpl
@@ -0,0 +1,21 @@
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td height="30" align="left" valign="bottom" bgcolor="#000000"><table width="100%" height="25" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ <span class="menu">Links:
+ <a class="menulink" href="index.py">glsr.gentoo.org</a> |
+ <a class="menulink" href="http://www.gentoo.org">www.gentoo.org</a> |
+ <a class="menulink" href="http://bugs.gentoo.org">bugs.gentoo.org</a> |
+ <a class="menulink" href="http://packages.gentoo.org">packages.gentoo.org</a>
+ </span>
+ <br>
+ <span class="footer_copyright">Gentoo Linux Script Repository v{GLSR_VERSION}, Copyright 2001-2004 Gentoo Technologies, Inc. Copyright 2004 Ian Leitch</span></td>
+ </tr>
+ </table></td>
+ </tr>
+</body>
+</html>
+
diff --git a/src/glsr/src/templates/admin/Categories.tpl b/src/glsr/src/templates/admin/Categories.tpl
new file mode 100644
index 0000000000..9705a5836b
--- /dev/null
+++ b/src/glsr/src/templates/admin/Categories.tpl
@@ -0,0 +1,80 @@
+
+ <form name="category_control_form" method="GET" action="index.py">
+ <input type="hidden" name="page" value="script">
+
+ {IF MESSAGE != ""}
+ <font class="message">{MESSAGE}</font><br /><br />
+ {!IF}
+
+ {IF WARN_MESSAGE == 1}
+ <font class="warn_message">No Categories Found</font><br /><br />
+ {!IF}
+
+ {IF TOTAL_CATS > 0}
+ <!-- Listing of all users in the system -->
+ <table width="90%" class="standard_table">
+ <tr>
+ <td colspan="4" class="header">Category Listing</td>
+ </tr>
+
+ <tr>
+ <td class="sub_header">Name</td>
+ <td class="sub_header">Description</td>
+ <td class="sub_header">Parent</td>
+ <td class="sub_header" align="center">Delete</td>
+ </tr>
+ {LOOP CAT_LOOP}
+ <tr>
+ <td class="standard_row_{CAT_LOOP.row}" style="padding-left: {CAT_LOOP.padding}px"><a href="index.py?page=script&show_modify_cat={CAT_LOOP.category_id}&mod_categories=Modify+Catgories">{CAT_LOOP.category_name}</a></td>
+ <td class="standard_row_{CAT_LOOP.row}">{CAT_LOOP.category_descr}</td>
+ <td class="standard_row_{CAT_LOOP.row}">{IF CAT_LOOP.parent_name == "None"}Root Category{ELSE}{CAT_LOOP.parent_name}{!IF}</td>
+ <td class="standard_row_{CAT_LOOP.row}" align="center"><input type="checkbox" name="delete" value="{CAT_LOOP.category_id}" /></td>
+ </tr>
+ {!LOOP}
+ <tr>
+ <td class="standard_cell" colspan="9" align="right"><input type="submit" class="button" name="delete_cats" value="Delete" />&nbsp;&nbsp;</td>
+ </tr>
+ </table>
+ {!IF}
+
+ {IF MODIFY_CAT != 0}
+ <!-- The form to add or modify categories -->
+ <input type="hidden" name="catid" value="{MODIFY_CAT}" />
+ <table width="45%" class="standard_table">
+ <tr>
+ <td colspan="" class="header">{IF ADD_CAT_FORM == 1}Add New Catgory{ELSE}Modify Category{!IF}</td>
+ </tr>
+
+ <tr>
+ <td class="standard_cell">
+ <font class="instructional">Name:</font><br />
+ <input type="text" class="text" name="name" value="{NAME}" />
+ </td>
+ </tr>
+ <tr>
+ <td class="standard_cell">
+ <font class="instructional">Parent:</font><br />
+ <select name="parent" class="dropdown">
+ <option value="0">None</option>
+ {LOOP PARENT_LOOP}
+ <option value="{PARENT_LOOP.category_id}" {IF PARENT_LOOP.category_name == PARENT}selected{!IF}>{PARENT_LOOP.category_name}</option>
+ {!LOOP}
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td class="standard_cell">
+ <font class="instructional">Description:</font><br />
+ <input type="text" class="text-long" name="descr" value="{DESCR}" />
+ </td>
+ </tr>
+ <tr>
+ <td class="standard_cell">
+ <input type="submit" class="button" name="{IF ADD_CAT_FORM == 1}add_new_cat{ELSE}modify_cat{!IF}" value="Save"/>
+ </td>
+ </tr>
+ </table>
+ {!IF}
+
+ </form>
+ \ No newline at end of file
diff --git a/src/glsr/src/templates/admin/Header.tpl b/src/glsr/src/templates/admin/Header.tpl
new file mode 100644
index 0000000000..2a2697aa30
--- /dev/null
+++ b/src/glsr/src/templates/admin/Header.tpl
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Gentoo Linux Script Repository</title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<link title="new" rel="stylesheet" href="{GLSR_URL}css/glsr.css" type="text/css">
+<link REL="shortcut icon" HREF="{GLSR_URL}images/favicon.ico" TYPE="image/x-icon">
+</head>
+<body>
+<table width="100%" height="100%" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td align="left" valign="top" height="125"><table width="100%" height="125" border="0" cellpadding="0" cellspacing="0" background="{GLSR_URL}images/header-bk.png">
+ <tr>
+ <td><img src="{GLSR_URL}images/glogo.png" width="193" height="125"><img src="{GLSR_URL}images/splogo-beta.png" width="350" height="125"></td>
+ <td align="right" valign="bottom">
+
+ {IF USER_ALIAS == ""}
+ <form name="login_form" method="post" action="index.py?page=login">
+ <input type="hidden" name="page" value="login" />
+ <table border="0" cellspacing="5" cellpadding="0">
+ <tr>
+ <td class="style3">Username:</td>
+ <td><input class="login_form_element" name="username" type="text" size="15" maxlength="15"></td>
+ </tr>
+ <tr>
+ <td class="style3">Password:</td>
+ <td><input class="login_form_element" name="password" type="password" size="15" maxlength="15"></td>
+ </tr>
+ <tr>
+ <td colspan="2" align="right"><input class="form_element" name="login" value="Login" type="submit" /></td>
+ </tr>
+ </table>
+ </form>
+ {!IF}
+ </td>
+ </tr>
+ </table></td>
+ </tr>
+ <tr>
+ <td height="25" align="left" valign="center" bgcolor="#000000"><span class="menu">
+ <a class="menulink" href="index.py?page=main">Main</a> |
+ <a class="menulink" href="index.py?page=stat">Statistics</a> |
+ <a class="menulink" href="index.py?page=news">News Announcements</a> |
+ <a class="menulink" href="index.py?page=user">User Management</a>
+ | <a class="menulink" href="index.py?page=script">Script Management</a>
+
+ {IF USER_ALIAS != ""}
+ | <a class="menulink" href="index.py?page=logout">Logout [{USER_ALIAS}]</a>
+ {!IF}
+
+ </span></td>
+ </tr>
+ <tr>
+ <td align="center" valign="top">
+ <br>
+
diff --git a/src/glsr/src/templates/admin/Languages.tpl b/src/glsr/src/templates/admin/Languages.tpl
new file mode 100644
index 0000000000..c1504b012d
--- /dev/null
+++ b/src/glsr/src/templates/admin/Languages.tpl
@@ -0,0 +1,67 @@
+
+ <form name="language_control_form" method="GET" action="index.py">
+ <input type="hidden" name="page" value="script">
+
+ {IF MESSAGE != ""}
+ <font class="message">{MESSAGE}</font><br /><br />
+ {!IF}
+
+ {IF WARN_MESSAGE == 1}
+ <font class="warn_message">No Languages Found</font><br /><br />
+ {!IF}
+
+ {IF TOTAL_LANGS > 0}
+ <!-- Listing of all users in the system -->
+ <table width="90%" class="standard_table">
+ <tr>
+ <td colspan="4" class="header">Language Listing</td>
+ </tr>
+
+ <tr>
+ <td class="sub_header">Name</td>
+ <td class="sub_header">Description</td>
+ <td class="sub_header" align="center">Delete</td>
+ </tr>
+ {LOOP LANG_LOOP}
+ <tr>
+ <td class="standard_row_{LANG_LOOP.row}"><a href="index.py?page=script&show_modify_lang={LANG_LOOP.language_id}">{LANG_LOOP.language_name}</a></td>
+ <td class="standard_row_{LANG_LOOP.row}">{LANG_LOOP.language_descr}</td>
+ <td class="standard_row_{LANG_LOOP.row}" align="center"><input type="checkbox" name="delete" value="{LANG_LOOP.language_id}" /></td>
+ </tr>
+ {!LOOP}
+ <tr>
+ <td class="standard_cell" colspan="9" align="right"><input type="submit" class="button" name="delete_langs" value="Delete" />&nbsp;&nbsp;</td>
+ </tr>
+ </table>
+ {!IF}
+
+ {IF MODIFY_LANG != 0}
+ <!-- The form to add or modify languages -->
+ <input type="hidden" name="langid" value="{MODIFY_LANG}" />
+ <table width="45%" class="standard_table">
+ <tr>
+ <td colspan="" class="header">{IF ADD_LANG_FORM == 1}Add New Language{ELSE}Modify Language{!IF}</td>
+ </tr>
+
+ <tr>
+ <td class="standard_cell">
+ <font class="instructional">Name:</font><br />
+ <input type="text" class="text" name="name" value="{NAME}" />
+ </td>
+ </tr>
+ <tr>
+ <td class="standard_cell">
+ <font class="instructional">Description:</font><br />
+ <input type="text" class="text-long" name="descr" value="{DESCR}" />
+ </td>
+ </tr>
+ <tr>
+ <td class="standard_cell">
+ <input type="submit" class="button" name="{IF ADD_LANG_FORM == 1}add_new_lang{ELSE}modify_lang{!IF}" value="Save"/>
+ </td>
+ </tr>
+ </table>
+ {!IF}
+
+ </form>
+ \ No newline at end of file
diff --git a/src/glsr/src/templates/admin/Main.tpl b/src/glsr/src/templates/admin/Main.tpl
new file mode 100644
index 0000000000..799746545c
--- /dev/null
+++ b/src/glsr/src/templates/admin/Main.tpl
@@ -0,0 +1,36 @@
+ <table width="80%" border="0" cellspacing="0" cellpadding="0" class="section_table">
+ <tr>
+ <td height="50" background="{GLSR_URL}images/header-bk.png"><span class="section_header_text">&nbsp;&nbsp;Site Statistics</span></td><td width="50%" height="50" align="right" valign="middle" background="{GLSR_URL}images/header-bk.png"><img src="{GLSR_URL}images/dialog-info.png" width="48" height="48"></td>
+ </tr>
+ <tr>
+ <td height="30" valign="middle" class="stats_row_1" style="border-right: 1px solid black">&nbsp;&nbsp;Total Users: {USER_COUNT}</td><td height="30" class="stats_row_1">&nbsp;&nbsp;Total Sessions: {SESSION_COUNT}</td>
+ </tr>
+ <tr>
+ <td height="30" class="stats_row_2" style="border-right: 1px solid black">&nbsp;&nbsp;Total Parent Scripts: {SCRIPT_COUNT}</td><td height="30" class="stats_row_2">&nbsp;&nbsp;Total Sub-Scripts: {SUBSCRIPT_COUNT}</td>
+ </tr>
+ <tr>
+ <td height="30" class="stats_row_3" style="border-right: 1px solid black">&nbsp;&nbsp;Total Categories: {CATEGORY_COUNT}</td><td height="30" class="stats_row_3">&nbsp;&nbsp;Total Comments: {COMMENT_COUNT}</td>
+ </tr>
+ <tr>
+ <td height="30" class="stats_row_4" style="border-right: 1px solid black">&nbsp;&nbsp;Database Size: {DBSIZE} (bytes)</td><td height="30" class="stats_row_4_1">&nbsp;&nbsp;More statistics...</td>
+ </tr>
+ </table>
+ <br>
+ <table width="80%" border="0" cellspacing="0" cellpadding="0" class="section_table">
+ <tr>
+ <td height="50" background="{GLSR_URL}images/header-bk.png">&nbsp;&nbsp;<span class="section_header_text">Scripts Pending Review</span></td><td width="50" height="50" align="center" valign="middle" background="{GLSR_URL}images/header-bk.png"><img src="{GLSR_URL}images/stock_notes.png" width="48" height="48"></td>
+ </tr>
+ <tr>
+ <td height="30" colspan="2" class="stats_row_4"><span>&nbsp;&nbsp;No scripts pending review.</span></td>
+ </tr>
+ </table>
+ <br>
+ <table width="80%" border="0" cellspacing="0" cellpadding="0" class="section_table">
+ <tr>
+ <td height="50" background="{GLSR_URL}images/header-bk.png">&nbsp;&nbsp;<span class="section_header_text">Who Is Online</span></td><td width="50" height="50" align="center" valign="middle" background="{GLSR_URL}images/header-bk.png"><img src="{GLSR_URL}images/people.png" width="48" height="48"></td>
+ </tr>
+ <tr>
+ <td height="30" colspan="2" class="stats_row_4"><span>&nbsp;&nbsp;{USER_ONLINE_LIST}</span></td>
+ </tr>
+ </table>
+
diff --git a/src/glsr/src/templates/admin/News.tpl b/src/glsr/src/templates/admin/News.tpl
new file mode 100644
index 0000000000..e62b970f7b
--- /dev/null
+++ b/src/glsr/src/templates/admin/News.tpl
@@ -0,0 +1,97 @@
+ <form name="news_control_form" method="GET" action="index.py">
+ <input type="hidden" name="page" value="news">
+
+ {IF MESSAGE != ""}
+ <font class="message">{MESSAGE}</font><br /><br />
+ {!IF}
+
+ <table width="90%" class="standard_table">
+ <tr>
+ <td class="header">News Announcement Controls</td>
+ <td class="header" align="right" valign="middle"><img src="{GLSR_URL}images/news.png" width="48" height="48" />
+ </tr>
+ <tr>
+ <td colspan="2" height="40" valign="middle" class="standard_cell">
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+
+ <td height="40" valign="center" class="">&nbsp;&nbsp;
+ {IF TOTAL_ANNOUNCE == 0}
+ <input type="submit" class="button" name="show_all_announce" value="List All Announcements" />
+ {ELSE}
+ <input type="submit" class="button" name="" value="Hide Announcement List" />
+ {!IF}
+ </td>
+
+ <td height="40" valign="center" class="">&nbsp;&nbsp;
+ <input type="submit" class="button" name="show_add_new_announce" value="Make Announcement" />
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+
+ <br />
+
+ {IF WARN_MESSAGE != ""}
+ <font class="warn_message">{WARN_MESSAGE}</font><br /><br />
+ {!IF}
+
+ {IF TOTAL_ANNOUNCE > 0}
+ <!-- Listing of all announcements in the system -->
+ <table width="90%" class="standard_table">
+ <tr>
+ <td colspan="9" class="header">Announcement Listing</td>
+ </tr>
+
+ <tr>
+ <td class="sub_header">ID</td>
+ <td class="sub_header">Subject</td>
+ <td class="sub_header">Created</td>
+ <td class="sub_header">Author</td>
+ <td class="sub_header" align="center">Delete</td>
+ </tr>
+ {LOOP ANNOUNCE_LOOP}
+ <tr>
+ <td class="standard_row_{ANNOUNCE_LOOP.row}"><a href="index.py?page=news&show_modify_announce={ANNOUNCE_LOOP.news_id}">{ANNOUNCE_LOOP.news_id}</a></td>
+ <td class="standard_row_{ANNOUNCE_LOOP.row}">{ANNOUNCE_LOOP.news_subject}</td>
+ <td class="standard_row_{ANNOUNCE_LOOP.row}">{ANNOUNCE_LOOP.news_date}</td>
+ <td class="standard_row_{ANNOUNCE_LOOP.row}">{ANNOUNCE_LOOP.news_author_id}</td>
+ <td class="standard_row_{ANNOUNCE_LOOP.row}" align="center"><input type="checkbox" name="delete" value="{ANNOUNCE_LOOP.news_id}" /></td>
+ </tr>
+ {!LOOP}
+ <tr>
+ <td class="standard_cell" colspan="9" align="right"><input type="submit" class="button" name="delete_announce" value="Delete" />&nbsp;&nbsp;</td>
+ </tr>
+ </table>
+ {!IF}
+
+ {IF ADD_MODIFY_ANNOUNCE != 0}
+ <!-- The form to add a new announcement or modify an existing one -->
+ <input type="hidden" name="annid" value="{ADD_MODIFY_ANNOUNCE}" />
+ <table width="45%" class="standard_table">
+ <tr>
+ <td colspan="" class="header">{ANNOUNCE_MODE}</td>
+ </tr>
+ <tr>
+ <td class="standard_cell">
+ <font class="instructional">Subject:</font><br />
+ <input type="text" class="text-long" name="subject" value="{SUBJECT}" />
+ </td>
+ </tr>
+ <tr>
+ <td class="standard_cell">
+ <font class="instructional">Announcement:</font><br />
+ <textarea rows="15" cols="50" class="text" name="announcement">{ANNOUNCEMENT}</textarea>
+ </td>
+ </tr>
+ <tr>
+ <td class="standard_cell">
+ <input type="submit" class="button" name="{IF ADD_ANNOUNCE_FORM == 1}add_new_announce{ELSE}modify_announce{!IF}" value="Save"/>
+ </td>
+ </tr>
+ </table>
+ {!IF}
+
+ </form>
diff --git a/src/glsr/src/templates/admin/Script_Controls.tpl b/src/glsr/src/templates/admin/Script_Controls.tpl
new file mode 100644
index 0000000000..8c7b476f86
--- /dev/null
+++ b/src/glsr/src/templates/admin/Script_Controls.tpl
@@ -0,0 +1,53 @@
+ <form name="script_control_form" method="GET" action="index.py">
+ <input type="hidden" name="page" value="script">
+
+ {IF MESSAGE != ""}
+ <font class="message">{MESSAGE}</font><br /><br />
+ {!IF}
+
+ <table width="90%" class="standard_table">
+ <tr>
+ <td class="header">Script Management Controls</td>
+ <td class="header" align="right" valign="middle"></td>
+ </tr>
+ <tr>
+ <td colspan="2" height="40" valign="center" class="standard_cell">
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+
+ <td height="40" valign="center" class="" nowrap>&nbsp;&nbsp;
+ {IF TOTAL_SCRIPTS == 0}
+ <input type="submit" class="button" name="list_all_scripts" value="List All Scripts" />
+ {ELSE}
+ <input type="submit" class="button" name="" value="Hide Script List" />
+ {!IF}
+ </td>
+
+ <td height="40" valign="center" class="" nowrap>&nbsp;&nbsp;
+ <input type="submit" class="button" name="open_search_page" value="Search Scripts" />
+ </td>
+
+ <td height="40" valign="center" class="" nowrap>&nbsp;&nbsp;
+ <input type="submit" class="button" name="show_all_categories" value="Modify Categories" />
+ </td>
+
+ <td height="40" valign="center" class="" nowrap>&nbsp;&nbsp;
+ <input type="submit" class="button" name="show_add_new_cat" value="Add Category" />
+ </td>
+
+ <td height="40" valign="center" class="" nowrap>&nbsp;&nbsp;
+ <input type="submit" class="button" name="show_all_languages" value="Modify Languages" />
+ </td>
+
+ <td height="40" valign="center" class="" nowrap>&nbsp;&nbsp;
+ <input type="submit" class="button" name="show_add_new_lang" value="Add Language" />
+ </td>
+
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ <br />
+
+ </form>
diff --git a/src/glsr/src/templates/admin/Script_Results.tpl b/src/glsr/src/templates/admin/Script_Results.tpl
new file mode 100644
index 0000000000..1065029235
--- /dev/null
+++ b/src/glsr/src/templates/admin/Script_Results.tpl
@@ -0,0 +1,41 @@
+
+
+ {IF WARN_MESSAGE == 1}
+ <font class="warn_message">No Scripts Found With Those Search Terms</font><br /><br />
+ {!IF}
+
+ {IF TOTAL_SCRIPTS > 0}
+ <!-- Listing of all users in the system -->
+ <table width="90%" class="standard_table">
+ <tr>
+ <td colspan="9" class="header">User Listing</td>
+ </tr>
+
+ <tr>
+ <td class="sub_header">Name</td>
+ <td class="sub_header">Version</td>
+ <td class="sub_header">Submitter</td>
+ <td class="sub_header">Category</td>
+ <td class="sub_header">Rank</td>
+ <td class="sub_header">Language</td>
+ <td class="sub_header">Date</td>
+ <td class="sub_header">Approved By</td>
+ <td class="sub_header">Status</td>
+ </tr>
+ {LOOP SCRIPT_LOOP}
+ <tr>
+ <td class="standard_row_{SCRIPT_LOOP.row}">{SCRIPT_LOOP.name}</a></td>
+ <td class="standard_row_{SCRIPT_LOOP.row}">{SCRIPT_LOOP.version}</td>
+ <td class="standard_row_{SCRIPT_LOOP.row}">{SCRIPT_LOOP.submitter}</td>
+ <td class="standard_row_{SCRIPT_LOOP.row}">{SCRIPT_LOOP.category}</td>
+ <td class="standard_row_{SCRIPT_LOOP.row}">{SCRIPT_LOOP.rank}</td>
+ <td class="standard_row_{SCRIPT_LOOP.row}">{SCRIPT_LOOP.language}</td>
+ <td class="standard_row_{SCRIPT_LOOP.row}">{SCRIPT_LOOP.date}</td>
+ <td class="standard_row_{SCRIPT_LOOP.row}">{SCRIPT_LOOP.approvedby}</td>
+ <td class="standard_row_{SCRIPT_LOOP.row}">{SCRIPT_LOOP.status}</td>
+
+ </tr>
+ {!LOOP}
+ </table>
+ {!IF}
+
diff --git a/src/glsr/src/templates/admin/Script_Search.tpl b/src/glsr/src/templates/admin/Script_Search.tpl
new file mode 100644
index 0000000000..4449718222
--- /dev/null
+++ b/src/glsr/src/templates/admin/Script_Search.tpl
@@ -0,0 +1,96 @@
+ <form name="script_search_form" method="GET" action="index.py">
+ <input type="hidden" name="page" value="script">
+
+ <table width="600px" class="standard_table">
+ <tr>
+ <td class="header">Script Search</td>
+ <td class="header" align="right" valign="middle">&nbsp;</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="middle" class="standard_cell">
+ <table border="0" width="550px" cellspacing="0" cellpadding="0">
+ <tr>
+ <td class="standard_cell">
+ <font class="instructional">Script Name:</font>
+ </td>
+ <td>
+ <input type="text" class="text-long" name="name" value="" />
+ </td>
+ </tr>
+ <tr>
+ <td valign="middle" class="standard_cell">
+ <font class="instructional">Description:</font>
+ </td>
+ <td>
+ <input type="text" class="text-long" name="descr" value="" />
+ </td>
+ </tr>
+ <tr>
+ <td valign="middle" class="standard_cell">
+ <font class="instructional">Submitter:</font>
+ </td>
+ <td>
+ <input type="text" class="text-long" name="submitter" value="" />
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" nowrap class="standard_cell" valign="middle">
+ <input type="checkbox" class="checkbox" name="most_recent" checked />&nbsp;&nbsp;Find only the latest versions of scripts.
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" bgcolor="#dddaec" valign="bottom"><hr /></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="middle" class="standard_cell">
+ <table border="0" width="550px" cellspacing="0" cellpadding="0">
+ <tr>
+ <td colspan="2" class="standard_cell"><font class="instructional">Language:</font></td>
+ <td class="standard_cell"><font class="instructional">Category:</font></td>
+ <td class="standard_cell"><font class="instructional">Status:</font></td>
+ </tr>
+ <tr>
+ <td nowrap class="standard_cell" width="1%" valign="top">
+ <input type="checkbox" class="checkbox" name="lang_perl" />Perl <br />
+ <input type="checkbox" class="checkbox" name="lang_python" />Python <br />
+ <input type="checkbox" class="checkbox" name="lang_ruby" />Ruby <br />
+ <input type="checkbox" class="checkbox" name="lang_php" />PHP <br />
+ <input type="checkbox" class="checkbox" name="lang_javascript" />Java Script <br />
+ </td>
+ <td nowrap class="standard_cell" valign="top">
+ <input type="checkbox" class="checkbox" name="lang_bash" />Bash <br />
+ <input type="checkbox" class="checkbox" name="lang_java" />Java <br />
+ <input type="checkbox" class="checkbox" name="lang_c" />C/C++ <br />
+ <input type="checkbox" class="checkbox" name="lang_html" />HTML <br />
+ <input type="checkbox" class="checkbox" name="lang_other" />Other <br />
+ </td>
+
+ <td nowrap class="standard_cell" valign="top">
+ <input type="checkbox" class="checkbox" name="cat_portage" />Portage <br />
+ <input type="checkbox" class="checkbox" name="cat_networking" />Networking <br />
+ <input type="checkbox" class="checkbox" name="cat_laptop" />Laptops <br />
+ <input type="checkbox" class="checkbox" name="cat_web" />Web <br />
+ <input type="checkbox" class="checkbox" name="cat_other" />Other <br />
+ </td>
+ <td nowrap class="standard_cell" valign="top">
+ <input type="checkbox" class="checkbox" name="stat_approved" />Approved <br />
+ <input type="checkbox" class="checkbox" name="stat_pending" />Pending <br />
+ <input type="checkbox" class="checkbox" name="stat_rejected" />Rejected <br />
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" bgcolor="#dddaec" valign="bottom"><hr /></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="standard_cell">
+ <input type="submit" class="button" name="script_search" value="Search" /></td>
+ </tr>
+ </table>
+
+ </form>
diff --git a/src/glsr/src/templates/admin/User.tpl b/src/glsr/src/templates/admin/User.tpl
new file mode 100644
index 0000000000..139597f9cb
--- /dev/null
+++ b/src/glsr/src/templates/admin/User.tpl
@@ -0,0 +1,2 @@
+
+
diff --git a/src/glsr/src/templates/admin/User_Controls.tpl b/src/glsr/src/templates/admin/User_Controls.tpl
new file mode 100644
index 0000000000..5cd427f46d
--- /dev/null
+++ b/src/glsr/src/templates/admin/User_Controls.tpl
@@ -0,0 +1,132 @@
+ <form name="user_control_form" method="GET" action="index.py">
+ <input type="hidden" name="page" value="user">
+
+ {IF MESSAGE != ""}
+ <font class="message">{MESSAGE}</font><br /><br />
+ {!IF}
+
+ <table width="90%" class="standard_table">
+ <tr>
+ <td class="header">User Management Controls</td>
+ <td class="header" align="right" valign="middle"><img src="{GLSR_URL}images/people.png" width="48" height="48" /></td>
+ </tr>
+ <tr>
+ <td colspan="2" height="40" valign="middle" class="standard_cell">
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+
+ <td height="40" valign="center" class="">&nbsp;&nbsp;
+ {IF TOTAL_USERS == 0}
+ <input type="submit" class="button" name="show_all_users" value="List All Users" />
+ {ELSE}
+ <input type="submit" class="button" name="" value="Hide User List" />
+ {!IF}
+ </td>
+
+ <td height="40" valign="center" class="">&nbsp;&nbsp;
+ <input type="submit" class="button" name="show_add_new_user" value="Add New User" />
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ <br />
+
+ {IF WARN_MESSAGE != ""}
+ <font class="warn_message">{WARN_MESSAGE}</font><br /><br />
+ {!IF}
+
+ {IF TOTAL_USERS > 0}
+ <!-- Listing of all users in the system -->
+ <table width="90%" class="standard_table">
+ <tr>
+ <td colspan="9" class="header">User Listing</td>
+ </tr>
+
+ <tr>
+ <td class="sub_header">Alias</td>
+ <td class="sub_header">Full Name</td>
+ <td class="sub_header">Email Address</td>
+ <td class="sub_header">Type</td>
+ <td class="sub_header">Rank</td>
+ <td class="sub_header">Joined</td>
+ <td class="sub_header">Last IP</td>
+ <td class="sub_header" align="center">Delete</td>
+ </tr>
+ {LOOP USER_LOOP}
+ <tr>
+ <td class="standard_row_{USER_LOOP.row}"><a href="index.py?page=user&show_modify_user={USER_LOOP.user_id}">{USER_LOOP.user_alias}</a></td>
+ <td class="standard_row_{USER_LOOP.row}">{USER_LOOP.user_fullname}</td>
+ <td class="standard_row_{USER_LOOP.row}">{USER_LOOP.user_email}</td>
+ <td class="standard_row_{USER_LOOP.row}">
+{IF USER_LOOP.type == 3}Admin{!IF}{IF USER_LOOP.user_type == 1}Developer{ELSE}User{!IF}</td>
+ <td class="standard_row_{USER_LOOP.row}">{USER_LOOP.user_rank}</td>
+ <td class="standard_row_{USER_LOOP.row}">{USER_LOOP.user_joined}</td>
+ <td class="standard_row_{USER_LOOP.row}">{USER_LOOP.user_lastip}</td>
+ <td class="standard_row_{USER_LOOP.row}" align="center"><input type="checkbox" name="delete" value="{USER_LOOP.user_id}" /></td>
+ </tr>
+ {!LOOP}
+ <tr>
+ <td class="standard_cell" colspan="9" align="right"><input type="submit" class="button" name="delete_users" value="Delete" />&nbsp;&nbsp;</td>
+ </tr>
+ </table>
+ {!IF}
+
+ {IF MODIFY_USER != 0}
+ <!-- The form to add a new user or modify an existing one -->
+ <input type="hidden" name="uid" value="{MODIFY_USER}" />
+ <table width="45%" class="standard_table">
+ <tr>
+ <td colspan="" class="header">{IF ADD_USER_FORM == 1}Add New User{ELSE}Modify User{!IF}</td>
+ </tr>
+
+ <tr>
+ <td class="standard_cell">
+ <font class="instructional">Alias:</font><br />
+ <input type="text" class="text" name="alias" value="{ALIAS}" maxlength="25" />
+ </td>
+ </tr>
+ <tr>
+ <td class="standard_cell">
+ <font class="instructional">Full Name:</font><br />
+ <input type="text" class="text" name="fullname" value="{FULLNAME}" maxlength="40" />
+ </td>
+ </tr>
+ <tr>
+ <td class="standard_cell">
+ <font class="instructional">Email:</font><br />
+ <input type="text" class="text" name="email" value="{EMAIL}" maxlength="50" />
+ </td>
+ </tr>
+ <tr>
+ <td class="standard_cell">
+ <font class="instructional">Type:</font><br />
+ <select name="type" class="dropdown">
+ <option value="0">User</option>
+ <option value="1" {IF TYPE == 1}selected{!IF}>Developer</option>
+ <option value="3" {IF TYPE == 3}selected{!IF}>Administrator</option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td class="standard_cell">
+ <font class="instructional">Password:</font><br />
+ <input type="password" class="text" name="password1" maxlength="32" />
+ </td>
+ </tr>
+ <tr>
+ <td class="standard_cell">
+ <font class="instructional">Password Confirm:</font><br />
+ <input type="password" class="text" name="password2" maxlength="32" />
+ </td>
+ </tr>
+ <tr>
+ <td class="standard_cell">
+ <input type="submit" class="button" name="{IF ADD_USER_FORM == 1}add_new_user{ELSE}modify_user{!IF}" value="Save"/>
+ </td>
+ </tr>
+ </table>
+ {!IF}
+
+ </form>
diff --git a/src/glsr/src/templates/test.tpl b/src/glsr/src/templates/test.tpl
new file mode 100644
index 0000000000..5902035d23
--- /dev/null
+++ b/src/glsr/src/templates/test.tpl
@@ -0,0 +1,15 @@
+<html>
+<head>
+</head>
+<body>
+<a href="{LINK_URI}">{LINK_TEXT}</a>
+<ul>
+{LOOP MYLOOP}
+<il> {MYLOOP}
+{!LOOP}
+</ul>
+{IF RANK == "Admin"}
+<font color="#000000">You're an Admin!</font>
+{!IF}
+</body>
+</html>