diff options
author | 2004-06-04 06:38:44 +0000 | |
---|---|---|
committer | 2004-06-04 06:38:44 +0000 | |
commit | 5a270d700934ca5ea31afee1018d7885ce1b018b (patch) | |
tree | 490abf233a409839c564a8c2b7cc9db9596d663e | |
parent | (no commit message) (diff) | |
download | gentoo-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
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 Binary files differnew file mode 100644 index 0000000000..51af152945 --- /dev/null +++ b/src/glsr/src/htdocs/images/4star.png diff --git a/src/glsr/src/htdocs/images/PythonPoweredSmall.gif b/src/glsr/src/htdocs/images/PythonPoweredSmall.gif Binary files differnew file mode 100644 index 0000000000..268980706a --- /dev/null +++ b/src/glsr/src/htdocs/images/PythonPoweredSmall.gif diff --git a/src/glsr/src/htdocs/images/dialog-info.png b/src/glsr/src/htdocs/images/dialog-info.png Binary files differnew file mode 100644 index 0000000000..502f53d4bd --- /dev/null +++ b/src/glsr/src/htdocs/images/dialog-info.png diff --git a/src/glsr/src/htdocs/images/favicon.ico b/src/glsr/src/htdocs/images/favicon.ico Binary files differnew file mode 100644 index 0000000000..e26ba8856c --- /dev/null +++ b/src/glsr/src/htdocs/images/favicon.ico diff --git a/src/glsr/src/htdocs/images/glogo.png b/src/glsr/src/htdocs/images/glogo.png Binary files differnew file mode 100644 index 0000000000..5dda23de73 --- /dev/null +++ b/src/glsr/src/htdocs/images/glogo.png diff --git a/src/glsr/src/htdocs/images/header-bk.png b/src/glsr/src/htdocs/images/header-bk.png Binary files differnew file mode 100644 index 0000000000..ec848ff6ad --- /dev/null +++ b/src/glsr/src/htdocs/images/header-bk.png diff --git a/src/glsr/src/htdocs/images/news.png b/src/glsr/src/htdocs/images/news.png Binary files differnew file mode 100644 index 0000000000..dbdb2fc457 --- /dev/null +++ b/src/glsr/src/htdocs/images/news.png diff --git a/src/glsr/src/htdocs/images/people.png b/src/glsr/src/htdocs/images/people.png Binary files differnew file mode 100644 index 0000000000..95699ebd9f --- /dev/null +++ b/src/glsr/src/htdocs/images/people.png diff --git a/src/glsr/src/htdocs/images/splogo-beta.png b/src/glsr/src/htdocs/images/splogo-beta.png Binary files differnew file mode 100644 index 0000000000..c8c3f2718f --- /dev/null +++ b/src/glsr/src/htdocs/images/splogo-beta.png diff --git a/src/glsr/src/htdocs/images/splogo.png b/src/glsr/src/htdocs/images/splogo.png Binary files differnew file mode 100644 index 0000000000..6049662092 --- /dev/null +++ b/src/glsr/src/htdocs/images/splogo.png diff --git a/src/glsr/src/htdocs/images/star.png b/src/glsr/src/htdocs/images/star.png Binary files differnew file mode 100644 index 0000000000..d66bfd7b02 --- /dev/null +++ b/src/glsr/src/htdocs/images/star.png diff --git a/src/glsr/src/htdocs/images/stock_notes.png b/src/glsr/src/htdocs/images/stock_notes.png Binary files differnew file mode 100644 index 0000000000..0221d59e5d --- /dev/null +++ b/src/glsr/src/htdocs/images/stock_notes.png 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 @@ + + </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" /> </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" /> </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"> 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"> Total Users: {USER_COUNT}</td><td height="30" class="stats_row_1"> Total Sessions: {SESSION_COUNT}</td> + </tr> + <tr> + <td height="30" class="stats_row_2" style="border-right: 1px solid black"> Total Parent Scripts: {SCRIPT_COUNT}</td><td height="30" class="stats_row_2"> Total Sub-Scripts: {SUBSCRIPT_COUNT}</td> + </tr> + <tr> + <td height="30" class="stats_row_3" style="border-right: 1px solid black"> Total Categories: {CATEGORY_COUNT}</td><td height="30" class="stats_row_3"> Total Comments: {COMMENT_COUNT}</td> + </tr> + <tr> + <td height="30" class="stats_row_4" style="border-right: 1px solid black"> Database Size: {DBSIZE} (bytes)</td><td height="30" class="stats_row_4_1"> 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"> <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> 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"> <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> {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=""> + {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=""> + <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" /> </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> + {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> + <input type="submit" class="button" name="open_search_page" value="Search Scripts" /> + </td> + + <td height="40" valign="center" class="" nowrap> + <input type="submit" class="button" name="show_all_categories" value="Modify Categories" /> + </td> + + <td height="40" valign="center" class="" nowrap> + <input type="submit" class="button" name="show_add_new_cat" value="Add Category" /> + </td> + + <td height="40" valign="center" class="" nowrap> + <input type="submit" class="button" name="show_all_languages" value="Modify Languages" /> + </td> + + <td height="40" valign="center" class="" nowrap> + <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"> </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 /> 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=""> + {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=""> + <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" /> </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> |