[Debtags-commits] [svn] r2012 - in daemon: . src

Enrico Zini enrico at costa.debian.org
Thu Oct 5 20:02:19 UTC 2006


Author: enrico
Date: Thu Oct  5 20:02:18 2006
New Revision: 2012

Added:
   daemon/src/dp   (contents, props changed)
Modified:
   daemon/   (props changed)
   daemon/src/Debtagsd.py
   daemon/src/cmdline.h
   daemon/src/config.cpp
   daemon/src/config.h
   daemon/src/debtagsd.cpp
   daemon/src/dq
Log:
 r3524 at viaza:  enrico | 2006-10-05 22:02:11 +0200
 Implemented reading the tag vocabulary
 Implemented saving the received patches in a directory


Modified: daemon/src/Debtagsd.py
==============================================================================
--- daemon/src/Debtagsd.py	(original)
+++ daemon/src/Debtagsd.py	Thu Oct  5 20:02:18 2006
@@ -15,6 +15,17 @@
 		self.sock.connect(self.sockfile)
 		self.sock.sendall(query + "\n")
 
+	def patch(self, patchGenerator):
+		"Send a patch to debtagsd"
+		self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+		self.sock.connect(self.sockfile)
+		self.sock.sendall("PATCH \n")
+		for line in patchGenerator:
+			self.sock.sendall(line)
+			if line[-1] != "\n":
+				self.sock.sendall("\n")
+		self.sock.sendall("\n")
+
 	def resultraw(self):
 		"Iterate all the lines of the result"
 		buf = ""

Modified: daemon/src/cmdline.h
==============================================================================
--- daemon/src/cmdline.h	(original)
+++ daemon/src/cmdline.h	Thu Oct  5 20:02:18 2006
@@ -41,8 +41,10 @@
 	StringOption* pidfile;
 	StringOption* ftsdb;
 	StringOption* tagdb;
+	StringOption* vocabulary;
 	StringOption* pkgdb;
 	StringOption* logfile;
+	StringOption* patchdir;
 
 	Engine* start;
 	Engine* stop;
@@ -75,10 +77,14 @@
 				"pathname of the Xapian index of package descriptions");
 		tagdb = startOpts->add<StringOption>("tagdb", 0, "tagdb", "pathname",
 				"pathname of the plaintext tag database");
+		vocabulary = startOpts->add<StringOption>("vocabulary", 0, "vocabulary", "pathname",
+				"pathname of the plaintext vocabulary file");
 		pkgdb = startOpts->add<StringOption>("pkgdb", 0, "pkgdb", "pathname",
 				"pathname of the file with package descriptions");
 		logfile = startOpts->add<StringOption>("logfile", 0, "logfile", "pathname",
 				"pathname of the log file where to write what happens with debtagsd");
+		patchdir = startOpts->add<StringOption>("patchdir", 0, "patchdir", "pathname",
+				"pathname of a directory that contains patches to the tag database");
 
 		// Create the kill options group
 		OptionGroup* killOpts = createGroup("Options controlling signaling a running daemon");

Modified: daemon/src/config.cpp
==============================================================================
--- daemon/src/config.cpp	(original)
+++ daemon/src/config.cpp	Thu Oct  5 20:02:18 2006
@@ -50,10 +50,14 @@
 		ftsdb = opts.ftsdb->stringValue();
 	if (opts.tagdb->boolValue())
 		tagdb = opts.tagdb->stringValue();
+	if (opts.vocabulary->boolValue())
+		vocabulary = opts.vocabulary->stringValue();
 	if (opts.pkgdb->boolValue())
 		pkgdb = opts.pkgdb->stringValue();
 	if (opts.logfile->boolValue())
 		logfile = opts.logfile->stringValue();
+	if (opts.patchdir->boolValue())
+		patchdir = opts.patchdir->stringValue();
 
 	if (opts.kill_signal->boolValue())
 		kill_signal = opts.kill_signal->intValue();

Modified: daemon/src/config.h
==============================================================================
--- daemon/src/config.h	(original)
+++ daemon/src/config.h	Thu Oct  5 20:02:18 2006
@@ -16,8 +16,10 @@
 	std::string sockfile;
 	std::string ftsdb;
 	std::string tagdb;
+	std::string vocabulary;
 	std::string pkgdb;
 	std::string logfile;
+	std::string patchdir;
 	int kill_signal;
 	std::ostream* logstream;
 
@@ -29,8 +31,10 @@
 		  sockfile("/var/run/debtagsd/debtagsd.sock"),
 		  ftsdb("/var/lib/debtags/fts"),
 		  tagdb("/var/lib/debtags/package-tags"),
+		  vocabulary("/var/lib/debtags/vocabulary"),
 		  pkgdb("/var/lib/dpkg/available"),
 		  logfile("/var/log/debtagsd.log"),
+		  patchdir("/var/lib/debtags/patches"),
 		  kill_signal(15),
 		  logstream(0)
 	{

Modified: daemon/src/debtagsd.cpp
==============================================================================
--- daemon/src/debtagsd.cpp	(original)
+++ daemon/src/debtagsd.cpp	Thu Oct  5 20:02:18 2006
@@ -1,3 +1,8 @@
+/**
+ * TODO (refactoring-wise)
+ *  - multithreaded
+ *  - timeout the network reads and writes
+ */
 #include <wibble/exception.h>
 #include <wibble/regexp.h>
 #include <wibble/sys/childprocess.h>
@@ -12,6 +17,7 @@
 #include <tagcoll/TextFormat.h>
 
 #include <iostream>
+#include <fstream>
 #include <sstream>
 #include <set>
 #include <string>
@@ -82,36 +88,6 @@
 			throw wibble::exception::System("accepting a connection on " + pathname);
 		return nsock;
 	}
-
-#if 0
-	-- Show how to get the peer credentials in a socket
-void* ProtocolServer::main() throw ()
-{
-	try {
-		while (1)
-		{
-			log_debug("Got a connection");
-
-			struct ucred cr;
-			socklen_t cl = sizeof(cr);
-			if (getsockopt(nsock, SOL_SOCKET, SO_PEERCRED, &cr, &cl) == -1)
-				throw SocketException(errno, "reading peer credentials");
-
-			log_debug(fmt("Connect from pid=%d, uid=%d, gid=%d",
-						cr.pid, cr.uid, cr.gid));
-
-			Credentials cred(cr.uid, cr.gid);
-			ServerHandler* handler = new ServerHandler(cred, state, queue, nsock);
-			// handler should delete itself when it's finished
-			handler->startDetached();
-			log_debug("Handler thread started");
-		}
-	} catch (Exception& e) {
-		queue.send(Message(new MessageError(string(e.type()) + ": " + e.desc())));
-	}
-	return 0;
-}
-#endif
 };
 
 using namespace std;
@@ -197,6 +173,27 @@
 	return res;
 }
 
+class Tags : public std::set<std::string>
+{
+public:
+	Tags(Config& cfg)
+	{
+		tagcoll::input::Stdio in(cfg.vocabulary);
+		DebDBParser parser(in);
+		DebDBParser::Record rec;
+		while (parser.nextRecord(rec))
+		{
+			DebDBParser::Record::const_iterator i = rec.find("Tag");
+			if (i != rec.end()) insert(i->second);
+		}
+	}
+
+	bool has(const std::string& tag)
+	{
+		return find(tag) != end();
+	}
+};
+
 /// Quick access to the short descriptions of every package
 class Descs : public std::map<std::string, std::pair<std::string, std::string> >
 {
@@ -252,8 +249,11 @@
 
 	tagcoll::coll::Fast<std::string, std::string> coll;
 	Descs desc;
+	Tags tags;
 	FullTextSearch fts;
 
+	size_t seq;
+
 	/// Output a package with its tags and description
 	void outputPackage(const std::string& pkg, Connection& conn)
 	{
@@ -430,6 +430,7 @@
 				while (true)
 				{
 					string line = conn.readline();
+					cfg.log() << "Patch line: " << line << endl;
 
 					// End with an empty line
 					if (line.empty()) break;
@@ -437,17 +438,57 @@
 					buf += line;
 					buf += "\n";
 				}
+				cfg.log() << "Got the patch" << endl;
 
 				// Parse the patch
 				tagcoll::input::String in(buf);
 				tagcoll::PatchList<std::string, std::string> patches =
 					tagcoll::textformat::parsePatch(in);
 
-				// TODO: validate the patch, removing all non existing tags
+				// Validate the patch, removing all non existing tags
+				for (tagcoll::PatchList<std::string, std::string>::iterator i = patches.begin();
+						i != patches.end(); ++i)
+				{
+					// We just need to remove nonexisting tags from added: they
+					// are harmless in removed
+					vector<string> nonexisting;
+					for (set<string>::const_iterator j = i->second.added.begin();
+							j != i->second.added.end(); ++j)
+						if (!tags.has(*j))
+							nonexisting.push_back(*j);
+					for (vector<string>::const_iterator j = nonexisting.begin();
+							j != nonexisting.end(); ++j)
+						i->second.added.erase(*j);
+				}
+
+				cfg.log() << "XX validated" << endl;
 
+				// Apply the patch
 				coll.applyChange(patches);
 
-				// TODO: save the patch on a file
+				cfg.log() << "XX applied" << endl;
+
+				// Save the patch on a file
+
+				// Build the file name
+				time_t now = time(NULL);
+				struct tm t;
+				if (localtime_r(&now, &t) == NULL)
+					throw wibble::exception::System("getting local time information");
+				char file[40];
+				snprintf(file, 40, "%04d%02d%02d-%02d%02d%02d-%d-%d.patch",
+						t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec,
+						getpid(), ++seq);
+				std::string fname = cfg.patchdir + "/" + file;
+
+				cfg.log() << "XX saving in " << fname << endl;
+
+				// Write the patch
+				ofstream out(fname.c_str());
+				out << buf;
+				out.close();
+
+				cfg.log() << "XX saved in " << fname << endl;
 			}
 			else
 				conn.write("Command not recognized: " + cmd + "\n");
@@ -459,7 +500,7 @@
 	}
 	
 public:
-	Debtagsd(Config& cfg) : cfg(cfg), desc(cfg), fts(cfg)
+	Debtagsd(Config& cfg) : cfg(cfg), desc(cfg), tags(cfg), fts(cfg), seq(0)
 	{
 		tagcoll::input::Stdio input(cfg.tagdb);
 		tagcoll::textformat::parse(input, tagcoll::coll::inserter(coll));

Modified: daemon/src/dq
==============================================================================
--- daemon/src/dq	(original)
+++ daemon/src/dq	Thu Oct  5 20:02:18 2006
@@ -1,44 +1,7 @@
 #!/usr/bin/python
 
-import socket
 import sys
-
-SOCKFILE='/tmp/debtagsd.sock'
-
-class Debtagsd:
-	def __init__(self, sockfile = SOCKFILE):
-		self.sockfile = sockfile
-
-	def query(self, query):
-		"Send a query to debtagsd"
-		# Connect
-		self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-		self.sock.connect(self.sockfile)
-		self.sock.sendall(query + "\n")
-
-	def resultraw(self):
-		"Iterate all the lines of the result"
-		buf = ""
-		while True:
-			c = self.sock.recv(1)
-			if not c:
-				if buf: yield buf
-				break
-			if c == "\n":
-				yield buf
-				buf = ""
-			else:
-				buf = buf + c
-		self.sock = None;
-
-	def resulttag(self):
-		return self.resultraw()
-
-	def resultpkgs(self):
-		for r in self.resultraw():
-			pkg, tags, desc = r.split(" ", 2)
-			tags = set(tags.split(','))
-			yield pkg, tags, desc
+from Debtagsd import Debtagsd
 
 srv = Debtagsd()
 



More information about the Debtags-commits mailing list