2 Storage class for P2P logging information.
4 2011, Razvan Deaconescu, razvan.deaconescu@cs.pub.ro
13 # Logging code heavily inspired by Logging HOWTO documentation:
14 # http://docs.python.org/dev/howto/logging.html#configuring-logging
17 # Create logger; default logging level is DEBUG.
18 logger = logging.getLogger(__name__)
19 logger.setLevel(logging.DEBUG)
21 # Create console handler and set level to ERROR.
22 ch = logging.StreamHandler()
23 ch.setLevel(logging.DEBUG)
26 formatter = logging.Formatter('%(filename)s:%(lineno)s - %(levelname)s: %(message)s')
28 # Add formatter to console handler.
29 ch.setFormatter(formatter)
31 # Add console handler to logger.
36 'CHOKE': {'id': 1, 'parameters': None},
37 'UNCHOKE': {'id': 2, 'parameters': None},
38 'INTERESTED': {'id': 3, 'parameters': None},
39 'NOT_INTERESTED': {'id': 4, 'parameters': None},
40 'HAVE': {'id': 5, 'parameters': None},
41 'BITFIELD': {'id': 6, 'parameters': None},
42 'REQUEST': {'id': 7, 'parameters': None},
43 'PIECE': {'id': 8, 'parameters': None},
44 'CANCEL': {'id': 9, 'parameters': None},
45 'DHT_PORT': {'id': 10, 'parameters': None}
48 bittorrent_clients = {
52 'url': 'http://www.tribler.org/trac',
54 'streaming_support': True,
61 'url': 'https://trac.p2p-next.org/',
63 'streaming_support': True,
67 'libtorrent-rasterbar': {
70 'url': 'http://www.rasterbar.com/products/libtorrent/',
72 'streaming_support': True,
79 'url': 'http://www.vuze.com/',
81 'streaming_support': True,
88 'url': 'http://www.transmissionbt.com/',
90 'streaming_support': False,
97 'url': 'http://aria2.sourceforge.net/',
99 'streaming_support': False,
105 'language': 'Python',
106 'url': 'http://www.bittorrent.com/',
108 'streaming_support': False,
114 transfer_directions = {
120 """ Class mimics a C structure. """
121 def __init__(self, torrent_filename=None, data_size=None,
123 self.torrent_filename = torrent_filename
124 self.data_size = data_size
125 self.description = description
127 class ClientSession(object):
128 """ Class mimics a C structure. """
129 def __init__(self, swarm_id=None, btclient=None, system_os=None,
130 system_os_version=None, system_ram=None, system_cpu=None,
131 public_ip=None, public_port=None, ds_limit=None, us_limit=None,
132 start_time=None, dht_enabled=None, pxe_enabled=None,
133 streaming_enabled=None, features=None, description=None):
134 self.swarm_id = swarm_id
135 self.btclient = btclient
136 self.system_os = system_os
137 self.system_os_version = system_os_version
138 self.system_ram = system_ram
139 self.system_cpu = system_cpu
140 self.public_ip = public_ip
141 self.public_port = public_port
142 self.ds_limit = ds_limit
143 self.us_limit = us_limit
144 self.start_time = start_time
145 self.dht_enabled = dht_enabled
146 self.pxe_enabled = pxe_enabled
147 self.streaming_enabled = streaming_enabled
148 self.features = features
149 self.description = description
151 class PeerStatusMessage(object):
152 """ Class mimics a C structure. """
153 def __init__(self, client_session_id=None, date=None, time=None,
154 peer_ip=None, peer_port=None, download_speed=None,
156 self.client_session_id = client_session_id
159 self.peer_ip = peer_ip
160 self.peer_port = peer_port
161 self.download_speed = download_speed
162 self.upload_speed = upload_speed
164 class StatusMessage(object):
165 """ Class mimics a C structure. """
166 def __init__(self, client_session_id=None, date=None, time=None,
167 num_peers=None, num_dht_peers=None, download_speed=None,
168 upload_speed=None, download_size=None, upload_size=None,
170 self.client_session_id = client_session_id
173 self.num_peers = num_peers
174 self.num_dht_peers = num_dht_peers
175 self.download_speed = download_speed
176 self.upload_speed = upload_speed
177 self.download_size = download_size
178 self.upload_size = upload_size
181 class VerboseMessage(object):
182 """ Class mimics a C structure. """
183 def __init__(self, client_session_id=None, date=None, time=None,
184 transfer_direction=None, peer_ip=None, peer_port=None,
185 message_type=None, index=None, begin=None, length=None,
187 self.client_session_id = client_session_id
190 self.transfer_direction = transfer_direction
191 self.peer_ip = peer_ip
192 self.peer_port = peer_port
193 self.message_type = message_type
197 self.listen_port = listen_port
199 class SwarmDataAccess(object):
203 def add_swarm(self, swarm):
206 def remove_swarm(self):
212 def update_swarm(self):
215 def add_client_session(self, session):
218 def remove_client_session(self):
221 def get_client_session(self):
224 def update_client_session(self):
227 def add_peer_status_message(self, msg):
230 def remove_peer_status_message(self):
233 def get_peer_status_message(self):
236 def update_peer_status_message(self):
239 def add_status_message(self, msg):
242 def remove_status_message(self):
245 def get_status_message(self):
248 def update_status_message(self):
251 def add_verbose_message(self, msg):
254 def remove_verbose_message(self):
257 def get_verbose_message(self):
260 def update_verbose_message(self):
263 class FileAccess(SwarmDataAccess):
264 def __init__(self, path):
265 self.base_path = path
267 def find_last_numeric_subfolder(path):
269 Find last numeric folder in base_path folder.
270 The last numeric folder is the last swarm_id.
273 pattern = re.compile("[0-9]+")
275 # Browse entries in base_path folder.
276 listing = os.listdir(path)
277 for entry in listing:
278 # If directory name is a number (id) add it to the list.
279 if os.path.isdir(os.path.join(path, entry)):
280 if pattern.match(entry):
281 dir_list.append(int(entry))
287 return dir_list[len(dir_list)-1]
289 class TreeTextFileAccess(FileAccess):
290 def __init__(self, path):
291 super(TreeTextFileAccess, self).__init__(path)
293 def add_swarm(self, swarm):
295 Create a subfolder with an unique id. Add 1 to the last numeric
296 subfolder id. In case none exists, use 1 as id.
298 id = find_last_numeric_subfolder(self.base_path)
304 swarm_path = os.path.join(self.base_path, str(id))
307 swarm_config = os.path.join(swarm_path, "swarm.conf")
308 f = open(swarm_config, 'w')
310 torrent_filename = %s
313 """ %(id, swarm.torrent_filename, swarm.data_size, swarm.description))
316 def add_client_session(self, session):
318 Create session subfolder in swarm subfolder and add config file.
319 TODO: Throw exception in case swarm subfolder doesn't exist.
321 swarm_path = os.path.join(self.base_path, str(session.swarm_id))
323 # Search first available folder in swarm_path.
324 id = find_last_numeric_subfolder(swarm_path)
330 # Create session subfolder.
331 session_path = os.path.join(swarm_path, str(id))
332 os.mkdir(session_path)
334 # Create and populate configuration file.
335 session_config = os.path.join(session_path, "client_session.conf")
336 f = open(session_config, 'w')
341 system_os_version = %s
351 streaming_enabled = %s
354 """ %(id, session.swarm_id, session.btclient, session.system_os,
355 session.system_os_version, session.system_ram, session.system_cpu,
356 session.public_ip, session.public_port, session.ds_limit,
357 session.us_limit, session.start_time, session.dht_enabled,
358 session.pxe_enabled, session.streaming_enabled,
359 session.features, session.description))
362 def add_peer_status_message(self, msg):
365 def add_status_message(self, msg):
368 def add_verbose_message(self, msg):
371 class DatabaseAccess(SwarmDataAccess):
375 def connect(self, database):
380 def disconnect(self):
383 class SQLiteDatabaseAccess(DatabaseAccess):
387 class MySQLDatabaseAccess(DatabaseAccess):