def action(req, fields): global MaxNewsItems req.write(InstDB.header("Menu")) box = InstDB.html_box() req.write(box.start("About")) req.write(InstDB.IncFile("about.inc")) req.write(box.end()) req.write("<p>\n") InstDB.Cur.execute( """\ SELECT DATE_FORMAT(N.Date,'%%a, %%Y-%%m-%%d %%H:%%i:%%s') AS Date, N.UserId, U.UserName, N.Title, N.Content FROM News AS N, Users AS U WHERE N.UserId=U.UserId ORDER BY N.Date DESC LIMIT %s""", MaxNewsItems) for entry in InstDB.Cur.fetchall(): req.write("""\ <p> <font class=newstitle>%s</font><br> <table width="100%%" border=0 cellpadding=4 cellspacing=0><tr class=lightbg><td> Submitted by <a href="patches.py?Action=User&UserId=%s">%s</a> on %s <p> %s </td></tr></table> """ % (entry["Title"], entry["UserId"], entry["UserName"], entry["Date"], entry["Content"])) req.write(InstDB.footer())
def action (req, fields): req.write (InstDB.header ("Initialize database")) if InstDB.Cur.execute ("SHOW tables") == 0: for fname in os.listdir (InstDB.BasePath + os.sep + "sql"): if fname[-4:] != ".sql": continue req.write ("Executing SQL in '%s'<br>\n" % fname) f = open (InstDB.BasePath + os.sep + "sql" + os.sep + fname, "r") sql = f.read () # Split text file into individual queries for query in string.split (sql, ';')[:-1]: InstDB.Cur.execute (query) # Import categories file f = open (InstDB.BasePath + os.sep + "sql" + os.sep + "categories.txt", "r") for line in f.readlines(): fields = string.split (line, "\t") InstDB.Cur.execute ("INSERT INTO Category (CategoryName, CategoryDescr)" " VALUES (%s, %s)", (fields[0], fields[1])) # Import licenses file f = open (InstDB.BasePath + os.sep + "sql" + os.sep + "licenses.txt", "r") for line in f.readlines(): fields = string.split (line, "\t") InstDB.Cur.execute ("INSERT INTO Licenses (LicenseName, LicenseDescr," " LicenseURL) VALUES (%s, %s, %s)", (fields[0], fields[1], fields[2])) else: req.write ("Database already contains tables, nothing done") req.write (InstDB.footer ())
def action(req, fields): req.write(InstDB.header("Software/Credits")) box = InstDB.html_box() req.write(box.start("Software/Credits")) req.write(InstDB.IncFile("software.inc")) req.write(box.end()) req.write(InstDB.footer())
def action(req, fields): Type = fields.get("Type", "Patch") if Type == "Inst": s = "Instruments" elif Type == "Sample": s = "Samples" else: s = "Patch Files" req.write(InstDB.header("List " + s)) if Type == "Inst": list_insts(req, fields) elif Type == "Sample": list_samples(req, fields) else: list_patches(req, fields) req.write(InstDB.footer())
def html_val(self, field, data): if self.fieldinfo.get(field, None): pass elif PatchHelper.fieldinfo.get(field, None): return PatchHelper.html_val(field, data) else: return None if field == "FormatStr": format = "%.1fkHz" % (int(data["SampleRate"]) / 1000.0) chan = int(data["Channels"]) if chan == 1: format += " Mono" elif chan == 2: format += " Stereo" else: format += " %d-channel" % chan format += " " + data["Format"] return format elif field == "SampleNameLink": return "<a href=\"patches.py?Action=item&ItemId=%d\">%s</a>" \ % (data["SampleId"], cgi.escape (data["SampleName"])) elif field == "SampleSize": return InstDB.pretty_size(data["SampleSize"]) else: return ItemHelper.html_val(self, field, data)
def html_val(self, field, data): if not self.fieldinfo.get(field, None): return None if field == "PropValue": return cgi.escape(InstDB.emailmunge(data["PropValue"])) else: return ItemHelper.html_val(self, field, data)
def init(req): InstDB.Req = req InstDB.Fields = util.FieldStorage(req) InstDB.connect() InstDB.User = None InstDB.Sess = Session.Session(req) if InstDB.Sess.is_new(): login = InstDB.Fields.get("Username", None) passwd = InstDB.Fields.get("Pass", None) if login and passwd: # lookup user by login name and password InstDB.Cur.execute( "SELECT * FROM Users WHERE Login=%s" " && Password=SHA1(%s)" " && !FIND_IN_SET('NoLogin', Flags)" " && !FIND_IN_SET('Confirm', Flags)", (login, passwd + InstDB.FuKraXor)) InstDB.User = InstDB.Cur.fetchone() if InstDB.User: InstDB.Cur.execute("UPDATE Users SET LastLogin=NULL" " WHERE UserId=%s" % InstDB.User["UserId"]) InstDB.Sess["UserId"] = InstDB.User["UserId"] InstDB.Sess.set_timeout(InstDB.SessTimeout) InstDB.Sess.save() InstDB.LoginError = "" else: InstDB.LoginError = "Invalid login" if not InstDB.Sess.has_key("UserId"): InstDB.Sess["UserId"] = 0 else: # Sess is not new InstDB.Sess.load() # Load session values InstDB.Cur.execute( "SELECT * FROM Users WHERE UserId=%s" " && !FIND_IN_SET('NoLogin', Flags)", (InstDB.Sess["UserId"], )) InstDB.User = InstDB.Cur.fetchone() if InstDB.User: del InstDB.User["Password"] # no need to keep it around InstDB.LoginError = "" else: InstDB.Sess["UserId"] = 0 InstDB.Sess.delete()
def query_matches(query, matches, matchstr): left = max_sub_matches - len(matches) if left <= 0: return matches count = InstDB.Cur.execute(query) if count == 0: return matches if count > left: count = left for i in range(0, count): row = InstDB.Cur.fetchone() matches += ((cgi.escape(row['type']), cgi.escape(row['name']), mark_match(InstDB.emailmunge(row['value']), matchstr)), ) return matches
def add_extra_props(req, props): tab = () if props: tab += (('<center>Additional Properties</center>', ), ) # Add all the properties to a hash propvals = {} for prop in props: propvals[string.capitalize (prop["PropName"])] \ = cgi.escape (InstDB.emailmunge (prop["PropValue"])) # Sort the property name keys sortkeys = propvals.keys() sortkeys.sort() # Add all the properties to the table for key in sortkeys: tab += ((key, propvals[key]), ) return tab
def action(req, fields): id = int(fields.get("ItemId", 0)) req.write(InstDB.header("Patch file details")) InstDB.Cur.execute("SELECT State,UserId FROM PatchInfo WHERE PatchId=%s", id) row = InstDB.Cur.fetchone() if not row: InstDB.error(req, "Patch file with ID '%d' not found" % id) req.write(InstDB.footer()) return # See if we are allowed to view this patch if row["State"] != "Active" \ and (not InstDB.User or not (row["UserId"] == InstDB.User["UserId"] or "Admin" in InstDB.User["Flags"])): InstDB.error(req, "You don't have permission to view that info") req.write(InstDB.footer()) return show_patch_item(id, fields, req) req.write(InstDB.footer())
def action (req, fields): topic = fields.get ("Topic", None) mini = fields.get ("Mini", '0') if mini != '0': mini = True else: mini = False title = topic_titles.get (topic, "Help") req.write (InstDB.header (title, mini)) if not topic_titles.get (topic, None): InstDB.error (req, "Help topic not found!") req.write (InstDB.footer (mini)) return box = InstDB.html_box () req.write (box.start (title)) req.write (InstDB.IncFile ("%s.inc" % topic)) req.write (box.end ()) req.write (InstDB.footer (mini))
def edit_patch_item(id, fields, req): itemCells = PatchHelper.edit_cell_format itemFields = InstDB.cells_to_fields(itemCells) InstDB.Cur.execute("SELECT PropId, PropName FROM Props ORDER BY PropName") propnames = InstDB.Cur.fetchall() # Was Save button clicked? - Save field values if fields.get("Save", None): update = PatchHelper.sql_update(itemFields, fields) update.where = ("PatchId=%d" % id, ) InstDB.Cur.execute(update.query()) props_update(id, fields) sel = PatchHelper.sql_select(itemFields) sel.where.insert(0, "PatchInfo.PatchId=%d" % id) InstDB.Cur.execute(sel.query()) row = InstDB.Cur.fetchone() if not row: # Shouldn't happen, thats why we raise an exception raise LookupError, "Patch file with ID '%d' not found" % id sel = props_select(id) InstDB.Cur.execute(sel.query()) props = InstDB.Cur.fetchall() # Get count of Instruments in this patch InstDB.Cur.execute("SELECT COUNT(*) AS Count FROM InstInfo" " WHERE PatchId=%s" % id) instcount = InstDB.Cur.fetchone()["Count"] # Get count of samples in this patch InstDB.Cur.execute("SELECT COUNT(*) AS Count FROM SampleInfo" " WHERE PatchId=%s" % id) samplecount = InstDB.Cur.fetchone()["Count"] tab = PatchHelper.form_cell_vals(itemCells, row) if instcount > 0: trow = ('<a href="patches.py?Action=list&Type=Inst&PatchId=%s' '&OrderBy=Bank">Instruments</a>' % id, instcount) else: trow = ("Instruments", "None") if samplecount > 0: trow += ( '<a href="patches.py?Action=list&Type=Sample&PatchId=%s' '&OrderBy=SampleNameLink">Samples</a>' % id, samplecount) else: trow += ("Samples", "None") tab += ((trow, )) tab += props_form_cells(props) req.write('<form action="" method=POST>\n') # Display patch item edit form box = InstDB.html_box() box.titlehtml = '\n <a href="patches.py?Action=item&ItemId=%d">' \ '<img src="images/view.png" alt="View Mode" width=15 height=15 border=0>' \ ' <font class="boxtitle">View</font></a>\n' % id # Show edit icon req.write(box.start("Patch File")) split = InstDB.tabsplits(tab) req.write(split.render()) req.write("<center><input type=submit name=Save value=\"Save\">" "</center>\n") req.write(box.end()) req.write("</form>\n<p>\n")
def action(req, fields): req.write(InstDB.header("Reset password")) login = fields.get("Login", None) email = fields.get("Email", None) if login or email: if login: InstDB.Cur.execute( "SELECT UserId, Login, UserEmail FROM Users" " WHERE Login=%s", login) else: InstDB.Cur.execute( "SELECT UserId, Login, UserEmail FROM Users" " WHERE UserEmail=%s", email) row = InstDB.Cur.fetchone() if not row: InstDB.error(req, "Sorry, no account matches the given input.") req.write(InstDB.footer()) return userid = row["UserId"] emailaddr = row["UserEmail"] login = row["Login"] InstDB.Cur.execute( "SELECT COUNT(*) AS count FROM Confirm" " WHERE UserId=%s && ConfirmAction='ResetPass'", userid) if InstDB.Cur.fetchone()["count"]: InstDB.error(req, "Password reset confirmation already sent.") req.write( '<p>\nIf you do not receive it soon, feel free to' ' email the <a href="mailto:[email protected]">admin</a>' ', or wait a day for this confirmation to expire.') req.write(InstDB.footer()) return confirm.new('ResetPass', userid, login) req.write('<font class="title">An email will be sent soon' ' to the email address you registered with, containing' ' directions on how to reset your password.</font>\n') req.write(InstDB.footer()) return box = InstDB.html_box() req.write(box.start("Reset password")) req.write(""" <form action="patches.py?Action=resetpass" method=post> <table border=0 cellpadding=8> <tr> <td align="center" bgcolor="#4070b0"> <b>Login</b><input type=text name=Login size=16><br> or<br> <b>Email</b><input type=text name=Email size=16> <p> <input type=submit value="Reset password"> <p> </td> <td> Enter your account login <b>OR</b> email address. A confirmation email will be sent to your registered email address with directions for resetting your password. </td> </tr> </table> </form> """) req.write(box.end()) req.write(InstDB.footer())
def action(req, fields): id = int(fields["ItemId"]) req.write(InstDB.header("Edit patch file details")) InstDB.Cur.execute("SELECT UserId FROM PatchInfo WHERE PatchId=%s", id) row = InstDB.Cur.fetchone() if not row: InstDB.error(req, "Patch file with ID '%d' not found" % id) req.write(InstDB.footer()) return # Do some security checks if not InstDB.User: InstDB.error(req, "Must login to edit patch information") req.write(InstDB.footer()) return if not "Admin" in InstDB.User["Flags"] \ and row["UserId"] != InstDB.User["UserId"]: InstDB.error(req, "You don't have permission to edit that info") req.write(InstDB.footer()) return edit_patch_item(id, fields, req) req.write(InstDB.footer())
def html_val(self, field, data): global StarWidths if field == "Author": if "Author" in data["PatchFlags"]: return cgi.escape(InstDB.emailmunge(data["UserName"])) else: return cgi.escape(InstDB.emailmunge(data["PatchAuthor"])) elif field == "CategoryName2": return self.category_name(int(data["CategoryId2"])) elif field == "CategoryName3": return self.category_name(int(data["CategoryId3"])) elif field == "CategoryLong": cats = data["CategoryName"] if data["CategoryId"] != 1: s = self.category_name(int(data["CategoryId2"])) if s: cats = cats + ", " + s s = self.category_name(int(data["CategoryId3"])) if s: cats = cats + ", " + s return cats elif field == "CramSize": return InstDB.pretty_size(data["CramSize"]) elif field == "CramSizeDetail": return InstDB.pretty_size (data["CramSize"]) \ + " (%d)" % data["CramSize"] elif field == "DownloadLink": return "<a href=\"download.py?PatchId=%d&Type=zip\">" \ "<img src=\"images/dnld.png\" alt=\"Download\" width=14 height=14 border=0>" \ "</a> (%d)" % (data["PatchId"], data["DownloadClicks"]) elif field == "Email": return cgi.escape(InstDB.emailmunge(data["Email"])) elif field == "FileName": return cgi.escape(data["FileName"]) + "." + data["PatchType"] elif field == "FileNameLink": return '<a href="patches.py?Action=item&ItemId=%d">%s.%s</a>' \ % (data["PatchId"], cgi.escape (data["FileName"]), data["PatchType"]) elif field == "FileSize": return InstDB.pretty_size(data["FileSize"]) elif field == "LicenseLink": if data["LicenseURL"]: return '<a href="%s">%s</a>' % (data["LicenseURL"], data["LicenseName"]) else: return data["LicenseName"] elif field == "Rating": if data["RateCount"] > 0: f = float(data["RatingValue"]) if f < 0.5: f = 0.5 elif f > 5.0: f = 5.0 fract = f - int(f) if fract < 0.5: ifract = 0 else: ifract = 5 width = StarWidths[int(f) * 2 + ifract / 5 - 1] return ( '<img src="images/stars_%d_%d.png" alt="%0.1f stars" width=%d height=11>' '(%d)' % (int(f), ifract, f, width, data["RateCount"])) else: return "None" elif field == "UserFileSize": return InstDB.pretty_size(data["FileSize"]) elif field == "UserLink": return "<a href=\"patches.py?Action=user&UserId=%d\">%s</a>" \ % (data["UserId"], cgi.escape (data["UserName"])) elif field == "ZipSize": return InstDB.pretty_size(data["ZipSize"]) elif field == "ZipSizeDetail": return InstDB.pretty_size (data["ZipSize"]) \ + " (%d)" % data["ZipSize"] elif field == "WebSiteLink": escurl = cgi.escape(data["WebSite"]) return '<a href="%s">%s</a>' % (escurl, escurl) else: return ItemHelper.html_val(self, field, data)
def action(req, fields): req.write(InstDB.header("Patch submission")) if not InstDB.AssertLogin(req): req.write(InstDB.footer()) return req.write(""" Upload files to <a href="ftp://sounds.resonance.org/incoming/">ftp://sounds.resonance.org/incoming/</a>. It is recommended that you read the <a href="patches.py?Action=help&Topic=submit">Content Submission Help</a>. <p> """) # Check if any incoming files have been selected Files = fields.getlist("Files") for fname in Files: (evil, fname) = os.path.split(fname) # Make sure no path of evil if not os.path.isfile(InstDB.IncomingPath + os.sep + fname): InstDB.error(req, "File not found '%s'" % cgi.escape(fname)) else: # Create new import queue task (don't activate yet) InstDB.Cur.execute( "INSERT INTO Queue" " (Type, Status, FileName, UserId)" " VALUES ('Import', 'Queued', %s, %s)", (fname, InstDB.User["UserId"])) # Get list of files in incoming directory file_list = os.listdir(InstDB.IncomingPath) file_list.sort() box = InstDB.html_box() box.tableattr = 'width="100%"' req.write(box.start("Incoming files")) req.write("<form action=\"patches.py?Action=submit\" method=POST>\n") if file_list: table = InstDB.tabular(("Import", "File", "Size", "Date")) table.tableattr = 'width="100%"' for file in file_list: check = "<input type=checkbox name=Files value=\"%s\">" \ % cgi.escape (file) stats = os.stat(InstDB.IncomingPath + "/" + file) req.write( table.addrow((check, cgi.escape(file), InstDB.pretty_size(stats.st_size), time.ctime(stats.st_mtime)))) req.write(table.end()) else: req.write("<b>No files in incoming directory</b><br>\n") req.write(box.end()) req.write("<center><input type=submit name=FileSelect" " value=\"Import and/or Refresh\"></center>\n") req.write("</form>\n") req.write("<p><p>\n") # Get queued tasks box = InstDB.html_box() box.tableattr = 'width="100%"' req.write(box.start("Your queued tasks")) sel = SqlHelpers.Select() sel.fields = ("QueueId", "Type", "Status", "UserId", "FileName", "Date") sel.tables = ("Queue", ) sel.where = ("Type in ('Import','Activate')", ) sel.orderby = "QueueId" InstDB.Cur.execute(sel.query()) table = InstDB.tabular( ("Position", "File Name", "Action", "Status", "Start Time")) table.tableattr = 'width="100%"' index = 0 any = False for row in InstDB.Cur.fetchall(): if row["UserId"] == InstDB.User["UserId"]: any = True if row["Status"] != "Error": ndxval = index status = row["Status"] else: ndxval = "N/A" status = '<font class="Error">' + row["Status"] + '</font>' req.write( table.addrow((ndxval, cgi.escape(row["FileName"]), row["Type"], status, row["Date"]))) if row["Status"] != "Error": index += 1 if any: req.write(table.end()) else: req.write("<b>No queued tasks</b><br>\n") req.write(box.end()) req.write("<p><p>\n") # Any activation form data submitted? Group fields by patch ID. patchFields = {} if fields.get("Activate", None): for field in fields.list: # Fields have "P<PatchId>_" prefix match = re.match("P([0-9]{1,10})_(.+)", field.name) if match: patchId = match.group(1) if not patchFields.get(patchId, None): patchFields[patchId] = {} patchFields[patchId][match.group(2)] = fields[field.name] # Files pending activation box = InstDB.html_box() box.tableattr = 'width="100%"' req.write(box.start("Files pending activation")) InstDB.Cur.execute( "SELECT PatchId, PatchType FROM PatchInfo" " WHERE UserId=%s && State='Imported'", InstDB.User["UserId"]) pendRows = InstDB.Cur.fetchall() if pendRows: activateCells = PatchHelper.edit_cell_format activateFields = InstDB.cells_to_fields(activateCells) displayedOne = False for pendRow in pendRows: pFields = patchFields.get(str(pendRow["PatchId"]), None) patchId = int(pendRow["PatchId"]) activate = pFields and pFields.get("Activate", None) errorMsg = "" if pFields: # Form data submitted for this patch? pFields["FileName"] = pFields["FileName"].strip() if not pFields["FileName"]: errorMsg = "File name is required" # Check if filename already used if not errorMsg: InstDB.Cur.execute( "SELECT COUNT(*) AS count FROM PatchInfo" " WHERE PatchId != %s && FileName=%s" " && PatchType=%s", (patchId, pFields["FileName"], pendRow["PatchType"])) if int(InstDB.Cur.fetchone()["count"]) > 0: errorMsg = "File name already in use" if pFields: update = PatchHelper.sql_update(activateFields, pFields) update.set["FileName"] = pFields["FileName"] update.where = ("PatchInfo.PatchId=%d" % patchId, ) if activate and not errorMsg: update.set["State"] = "Activating" InstDB.Cur.execute(update.query()) props_update(patchId, pFields) # Update extra properties # Queue activation task if activate and not errorMsg: InstDB.Cur.execute( "INSERT INTO Queue" " (Type, Status, UserId, ItemId, FileName)" " VALUES ('Activate', 'Queued', %s, %s, %s)", (InstDB.User["UserId"], patchId, "%s.%s" % (pFields["FileName"], pendRow["PatchType"]))) if (not activate or errorMsg) and not displayedOne: req.write( "<form action=\"patches.py?Action=submit\" method=POST>\n") displayedOne = True if errorMsg: req.write('<font class="error">%s</font><br>\n' % cgi.escape(errorMsg)) if not activate or errorMsg: sel = PatchHelper.sql_select(activateFields) sel.fields.insert(0, "PatchInfo.PatchId") sel.where.insert(0, "PatchInfo.PatchId=%d" % patchId) InstDB.Cur.execute(sel.query()) row = InstDB.Cur.fetchone() display_patch(req, row, pFields) if displayedOne: req.write("<input type=submit name=Activate" " value=\"Update\">\n") req.write("</form>\n") else: req.write("<b>No files pending activation</b><br>\n") req.write(box.end()) req.write(InstDB.footer())
def action(req, fields): id = int(fields.get("PatchId", 0)) filetype = fields.get("Type", None) if filetype != "zip": filetype = "CRAM" itemFields = ("FileName", "PatchType", "ZipSize", "CramSize") sel = PatchHelper.sql_select(itemFields) sel.fields.append("DATEDIFF(NOW(), PatchInfo.DateImported) AS ImportDays" ) # Days since imported sel.where.insert(0, "PatchInfo.State = 'Active'") sel.where.insert(0, "PatchInfo.PatchId=%d" % id) InstDB.Cur.execute(sel.query()) PatchRow = InstDB.Cur.fetchone() if not PatchRow: req.write(InstDB.header("Download Error")) InstDB.error(req, "Instrument file with ID '%d' not found" % id) req.write(InstDB.footer()) return # For now, we just select a random mirror, unless imported less than 2 days ago, then we use default mirror if (PatchRow["ImportDays"] > 2): InstDB.Cur.execute( "SELECT MirrorId, BaseURL FROM Mirrors" " WHERE FIND_IN_SET('Active', Flags) && FIND_IN_SET(%s, Flags)" " ORDER BY RAND() LIMIT 1", filetype) else: # Just use first active mirror with file type available (usually Mirror 1, unless its inactive) InstDB.Cur.execute( "SELECT MirrorId, BaseURL FROM Mirrors WHERE" " FIND_IN_SET('Active', Flags) && FIND_IN_SET(%s, Flags)" " ORDER BY MirrorId LIMIT 1", filetype) mirror = InstDB.Cur.fetchone() if not mirror: req.write(InstDB.header("Download Error")) InstDB.error(req, "No active mirror found for requested instrument file") req.write(InstDB.footer()) return # Update PatchInfo file download count for file type and set some vars if filetype == "zip": filesize = PatchRow["ZipSize"] fileext = "zip" InstDB.Cur.execute( "UPDATE PatchInfo SET ZipClicks=ZipClicks+1" " WHERE PatchId=%s", id) else: filesize = PatchRow["CramSize"] fileext = "cram" InstDB.Cur.execute( "UPDATE PatchInfo SET CramClicks=CramClicks+1" " WHERE PatchId=%s", id) # Update Mirror download count and download size counters InstDB.Cur.execute( "UPDATE Mirrors SET DownloadClicks=DownloadClicks+1," "DownloadSize=DownloadSize+%s,DownloadTotal=DownloadTotal+%s" " WHERE MirrorId=%s", (filesize, filesize, mirror["MirrorId"])) # If user logged in, mark file as downloaded if InstDB.User: InstDB.Cur.execute( "SELECT COUNT(*) AS count FROM FileMarks" " WHERE UserId=%s && PatchId=%s", (InstDB.User['UserId'], id)) if InstDB.Cur.fetchone()["count"] == 0: InstDB.Cur.execute( "INSERT FileMarks (UserId, PatchId, MarkFlags)" " VALUES(%s,%s,'Downloaded')", (InstDB.User['UserId'], id)) else: InstDB.Cur.execute( "UPDATE FileMarks SET MarkFlags=CONCAT(MarkFlags, \",Downloaded\")," "MarkTime=Null WHERE UserId=%s && PatchId=%s", (InstDB.User['UserId'], id)) # Redirect to file to download if req.proto_num >= 1001: req.status = apache.HTTP_TEMPORARY_REDIRECT else: req.status = apache.HTTP_MOVED_TEMPORARILY # FIXME - Does redirect Location: URL need to be escaped??? req.headers_out["Location"] = "%s/%s.%s.%s" \ % (mirror["BaseURL"], PatchRow["FileName"], PatchRow["PatchType"], fileext) req.send_http_header()
def action(req, fields): req.write(InstDB.header("Edit profile")) if not InstDB.AssertLogin(req): req.write(InstDB.footer()) return itemCells = UsersHelper.edit_cell_format itemFields = InstDB.cells_to_fields(itemCells) errmsg = None # Was Save button clicked? - Update field values if fields.get("Save", None): data = fields password = fields.get("Password", "") verify = fields.get("PassVerify", "") email = fields.get("UserEmail", "") if len(password) > 0 and len(password) < 5: errmsg = "Passwords must be 5-32 characters, leave blank for no change" if not errmsg and password != verify: errmsg = "Password and Verify don't match" if not errmsg: n = string.find(email, "@") n2 = string.find(email, " ") if n <= 0 or n == len(email) - 1 or n2 >= 0: errmsg = "A valid email address is required" if not errmsg: update = UsersHelper.sql_update(itemFields, fields) if password: update.setnesc["Password"] = '******' \ % MySQLdb.escape_string (password + InstDB.FuKraXor) update.where = ("UserId=%d" % InstDB.User["UserId"], ) # Use login if UserName not set if not fields.get("UserName", None): update.setnesc["UserName"] = "******" if update.set.get("UserName"): del update.set["UserName"] InstDB.Cur.execute(update.query()) req.write("<font size=+1>User profile updated</font>\n<p>\n") else: req.write('<font class="error">%s</font><p>\n' % errmsg) else: # First page load? sel = UsersHelper.sql_select(itemFields) sel.where.insert(0, "UserId=%d" % InstDB.User["UserId"]) InstDB.Cur.execute(sel.query()) data = InstDB.Cur.fetchone() tab = (("Password", "<input type=password name=Password>"), ("Verify", "<input type=password name=PassVerify>")) tab += tuple(UsersHelper.form_cell_vals(itemCells, data)) tab += (("<input type=submit name=Save value=\"Save\">\n", ), ) # Display form box = InstDB.html_box() req.write(box.start("User Profile")) req.write( "<table border=0 cellpadding=8>\n<tr>\n<td valign=top bgcolor=#408ee6>\n" ) req.write("<form action=\"patches.py?Action=profile\" method=POST>\n") split = InstDB.tabsplits(tab) req.write(split.render()) req.write("</form>\n") req.write("</td>\n<td valign=top>\n") req.write("<vr>\n</td>\n<td valign=top>\n") req.write(InstDB.IncFile("profile.inc")) req.write("</td>\n</tr>\n</table>\n") req.write(box.end()) req.write(InstDB.footer())
def action(req, fields): req.write(InstDB.header("Registration")) itemCells = UsersHelper.edit_cell_format errmsg = None recaptcha_error = None # Was Register button clicked? - Save field values if fields.get("Register", None): data = fields login = fields.get("Login", "") password = fields.get("Password", "") verify = fields.get("PassVerify", "") email = fields.get("UserEmail", "") captcha_challenge = fields.get("recaptcha_challenge_field", "") captcha_response = fields.get("recaptcha_response_field", "") if not login: errmsg = "Login name is required" elif not verify_chars(login, InstDB.LoginAllowChars): errmsg = "Only these characters are allowed in login: '******'" \ % InstDB.LoginAllowChars elif login and InstDB.Cur.execute \ ("SELECT 1 FROM Users WHERE Login=%s", login) == 1: errmsg = "The login '%s' is already used" % (cgi.escape(login)) if not errmsg and len(password) < 5: errmsg = "A password with 5-32 characters is required" if not errmsg and password != verify: errmsg = "Password and Verify don't match" if not errmsg: n = string.find(email, "@") n2 = string.find(email, " ") if n <= 0 or n == len(email) - 1 or n2 >= 0: errmsg = "A valid email address is required" if not errmsg and not verify_chars(email, InstDB.EmailAllowChars): errmsg = "Only these characters are allowed in email address: '%s'" \ % InstDB.EmailAllowChars if not errmsg and InstDB.Cur.execute \ ("SELECT Login FROM Users WHERE UserEmail=%s", email) == 1: existLogin = InstDB.Cur.fetchone()["Login"] errmsg = "Login '%s' is already registered with that email address." \ % existLogin if not errmsg: resp = recaptcha_submit(captcha_challenge, captcha_response, InstDB.ReCaptchaPrvKey, req.connection.remote_ip) if not resp.is_valid: errmsg = "Are you human? reCAPTCHA response incorrect." recaptcha_error = resp.error_code if not errmsg: itemFields = InstDB.cells_to_fields( InstDB.delete_cells(itemCells, "UserName")) insert = UsersHelper.sql_insert(itemFields, fields) insert.set["Login"] = login insert.set["Flags"] = "Confirm" insert.setnesc["Password"] = '******' \ % MySQLdb.escape_string (password + InstDB.FuKraXor) insert.setnesc["DateCreated"] = "NULL" insert.set["LastLogin"] = 0 # Use login if UserName not set username = fields.get("UserName", None) if not username: username = login insert.set["UserName"] = username InstDB.Cur.execute(insert.query()) userid = InstDB.DB.insert_id() confirm.new("Register", userid, login) # Add new account for phpbb forums if InstDB.EnableForums: retval = phpbb.add_user(login, password, email) if retval != 0: raise RuntimeWarning, "Failed to add user '%s' to PHPBB forums (retval=%d)" % ( login, retval) req.write('<font class="title">Registration successful, an email' ' will be sent shortly with directions on activating' ' your account.</font>\n') req.write(InstDB.footer()) return else: InstDB.error(req, errmsg) req.write("<p>\n") else: data = {"UserFlags": ('EmailNews', 'NotifyMessage', 'NotifyRatings')} tab = (("Login", '<input type=text name=Login value="%s">' % cgi.escape(data.get("Login", ""))), ("Password", "<input type=password name=Password>"), ("Verify", "<input type=password name=PassVerify>")) tab += tuple(UsersHelper.form_cell_vals(itemCells, data)) tab += ((recaptcha_display(InstDB.ReCaptchaPubKey, False, recaptcha_error), ), ) tab += (('<input type=submit name=Register value="Register">\n' '<a href="patches.py?Action=help&Topic=privacy&Mini=1"' ' target="_blank">Privacy Policy</a>', ), ) # Display register form box = InstDB.html_box() req.write(box.start("User Registration")) req.write("<table border=0 cellpadding=8>\n<tr>\n<td valign=top>\n") req.write("<form action=\"patches.py?Action=register\" method=POST>\n") split = InstDB.tabsplits(tab) split.tableattr = 'bgcolor="#408ee6"' split.cellspacing = 4 req.write(split.render()) req.write("</form>\n") req.write("</td>\n<td valign=top>\n") req.write(InstDB.IncFile("register.inc")) req.write("</td>\n</tr>\n</table>\n") req.write(box.end()) req.write(InstDB.footer())
def action (req, fields): msg = fields.get ("Msg", None) if msg == "Registered": req.write (InstDB.header ("Email confirmation")) req.write (InstDB.IncFile ("activated.inc")) req.write (InstDB.footer ()) return elif msg == "Reset": req.write (InstDB.header ("Email confirmation")) req.write ('<font class="title">Password has been reset and will be' ' emailed to you shortly.</font>\n') req.write (InstDB.footer ()) return login = fields.get ("Login", None) hashkey = fields.get ("HashKey", None) if not login or not hashkey: req.write (InstDB.header ("Email confirmation")) InstDB.error (req, "Invalid confirmation data") req.write (InstDB.footer ()) return InstDB.Cur.execute ("SELECT UserId FROM Users WHERE Login=%s", login) row = InstDB.Cur.fetchone () if not row: req.write (InstDB.header ("Email confirmation")) InstDB.error (req, "Invalid confirmation data") req.write (InstDB.footer ()) return userid = row["UserId"] InstDB.Cur.execute ("SELECT ConfirmAction FROM Confirm" " WHERE UserId=%s && HashKey=%s", (userid, hashkey)) row = InstDB.Cur.fetchone () if not row: req.write (InstDB.header ("Email confirmation")) InstDB.error (req, "Email confirmation not found, perhaps it expired?") req.write (InstDB.footer ()) return if row["ConfirmAction"] == "Register": InstDB.Cur.execute ("UPDATE Users SET Flags='' WHERE UserId=%s", userid) if InstDB.EnableForums: retval = phpbb.activate_user (login) # Activate the forum account if retval != 0: raise RuntimeWarning, "Failed to activate PHPBB user '%s' (retval=%d)" % (login, retval) # Redirect to confirm page with Msg=Registered parameter if req.proto_num >= 1001: req.status = apache.HTTP_TEMPORARY_REDIRECT else: req.status = apache.HTTP_MOVED_TEMPORARILY req.headers_out["Location"] = "patches.py?Action=confirm&Msg=Registered" req.send_http_header() elif row["ConfirmAction"] == "ResetPass": newpass = "" for i in range (0, 8): newpass += random.choice ("ABCDEFGHIJKLMNPQRSTUVWXYZ" "abcdefghjkmnpqrstuvwxyz23456789") InstDB.Cur.execute ("UPDATE Users SET Password=SHA1(%s)" " WHERE UserId=%s", (newpass + InstDB.FuKraXor, userid)) f = open (InstDB.IncludePath + os.sep + "newpass.msg") email = f.read () % { "Login" : login, "Password" : newpass } # Queue email task InstDB.Cur.execute ("INSERT INTO Queue (Type, Status, UserId, Content)" " VALUES ('Email', 'Queued', %s, %s)", (userid, email)) # Redirect to confirm page with Msg=Reset parameter if req.proto_num >= 1001: req.status = apache.HTTP_TEMPORARY_REDIRECT else: req.status = apache.HTTP_MOVED_TEMPORARILY req.headers_out["Location"] = "patches.py?Action=confirm&Msg=Reset" req.send_http_header() # Remove the confirmation, we done with it InstDB.Cur.execute ("DELETE FROM Confirm WHERE UserId=%s && HashKey=%s", (userid, hashkey))
def display_patch(req, row, fields): itemCells = InstDB.delete_cells(PatchHelper.edit_cell_format, "FileName") prefix = "P%d_" % row["PatchId"] # Prefix field names with patch ID tab = [["Activate", "<input type=checkbox name=%sActivate>" % prefix], [ "File Name", '<input type=text name=%sFileName value="%s" size=48>' '.%s' % (prefix, row["FileName"], row["PatchType"]) ]] tab += PatchHelper.form_cell_vals(itemCells, row, prefix) patchid = row["PatchId"] # Get patch property values sel = props_select(patchid) InstDB.Cur.execute(sel.query()) props = InstDB.Cur.fetchall() # Get count of Instruments in this patch InstDB.Cur.execute( "SELECT COUNT(*) AS Count FROM InstInfo" " WHERE PatchId=%s", patchid) instcount = InstDB.Cur.fetchone()["Count"] # Get count of samples in this patch InstDB.Cur.execute( "SELECT COUNT(*) AS Count FROM SampleInfo" " WHERE PatchId=%s", patchid) samplecount = InstDB.Cur.fetchone()["Count"] if instcount > 0: trow = ('<a href="patches.py?Action=list&Type=Inst&PatchId=%s' '&OrderBy=Bank">Instruments</a>' % patchid, instcount) else: trow = ("Instruments", "None") if samplecount > 0: trow += ( '<a href="patches.py?Action=list&Type=Sample&PatchId=%s' '&OrderBy=Name">Samples</a>' % patchid, samplecount) else: trow += ("Samples", "None") tab += ((trow, )) tab += props_form_cells(props, prefix) # Get list of extracted files patchFilePath = InstDB.ActivatePath + os.sep + str( row["PatchId"]) + "-files" file_list = os.listdir(patchFilePath) file_list.sort() table = InstDB.tabular(("File name", "Size")) table.tableattr = 'width="100%"' table.ttlrowattr = 'bgcolor="#110044"' tableStr = "" for fname in file_list: if fields: newname = fields.get("File_%s" % fname, None) else: newname = None if newname and newname != fname: # File rename requested? (evil, newname) = os.path.split(newname) # Make sure no path of evil try: os.rename(patchFilePath + os.sep + fname, patchFilePath + os.sep + newname) fname = newname except: InstDB.error( req, "Failed to rename file '%s' to '%s'!" % (fname, newname)) namefield = '<input type=text name="%sFile_%s" value="%s" size=60>' \ % (prefix, cgi.escape (fname), cgi.escape (fname)) stats = os.stat(patchFilePath + os.sep + fname) tableStr += table.addrow( (namefield, InstDB.pretty_size(stats.st_size))) tableStr += table.end() tab += (("<center><b>Archive files</b></center>\n", ), ) tab += ((tableStr, ), ) split = InstDB.tabsplits(tab) req.write(split.render()) req.write("<p>\n")
def show_patch_item(id, fields, req): RateOrder = fields.get("RateOrder", "Date") OrderDir = int(fields.get("OrderDir", 0)) if OrderDir < 0 or OrderDir > 2: OrderDir = 0 recaptcha_error = None comment = "" # Check for comment/rating submission if fields.get("submit", None): comment = fields.get("comment", "") captcha_challenge = fields.get("recaptcha_challenge_field", "") captcha_response = fields.get("recaptcha_response_field", "") if InstDB.User: # User is logged in? rating = int(fields.get("rating", 0)) if rating not in range(0, 6): rating = 0 # Select existing comment/rating if any InstDB.Cur.execute( "SELECT Rating, Comment FROM Ratings" " WHERE PatchId=%s && UserId=%s", (id, InstDB.User["UserId"])) row = InstDB.Cur.fetchone() if row: # Existing comment/rating? InstDB.Cur.execute( "UPDATE Ratings SET Rating=%s, Comment=%s" " WHERE PatchId=%s && UserId=%s", (rating, comment, id, InstDB.User["UserId"])) # Calculate increment value for RateCount (user count) if rating != 0 and row["Rating"] == 0: countinc = 1 # inc elif rating == 0 and row["Rating"] != 0: countinc = -1 # dec else: countinc = 0 # Don't change # Update RateTotal (+ new rating - old) and RateCount InstDB.Cur.execute( "UPDATE PatchInfo SET RateTotal=RateTotal" " + %s - %s, RateCount=RateCount + %s" " WHERE PatchId=%s", (rating, row["Rating"], countinc, id)) InstDB.show_status(req, "Updated comment/rating data") else: # Insert new comment/rating InstDB.Cur.execute( "INSERT INTO Ratings (PatchId, UserId," " Rating, Comment) VALUES(%s,%s,%s,%s)", (id, InstDB.User["UserId"], rating, comment)) if rating != 0: # Update RateTotal and RateCount for patch file InstDB.Cur.execute( "UPDATE PatchInfo SET RateTotal=" "RateTotal+%s, RateCount=RateCount+1" " WHERE PatchId=%s", (rating, id)) InstDB.show_status(req, "Added new comment/rating") elif comment: # User not logged in - add an anonymous comment resp = recaptcha_submit(captcha_challenge, captcha_response, InstDB.ReCaptchaPrvKey, req.connection.remote_ip) if resp.is_valid: InstDB.Cur.execute( "INSERT INTO Ratings" " (PatchId, UserId, Comment) VALUES(%s,1,%s)", (id, comment)) InstDB.show_status(req, "Anonymous comment added") comment = "" else: InstDB.error( req, "reCAPTCHA response incorrect. Comment not added.") recaptcha_error = resp.error_code itemCells = PatchHelper.cell_format itemFields = InstDB.cells_to_fields(itemCells) sel = PatchHelper.sql_select(itemFields) # Add UserId field if not already in select query if not "PatchInfo.UserId" in sel.fields: sel.fields += ("PatchInfo.UserId", ) sel.where.insert(0, "PatchInfo.State = 'Active'") sel.where.insert(0, "PatchInfo.PatchId=%d" % id) InstDB.Cur.execute(sel.query()) patchRow = InstDB.Cur.fetchone() if not patchRow: # Shouldn't happen, thats why we raise an exception raise LookupError, "Patch file with ID '%d' not found" % id fields = InstDB.cells_to_fields(PropHelper.cell_format) sel = PropHelper.sql_select(fields) sel.where.insert(0, "ItemProps.ItemId=%d" % id) InstDB.Cur.execute(sel.query()) props = InstDB.Cur.fetchall() # Get count of Instruments in this patch InstDB.Cur.execute( "SELECT COUNT(*) AS Count FROM InstInfo" " WHERE PatchId=%s", id) instcount = InstDB.Cur.fetchone()["Count"] # Get count of samples in this patch InstDB.Cur.execute( "SELECT COUNT(*) AS Count FROM SampleInfo" " WHERE PatchId=%s", id) samplecount = InstDB.Cur.fetchone()["Count"] # If user is logged in - see if they have rated this file UserRating = None if InstDB.User: InstDB.Cur.execute( "SELECT Date, Rating, Comment FROM Ratings" " WHERE PatchId=%s && UserId=%s", (id, InstDB.User["UserId"])) UserRating = InstDB.Cur.fetchone() # Get ratings/comments RatingFields = RatingHelper.list_format sel = RatingHelper.sql_select(RatingFields) sel.where.insert(0, "PatchId=%d" % id) sel.orderby = RatingHelper.sql_order_field(RateOrder, OrderDir) sel.limit = str(InstDB.MaxRatings) sel.calc_found_rows = True InstDB.Cur.execute(sel.query()) RatingRows = InstDB.Cur.fetchall() # Get total number of comments/ratings InstDB.Cur.execute("SELECT FOUND_ROWS() AS Total") RatingRowsTotal = InstDB.Cur.fetchone()["Total"] tab = PatchHelper.cell_vals(itemCells, patchRow) if instcount > 0: tmptab = ( '<a href="patches.py?Action=list&Type=Inst&PatchId=%s' '&OrderBy=Bank">Instruments</a>' % id, instcount) else: tmptab = ("Instruments", "None") if samplecount > 0: tmptab += ( '<a href="patches.py?Action=list&Type=Sample&PatchId=%s' '&OrderBy=SampleName">Samples</a>' % id, samplecount) else: tmptab += ("Samples", "None") tab += (tmptab, ) tab += add_extra_props(req, props) tab += (("<center>Rating & Comment</center>", ), ) if InstDB.User: # User logged in? if UserRating: tab += (("Modified", UserRating["Date"]), ) # selected item if UserRating: s = str(UserRating["Rating"]) else: s = "0" tab += (("Rating", InstDB.form_radio("rating", InstDB.RatingRadio, s)), ) captcha_code = "" else: tab += (("Rating", "Login to rate this file"), ) captcha_code = recaptcha_display(InstDB.ReCaptchaPubKey, False, recaptcha_error) if UserRating: comment = cgi.escape(UserRating["Comment"]) submit = "Update" else: submit = "Submit" tab += (("Comment", "<textarea name=comment rows=5 cols=40>%s</textarea>\n" % comment + captcha_code), ("<center>\n<input name=submit type=submit value=%s>\n</center>\n" \ % submit,)) # Display patch item info box = InstDB.html_box() # User is admin or owns this patch file? - show edit icon if InstDB.User and ("Admin" in InstDB.User["Flags"] \ or patchRow["UserId"] == InstDB.User["UserId"]): box.titlehtml = '\n <a href="patches.py?Action=edit&ItemId=%d">' \ '<img src="images/edit.png" alt="Edit Mode" width=10 height=15 border=0>' \ ' <font class="boxtitle">Edit</font></a>\n' % id req.write(box.start("Patch File")) req.write('<form action="" method=POST>\n') split = InstDB.tabsplits(tab) req.write(split.render()) req.write("</form>\n") req.write(box.end()) req.write("<p><p>\n") # Show ratings/comments table if RatingRows: box = InstDB.html_box() req.write(box.start("Comments")) sortList = [] for field in RatingFields: if RatingHelper.field_searchable(field): sortList += ((field, RatingHelper.field_title(field)), ) else: sortList += (RatingHelper.field_title(field), ) urlstr = urlencode((("Action", "item"), ("ItemId", str(id)))) urlstr = cgi.escape(urlstr) titles = sort_titles(sortList, urlstr, RateOrder, OrderDir) table = InstDB.tabular(titles) table.cellpadding = "4" table.tableattr = 'width="100%"' # Display comments for row in RatingRows: req.write(table.addrow(RatingHelper.html_vals(RatingFields, row))) req.write(table.end()) req.write(box.end())
def list_samples(req, fields): OrderBy = fields.get("OrderBy", None) OrderDir = int(fields.get("OrderDir", 0)) if OrderDir < 0 or OrderDir > 2: OrderDir = 0 Offset = int(fields.get("Offset", 0)) Count = int(fields.get("Count", 50)) PatchId = int(fields.get("PatchId", 0)) if Count <= 5: Count = 5 elif Count > InstDB.MaxListItems: Count = InstDB.MaxListItems InstDB.Cur.execute("SELECT State, UserId FROM PatchInfo WHERE PatchId=%s", PatchId) row = InstDB.Cur.fetchone() if not row: InstDB.error(req, "Specified patch file not found") return # Only allow list if patch is active, user is admin or user owns imported file if row["State"] != "Active": if not InstDB.User or ("Admin" not in InstDB.User["Flags"] and \ (row["State"] != 'Imported' or InstDB.User["UserId"] != row["UserId"])): InstDB.error(req, "Permission denied to specified patch file") return itemFields = SampleHelper.list_format extraFields = ("State", ) if PatchId: extraFields += ("PatchId", ) # Create SQL query sel = SampleHelper.sql_select(itemFields + extraFields) # Make sure order by field is valid if OrderBy and not SampleHelper.field_searchable(OrderBy): OrderBy = None if not OrderBy: OrderBy = "SampleName" sel.orderby = SampleHelper.sql_order_field(OrderBy, OrderDir) sel.limit = "%d,%d" % (Offset, Count) if PatchId: sel.where.insert(0, "PatchInfo.PatchId=%d" % PatchId) sel.calc_found_rows = True InstDB.Cur.execute(sel.query()) rows = InstDB.Cur.fetchall() # Get total number of matching items InstDB.Cur.execute("SELECT FOUND_ROWS() AS Total") row = InstDB.Cur.fetchone() total = int(row["Total"]) # Re URL-ify the input fields pager_urlstr = urlencode( (("Action", "list"), ("Type", "Sample"), ("OrderBy", OrderBy), ("OrderDir", OrderDir), ("Count", Count), ("PatchId", PatchId))) pager_urlstr = cgi.escape(pager_urlstr) # Display the pager bar InstDB.show_pager(req, pager_urlstr, Offset, Count, total) # Create clickable titles that sort output urlstr = urlencode((("Action", "list"), ("Type", "Sample"), ("Count", Count), ("PatchId", PatchId))) urlstr = cgi.escape(urlstr) sortList = [] for field in itemFields: if SampleHelper.field_searchable(field): sortList += ((field, SampleHelper.field_title(field)), ) else: sortList += (SampleHelper.field_title(field), ) titles = sort_titles(sortList, urlstr, OrderBy, OrderDir, SampleHelper) table = InstDB.tabular(titles) table.tableattr = 'width="100%"' for row in rows: req.write(table.addrow(SampleHelper.html_vals(itemFields, row))) req.write(table.end()) # Display the pager bar InstDB.show_pager(req, pager_urlstr, Offset, Count, total)
def list_patches(req, fields): OrderBy = fields.get("OrderBy", None) Category = int(fields.get("Category", 0)) CategoryExact = int(fields.get("CategoryExact", 0)) OrderDir = int(fields.get("OrderDir", 0)) if OrderDir < 0 or OrderDir > 2: OrderDir = 0 Offset = int(fields.get("Offset", 0)) Count = int(fields.get("Count", 50)) if Count <= 5: Count = 5 elif Count > InstDB.MaxListItems: Count = InstDB.MaxListItems itemFields = list(PatchHelper.list_format) # Category specified? if Category: CategoryIds = (str(Category), ) if not CategoryExact: # Exact category NOT specified? InstDB.Cur.execute("SELECT CategoryName FROM Category" " WHERE CategoryId=%s", Category) # Name res = InstDB.Cur.fetchone() if res: # Get list of sub categories (if any) InstDB.Cur.execute( "SELECT CategoryId FROM Category" " WHERE LEFT(CategoryName, %s) = %s", (len(res["CategoryName"]) + 1, res["CategoryName"] + ':')) for row in InstDB.Cur.fetchall(): CategoryIds += (str(row["CategoryId"]), ) # Remove category from item fields if "CategoryName" in itemFields: itemFields.remove("CategoryName") # Create SQL query sel = PatchHelper.sql_select(itemFields) # Make sure order by field is valid if OrderBy and not PatchHelper.field_searchable(OrderBy): OrderBy = None if not OrderBy: OrderBy = "FileName" sel.orderby = PatchHelper.sql_order_field(OrderBy, OrderDir) sel.limit = "%d,%d" % (Offset, Count) sel.where.append("PatchInfo.State = 'Active'") sel.calc_found_rows = True if Category: # Match categories (1st, 2nd or 3rd) s = string.join(CategoryIds, ',') sel.where.insert( 0, "(PatchInfo.CategoryId IN (%s)" " || PatchInfo.CategoryId2 IN (%s)" " || PatchInfo.CategoryId3 IN (%s))" % (s, s, s)) if not "PatchInfo.CategoryId" in sel.fields: sel.fields += ("PatchInfo.CategoryId", ) InstDB.Cur.execute(sel.query()) rows = InstDB.Cur.fetchall() # Get total number of matching items InstDB.Cur.execute("SELECT FOUND_ROWS() AS Total") row = InstDB.Cur.fetchone() total = int(row["Total"]) # Re URL-ify the input fields pager_urlstr = urlencode( (("Action", "list"), ("Type", "Patch"), ("Category", Category), ("OrderBy", OrderBy), ("OrderDir", OrderDir), ("Count", Count))) pager_urlstr = cgi.escape(pager_urlstr) # Display the pager bar InstDB.show_pager(req, pager_urlstr, Offset, Count, total) # Create clickable titles that sort output urlstr = urlencode((("Action", "list"), ("Type", "Patch"), ("Category", Category), ("Count", Count))) urlstr = cgi.escape(urlstr) sortList = [] for field in itemFields: if PatchHelper.field_searchable(field): sortList += ((field, PatchHelper.field_title(field)), ) else: sortList += (PatchHelper.field_title(field), ) titles = sort_titles(sortList, urlstr, OrderBy, OrderDir, PatchHelper) if rows: table = InstDB.tabular(titles) table.tableattr = 'width="100%"' for row in rows: req.write(table.addrow(PatchHelper.html_vals(itemFields, row))) req.write(table.end()) else: req.write("<b>No files match criteria</b>\n") # Display the pager bar InstDB.show_pager(req, pager_urlstr, Offset, Count, total)
os.rmdir(extractDir) raise InstDB.ImportError, "Unknown file type" # Import the instrument information ItemId = PatchImport.import_patch(extractDir, UserId) # Move original file to original/<ItemId> (purged after some time) os.rename(importFileName, InstDB.OriginalPath + os.sep + str(ItemId)) return ItemId # Main outer loop (persistently tries to connect to database) while True: try: InstDB.connect() except MySQLdb.Error, detail: log("Failed to connect to database: %s" % detail) time.sleep(CONNECT_RETRY_INTERVAL) continue # Inner loop polls for active tasks and executes them while True: try: InstDB.Cur.execute("SELECT * FROM Queue" " WHERE Status='Queued' && Type IN (%s)" " ORDER BY QueueId" % taskTypes) QueueId = 0 for row in InstDB.Cur.fetchall(): # For each queued task QueueId = row["QueueId"]
def action(req, fields): text = fields.get("Text", "") offset = int(fields.get("Offset", 0)) count = int(fields.get("Count", 20)) exceeded = 0 # set to 1 if max_results is exceeded try: InstDB.Cur.execute("DROP TABLE _scores") InstDB.Cur.execute("DROP TABLE _total_scores") except MySQLdb.OperationalError: pass # Create temporary scoring table InstDB.Cur.execute("""\ CREATE TEMPORARY TABLE _scores ( pid INT UNSIGNED NOT NULL, rating INT UNSIGNED NOT NULL, flag SMALLINT UNSIGNED NOT NULL, INDEX (pid))""") # Create temporary total scores table InstDB.Cur.execute("""\ CREATE TEMPORARY TABLE _total_scores ( pid INT UNSIGNED NOT NULL, rating INT UNSIGNED NOT NULL, flags SMALLINT UNSIGNED NOT NULL, INDEX (pid), INDEX (rating))""") # Insert scores for matches to Patch Name or FileName rows = InstDB.Cur.execute( """\ INSERT INTO _scores SELECT PatchId, %s, %s FROM PatchInfo WHERE INSTR(PatchName, %s) || INSTR(FileName, %s) LIMIT %s""", (patch_name_score, patch_name_score, text, text, max_results)) if rows == max_results: exceeded = 1 # Insert scores for matches to Patch properties (each property ++) rows = InstDB.Cur.execute( """\ INSERT INTO _scores SELECT ItemProps.ItemId, COUNT(*) * %s, %s FROM ItemProps, Items WHERE ItemProps.ItemId=Items.ItemId && Items.ItemType='Patch' && INSTR(PropValue, %s) GROUP BY ItemProps.ItemId LIMIT %s""", (patch_prop_score, patch_prop_score, text, max_results)) if rows == max_results: exceeded = 1 # Insert scores for matches to instrument names (each instrument ++) rows = InstDB.Cur.execute( """\ INSERT INTO _scores SELECT PatchId, COUNT(*) * %s, %s FROM InstInfo WHERE INSTR(InstName, %s) GROUP BY PatchId LIMIT %s""", (inst_name_score, inst_name_score, text, max_results)) if rows == max_results: exceeded = 1 # Insert scores for matches to instrument properties (each property ++) rows = InstDB.Cur.execute( """\ INSERT INTO _scores SELECT InstInfo.PatchId, COUNT(*) * %s, %s FROM ItemProps, Items, InstInfo WHERE ItemProps.ItemId=Items.ItemId && Items.ItemType='Inst' && INSTR(PropValue, %s) && ItemProps.ItemId=InstInfo.InstId GROUP BY InstInfo.PatchId LIMIT %s""", (inst_prop_score, inst_prop_score, text, max_results)) if rows == max_results: exceeded = 1 # Insert scores for matches to sample names (each sample ++) rows = InstDB.Cur.execute( """\ INSERT INTO _scores SELECT PatchId, COUNT(*) * %s, %s FROM SampleInfo WHERE INSTR(SampleName, %s) GROUP BY PatchId LIMIT %s""", (sample_name_score, sample_name_score, text, max_results)) if rows == max_results: exceeded = 1 # Insert scores for matches to sample properties (each property ++) rows = InstDB.Cur.execute( """\ INSERT INTO _scores SELECT SampleInfo.PatchId, COUNT(*) * %s, %s FROM ItemProps, Items, SampleInfo WHERE ItemProps.ItemId=Items.ItemId && Items.ItemType='Sample' && INSTR(PropValue, %s) && ItemProps.ItemId=SampleInfo.SampleId GROUP BY SampleInfo.PatchId LIMIT %s""", (sample_prop_score, sample_prop_score, text, max_results)) if rows == max_results: exceeded = 1 # Sum up all the ratings into temp total ratings table InstDB.Cur.execute("""\ INSERT INTO _total_scores SELECT pid, SUM(rating), BIT_OR(flag) FROM _scores, PatchInfo WHERE pid = PatchInfo.PatchId && PatchInfo.State='Active' GROUP BY pid""") # Drop temp ratings table InstDB.Cur.execute("DROP TABLE _scores") # Get max rating InstDB.Cur.execute("SELECT MAX(rating) AS max_rating," " COUNT(*) AS total_count FROM _total_scores") row = InstDB.Cur.fetchone() max_rating = row["max_rating"] total_count = row["total_count"] itemCells = (("FileNameLink", ), ("PatchName", ), ("DownloadLink", "PatchType", "FileSize"), ("Rating", "DateImported"), ("CategoryName", "LicenseName"), ("Version", "WebSiteLink", "Email")) # convert sequence of sequence of strings to list of string fields itemFields = [] for cell in itemCells: for field in cell: itemFields += (field, ) sel = PatchHelper.sql_select(itemFields) # Create SELECT query sel.where.insert(0, "PatchInfo.State = 'Active'") sel.where.insert(0, "_total_scores.pid=PatchInfo.PatchId") sel.tables += ("_total_scores", ) sel.orderby = "rating DESC" sel.fields += ("pid", "rating", "flags") sel.limit = "%d, %d" % (offset, count) InstDB.Cur.execute(sel.query()) req.write(InstDB.header("Search results")) if total_count == 0: req.write("<b>No matches to '%s'</b>\n" % (cgi.escape(text))) req.write(InstDB.footer()) InstDB.Cur.execute("DROP TABLE _total_scores") return if exceeded: warn = " (results truncated due to excessive matches)" else: warn = "" if total_count == 1: matchstr = "Found 1 match to '%s'%s\n" % (cgi.escape(text), warn) else: matchstr = "Found %d matches to '%s'%s\n" \ % (total_count, cgi.escape (text), warn) req.write("<b>" + matchstr + "</b>\n") # Re URL-ify the input fields urlstr = urlencode( (("Action", "search"), ("Text", text), ("Count", count))) urlstr = cgi.escape(urlstr) # Display the result pager bar InstDB.show_pager(req, urlstr, offset, count, total_count) req.write("<p>\n") # loop over matches for row in InstDB.Cur.fetchall(): score = int(float(row["rating"]) / float(max_rating) * 100.0) if score == 0: score = 1 scoreStr = "Score %d (%s/%s)" % (score, row["rating"], max_rating) # box start for result item box = InstDB.html_box() box.fontsize = "+0" box.tableattr = 'width="640"' req.write(box.start(scoreStr)) tab = PatchHelper.cell_vals(itemCells, row) split = InstDB.tabsplits(tab) split.tableattr = 'width="100%"' req.write(split.render()) # Create array of matching info to display (Type, Name, Value) matches = () flags = int(row["flags"]) esctext = InstDB.sqlescape(text) if flags & patch_prop_score: # Patch property matches? query = """\ SELECT '%s' AS type, P.PropName AS name, I.PropValue AS value FROM ItemProps AS I, Props AS P WHERE I.ItemId=%d && INSTR(I.PropValue, '%s') && I.PropId=P.PropId""" \ % ("Patch Property", int (row["pid"]), esctext) matches = query_matches(query, matches, text) if flags & inst_name_score: # Instrument name matches? query = "SELECT '%s' AS type, '%s' AS name, InstName AS value" \ " FROM InstInfo WHERE PatchId=%d && INSTR(InstName, '%s')" \ % ("Instrument", "Name", int (row["pid"]), esctext) matches = query_matches(query, matches, text) if flags & inst_prop_score: # Instrument property matches? query = """\ SELECT '%s' AS type, Props.PropName AS name, ItemProps.PropValue AS value FROM ItemProps, Props, Items, InstInfo WHERE Items.ItemType='Inst' && INSTR(ItemProps.PropValue, '%s') && ItemProps.ItemId=InstInfo.InstId && InstInfo.PatchId=%d && ItemProps.ItemId=Items.ItemId && ItemProps.PropId=Props.PropId""" \ % ("Instrument Property", esctext, int (row["pid"])) matches = query_matches(query, matches, text) if flags & sample_name_score: # Sample name matches? query = "SELECT '%s' AS type, '%s' AS name, SampleName AS value" \ " FROM SampleInfo WHERE PatchId=%d" \ " && INSTR(SampleName, '%s')" \ % ("Sample", "Name", int (row["pid"]), esctext) matches = query_matches(query, matches, text) if flags & sample_prop_score: # Sample property matches? query = """\ SELECT '%s' AS type, Props.PropName AS name, ItemProps.PropValue AS value FROM ItemProps, Props, Items, SampleInfo WHERE Items.ItemType='Sample' && INSTR(ItemProps.PropValue, '%s') && ItemProps.ItemId=SampleInfo.SampleId && SampleInfo.PatchId=%d && ItemProps.ItemId=Items.ItemId && ItemProps.PropId=Props.PropId""" \ % ("Sample Property", esctext, int (row["pid"])) matches = query_matches(query, matches, text) if matches: table = InstDB.tabular(("Item", "Field", "Value")) table.tableattr = 'width="100%"' table.cellspacing = 2 for m in matches: req.write(table.addrow(m)) req.write(table.end()) req.write(box.end()) req.write("<p>\n") req.write("<p>\n") InstDB.show_pager(req, urlstr, offset, count, total_count) req.write(InstDB.footer()) InstDB.Cur.execute("DROP TABLE _total_scores")
def action(req, fields): if not InstDB.User or "Admin" not in InstDB.User["Flags"]: req.write(InstDB.header("Admin only")) InstDB.error(req, "Administrator privileges required for this function") req.write(InstDB.footer()) return req.write(InstDB.header("Email news")) subject = fields.get("Subject", None) msg = fields.get("Message", None) # Message submitted? if subject and msg: message = "Subject: " + subject + "\r\n\r\n" + msg query = "SELECT UserId FROM Users WHERE !FIND_IN_SET('NoLogin', Flags)" allUsers = fields.get("AllUsers", None) if not allUsers: query += " && FIND_IN_SET('EmailNews', UserFlags)" InstDB.Cur.execute(query) for row in InstDB.Cur.fetchall(): # Queue email task InstDB.Cur.execute( "INSERT INTO Queue (Type, Status, UserId, Content)" " VALUES ('Email', 'Queued', %s, %s)", (row["UserId"], message)) if allUsers: allstr = "ALL" else: allstr = "EmailNews" req.write('<font class="title">Sent message to %s users.</font>\n' % allstr) req.write(InstDB.footer()) return box = InstDB.html_box() req.write(box.start("Email news")) req.write(""" <form action="patches.py?Action=emailnews" method=post> <table border=0 cellpadding=8> <tr> <td><b>Subject:</b></td> <td><input type=text name=Subject size=64></td> </tr> <tr> <td><b>All users:</b></td> <td><input type=checkbox name=AllUsers> Email <b>ALL</b> users?</td> </tr> <tr> <td colspan=2> <textarea name=Message rows=16 cols=80> </textarea> </td> </tr> <tr> <td colspan=2> <input type=submit name=Submit value=Submit> </td> </tr> </table> </form> """) req.write(box.end()) req.write(InstDB.footer())
def action(req, fields): sums = fields.get("Md5Sums", None) req.write(InstDB.header("MD5 Find")) # Form submitted? if sums: table = InstDB.tabular(["MD5", "Label", "FileName"]) table.tableattr = 'width="100%"' reObj = re.compile("[0-9a-fA-F]{32}") for line in sums.split('\n'): if not reObj.match(line): continue md5 = line[:32] label = line[32:].strip() InstDB.Cur.execute( "SELECT PatchId, FileName FROM Files WHERE Md5=%s", md5) result = InstDB.Cur.fetchone() if result: filelink = '<a href="patches.py?Action=item&ItemId=%d">%s</a>' \ % (result["PatchId"], result["FileName"]) else: filelink = "Not found" req.write(table.addrow([md5, label, filelink])) req.write(table.end()) req.write(InstDB.footer()) return box = InstDB.html_box() req.write(box.start("MD5 Find")) req.write(""" <form action="" method=post> <table border=0 cellpadding=8> <tr> <td> Enter one MD5 signature per line optionally followed by white space and a file name (or any other text). The MD5 signatures will be searched for in the database. The correct text output can be obtained from programs like <b>md5sum</b> and others (see Wikipedia <a href="http://en.wikipedia.org/wiki/Md5sum">Md5sum</a>).<br> Example: <i>752091450e308127a4d70c7623dd4e37 Fluid.sf2</i><br> </td> </tr> <tr> <td> <textarea name=Md5Sums rows=16 cols=80> </textarea> </td> </tr> <tr> <td> <input type=submit name=Submit value=Submit> </td> </tr> </table> </form> """) req.write(box.end()) req.write(InstDB.footer())
def action(req, fields): req.write(InstDB.header("Browse by Category")) # Get count of active patch files for primary category InstDB.Cur.execute( "SELECT CategoryId, COUNT(*) AS UseCount FROM PatchInfo" + " WHERE State='Active' GROUP BY CategoryId") UseCounts = {} for row in InstDB.Cur.fetchall(): UseCounts[row["CategoryId"]] = row["UseCount"] # Get count of active patch files for secondary category InstDB.Cur.execute("SELECT CategoryId2, COUNT(*) AS UseCount" " FROM PatchInfo WHERE CategoryId2 != 0" " && State='Active' GROUP BY CategoryId2") for row in InstDB.Cur.fetchall(): oldcount = UseCounts.get(row["CategoryId2"], 0) UseCounts[row["CategoryId2"]] = oldcount + row["UseCount"] # Get count of active patch files for 3rd category InstDB.Cur.execute("SELECT CategoryId3, COUNT(*) AS UseCount" " FROM PatchInfo WHERE CategoryId3 != 0" " && State='Active' GROUP BY CategoryId3") for row in InstDB.Cur.fetchall(): oldcount = UseCounts.get(row["CategoryId3"], 0) UseCounts[row["CategoryId3"]] = oldcount + row["UseCount"] # Select all categories (including sub categories) InstDB.Cur.execute("SELECT CategoryId, CategoryName FROM Category" " ORDER BY CategoryName") req.write("<table border=0 cellpadding=4 cellspacing=0>\n") # Loop over categories, displaying only master categories and summing # sub category use counts count = 0 dispcount = 0 rows = InstDB.Cur.fetchall() for i in range(0, len(rows)): row = rows[i] # Next row or None if last if i + 1 < len(rows): nextRow = rows[i + 1] else: nextRow = None # Store ID and name of master category if string.find(row["CategoryName"], ':') == -1: id = row["CategoryId"] name = row["CategoryName"] count += UseCounts.get(row["CategoryId"], 0) # Next row is a sub category? - yes: still processing a master category if nextRow and string.find(nextRow["CategoryName"], ':') != -1: continue if dispcount % 4 == 0: if dispcount != 0: req.write("</tr>\n") req.write("<tr>\n") (width, height) = image_sizes.get(name, [100, 100]) req.write("""\ <td align="center"> <a href="patches.py?Action=list&Category=%s"> <img src="images/category/%s.png" alt="Category Image" border=0 width=%d height=%d><br> <b>%s</b> (%d) </a> </td> """ % (id, name, width, height, name, count)) count = 0 dispcount += 1 if dispcount % 4 != 1: req.write("</tr>\n") req.write("</table>") req.write(InstDB.footer())