[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