From 44be4bb654e313344a427f35a527de3e636f4a61 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Wed, 23 Jun 2021 17:25:03 -0400 Subject: Add SBoTools plugin (needs a lot more work) --- SBoTools/plugin.py | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 SBoTools/plugin.py (limited to 'SBoTools/plugin.py') diff --git a/SBoTools/plugin.py b/SBoTools/plugin.py new file mode 100644 index 0000000..0e18e9d --- /dev/null +++ b/SBoTools/plugin.py @@ -0,0 +1,177 @@ +### +# Copyright (c) 2021, B. Watson +# All rights reserved. +# +# +### + +# TODO: add maintainer name/email to the DB. + +import os +import glob +import subprocess +import sys +import re +import sqlite3 + +from supybot import utils, plugins, ircutils, callbacks +from supybot.commands import * +import supybot.utils.minisix as minisix + +try: + from supybot.i18n import PluginInternationalization + _ = PluginInternationalization('SBoTools') +except ImportError: + # Placeholder that allows to run the plugin on a bot + # without the i18n module + _ = lambda x: x + +class SBoTools(callbacks.Plugin): + """Provides SlackBuilds.org build searches""" + threaded = True + + db = None + categories = None + + def getMaxResults(self, msg): + maxresults = self.registryValue('maxresults') + if msg.channel is None: + # private message, increase limit + maxresults *= 5 + return maxresults + + def InitDB(self): + if self.db is None: + filename = self.registryValue('dbpath') + if(os.path.exists(filename)): + self.db = sqlite3.connect(filename) + return self.db + + def getCategory(self, cat): + if self.categories is None: + self.categories = {} + db = self.InitDB(); + cursor = db.cursor() + cursor.execute("select id, name from categories"); + result = cursor.fetchall() + for (id, name) in result: + self.categories[name] = id + + if cat in self.categories: + return self.categories[cat] + else: + return None + + def sbosearch(self, irc, msg, args, tflag, terms): + """ [] | [-t] [ ...]> + + Search the SlackBuilds.org build database. Case-insensitive + substring match. Without -t, does a search by name only. With + -t, searches names, descriptions, and tags. With multiple search + terms, results are ANDed together. + """ + + category = None + if(not tflag): + if(len(terms) > 1): + irc.error("only one search term allowed unless using -t flag", Raise=True) + t = terms[0].split('/',1) + if(len(t) != 1): + category = self.getCategory(t[0]) + if(category is None): + irc.error("invalid category '" + t[0] + "'", Raise=True) + terms[0] = t[1] + + + db = self.InitDB(); + cursor = db.cursor() + tags = False; + + sql = "select distinct(b.id) from builds b, tags t " + sql += "where b.id = t.build_id" + + if(category is not None): + sql += " and b.category=" + str(category) + " " + + for (term) in terms: + tlike = "'%" + term.replace("'", "''") + "%'" + if(tflag): + sql += " and (b.name like " + tlike + " or b.descrip like " + tlike + " or t.tag like " + tlike + ")" + else: + sql += " and b.name like " + tlike + + maxresults = self.getMaxResults(msg) + sql += " limit " + str(maxresults + 1) + + cursor.execute(sql) + result = cursor.fetchall() + if(len(result) == 0): + irc.reply("no results found") + else: + lines = [] + for (i) in result: + c2 = db.cursor() + c2.execute("select b.name, c.name from builds b, categories c where b.category=c.id and b.id=?", (i[0],)) + xres = c2.fetchall(); + if(len(result) == 1): + (name, cat) = xres[0] + #irc.reply("would be showing !sboinfo " + cat + "/" + name); + self.SBoInfo(irc, msg, cat + "/" + name) + return; + for (name, cat) in xres: + lines.append(cat + "/" + name) + + if(len(result) > maxresults): + lines.append("[too many results, only showing first " + str(maxresults) + "]") + irc.replies(lines, joiner=' | ') + + sbosearch = thread(wrap(sbosearch, [optional(('literal', ['-t'])), many('somethingWithoutSpaces')])) + + def SBoInfo(self, irc, msg, catbuild): + category = None + build = None + + t = catbuild.split('/',1) + if(len(t) == 1): + build = catbuild + else: + category = self.getCategory(t[0]) + if(category is None): + irc.error("invalid category '" + t[0] + "'", Raise=True) + build = t[1] + + db = self.InitDB(); + cursor = db.cursor() + if(category is None): + cursor.execute("select b.id, b.name, c.name, b.descrip, b.version from builds b, categories c where b.category = c.id and b.name = ?", (build,)) + else: + cursor.execute("select b.id, b.name, c.name, b.descrip, b.version from builds b, categories c where c.id = ? and b.category = c.id and b.name = ?", (category, build,)) + + result = cursor.fetchall() + if(len(result) == 0): + irc.reply("no results found") + else: + lines = [] + for (bid, bname, cname, bdescrip, bversion) in result: + lines.append(cname + "/" + bname + " v" + bversion + ": " + bdescrip) + cursor.execute("select b.name from builds b, deps d where d.build_id=? and b.id=d.depends_on", (bid,)) + depres = cursor.fetchall() + if(len(depres) != 0): + deps = "" + for (depname) in depres: + deps += depname[0] + " " + lines.append("deps: " + deps) + + irc.replies(lines, joiner=' | ') + + def sboinfo(self, irc, msg, args, catbuild): + """ [] + + Show detailed information about a SBo build. The argument must be + an exact match (this is not a search). + """ + self.SBoInfo(irc, msg, catbuild) + + sboinfo = thread(wrap(sboinfo, ['somethingWithoutSpaces'])) + +Class = SBoTools -- cgit v1.2.3