def _friend_item(users, user, item): """Parses a new friend item.""" # Sometimes API returns an empty new friend item: # { "date": 1390235880, "source_id": 1334862, "type": "friend" } if "friends" not in item: return None html = "" rows = [] for friend in item["friends"]["items"]: friend = users[friend["uid"]] friend_url = _get_user_url(friend["id"]) rows.append([ _link(friend_url, _image(friend["photo"])), _link(friend_url, friend["name"]), ]) html += _table(rows, column_spacing=7) if item["friends"]["count"] > len(item["friends"]["items"]): html += _block("[показаны не все новые друзья]") return { "title": user["name"] + ": новые друзья", "text": html, "url": _vk_url("friends?id={}§ion=all".format(user["id"])), }
def _friend_item(users, user, item): """Parses a new friend item.""" # Sometimes API returns an empty new friend item: # { "date": 1390235880, "source_id": 1334862, "type": "friend" } if "friends" not in item: return None html = "" friends = item["friends"][1:] rows = [] for friend in friends: friend = users[friend["uid"]] friend_url = _get_user_url(friend["id"]) rows.append([ _link(friend_url, _image(friend["photo"])), _link(friend_url, friend["name"]), ]) html += _table(rows, column_spacing=7) if item["friends"][0] > len(friends): html += _block("[показаны не все новые друзья]") return { "title": user["name"] + ": новые друзья", "text": html, "url": _vk_url("friends?id={}§ion=all".format(user["id"])), }
def _parse_text(html): """Parses a post text.""" html = _TEXT_URL_RE.sub(r"\1" + _link(r"\2", r"\2") + r"\3", html) html = _DOMAIN_ONLY_TEXT_URL_RE.sub(r"\1" + _link(r"http://\2", r"\2") + r"\3", html) html = _USER_LINK_RE.sub(_em(_link(_vk_url(r"\1"), r"\2")), html) return html.strip()
def _parse_text(html): """Parses a post text.""" html = _TEXT_URL_RE.sub(r"\1" + _link(r"\2", r"\2") + r"\3", html) html = _DOMAIN_ONLY_TEXT_URL_RE.sub( r"\1" + _link(r"http://\2", r"\2") + r"\3", html) html = _USER_LINK_RE.sub(_em(_link(_vk_url(r"\1"), r"\2")), html) return html.strip()
def _photo_item(users, user, api_item): """Parses a photo item.""" if api_item["type"] == "photo": title = "новые фотографии" photos = api_item["photos"] get_photo_url = lambda photo: _vk_url("feed?" + urlencode({ "section": "photos", "z": "photo{owner_id}_{photo_id}/feed1_{source_id}_{timestamp}".format( owner_id=photo["owner_id"], photo_id=photo["pid"], source_id=api_item["source_id"], timestamp=api_item["date"])})) elif api_item["type"] == "photo_tag": title = "новые отметки на фотографиях" photos = api_item["photo_tags"] get_photo_url = lambda photo: _vk_url("feed?" + urlencode({ "z": "photo{owner_id}_{photo_id}/feed3_{source_id}_{timestamp}".format( owner_id=photo["owner_id"], photo_id=photo["pid"], source_id=api_item["source_id"], timestamp=api_item["date"])})) else: raise Error("Logical error.") item = { "title": user["name"] + ": " + title, "text": "", } for photo in photos[1:]: url = get_photo_url(photo) item.setdefault("url", url) item["text"] += _block(_link(url, _image(photo["src_big"]))) if photos[0] > len(photos) - 1: item["text"] += _block("[показаны не все фотографии]") return item
def _parse_text(text, tweet_entities): """Parses a tweet text.""" sorted_entities = [] for entity_type, entities in tweet_entities.items(): for entity in entities: sorted_entities.append((entity_type, entity)) sorted_entities.sort( key=lambda entity_tuple: entity_tuple[1]["indices"][0], reverse=True) html = "" media_html = "" pos = len(text) for entity_type, entity in sorted_entities: start, end = entity["indices"] if end < pos: html = text[end:pos] + html if entity_type == "urls": html = _link(entity["expanded_url"], entity["display_url"]) + html elif entity_type == "user_mentions": html = _link(_twitter_user_url(entity["screen_name"]), entity["name"]) + html elif entity_type == "hashtags": html = _link( _TWITTER_URL + "search?" + urlencode( {"q": "#" + entity["full_text"]}), text[start:end]) + html elif entity_type == "media": html = _link(entity["expanded_url"], entity["display_url"]) + html media_html += _block( _link(entity["expanded_url"], _image(entity["media_url_https"]))) else: LOG.error("Unknown tweet entity:\n%s", pprint.pformat(entity)) html = text[start:end] + html pos = start if pos: html = text[:pos] + html return _block(html) + media_html
def _parse_text(text, tweet_entities): """Parses a tweet text.""" sorted_entities = [] for entity_type, entities in tweet_entities.items(): for entity in entities: sorted_entities.append(( entity_type, entity )) sorted_entities.sort( key=lambda entity_tuple: entity_tuple[1]["indices"][0], reverse=True) html = "" media_html = "" pos = len(text) for entity_type, entity in sorted_entities: start, end = entity["indices"] if end < pos: html = text[end:pos] + html if entity_type == "urls": html = _link(entity["expanded_url"], entity["display_url"]) + html elif entity_type == "user_mentions": html = _link(_twitter_user_url(entity["screen_name"]), entity["name"]) + html elif entity_type == "hashtags": html = _link(_TWITTER_URL + "search?" + urlencode({ "q": "#" + entity["text"] }), text[start:end]) + html elif entity_type == "media": html = _link(entity["expanded_url"], entity["display_url"]) + html media_html += _block(_link(entity["expanded_url"], _image(entity["media_url_https"]))) else: LOG.error("Unknown tweet entity:\n%s", pprint.pformat(entity)) html = text[start:end] + html pos = start if pos: html = text[:pos] + html return _block(html) + media_html
def _photo_item(users, user, api_item): """Parses a photo item.""" if api_item["type"] == "photo": title = "новые фотографии" photos = api_item["photos"] get_photo_url = lambda photo: _vk_url("feed?" + urlencode({ "section": "photos", "z": "photo{owner_id}_{photo_id}/feed1_{source_id}_{timestamp}".format( owner_id=photo["owner_id"], photo_id=photo["id"], source_id=api_item["source_id"], timestamp=api_item["date"]) })) elif api_item["type"] == "photo_tag": title = "новые отметки на фотографиях" photos = api_item["photo_tags"] get_photo_url = lambda photo: _vk_url("feed?" + urlencode({ "z": "photo{owner_id}_{photo_id}/feed3_{source_id}_{timestamp}".format( owner_id=photo["owner_id"], photo_id=photo["id"], source_id=api_item["source_id"], timestamp=api_item["date"]) })) else: raise Error("Logical error.") item = { "title": user["name"] + ": " + title, "text": "", } for photo in photos["items"]: url = get_photo_url(photo) item.setdefault("url", url) item["text"] += _block(_link(url, _image(photo["photo_604"]))) if photos["count"] > len(photos["items"]): item["text"] += _block("[показаны не все фотографии]") return item
def _post_item(users, user, item): """Parses a wall post item.""" attachment_order = ( "doc", "note", "page", "poll", "album", "posted_photo", "photo", "graffiti", "app", "video", "link", "audio", ) def attachment_sort_key(attachment): try: return attachment_order.index(attachment["type"]) except ValueError: return len(attachment_order) top_html = "" bottom_html = "" categories = set() unknown_attachments = set() attachments = sorted( item.get("attachments", []), key=attachment_sort_key) if not item["text"] and not attachments and "geo" in item: LOG.debug("Skip check-in item from %s from %s.", user["name"], item["date"]) return if ( "attachment" in item and item["text"] == item["attachment"][item["attachment"]["type"]].get("title") ): main_html = "" else: main_html = _parse_text(item["text"]) photo_count = functools.reduce( lambda count, attachment: count + ( attachment["type"] in ("app", "graffiti", "photo", "posted_photo") ), attachments, 0) big_image = photo_count == 1 for attachment in attachments: attachment_category = attachment["type"] # Notice: attachment object is not always stored in # attachment[attachment["type"]] - sometimes it's stored under a # different key, so we can't obtain it here for all attachment types. if attachment["type"] == "app": info = attachment[attachment["type"]] top_html += _block( _vk_link(_vk_id("app", info["app_id"]), _image(info["src_big" if big_image else "src"]))) elif attachment["type"] == "graffiti": info = attachment[attachment["type"]] top_html += _block( _vk_link(_vk_id("graffiti", info["gid"]), _image(info["src_big" if big_image else "src"]))) elif attachment["type"] == "link": info = attachment[attachment["type"]] link_block = _em("Ссылка: " + _link(info["url"], info["title"])) link_description = _parse_text(info["description"]) or info["title"] if "image_src" in info: if link_description: link_block += _image_block(info["url"], info["image_src"], link_description) else: link_block += _block(_link(info["url"], _image(info["image_src"]))) elif link_description: link_block += _block(link_description) top_html += _block(link_block) elif attachment["type"] == "album": info = attachment[attachment["type"]] top_html += _image_block( _vk_url("album", info["owner_id"], info["aid"]), info["thumb"]["src"], "Альбом: {description} ({size} фото)".format(description=info["description"].strip(), size=info["size"])) elif attachment["type"] == "photo": top_html += _photo(attachment[attachment["type"]], big_image) attachment_category = "posted_photo" elif attachment["type"] == "posted_photo": top_html += _photo(attachment[attachment["type"]], big_image) elif attachment["type"] == "photos_list": # It seems like photos_list always duplicates photo attachments attachment_category = "posted_photo" elif attachment["type"] == "audio": info = attachment[attachment["type"]] bottom_html += _block(_em( "Аудиозапись: " + _vk_link( "search?" + urlencode({ "c[q]": info["performer"] + " - " + info["title"], "c[section]": "audio" }), "{} - {} ({})".format(info["performer"], info["title"], _duration(info["duration"]))))) elif attachment["type"] == "doc": info = attachment[attachment["type"]] if "url" in info and "thumb" in info: bottom_html += _block(_image_block( info["url"], info["thumb"], _link(info["url"], info["title"]))) else: bottom_html += _block(_em("Документ: {}".format(info["title"]))) elif attachment["type"] == "video": info = attachment[attachment["type"]] top_html += _block( _image(info["image"]) + _block(_em("{} ({})".format(info["title"], _duration(info["duration"]))))) elif attachment["type"] == "note": top_html += _block(_em("Заметка: {}".format( attachment[attachment["type"]]["title"]))) elif attachment["type"] == "page": top_html += _block(_em("Страница: {}".format( attachment[attachment["type"]]["title"]))) elif attachment["type"] == "poll": top_html += _block(_em("Опрос: {}".format( attachment[attachment["type"]]["question"]))) else: unknown_attachments.add(attachment["type"]) categories.add(_CATEGORY_TYPE + attachment_category) if unknown_attachments: LOG.error("Got a post with unknown attachment type (%s):\n%s", ", ".join(unknown_attachments), pprint.pformat(item)) html = top_html + main_html + bottom_html if "copy_owner_id" in item and "copy_post_id" in item: html = _block( _em(_link( _get_user_url(item["copy_owner_id"]), users[item["copy_owner_id"]]["name"] )) + " пишет:" ) + html if "copy_text" in item: html = _quote_block(item["copy_text"], html) categories.add(_CATEGORY_TYPE_REPOST) return { "title": user["name"] + ": запись на стене", "text": html, "url": _vk_url("wall", user["id"], item["post_id"]), "categories": categories, }
def _vk_link(target, html): """Renders a VK link.""" return _link(_vk_url(target), html)
def _post_item(users, user, item): """Parses a wall post item.""" attachment_order = ( "doc", "note", "page", "poll", "album", "posted_photo", "photo", "graffiti", "app", "video", "link", "audio", ) def attachment_sort_key(attachment): try: return attachment_order.index(attachment["type"]) except ValueError: return len(attachment_order) top_html = "" bottom_html = "" categories = set() unknown_attachments = set() attachments = sorted(item.get("attachments", []), key=attachment_sort_key) if not item["text"] and not attachments and "geo" in item: LOG.debug("Skip check-in item from %s from %s.", user["name"], item["date"]) return if ("attachment" in item and item["text"] == item["attachment"][item["attachment"]["type"]].get("title")): main_html = "" else: main_html = _parse_text(item["text"]) photo_count = functools.reduce( lambda count, attachment: count + (attachment["type"] in ("app", "graffiti", "photo", "posted_photo")), attachments, 0) big_image = photo_count == 1 for attachment in attachments: attachment_category = attachment["type"] # Notice: attachment object is not always stored in # attachment[attachment["type"]] - sometimes it's stored under a # different key, so we can't obtain it here for all attachment types. if attachment["type"] == "app": info = attachment[attachment["type"]] top_html += _block( _vk_link( _vk_id("app", info["id"]), _image(info["photo_604" if big_image else "photo_130"]))) elif attachment["type"] == "graffiti": info = attachment[attachment["type"]] top_html += _block( _vk_link( _vk_id("graffiti", info["id"]), _image(info["photo_604" if big_image else "photo_130"]))) elif attachment["type"] == "link": info = attachment[attachment["type"]] link_block = _em("Ссылка: " + _link(info["url"], info["title"])) link_description = _parse_text( info["description"]) or info["title"] if "photo" in info: if link_description: link_block += _image_block(info["url"], info["photo"]["photo_130"], link_description) else: link_block += _block( _link(info["url"], _image(info["photo"]["photo_130"]))) elif link_description: link_block += _block(link_description) top_html += _block(link_block) elif attachment["type"] == "album": info = attachment[attachment["type"]] top_html += _image_block( _vk_url("album", info["owner_id"], info["id"]), info["thumb"]["photo_130"], "Альбом: {description} ({size} фото)".format( description=info["description"].strip(), size=info["size"])) elif attachment["type"] == "photo": top_html += _photo(attachment[attachment["type"]], big_image) attachment_category = "posted_photo" elif attachment["type"] == "posted_photo": top_html += _photo(attachment[attachment["type"]], big_image) elif attachment["type"] == "photos_list": # It seems like photos_list always duplicates photo attachments attachment_category = "posted_photo" elif attachment["type"] == "audio": info = attachment[attachment["type"]] bottom_html += _block( _em("Аудиозапись: " + _vk_link( "search?" + urlencode({ "c[q]": info["artist"] + " - " + info["title"], "c[section]": "audio" }), "{} - {} ({})".format(info["artist"], info["title"], _duration(info["duration"]))))) elif attachment["type"] == "doc": info = attachment[attachment["type"]] bottom_html += _block(_em("Документ: {}".format(info["title"]))) elif attachment["type"] == "video": info = attachment[attachment["type"]] video_block = _block( _em("{} ({})".format(info["title"], _duration(info["duration"])))) # Restricted videos may appear without image if "photo_320" in info: video_block = _block(_image(info["photo_320"]) + video_block) top_html += video_block categories.add(_CATEGORY_ATTACHMENT + "video/" + str(info["id"])) elif attachment["type"] == "note": top_html += _block( _em("Заметка: {}".format( attachment[attachment["type"]]["title"]))) elif attachment["type"] == "page": top_html += _block( _em("Страница: {}".format( attachment[attachment["type"]]["title"]))) elif attachment["type"] == "poll": top_html += _block( _em("Опрос: {}".format( attachment[attachment["type"]]["question"]))) else: unknown_attachments.add(attachment["type"]) categories.add(_CATEGORY_TYPE + attachment_category) if unknown_attachments: LOG.error("Got a post with unknown attachment type (%s):\n%s", ", ".join(unknown_attachments), pprint.pformat(item)) html = top_html + main_html + bottom_html if "copy_owner_id" in item and "copy_post_id" in item: html = _block( _em( _link(_get_user_url(item["copy_owner_id"]), users[ item["copy_owner_id"]]["name"])) + " пишет:") + html if "copy_text" in item: html = _quote_block(item["copy_text"], html) categories.add(_CATEGORY_TYPE_REPOST) return { "title": user["name"] + ": запись на стене", "text": html, "url": _vk_url("wall", user["id"], item["post_id"]), "categories": categories, }