aboutsummaryrefslogtreecommitdiff
path: root/SBoTools
diff options
context:
space:
mode:
Diffstat (limited to 'SBoTools')
-rw-r--r--SBoTools/README.md1
-rw-r--r--SBoTools/__init__.py48
-rw-r--r--SBoTools/config.py42
-rw-r--r--SBoTools/plugin.py177
-rw-r--r--SBoTools/test.py15
5 files changed, 283 insertions, 0 deletions
diff --git a/SBoTools/README.md b/SBoTools/README.md
new file mode 100644
index 0000000..a694e68
--- /dev/null
+++ b/SBoTools/README.md
@@ -0,0 +1 @@
+Provides Slackware package database lookups.
diff --git a/SBoTools/__init__.py b/SBoTools/__init__.py
new file mode 100644
index 0000000..fe66e85
--- /dev/null
+++ b/SBoTools/__init__.py
@@ -0,0 +1,48 @@
+###
+# Copyright (c) 2021, B. Watson
+# All rights reserved.
+#
+#
+###
+
+"""
+SlackTools: Provides Unix manpage lookups
+"""
+
+import sys
+import supybot
+from supybot import world
+
+# Use this for the version of this plugin.
+__version__ = "0.0.1"
+
+# XXX Replace this with an appropriate author or supybot.Author instance.
+__author__ = supybot.Author('B. Watson', 'Urchlay', 'yalhcru@gmail.com')
+
+# This is a dictionary mapping supybot.Author instances to lists of
+# contributions.
+__contributors__ = {}
+
+# This is a url where the most recent plugin package can be downloaded.
+__url__ = ''
+
+from . import config
+from . import plugin
+if sys.version_info >= (3, 4):
+ from importlib import reload
+else:
+ from imp import reload
+# In case we're being reloaded.
+reload(config)
+reload(plugin)
+# Add more reloads here if you add third-party modules and want them to be
+# reloaded when this plugin is reloaded. Don't forget to import them as well!
+
+if world.testing:
+ from . import test
+
+Class = plugin.Class
+configure = config.configure
+
+
+# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
diff --git a/SBoTools/config.py b/SBoTools/config.py
new file mode 100644
index 0000000..b13dc28
--- /dev/null
+++ b/SBoTools/config.py
@@ -0,0 +1,42 @@
+###
+# Copyright (c) 2021, B. Watson
+# All rights reserved.
+#
+#
+###
+
+from supybot import conf, registry
+try:
+ from supybot.i18n import PluginInternationalization
+ _ = PluginInternationalization('SBoTools')
+except:
+ # Placeholder that allows to run the plugin on a bot
+ # without the i18n module
+ _ = lambda x: x
+
+
+def configure(advanced):
+ # This will be called by supybot to configure this module. advanced is
+ # a bool that specifies whether the user identified themself as an advanced
+ # user or not. You should effect your configuration by manipulating the
+ # registry as appropriate.
+ from supybot.questions import expect, anything, something, yn
+ conf.registerPlugin('SBoTools', True)
+
+
+SBoTools = conf.registerPlugin('SBoTools')
+# This is where your configuration variables (if any) should go. For example:
+# conf.registerGlobalValue(SBoTools, 'someConfigVariableName',
+# registry.Boolean(False, _("""Help for someConfigVariableName.""")))
+
+conf.registerGlobalValue(SBoTools, 'dbpath',
+ registry.String("/home/slackfacts/supybot/SBoTools.sqlite3", _("""Path to sqite3 database.""")))
+
+conf.registerGlobalValue(SBoTools, 'maxresults',
+ registry.Integer(5, _("""Maximum number of results to send to client.""")))
+
+## conf.registerGlobalValue(SBoTools, 'slackpath',
+## registry.String("/data/mirrors/slackware/slackware64-14.2", _("""Filesystem path to Slackware mirror (NO trailing slash!)""")))
+##
+## conf.registerGlobalValue(SBoTools, 'baseurl',
+## registry.String("https://slackware.uk/slackware/slackware64-14.2", _("""Web URL of Slackware mirror (NO trailing slash!)""")))
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
diff --git a/SBoTools/test.py b/SBoTools/test.py
new file mode 100644
index 0000000..14d770b
--- /dev/null
+++ b/SBoTools/test.py
@@ -0,0 +1,15 @@
+###
+# Copyright (c) 2021, B. Watson
+# All rights reserved.
+#
+#
+###
+
+from supybot.test import *
+
+
+class SlackToolsTestCase(PluginTestCase):
+ plugins = ('SlackTools',)
+
+
+# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: