def text_view_comments(request, key, version_key=None, adminkey=None): text = get_text_by_keys_or_404(key) read_only = False if version_key : text_version = get_textversion_by_keys_or_404(version_key, adminkey, key) if settings.ALLOW_CLIENT_MODIF_ON_LAST_VERSION_ONLY : read_only = (text.last_text_version_id != text_version.id) else : text_version = text.get_latest_version() comments = get_viewable_comments(request, text_version.comment_set.filter(reply_to__isnull=True),text) filter_datas = get_filter_datas(request, text_version, text) get_params = simplejson.dumps(request.GET) wrapped_text_version, _ , _ = spannify(text_version.get_content()) from cm.models import ApplicationConfiguration categories = {} for i in range(1, 6): if text_version.__dict__['category_' + str(i)] == None or text_version.__dict__['category_' + str(i)].lower() != 'none': if text_version.__dict__['category_' + str(i)] != None and text_version.__dict__['category_' + str(i)] != '': categories[i] = text_version.__dict__['category_' + str(i)] else: if ApplicationConfiguration.get_key('workspace_category_' + str(i)) != None and ApplicationConfiguration.get_key('workspace_category_' + str(i)) != '': categories[i] = ApplicationConfiguration.get_key('workspace_category_' + str(i)) template_dict = { 'text' : text, 'text_version' : text_version, 'title' : text_version.title, # TODO use it ... 'get_params' : get_params, 'content' : wrapped_text_version, 'client_date_fmt' : settings.CLIENT_DATE_FMT, 'read_only' : read_only, } template_dict['json_comments'] = jsonize(comments, request) template_dict['json_filter_datas'] = jsonize(filter_datas, request) if categories: categories[0] = 'none' template_dict['categories'] = jsonize(categories, request) custom_css_str = ApplicationConfiguration.get_key('custom_css') if custom_css_str: custom_css = cssutils.parseString(custom_css_str) for css_rule in custom_css: if css_rule.type == css_rule.STYLE_RULE and css_rule.wellformed: css_rule.selectorText = "#textcontainer %s" %css_rule.selectorText template_dict['custom_css'] = custom_css.cssText template_dict['custom_font'] = ApplicationConfiguration.get_key('custom_font') template_dict['custom_titles_font'] = ApplicationConfiguration.get_key('custom_titles_font') return render_to_response('site/text_view_comments.html', template_dict, context_instance=RequestContext(request))
def text_export(request, key, format, download, whichcomments, withcolor, adminkey=None): text, admin = get_text_and_admin(key, adminkey) text_version = text.get_latest_version() if format == 'xml': return xml_export(request, text_version, whichcomments) original_content = text_version.content original_format = text_version.format # BD : html or markdown for now ... download_response = download == "1" with_color = withcolor == "1" comments = [] # whichcomments=="none" if whichcomments == "filtered" or whichcomments == "all": _comments = text_version.comment_set.all() if whichcomments == "filtered" : filteredIds = [] if request.method == 'POST' : ll = request.POST.get('filteredIds',[]).split(",") filteredIds = [ int(l) for l in ll if l] _comments = text_version.comment_set.filter(id__in=filteredIds) # security ! TODO CROSS PERMISSIONS WITH POST CONTENT comments = get_viewable_comments(request, _comments, text, order_by=('start_wrapper','start_offset','end_wrapper','end_offset'))# whichcomments=="all" # decide to use pandoc or not if format in ('markdown', 'latex', 'epub') : use_pandoc = True else: use_pandoc = (original_format == 'markdown' or original_format == 'rst') # attachments # for html, inline images only when exporting if format != 'html' or download_response : # for epub, file paths if format == 'epub': original_content = from_html_links_to_inline_imgs(original_content, False) # for latex, file name elif format == 'latex': original_content = from_html_links_to_inline_imgs(original_content, False, False) # for everything else, inline b64 encoded else: original_content = from_html_links_to_inline_imgs(original_content) if len(comments) == 0 : #want to bypass html conversion in this case # Prepends title if original_format == 'html': original_content = "<h1>%s</h1>%s" %(text_version.title, original_content) elif original_format == 'markdown': original_content = "%s\n======\n%s" %(text_version.title, original_content) elif original_format == 'rst': underline = '=' * len(text_version.title) original_content = "%s\n%s\n%s" %(text_version.title, underline, original_content) return content_export2(request, original_content, text_version.title, original_format, format, use_pandoc, download_response) else : # case comments to be added html = pandoc_convert(original_content, original_format, 'html') wrapped_text_version, _ , _ = spannify(html) with_markers = True marked_content = insert_comment_markers(wrapped_text_version, comments, with_markers, with_color) # Prepends title marked_content = "<h1>%s</h1>%s" %(text_version.title, marked_content) viewable_comments = [x for x in comments_thread(request, text_version, text) if x in comments] extended_comments = {} nb_children = {} for cc in viewable_comments : id = 0 #<-- all top comments are children of comment with id 0 if cc.is_reply() : id = cc.reply_to_id nb_children[id] = nb_children.get(id, 0) + 1 cc.num = "%d"%nb_children[id] extended_comments[cc.id] = cc if cc.is_reply() : cc.num = "%s.%s"%(extended_comments[cc.reply_to_id].num, cc.num) html_comments=render_to_string('site/macros/text_comments.html',{'comments':viewable_comments }, context_instance=RequestContext(request)) content = "%s%s"%(marked_content, html_comments) content_format = "html" return content_export2(request, content, text_version.title, content_format, format, use_pandoc, download_response)
def compute_new_comment_positions(old_content, old_format, new_content, new_format, commentList): # cf. TextVersion.get_content previousVersionContent = pandoc_convert(old_content, old_format, 'html') newVersionContent = pandoc_convert(new_content, new_format, 'html') _, previous_char_list, span_starts_previous = spannify( previousVersionContent, False) _, new_char_list, span_starts_new = spannify(newVersionContent, False) sm = SequenceMatcher(None, previous_char_list, new_char_list) opcodes = sm.get_opcodes() to_remove_comments_ids = set() # limit to real comments (not replies) and those that have scope commentList = [ c for c in commentList if not c.is_reply() and not c.is_scope_removed() ] for comment in commentList: try: comment.initial_start_offset = span_starts_previous[ comment.start_wrapper] + comment.start_offset comment.initial_end_offset = span_starts_previous[ comment.end_wrapper] + comment.end_offset except KeyError: logging.error( 'Key error (wrapper out of bounds of span_starts_previous)') continue comment.computed_start_offset = comment.initial_start_offset comment.computed_end_offset = comment.initial_end_offset # comment.computed_start_wrapper = None # comment.computed_end_wrapper = None comment.valid = True for tag, i1, i2, j1, j2 in opcodes: #print tag, i1, i2, j1, j2 for i in xrange(len(commentList)): if tag != 'equal': comment = commentList[i] if not comment.valid: continue if comment.initial_start_offset >= i2: # if offset delta = ((j2 - j1) - (i2 - i1)) comment.computed_start_offset += delta comment.computed_end_offset += delta elif comment.initial_end_offset > i1: comment.valid = False # id, initial_start, initial_end, computed_start, computed_end, valid = self.computationResults[i] for cc in commentList: if cc.valid: for id in xrange(len(span_starts_new.keys())): start = span_starts_new.get(id, 0) end = span_starts_new.get(id + 1, sys.maxint) # adjust start if cc.computed_start_offset >= start and cc.computed_start_offset < end: cc.start_wrapper = id cc.start_offset = cc.computed_start_offset - start # adjust end if cc.computed_end_offset >= start and cc.computed_end_offset < end: cc.end_wrapper = id cc.end_offset = cc.computed_end_offset - start # returns to_modify, to_remove return [c for c in commentList if c.valid], \ [c for c in commentList if not c.valid]
def compute_new_comment_positions(old_content, old_format, new_content, new_format, commentList): # cf. TextVersion.get_content previousVersionContent = pandoc_convert(old_content, old_format, 'html') newVersionContent = pandoc_convert(new_content, new_format, 'html') _, previous_char_list, span_starts_previous = spannify(previousVersionContent, False) _, new_char_list, span_starts_new = spannify(newVersionContent, False) sm = SequenceMatcher(None, previous_char_list, new_char_list) opcodes = sm.get_opcodes() to_remove_comments_ids = set() # limit to real comments (not replies) and those that have scope commentList = [c for c in commentList if not c.is_reply() and not c.is_scope_removed()] for comment in commentList: try: comment.initial_start_offset = span_starts_previous[comment.start_wrapper] + comment.start_offset comment.initial_end_offset = span_starts_previous[comment.end_wrapper] + comment.end_offset except KeyError: logging.error('Key error (wrapper out of bounds of span_starts_previous)') continue comment.computed_start_offset = comment.initial_start_offset comment.computed_end_offset = comment.initial_end_offset # comment.computed_start_wrapper = None # comment.computed_end_wrapper = None comment.valid = True for tag, i1, i2, j1, j2 in opcodes: #print tag, i1, i2, j1, j2 for i in xrange(len(commentList)) : if tag != 'equal' : comment = commentList[i] if not comment.valid: continue if comment.initial_start_offset >= i2 : # if offset delta = ((j2 - j1) - (i2 - i1)) comment.computed_start_offset += delta comment.computed_end_offset += delta elif comment.initial_end_offset > i1: comment.valid = False # id, initial_start, initial_end, computed_start, computed_end, valid = self.computationResults[i] for cc in commentList: if cc.valid: for id in xrange(len(span_starts_new.keys())): start = span_starts_new.get(id, 0) end = span_starts_new.get(id+1, sys.maxint) # adjust start if cc.computed_start_offset >= start and cc.computed_start_offset < end: cc.start_wrapper = id cc.start_offset = cc.computed_start_offset - start # adjust end if cc.computed_end_offset >= start and cc.computed_end_offset < end: cc.end_wrapper = id cc.end_offset = cc.computed_end_offset - start # returns to_modify, to_remove return [c for c in commentList if c.valid], \ [c for c in commentList if not c.valid]