def testForceUnicode(self):
   self.assertEquals(u"aaa", util.force_unicode("aaa"))
   self.assertEquals(u"12", util.force_unicode(12))
   self.assertEquals(u"\u0430\u0431\u0432",
                     util.force_unicode("\xd0\xb0\xd0\xb1\xd0\xb2"))
   self.assertEquals(u'\u30e6\u30cb\u30b3\u30fc\u30c9',
                     util.force_unicode(u'\u30e6\u30cb\u30b3\u30fc\u30c9'))
Exemple #2
0
 def testForceUnicode(self):
     self.assertEquals(u"aaa", util.force_unicode("aaa"))
     self.assertEquals(u"12", util.force_unicode(12))
     self.assertEquals(u"\u0430\u0431\u0432",
                       util.force_unicode("\xd0\xb0\xd0\xb1\xd0\xb2"))
     self.assertEquals(
         u'\u30e6\u30cb\u30b3\u30fc\u30c9',
         util.force_unicode(u'\u30e6\u30cb\u30b3\u30fc\u30c9'))
Exemple #3
0
 def append(self, tag):
   """Appends a tag if it doesn't already exist."""
   tag = util.force_unicode(tag)
   if tag in self._tags:
     return
   self._operation_queue.wavelet_modify_tag(
       self._wave_id, self._wavelet_id, tag)
   self._tags.append(tag)
Exemple #4
0
 def remove(self, tag):
   """Removes a tag if it exists."""
   tag = util.force_unicode(tag)
   if not tag in self._tags:
     return
   self._operation_queue.wavelet_modify_tag(
       self._wave_id, self._wavelet_id, tag, modify_how='remove')
   self._tags.remove(tag)
 def append(self, tag):
     """Appends a tag if it doesn't already exist."""
     tag = util.force_unicode(tag)
     if tag in self._tags:
         return
     self._operation_queue.wavelet_modify_tag(self._wave_id,
                                              self._wavelet_id, tag)
     self._tags.append(tag)
 def remove(self, tag):
     """Removes a tag if it exists."""
     tag = util.force_unicode(tag)
     if not tag in self._tags:
         return
     self._operation_queue.wavelet_modify_tag(self._wave_id,
                                              self._wavelet_id,
                                              tag,
                                              modify_how='remove')
     self._tags.remove(tag)
Exemple #7
0
    def _decode_data(self, data, charset):
        """ Decode string data.

        :returns: unicode string
        """

        try:
            return util.force_unicode(data, charset)
        except UnicodeDecodeError:
            raise BadRequest('wrong charset')
Exemple #8
0
    def append_markup(self, markup):
        """Interpret the markup text as xhtml and append the result to the doc.

    Args:
      markup: The markup'ed text to append.
    """
        markup = util.force_unicode(markup)
        self._operation_queue.document_append_markup(self.wave_id,
                                                     self.wavelet_id,
                                                     self.blip_id, markup)
        self._content += util.parse_markup(markup)
Exemple #9
0
  def append_markup(self, markup):
    """Interpret the markup text as xhtml and append the result to the doc.

    Args:
      markup: The markup'ed text to append.
    """
    markup = util.force_unicode(markup)
    self._operation_queue.document_append_markup(self.wave_id,
                                                 self.wavelet_id,
                                                 self.blip_id,
                                                 markup)
    self._content += util.parse_markup(markup)
Exemple #10
0
def run_chain(chain, content):
    """Run content through a filter chain.

    Works with either a string or a sequence of filters"""
    if chain == None: #pragma: no cover
        return content
    if not hasattr(chain,'__iter__'):
        #Not a sequence, must be a string, parse it
        chain = parse_chain(chain)
    for fn in chain:
        f = load_filter(fn)
        logger.debug("Applying filter: "+fn)
        content = f.run(content)
    logger.debug("Content:"+content)
    return util.force_unicode(content)
Exemple #11
0
def run_chain(chain, content):
    """Run content through a filter chain.

    Works with either a string or a sequence of filters"""
    if chain is None: #pragma: no cover
        return content
    if not hasattr(chain, '__iter__'):
        #Not a sequence, must be a string, parse it
        chain = parse_chain(chain)
    for fn in chain:
        f = load_filter(fn)
        logger.debug("Applying filter: " + fn)
        content = f.run(content)
    logger.debug("Content: " + content)
    return util.force_unicode(content)
  def reply(self, initial_content=None):
    """Replies to the conversation in this wavelet.

    Args:
      initial_content: If set, start with this (string) content.

    Returns:
      A transient version of the blip that contains the reply.
    """
    if not initial_content:
      initial_content = u'\n'
    initial_content = util.force_unicode(initial_content)
    blip_data = self._operation_queue.wavelet_append_blip(
       self.wave_id, self.wavelet_id, initial_content)

    instance = blip.Blip(blip_data, self._blips, self._operation_queue)
    self._blips._add(instance)
    return instance
    def _set_title(self, title):
        title = util.force_unicode(title)

        if title.find('\n') != -1:
            raise errors.Error('Wavelet title should not contain a newline ' +
                               'character. Specified: ' + title)

        self._operation_queue.wavelet_set_title(self.wave_id, self.wavelet_id,
                                                title)
        self._title = title

        # Adjust the content of the root blip, if it is available in the context.
        if self._root_blip:
            content = '\n'
            splits = self._root_blip._content.split('\n', 2)
            if len(splits) == 3:
                content += splits[2]
            self._root_blip._content = '\n' + title + content
Exemple #14
0
  def _set_title(self, title):
    title = util.force_unicode(title)

    if title.find('\n') != -1:
      raise errors.Error('Wavelet title should not contain a newline ' +
                         'character. Specified: ' + title)

    self._operation_queue.wavelet_set_title(self.wave_id, self.wavelet_id,
                                            title)
    self._title = title

    # Adjust the content of the root blip, if it is available in the context.
    if self._root_blip:
      content = '\n'
      splits = self._root_blip._content.split('\n', 2)
      if len(splits) == 3:
        content += splits[2]
      self._root_blip._content = '\n' + title + content
    def reply(self, initial_content=None):
        """Replies to the conversation in this wavelet.

    Args:
      initial_content: If set, start with this (string) content.

    Returns:
      A transient version of the blip that contains the reply.
    """
        if not initial_content:
            initial_content = u'\n'
        initial_content = util.force_unicode(initial_content)
        blip_data = self._operation_queue.wavelet_append_blip(
            self.wave_id, self.wavelet_id, initial_content)

        instance = blip.Blip(blip_data, self._blips, self._operation_queue)
        self._blips._add(instance)
        return instance
Exemple #16
0
  def _execute(self, modify_how, what, bundled_annotations=None):
    """Executes this BlipRefs object.

    Args:
      modify_how: What to do. Any of the operation declared at the top.
      what: Depending on the operation. For delete, has to be None.
            For the others it is a singleton, a list or a function returning
            what to do; for ANNOTATE tuples of (key, value), for the others
            either string or elements.
            If what is a function, it takes three parameters, the content of
            the blip, the beginning of the matching range and the end.
      bundled_annotations: Annotations to apply immediately.
    Raises:
      IndexError when trying to access content outside of the blip.
      ValueError when called with the wrong values.
    Returns:
      self for chainability.
    """
    blip = self._blip

    if modify_how != BlipRefs.DELETE:
      if type(what) != list:
        what = [what]
      next_index = 0

    matched = []
    # updated_elements is used to store the element type of the
    # element to update
    updated_elements = []
    
    # For now, if we find one markup, we'll use it everywhere.
    next = None
    hit_found = False

    for start, end in self._hits():
      hit_found = True
      if start < 0:
        start += len(blip)
        if end == 0:
          end += len(blip)
      if end < 0:
        end += len(blip)
      if len(blip) == 0:
        if start != 0 or end != 0:
          raise IndexError('Start and end have to be 0 for empty document')
      elif start < 0 or end < 1 or start >= len(blip) or end > len(blip):
        raise IndexError('Position outside the document')
      if modify_how == BlipRefs.DELETE:
        for i in range(start, end):
          if i in blip._elements:
            del blip._elements[i]
        blip._delete_annotations(start, end)
        blip._shift(end, start - end)
        blip._content = blip._content[:start] + blip._content[end:]
      else:
        if callable(what):
          next = what(blip._content, start, end)
          matched.append(next)
        else:
          next = what[next_index]
          next_index = (next_index + 1) % len(what)
        if isinstance(next, str):
          next = util.force_unicode(next)
        if modify_how == BlipRefs.ANNOTATE:
          key, value = next
          blip.annotations._add_internal(key, value, start, end)
        elif modify_how == BlipRefs.CLEAR_ANNOTATION:
          blip.annotations._delete_internal(next, start, end)
        elif modify_how == BlipRefs.UPDATE_ELEMENT:
          el = blip._elements.get(start)
          if not element:
            raise ValueError('No element found at index %s' % start)
          # the passing around of types this way feels a bit dirty:
          updated_elements.append(element.Element.from_json({'type': el.type,
              'properties': next}))
          for k, b in next.items():
            setattr(el, k, b)
        else:
          if modify_how == BlipRefs.INSERT:
            end = start
          elif modify_how == BlipRefs.INSERT_AFTER:
            start = end
          elif modify_how == BlipRefs.REPLACE:
            pass
          else:
            raise ValueError('Unexpected modify_how: ' + modify_how)

          if isinstance(next, element.Element):
            text = ' '
          else:
            text = next

          # in the case of a replace, and the replacement text is shorter,
          # delete the delta.
          if start != end and len(text) < end - start:
            blip._delete_annotations(start + len(text), end)

          blip._shift(end, len(text) + start - end)
          blip._content = blip._content[:start] + text + blip._content[end:]
          if bundled_annotations:
            end_annotation = start + len(text)
            blip._delete_annotations(start, end_annotation)
            for key, value in bundled_annotations:
              blip.annotations._add_internal(key, value, start, end_annotation)

          if isinstance(next, element.Element):
            blip._elements[start] = next

    # No match found, return immediately without generating op.
    if not hit_found:
      return

    operation = blip._operation_queue.document_modify(blip.wave_id,
                                                      blip.wavelet_id,
                                                      blip.blip_id)
    for param, value in self._params.items():
      operation.set_param(param, value)

    modify_action = {'modifyHow': modify_how}
    if modify_how == BlipRefs.DELETE:
      pass
    elif modify_how == BlipRefs.UPDATE_ELEMENT:
      modify_action['elements'] = updated_elements
    elif (modify_how == BlipRefs.REPLACE or
          modify_how == BlipRefs.INSERT or
          modify_how == BlipRefs.INSERT_AFTER):
      if callable(what):
        what = matched
      if what:
        if not isinstance(next, element.Element):
          modify_action['values'] = [util.force_unicode(value) for value in what]
        else:
          modify_action['elements'] = what
    elif modify_how == BlipRefs.ANNOTATE:
      modify_action['values'] = [x[1] for x in what]
      modify_action['annotationKey'] = what[0][0]
    elif modify_how == BlipRefs.CLEAR_ANNOTATION:
      modify_action['annotationKey'] = what[0]
    if bundled_annotations:
      modify_action['bundledAnnotations'] = [
          {'key': key, 'value': value} for key, value in bundled_annotations]
    operation.set_param('modifyAction', modify_action)

    return self
Exemple #17
0
  def _execute(self, modify_how, what, bundled_annotations=None):
    """Executes this BlipRefs object.

    Args:
      modify_how: What to do. Any of the operation declared at the top.
      what: Depending on the operation. For delete, has to be None.
            For the others it is a singleton, a list or a function returning
            what to do; for ANNOTATE tuples of (key, value), for the others
            either string or elements.
            If what is a function, it takes three parameters, the content of
            the blip, the beginning of the matching range and the end.
      bundled_annotations: Annotations to apply immediately.
    Raises:
      IndexError when trying to access content outside of the blip.
      ValueError when called with the wrong values.
    Returns:
      self for chainability.
    """
    blip = self._blip

    if modify_how != BlipRefs.DELETE:
      if not isinstance(what, list):
        what = [what]
      next_index = 0

    matched = []
    # updated_elements is used to store the element type of the
    # element to update
    updated_elements = []
    
    # For now, if we find one markup, we'll use it everywhere.
    next = None
    hit_found = False

    for start, end in self._hits():
      hit_found = True
      if start < 0:
        start += len(blip)
        if end == 0:
          end += len(blip)
      if end < 0:
        end += len(blip)
      if len(blip) == 0:
        if start != 0 or end != 0:
          raise IndexError('Start and end have to be 0 for empty document')
      elif start < 0 or end < 1 or start >= len(blip) or end > len(blip):
        raise IndexError('Position outside the document')
      if modify_how == BlipRefs.DELETE:
        for i in range(start, end):
          if i in blip._elements:
            del blip._elements[i]
        blip._delete_annotations(start, end)
        blip._shift(end, start - end)
        blip._content = blip._content[:start] + blip._content[end:]
      else:
        if callable(what):
          next = what(blip._content, start, end)
          matched.append(next)
        else:
          next = what[next_index]
          next_index = (next_index + 1) % len(what)
        if isinstance(next, str):
          next = util.force_unicode(next)
        if modify_how == BlipRefs.ANNOTATE:
          key, value = next
          blip.annotations._add_internal(key, value, start, end)
        elif modify_how == BlipRefs.CLEAR_ANNOTATION:
          blip.annotations._delete_internal(next, start, end)
        elif modify_how == BlipRefs.UPDATE_ELEMENT:
          el = blip._elements.get(start)
          if not el:
            raise ValueError('No element found at index %s' % start)
          # the passing around of types this way feels a bit dirty:
          updated_elements.append(element.Element.from_json({'type': el.type,
              'properties': next}))
          for k, b in next.items():
            setattr(el, k, b)
        else:
          if modify_how == BlipRefs.INSERT:
            end = start
          elif modify_how == BlipRefs.INSERT_AFTER:
            start = end
          elif modify_how == BlipRefs.REPLACE:
            pass
          else:
            raise ValueError('Unexpected modify_how: ' + modify_how)

          if isinstance(next, element.Element):
            text = ' '
          else:
            text = next

          # in the case of a replace, and the replacement text is shorter,
          # delete the delta.
          if start != end and len(text) < end - start:
            blip._delete_annotations(start + len(text), end)

          blip._shift(end, len(text) + start - end)
          blip._content = blip._content[:start] + text + blip._content[end:]
          if bundled_annotations:
            end_annotation = start + len(text)
            blip._delete_annotations(start, end_annotation)
            for key, value in bundled_annotations:
              blip.annotations._add_internal(key, value, start, end_annotation)

          if isinstance(next, element.Element):
            blip._elements[start] = next

    # No match found, return immediately without generating op.
    if not hit_found:
      return

    operation = blip._operation_queue.document_modify(blip.wave_id,
                                                      blip.wavelet_id,
                                                      blip.blip_id)
    for param, value in self._params.items():
      operation.set_param(param, value)

    modify_action = {'modifyHow': modify_how}
    if modify_how == BlipRefs.DELETE:
      pass
    elif modify_how == BlipRefs.UPDATE_ELEMENT:
      modify_action['elements'] = updated_elements
    elif (modify_how == BlipRefs.REPLACE or
          modify_how == BlipRefs.INSERT or
          modify_how == BlipRefs.INSERT_AFTER):
      if callable(what):
        what = matched
      if what:
        if not isinstance(next, element.Element):
          modify_action['values'] = [util.force_unicode(value) for value in what]
        else:
          modify_action['elements'] = what
    elif modify_how == BlipRefs.ANNOTATE:
      modify_action['values'] = [x[1] for x in what]
      modify_action['annotationKey'] = what[0][0]
    elif modify_how == BlipRefs.CLEAR_ANNOTATION:
      modify_action['annotationKey'] = what[0]
    if bundled_annotations:
      modify_action['bundledAnnotations'] = [
          {'key': key, 'value': value} for key, value in bundled_annotations]
    operation.set_param('modifyAction', modify_action)

    return self