first draft on class-based status parser
authorRazvan Deaconescu <razvan.deaconescu@cs.pub.ro>
Thu, 22 Apr 2010 08:44:12 +0000 (11:44 +0300)
committerRazvan Deaconescu <razvan.deaconescu@cs.pub.ro>
Thu, 22 Apr 2010 10:00:42 +0000 (13:00 +0300)
ppf/log-parser/generic/GenericStatusParser.py [new file with mode: 0644]
ppf/log-parser/generic/LibtorrentStatusParser.py [new file with mode: 0644]

diff --git a/ppf/log-parser/generic/GenericStatusParser.py b/ppf/log-parser/generic/GenericStatusParser.py
new file mode 100644 (file)
index 0000000..8310b0b
--- /dev/null
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+
+import sys
+import getopt
+import re
+from DatabaseWriter import DatabaseWriter
+from DatabaseCommander import DatabaseCommander
+import julian
+import datetime
+
+import logging
+
+# configure logging (change to logging.ERROR when no DEBUG required)
+logging.basicConfig(level=logging.DEBUG)
+
+class GenericStatusParser:
+    """
+    Abstract-like parser class used for parsing BitTorrent log messages.
+    Inherited by client-specific classes
+    """
+
+    def __init__(self):
+        pass
+
+    # return boolean
+    #
+    def is_status_line(line):
+        return True
+
+    # return integer
+    #
+    def canon_num_peers(non_canon_value):
+        return 0
+
+    # return integer
+    #
+    def canon_dht(non_canon_value):
+        return 0
+
+    # return integer
+    #
+    # 119.51kb/s -> 119
+    def canon_download_speed(non_canon_value):
+        return 0
+
+    # return integer
+    #
+    # 12119.51kb/s -> 12119
+    def canon_upload_speed(non_canon_value):
+        return 0
+
+    # return timedelta object
+    #
+    # 698mb -> 698*1024*1024
+    def canon_download_size(non_canon_value):
+        return 0
+
+    # return timedelta object
+    #
+    # 492mb -> 492*1024*1024
+    def canon_upload_size(non_canon_value):
+        return 0
+
+    # return timedelta object
+    #
+    # 1h 38m 37s -> [0, 1, 38, 37]
+    # 3d 5h 24m 34s -> [3, 5, 24, 34]
+    def canon_eta(non_canon_value):
+        return datetime.timedelta()
+
+    def timedelta_to_seconds(delta):
+        return delta.days * 24 * 3600 + delta.seconds
+
+    # return list of required 
+    def parse_status_line(line):
+        num_peers = 0
+        dht = 0
+        download_speed = 0
+        upload_speed = 0
+        download_size = 0
+        upload_size = 0
+        eta = 0
+
+        return (num_peers, dht, download_speed, upload_speed, download_size, upload_size, eta)
+
+    def parse_status_file(client_session_id, session_start, filename, callback_func, callback_arg = None):
+
+        message_time = session_start
+        one_second = datetime.timedelta(0, 1)
+
+        try:
+            fin = open(filename, "r")
+            while 1:
+                line = fin.readline()
+                if not line:
+                    break
+
+                line = line.strip()
+                if is_status_line(line) == False:
+                    continue
+
+                (num_peers, dht, download_speed, upload_speed, download_size, upload_size, eta_seconds) = parse_status_line(line)
+
+                message_time = message_time + one_second
+
+                logging.debug("(%d, %s, %s, %d, %d kb/s, %d kb/s, %d bytes, %d bytes)" % (num_peers, date, time, dht, download_speed, upload_speed, download_size, upload_size))
+
+                if callback_arg == None:
+                    callback_func(client_session_id, message_time,
+                            num_peers, dht,
+                            download_speed, upload_speed,
+                            download_size, upload_size,
+                            eta_seconds)
+                else:
+                    callback_func(client_session_id, message_time,
+                            num_peers, dht,
+                            download_speed, upload_speed,
+                            download_size, upload_size,
+                            eta_seconds)
+
+        except IOError:
+            logging.error("Error processing file %s." % filename)
diff --git a/ppf/log-parser/generic/LibtorrentStatusParser.py b/ppf/log-parser/generic/LibtorrentStatusParser.py
new file mode 100644 (file)
index 0000000..8682517
--- /dev/null
@@ -0,0 +1,156 @@
+#!/usr/bin/env python
+
+import sys
+import getopt
+import re
+from DatabaseWriter import DatabaseWriter
+from DatabaseCommander import DatabaseCommander
+import julian
+import datetime
+
+import logging
+
+# configure logging (change to logging.ERROR when no DEBUG required)
+logging.basicConfig(level=logging.DEBUG)
+
+class LibtorrentStatusParser:
+    """
+    Abstract-like parser class used for parsing BitTorrent log messages.
+    Inherited by client-specific classes
+    """
+
+    def __init__(self):
+        pass
+
+    # return boolean
+    #
+    def is_status_line(line):
+    if re.match("^ps", line) == None:
+        return False
+    return True
+
+    # return integer
+    #
+    def canon_num_peers(non_canon_value):
+        return int(non_canon_value)
+
+    # return integer
+    #
+    def canon_dht(non_canon_value):
+        return int(non_canon_value)
+
+    # return integer
+    #
+    # 119.51kb/s -> 119
+    def canon_download_speed(non_canon_value):
+        return int(float(non_canon_value.strip("kb/s")))
+
+    # return integer
+    #
+    # 12119.51kb/s -> 12119
+    def canon_upload_speed(non_canon_value):
+        return int(float(non_canon_value.strip("kb/s")))
+
+    # return timedelta object
+    #
+    # 698mb -> 698*1024*1024
+    def canon_download_size(non_canon_value):
+        return int(non_canon_value.strip("mb")) * 1024 * 1024
+
+    # return timedelta object
+    #
+    # 492mb -> 492*1024*1024
+    def canon_upload_size(non_canon_value):
+        return int(non_canon_value.strip("mb")) * 1024 * 1024
+
+    # return timedelta object
+    #
+    # 1h 38m 37s -> [0, 1, 38, 37]
+    # 3d 5h 24m 34s -> [3, 5, 24, 34]
+    def canon_eta(non_canon_value):
+        eta_string_array = re.split('\ *[dhms]\ *', non_canon_value)
+        eta_string_array.remove('')
+        eta = []
+        for i in range(0, len(eta_string_array)):
+            eta.append(int(eta_string_array[i]))
+        for i in range(len(eta_string_array), 4):
+            eta.insert(0, 0)
+
+        return datetime.timedelta(eta[0], eta[3], 0, 0, eta[2], eta[1], 0)
+
+    def timedelta_to_seconds(delta):
+        return delta.days * 24 * 3600 + delta.seconds
+
+    # return list of required 
+    def parse_status_line(line):
+        num_peers = 0
+        dht = 0
+        download_speed = 0
+        upload_speed = 0
+        download_size = 0
+        upload_size = 0
+        eta = 0
+
+        string_array = re.split("\ *[,<>]+\ *", line)
+        if DEBUG == True:
+            print "string_array is: ", string_array
+
+        for string in string_array:
+            pair = re.split("\ *:\ *", string)
+            if pair[0] == "ps":
+                num_peers = libtorrent_canon_num_peers(pair[1])
+            if pair[0] == "dht":
+                dht = libtorrent_canon_dht(pair[1])
+            if pair[0] == "dl":
+                download_speed = libtorrent_canon_download_speed(pair[1])
+            if pair[0] == "ul":
+                upload_speed = libtorrent_canon_upload_speed(pair[1])
+            if pair[0] == "dld":
+                download_size = libtorrent_canon_download_size(pair[1])
+            if pair[0] == "uld":
+                upload_size = libtorrent_canon_upload_size(pair[1])
+            if pair[0] == "size":
+                pass
+            if pair[0] == "eta":
+                eta = libtorrent_canon_eta(pair[1])
+                eta_seconds = eta.days * 24 * 3600 + eta.seconds
+
+        return (num_peers, dht, download_speed, upload_speed, download_size, upload_size, eta_seconds)
+
+    def parse_status_file(client_session_id, session_start, filename, callback_func, callback_arg = None):
+
+        message_time = session_start
+        one_second = datetime.timedelta(0, 1)
+
+        try:
+            fin = open(filename, "r")
+            while 1:
+                line = fin.readline()
+                if not line:
+                    break
+
+                line = line.strip()
+                if is_status_line(line) == False:
+                    continue
+
+                (num_peers, dht, download_speed, upload_speed, download_size, upload_size, eta_seconds) = parse_status_line(line)
+
+                message_time = message_time + one_second
+
+                logging.debug("(%d, %s, %s, %d, %d kb/s, %d kb/s, %d bytes, %d bytes)" % (num_peers, date, time, dht, download_speed, upload_speed, download_size, upload_size))
+
+                if callback_arg == None:
+                    callback_func(client_session_id, message_time,
+                            num_peers, dht,
+                            download_speed, upload_speed,
+                            download_size, upload_size,
+                            eta_seconds)
+                else:
+                    callback_func(client_session_id, message_time,
+                            num_peers, dht,
+                            download_speed, upload_speed,
+                            download_size, upload_size,
+                            eta_seconds)
+
+        except IOError:
+            logging.error("Error processing file %s." % filename)