def create_nodes_for_path(path, authors=()): nodes, last = parse_path(path) current_node = get_root_node() current_path = "" for short_title, index in nodes: # slot current_path += '/' + short_title try: current_slot = get_node_for_path(current_path) except IllegalPath: current_slot = create_slot(short_title) current_node.append_child(current_slot) # alternatives current_path += '.' + str(index) try: current_node = get_node_for_path(current_path) except IllegalPath: if current_slot.child_order_set.count() == 0: highest_index = 0 else: highest_index = current_slot.child_order_set.order_by( 'position')[0].position for i in range(highest_index, index): current_node = create_structureNode(short_title + '_long', authors=authors) current_slot.append_child(current_node) return current_node
def create_post(text, author, path=None, do_escape=True): if do_escape: text = escape(text) split_text = user_ref_pattern.split(text) mentions = [] for i in range(1, len(split_text), 2): username = split_text[i] try: u = User.objects.get(username__iexact=username) split_text[i] = '<a href="/#/user/{0}">@{0}</a>'.format(u.username) mentions.append(u) except User.DoesNotExist: split_text[i] = '@' + username text = "".join(split_text) split_text = tag_pattern.split(text) for i in range(1, len(split_text), 2): tagname = split_text[i] split_text[i] = '<a href="/#/search/{0}">#{0}</a>'.format(tagname) text = "".join(split_text) split_text = internal_link_pattern.split(text) nodes = [] if path is not None: nodes.append(backend.get_node_for_path(path)) for i in range(1, len(split_text), 2): path = split_text[i] try: n = backend.get_node_for_path(path) if n.node_type == backend.Node.SLOT: slot = n n = backend.get_favorite_if_slot(n) position = backend.NodeOrder.objects.filter(child=n).filter( parent=slot).all()[0].position path += "." + str(position) split_text[i] = '<a href="{0}">{1}</a>'.format( '/#' + path, path.rsplit('/', 1)[1]) nodes.append(n) except backend.IllegalPath: pass text = "".join(split_text) split_text = url_pattern.split(text) for i in range(1, len(split_text), 2): link = split_text[i] split_text[i] = '<a href="{0}">{0}</a>'.format(link) text = "".join(split_text) post = Post() post.text = text post.author = author post.save() post.mentions.add(*mentions) post.node_references.add(*nodes) post.save() return post
def post_new_argument_for_node_message(user, path, arg_type, arg_path): post = Post() post.location = backend.get_node_for_path(path) post.author = get_system_user() post.post_type = Post.ARGUMENT_CREATED post.save() post.mentions = [user] post.node_references = [backend.get_node_for_path(arg_path), post.location] post.render() # email notification notify_new_argument(post.location, post) return post
def load_graph_data(request, path, graph_data_type): if not path.strip("/"): # root node! nodes = [backend.get_root_node()] # related_nodes = [] else: slot_path = path.rsplit(".", 1)[0] slot = assert_node_for_path(slot_path) if graph_data_type == "withSpam": # This means display ALL nodes nodes = backend.get_ordered_children_for(slot) else: # if graph_data_type == 'full': nodes = ( backend.Node.objects.filter(parents=slot) .annotate(spam_count=Count("spam_flags", distinct=True)) .filter(spam_count__lt=2) .filter(votes__isnull=False) ) current_node = backend.get_node_for_path(path) nodes = list(nodes) if current_node not in nodes: nodes.append(current_node) graph_data_children = map(create_graph_data_node_for_structure_node, nodes) data = {"graphDataChildren": graph_data_children, "graphDataRelated": []} return json_response({"loadGraphDataResponse": data})
def create_graph_data_node_for_structure_node(node, slot=None, path=None, slot_path=None): if slot_path: slot = get_node_for_path(slot_path) if not path: path = get_good_path_for_structure_node(node, slot, slot_path) if slot: if not slot_path: slot_path = slot.get_a_path() origin_group = [ slot_path + '.' + str(n.get_index(slot)) for n in node.sources.filter(parents__in=[slot]).all() ] origin_group += [ n.get_a_path() for n in node.sources.exclude(parents__in=[slot]).all() ] else: origin_group = [n.get_a_path() for n in node.sources.all()] graph_data_node = dict( path=path, authorGroup=[create_user_info(a) for a in node.text.authors.all()], follows=node.votes.count(), spamFlags=node.spam_flags.count(), unFollows=node.get_unfollows(), newFollows=node.get_newfollows(), title=node.title, originGroup=[o.rstrip('/') for o in origin_group]) return graph_data_node
def load_text(request, path): prefix, path_type = parse_suffix(path) try: node = backend.get_node_for_path(prefix) except backend.IllegalPath: return json_error_response("IllegalPath", "Illegal Path: " + path) paragraphs = [ { "wikiText": "=" + node.title + "=\n" + node.text.text, "path": path, "isFollowing": node.votes.filter(user=request.user.id).count() > 0, "authorGroup": [create_user_info(a) for a in node.text.authors.all()], } ] for slot in backend.get_ordered_children_for(node): favorite = backend.get_favorite_if_slot(slot) paragraphs.append( { "wikiText": build_text(favorite, depth=2), "path": path + "/" + slot.title + "." + str(favorite.get_index(slot)), "isFollowing": favorite.votes.filter(user=request.user.id).count() > 0, "authorGroup": [create_user_info(a) for a in favorite.text.authors.all()], } ) return json_response( { "loadTextResponse": { "paragraphs": paragraphs, "isFollowing": node.votes.filter(user=request.user.id).count() > 0, } } )
def create_graph_data_node_for_structure_node(node, slot=None, path=None, slot_path=None): if slot_path: slot = get_node_for_path(slot_path) if not path: path = get_good_path_for_structure_node(node, slot, slot_path) if slot: if not slot_path: slot_path = slot.get_a_path() origin_group = [slot_path + '.' + str(n.get_index(slot)) for n in node.sources.filter(parents__in=[slot]).all()] origin_group += [n.get_a_path() for n in node.sources.exclude(parents__in=[slot]).all()] else: origin_group = [n.get_a_path() for n in node.sources.all()] graph_data_node = dict( path=path, authorGroup=[create_user_info(a) for a in node.text.authors.all()], follows=node.votes.count(), spamFlags=node.spam_flags.count(), unFollows=node.get_unfollows(), newFollows=node.get_newfollows(), title=node.title, originGroup=[o.rstrip('/') for o in origin_group] ) return graph_data_node
def store_derivate(path, arg_text, arg_type, derivate_wiki_text, author): node = get_node_for_path(path) arg_title, arg_text = backend.split_title_from_text(arg_text) slot_path = path.rsplit('.', 1)[0] slot = get_node_for_path(slot_path) structure_schema = backend.parse(derivate_wiki_text, None) score_tree = build_score_tree(node, structure_schema) new_node, path_couples = backend.create_derivate_from_structure_node_schema( structure_schema, slot, author, node, score_tree, arg_type, arg_title, arg_text) new_path = get_good_path_for_structure_node(new_node, slot, slot_path) return new_path, path_couples
def fork_node_and_add_slot(path, user, wiki_text): source_node = assert_node_for_path(path) authors = list(source_node.text.authors.all()) + [user] title = source_node.title # create fork fork = create_structureNode(title, source_node.text.text, authors) parent_slot_path = path.rsplit('.', 1)[0] parent_slot = get_node_for_path(parent_slot_path) parent_slot.append_child(fork) fork_path = parent_slot_path + '.' + str(fork.get_index(parent_slot)) short_titles = set() for slot in get_ordered_children_for(source_node): fork.append_child(slot) short_titles.add(slot.title) # create new slot plus node schema = parse(wiki_text, 'foo') short_title = turn_into_valid_short_title(schema['title'], short_titles) new_slot = create_slot(short_title) fork.append_child(new_slot) node = create_structure_from_structure_node_schema(schema, new_slot, user) arg_title = "Abschnitt über '{0}' fehlt.".format(schema['title']) source_node.add_derivate(fork, 'con', arg_title, authors=[user]) # auto follow follow_node(fork, user.id) follow_node(node, user.id) return fork_path
def create_alternatives_for_urheberrecht(path): ulf = create_user("ulf") timo = create_user("timo") slot_path = path.rsplit(".", 1)[0] slot = get_node_for_path(slot_path) w1 = "Reform des Urheberrechts sollte von der Basis kommen." a1 = create_structureNode("Urheberrecht", w1, authors=[ulf]) slot.append_child(a1) w2a = "Abschaffung des Urheberrechts!" a2a = create_structureNode("Kein Urheberrecht", w2a, authors=[ulf]) slot.append_child(a2a) w2b = "Völlige Abschaffung des Urheber- und Patentrechts!" a2b = create_structureNode("Kein Urheberrecht", w2b, authors=[ulf]) slot.append_child(a2b) arga = a2a.add_derivate( a2b, "con", "Patentrecht ist genauso böse", "Das patentrecht ist mindestens genauso schlimm und muss auch weg!", [ulf], ) w2c = "Völlige Abschaffung des Urheber- und Patentrechts! Außerdem Todesstrafe für alle Patentanwälte." a2c = create_structureNode("Kein Urheberrecht", w2c, authors=[timo]) slot.append_child(a2c) argb = a2b.add_derivate(a2c, "con", "Patentanwälte stinken!", "Dieses Pack gehört ausgerottet!", [timo]) # create votes original = get_node_for_path(path) hugo = create_user("hugo") hans = create_user("hans") hein = create_user("hein") create_vote(ulf, [a1]) create_vote(ulf, [a2a, a2b]) create_vote(timo, [a2c]) create_vote(hugo, [original]) create_vote(hein, [original]) create_vote(hans, [a1]) create_vote(hans, [a2b]) create_vote(hans, [arga]) create_vote(ulf, [arga]) create_spam_flag(hein, [argb]) create_spam_flag(hein, [a2c])
def load_index(request, path): try: node = backend.get_node_for_path(path) except backend.IllegalPath: return json_error_response("NonExistingNode", "Illegal Path: " + path) slot_list = backend.get_ordered_children_for(node) index_nodes = [create_index_node_for_slot(slot) for slot in slot_list] return json_response({"loadIndexResponse": index_nodes})
def post_new_derivate_for_node_message(user, original_path, derivate_path): post = Post() original_node = backend.get_node_for_path(original_path) derivate_node = backend.get_node_for_path(derivate_path) post.location = original_node post.post_type = Post.NODE_REFINED post.author = get_system_user() post.save() post.node_references = [original_node, derivate_node] post.mentions = [user] post.render() # email notification notify_derivate(original_node, post) return post
def load_argument_index(request, path): prefix, path_type = parse_suffix(path) try: node = backend.get_node_for_path(prefix) except backend.IllegalPath: return json_error_response("NonExistingNode", "Illegal Path: " + path) argument_list = backend.get_ordered_arguments_for(node) data = [create_index_node_for_argument(a, node) for a in argument_list] return json_response({"loadIndexResponse": data})
def post_node_was_unflagged_message(path, user): post = Post() post.location = backend.get_node_for_path(path) post.author = get_system_user() post.post_type = Post.SPAM_UNMARKED post.save() post.mentions = [user] post.node_references = [post.location] post.render() return post
def store_derivate(path, arg_text, arg_type, derivate_wiki_text, author): new_node, new_path = store_structure_node(path, derivate_wiki_text, author) node = get_node_for_path(path) arg_title, arg_text = backend.split_title_from_text(arg_text) arg = node.add_derivate(new_node, arg_type=arg_type, title=arg_title, text=arg_text, authors=[author]) # add auto follow create_vote(author, [arg]) return new_path
def store_structure_node(path, wiki_text, author): slot_path = path.rsplit('.', 1)[0] slot = get_node_for_path(slot_path) structure = backend.parse(wiki_text, None) structure_node = backend.create_structure_from_structure_node_schema( structure, slot, [author]) # add auto follow create_vote(author, [structure_node]) return structure_node, get_good_path_for_structure_node(structure_node, slot, slot_path)
def load_microblogging(request, path, select_id, microblogging_load_type): try: node = backend.get_node_for_path(path) except backend.IllegalPath: return json_error_response('Illegal path','Illegal path: '+path) if microblogging_load_type == "newer": startpoint = Q(id__gt=select_id) else: # older startpoint = Q(id__lt=select_id) posts = node.microblogging_references.filter(startpoint).prefetch_related('author', 'is_reference_to')[:20] return json_response({'loadMicrobloggingResponse':convert_response_list(reversed(posts))})
def store_argument(path, arg_text, arg_type, author): node = get_node_for_path(path) title, arg_text = backend.split_title_from_text(arg_text) original_argument = create_argument(node, arg_type, title, arg_text, [author]) # add auto follow create_vote(author, [original_argument]) # copy argument for all derivates for d in node.traverse_derivates(): new_argument = create_argument(d, arg_type, title, arg_text, [author]) original_argument.add_derivate(new_argument) return path + "." + arg_type + "." + str(node.arguments.count())
def store_structure_node(path, wiki_text, author, argument=None): slot_path = path.rsplit('.', 1)[0] slot = get_node_for_path(slot_path) structure_schema = backend.parse(wiki_text, None) clone_candidates = None if argument: clone_candidates = slot.children.all() structure_node = backend.create_structure_from_structure_node_schema( structure_schema, slot, author, clone_candidates) # add auto follow create_vote(author, [structure_node]) return structure_node, get_good_path_for_structure_node(structure_node, slot, slot_path)
def mark_node(request, path, mark_type): """ If an argument is marked but wasn't created at this location it must be copied and the marking is to apply to the copied one. """ if not request.user.is_authenticated: return json_response({"error": "You're not authenticated."}) user = request.user try: node = backend.get_node_for_path(path) except backend.IllegalPath: return json_error_response("Illegal Path", "Illegal Path: " + path) if not node: return json_response({"error": "Invalid path."}) if mark_type in ("spam", "notspam"): MarkClass = backend.SpamFlag marks = node.spam_flags.filter(user=user.id) else: # follow or unfollow MarkClass = backend.Vote marks = node.votes.filter(user=user.id) if marks.count() >= 1: # TODO: if a mark changes for a node that mark has to be copied mark = marks[0] else: mark = MarkClass() mark.user_id = request.user.id or 1 # TODO FIXME: Why can this be none during testing? mark.save() mark.nodes.add(node) mark.save() ## @jonny: I don't understand what this is for. Seems wrong to me: # if backend.get_similar_path(node, path) != path: #This means it is an argument which wasn't created here # a = backend.Argument() # a.concerns = backend.get_path_parent(node, path) # a.arg_type = node.arg_type # a.parents = node.parents # a.sources = node.sources # a.node_type = node.node_type # a.save() # t = backend.Text() # t.node = a # t.text = node.text_object.text # t.authors = node.text_object.authors # t.save() # node = a return json_response({"markNodeResponse": {}})
def load_graph_data(request, path, graph_data_type): if not path.strip("/"): # root node! nodes = [backend.get_root_node()] related_nodes = [] else: slot_path = path.rsplit(".", 1)[0] try: slot = backend.get_node_for_path(slot_path) except backend.IllegalPath: return json_error_response("NonExistingNode", "Could not find slot: " + slot_path + " for node " + path) nodes = backend.get_ordered_children_for(slot) sources = Q(derivates__in=nodes) derivates = Q(sources__in=nodes) related_nodes = ( backend.Node.objects.filter(sources | derivates).exclude(id__in=[n.id for n in nodes]).distinct().all() ) graph_data_children = [create_graph_data_node_for_structure_node(n) for n in nodes] graph_data_related = [create_graph_data_node_for_structure_node(n) for n in related_nodes] data = {"graphDataChildren": graph_data_children, "graphDataRelated": graph_data_related} return json_response({"loadGraphDataResponse": data})
def load_graph_data(request, path, graph_data_type): if not path.strip('/'): # root node! nodes = [backend.get_root_node()] # related_nodes = [] else: slot_path = path.rsplit('.', 1)[0] slot = assert_node_for_path(slot_path) if graph_data_type == "withSpam": # This means display ALL nodes nodes = backend.get_ordered_children_for(slot) else: # if graph_data_type == 'full': nodes = backend.Node.objects.filter(parents=slot)\ .annotate(spam_count=Count('spam_flags', distinct=True))\ .filter(spam_count__lt=2)\ .filter(votes__isnull=False) current_node = backend.get_node_for_path(path) nodes = list(nodes) if current_node not in nodes: nodes.append(current_node) graph_data_children = map(create_graph_data_node_for_structure_node, nodes) data = {'graphDataChildren': graph_data_children, 'graphDataRelated': []} return json_response({'loadGraphDataResponse': data})
def assert_node_for_path(path): try: node = backend.get_node_for_path(path) except backend.IllegalPath: raise UnknownNode(path) return node