aboutsummaryrefslogtreecommitdiff
path: root/SBoTools/plugin.py
diff options
context:
space:
mode:
Diffstat (limited to 'SBoTools/plugin.py')
-rw-r--r--SBoTools/plugin.py177
1 files changed, 177 insertions, 0 deletions
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):
+ """ [<category/>]<build> | [-t] <searchterm> [<searchterm> ...]>
+
+ 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):
+ """ [<category/>]<build>
+
+ 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