Example #1
0
def import_comment(comment_el, asset, openid_for):
    jtalkid = comment_el.get("jtalkid")
    atom_id = "%s:talk:%s" % (asset.atom_id, jtalkid)
    logging.debug("Yay importing comment %s", jtalkid)

    try:
        comment = Asset.objects.get(atom_id=atom_id)
    except Asset.DoesNotExist:
        comment = Asset(atom_id=atom_id)

    comment_props = {}
    for prop in comment_el.findall("props/prop"):
        key = prop.get("name")
        val = prop.get("value")
        comment_props[key] = val

    comment.title = comment_el.findtext("subject") or ""

    body = comment_el.findtext("body")
    if int(comment_props.get("opt_preformatted") or 0):
        comment.content = body
    else:
        logging.debug("    Oops, comment not preformatted, let's parse it")
        content_root = BeautifulSoup(body)
        format_soup(content_root)
        comment.content = str(content_root)

    comment.in_reply_to = asset
    comment.in_thread_of = asset.in_thread_of or asset

    poster = comment_el.get("poster")
    if poster:
        openid = openid_for(poster)
        logging.debug("    Saving %s as comment author", openid)
        comment.author = person_for_openid(openid)
    else:
        logging.debug("    Oh huh this comment was anonymous, fancy that")

    comment.imported = True
    comment.save()

    comment.private_to = asset.private_to.all()

    for reply_el in comment_el.findall("comments/comment"):
        import_comment(reply_el, comment, openid_for)
Example #2
0
def import_events(source, atomid_prefix, foafsource):
    tree = ElementTree.parse(source)

    username = tree.getroot().get("username")
    server = tree.getroot().get("server")
    server_domain = ".".join(server.rsplit(".", 2)[1:])
    openid_for = partial(generate_openid, server_domain)
    if atomid_prefix is None:
        atomid_prefix = "urn:lj:%s:atom1:%s:" % (server_domain, username)

    post_author = make_my_openid(openid_for(username))

    # First, if there's a FOAF, learn all my friends' names and faces.
    if foafsource:
        import_foaf(foafsource, server_domain)

    # Now update groups and friends, so we can knit the posts together right.
    group_objs = dict()
    for group in tree.findall("/friends/group"):
        id = int(group.findtext("id"))
        name = group.findtext("name")

        tag = "%sgroup:%d" % (atomid_prefix, id)
        group_obj, created = giraffe.friends.models.Group.objects.get_or_create(
            tag=tag, defaults={"display_name": name}
        )
        group_objs[id] = group_obj

    all_friends_tag = "%sfriends" % atomid_prefix
    all_friends_group, created = giraffe.friends.models.Group.objects.get_or_create(
        tag=all_friends_tag, defaults={"display_name": "Friends"}
    )

    for friend in tree.findall("/friends/friend"):
        friendname = friend.findtext("username")
        openid = openid_for(friendname)

        ident_person = person_for_openid(openid, friend.findtext("fullname"))

        # Update their groups.
        group_ids = tuple(int(groupnode.text) for groupnode in friend.findall("groups/group"))
        logging.debug("Setting %s's groups to %r", friendname, group_ids)
        ident_person.groups = [all_friends_group] + [group_objs[id] for id in group_ids]

    # Import the posts.
    for event in tree.findall("/events/event"):
        ditemid = event.get("ditemid")
        logging.debug("Parsing event %s", ditemid)
        atom_id = "%s%s" % (atomid_prefix, ditemid)

        try:
            post = Asset.objects.get(atom_id=atom_id)
        except Asset.DoesNotExist:
            post = Asset(atom_id=atom_id)

        event_props = {}
        for prop in event.findall("props/prop"):
            key = prop.get("name")
            val = prop.get("value")
            event_props[key] = val

        post.title = event.findtext("subject") or ""
        post.author = post_author

        publ = event.findtext("date")
        assert publ, "event has no date :("
        publ_dt = datetime.strptime(publ, "%Y-%m-%d %H:%M:%S")
        # TODO: is this in the account's timezone or what?
        post.published = publ_dt

        content_root = BeautifulSoup(event.findtext("event"))
        # Add line breaks to the post if it's not preformatted.
        if not int(event_props.get("opt_preformatted", 0)):
            format_soup(content_root)
        # Remove any lj-raw tags.
        for el in content_root.findAll(re.compile(r"lj-(?:raw|cut)")):
            # Replace it with its children.
            el_parent = el.parent
            el_index = el_parent.contents.index(el)
            el.extract()
            for child in reversed(list(el.contents)):
                el_parent.insert(el_index, child)
        # TODO: handle opt_nocomments prop
        # TODO: put music and mood in the post content
        # TODO: handle taglist prop
        post.content = str(content_root)

        post.imported = True
        post.save()
        logging.info("Saved new post %s (%s) as #%d", ditemid, post.title, post.pk)

        security = event.get("security")
        private_group = giraffe.friends.models.Group.objects.get(tag="private")
        if security == "private":
            logging.debug("Oh ho post %s is all fancy private", ditemid)
            post.private_to = [private_group]
        elif security == "usemask":
            bin = lambda s: str(s) if s <= 1 else bin(s >> 1) + str(s & 1)

            mask = int(event.get("allowmask"))
            logging.debug("Post %s has mask %s?", ditemid, bin(mask))

            if mask == 1:
                mask_groups = [all_friends_group]
                # Plus all the other bits are 0, so we'll add no other groups.
            else:
                mask_groups = list()

            for i in range(1, 30):
                mask = mask >> 1
                if mask == 0:
                    break
                logging.debug("    Remaining mask %s", bin(mask))
                if mask & 0x01:
                    logging.debug("    Yay %s has group %d!", ditemid, i)
                    if i in group_objs:
                        logging.debug("    And group %d exists woohoo!!", i)
                        mask_groups.append(group_objs[i])

            logging.debug("So post %s gets %d groups", ditemid, len(mask_groups))
            post.private_to = mask_groups

        # Import the comments.
        for comment in event.findall("comments/comment"):
            import_comment(comment, post, openid_for)