Example #1
0
    def on_patch(self, data):
        buf_id = data['id']
        buf = self.FLOO_BUFS[buf_id]
        view = self.get_view(buf_id)
        DMP = dmp.diff_match_patch()
        if len(data['patch']) == 0:
            msg.error('wtf? no patches to apply. server is being stupid')
            return
        dmp_patches = DMP.patch_fromText(data['patch'])
        # TODO: run this in a separate thread
        if view:
            old_text = view.get_text()
        else:
            old_text = buf.get('buf', '')
        md5_before = hashlib.md5(old_text.encode('utf-8')).hexdigest()
        if md5_before != data['md5_before']:
            msg.debug('maybe vim is lame and discarded a trailing newline')
            old_text += '\n'
        md5_before = hashlib.md5(old_text.encode('utf-8')).hexdigest()
        if md5_before != data['md5_before']:
            msg.warn('starting md5s don\'t match for %s. ours: %s patch: %s this is dangerous!' %
                    (buf['path'], md5_before, data['md5_before']))

        t = DMP.patch_apply(dmp_patches, old_text)

        clean_patch = True
        for applied_patch in t[1]:
            if not applied_patch:
                clean_patch = False
                break

        if G.DEBUG:
            if len(t[0]) == 0:
                msg.debug('OMG EMPTY!')
                msg.debug('Starting data:', buf['buf'])
                msg.debug('Patch:', data['patch'])
            if '\x01' in t[0]:
                msg.debug('FOUND CRAZY BYTE IN BUFFER')
                msg.debug('Starting data:', buf['buf'])
                msg.debug('Patch:', data['patch'])

        if not clean_patch:
            msg.error('failed to patch %s cleanly. re-fetching buffer' % buf['path'])
            return self.agent.send_get_buf(buf_id)

        cur_hash = hashlib.md5(t[0].encode('utf-8')).hexdigest()
        if cur_hash != data['md5_after']:
            msg.warn(
                '%s new hash %s != expected %s. re-fetching buffer...' %
                (buf['path'], cur_hash, data['md5_after'])
            )
            return self.agent.send_get_buf(buf_id)

        buf['buf'] = t[0]
        buf['md5'] = cur_hash

        if not view:
            self.save_buf(buf)
            return
        view.apply_patches(buf, t)
Example #2
0
 def patches(self):
     return dmp.diff_match_patch().patch_make(self.previous, self.current)
Example #3
0
 def __generateDiff(self, a, b):
     dmp = dmp_module.diff_match_patch()
     diff = dmp.diff_main(a, b)
     dmp.diff_cleanupSemantic(diff)
     return diff
Example #4
0
 def patches(self):
     return dmp.diff_match_patch().patch_make(self.previous, self.current)
Example #5
0
    def apply_patch(patch_data):
        buf_id = patch_data['id']
        buf = BUFS[buf_id]
        view = get_view(buf_id)
        DMP = dmp.diff_match_patch()
        if len(patch_data['patch']) == 0:
            msg.error('wtf? no patches to apply. server is being stupid')
            return
        msg.debug('patch is', patch_data['patch'])
        dmp_patches = DMP.patch_fromText(patch_data['patch'])
        # TODO: run this in a separate thread
        if view:
            old_text = get_text(view)
        else:
            old_text = buf.get('buf', '')
        md5_before = hashlib.md5(old_text.encode('utf-8')).hexdigest()
        if md5_before != patch_data['md5_before']:
            msg.warn('starting md5s don\'t match for %s. this is dangerous!' % buf['path'])

        t = DMP.patch_apply(dmp_patches, old_text)

        clean_patch = True
        for applied_patch in t[1]:
            if not applied_patch:
                clean_patch = False
                break

        if G.DEBUG:
            if len(t[0]) == 0:
                msg.debug('OMG EMPTY!')
                msg.debug('Starting data:', buf['buf'])
                msg.debug('Patch:', patch_data['patch'])
            if '\x01' in t[0]:
                msg.debug('FOUND CRAZY BYTE IN BUFFER')
                msg.debug('Starting data:', buf['buf'])
                msg.debug('Patch:', patch_data['patch'])

        if not clean_patch:
            msg.error('failed to patch %s cleanly. re-fetching buffer' % buf['path'])
            return Listener.get_buf(buf_id)

        cur_hash = hashlib.md5(t[0].encode('utf-8')).hexdigest()
        if cur_hash != patch_data['md5_after']:
            msg.warn(
                '%s new hash %s != expected %s. re-fetching buffer...' %
                (buf['path'], cur_hash, patch_data['md5_after'])
            )
            return Listener.get_buf(buf_id)

        buf['buf'] = t[0]
        buf['md5'] = cur_hash

        if not view:
            save_buf(buf)
            return

        selections = [x for x in view.sel()]  # deep copy
        regions = []
        for patch in t[2]:
            offset = patch[0]
            length = patch[1]
            patch_text = patch[2]
            region = sublime.Region(offset, offset + length)
            regions.append(region)
            MODIFIED_EVENTS.put(1)
            view.run_command('floo_view_replace_region', {'r': [offset, offset + length], 'data': patch_text})
            new_sels = []
            for sel in selections:
                a = sel.a
                b = sel.b
                new_offset = len(patch_text) - length
                if sel.a > offset:
                    a += new_offset
                if sel.b > offset:
                    b += new_offset
                new_sels.append(sublime.Region(a, b))
            selections = [x for x in new_sels]

        SELECTED_EVENTS.put(1)
        view.sel().clear()
        region_key = 'floobits-patch-' + patch_data['username']
        view.add_regions(region_key, regions, 'floobits.patch', 'circle', sublime.DRAW_OUTLINED)
        utils.set_timeout(view.erase_regions, 1000, region_key)
        for sel in selections:
            SELECTED_EVENTS.put(1)
            view.sel().add(sel)

        now = datetime.now()
        view.set_status('Floobits', 'Changed by %s at %s' % (patch_data['username'], now.strftime('%H:%M')))
Example #6
0
    def on_patch(self, data):
        added_newline = False
        buf_id = data["id"]
        buf = self.FLOO_BUFS[buf_id]
        view = self.get_view(buf_id)
        DMP = dmp.diff_match_patch()
        if len(data["patch"]) == 0:
            msg.error("wtf? no patches to apply. server is being stupid")
            return
        dmp_patches = DMP.patch_fromText(data["patch"])
        # TODO: run this in a separate thread
        if view:
            old_text = view.get_text()
        else:
            old_text = buf.get("buf", "")
        md5_before = hashlib.md5(old_text.encode("utf-8")).hexdigest()
        if md5_before != data["md5_before"]:
            msg.debug("maybe vim is lame and discarded a trailing newline")
            old_text += "\n"
            added_newline = True
        md5_before = hashlib.md5(old_text.encode("utf-8")).hexdigest()
        if md5_before != data["md5_before"]:
            msg.warn(
                "starting md5s don't match for %s. ours: %s patch: %s this is dangerous!"
                % (buf["path"], md5_before, data["md5_before"])
            )
            if added_newline:
                old_text = old_text[:-1]
                md5_before = hashlib.md5(old_text.encode("utf-8")).hexdigest()

        t = DMP.patch_apply(dmp_patches, old_text)

        clean_patch = True
        for applied_patch in t[1]:
            if not applied_patch:
                clean_patch = False
                break

        if G.DEBUG:
            if len(t[0]) == 0:
                msg.debug("OMG EMPTY!")
                msg.debug("Starting data:", buf["buf"])
                msg.debug("Patch:", data["patch"])
            if "\x01" in t[0]:
                msg.debug("FOUND CRAZY BYTE IN BUFFER")
                msg.debug("Starting data:", buf["buf"])
                msg.debug("Patch:", data["patch"])

        if not clean_patch:
            msg.error("failed to patch %s cleanly. re-fetching buffer" % buf["path"])
            return self.agent.send_get_buf(buf_id)

        cur_hash = hashlib.md5(t[0].encode("utf-8")).hexdigest()
        if cur_hash != data["md5_after"]:
            msg.warn(
                "%s new hash %s != expected %s. re-fetching buffer..." % (buf["path"], cur_hash, data["md5_after"])
            )
            return self.agent.send_get_buf(buf_id)

        buf["buf"] = t[0]
        buf["md5"] = cur_hash

        if not view:
            self.save_buf(buf)
            return
        view.apply_patches(buf, t)
Example #7
0
import os
import json
import hashlib
import collections
import Queue

from lib import diff_match_patch as dmp

import msg
import shared as G
import utils
import sublime


DMP = dmp.diff_match_patch()


def buf_populated(func):
    def wrapped(self, data):
        if data.get('id') is None:
            msg.debug('no buf id in data')
            return
        buf = self.FLOO_BUFS.get(data['id'])
        if buf is None or 'buf' not in buf:
            msg.debug('buf is not populated yet')
            return
        func(self, data)
    return wrapped

Example #8
0
#!/usr/bin/env python
"""
Command line tool managing text patches based on google-diff-match-patch

"""

import argparse
import os
from lib.diff_match_patch import diff_match_patch
import re
import sys

dmp = diff_match_patch()            # dmp object instance

class bcolors:
    REMOVED = '\033[9;97;41m'
    ADDED = '\033[97;42m'
    ENDC = '\033[0m'


def diff(file1, file2, options):
    """ print the diff between two files so that I can then run
         ../multivers.py diff left.txt right.txt --extdir=. --incdir=. --printhtmldiff
        on it to see the semantic diffs.
    """

    path1 = os.path.join(options.basedir, options.extdir, file1)
    path2 = os.path.join(options.basedir, options.incdir, file2)

    diffs = dmp.diff_main(file(path1).read(), file(path2).read())
    dmp.diff_cleanupSemantic(diffs)
    def apply_patch(patch_data):
        buf_id = patch_data['id']
        buf = BUFS[buf_id]
        view = get_view(buf_id)
        DMP = dmp.diff_match_patch()
        if len(patch_data['patch']) == 0:
            msg.error('wtf? no patches to apply. server is being stupid')
            return
        msg.debug('patch is', patch_data['patch'])
        dmp_patches = DMP.patch_fromText(patch_data['patch'])
        # TODO: run this in a separate thread
        if view:
            old_text = get_text(view)
        else:
            old_text = buf.get('buf', '')
        md5_before = hashlib.md5(old_text.encode('utf-8')).hexdigest()
        if md5_before != patch_data['md5_before']:
            msg.warn('starting md5s don\'t match for %s. this is dangerous!' % buf['path'])

        t = DMP.patch_apply(dmp_patches, old_text)

        clean_patch = True
        for applied_patch in t[1]:
            if not applied_patch:
                clean_patch = False
                break

        if G.DEBUG:
            if len(t[0]) == 0:
                msg.debug('OMG EMPTY!')
                msg.debug('Starting data:', buf['buf'])
                msg.debug('Patch:', patch_data['patch'])
            if '\x01' in t[0]:
                msg.debug('FOUND CRAZY BYTE IN BUFFER')
                msg.debug('Starting data:', buf['buf'])
                msg.debug('Patch:', patch_data['patch'])

        if not clean_patch:
            msg.error('failed to patch %s cleanly. re-fetching buffer' % buf['path'])
            return Listener.get_buf(buf_id)

        cur_hash = hashlib.md5(t[0].encode('utf-8')).hexdigest()
        if cur_hash != patch_data['md5_after']:
            msg.warn(
                '%s new hash %s != expected %s. re-fetching buffer...' %
                (buf['path'], cur_hash, patch_data['md5_after'])
            )
            return Listener.get_buf(buf_id)

        buf['buf'] = t[0]
        buf['md5'] = cur_hash

        if not view:
            save_buf(buf)
            return

        selections = [x for x in view.sel()]  # deep copy
        regions = []
        for patch in t[2]:
            offset = patch[0]
            length = patch[1]
            patch_text = patch[2]
            region = sublime.Region(offset, offset + length)
            regions.append(region)
            MODIFIED_EVENTS.put(1)
            view.run_command('floo_view_replace_region', {'r': [offset, offset + length], 'data': patch_text})
            new_sels = []
            for sel in selections:
                a = sel.a
                b = sel.b
                new_offset = len(patch_text) - length
                if sel.a > offset:
                    a += new_offset
                if sel.b > offset:
                    b += new_offset
                new_sels.append(sublime.Region(a, b))
            selections = [x for x in new_sels]

        SELECTED_EVENTS.put(1)
        view.sel().clear()
        region_key = 'floobits-patch-' + patch_data['username']
        view.add_regions(region_key, regions, 'floobits.patch', 'circle', sublime.DRAW_OUTLINED)
        utils.set_timeout(view.erase_regions, 1000, region_key)
        for sel in selections:
            SELECTED_EVENTS.put(1)
            view.sel().add(sel)

        now = datetime.now()
        view.set_status('Floobits', 'Changed by %s at %s' % (patch_data['username'], now.strftime('%H:%M')))
Example #10
0
 def __init__(self, dispatcher):
     self.infinote_pool = InfinotePool(self)
     self.diff_mp = diff_match_patch()
     self._update_wiki_graph()
     dispatcher.signals.subscribe('ws_disconnect', self.leave_wiki_article)
     dispatcher.signals.subscribe('view_changed', self.leave_wiki_article, filters = [(r'/wiki/(?P<slug>[^/]+)/',True),(r'/wiki/(?P<slug>[^/]+)/edit/$',False)])
Example #11
0
#!/usr/bin/env python
"""
Command line tool managing text patches based on google-diff-match-patch

"""

import argparse
import os
from lib.diff_match_patch import diff_match_patch
import re
import sys

dmp = diff_match_patch()  # dmp object instance


class bcolors:
    REMOVED = '\033[9;97;41m'
    ADDED = '\033[97;42m'
    ENDC = '\033[0m'


def diff(file1, file2, options):
    """ print the diff between two files so that I can then run
         ../multivers.py diff left.txt right.txt --extdir=. --incdir=. --printhtmldiff
        on it to see the semantic diffs.
    """

    path1 = os.path.join(options.basedir, options.extdir, file1)
    path2 = os.path.join(options.basedir, options.incdir, file2)

    diffs = dmp.diff_main(file(path1).read(), file(path2).read())