<commit_before>from . import api
from . import status
from . import errors
import operator

class List(list):
	def filter(self, **kwargs):
		kvops = []
		for k, v in kwargs.items():
			if '__' in k[1:-1]:
				k, o = k.rsplit('__', 1)
				try:
					op = getattr(operator, o)
				except AttributeError:
					raise errors.InvalidOperatorError("__{}".format(o))
			else:
				op = operator.eq
			kvops.append((k, v, op))
		return List(filter(
			lambda i: all(hasattr(i, k) and op(getattr(i, k), v) for k, v, op in kvops),
			self
		))

	def sort(self, key, reverse=False):
		return List(sorted(self, key=lambda x: getattr(x, key, 0), reverse=reverse))

	@property
	def first(self):
	    return self[0]

	@property
	def last(self):
		return self[-1]


class Group:
	def __init__(self, **kwargs):
		messages = kwargs.pop('messages', {})
		self.message_count = messages.get('count')
		self.last_message_id = messages.get('last_message_id')
		self.last_message_created_at = messages.get('last_message_created_at')
		self._members = [Member(**m) for m in kwargs.pop('members')]
		self.__dict__.update(**kwargs)

	def __str__(self):
		return "{}, {}/{} members, {} messages".format(
				self.name, len(self.members()),
				self.max_members, self.message_count)

	def __len__(self):
		return self.message_count

	@classmethod
	def list(cls):
		return List(Group(**g) for g in api.Groups.index())

	@classmethod
	def former_list(cls):
		return List(Group(**g) for g in api.Groups.index(former=True))

	@staticmethod
	def _chunkify(text, chunk_size=450):
		if text is None:
			return [None]
		chunks = []
		while len(text) > chunk_size:
			portion = text[:chunk_size]
			i = len(portion.rsplit(None, 1)[0])
			chunks.append(portion[:i].strip())
			text = text[i:].strip()
		chunks.append(text)
		return chunks

	def refresh(self):
		self.__init__(**api.Groups.show(self.id))

	def messages(self, before=None, since=None, after=None, limit=None):
		r = api.Messages.index(self.id, before_id=before, since_id=since, after_id=after)
		self.message_count = r['count']
		return List(Message(**m) for m in r['messages'])<commit_msg>Added a MessageList class<commit_after>from . import api
from . import status
from . import errors
import operator

class List(list):
	def filter(self, **kwargs):
		kvops = []
		for k, v in kwargs.items():
			if '__' in k[1:-1]:
				k, o = k.rsplit('__', 1)
				try:
					op = getattr(operator, o)
				except AttributeError:
					raise errors.InvalidOperatorError("__{}".format(o))
			else:
				op = operator.eq
			kvops.append((k, v, op))
		return List(filter(
			lambda i: all(hasattr(i, k) and op(getattr(i, k), v) for k, v, op in kvops),
			self
		))

	def sort(self, key, reverse=False):
		return List(sorted(self, key=lambda x: getattr(x, key, 0), reverse=reverse))

	@property
	def first(self):
	    return self[0]

	@property
	def last(self):
		return self[-1]


class MessageList(List):
	def __init__(self, group, iter, backward=False):
		super().__init__(iter)
		self.backward = backward
		self.group = group

	@property
	def oldest(self):
	    return self.first if self.backward else self.last
	
	@property
	def newest(self):
	    return self.last if self.backward else self.first

	def prepend(self, iter):
		for each in self.older():
			self.insert(0, each)

	def newer(self):
		return self.group.messages(after=self.newest.id)
		
	def older(self):
		return self.group.messages(before=self.oldest.id)
		
	def inewer(self):
		new = self.newer()
		if not new:
			return False
		if self.backward:
			self.extend(self.newer())
		else:
			self.prepend(self.newer())
		return True
		
	def iolder(self):
		old = self.older()
		if not old:
			return False
		if self.backward:
			self.prepend(self.older())
		else:
			self.extend(self.older())
		return True


class Group:
	def __init__(self, **kwargs):
		messages = kwargs.pop('messages', {})
		self.message_count = messages.get('count')
		self.last_message_id = messages.get('last_message_id')
		self.last_message_created_at = messages.get('last_message_created_at')
		self._members = [Member(**m) for m in kwargs.pop('members')]
		self.__dict__.update(**kwargs)

	def __str__(self):
		return "{}, {}/{} members, {} messages".format(
				self.name, len(self.members()),
				self.max_members, self.message_count)

	def __len__(self):
		return self.message_count

	@classmethod
	def list(cls):
		return List(Group(**g) for g in api.Groups.index())

	@classmethod
	def former_list(cls):
		return List(Group(**g) for g in api.Groups.index(former=True))

	@staticmethod
	def _chunkify(text, chunk_size=450):
		if text is None:
			return [None]
		chunks = []
		while len(text) > chunk_size:
			portion = text[:chunk_size]
			i = len(portion.rsplit(None, 1)[0])
			chunks.append(portion[:i].strip())
			text = text[i:].strip()
		chunks.append(text)
		return chunks

	def refresh(self):
		self.__init__(**api.Groups.show(self.id))

	def messages(self, before=None, since=None, after=None, limit=None):
		try:
			r = api.Messages.index(self.id, before_id=before, since_id=since, after_id=after)
		except errors.InvalidResponseError as e:
			if e.args[0].status_code != 304:
				raise e
			return None
		self.message_count = r['count']
		return MessageList(self, (Message(**m) for m in r['messages']), backward=after is not None)
{'fraction_non_alphanumeric': 0.15015128593040847, 'fraction_numerical': 0.00510590015128593, 'mean_word_length': 4.061244019138756, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4777898', 'n_tokens_mistral': 2104, 'n_tokens_neox': 1862, 'n_words': 458}