diff --git a/earwigbot/commands/notes.py b/earwigbot/commands/notes.py index 00ca631..8672bbd 100644 --- a/earwigbot/commands/notes.py +++ b/earwigbot/commands/notes.py @@ -20,6 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from datetime import datetime from os import path import sqlite3 as sqlite from threading import Lock @@ -42,7 +43,6 @@ class Notes(Command): "read": self.do_read, "edit": self.do_edit, "info": self.do_info, - "history": self.do_history, "rename": self.do_rename, "delete": self.do_delete, } @@ -58,15 +58,6 @@ class Notes(Command): else: self.reply("Unknown subcommand: \x0303{0}\x0F.".format(command)) - def create_db(self, conn): - """Initialize the notes database with its necessary tables.""" - script = """ - CREATE TABLE entries (entry_id, entry_slug, entry_title, entry_revision); - CREATE TABLE users (user_id, user_host); - CREATE TABLE revisions (rev_id, rev_entry, rev_user, rev_timestamp, rev_content); - """ - conn.executescript(script) - def do_list(self, data): """Show a list of entries in the notes database.""" query = "SELECT entry_title FROM entries" @@ -95,7 +86,7 @@ class Notes(Command): with sqlite.connect(self._dbfile) as conn, self._db_access_lock: try: title, content = conn.execute(query, (slug,)).fetchone() - except sqlite.OperationalError: + except (sqlite.OperationalError, TypeError): title, content = slug, None if content: @@ -105,22 +96,60 @@ class Notes(Command): def do_edit(self, data): """Edit an entry in the notes database.""" - pass + query1 = """SELECT entry_id, entry_title, user_host FROM entries + INNER JOIN revisions ON entry_revision = rev_id + INNER JOIN users ON rev_user = user_id + WHERE entry_slug = ?""" + query2 = "INSERT INTO revisions VALUES (?, ?, ?, ?, ?)" + query3 = "INSERT INTO entries VALUES (?, ?, ?, ?)" + query4 = "UPDATE entries SET entry_revision = ? WHERE entry_id = ?" + try: + slug = data.args[1].lower().replace("_", "").replace("-", "") + except IndexError: + self.reply(data, "Please name an entry to edit.") + return + content = " ".join(data.args[2:]).strip() + if not content: + self.reply(data, "Please give some content to put in the entry.") + return + + with sqlite.connect(self._dbfile) as conn, self._db_access_lock: + create = True + try: + id_, title, author = conn.execute(query1, (slug,)).fetchone() + create = False + except sqlite.OperationalError: + id_, title, author = 1, data.args[1], data.host + self.create_db(conn) + except TypeError: + id_ = self.get_next_entry(conn) + title, author = data.args[1], data.host + permdb = self.config.irc["permissions"] + if author != data.host and not permdb.is_admin(data): + msg = "You must be an author or a bot admin to edit this entry." + self.reply(data, msg) + return + revid = self.get_next_revision(conn) + userid = self.get_user(conn, data.host) + now = datetime.utcnow() + conn.execute(query2, (revid, id_, userid, now, content)) + if create: + conn.execute(query3, (id_, slug, title, revid)) + else: + conn.execute(query4, (revid, id_)) + + self.reply(data, "Entry \x0302{0}\x0F updated.".format(title)) def do_info(self, data): """Get info on an entry in the notes database.""" - pass - - def do_history(self, data): - """Get the history of an entry in the notes database.""" query = """SELECT entry_title, rev_timestamp, user_host FROM entries - INNER JOIN revisions ON entry_revision = rev_id + INNER JOIN revisions ON entry_id = rev_entry INNER JOIN users ON rev_user = user_id WHERE entry_slug = ?""" try: slug = data.args[1].lower().replace("_", "").replace("-", "") except IndexError: - self.reply(data, "Please name an entry to get the history of.") + self.reply(data, "Please name an entry to get info on.") return with sqlite.connect(self._dbfile) as conn, self._db_access_lock: @@ -151,3 +180,39 @@ class Notes(Command): def do_delete(self, data): """Delete an entry from the notes database.""" pass + + def create_db(self, conn): + """Initialize the notes database with its necessary tables.""" + script = """ + CREATE TABLE entries (entry_id, entry_slug, entry_title, + entry_revision); + CREATE TABLE users (user_id, user_host); + CREATE TABLE revisions (rev_id, rev_entry, rev_user, rev_timestamp, + rev_content); + """ + conn.executescript(script) + + def get_next_entry(self, conn): + """Get the next entry ID.""" + query = "SELECT MAX(entry_id) FROM entries" + next = conn.execute(query).fetchone()[0] + return next + 1 if next else 1 + + def get_next_revision(self, conn): + """Get the next revision ID.""" + query = "SELECT MAX(rev_id) FROM revisions" + next = conn.execute(query).fetchone()[0] + return next + 1 if next else 1 + + def get_user(self, conn, host): + """Get the user ID corresponding to a hostname, or make one.""" + query1 = "SELECT user_host FROM users WHERE user_id = ?" + query2 = "SELECT MAX(user_id) FROM users" + query3 = "INSERT INTO users VALUES (?, ?)" + user = conn.execute(query1).fetchone()[0] + if user: + return user + last = conn.execute(query2).fetchone()[0] + next = last + 1 if last else 1 + conn.execute(query3, (next, host)) + return next