code:
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2011 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 14:41+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Chinese (China) (http://www.transifex.com/gnu-social/gnu-social/language/zh_CN/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: zh_CN\n"
"Plural-Forms: nplurals=1; plural=0;\n"

#. TRANS: Link to subscribe to a remote entity.
#. TRANS: Link text for a user to subscribe to an OStatus user.
#: OStatusPlugin.php:206 OStatusPlugin.php:227 OStatusPlugin.php:1196
msgid "Subscribe"
msgstr "关注"

#. TRANS: Exception in OStatus when invalid URI was entered.
#: OStatusPlugin.php:249 OStatusPlugin.php:284
msgid "Invalid URI."
msgstr ""

#. TRANS: Error message in OStatus plugin. Do not translate the domain names
#. example.com
#. TRANS: and example.net, as these are official standard domain names for use
#. in examples.
#: OStatusPlugin.php:258 OStatusPlugin.php:291 actions/ostatussub.php:253
#: actions/ostatussub.php:261 actions/ostatussub.php:287
msgid ""
"Sorry, we could not reach that address. Please make sure that the OStatus "
"address is like nickname@example.com or http://example.net/nickname."
msgstr ""

#. TRANS: Title. %s is a domain name.
#: OStatusPlugin.php:519
#, php-format
msgid "Sent from %s via OStatus"
msgstr "从 %s 通过 OStatus 发布"

#. TRANS: Title for unfollowing a remote profile.
#: OStatusPlugin.php:657
msgctxt "TITLE"
msgid "Unfollow"
msgstr ""

#. TRANS: Success message for unsubscribe from user attempt through OStatus.
#. TRANS: %1$s is the unsubscriber's name, %2$s is the unsubscribed user's
#. name.
#: OStatusPlugin.php:660
#, php-format
msgid "%1$s stopped following %2$s."
msgstr "%1$s 取消了对 %2$s 的关注。"

#. TRANS: Title for joining a remote groep.
#: OStatusPlugin.php:707
msgctxt "TITLE"
msgid "Join"
msgstr "加入"

#. TRANS: Success message for subscribe to group attempt through OStatus.
#. TRANS: %1$s is the member name, %2$s is the subscribed group's name.
#: OStatusPlugin.php:710
#, php-format
msgid "%1$s has joined group %2$s."
msgstr "%1$s加入了%2$s小组。"

#. TRANS: Exception thrown when joining a remote group fails.
#: OStatusPlugin.php:719
msgid "Failed joining remote group."
msgstr "加入远程小组失败。"

#. TRANS: Title for leaving a remote group.
#: OStatusPlugin.php:761
msgctxt "TITLE"
msgid "Leave"
msgstr "离开"

#. TRANS: Success message for unsubscribe from group attempt through OStatus.
#. TRANS: %1$s is the member name, %2$s is the unsubscribed group's name.
#: OStatusPlugin.php:764
#, php-format
msgid "%1$s has left group %2$s."
msgstr ""

#. TRANS: Title for following a remote list.
#: OStatusPlugin.php:807
msgctxt "TITLE"
msgid "Follow list"
msgstr ""

#. TRANS: Success message for remote list follow through OStatus.
#. TRANS: %1$s is the subscriber name, %2$s is the list, %3$s is the lister's
#. name.
#: OStatusPlugin.php:810
#, php-format
msgid "%1$s is now following people listed in %2$s by %3$s."
msgstr ""

#. TRANS: Exception thrown when subscription to remote list fails.
#: OStatusPlugin.php:820
msgid "Failed subscribing to remote list."
msgstr ""

#. TRANS: Title for unfollowing a remote list.
#: OStatusPlugin.php:859
msgid "Unfollow list"
msgstr ""

#. TRANS: Success message for remote list unfollow through OStatus.
#. TRANS: %1$s is the subscriber name, %2$s is the list, %3$s is the lister's
#. name.
#: OStatusPlugin.php:862
#, php-format
msgid "%1$s stopped following the list %2$s by %3$s."
msgstr ""

#. TRANS: Title for listing a remote profile.
#: OStatusPlugin.php:938
msgctxt "TITLE"
msgid "List"
msgstr "列表"

#. TRANS: Success message for remote list addition through OStatus.
#. TRANS: %1$s is the list creator's name, %2$s is the added list member, %3$s
#. is the list name.
#: OStatusPlugin.php:941
#, php-format
msgid "%1$s listed %2$s in the list %3$s."
msgstr ""

#. TRANS: Title for unlisting a remote profile.
#: OStatusPlugin.php:989
msgctxt "TITLE"
msgid "Unlist"
msgstr ""

#. TRANS: Success message for remote list removal through OStatus.
#. TRANS: %1$s is the list creator's name, %2$s is the removed list member,
#. %3$s is the list name.
#: OStatusPlugin.php:992
#, php-format
msgid "%1$s removed %2$s from the list %3$s."
msgstr ""

#. TRANS: Title for unliking a remote notice.
#: OStatusPlugin.php:1039
msgid "Unlike"
msgstr ""

#. TRANS: Success message for remove a favorite notice through OStatus.
#. TRANS: %1$s is the unfavoring user's name, %2$s is URI to the no longer
#. favored notice.
#: OStatusPlugin.php:1042
#, php-format
msgid "%1$s no longer likes %2$s."
msgstr ""

#. TRANS: Link text for link to remote subscribe.
#: OStatusPlugin.php:1118
msgid "Remote"
msgstr "远程"

#. TRANS: Title for activity.
#: OStatusPlugin.php:1158
msgid "Profile update"
msgstr "个人信息更新"

#. TRANS: Ping text for remote profile update through OStatus.
#. TRANS: %s is user that updated their profile.
#: OStatusPlugin.php:1161
#, php-format
msgid "%s has updated their profile page."
msgstr "%s 更新了他/她的个人信息页。"

#. TRANS: Link text for a user to list an OStatus user.
#: OStatusPlugin.php:1205
msgid "List"
msgstr "列表"

#. TRANS: Plugin description.
#: OStatusPlugin.php:1220
msgid ""
"Follow people across social networks that implement <a "
"href=\"http://ostatus.org/\">OStatus</a>."
msgstr ""

#. TRANS: Client exception.
#: actions/pushhub.php:66
msgid "Publishing outside feeds not supported."
msgstr ""

#. TRANS: Client exception. %s is a mode.
#: actions/pushhub.php:69
#, php-format
msgid "Unrecognized mode \"%s\"."
msgstr ""

#. TRANS: Client exception. %s is a topic.
#: actions/pushhub.php:89
#, php-format
msgid ""
"Unsupported hub.topic %s this hub only serves local user and group Atom "
"feeds."
msgstr ""

#. TRANS: Client exception. %s is the invalid lease value.
#: actions/pushhub.php:95
#, php-format
msgid "Invalid hub.lease \"%s\". It must be empty or positive integer."
msgstr ""

#. TRANS: Client exception. %s is the invalid hub secret.
#: actions/pushhub.php:101
#, php-format
msgid "Invalid hub.secret \"%s\". It must be under 200 bytes."
msgstr ""

#. TRANS: Client exception. %s is a feed URL.
#: actions/pushhub.php:151
#, php-format
msgid "Invalid hub.topic \"%s\". User does not exist."
msgstr ""

#. TRANS: Client exception. %s is a feed URL.
#: actions/pushhub.php:160
#, php-format
msgid "Invalid hub.topic \"%s\". Group does not exist."
msgstr ""

#. TRANS: Client exception. %s is a feed URL.
#: actions/pushhub.php:176
#, php-format
msgid "Invalid hub.topic %s; list does not exist."
msgstr ""

#. TRANS: Client exception.
#. TRANS: %1$s is this argument to the method this exception occurs in, %2$s
#. is a URL.
#: actions/pushhub.php:202
#, php-format
msgid "Invalid URL passed for %1$s: \"%2$s\""
msgstr ""

#. TRANS: Field label.
#: actions/ostatusgroup.php:78
msgid "Join group"
msgstr "加入小组"

#. TRANS: Tooltip for field label "Join group". Do not translate the
#. "example.net"
#. TRANS: domain name in the URL, as it is an official standard domain name
#. for examples.
#: actions/ostatusgroup.php:82
msgid "OStatus group's address, like http://example.net/group/nickname."
msgstr "OStatus 小组的地址，例如 http://example.net/group/nickname。"

#. TRANS: Button text.
#. TRANS: Button text to continue joining a remote list.
#. TRANS: Button text.
#: actions/ostatusgroup.php:87 actions/ostatuspeopletag.php:82
#: actions/ostatussub.php:101
msgctxt "BUTTON"
msgid "Continue"
msgstr "继续"

#. TRANS: Error text displayed when trying to join a remote group the user is
#. already a member of.
#: actions/ostatusgroup.php:107
msgid "You are already a member of this group."
msgstr "你已经是该小组成员。"

#. TRANS: OStatus remote group subscription dialog error.
#: actions/ostatusgroup.php:142
msgid "Already a member!"
msgstr "已经是成员了！"

#. TRANS: OStatus remote group subscription dialog error.
#: actions/ostatusgroup.php:152
msgid "Remote group join failed!"
msgstr "加入远程小组失败！"

#. TRANS: Page title for OStatus remote group join form
#: actions/ostatusgroup.php:167
msgid "Confirm joining remote group"
msgstr "确认加入远程小组"

#. TRANS: Form instructions.
#: actions/ostatusgroup.php:178
msgid ""
"You can subscribe to groups from other supported sites. Paste the group's "
"profile URI below:"
msgstr ""

#. TRANS: Client error displayed when trying to list a local object as if it
#. is remote.
#: actions/ostatustag.php:40
msgid "You can use the local list functionality!"
msgstr ""

#. TRANS: Header for listing a remote object. %s is a remote object's name.
#: actions/ostatustag.php:54
#, php-format
msgid "List %s"
msgstr "列表 %s"

#. TRANS: Button text to list a remote object.
#: actions/ostatustag.php:56
msgctxt "BUTTON"
msgid "Go"
msgstr "转到"

#. TRANS: Field label.
#: actions/ostatustag.php:68 actions/ostatusinit.php:134
msgid "User nickname"
msgstr ""

#. TRANS: Field title.
#: actions/ostatustag.php:70
msgid "Nickname of the user you want to list."
msgstr ""

#. TRANS: Field label.
#: actions/ostatustag.php:74 actions/ostatusinit.php:144
msgid "Profile Account"
msgstr ""

#. TRANS: Field title.
#: actions/ostatustag.php:76
msgid "Your account id (for example user@example.com)."
msgstr ""

#. TRANS: Client error displayed when remote profile address could not be
#. confirmed.
#. TRANS: Client error.
#: actions/ostatustag.php:103 actions/ostatusinit.php:191
msgid "Could not confirm remote profile address."
msgstr ""

#. TRANS: Title for an OStatus list.
#: actions/ostatustag.php:121
msgid "OStatus list"
msgstr ""

#. TRANS: Client error displayed trying to perform an action without providing
#. an ID.
#. TRANS: Client error.
#: actions/peopletagsalmon.php:38 actions/usersalmon.php:36
#: actions/groupsalmon.php:38
msgid "No ID."
msgstr "没有 ID。"

#. TRANS: Client error displayed when referring to a non-existing list.
#. TRANS: Client error.
#: actions/peopletagsalmon.php:45 actions/ostatusinit.php:240
msgid "No such list."
msgstr "该名单不存在"

#. TRANS: Client error displayed when trying to send a message to a remote
#. list.
#: actions/peopletagsalmon.php:54
msgid "Cannot accept remote posts for a remote list."
msgstr ""

#. TRANS: Client error displayed when trying to subscribe a group to a list.
#. TRANS: Client error displayed when trying to unsubscribe a group from a
#. list.
#: actions/peopletagsalmon.php:91 actions/peopletagsalmon.php:124
msgid "Groups cannot subscribe to lists."
msgstr ""

#. TRANS: Server error displayed when subscribing a remote user to a list
#. fails.
#. TRANS: %1$s is a profile URI, %2$s is a list name.
#: actions/peopletagsalmon.php:109
#, php-format
msgid "Could not subscribe remote user %1$s to list %2$s."
msgstr ""

#. TRANS: Client error displayed when trying to unsubscribe a remote user from
#. a list fails.
#. TRANS: %1$s is a profile URL, %2$s is a list name.
#: actions/peopletagsalmon.php:133
#, php-format
msgid "Could not unsubscribe remote user %1$s from list %2$s."
msgstr ""

#. TRANS: Client error.
#: actions/ostatusinit.php:44
msgid "You can use the local subscription!"
msgstr ""

#. TRANS: Client error displayed when the session token does not match or is
#. not given.
#: actions/ostatusinit.php:68 actions/ostatussub.php:339
msgid "There was a problem with your session token. Try again, please."
msgstr "你的 session 出现了一个问题，请重试。"

#. TRANS: Form title.
#: actions/ostatusinit.php:85
msgctxt "TITLE"
msgid "Subscribe to user"
msgstr ""

#. TRANS: Form legend. %s is a group name.
#: actions/ostatusinit.php:101
#, php-format
msgid "Join group %s"
msgstr ""

#. TRANS: Button text to join a group.
#: actions/ostatusinit.php:103
msgctxt "BUTTON"
msgid "Join"
msgstr "加入"

#. TRANS: Form legend. %1$s is a list, %2$s is a lister's name.
#: actions/ostatusinit.php:106
#, php-format
msgid "Subscribe to list %1$s by %2$s"
msgstr ""

#. TRANS: Button text to subscribe to a list.
#. TRANS: Button text to subscribe to a profile.
#: actions/ostatusinit.php:108 actions/ostatusinit.php:114
msgctxt "BUTTON"
msgid "Subscribe"
msgstr "关注"

#. TRANS: Form legend. %s is a nickname.
#: actions/ostatusinit.php:112
#, php-format
msgid "Subscribe to %s"
msgstr ""

#. TRANS: Field label.
#: actions/ostatusinit.php:129
msgid "Group nickname"
msgstr ""

#. TRANS: Field title.
#: actions/ostatusinit.php:131
msgid "Nickname of the group you want to join."
msgstr ""

#. TRANS: Field title.
#: actions/ostatusinit.php:136
msgid "Nickname of the user you want to follow."
msgstr ""

#. TRANS: Tooltip for field label "Profile Account".
#: actions/ostatusinit.php:146
msgid "Your account ID (e.g. user@example.com)."
msgstr ""

#. TRANS: Client error.
#: actions/ostatusinit.php:168
msgid "Must provide a remote profile."
msgstr ""

#. TRANS: Client error.
#. TRANS: Client error displayed when referring to a non-existing user.
#: actions/ostatusinit.php:217 actions/ostatusinit.php:231
#: actions/usersalmon.php:43
msgid "No such user."
msgstr "没有这个用户。"

#. TRANS: Client error.
#: actions/ostatusinit.php:225 actions/groupsalmon.php:45
msgid "No such group."
msgstr "没有这个组。"

#. TRANS: Client error.
#: actions/ostatusinit.php:243
msgid "No local user or group nickname provided."
msgstr ""

#. TRANS: Page title.
#: actions/ostatusinit.php:250
msgid "OStatus Connect"
msgstr ""

#. TRANS: Server exception thrown when referring to a non-existing or empty
#. feed.
#: actions/pushcallback.php:51
msgid "Empty or invalid feed id."
msgstr ""

#. TRANS: Server exception. %s is a feed ID.
#: actions/pushcallback.php:57
#, php-format
msgid "Unknown PuSH feed id %s"
msgstr ""

#. TRANS: Client exception. %s is an invalid feed name.
#: actions/pushcallback.php:96
#, php-format
msgid "Bad hub.topic feed \"%s\"."
msgstr ""

#. TRANS: Client exception. %s is an invalid topic.
#: actions/pushcallback.php:103
#, php-format
msgid "Unexpected subscribe request for %s."
msgstr ""

#. TRANS: Client exception. %s is an invalid topic.
#: actions/pushcallback.php:108
#, php-format
msgid "Unexpected unsubscribe request for %s."
msgstr ""

#. TRANS: Client exception thrown when an undefied activity is performed.
#. TRANS: Client exception.
#: actions/usersalmon.php:71 classes/Ostatus_profile.php:510
msgid "Cannot handle that kind of post."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:95
msgid "Not to anyone in reply to anything."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:138 actions/usersalmon.php:170
msgid "Not a person object."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:145
msgid "Unidentified profile being listed."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:150
msgid "This user is not the one being listed."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:160
msgid "The listing could not be saved."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:177
msgid "Unidentified profile being unlisted."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:182
msgid "This user is not the one being unlisted."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:193
msgid "The listing could not be deleted."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:214
msgid "Cannot handle that kind of object for liking/faving."
msgstr ""

#. TRANS: Client exception. %s is an object ID.
#: actions/usersalmon.php:221
#, php-format
msgid "Notice with ID %s unknown."
msgstr ""

#. TRANS: Client exception. %1$s is a notice ID, %2$s is a user ID.
#: actions/usersalmon.php:226
#, php-format
msgid "Notice with ID %1$s not posted by %2$s."
msgstr ""

#. TRANS: Field label.
#: actions/ostatuspeopletag.php:74
msgid "Subscribe to list"
msgstr ""

#. TRANS: Field title.
#: actions/ostatuspeopletag.php:77
msgid "Address of the OStatus list, like http://example.net/user/all/tag."
msgstr ""

#. TRANS: Error text displayed when trying to subscribe to a list already a
#. subscriber to.
#: actions/ostatuspeopletag.php:102
msgid "You are already subscribed to this list."
msgstr ""

#. TRANS: OStatus remote group subscription dialog error.
#. TRANS: OStatus remote subscription dialog error.
#: actions/ostatuspeopletag.php:144 actions/ostatussub.php:318
msgid "Already subscribed!"
msgstr "已经关注了！"

#. TRANS: Page title for OStatus remote list subscription form
#: actions/ostatuspeopletag.php:165
msgid "Confirm subscription to remote list"
msgstr ""

#. TRANS: Instructions for OStatus list subscription form.
#: actions/ostatuspeopletag.php:177
msgid ""
"You can subscribe to lists from other supported sites. Paste the list's URI "
"below:"
msgstr ""

#. TRANS: Client error.
#: actions/groupsalmon.php:54
msgid "Cannot accept remote posts for a remote group."
msgstr ""

#. TRANS: Client error.
#: actions/groupsalmon.php:125
msgid "Groups cannot join groups."
msgstr ""

#. TRANS: Client error displayed when trying to join a group the user is
#. blocked from by a group admin.
#: actions/groupsalmon.php:138
msgid "You have been blocked from that group by the admin."
msgstr "你已经被管理员从该小组中屏蔽。"

#. TRANS: Server error. %1$s is a profile URI, %2$s is a group nickname.
#: actions/groupsalmon.php:145
#, php-format
msgid "Could not join remote user %1$s to group %2$s."
msgstr ""

#. TRANS: Client error displayed when trying to have a group join another
#. group.
#: actions/groupsalmon.php:157
msgid "Groups cannot be members of groups"
msgstr ""

#. TRANS: Server error. %1$s is a profile URI, %2$s is a group nickname.
#: actions/groupsalmon.php:166
#, php-format
msgid "Could not remove remote user %1$s from group %2$s."
msgstr ""

#. TRANS: Field label for a field that takes an OStatus user address.
#: actions/ostatussub.php:94
msgid "Subscribe to"
msgstr ""

#. TRANS: Tooltip for field label "Subscribe to".
#: actions/ostatussub.php:97
msgid ""
"OStatus user's address, like nickname@example.com or "
"http://example.net/nickname."
msgstr ""

#. TRANS: Button text.
#: actions/ostatussub.php:136
msgid "Join"
msgstr "加入"

#. TRANS: Tooltip for button "Join".
#: actions/ostatussub.php:138
msgctxt "BUTTON"
msgid "Join this group"
msgstr ""

#. TRANS: Button text.
#: actions/ostatussub.php:141
msgctxt "BUTTON"
msgid "Confirm"
msgstr "确认"

#. TRANS: Tooltip for button "Confirm".
#: actions/ostatussub.php:143
msgid "Subscribe to this user"
msgstr "关注这个用户"

#. TRANS: Extra paragraph in remote profile view when already subscribed.
#: actions/ostatussub.php:164
msgid "You are already subscribed to this user."
msgstr ""

#. TRANS: Error text.
#: actions/ostatussub.php:265 actions/ostatussub.php:269
#: actions/ostatussub.php:273 actions/ostatussub.php:277
#: actions/ostatussub.php:281
msgid ""
"Sorry, we could not reach that feed. Please try that OStatus address again "
"later."
msgstr ""

#. TRANS: OStatus remote subscription dialog error.
#: actions/ostatussub.php:323
msgid "Remote subscription failed!"
msgstr ""

#. TRANS: Form title.
#: actions/ostatussub.php:365
msgid "Subscribe to user"
msgstr ""

#. TRANS: Page title for OStatus remote subscription form.
#: actions/ostatussub.php:385
msgid "Confirm"
msgstr "确认"

#. TRANS: Instructions.
#: actions/ostatussub.php:397
msgid ""
"You can subscribe to users from other supported sites. Paste their address "
"or profile URI below:"
msgstr ""

#. TRANS: Server exception.
#: classes/FeedSub.php:219
msgid "Attempting to start PuSH subscription for feed with no hub."
msgstr ""

#. TRANS: Server exception.
#: classes/FeedSub.php:255
msgid "Attempting to end PuSH subscription for feed with no hub."
msgstr ""

#. TRANS: Client exception. %s is a HTTP status code.
#: classes/HubSub.php:163
#, php-format
msgid "Hub subscriber verification returned HTTP %s."
msgstr ""

#. TRANS: Exception. %1$s is a response status code, %2$s is the body of the
#. response.
#: classes/HubSub.php:269
#, php-format
msgid "Callback returned status: %1$s. Body: %2$s"
msgstr ""

#. TRANS: Server exception. %s is a URI
#: classes/Ostatus_profile.php:187 classes/Ostatus_profile.php:205
#, php-format
msgid "Invalid ostatus_profile state: Two or more IDs set for %s."
msgstr ""

#. TRANS: Server exception. %s is a URI
#: classes/Ostatus_profile.php:190 classes/Ostatus_profile.php:208
#, php-format
msgid "Invalid ostatus_profile state: All IDs empty for %s."
msgstr ""

#. TRANS: Server exception.
#: classes/Ostatus_profile.php:399
msgid ""
"Invalid type passed to Ostatus_profile::notify. It must be XML string or "
"Activity entry."
msgstr ""

#. TRANS: Exception.
#: classes/Ostatus_profile.php:432
msgid "Unknown feed format."
msgstr ""

#. TRANS: Exception.
#: classes/Ostatus_profile.php:456
msgid "RSS feed without a channel."
msgstr ""

#. TRANS: Client exception thrown when trying to share multiple activities at
#. once.
#: classes/Ostatus_profile.php:548
msgid "Can only handle share activities with exactly one object."
msgstr ""

#. TRANS: Client exception thrown when trying to share a non-activity object.
#: classes/Ostatus_profile.php:555
msgid "Can only handle shared activities."
msgstr ""

#: classes/Ostatus_profile.php:566
msgid "Shared activity does not have an id"
msgstr ""

#. TRANS: Client exception thrown when saving an activity share fails.
#. TRANS: %s is a share ID.
#: classes/Ostatus_profile.php:584
#, php-format
msgid "Failed to save activity %s."
msgstr ""

#. TRANS: Client exception. %s is a source URI.
#: classes/Ostatus_profile.php:616 classes/Ostatus_profile.php:783
#, php-format
msgid "No content for notice %s."
msgstr "通知 %s 没有内容。"

#. TRANS: Shown when a notice is longer than supported and/or when attachments
#. are present. At runtime
#. TRANS: this will usually be replaced with localised text from StatusNet
#. core messages.
#: classes/Ostatus_profile.php:651 classes/Ostatus_profile.php:818
msgid "Show more"
msgstr "显示更多"

#. TRANS: Exception. %s is a profile URL.
#: classes/Ostatus_profile.php:1015
#, php-format
msgid "Could not reach profile page %s."
msgstr ""

#. TRANS: Exception. %s is a URL.
#: classes/Ostatus_profile.php:1073 scripts/update_ostatus_profiles.php:187
#, php-format
msgid "Could not find a feed URL for profile page %s."
msgstr ""

#. TRANS: Feed sub exception.
#: classes/Ostatus_profile.php:1180
msgid "Cannot find enough profile information to make a feed."
msgstr ""

#. TRANS: Server exception. %s is a URL.
#: classes/Ostatus_profile.php:1244 scripts/update_ostatus_profiles.php:56
#, php-format
msgid "Invalid avatar URL %s."
msgstr ""

#. TRANS: Server exception. %s is a URI.
#: classes/Ostatus_profile.php:1257 scripts/update_ostatus_profiles.php:67
#, php-format
msgid "Tried to update avatar for unsaved remote profile %s."
msgstr ""

#. TRANS: Server exception. %s is a URL.
#: classes/Ostatus_profile.php:1267 scripts/update_ostatus_profiles.php:77
#, php-format
msgid "Unable to fetch avatar from %s."
msgstr ""

#. TRANS: Server exception.
#: classes/Ostatus_profile.php:1460
msgid "No author ID URI found."
msgstr ""

#. TRANS: Exception.
#: classes/Ostatus_profile.php:1486
msgid "No profile URI."
msgstr ""

#. TRANS: Exception.
#: classes/Ostatus_profile.php:1492
msgid "Local user cannot be referenced as remote."
msgstr ""

#. TRANS: Exception.
#: classes/Ostatus_profile.php:1497
msgid "Local group cannot be referenced as remote."
msgstr ""

#. TRANS: Exception.
#: classes/Ostatus_profile.php:1505
msgid "Local list cannot be referenced as remote."
msgstr ""

#. TRANS: Server exception.
#: classes/Ostatus_profile.php:1560 classes/Ostatus_profile.php:1599
msgid "Cannot save local profile."
msgstr ""

#. TRANS: Server exception.
#: classes/Ostatus_profile.php:1612
msgid "Cannot save local list."
msgstr ""

#. TRANS: Server exception.
#: classes/Ostatus_profile.php:1620
msgid "Cannot save OStatus profile."
msgstr ""

#. TRANS: Exception.
#: classes/Ostatus_profile.php:1933 classes/Ostatus_profile.php:1960
#: scripts/update_ostatus_profiles.php:212
msgid "Not a valid webfinger address."
msgstr ""

#. TRANS: Exception. %s is a webfinger address.
#: classes/Ostatus_profile.php:2042
#, php-format
msgid "Could not save profile for \"%s\"."
msgstr ""

#. TRANS: Exception. %s is a webfinger address.
#: classes/Ostatus_profile.php:2062
#, php-format
msgid "Could not save OStatus profile for \"%s\"."
msgstr ""

#. TRANS: Exception. %s is a webfinger address.
#: classes/Ostatus_profile.php:2070 scripts/update_ostatus_profiles.php:267
#, php-format
msgid "Could not find a valid profile for \"%s\"."
msgstr ""

#. TRANS: Server exception.
#: classes/Ostatus_profile.php:2113
msgid "Could not store HTML content of long post as file."
msgstr ""

#. TRANS: Server exception.
#. TRANS: %1$s is a protocol, %2$s is a URI.
#: classes/Ostatus_profile.php:2147
#, php-format
msgid "Unrecognized URI protocol for profile: %1$s (%2$s)."
msgstr ""

#. TRANS: Server exception. %s is a URI.
#: classes/Ostatus_profile.php:2154
#, php-format
msgid "No URI protocol for profile: %s."
msgstr ""

#. TRANS: Exception.
#: lib/magicenvelope.php:112
msgid "Unable to locate signer public key."
msgstr ""

#. TRANS: Exception when public key was not properly formatted.
#: lib/magicenvelope.php:131
msgid "Incorrectly formatted public key element."
msgstr ""

#: lib/magicenvelope.php:213
msgid "Salmon post must be an Atom entry."
msgstr ""

#. TRANS: Client error. Do not translate "application/magic-envelope+xml".
#: lib/salmonaction.php:46
msgid "Salmon requires \"application/magic-envelope+xml\"."
msgstr ""

#. TRANS: Exception.
#: lib/salmonaction.php:59
msgid "Received a salmon slap from unidentified actor."
msgstr ""

#. TRANS: Client error.
#: lib/salmonaction.php:72
msgid "Salmon signature verification failed."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:121
msgid "Unrecognized activity type."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:137
msgid "This target does not understand posts."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:143
msgid "This target does not understand follows."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:149
msgid "This target does not understand unfollows."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:155
msgid "This target does not understand share events."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:161
msgid "This target does not understand joins."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:167
msgid "This target does not understand leave events."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:173
msgid "This target does not understand list events."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:179
msgid "This target does not understand unlist events."
msgstr ""

#. TRANS: String in the gettext speed test script. Unimportant.
#: tests/gettext-speedtest.php:58
msgid "Feeds"
msgstr "Feeds"


code:
# Translation file for GNU social - the free software social networking platform
# Copyright (C) 2015 - 2019 Free Software Foundation, Inc http://www.fsf.org
# This file is under https://www.gnu.org/licenses/agpl v3 or later
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-05 16:23+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Chinese (Taiwan) (http://www.transifex.com/gnu-social/gnu-social/language/zh_TW/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: zh_TW\n"
"Plural-Forms: nplurals=1; plural=0;\n"

#. TRANS: Link to subscribe to a remote entity.
#. TRANS: Link text for a user to subscribe to an OStatus user.
#: OStatusPlugin.php:206 OStatusPlugin.php:227 OStatusPlugin.php:1196
msgid "Subscribe"
msgstr ""

#. TRANS: Exception in OStatus when invalid URI was entered.
#: OStatusPlugin.php:249 OStatusPlugin.php:284
msgid "Invalid URI."
msgstr ""

#. TRANS: Error message in OStatus plugin. Do not translate the domain names
#. example.com
#. TRANS: and example.net, as these are official standard domain names for use
#. in examples.
#: OStatusPlugin.php:258 OStatusPlugin.php:291 actions/ostatussub.php:253
#: actions/ostatussub.php:261 actions/ostatussub.php:287
msgid ""
"Sorry, we could not reach that address. Please make sure that the OStatus "
"address is like nickname@example.com or http://example.net/nickname."
msgstr ""

#. TRANS: Title. %s is a domain name.
#: OStatusPlugin.php:519
#, php-format
msgid "Sent from %s via OStatus"
msgstr ""

#. TRANS: Title for unfollowing a remote profile.
#: OStatusPlugin.php:657
msgctxt "TITLE"
msgid "Unfollow"
msgstr ""

#. TRANS: Success message for unsubscribe from user attempt through OStatus.
#. TRANS: %1$s is the unsubscriber's name, %2$s is the unsubscribed user's
#. name.
#: OStatusPlugin.php:660
#, php-format
msgid "%1$s stopped following %2$s."
msgstr ""

#. TRANS: Title for joining a remote groep.
#: OStatusPlugin.php:707
msgctxt "TITLE"
msgid "Join"
msgstr ""

#. TRANS: Success message for subscribe to group attempt through OStatus.
#. TRANS: %1$s is the member name, %2$s is the subscribed group's name.
#: OStatusPlugin.php:710
#, php-format
msgid "%1$s has joined group %2$s."
msgstr ""

#. TRANS: Exception thrown when joining a remote group fails.
#: OStatusPlugin.php:719
msgid "Failed joining remote group."
msgstr ""

#. TRANS: Title for leaving a remote group.
#: OStatusPlugin.php:761
msgctxt "TITLE"
msgid "Leave"
msgstr ""

#. TRANS: Success message for unsubscribe from group attempt through OStatus.
#. TRANS: %1$s is the member name, %2$s is the unsubscribed group's name.
#: OStatusPlugin.php:764
#, php-format
msgid "%1$s has left group %2$s."
msgstr ""

#. TRANS: Title for following a remote list.
#: OStatusPlugin.php:807
msgctxt "TITLE"
msgid "Follow list"
msgstr ""

#. TRANS: Success message for remote list follow through OStatus.
#. TRANS: %1$s is the subscriber name, %2$s is the list, %3$s is the lister's
#. name.
#: OStatusPlugin.php:810
#, php-format
msgid "%1$s is now following people listed in %2$s by %3$s."
msgstr ""

#. TRANS: Exception thrown when subscription to remote list fails.
#: OStatusPlugin.php:820
msgid "Failed subscribing to remote list."
msgstr ""

#. TRANS: Title for unfollowing a remote list.
#: OStatusPlugin.php:859
msgid "Unfollow list"
msgstr ""

#. TRANS: Success message for remote list unfollow through OStatus.
#. TRANS: %1$s is the subscriber name, %2$s is the list, %3$s is the lister's
#. name.
#: OStatusPlugin.php:862
#, php-format
msgid "%1$s stopped following the list %2$s by %3$s."
msgstr ""

#. TRANS: Title for listing a remote profile.
#: OStatusPlugin.php:938
msgctxt "TITLE"
msgid "List"
msgstr ""

#. TRANS: Success message for remote list addition through OStatus.
#. TRANS: %1$s is the list creator's name, %2$s is the added list member, %3$s
#. is the list name.
#: OStatusPlugin.php:941
#, php-format
msgid "%1$s listed %2$s in the list %3$s."
msgstr ""

#. TRANS: Title for unlisting a remote profile.
#: OStatusPlugin.php:989
msgctxt "TITLE"
msgid "Unlist"
msgstr ""

#. TRANS: Success message for remote list removal through OStatus.
#. TRANS: %1$s is the list creator's name, %2$s is the removed list member,
#. %3$s is the list name.
#: OStatusPlugin.php:992
#, php-format
msgid "%1$s removed %2$s from the list %3$s."
msgstr ""

#. TRANS: Title for unliking a remote notice.
#: OStatusPlugin.php:1039
msgid "Unlike"
msgstr ""

#. TRANS: Success message for remove a favorite notice through OStatus.
#. TRANS: %1$s is the unfavoring user's name, %2$s is URI to the no longer
#. favored notice.
#: OStatusPlugin.php:1042
#, php-format
msgid "%1$s no longer likes %2$s."
msgstr ""

#. TRANS: Link text for link to remote subscribe.
#: OStatusPlugin.php:1118
msgid "Remote"
msgstr ""

#. TRANS: Title for activity.
#: OStatusPlugin.php:1158
msgid "Profile update"
msgstr ""

#. TRANS: Ping text for remote profile update through OStatus.
#. TRANS: %s is user that updated their profile.
#: OStatusPlugin.php:1161
#, php-format
msgid "%s has updated their profile page."
msgstr ""

#. TRANS: Link text for a user to list an OStatus user.
#: OStatusPlugin.php:1205
msgid "List"
msgstr ""

#. TRANS: Plugin description.
#: OStatusPlugin.php:1220
msgid ""
"Follow people across social networks that implement <a "
"href=\"http://ostatus.org/\">OStatus</a>."
msgstr ""

#. TRANS: Client exception.
#: actions/pushhub.php:66
msgid "Publishing outside feeds not supported."
msgstr ""

#. TRANS: Client exception. %s is a mode.
#: actions/pushhub.php:69
#, php-format
msgid "Unrecognized mode \"%s\"."
msgstr ""

#. TRANS: Client exception. %s is a topic.
#: actions/pushhub.php:89
#, php-format
msgid ""
"Unsupported hub.topic %s this hub only serves local user and group Atom "
"feeds."
msgstr ""

#. TRANS: Client exception. %s is the invalid lease value.
#: actions/pushhub.php:95
#, php-format
msgid "Invalid hub.lease \"%s\". It must be empty or positive integer."
msgstr ""

#. TRANS: Client exception. %s is the invalid hub secret.
#: actions/pushhub.php:101
#, php-format
msgid "Invalid hub.secret \"%s\". It must be under 200 bytes."
msgstr ""

#. TRANS: Client exception. %s is a feed URL.
#: actions/pushhub.php:151
#, php-format
msgid "Invalid hub.topic \"%s\". User does not exist."
msgstr ""

#. TRANS: Client exception. %s is a feed URL.
#: actions/pushhub.php:160
#, php-format
msgid "Invalid hub.topic \"%s\". Group does not exist."
msgstr ""

#. TRANS: Client exception. %s is a feed URL.
#: actions/pushhub.php:176
#, php-format
msgid "Invalid hub.topic %s; list does not exist."
msgstr ""

#. TRANS: Client exception.
#. TRANS: %1$s is this argument to the method this exception occurs in, %2$s
#. is a URL.
#: actions/pushhub.php:202
#, php-format
msgid "Invalid URL passed for %1$s: \"%2$s\""
msgstr ""

#. TRANS: Field label.
#: actions/ostatusgroup.php:78
msgid "Join group"
msgstr ""

#. TRANS: Tooltip for field label "Join group". Do not translate the
#. "example.net"
#. TRANS: domain name in the URL, as it is an official standard domain name
#. for examples.
#: actions/ostatusgroup.php:82
msgid "OStatus group's address, like http://example.net/group/nickname."
msgstr ""

#. TRANS: Button text.
#. TRANS: Button text to continue joining a remote list.
#. TRANS: Button text.
#: actions/ostatusgroup.php:87 actions/ostatuspeopletag.php:82
#: actions/ostatussub.php:101
msgctxt "BUTTON"
msgid "Continue"
msgstr ""

#. TRANS: Error text displayed when trying to join a remote group the user is
#. already a member of.
#: actions/ostatusgroup.php:107
msgid "You are already a member of this group."
msgstr ""

#. TRANS: OStatus remote group subscription dialog error.
#: actions/ostatusgroup.php:142
msgid "Already a member!"
msgstr ""

#. TRANS: OStatus remote group subscription dialog error.
#: actions/ostatusgroup.php:152
msgid "Remote group join failed!"
msgstr ""

#. TRANS: Page title for OStatus remote group join form
#: actions/ostatusgroup.php:167
msgid "Confirm joining remote group"
msgstr ""

#. TRANS: Form instructions.
#: actions/ostatusgroup.php:178
msgid ""
"You can subscribe to groups from other supported sites. Paste the group's "
"profile URI below:"
msgstr ""

#. TRANS: Client error displayed when trying to list a local object as if it
#. is remote.
#: actions/ostatustag.php:40
msgid "You can use the local list functionality!"
msgstr ""

#. TRANS: Header for listing a remote object. %s is a remote object's name.
#: actions/ostatustag.php:54
#, php-format
msgid "List %s"
msgstr ""

#. TRANS: Button text to list a remote object.
#: actions/ostatustag.php:56
msgctxt "BUTTON"
msgid "Go"
msgstr ""

#. TRANS: Field label.
#: actions/ostatustag.php:68 actions/ostatusinit.php:134
msgid "User nickname"
msgstr ""

#. TRANS: Field title.
#: actions/ostatustag.php:70
msgid "Nickname of the user you want to list."
msgstr ""

#. TRANS: Field label.
#: actions/ostatustag.php:74 actions/ostatusinit.php:144
msgid "Profile Account"
msgstr ""

#. TRANS: Field title.
#: actions/ostatustag.php:76
msgid "Your account id (for example user@example.com)."
msgstr ""

#. TRANS: Client error displayed when remote profile address could not be
#. confirmed.
#. TRANS: Client error.
#: actions/ostatustag.php:103 actions/ostatusinit.php:191
msgid "Could not confirm remote profile address."
msgstr ""

#. TRANS: Title for an OStatus list.
#: actions/ostatustag.php:121
msgid "OStatus list"
msgstr ""

#. TRANS: Client error displayed trying to perform an action without providing
#. an ID.
#. TRANS: Client error.
#: actions/peopletagsalmon.php:38 actions/usersalmon.php:36
#: actions/groupsalmon.php:38
msgid "No ID."
msgstr "無此通知"

#. TRANS: Client error displayed when referring to a non-existing list.
#. TRANS: Client error.
#: actions/peopletagsalmon.php:45 actions/ostatusinit.php:240
msgid "No such list."
msgstr ""

#. TRANS: Client error displayed when trying to send a message to a remote
#. list.
#: actions/peopletagsalmon.php:54
msgid "Cannot accept remote posts for a remote list."
msgstr ""

#. TRANS: Client error displayed when trying to subscribe a group to a list.
#. TRANS: Client error displayed when trying to unsubscribe a group from a
#. list.
#: actions/peopletagsalmon.php:91 actions/peopletagsalmon.php:124
msgid "Groups cannot subscribe to lists."
msgstr ""

#. TRANS: Server error displayed when subscribing a remote user to a list
#. fails.
#. TRANS: %1$s is a profile URI, %2$s is a list name.
#: actions/peopletagsalmon.php:109
#, php-format
msgid "Could not subscribe remote user %1$s to list %2$s."
msgstr ""

#. TRANS: Client error displayed when trying to unsubscribe a remote user from
#. a list fails.
#. TRANS: %1$s is a profile URL, %2$s is a list name.
#: actions/peopletagsalmon.php:133
#, php-format
msgid "Could not unsubscribe remote user %1$s from list %2$s."
msgstr ""

#. TRANS: Client error.
#: actions/ostatusinit.php:44
msgid "You can use the local subscription!"
msgstr ""

#. TRANS: Client error displayed when the session token does not match or is
#. not given.
#: actions/ostatusinit.php:68 actions/ostatussub.php:339
msgid "There was a problem with your session token. Try again, please."
msgstr ""

#. TRANS: Form title.
#: actions/ostatusinit.php:85
msgctxt "TITLE"
msgid "Subscribe to user"
msgstr ""

#. TRANS: Form legend. %s is a group name.
#: actions/ostatusinit.php:101
#, php-format
msgid "Join group %s"
msgstr ""

#. TRANS: Button text to join a group.
#: actions/ostatusinit.php:103
msgctxt "BUTTON"
msgid "Join"
msgstr ""

#. TRANS: Form legend. %1$s is a list, %2$s is a lister's name.
#: actions/ostatusinit.php:106
#, php-format
msgid "Subscribe to list %1$s by %2$s"
msgstr ""

#. TRANS: Button text to subscribe to a list.
#. TRANS: Button text to subscribe to a profile.
#: actions/ostatusinit.php:108 actions/ostatusinit.php:114
msgctxt "BUTTON"
msgid "Subscribe"
msgstr ""

#. TRANS: Form legend. %s is a nickname.
#: actions/ostatusinit.php:112
#, php-format
msgid "Subscribe to %s"
msgstr ""

#. TRANS: Field label.
#: actions/ostatusinit.php:129
msgid "Group nickname"
msgstr ""

#. TRANS: Field title.
#: actions/ostatusinit.php:131
msgid "Nickname of the group you want to join."
msgstr ""

#. TRANS: Field title.
#: actions/ostatusinit.php:136
msgid "Nickname of the user you want to follow."
msgstr ""

#. TRANS: Tooltip for field label "Profile Account".
#: actions/ostatusinit.php:146
msgid "Your account ID (e.g. user@example.com)."
msgstr ""

#. TRANS: Client error.
#: actions/ostatusinit.php:168
msgid "Must provide a remote profile."
msgstr ""

#. TRANS: Client error.
#. TRANS: Client error displayed when referring to a non-existing user.
#: actions/ostatusinit.php:217 actions/ostatusinit.php:231
#: actions/usersalmon.php:43
msgid "No such user."
msgstr "無此使用者"

#. TRANS: Client error.
#: actions/ostatusinit.php:225 actions/groupsalmon.php:45
msgid "No such group."
msgstr "無此使用者"

#. TRANS: Client error.
#: actions/ostatusinit.php:243
msgid "No local user or group nickname provided."
msgstr ""

#. TRANS: Page title.
#: actions/ostatusinit.php:250
msgid "OStatus Connect"
msgstr ""

#. TRANS: Server exception thrown when referring to a non-existing or empty
#. feed.
#: actions/pushcallback.php:51
msgid "Empty or invalid feed id."
msgstr ""

#. TRANS: Server exception. %s is a feed ID.
#: actions/pushcallback.php:57
#, php-format
msgid "Unknown PuSH feed id %s"
msgstr ""

#. TRANS: Client exception. %s is an invalid feed name.
#: actions/pushcallback.php:96
#, php-format
msgid "Bad hub.topic feed \"%s\"."
msgstr ""

#. TRANS: Client exception. %s is an invalid topic.
#: actions/pushcallback.php:103
#, php-format
msgid "Unexpected subscribe request for %s."
msgstr ""

#. TRANS: Client exception. %s is an invalid topic.
#: actions/pushcallback.php:108
#, php-format
msgid "Unexpected unsubscribe request for %s."
msgstr ""

#. TRANS: Client exception thrown when an undefied activity is performed.
#. TRANS: Client exception.
#: actions/usersalmon.php:71 classes/Ostatus_profile.php:510
msgid "Cannot handle that kind of post."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:95
msgid "Not to anyone in reply to anything."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:138 actions/usersalmon.php:170
msgid "Not a person object."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:145
msgid "Unidentified profile being listed."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:150
msgid "This user is not the one being listed."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:160
msgid "The listing could not be saved."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:177
msgid "Unidentified profile being unlisted."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:182
msgid "This user is not the one being unlisted."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:193
msgid "The listing could not be deleted."
msgstr ""

#. TRANS: Client exception.
#: actions/usersalmon.php:214
msgid "Cannot handle that kind of object for liking/faving."
msgstr ""

#. TRANS: Client exception. %s is an object ID.
#: actions/usersalmon.php:221
#, php-format
msgid "Notice with ID %s unknown."
msgstr ""

#. TRANS: Client exception. %1$s is a notice ID, %2$s is a user ID.
#: actions/usersalmon.php:226
#, php-format
msgid "Notice with ID %1$s not posted by %2$s."
msgstr ""

#. TRANS: Field label.
#: actions/ostatuspeopletag.php:74
msgid "Subscribe to list"
msgstr ""

#. TRANS: Field title.
#: actions/ostatuspeopletag.php:77
msgid "Address of the OStatus list, like http://example.net/user/all/tag."
msgstr ""

#. TRANS: Error text displayed when trying to subscribe to a list already a
#. subscriber to.
#: actions/ostatuspeopletag.php:102
msgid "You are already subscribed to this list."
msgstr ""

#. TRANS: OStatus remote group subscription dialog error.
#. TRANS: OStatus remote subscription dialog error.
#: actions/ostatuspeopletag.php:144 actions/ostatussub.php:318
msgid "Already subscribed!"
msgstr ""

#. TRANS: Page title for OStatus remote list subscription form
#: actions/ostatuspeopletag.php:165
msgid "Confirm subscription to remote list"
msgstr ""

#. TRANS: Instructions for OStatus list subscription form.
#: actions/ostatuspeopletag.php:177
msgid ""
"You can subscribe to lists from other supported sites. Paste the list's URI "
"below:"
msgstr ""

#. TRANS: Client error.
#: actions/groupsalmon.php:54
msgid "Cannot accept remote posts for a remote group."
msgstr ""

#. TRANS: Client error.
#: actions/groupsalmon.php:125
msgid "Groups cannot join groups."
msgstr ""

#. TRANS: Client error displayed when trying to join a group the user is
#. blocked from by a group admin.
#: actions/groupsalmon.php:138
msgid "You have been blocked from that group by the admin."
msgstr ""

#. TRANS: Server error. %1$s is a profile URI, %2$s is a group nickname.
#: actions/groupsalmon.php:145
#, php-format
msgid "Could not join remote user %1$s to group %2$s."
msgstr ""

#. TRANS: Client error displayed when trying to have a group join another
#. group.
#: actions/groupsalmon.php:157
msgid "Groups cannot be members of groups"
msgstr ""

#. TRANS: Server error. %1$s is a profile URI, %2$s is a group nickname.
#: actions/groupsalmon.php:166
#, php-format
msgid "Could not remove remote user %1$s from group %2$s."
msgstr ""

#. TRANS: Field label for a field that takes an OStatus user address.
#: actions/ostatussub.php:94
msgid "Subscribe to"
msgstr ""

#. TRANS: Tooltip for field label "Subscribe to".
#: actions/ostatussub.php:97
msgid ""
"OStatus user's address, like nickname@example.com or "
"http://example.net/nickname."
msgstr ""

#. TRANS: Button text.
#: actions/ostatussub.php:136
msgid "Join"
msgstr ""

#. TRANS: Tooltip for button "Join".
#: actions/ostatussub.php:138
msgctxt "BUTTON"
msgid "Join this group"
msgstr ""

#. TRANS: Button text.
#: actions/ostatussub.php:141
msgctxt "BUTTON"
msgid "Confirm"
msgstr "確認"

#. TRANS: Tooltip for button "Confirm".
#: actions/ostatussub.php:143
msgid "Subscribe to this user"
msgstr ""

#. TRANS: Extra paragraph in remote profile view when already subscribed.
#: actions/ostatussub.php:164
msgid "You are already subscribed to this user."
msgstr ""

#. TRANS: Error text.
#: actions/ostatussub.php:265 actions/ostatussub.php:269
#: actions/ostatussub.php:273 actions/ostatussub.php:277
#: actions/ostatussub.php:281
msgid ""
"Sorry, we could not reach that feed. Please try that OStatus address again "
"later."
msgstr ""

#. TRANS: OStatus remote subscription dialog error.
#: actions/ostatussub.php:323
msgid "Remote subscription failed!"
msgstr ""

#. TRANS: Form title.
#: actions/ostatussub.php:365
msgid "Subscribe to user"
msgstr ""

#. TRANS: Page title for OStatus remote subscription form.
#: actions/ostatussub.php:385
msgid "Confirm"
msgstr "確認"

#. TRANS: Instructions.
#: actions/ostatussub.php:397
msgid ""
"You can subscribe to users from other supported sites. Paste their address "
"or profile URI below:"
msgstr ""

#. TRANS: Server exception.
#: classes/FeedSub.php:219
msgid "Attempting to start PuSH subscription for feed with no hub."
msgstr ""

#. TRANS: Server exception.
#: classes/FeedSub.php:255
msgid "Attempting to end PuSH subscription for feed with no hub."
msgstr ""

#. TRANS: Client exception. %s is a HTTP status code.
#: classes/HubSub.php:163
#, php-format
msgid "Hub subscriber verification returned HTTP %s."
msgstr ""

#. TRANS: Exception. %1$s is a response status code, %2$s is the body of the
#. response.
#: classes/HubSub.php:269
#, php-format
msgid "Callback returned status: %1$s. Body: %2$s"
msgstr ""

#. TRANS: Server exception. %s is a URI
#: classes/Ostatus_profile.php:187 classes/Ostatus_profile.php:205
#, php-format
msgid "Invalid ostatus_profile state: Two or more IDs set for %s."
msgstr ""

#. TRANS: Server exception. %s is a URI
#: classes/Ostatus_profile.php:190 classes/Ostatus_profile.php:208
#, php-format
msgid "Invalid ostatus_profile state: All IDs empty for %s."
msgstr ""

#. TRANS: Server exception.
#: classes/Ostatus_profile.php:399
msgid ""
"Invalid type passed to Ostatus_profile::notify. It must be XML string or "
"Activity entry."
msgstr ""

#. TRANS: Exception.
#: classes/Ostatus_profile.php:432
msgid "Unknown feed format."
msgstr ""

#. TRANS: Exception.
#: classes/Ostatus_profile.php:456
msgid "RSS feed without a channel."
msgstr ""

#. TRANS: Client exception thrown when trying to share multiple activities at
#. once.
#: classes/Ostatus_profile.php:548
msgid "Can only handle share activities with exactly one object."
msgstr ""

#. TRANS: Client exception thrown when trying to share a non-activity object.
#: classes/Ostatus_profile.php:555
msgid "Can only handle shared activities."
msgstr ""

#: classes/Ostatus_profile.php:566
msgid "Shared activity does not have an id"
msgstr ""

#. TRANS: Client exception thrown when saving an activity share fails.
#. TRANS: %s is a share ID.
#: classes/Ostatus_profile.php:584
#, php-format
msgid "Failed to save activity %s."
msgstr ""

#. TRANS: Client exception. %s is a source URI.
#: classes/Ostatus_profile.php:616 classes/Ostatus_profile.php:783
#, php-format
msgid "No content for notice %s."
msgstr ""

#. TRANS: Shown when a notice is longer than supported and/or when attachments
#. are present. At runtime
#. TRANS: this will usually be replaced with localised text from StatusNet
#. core messages.
#: classes/Ostatus_profile.php:651 classes/Ostatus_profile.php:818
msgid "Show more"
msgstr ""

#. TRANS: Exception. %s is a profile URL.
#: classes/Ostatus_profile.php:1015
#, php-format
msgid "Could not reach profile page %s."
msgstr ""

#. TRANS: Exception. %s is a URL.
#: classes/Ostatus_profile.php:1073 scripts/update_ostatus_profiles.php:187
#, php-format
msgid "Could not find a feed URL for profile page %s."
msgstr ""

#. TRANS: Feed sub exception.
#: classes/Ostatus_profile.php:1180
msgid "Cannot find enough profile information to make a feed."
msgstr ""

#. TRANS: Server exception. %s is a URL.
#: classes/Ostatus_profile.php:1244 scripts/update_ostatus_profiles.php:56
#, php-format
msgid "Invalid avatar URL %s."
msgstr ""

#. TRANS: Server exception. %s is a URI.
#: classes/Ostatus_profile.php:1257 scripts/update_ostatus_profiles.php:67
#, php-format
msgid "Tried to update avatar for unsaved remote profile %s."
msgstr ""

#. TRANS: Server exception. %s is a URL.
#: classes/Ostatus_profile.php:1267 scripts/update_ostatus_profiles.php:77
#, php-format
msgid "Unable to fetch avatar from %s."
msgstr ""

#. TRANS: Server exception.
#: classes/Ostatus_profile.php:1460
msgid "No author ID URI found."
msgstr ""

#. TRANS: Exception.
#: classes/Ostatus_profile.php:1486
msgid "No profile URI."
msgstr ""

#. TRANS: Exception.
#: classes/Ostatus_profile.php:1492
msgid "Local user cannot be referenced as remote."
msgstr ""

#. TRANS: Exception.
#: classes/Ostatus_profile.php:1497
msgid "Local group cannot be referenced as remote."
msgstr ""

#. TRANS: Exception.
#: classes/Ostatus_profile.php:1505
msgid "Local list cannot be referenced as remote."
msgstr ""

#. TRANS: Server exception.
#: classes/Ostatus_profile.php:1560 classes/Ostatus_profile.php:1599
msgid "Cannot save local profile."
msgstr ""

#. TRANS: Server exception.
#: classes/Ostatus_profile.php:1612
msgid "Cannot save local list."
msgstr ""

#. TRANS: Server exception.
#: classes/Ostatus_profile.php:1620
msgid "Cannot save OStatus profile."
msgstr ""

#. TRANS: Exception.
#: classes/Ostatus_profile.php:1933 classes/Ostatus_profile.php:1960
#: scripts/update_ostatus_profiles.php:212
msgid "Not a valid webfinger address."
msgstr ""

#. TRANS: Exception. %s is a webfinger address.
#: classes/Ostatus_profile.php:2042
#, php-format
msgid "Could not save profile for \"%s\"."
msgstr ""

#. TRANS: Exception. %s is a webfinger address.
#: classes/Ostatus_profile.php:2062
#, php-format
msgid "Could not save OStatus profile for \"%s\"."
msgstr ""

#. TRANS: Exception. %s is a webfinger address.
#: classes/Ostatus_profile.php:2070 scripts/update_ostatus_profiles.php:267
#, php-format
msgid "Could not find a valid profile for \"%s\"."
msgstr ""

#. TRANS: Server exception.
#: classes/Ostatus_profile.php:2113
msgid "Could not store HTML content of long post as file."
msgstr ""

#. TRANS: Server exception.
#. TRANS: %1$s is a protocol, %2$s is a URI.
#: classes/Ostatus_profile.php:2147
#, php-format
msgid "Unrecognized URI protocol for profile: %1$s (%2$s)."
msgstr ""

#. TRANS: Server exception. %s is a URI.
#: classes/Ostatus_profile.php:2154
#, php-format
msgid "No URI protocol for profile: %s."
msgstr ""

#. TRANS: Exception.
#: lib/magicenvelope.php:112
msgid "Unable to locate signer public key."
msgstr ""

#. TRANS: Exception when public key was not properly formatted.
#: lib/magicenvelope.php:131
msgid "Incorrectly formatted public key element."
msgstr ""

#: lib/magicenvelope.php:213
msgid "Salmon post must be an Atom entry."
msgstr ""

#. TRANS: Client error. Do not translate "application/magic-envelope+xml".
#: lib/salmonaction.php:46
msgid "Salmon requires \"application/magic-envelope+xml\"."
msgstr ""

#. TRANS: Exception.
#: lib/salmonaction.php:59
msgid "Received a salmon slap from unidentified actor."
msgstr ""

#. TRANS: Client error.
#: lib/salmonaction.php:72
msgid "Salmon signature verification failed."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:121
msgid "Unrecognized activity type."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:137
msgid "This target does not understand posts."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:143
msgid "This target does not understand follows."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:149
msgid "This target does not understand unfollows."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:155
msgid "This target does not understand share events."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:161
msgid "This target does not understand joins."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:167
msgid "This target does not understand leave events."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:173
msgid "This target does not understand list events."
msgstr ""

#. TRANS: Client exception.
#: lib/salmonaction.php:179
msgid "This target does not understand unlist events."
msgstr ""

#. TRANS: String in the gettext speed test script. Unimportant.
#: tests/gettext-speedtest.php:58
msgid "Feeds"
msgstr ""

repo_name: spookie/gnu

license: mit


code:
#!/usr/bin/env php
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.

/**
 * @package   GNUsocial
 * @copyright 2010 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

define('INSTALLDIR', dirname(__DIR__, 3));
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');

$longoptions = array('dry-run');

$helptext = <<<END_OF_USERROLE_HELP
fixup_shadow.php [options]
Patches up stray ostatus_profile entries with corrupted shadow entries
for local users and groups.

     --dry-run  look but don't touch

END_OF_USERROLE_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

$dry = have_option('dry-run');

// Look for user.uri matches... These may not match up with the current
// URL schema if the site has changed names.
echo "Checking for bogus ostatus_profile entries matching user.uri...\n";

$user = new User();
$oprofile = new Ostatus_profile();
$user->joinAdd($oprofile, 'INNER', 'oprofile', 'uri');
$user->find();
$count = $user->N;
echo "Found $count...\n";

while ($user->fetch()) {
    $uri = $user->getUri();
    echo "user $user->id ($user->nickname) hidden by $uri";
    if ($dry) {
        echo " - skipping\n";
    } else {
        echo " - removing bogus ostatus_profile entry...";
        $evil = Ostatus_profile::getKV('uri', $uri);
        $evil->delete();
        echo "  ok\n";
    }
}
echo "\n";

// Also try user_group.uri matches for local groups.
// Not all group entries will have this filled out, though, as it's new!
echo "Checking for bogus ostatus_profile entries matching local user_group.uri...\n";
$group = new User_group();
$group->joinAdd(array('uri', 'ostatus_profile:uri'));
$group->joinAdd(array('id', 'local_group:group_id'));
$group->find();
$count = $group->N;
echo "Found $count...\n";

while ($group->fetch()) {
    $uri = $group->getUri();
    echo "group $group->id ($group->nickname) hidden by $uri";
    if ($dry) {
        echo " - skipping\n";
    } else {
        echo " - removing bogus ostatus_profile entry...";
        $evil = Ostatus_profile::getKV('uri', $uri);
        $evil->delete();
        echo "  ok\n";
    }
}
echo "\n";

// And there may be user_group entries remaining where we've already killed
// the ostatus_profile. These were "harmless" until our lookup started actually
// using the uri field, at which point we can clearly see it breaks stuff.
echo "Checking for leftover bogus user_group.uri entries obscuring local_group entries...\n";

$group = new User_group();
$group->joinAdd(array('id', 'local_group:group_id'), 'LEFT');
$group->whereAdd('group_id IS NULL');

$marker = mt_rand(31337, 31337000);
$groupTemplate = common_local_url('groupbyid', array('id' => $marker));
$encGroup = $group->escape($groupTemplate, true);
$encGroup = str_replace($marker, '%', $encGroup);
echo "  LIKE '$encGroup'\n";
$group->whereAdd("uri LIKE '$encGroup'");

$group->find();
$count = $group->N;
echo "Found $count...\n";

while ($group->fetch()) {
    $uri = $group->getUri();
    if (preg_match('!/group/(\d+)/id!', $uri, $matches)) {
        $id = intval($matches[1]);
        $local = Local_group::getKV('group_id', $id);
        if ($local) {
            $nick = $local->nickname;
        } else {
            $nick = '<deleted>';
        }
        echo "local group $id ($local->nickname) hidden by $uri (bogus group id $group->id)";
        if ($dry) {
            echo " - skipping\n";
        } else {
            echo " - removing bogus user_group entry...";
            $evil = User_group::getKV('id', $group->id);
            $evil->delete();
            echo "  ok\n";
        }
    }
}
echo "\n";

// Fallback?
echo "Checking for bogus profiles blocking local users/groups by URI pattern match...\n";
$oprofile = new Ostatus_profile();

$marker = mt_rand(31337, 31337000);

$profileTemplate = common_local_url('userbyid', array('id' => $marker));
$encProfile = $oprofile->escape($profileTemplate, true);
$encProfile = str_replace($marker, '%', $encProfile);
echo "  LIKE '$encProfile'\n";

$groupTemplate = common_local_url('groupbyid', array('id' => $marker));
$encGroup = $oprofile->escape($groupTemplate, true);
$encGroup = str_replace($marker, '%', $encGroup);
echo "  LIKE '$encGroup'\n";

$sql = "SELECT * FROM ostatus_profile WHERE uri LIKE '%s' OR uri LIKE '%s'";
$oprofile->query(sprintf($sql, $encProfile, $encGroup));

$count = $oprofile->N;
echo "Found $count...\n";

while ($oprofile->fetch()) {
    $uri = $oprofile->getUri();
    if (preg_match('!/group/(\d+)/id!', $oprofile->getUri(), $matches)) {
        $id = intval($matches[1]);
        $group = Local_group::getKV('group_id', $id);
        if ($group) {
            $nick = $group->nickname;
        } else {
            $nick = '<deleted>';
        }
        echo "group $id ($nick) hidden by $uri";
    } elseif (preg_match('!/user/(\d+)!', $uri, $matches)) {
        $id = intval($matches[1]);
        $user = User::getKV('id', $id);
        if ($user) {
            $nick = $user->nickname;
        } else {
            $nick = '<deleted>';
        }
        echo "user $id ($nick) hidden by $uri";
    } else {
        echo "$uri matched query, but we don't recognize it.\n";
        continue;
    }

    if ($dry) {
        echo " - skipping\n";
    } else {
        echo " - removing bogus ostatus_profile entry...";
        $evil = clone($oprofile);
        $evil->delete();
        echo "  ok\n";
    }
}

if ($count && $dry) {
    echo "NO CHANGES MADE -- To delete the bogus entries, run again without --dry-run option.\n";
} else {
    echo "done.\n";
}


code:
#!/usr/bin/env php
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.

/**
 * @package   GNUsocial
 * @copyright 2010 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

define('INSTALLDIR', dirname(__DIR__, 3));
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');

$longoptions = array('delete-inactive');
$shortoptions = 'd';

$helptext = <<<END_OF_HELP
gcfeeds.php [options]
Clean up feeds that no longer have subscribers.

    -d --delete-inactive    Delete inactive feeds from feedsub table.

END_OF_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

$delete_inactive = have_option('d', 'delete-inactive');
$delcount = 0;

$feedsub = new FeedSub();
$feedsub->find();
while ($feedsub->fetch()) {
    try {
        echo $feedsub->getUri() . " ({$feedsub->sub_state})";
        if ($feedsub->garbageCollect()) {
            if ($delete_inactive) {
                $delcount++;
                $feedsub->delete();
                echo " DELETED";
            }
            echo " INACTIVE\n";
        } else {
            echo " ACTIVE\n";
        }
    } catch (NoProfileException $e) {
        echo " DELETED (no profile)\n";
        $feedsub->delete();
        continue;
    } catch (NoUriException $e) {
        // Probably the getUri() call
        echo "[unknown] DELETED (no uri)\n";
        $feedsub->delete();
        continue;
    } catch (Exception $e) {
        echo " ERROR: {$e->getMessage()}\n";
    }
}

if ($delete_inactive) {
    echo "\nDeleted $delcount inactive feeds.\n";
}


code:
#!/usr/bin/env php
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.

/**
 * @package   GNUsocial
 * @copyright 2010 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

define('INSTALLDIR', dirname(__DIR__, 3));
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');

$helptext = <<<END_OF_HELP
resub-feed.php
Resubscribe to any soon expiring feeds. Default time to expiration is 1 day.

END_OF_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

try {
    $sub = FeedSub::renewalCheck();
} catch (NoResultException $e) {
    echo 'There were no expiring feeds.';
    exit;
}

while ($sub->fetch()) {
    echo "Renewing feed subscription\n\tExp.: {$sub->sub_end}\n\tFeed: {$sub->uri}\n\tHub:  {$sub->huburi}\n";
    try {
        $sub->renew();
    } catch (Exception $e) {
        echo "FAILED: {$e->getMessage()}\n";
    }
}

echo "Done!";


code:
#!/usr/bin/env php
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.

/**
 * @package   GNUsocial
 * @copyright 2010 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

define('INSTALLDIR', dirname(__DIR__, 3));
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');

$longoptions = array('unsub');
$shortoptions = 'u';

$helptext = <<<END_OF_HELP
resub-feed.php [options] http://example.com/atom-feed-url
Reinitialize the WebSub subscription for the given feed. This may help get
things restarted if we and the hub have gotten our states out of sync.

Options:

   -u --unsub  Unsubscribe instead of subscribing.

END_OF_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

$validate = new Validate();

if (empty($args[0]) || !$validate->uri($args[0])) {
    print "$helptext";
    exit(1);
}

$feedurl = $args[0];

$sub = FeedSub::getKV('uri', $feedurl);
if (!$sub) {
    print "Feed $feedurl is not subscribed.\n";
    exit(1);
}

print "Old state:\n";
showSub($sub);

try {
    echo "\n";
    if (have_option('u') || have_option('--unsub')) {
        echo "Pinging hub {$sub->huburi} with unsubscription for {$sub->uri}\n";
        $sub->unsubscribe();
    } else {
        echo "Pinging hub {$sub->huburi} with new subscription for {$sub->uri}\n";
        $sub->subscribe();
    }
    echo "ok\n";
} catch (Exception $e) {
    echo 'Could not confirm. '.get_class($e).': '.$e->getMessage()."\n";
}

$sub2 = FeedSub::getKV('uri', $feedurl);

print "\n";
print "New state:\n";
showSub($sub2);

function showSub($sub)
{
    print "  Subscription state: $sub->sub_state\n";
    print "  Signature secret: $sub->secret\n";
    print "  Sub start date: $sub->sub_start\n";
    print "  Sub end date: $sub->sub_end\n";
    print "  Sub lease remaining: {$sub->getLeaseRemaining()}\n";
    print "  Record created: $sub->created\n";
    print "  Record modified: $sub->modified\n";
}


code:
#!/usr/bin/env php
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.

/**
 * @copyright 2010 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

/*
 *  Run this from INSTALLDIR/plugins/OStatus/scripts
 */

define('INSTALLDIR', dirname(__DIR__, 3));
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');

$shortoptions = 'd';
$longoptions = array('dry-run');

$helptext = <<<END_OF_HELP
rm_bad_feedsubs.php [options]
Deletes feedsub records that are in the inconsistent state of "subscribe"
and are older than one hour. If the hub hasn't answered back in an hour
the hub is probably either broken or doesn't exist.'

      Options:

    -d --dry-run look but don't mess with it

END_OF_HELP;

require_once INSTALLDIR . '/scripts/commandline.inc';

$dry = false;

if (have_option('d') || have_option('dry-run')) {
    $dry = true;
}

echo "Looking for feed subscriptions with dirty no good huburis...\n";

$feedsub = new FeedSub();
$feedsub->sub_state = 'subscribe';
$feedsub->whereAdd("created < (CURRENT_TIMESTAMP - INTERVAL '1' HOUR)");
$feedsub->find();
$cnt = 0;

while ($feedsub->fetch()) {
    echo "----------------------------------------------------------------------------------------\n";
    echo  '           feed: '
        . $feedsub->uri . "\n"
        . '        hub uri: '
        . $feedsub->huburi ."\n"
        . ' subscribe date: '
        . date('r', strtotime($feedsub->created)) . "\n";

    if (!$dry) {
        $feedsub->delete();
        echo "                 (DELETED)\n";
    } else {
        echo "                 (WOULD BE DELETED)\n";
    }
    echo "----------------------------------------------------------------------------------------\n";
    $cnt++;
}
if ($cnt == 0) {
    echo "None found.\n";
} else {
    echo "Deleted $cnt bogus hub URIs.\n";
}
echo "Done.\n";


code:
#!/usr/bin/env php
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.

/**
 * @package   GNUsocial
 * @copyright 2010 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

define('INSTALLDIR', dirname(__DIR__, 3));
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');

$longoptions = array('skip=', 'count=');

$helptext = <<<END_OF_HELP
testfeed.php [options] http://example.com/atom-feed-url
Pull an Atom feed and run items in it as though they were live WebSub updates.
Mainly intended for testing funky feed formats.

     --skip=N   Ignore the first N items in the feed.
     --count=N  Only process up to N items from the feed, after skipping.

END_OF_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

$validate = new Validate();

if (empty($args[0]) || !$validate->uri($args[0])) {
    print "$helptext";
    exit(1);
}

$feedurl = $args[0];
$skip = have_option('skip') ? intval(get_option_value('skip')) : 0;
$count = have_option('count') ? intval(get_option_value('count')) : 0;

$sub = FeedSub::getKV('uri', $feedurl);
if (!$sub) {
    print "Feed $feedurl is not subscribed.\n";
    exit(1);
}

// XXX: This could maybe be replaced with $sub->importFeed()

// Fetch the URL
try {
    $xml = HTTPClient::quickGet($feedurl, 'application/atom+xml');
} catch (Exception $e) {
    echo sprintf("Could not fetch feedurl %s (%d).\n", $e->getMessage(), $e->getCode());
    exit(1);
}

$feed = new DOMDocument();
if (!$feed->loadXML($xml)) {
    print "Bad XML.\n";
    exit(1);
}

if ($skip || $count) {
    $entries = $feed->getElementsByTagNameNS(ActivityUtils::ATOM, 'entry');
    $remove = array();
    for ($i = 0; $i < $skip && $i < $entries->length; $i++) {
        $item = $entries->item($i);
        if ($item) {
            $remove[] = $item;
        }
    }
    if ($count) {
        for ($i = $skip + $count; $i < $entries->length; $i++) {
            $item = $entries->item($i);
            if ($item) {
                $remove[] = $item;
            }
        }
    }
    foreach ($remove as $item) {
        $item->parentNode->removeChild($item);
    }
}

echo "Calling event StartFeedSubReceive\n";
Event::handle('StartFeedSubReceive', array($sub, $feed));


code:
#!/usr/bin/env php
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.

/**
 * @copyright 2010 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

define('INSTALLDIR', dirname(__DIR__, 3));
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');

$longoptions = array('all', 'suspicious', 'quiet');

$helptext = <<<END_OF_HELP
update-profile-data.php [options] [http://example.com/profile/url]

Rerun profile discovery for the given OStatus remote profile, and save the
updated profile data (nickname, fullname, avatar, bio, etc).
Doesn't touch feed state.
Can be used to clean up after breakages.

Options:
  --all        Run for all known OStatus profiles
  --suspicious Run for OStatus profiles with all-numeric nicknames
               (fixes 0.9.7 prerelease back-compatibility bug)

END_OF_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

function showProfileInfo(Ostatus_profile $oprofile)
{
    if ($oprofile->isGroup()) {
        echo "group\n";
    } else {
        $profile = $oprofile->localProfile();
        foreach (array('nickname', 'fullname', 'bio', 'homepage', 'location') as $field) {
            print "  $field: {$profile->$field}\n";
        }
    }
    echo "\n";
}

function fixProfile(Ostatus_profile $oprofile)
{
    echo "Before:\n";
    showProfileInfo($oprofile);

    $feedurl = $oprofile->feeduri;
    $client = new HTTPClient();
    $response = $client->get($feedurl);
    if ($response->isOk()) {
        echo "Updating profile from feed: $feedurl\n";
        $dom = new DOMDocument();
        if ($dom->loadXML($response->getBody())) {
            if ($dom->documentElement->tagName !== 'feed') {
                echo "  (no <feed> element in feed URL response; skipping)\n";
                return false;
            }
            $actorObj = ActivityUtils::getFeedAuthor($dom->documentElement);
            if ($actorObj) {
                $oprofile->updateFromActivityObject($actorObj);
                echo "  (ok)\n";
            } else {
                echo "  (no author on feed; skipping)\n";
                return false;
            }
        } else {
            echo "  (bad feed; skipping)\n";
            return false;
        }
    } else {
        echo "Failed feed fetch: {$response->getStatus()} for $feedurl\n";
        return false;
    }

    echo "After:\n";
    showProfileInfo($oprofile);
    return true;
}

$ok = true;
$validate = new Validate();
if (have_option('all')) {
    $oprofile = new Ostatus_profile();
    $oprofile->find();
    echo "Found $oprofile->N profiles:\n\n";
    while ($oprofile->fetch()) {
        try {
            $ok = fixProfile($oprofile) && $ok;
        } catch (Exception $e) {
            $ok = false;
            echo "Failed on URI=="._ve($oprofile->uri).": {$e->getMessage()}\n";
        }
    }
} elseif (have_option('suspicious')) {
    $oprofile = new Ostatus_profile();
    $oprofile->joinAdd(['profile_id', 'profile:id']);
    $oprofile->whereAdd("CHAR_LENGTH(nickname) = 1 AND nickname BETWEEN '0' AND '9'");
    $oprofile->find();
    echo "Found $oprofile->N matching profiles:\n\n";
    while ($oprofile->fetch()) {
        try {
            $ok = fixProfile($oprofile) && $ok;
        } catch (Exception $e) {
            $ok = false;
            echo "Failed on URI=="._ve($oprofile->uri).": {$e->getMessage()}\n";
        }
    }
} elseif (!empty($args[0]) && $validate->uri($args[0])) {
    $uri = $args[0];
    $oprofile = Ostatus_profile::getKV('uri', $uri);

    if (!$oprofile instanceof Ostatus_profile) {
        print "No OStatus remote profile known for URI $uri\n";
        return false;
    }

    try {
        $ok = fixProfile($oprofile) && $ok;
    } catch (Exception $e) {
        $ok = false;
        echo "Failed on URI=="._ve($oprofile->uri).": {$e->getMessage()}\n";
    }
} else {
    print "$helptext";
    $ok = false;
}

exit($ok ? 0 : 1);


code:
#!/usr/bin/env php
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.

/**
 * @package   GNUsocial
 * @copyright 2010 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

define('INSTALLDIR', dirname(__DIR__, 3));
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');

$helptext = <<<END_OF_HELP
update-profile.php [options] http://example.com/profile/url

Rerun profile and feed info discovery for the given OStatus remote profile,
and reinitialize its WebSub subscription for the given feed. This may help get
things restarted if the hub or feed URLs have changed for the profile.

END_OF_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

$validate = new Validate();

if (empty($args[0]) || !$validate->uri($args[0])) {
    print "$helptext";
    exit(1);
}

$uri = $args[0];

$oprofile = Ostatus_profile::getKV('uri', $uri);

if (!$oprofile) {
    print "No OStatus remote profile known for URI $uri\n";
    exit(1);
}

print "Old profile state for $oprofile->uri\n";
showProfile($oprofile);

print "\n";
print "Re-running feed discovery for profile URL $oprofile->uri\n";

$feedurl = null;
$salmonuri = null;

// @fixme will bork where the URI isn't the profile URL for now
$discover = new FeedDiscovery();
try {
    $feedurl = $discover->discoverFromURL($oprofile->uri);
    $salmonuri = $discover->getAtomLink(Salmon::REL_SALMON)
                    ?: $discover->getAtomLink(Salmon::NS_REPLIES);  // NS_REPLIES is deprecated
    if (empty($salmonuri)) {
        throw new FeedSubNoSalmonException('No salmon upstream URI was found');
    }
} catch (FeedSubException $e) {
    $acct = $oprofile->localProfile()->getAcctUri();
    print "Could not discover feeds HTML response, trying reconstructed acct URI: {$acct}\n";
    $disco = new Discovery();
    $xrd = $disco->lookup($acct);
    $hints = DiscoveryHints::fromXRD($xrd);

    if (array_key_exists('feedurl', $hints)) {
        // Prefer $hints['feedurl'] to current $feedurl value
        $feedurl = $hints['feedurl'];
    } elseif (empty($feedurl)) {
        // if (empty($feedurl) && !array_key_exists('feedurl', $hints))
        throw new FeedSubNoFeedException($acct);
    }

    $salmonuri = array_key_exists('salmon', $hints) ? $hints['salmon'] : $salmonuri;

    // get the hub data too and put it in the FeedDiscovery object
    $discover->discoverFromFeedUrl($feedurl);
}

$huburi = $discover->getHubLink();

print "  Feed URL: $feedurl\n";
print "  Hub URL: $huburi\n";
print "  Salmon URL: $salmonuri\n";

if ($feedurl != $oprofile->feeduri || $salmonuri != $oprofile->salmonuri) {
    print "\n";
    print "Updating...\n";
    // @fixme update keys :P
    #$orig = clone($oprofile);
    #$oprofile->feeduri = $feedurl;
    #$oprofile->salmonuri = $salmonuri;
    #$ok = $oprofile->update($orig);
    $ok = $oprofile->query('UPDATE ostatus_profile SET ' .
        'feeduri=\'' . $oprofile->escape($feedurl) . '\',' .
        'salmonuri=\'' . $oprofile->escape($salmonuri) . '\' ' .
        'WHERE uri=\'' . $oprofile->escape($uri) . '\'');

    if (!$ok) {
        print "Failed to update profile record...\n";
        exit(1);
    }

    $oprofile->decache();
} else {
    print "\n";
    print "Ok, ostatus_profile record unchanged.\n\n";
}

$sub = FeedSub::ensureFeed($feedurl);

if ($huburi != $sub->huburi) {
    print "\n";
    print "Updating hub record for feed; was $sub->huburi\n";
    $orig = clone($sub);
    $sub->huburi = $huburi;
    $ok = $sub->update($orig);

    if (!$ok) {
        print "Failed to update sub record...\n";
        exit(1);
    }
} else {
    print "\n";
    print "Feed record ok, not changing.\n\n";
}

echo "\n";
echo "Pinging hub {$sub->huburi} with new subscription for {$sub->uri}\n";
try {
    $sub->subscribe();
    echo "ok\n";
} catch (Exception $e) {
    echo 'Could not confirm. '.get_class($e).': '.$e->getMessage()."\n";
}

$o2 = Ostatus_profile::getKV('uri', $uri);

print "\n";
print "New profile state:\n";
showProfile($o2);

print "\n";
print "New feed state:\n";
$sub2 = FeedSub::ensureFeed($feedurl);
showSub($sub2);

function showProfile($oprofile)
{
    print "  Feed URL: $oprofile->feeduri\n";
    print "  Salmon URL: $oprofile->salmonuri\n";
    print "  Avatar URL: $oprofile->avatar\n";
    print "  Profile ID: $oprofile->profile_id\n";
    print "  Group ID: $oprofile->group_id\n";
    print "  Record created: $oprofile->created\n";
    print "  Record modified: $oprofile->modified\n";
}

function showSub($sub)
{
    print "  Subscription state: $sub->sub_state\n";
    print "  Signature secret: $sub->secret\n";
    print "  Sub start date: $sub->sub_start\n";
    print "  Record created: $sub->created\n";
    print "  Record modified: $sub->modified\n";
}


code:
#!/usr/bin/env php
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.

/**
 * @package   GNUsocial
 * @copyright 2011 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

define('INSTALLDIR', dirname(__DIR__, 3));
define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');

$shortoptions = 'u:af';
$longoptions = array('uri=', 'all', 'force');

$helptext = <<<UPDATE_OSTATUS_PROFILES
update_ostatus_profiles.php [options]
Refetch / update OStatus profile info and avatars. Useful if you
do something like accidentally delete your avatars directory when
you have no backup.

    -u --uri OStatus profile URI to update
    -a --all update all

    -f --force  Force update (despite identical avatar URLs etc.)

UPDATE_OSTATUS_PROFILES;

require_once INSTALLDIR . '/scripts/commandline.inc';

/*
 * Hacky class to remove some checks and get public access to
 * protected mentods
 */
class LooseOstatusProfile extends Ostatus_profile
{
    /**
     * Look up and if necessary create an Ostatus_profile for the remote entity
     * with the given profile page URL. This should never return null -- you
     * will either get an object or an exception will be thrown.
     *
     * @param string $profile_url
     * @return Ostatus_profile
     * @throws Exception on various error conditions
     * @throws OStatusShadowException if this reference would obscure a local user/group
     */
    public static function updateProfileURL($profile_url, $hints=array())
    {
        $oprofile = null;

        $hints['profileurl'] = $profile_url;

        // Fetch the URL
        // XXX: HTTP caching

        $client = new HTTPClient();
        $client->setHeader('Accept', 'text/html,application/xhtml+xml');
        $response = $client->get($profile_url);

        if (!$response->isOk()) {
            // TRANS: Exception. %s is a profile URL.
            throw new Exception(sprintf(_('Could not reach profile page %s.'), $profile_url));
        }

        // Check if we have a non-canonical URL

        $finalUrl = $response->getEffectiveUrl();

        if ($finalUrl != $profile_url) {
            $hints['profileurl'] = $finalUrl;
        }

        // Try to get some hCard data

        $body = $response->getBody();

        $hcardHints = DiscoveryHints::hcardHints($body, $finalUrl);

        if (!empty($hcardHints)) {
            $hints = array_merge($hints, $hcardHints);
        }

        // Check if they've got an LRDD header

        $lrdd = LinkHeader::getLink($response, 'lrdd', 'application/xrd+xml');
        try {
            $xrd = new XML_XRD();
            $xrd->loadFile($lrdd);
            $xrdHints = DiscoveryHints::fromXRD($xrd);
            $hints = array_merge($hints, $xrdHints);
        } catch (Exception $e) {
            // No hints available from XRD
        }

        // If discovery found a feedurl (probably from LRDD), use it.

        if (array_key_exists('feedurl', $hints)) {
            return self::ensureFeedURL($hints['feedurl'], $hints);
        }

        // Get the feed URL from HTML

        $discover = new FeedDiscovery();

        $feedurl = $discover->discoverFromHTML($finalUrl, $body);

        if (!empty($feedurl)) {
            $hints['feedurl'] = $feedurl;
            return self::ensureFeedURL($feedurl, $hints);
        }

        // TRANS: Exception. %s is a URL.
        throw new Exception(sprintf(_m('Could not find a feed URL for profile page %s.'), $finalUrl));
    }

    /**
     * Look up, and if necessary create, an Ostatus_profile for the remote
     * entity with the given webfinger address.
     * This should never return null -- you will either get an object or
     * an exception will be thrown.
     *
     * @param string $addr webfinger address
     * @return Ostatus_profile
     * @throws Exception on error conditions
     * @throws OStatusShadowException if this reference would obscure a local user/group
     */
    public static function updateWebfinger($addr)
    {
        $disco = new Discovery();

        try {
            $xrd = $disco->lookup($addr);
        } catch (Exception $e) {
            // Save negative cache entry so we don't waste time looking it up again.
            // @fixme distinguish temporary failures?
            self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), null);
            // TRANS: Exception.
            throw new Exception(_m('Not a valid webfinger address.'));
        }

        $hints = array('webfinger' => $addr);

        try {
            $dHints = DiscoveryHints::fromXRD($xrd);
            $hints = array_merge($hints, $xrdHints);
        } catch (Exception $e) {
            // No hints available from XRD
        }

        // If there's an Hcard, let's grab its info
        if (array_key_exists('hcard', $hints)) {
            if (!array_key_exists('profileurl', $hints) ||
                $hints['hcard'] != $hints['profileurl']) {
                $hcardHints = DiscoveryHints::fromHcardUrl($hints['hcard']);
                $hints = array_merge($hcardHints, $hints);
            }
        }

        // If we got a feed URL, try that
        if (array_key_exists('feedurl', $hints)) {
            try {
                common_log(LOG_INFO, "Discovery on acct:$addr with feed URL " . $hints['feedurl']);
                $oprofile = self::ensureFeedURL($hints['feedurl'], $hints);
                self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->uri);
                return $oprofile;
            } catch (Exception $e) {
                common_log(LOG_WARNING, "Failed creating profile from feed URL '$feedUrl': " . $e->getMessage());
                // keep looking
            }
        }

        // If we got a profile page, try that!
        if (array_key_exists('profileurl', $hints)) {
            try {
                common_log(LOG_INFO, "Discovery on acct:$addr with profile URL $profileUrl");
                $oprofile = self::ensureProfileURL($hints['profileurl'], $hints);
                self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->uri);
                return $oprofile;
            } catch (OStatusShadowException $e) {
                // We've ended up with a remote reference to a local user or group.
                // @fixme ideally we should be able to say who it was so we can
                // go back and refer to it the regular way
                throw $e;
            } catch (Exception $e) {
                common_log(LOG_WARNING, "Failed creating profile from profile URL '$profileUrl': " . $e->getMessage());
                // keep looking
                //
                // @fixme this means an error discovering from profile page
                // may give us a corrupt entry using the webfinger URI, which
                // will obscure the correct page-keyed profile later on.
            }
        }
        throw new Exception(sprintf(_m('Could not find a valid profile for "%s".'), $addr));
    }
}

function pullOstatusProfile($uri)
{
    $oprofile = null;
    $validate = new Validate();

    if ($validate->email($uri)) {
        $oprofile = LooseOstatusProfile::updateWebfinger($uri);
    } elseif ($validate->uri($uri)) {
        $oprofile = LooseOstatusProfile::updateProfileURL($uri);
    } else {
        print "Sorry, we could not reach the address: $uri\n";
        return false;
    }

    return $oprofile;
}

$quiet = have_option('q', 'quiet');

$lop = new LooseOstatusProfile();

if (have_option('u', 'uri')) {
    $lop->uri = get_option_value('u', 'uri');
} elseif (!have_option('a', 'all')) {
    show_help();
    exit(1);
}

$forceUpdates = have_option('f', 'force');

$cnt = $lop->find();

if (!empty($cnt)) {
    if (!$quiet) {
        echo 'Found ' . $cnt . ' OStatus profiles:' . "\n";
    }
} else {
    if (have_option('u', 'uri')) {
        if (!$quiet) {
            echo "Couldn't find an existing OStatus profile with that URI.\n";
        }
    } else {
        if (!$quiet) {
            echo "Couldn't find any existing OStatus profiles.\n";
        }
    }
    exit(0);
}

while ($lop->fetch()) {
    if (!$quiet) {
        echo "Updating OStatus profile '" . $lop->uri . "' ... ";
    }
    try {
        $oprofile = pullOstatusProfile($lop->uri);

        if (!empty($oprofile)) {
            $orig = clone($lop);
            $lop->avatar = $oprofile->avatar;
            $lop->update($orig);
            $lop->updateAvatar($oprofile->avatar, $forceUpdates);
            if (!$quiet) {
                echo 'Done.' . "\n";
            }
        }
    } catch (Exception $e) {
        if (!$quiet) {
            echo $e->getMessage() . "\n";
        }
        common_log(LOG_WARNING, $e->getMessage(), __FILE__);
        // continue on error
    }
}

if (!$quiet) {
    echo 'OK.' . "\n";
}


code:
<?php

if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
    print "This script must be run from the command line\n";
    exit();
}

define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..'));
define('GNUSOCIAL', true);
define('STATUSNET', true);  // compatibility

require_once INSTALLDIR . '/lib/util/common.php';
require_once INSTALLDIR . '/plugins/OStatus/lib/feeddiscovery.php';

class FeedDiscoveryTest extends PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider provider
     *
     */
    public function testProduction($url, $html, $expected)
    {
        $sub = new FeedDiscovery();
        $url = $sub->discoverFromHTML($url, $html);
        $this->assertEquals($expected, $url);
    }

    static public function provider()
    {
        $sampleHeader = <<<END
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>leŭksman  </title>

<meta name="generator" content="WordPress 2.8.6" />

<link rel="stylesheet" href="http://leuksman.com/log/wp-content/themes/leuksman/style.css" type="text/css" media="screen" />
<link rel="alternate" type="application/rss+xml" title="leŭksman RSS Feed" href="http://leuksman.com/log/feed/" />
<link rel="pingback" href="http://leuksman.com/log/xmlrpc.php" />

<meta name="viewport" content="width = 640" />

<xmeta name="viewport" content="initial-scale=2.3, user-scalable=no" />

<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://leuksman.com/log/xmlrpc.php?rsd" />
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://leuksman.com/log/wp-includes/wlwmanifest.xml" />
<link rel='index' title='leŭksman' href='http://leuksman.com/log' />
<meta name="generator" content="WordPress 2.8.6" />

END;
        return array(
                     array('http://example.com/',
                           '<link rel="alternate" href="http://example.com/feed/rss" type="application/rss+xml">',
                           'http://example.com/feed/rss'),
                     array('http://example.com/atom',
                           '<link rel="alternate" href="http://example.com/feed/atom" type="application/atom+xml">',
                           'http://example.com/feed/atom'),
                     array('http://example.com/empty',
                           '<link rel="alternate" href="http://example.com/index.pdf" type="application/pdf">',
                           false),
                     array('http://example.com/tagsoup',
                           '
<LINK rel=alternate hRef=http://example.com/feed/rss type=application/rss+xml><fnork',
                           'http://example.com/feed/rss'),
                     // 'rel' attribute must be lowercase, alone per http://www.rssboard.org/rss-autodiscovery
                     // but we're going to be liberal in what we receive.
                     array('http://example.com/tagsoup2',
                           '
<LINK rel=" feeders    alternate 467" hRef=http://example.com/feed/rss type=application/rss+xml><fnork',
                           'http://example.com/feed/rss'),
                     array('http://example.com/tagsoup3',
                           '
<LINK rel=ALTERNATE hRef=http://example.com/feed/rss type=application/rss+xml><fnork',
                           false),
                     array('http://example.com/relative/link1',
                           '<link rel="alternate" href="/feed/rss" type="application/rss+xml">',
                           'http://example.com/feed/rss'),
                     array('http://example.com/relative/link2',
                           '<link rel="alternate" href="../feed/rss" type="application/rss+xml">',
                           'http://example.com/feed/rss'),
                     // This one can't resolve correctly; relative link is bogus.
                     array('http://example.com/relative/link3',
                           '<link rel="alternate" href="http:/feed/rss" type="application/rss+xml">',
                           'http:/feed/rss'),
                     array('http://example.com/base/link1',
                           '<link rel="alternate" href="/feed/rss" type="application/rss+xml"><base href="http://target.example.com/">',
                           'http://target.example.com/feed/rss'),
                     array('http://example.com/base/link2',
                           '<link rel="alternate" href="feed/rss" type="application/rss+xml"><base href="http://target.example.com/">',
                           'http://target.example.com/feed/rss'),
                     // This one can't resolve; relative link is bogus.
                     array('http://example.com/base/link3',
                           '<link rel="alternate" href="http:/feed/rss" type="application/rss+xml"><base href="http://target.example.com/">',
                           'http:/feed/rss'),
                     // Trick question! There's a <base> but no href on it
                     array('http://example.com/relative/fauxbase',
                           '<link rel="alternate" href="../feed/rss" type="application/rss+xml"><base target="top">',
                           'http://example.com/feed/rss'),
                     // Actual WordPress blog header example
                     array('http://leuksman.com/log/',
                           $sampleHeader,
                           'http://leuksman.com/log/feed/'));
    }
}


code:
<?php

if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
    print "This script must be run from the command line\n";
    exit();
}

define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..'));
define('GNUSOCIAL', true);
define('STATUSNET', true);  // compatibility

require_once INSTALLDIR . '/lib/util/common.php';

class MagicEnvelopeTest extends PHPUnit_Framework_TestCase
{
    /**
     * Test that MagicEnvelope builds the correct plaintext for signing.
     * @dataProvider provider
     */
    public function testSignatureText(MagicEnvelope $env, $expected)
    {
        $text = $env->signingText();

        $this->assertEquals($expected, $text, "'$text' should be '$expected'");
    }

    static public function provider()
    {
        // Sample case given in spec:
        // http://salmon-protocol.googlecode.com/svn/trunk/draft-panzer-magicsig-00.html#signing
        $magic_env = new MagicEnvelope();
        $magic_env->data = 'Tm90IHJlYWxseSBBdG9t';
        $magic_env->data_type = 'application/atom+xml';
        $magic_env->encoding = 'base64url';
        $magic_env->alg = 'RSA-SHA256';

        return array(
            array(
                $magic_env,
                'Tm90IHJlYWxseSBBdG9t.YXBwbGljYXRpb24vYXRvbSt4bWw=.YmFzZTY0dXJs.UlNBLVNIQTI1Ng=='
            )
        );
    }
}