def map_event_section(events, patterns, text = "\n"):
	"""
		Map each event to a section in the text. Sections are provided by patterns.
	"""
	def make_event_data(pad, revs, event, args = ()):
		return pad, revs, event, args

	for event_data in events:
		pad, revs, event, data = make_event_data(*event_data)
		event_changeset = text_events.parse_event_changeset(event[u'changeset'])

		text, changes, new_changes = text_events.text_apply_event(text, event_changeset)

		range_sections = []

		for start, end, section in make_sections_mapping(patterns, text):
			for change_start, change_end in new_changes:
				if start <= change_start < end or start < change_end <= end:
					if section and (start, end, section) not in range_sections:
						range_sections.append((start, end, section))

		sections = []

		for s_start, s_end, s_section in range_sections:
			for e_start, e_end, e_section in range_sections:
				if s_section != e_section and s_start <= e_start and e_end <= s_end:
					if e_end - e_start < s_end - s_start:
						break
			else:
				sections.append(s_section[-1]) # get only last part

		(section,) = sections if len(sections) == 1 else (None,)

		yield pad, revs, event, data + (section,)
def build_event_text(events, text = "\n"):
	import text_events

	for event in events:
		event_data = text_events.text_apply_event(text, event.changeset_data)
		text, event_changes, event_new_changes = event_data

	return text
Example #3
0
def build_event_text(events, text="\n"):
    import text_events

    for event in events:
        event_data = text_events.text_apply_event(text, event.changeset_data)
        text, event_changes, event_new_changes = event_data

    return text
Example #4
0
def map_event_section(events, patterns, text="\n"):
    """
		Map each event to a section in the text. Sections are provided by patterns.
	"""
    def make_event_data(pad, revs, event, args=()):
        return pad, revs, event, args

    for event_data in events:
        pad, revs, event, data = make_event_data(*event_data)
        event_changeset = text_events.parse_event_changeset(
            event[u'changeset'])

        text, changes, new_changes = text_events.text_apply_event(
            text, event_changeset)

        range_sections = []

        for start, end, section in make_sections_mapping(patterns, text):
            for change_start, change_end in new_changes:
                if start <= change_start < end or start < change_end <= end:
                    if section and (start, end, section) not in range_sections:
                        range_sections.append((start, end, section))

        sections = []

        for s_start, s_end, s_section in range_sections:
            for e_start, e_end, e_section in range_sections:
                if s_section != e_section and s_start <= e_start and e_end <= s_end:
                    if e_end - e_start < s_end - s_start:
                        break
            else:
                sections.append(s_section[-1])  # get only last part

        (section, ) = sections if len(sections) == 1 else (None, )

        yield pad, revs, event, data + (section, )
def merge_events(events, threshold, text = "\n"):
	"""
		Merge events with the same author and if they overlap or have common bounds. 
		Events may even not be subsequent, but they shouldn't depend on alternating events happened
		in the middle.

		"event_queue" is filled while events are in time window (threshold), 
		then it is processed by taking the expanding event subsequence and trying to get a changeset from it.
		The longest event subsequence with correct independent changeset is merged into one event.
	"""

	events = iter(events)
	event_queue = []

	next_event = next(events, None)

	while next_event or event_queue:

		while next_event:
			if event_queue:
				base_merge_event, base_include = event_queue[0]

				timestamp = base_merge_event.events[0].timestamp
				new_timestamp = next_event.events[-1].timestamp

				if new_timestamp - timestamp >= threshold:
					break

			event_queue.append((next_event, True))
			next_event = next(events, None)

		event_author = None

		check_queue = []
		check_event_queue = []

		max_event_queue = []
		max_event_positive_change = None
		max_event_negative_change = None

		for merge_event, include in event_queue:
			if event_author is None:
				event_author = merge_event.events[0].author

			if merge_event.events[0].author == event_author:
				check_event_queue.append(merge_event)

			check_queue_length = 0
			for event in merge_event.events:
				check_include = include and event.author == event_author
				check_queue.append((event.changeset_data, check_include))

				if check_include:
					check_queue_length = len(check_queue)

			if not check_queue_length:
				continue

			event_changes = text_events.text_make_changes_events(text, check_queue[:check_queue_length])

			if event_changes:
				max_event_queue = list(check_event_queue)
				max_event_positive_change, max_event_negative_change = event_changes

		new_event_index = 0
		for event_index, (merge_event, include) in enumerate(event_queue):
			include &= merge_event not in max_event_queue

			if new_event_index or include:
				event_queue[new_event_index] = merge_event, include
				new_event_index += 1
			else:
				for event in merge_event.events:
					event_data = text_events.text_apply_event(text, event.changeset_data)
					text, event_changes, event_new_changes = event_data

		del event_queue[new_event_index:]

		if max_event_queue:
			merge_event = MergeEvent([event for merge_event in max_event_queue for event in merge_event.events])
			merge_event.positive_changes = max_event_positive_change
			merge_event.negative_changes = max_event_negative_change
			merge_event.merge_count = len(max_event_queue)
			yield merge_event