<commit_before>import time, logging
from itertools import chain

from ..lib import reverts
from ..types import Timestamp
from ..util import iteration

from .collection import Collection

logger = logging.getLogger("mw.database.revisions")

class RevisionLike(Collection):
	
	def revert(self, rev, radius=15, before=None):
		
		# Load history
		past_revs = reversed(list(self.query(
			page_id=rev['page_id'],
			limit=radius,
			before_id=rev['rev_id'],
			direction="older"
		)))
		future_revs = self.query(
			page_id=rev['page_id'],
			limit=radius,
			after_id=rev['rev_id'],
			before=before,
			direction="newer"
		)
		checksum_revisions = ((rev['rev_sha1'], rev)
		                      for rev in chain(past_revs, [rev], future_revs))
		
		for reverting, reverteds, reverted_to in reverts.reverts(checksum_revisions, radius=radius):
			if rev['rev_id'] in {r['rev_id'] for r in reverteds}:
				return (reverting, reverteds, reverted_to)
			
		return None
	
class AllRevisions(RevisionLike):
	
	def get(self, rev_ids, include_page=False):
		rev_ids = set(int(id) for id in rev_ids)
		revisions = self.db.revisions.get(rev_ids, include_page)
		archives = self.db.archives.get(rev_ids, include_page)
		
		return chain(revisions, archives)
		
	def query(self, *args, **kwargs):
		
		revisions = self.db.revisions.query(*args, **kwargs)
		if 'include_page' in kwargs: del kwargs['include_page']
		archives = self.db.archives.query(*args, **kwargs)
		
		if 'direction' in kwargs:
			direction = kwargs['direction']
			if direction not in self.DIRECTIONS: 
				raise TypeError("direction must be in {0}".format(self.DIRECTIONS))
			
			if direction == "newer":
				collated_revisions = iteration.sequence(
					revisions, 
					archives,
					compare=lambda r1, r2: (r1['rev_timestamp'], r1['rev_id']) <= \
					               (r2['rev_timestamp'], r2['rev_id'])
				)
			else: # direction == "older"
				collated_revisions = iteration.sequence(
					revisions, 
					archives,
					compare=lambda r1, r2: (r1['rev_timestamp'], r1['rev_id']) >= \
					               (r2['rev_timestamp'], r2['rev_id'])
				)
		else:
			collated_revisions = chain(revisions, archives)
		
		if 'limit' in kwargs:
			limit = kwargs['limit']
			
			for i, rev in collated_revisions:
				yield rev 
				if i >= limit: break
			
		else:
			for rev in collated_revisions:
				yield rev

class Revisions(RevisionLike):
	
	def get(self, rev_ids, include_page=False):<commit_msg>Fixed limit bug in db.AllRevisions.<commit_after>import time, logging
from itertools import chain

from ..lib import reverts
from ..types import Timestamp
from ..util import iteration

from .collection import Collection

logger = logging.getLogger("mw.database.revisions")

class RevisionLike(Collection):
	
	def revert(self, rev, radius=15, before=None):
		
		# Load history
		past_revs = reversed(list(self.query(
			page_id=rev['page_id'],
			limit=radius,
			before_id=rev['rev_id'],
			direction="older"
		)))
		future_revs = self.query(
			page_id=rev['page_id'],
			limit=radius,
			after_id=rev['rev_id'],
			before=before,
			direction="newer"
		)
		checksum_revisions = ((rev['rev_sha1'], rev)
		                      for rev in chain(past_revs, [rev], future_revs))
		
		for reverting, reverteds, reverted_to in reverts.reverts(checksum_revisions, radius=radius):
			if rev['rev_id'] in {r['rev_id'] for r in reverteds}:
				return (reverting, reverteds, reverted_to)
			
		return None
	
class AllRevisions(RevisionLike):
	
	def get(self, rev_ids, include_page=False):
		rev_ids = set(int(id) for id in rev_ids)
		revisions = self.db.revisions.get(rev_ids, include_page)
		archives = self.db.archives.get(rev_ids, include_page)
		
		return chain(revisions, archives)
		
	def query(self, *args, **kwargs):
		
		revisions = self.db.revisions.query(*args, **kwargs)
		if 'include_page' in kwargs: del kwargs['include_page']
		archives = self.db.archives.query(*args, **kwargs)
		
		if 'direction' in kwargs:
			direction = kwargs['direction']
			if direction not in self.DIRECTIONS: 
				raise TypeError("direction must be in {0}".format(self.DIRECTIONS))
			
			if direction == "newer":
				collated_revisions = iteration.sequence(
					revisions, 
					archives,
					compare=lambda r1, r2: (r1['rev_timestamp'], r1['rev_id']) <= \
					               (r2['rev_timestamp'], r2['rev_id'])
				)
			else: # direction == "older"
				collated_revisions = iteration.sequence(
					revisions, 
					archives,
					compare=lambda r1, r2: (r1['rev_timestamp'], r1['rev_id']) >= \
					               (r2['rev_timestamp'], r2['rev_id'])
				)
		else:
			collated_revisions = chain(revisions, archives)
		
		if 'limit' in kwargs:
			limit = kwargs['limit']
			
			for i, rev in enumerate(collated_revisions):
				yield rev 
				if i >= limit: break
			
		else:
			for rev in collated_revisions:
				yield rev

class Revisions(RevisionLike):
	
	def get(self, rev_ids, include_page=False):
{'fraction_non_alphanumeric': 0.1270997773730014, 'fraction_numerical': 0.0064764217769682254, 'mean_word_length': 3.6230121608980355, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 7, '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': '6317011', 'n_tokens_mistral': 2004, 'n_tokens_neox': 1640, 'n_words': 389}