Source code for bitween.components.models.contact_shares

from threading import Lock

from . import logger

from .helpers import is_valid_ipv6_address
from .helpers import is_valid_ipv4_address


[docs]class ContactShares: """ this class holds all the discovered UserShares """ def __init__(self): """ this class holds all the discovered UserShares basically it works as a wrapper around a dict with the following structure: self.dict = { 'user@server': { 'resource': { "ip_v4": [], "ip_v6": [], "port": 0 "shares": { 'some_hash': { 'hash': 'some_hash', 'name': '', 'size': 0, 'files': [] } } } } } """ self.dict = {} # StoredDict('user_cache.json', autocommit=True) self.lock = Lock()
[docs] def get_user(self, jid): """ get user dict :param jid: :return: dictionary with all data for user with jid """ jid = str(jid) if not self.dict.get(jid, {}): self.dict[jid] = {} user = self.dict.get(jid, {}) return user
[docs] def get_resource(self, jid, resource): """ get resource dict of user with JID jid :param jid: :param resource: :return: """ jid = str(jid) user = self.get_user(jid) if not user.get(resource, False): user[resource] = {'ip_v4': [], 'ip_v6': [], 'shares': {} } return user.get(resource)
[docs] def add_address(self, jid, resource, address, port): """ add Address and Port to Resource resource of jid :param jid: :param resource: :param address: :param port: :return: """ res = self.get_resource(jid, resource) if is_valid_ipv4_address(address): res['ip_v4'].append((address, port)) elif is_valid_ipv6_address(address): res['ip_v6'].append((address, port)) else: logger.error('invalid address: %s' % address)
[docs] def get_ipv4_addresses(self, jid, resource): """ return all IPv4 Addresses of JIDs Resource resource :param jid: :param resource: :return: list of IPv4 Addresses """ res = self.get_resource(jid, resource) return res.get('ip_v4', [])
[docs] def get_ipv6_addresses(self, jid, resource): """ return all IPv6 Addresses of JIDs Resource resource :param jid: :param resource: :return: """ res = self.get_resource(jid, resource) return res.get('ip_v6', [])
[docs] def clear_addresses(self, jid, resource): """ clear Addresses of JIDs Resource :param jid: :param resource: :return: """ res = self.get_resource(jid, resource) res['ip_v4'] = [] res['ip_v6'] = []
[docs] def clear_shares(self, jid, resource): """ clear Shares of JIDs Resource :param jid: :param resource: :return: """ res = self.get_resource(jid, resource) res['shares'] = {}
[docs] def clear(self, jid, resource=None): """ clear whole User with JID jid. If resource != None, clear resource of the JID :param jid: :param resource: :return: """ jid = str(jid) if resource == None: self.dict[jid] = {} else: self.clear_addresses(jid, resource) self.clear_shares(jid, resource)
[docs] def add_share(self, jid, resource, hash, name='', size=0, files=None): """ Add a Share to a JIDs Resource :param jid: :param resource: :param hash: SHA1 Hash :type hash: str :param name: name of the share :type name: str :param size: size of the share in bytes :type size: int :param files: list of files in the Share :type files: list of str :return: """ res = self.get_resource(jid, resource) res['shares'][hash] = {} res['shares'][hash]['name'] = name res['shares'][hash]['size'] = size res['shares'][hash]['files'] = files res['shares'][hash]['hash'] = hash
[docs] def add_share_by_info(self, jid, resource, info): """ add a share by torrent info :param jid: :param resource: :param info: dict from torrent_handles.get_shares() :return: """ self.add_share(jid, resource, info.get('hash'), info.get('name', ''), info.get('total_size', 0))
def __iter__(self): with self.lock: for x, y in self.dict: yield x, y def __getitem__(self, item): with self.lock: return self.dict[item] def __setitem__(self, key, value): with self.lock: self.dict[key] = value def __delitem__(self, key): with self.lock: del self.dict[key] @property def hashes(self): """ returns a dict with all hashes and a list of ip_port tuples for each hash :return: """ h = {} for user in self.dict.keys(): logger.debug(user) for resource in self.dict[user].keys(): logger.debug(resource) for share in self.dict[user][resource]['shares']: logger.debug(share) hash = self.dict[user][resource]['shares'][share]['hash'] if not h.get(hash, False): h[hash] = [] for (address, port) in self.dict[user][resource]['ip_v4'] + self.dict[user][resource]['ip_v6']: address_tuple = (address, port) if address_tuple not in h[hash]: h[hash].append( (address, port)) return h