Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
  • 4 commits
  • 22 files changed
  • 0 commit comments
  • 1 contributor
View
52 lib/stdlib/apis/facebook/auth/auth.opa
@@ -1,3 +1,4 @@
+package facebook
/*
Copyright © 2011 MLstate
@@ -22,9 +23,9 @@
*/
import stdlib.apis.common
-import stdlib.apis.facebook
-import stdlib.apis.facebook.lib
-import stdlib.apis.facebook.dialog
+//import stdlib.apis.facebook
+//import stdlib.apis.facebook.lib
+//import stdlib.apis.facebook.dialog
/**
* {1 About this module}
@@ -76,6 +77,12 @@ type FbAuth.token = {
type FbAuth.token_res =
{ token : FbAuth.token } / { error : Facebook.error }
+/**
+ * Parsed result of a app page token request
+ */
+type FbAuth.page_token_res =
+ { page_token : string } / { error : Facebook.error }
+
FbAuth(conf:Facebook.config) = {{
@@ -162,4 +169,43 @@ FbAuth(conf:Facebook.config) = {{
, ("grant_type","client_credentials") ]
access_token_internal(data)
+ /**
+ * Gets an application page access token. These tokens do not expire.
+ *
+ * @param id The [APP_ID] of the app you want the page token for.
+ * @param page_name The name of the app
+ * @param token Your access token, must have [manage_pages] permission
+ *
+ * @return A [FbAuth.page_token_res] with either a page token or
+ * an error in case of failure
+ */
+ application_page_token(id, page_name, token) : FbAuth.page_token_res =
+ match FbLib.fb_get(graph_url, "/{id}/accounts?access_token={token}", []) with
+ | {none} -> {error=Facebook.make_error("application_page_token","Network error")}
+ | {some=r} ->
+ match Json.of_string(r) with
+ | {some={Record=r}} ->
+ match List.assoc("data",r) with
+ | {some={List=l}} ->
+ match List.find((o ->
+ match o with
+ | {Record=r} ->
+ match List.assoc("name",r) with
+ | {some={String=name}} -> name == page_name
+ | _ -> false
+ end
+ | _ -> false
+ end),l) with
+ | {some={Record=r}} ->
+ match List.assoc("access_token",r) with
+ | {some={String=page_token}} -> ~{page_token} : FbAuth.page_token_res
+ | _ -> {error=Facebook.make_error("application_page_token","No access token in response")}
+ end
+ | _ -> {error=Facebook.make_error("application_page_token","No matching page name")}
+ end
+ | _ -> {error=Facebook.make_error("application_page_token","No data")}
+ end
+ | _ -> {error=Facebook.make_error("application_page_token","Json parse error")}
+ end
+
}}
View
5 lib/stdlib/apis/facebook/dialog/dialog.opa
@@ -1,3 +1,4 @@
+package facebook
/*
Copyright © 2011 MLstate
@@ -22,8 +23,8 @@
*/
import stdlib.apis.common
-import stdlib.apis.facebook
-import stdlib.apis.facebook.lib
+//import stdlib.apis.facebook
+//import stdlib.apis.facebook.lib
/**
* {1 About this module}
View
572 lib/stdlib/apis/facebook/facebook.opa
@@ -1,3 +1,4 @@
+package facebook
/*
Copyright © 2011 MLstate
@@ -70,10 +71,12 @@ type Facebook.error = {
* https://developers.facebook.com/docs/authentication/permissions/
*/
type Facebook.permission =
+
/* Data permissions - self */
{ user_about_me } /** Provides access to the "About Me" section of the profile in the about property */
/ { user_activities } /** Provides access to the user's list of activities as the activities connection */
/ { user_birthday } /** Provides access to the birthday with year as the birthday_date property */
+ / { user_checkins } /** Provides read access to the authorized user's check-ins or a friend's check-ins that the user can see. This permission is superseded by user_status for new applications as of March, 2012. */
/ { user_education_history } /** Provides access to education history as the education property */
/ { user_events } /** Provides access to the list of events the user is attending as the events connection */
/ { user_groups } /** Provides access to the list of groups the user is a member of as the groups connection */
@@ -82,18 +85,44 @@ type Facebook.permission =
/ { user_likes } /** Provides access to the list of all of the pages the user has liked as the likes connection */
/ { user_location } /** Provides access to the user's current location as the location property */
/ { user_notes } /** Provides access to the user's notes as the notes connection */
- / { user_online_presence } /** Provides access to the user's online/offline presence */
- / { user_photo_video_tags } /** Provides access to the photos the user has been tagged in as the photos connection */
/ { user_photos } /** Provides access to the photos the user has uploaded */
+ / { user_questions } /** Provides access to the questions the user or friend has asked */
/ { user_relationships } /** Provides access to the user's family and personal relationships and rela
tionship status */
/ { user_relationship_details } /** Provides access to the user's relationship preferences */
/ { user_religion_politics } /** Provides access to the user's religious and political affiliations */
/ { user_status } /** Provides access to the user's most recent status message */
+ / { user_subscriptions } /** Provides access to the user's subscribers and subscribees */
/ { user_videos } /** Provides access to the videos the user has uploaded */
/ { user_website } /** Provides access to the user's web site URL */
/ { user_work_history } /** Provides access to work history as the work property */
/ { email } /** Provides access to the user's primary email address in the email property. Do not spam users. Your use of email must comply both with Facebook policies and with the CAN-SPAM Act. */
+
+ /* Data permissions - friends */
+ / { friends_about_me } /** Provides access to the "About Me" section of the profile in the about property */
+ / { friends_activities } /** Provides access to the friend's list of activities as the activities connection */
+ / { friends_birthday } /** Provides access to the birthday with year as the birthday_date property */
+ / { friends_checkins } /** Provides read access to the authorized friend's check-ins or a friend's check-ins that the friend can see. This permission is superseded by friend_status for new applications as of March, 2012. */
+ / { friends_education_history } /** Provides access to education history as the education property */
+ / { friends_events } /** Provides access to the list of events the friend is attending as the events connection */
+ / { friends_groups } /** Provides access to the list of groups the friend is a member of as the groups connection */
+ / { friends_hometown } /** Provides access to the friend's hometown in the hometown property */
+ / { friends_interests } /** Provides access to the friend's list of interests as the interests connection */
+ / { friends_likes } /** Provides access to the list of all of the pages the friend has liked as the likes connection */
+ / { friends_location } /** Provides access to the friend's current location as the location property */
+ / { friends_notes } /** Provides access to the friend's notes as the notes connection */
+ / { friends_photos } /** Provides access to the photos the friend has uploaded */
+ / { friends_questions } /** Provides access to the questions the friend or friend has asked */
+ / { friends_relationships } /** Provides access to the friend's family and personal relationships and relationship status */
+ / { friends_relationship_details } /** Provides access to the friend's relationship preferences */
+ / { friends_religion_politics } /** Provides access to the friend's religious and political affiliations */
+ / { friends_status } /** Provides access to the friend's most recent status message */
+ / { friends_subscriptions } /** Provides access to the friend's subscribers and subscribees */
+ / { friends_videos } /** Provides access to the videos the friend has uploaded */
+ / { friends_website } /** Provides access to the friend's web site URL */
+ / { friends_work_history } /** Provides access to work history as the work property */
+
+ /* Extended permissions */
/ { read_friendlists } /** Provides access to any friend lists the user created. All user's friends are provided as part of basic data, this extended permission grants access to the lists of friends a user has created, and should only be requested if your application utilizes lists of friends. */
/ { read_insights } /** Provides read access to the Insights data for pages, applications, and domains the user owns. */
/ { read_mailbox } /** Provides the ability to read from a user's Facebook Inbox. */
@@ -101,40 +130,43 @@ tionship status */
/ { read_stream } /** Provides access to all the posts in the user's News Feed and enables your application to perform searches against the user's News Feed */
/ { xmpp_login } /** Provides applications that integrate with Facebook Chat the ability to log in users. */
/ { ads_management } /** Provides the ability to manage ads and call the Facebook Ads API on behalf of a user. */
- / { user_checkins } /** Provides read access to the authorized user's check-ins or a friend's check-ins that the user can see. */
- /* Data permissions - friends */
- / { friends_about_me } /** Provides access to the "About Me" section of the profile in the about property */
- / { friends_activities } /** Provides access to the user's list of activities as the activities connection */
- / { friends_birthday } /** Provides access to the birthday with year as the birthday_date property */
- / { friends_education_history } /** Provides access to education history as the education property */
- / { friends_events } /** Provides access to the list of events the user is attending as the events connection */
- / { friends_groups } /** Provides access to the list of groups the user is a member of as the groups connection */
- / { friends_hometown } /** Provides access to the user's hometown in the hometown property */
- / { friends_interests } /** Provides access to the user's list of interests as the interests connection */
- / { friends_likes } /** Provides access to the list of all of the pages the user has liked as the likes connection */
- / { friends_location } /** Provides access to the user's current location as the location property */
- / { friends_notes } /** Provides access to the user's notes as the notes connection */
- / { friends_online_presence } /** Provides access to the user's online/offline presence */
- / { friends_photo_video_tags } /** Provides access to the photos the user has been tagged in as the photos connection */
- / { friends_photos } /** Provides access to the photos the user has uploaded */
- / { friends_relationships } /** Provides access to the user's family and personal relationships and relationship status */
- / { friends_relationship_details } /** Provides access to the user's relationship preferences */
- / { friends_religion_politics } /** Provides access to the user's religious and political affiliations */
- / { friends_status } /** Provides access to the user's most recent status message */
- / { friends_videos } /** Provides access to the videos the user has uploaded */
- / { friends_website } /** Provides access to the user's web site URL */
- / { friends_work_history } /** Provides access to work history as the work property */
+ / { create_event } /** Enables your application to create and modify events on the user's behalf */
/ { manage_friendlists } /** Provides access to any friend lists the user created. All user's friends are provided as part of basic data, this extended permission grants access to the lists of friends a user has created, and should only be requested if your application utilizes lists of friends. */
- / { friends_checkins } /** Provides read access to the authorized user's check-ins or a friend's check-ins that the user can see. */
+ / { manage_notifications } /** Enables your app to read notifications and mark them as read. Intended usage: This permission should be used to let users read and act on their notifications; it should not be used to for the purposes of modeling user behavior or data mining. Apps that misuse this permission may be banned from requesting it. */
/* Publishing permissions */
- / { publish_stream } /** Enables your application to post content, comments, and likes to a user's stream and to the streams of the user's friends. With this permission, you can publish content to a user's feed at any time, without requiring offline_access. However, please note that Facebook recommends a user-initiated sharing model. */
- / { create_event } /** Enables your application to create and modify events on the user's behalf */
- / { rsvp_event } /** Enables your application to RSVP to events on the user's behalf */
- / { sms } /** Enables your application to send messages to the user and respond to messages from the user via text message */
- / { offline_access } /** Enables your application to perform authorized requests on behalf of the user at any time. By default, most access tokens expire after a short time period to ensure applications only make requests on behalf of the user when the are actively using the application. This permission makes the access token returned by our OAuth endpoint long-lived. */
+ / { user_online_presence } /** Provides access to the user's online/offline presence */
+ / { friends_online_presence } /** Provides access to the friend's online/offline presence */
/ { publish_checkins } /** Enables your application to perform checkins on behalf of the user */
+ / { publish_stream } /** Enables your app to post content, comments, and likes to a user's stream and to the streams of the user's friends. This is a superset publishing permission which also includes publish_actions. However, please note that Facebook recommends a user-initiated sharing model. Please read the Platform Policies to ensure you understand how to properly use this permission. Note, you do not need to request the publish_stream permission in order to use the Feed Dialog, the Requests Dialog or the Send Dialog. */
+ / { rsvp_event } /** Enables your application to RSVP to events on the user's behalf */
+
+ /* Open Graph Permissions */
+ / { publish_actions } /** Allows your app to publish to the Open Graph using Built-in Actions, Achievements, Scores, or Custom Actions. Your app can also publish other activity which is detailed in the Publishing Permissions doc. Note: The user-prompt for this permission will be displayed in the first screen of the Enhanced Auth Dialog and cannot be revoked as part of the authentication flow. However, a user can later revoke this permission in their Account Settings. If you want to be notified if this happens, you should subscribe to the permissions object within the Realtime API. */
+ / { user_actions_music } /** Allows you to retrieve the actions published by all applications using the built-in music.listens action. */
+ / { friends_actions_music } /** Allows you to retrieve the actions published by all applications using the built-in music.listens action. */
+ / { user_actions_news } /** Allows you to retrieve the actions published by all applications using the built-in news.reads action. */
+ / { friends_actions_news } /** Allows you to retrieve the actions published by all applications using the built-in news.reads action. */
+ / { user_actions_video } /** Allows you to retrieve the actions published by all applications using the built-in video.watches action. */
+ / { friends_actions_video } /** Allows you to retrieve the actions published by all applications using the built-in video.watches action. */
+ / { user_actions_namespace:string } /** Allows you retrieve the actions published by another application as specified by the app namespace. For example, to request the ability to retrieve the actions published by an app which has the namespace awesomeapp, prompt the user for the users_actions:awesomeapp and/or friends_actions:awesomeapp permissions. */
+ / { friends_actions_namespace:string } /** Allows you retrieve the actions published by another application as specified by the app namespace. For example, to request the ability to retrieve the actions published by an app which has the namespace awesomeapp, prompt the user for the users_actions:awesomeapp and/or friends_actions:awesomeapp permissions. */
+ / { user_games_activity } /** Allows you post and retrieve game achievement activity. */
+ / { friends_games_activity } /** Allows you post and retrieve game achievement activity. */
+
/* Page permissions */
- / { manage_pages } /** Enables your application to retrieve access_tokens for pages the user administrates. The access tokens can be queried using the "accounts" connection in the Graph API. This permission is only compatible with the Graph API. */
+ / { manage_pages } /** Enables your application to retrieve access_tokens for Pages and Applications that the user administrates. The access tokens can be queried by calling /<user_id>/accounts via the Graph API. This permission is only compatible with the Graph API, not the deprecated REST API. See https://developers.facebook.com/roadmap/offline-access-removal/#page_access_token for generating long-lived Page access tokens that do not expire after 60 days.*/
+
+ /* These are not in the current docs but get returned anyway, deprecated? */
+ / {installed}
+ / {status_update}
+ / {photo_upload}
+ / {video_upload}
+ / {sms}
+ / {create_note}
+ / {share_item}
+ / {user_photo_video_tags}
+ / {friends_photo_video_tags}
+ / {bookmarked}
/**
* Link in a feed
@@ -199,6 +231,69 @@ type Facebook.feed = {
actions : list(Facebook.feed_link)
}
+/** A Facebook post for [FbGraph.Post.post]. */
+type Facebook.post = {
+ message : string
+ link : string
+ picture : string
+ name : string
+ caption : string
+ description : string
+ actions : list(Facebook.feed_link)
+ privacy : string
+}
+
+type Facebook.property =
+ { id } /** The application ID string */
+ / { name } /** The title of the application string */
+ / { description } /** The description of the application written by the 3rd party developers string */
+ / { category } /** The category of the application string */
+ / { company } /** The company the application belongs to string */
+ / { icon_url } /** The URL of the application's icon string */
+ / { subcategory } /** The subcategory of the application string */
+ / { link } /** A link to the Application's profile page string */
+ / { logo_url } /** The URL of the application's logo string */
+ / { daily_active_users } /** The number of daily active users the application has string */
+ / { weekly_active_users } /** The number of weekly active users the application has string */
+ / { monthly_active_users } /** The number of monthly active users the application has string */
+ / { migrations } /** Migrations settings for app profile */
+ / { namespace } /** The namespace for the app */
+ / { restrictions } /** Demographic restrictions set for this app (Object with one or more of the following fields: type, location, age, and age_distr) */
+ / { app_domains } /** Domains and subdomains this app can use (array) */
+ / { auth_dialog_data_help_url } /** The URL of a special landing page that helps users of an app begin publishing Open Graph activity (string) */
+ / { auth_dialog_description } /** The description of an app that appears in the Auth Dialog (string) */
+ / { auth_dialog_headline } /** One line description of an app that appears in the Auth Dialog (string) */
+ / { auth_dialog_perms_explanation } /** The text to explain why an app needs additional permissions that appears in the Auth Dialog (string) */
+ / { auth_referral_user_perms } /** Basic user permissions that a user must grant when Authenticated Referrals are enabled (array) */
+ / { auth_referral_friend_perms } /** Basic friends permissions that a user must grant when Authenticated Referrals are enabled (array) */
+ / { auth_referral_default_activity_privacy } /** The default privacy setting selected for Open Graph activities in the Auth Dialog (string which is one of: SELF, EVERYONE, ALL_FRIENDS or NONE) */
+ / { auth_referral_enabled } /** Indicates whether Authenticated Referrals are enabled (bool) */
+ / { auth_referral_extended_perms } /** Extended permissions that a user can choose to grant when Authenticated Referrals are enabled (array) */
+ / { auth_referral_response_type } /** The format that an app receives the Auth token from the Auth Dialog in (string which is one of: code or token) */
+ / { canvas_fluid_height } /** Indicates whether app uses fluid or settable height values for Canvas (bool) */
+ / { canvas_fluid_width } /** Indicates whether app uses fluid or fixed width values for Canvas (bool) */
+ / { canvas_url } /** The non-secure URL from which Canvas app content is loaded (string) */
+ / { contact_email } /** Email address listed for users to contact developers (string) */
+ / { created_time } /** Unix timestamp that indicates when the app was created int */
+ / { creator_uid } /** User ID of the creator of this app int */
+ / { deauth_callback_url } /** URL that is pinged whenever a user removes the app (string) */
+ / { iphone_app_store_id } /** ID of the app in the iPhone App Store string */
+ / { hosting_url } /** Webspace created with one of our hosting partners for this app string */
+ / { mobile_web_url } /** URL to which Mobile users will be directed when using the app (string) */
+ / { page_tab_default_name } /** The title of the app when used in a Page Tab (string) */
+ / { page_tab_url } /** The non-secure URL from which Page Tab app content is loaded (string) */
+ / { privacy_policy_url } /** The URL that links to a Privacy Policy for the app (string) */
+ / { secure_canvas_url } /** The secure URL from which Canvas app content is loaded (string) */
+ / { secure_page_tab_url } /** The secure URL from which Page Tab app content is loaded (string) */
+ / { server_ip_whitelist } /** App requests must originate from this comma-separated list of IP addresses (string) */
+ / { social_discovery } /** Indicates whether app usage stories show up in the Ticker or News Feed (bool) */
+ / { terms_of_service_url } /** URL to Terms of Service which is linked to in Auth Dialog (string) */
+ / { user_support_email } /** Main contact email for this app (string) */
+ / { user_support_url } /** URL of support for users of an app shown in Canvas footer (string) */
+ / { website_url } /** URL of a website that integrates with this app (string) */
+
+type Facebook.properties = list(Facebook.property)
+
Facebook = {{
/* Facebook static */
@@ -239,130 +334,299 @@ Facebook = {{
permission_to_string(p) =
match p:Facebook.permission with
- { user_about_me } -> "user_about_me"
- { user_activities } -> "user_activities"
- { user_birthday } -> "user_birthday"
- { user_education_history } -> "user_education_history"
- { user_events } -> "user_events"
- { user_groups } -> "user_groups"
- { user_hometown } -> "user_hometown"
- { user_interests } -> "user_interests"
- { user_likes } -> "user_likes"
- { user_location } -> "user_location"
- { user_notes } -> "user_notes"
- { user_online_presence } -> "user_online_presence"
- { user_photo_video_tags } -> "user_photo_video_tags"
- { user_photos } -> "user_photos"
- { user_relationships } -> "user_relationships"
- { user_relationship_details } -> "user_relationship_details"
- { user_religion_politics } -> "user_religion_politics"
- { user_status } -> "user_status"
- { user_videos } -> "user_videos"
- { user_website } -> "user_website"
- { user_work_history } -> "user_work_history"
- { email } -> "email"
- { read_friendlists } -> "read_friendlists"
- { read_insights } -> "read_insights"
- { read_mailbox } -> "read_mailbox"
- { read_requests } -> "read_requests"
- { read_stream } -> "read_stream"
- { xmpp_login } -> "xmpp_login"
- { ads_management } -> "ads_management"
- { user_checkins } -> "user_checkins"
- { friends_about_me } -> "friends_about_me"
- { friends_activities } -> "friends_activities"
- { friends_birthday } -> "friends_birthday"
- { friends_education_history } -> "friends_education_history"
- { friends_events } -> "friends_events"
- { friends_groups } -> "friends_groups"
- { friends_hometown } -> "friends_hometown"
- { friends_interests } -> "friends_interests"
- { friends_likes } -> "friends_likes"
- { friends_location } -> "friends_location"
- { friends_notes } -> "friends_notes"
- { friends_online_presence } -> "friends_online_presence"
- { friends_photo_video_tags } -> "friends_photo_video_tags"
- { friends_photos } -> "friends_photos"
- { friends_relationships } -> "friends_relationships"
- { friends_relationship_details } -> "friends_relationship_details"
- { friends_religion_politics } -> "friends_religion_politics"
- { friends_status } -> "friends_status"
- { friends_videos } -> "friends_videos"
- { friends_website } -> "friends_website"
- { friends_work_history } -> "friends_work_history"
- { manage_friendlists } -> "manage_friendlists"
- { friends_checkins } -> "friends_checkins"
- { publish_stream } -> "publish_stream"
- { create_event } -> "create_event"
- { rsvp_event } -> "rsvp_event"
- { sms } -> "sms"
- { offline_access } -> "offline_access"
- { publish_checkins } -> "publish_checkins"
- { manage_pages } -> "manage_pages"
+ | { user_about_me } -> "user_about_me"
+ | { user_activities } -> "user_activities"
+ | { user_birthday } -> "user_birthday"
+ | { user_checkins } -> "user_checkins"
+ | { user_education_history } -> "user_education_history"
+ | { user_events } -> "user_events"
+ | { user_groups } -> "user_groups"
+ | { user_hometown } -> "user_hometown"
+ | { user_interests } -> "user_interests"
+ | { user_likes } -> "user_likes"
+ | { user_location } -> "user_location"
+ | { user_notes } -> "user_notes"
+ | { user_photos } -> "user_photos"
+ | { user_questions } -> "user_questions"
+ | { user_relationships } -> "user_relationships"
+ | { user_relationship_details } -> "user_relationship_details"
+ | { user_religion_politics } -> "user_religion_politics"
+ | { user_status } -> "user_status"
+ | { user_subscriptions } -> "user_subscriptions"
+ | { user_videos } -> "user_videos"
+ | { user_website } -> "user_website"
+ | { user_work_history } -> "user_work_history"
+ | { email } -> "email"
+ | { friends_about_me } -> "friends_about_me"
+ | { friends_activities } -> "friends_activities"
+ | { friends_birthday } -> "friends_birthday"
+ | { friends_checkins } -> "friends_checkins"
+ | { friends_education_history } -> "friends_education_history"
+ | { friends_events } -> "friends_events"
+ | { friends_groups } -> "friends_groups"
+ | { friends_hometown } -> "friends_hometown"
+ | { friends_interests } -> "friends_interests"
+ | { friends_likes } -> "friends_likes"
+ | { friends_location } -> "friends_location"
+ | { friends_notes } -> "friends_notes"
+ | { friends_photos } -> "friends_photos"
+ | { friends_questions } -> "friends_questions"
+ | { friends_relationships } -> "friends_relationships"
+ | { friends_relationship_details } -> "friends_relationship_details"
+ | { friends_religion_politics } -> "friends_religion_politics"
+ | { friends_status } -> "friends_status"
+ | { friends_subscriptions } -> "friends_subscriptions"
+ | { friends_videos } -> "friends_videos"
+ | { friends_website } -> "friends_website"
+ | { friends_work_history } -> "friends_work_history"
+ | { read_friendlists } -> "read_friendlists"
+ | { read_insights } -> "read_insights"
+ | { read_mailbox } -> "read_mailbox"
+ | { read_requests } -> "read_requests"
+ | { read_stream } -> "read_stream"
+ | { xmpp_login } -> "xmpp_login"
+ | { ads_management } -> "ads_management"
+ | { create_event } -> "create_event"
+ | { manage_friendlists } -> "manage_friendlists"
+ | { manage_notifications } -> "manage_notifications"
+ | { user_online_presence } -> "user_online_presence"
+ | { friends_online_presence } -> "friends_online_presence"
+ | { publish_checkins } -> "publish_checkins"
+ | { publish_stream } -> "publish_stream"
+ | { rsvp_event } -> "rsvp_event"
+ | { publish_actions } -> "publish_actions"
+ | { user_actions_music } -> "user_actions.music"
+ | { user_actions_news } -> "user_actions.news"
+ | { user_actions_video } -> "user_actions.video"
+ | { ~user_actions_namespace } -> "user_actions:{user_actions_namespace}"
+ | { user_games_activity } -> "user_games_activity"
+ | { friends_actions_music } -> "friends_actions.music"
+ | { friends_actions_news } -> "friends_actions.news"
+ | { friends_actions_video } -> "friends_actions.video"
+ | { ~friends_actions_namespace } -> "friends_actions:{friends_actions_namespace}"
+ | { friends_games_activity } -> "friends_games_activity"
+ | { manage_pages } -> "manage_pages"
+ | {installed} -> "installed"
+ | {status_update} -> "status_update"
+ | {photo_upload} -> "photo_upload"
+ | {video_upload} -> "video_upload"
+ | {sms} -> "sms"
+ | {create_note} -> "create_note"
+ | {share_item} -> "share_item"
+ | {user_photo_video_tags} -> "user_photo_video_tags"
+ | {friends_photo_video_tags} -> "friends_photo_video_tags"
+ | {bookmarked} -> "bookmarked"
permission_of_string(p) : option(Facebook.permission) =
- match p:string with
- "user_about_me" -> {some={user_about_me}}
- "user_activities" -> {some={user_activities}}
- "user_birthday" -> {some={user_birthday}}
- "user_education_history" -> {some={user_education_history}}
- "user_events" -> {some={user_events}}
- "user_groups" -> {some={user_groups}}
- "user_hometown" -> {some={user_hometown}}
- "user_interests" -> {some={user_interests}}
- "user_likes" -> {some={user_likes}}
- "user_location" -> {some={user_location}}
- "user_notes" -> {some={user_notes}}
- "user_online_presence" -> {some={user_online_presence}}
- "user_photo_video_tags" -> {some={user_photo_video_tags}}
- "user_photos" -> {some={user_photos}}
- "user_relationships" -> {some={user_relationships}}
- "user_relationship_details" -> {some={user_relationship_details}}
- "user_religion_politics" -> {some={user_religion_politics}}
- "user_status" -> {some={user_status}}
- "user_videos" -> {some={user_videos}}
- "user_website" -> {some={user_website}}
- "user_work_history" -> {some={user_work_history}}
- "email" -> {some={email}}
- "read_friendlists" -> {some={read_friendlists}}
- "read_insights" -> {some={read_insights}}
- "read_mailbox" -> {some={read_mailbox}}
- "read_requests" -> {some={read_requests}}
- "read_stream" -> {some={read_stream}}
- "xmpp_login" -> {some={xmpp_login}}
- "ads_management" -> {some={ads_management}}
- "user_checkins" -> {some={user_checkins}}
- "friends_about_me" -> {some={friends_about_me}}
- "friends_activities" -> {some={friends_activities}}
- "friends_birthday" -> {some={friends_birthday}}
- "friends_education_history" -> {some={friends_education_history}}
- "friends_events" -> {some={friends_events}}
- "friends_groups" -> {some={friends_groups}}
- "friends_hometown" -> {some={friends_hometown}}
- "friends_interests" -> {some={friends_interests}}
- "friends_likes" -> {some={friends_likes}}
- "friends_location" -> {some={friends_location}}
- "friends_notes" -> {some={friends_notes}}
- "friends_online_presence" -> {some={friends_online_presence}}
- "friends_photo_video_tags" -> {some={friends_photo_video_tags}}
- "friends_photos" -> {some={friends_photos}}
- "friends_relationships" -> {some={friends_relationships}}
- "friends_relationship_details" -> {some={friends_relationship_details}}
- "friends_religion_politics" -> {some={friends_religion_politics}}
- "friends_status" -> {some={friends_status}}
- "friends_videos" -> {some={friends_videos}}
- "friends_website" -> {some={friends_website}}
- "friends_work_history" -> {some={friends_work_history}}
- "manage_friendlists" -> {some={manage_friendlists}}
- "friends_checkins" -> {some={friends_checkins}}
- "publish_stream" -> {some={publish_stream}}
- "create_event" -> {some={create_event}}
- "rsvp_event" -> {some={rsvp_event}}
- "sms" -> {some={sms}}
- "offline_access" -> {some={offline_access}}
- "publish_checkins" -> {some={publish_checkins}}
- "manage_pages" -> {some={manage_pages}}
- _ -> none
+ len = String.length(p)
+ if String.has_prefix("user_actions:",p) && len > 13
+ then {some={user_actions_namespace=String.substring(13,len-13,p)}}
+ else if String.has_prefix("friends_actions:",p) && len > 16
+ then {some={friends_actions_namespace=String.substring(16,len-16,p)}}
+ else
+ match p with
+ | "user_about_me" -> {some={ user_about_me }}
+ | "user_activities" -> {some={ user_activities }}
+ | "user_birthday" -> {some={ user_birthday }}
+ | "user_checkins" -> {some={ user_checkins }}
+ | "user_education_history" -> {some={ user_education_history }}
+ | "user_events" -> {some={ user_events }}
+ | "user_groups" -> {some={ user_groups }}
+ | "user_hometown" -> {some={ user_hometown }}
+ | "user_interests" -> {some={ user_interests }}
+ | "user_likes" -> {some={ user_likes }}
+ | "user_location" -> {some={ user_location }}
+ | "user_notes" -> {some={ user_notes }}
+ | "user_photos" -> {some={ user_photos }}
+ | "user_questions" -> {some={ user_questions }}
+ | "user_relationships" -> {some={ user_relationships }}
+ | "user_relationship_details" -> {some={ user_relationship_details }}
+ | "user_religion_politics" -> {some={ user_religion_politics }}
+ | "user_status" -> {some={ user_status }}
+ | "user_subscriptions" -> {some={ user_subscriptions }}
+ | "user_videos" -> {some={ user_videos }}
+ | "user_website" -> {some={ user_website }}
+ | "user_work_history" -> {some={ user_work_history }}
+ | "email" -> {some={ email }}
+ | "friends_about_me" -> {some={ friends_about_me }}
+ | "friends_activities" -> {some={ friends_activities }}
+ | "friends_birthday" -> {some={ friends_birthday }}
+ | "friends_checkins" -> {some={ friends_checkins }}
+ | "friends_education_history" -> {some={ friends_education_history }}
+ | "friends_events" -> {some={ friends_events }}
+ | "friends_groups" -> {some={ friends_groups }}
+ | "friends_hometown" -> {some={ friends_hometown }}
+ | "friends_interests" -> {some={ friends_interests }}
+ | "friends_likes" -> {some={ friends_likes }}
+ | "friends_location" -> {some={ friends_location }}
+ | "friends_notes" -> {some={ friends_notes }}
+ | "friends_photos" -> {some={ friends_photos }}
+ | "friends_questions" -> {some={ friends_questions }}
+ | "friends_relationships" -> {some={ friends_relationships }}
+ | "friends_relationship_details" -> {some={ friends_relationship_details }}
+ | "friends_religion_politics" -> {some={ friends_religion_politics }}
+ | "friends_status" -> {some={ friends_status }}
+ | "friends_subscriptions" -> {some={ friends_subscriptions }}
+ | "friends_videos" -> {some={ friends_videos }}
+ | "friends_website" -> {some={ friends_website }}
+ | "friends_work_history" -> {some={ friends_work_history }}
+ | "read_friendlists" -> {some={ read_friendlists }}
+ | "read_insights" -> {some={ read_insights }}
+ | "read_mailbox" -> {some={ read_mailbox }}
+ | "read_requests" -> {some={ read_requests }}
+ | "read_stream" -> {some={ read_stream }}
+ | "xmpp_login" -> {some={ xmpp_login }}
+ | "ads_management" -> {some={ ads_management }}
+ | "create_event" -> {some={ create_event }}
+ | "manage_friendlists" -> {some={ manage_friendlists }}
+ | "manage_notifications" -> {some={ manage_notifications }}
+ | "user_online_presence" -> {some={ user_online_presence }}
+ | "friends_online_presence" -> {some={ friends_online_presence }}
+ | "publish_checkins" -> {some={ publish_checkins }}
+ | "publish_stream" -> {some={ publish_stream }}
+ | "rsvp_event" -> {some={ rsvp_event }}
+ | "publish_actions" -> {some={ publish_actions }}
+ | "user_actions.music" -> {some={ user_actions_music }}
+ | "user_actions.news" -> {some={ user_actions_news }}
+ | "user_actions.video" -> {some={ user_actions_video }}
+ | "user_games_activity" -> {some={ user_games_activity }}
+ | "friends_actions.music" -> {some={ friends_actions_music }}
+ | "friends_actions.news" -> {some={ friends_actions_news }}
+ | "friends_actions.video" -> {some={ friends_actions_video }}
+ | "friends_games_activity" -> {some={ friends_games_activity }}
+ | "manage_pages" -> {some={ manage_pages }}
+ | "installed" -> {some={installed}}
+ | "status_update" -> {some={status_update}}
+ | "photo_upload" -> {some={photo_upload}}
+ | "video_upload" -> {some={video_upload}}
+ | "sms" -> {some={sms}}
+ | "create_note" -> {some={create_note}}
+ | "share_item" -> {some={share_item}}
+ | "user_photo_video_tags" -> {some={user_photo_video_tags}}
+ | "friends_photo_video_tags" -> {some={friends_photo_video_tags}}
+ | "bookmarked" -> {some={bookmarked}}
+ | _ -> {none}
+
+ string_of_property(property:Facebook.property) : string =
+ match property with
+ | { id } -> "id"
+ | { name } -> "name"
+ | { description } -> "description"
+ | { category } -> "category"
+ | { company } -> "company"
+ | { icon_url } -> "icon_url"
+ | { subcategory } -> "subcategory"
+ | { link } -> "link"
+ | { logo_url } -> "logo_url"
+ | { daily_active_users } -> "daily_active_users"
+ | { weekly_active_users } -> "weekly_active_users"
+ | { monthly_active_users } -> "monthly_active_users"
+ | { migrations } -> "migrations"
+ | { namespace } -> "namespace"
+ | { restrictions } -> "restrictions"
+ | { app_domains } -> "app_domains"
+ | { auth_dialog_data_help_url } -> "auth_dialog_data_help_url"
+ | { auth_dialog_description } -> "auth_dialog_description"
+ | { auth_dialog_headline } -> "auth_dialog_headline"
+ | { auth_dialog_perms_explanation } -> "auth_dialog_perms_explanation"
+ | { auth_referral_user_perms } -> "auth_referral_user_perms"
+ | { auth_referral_friend_perms } -> "auth_referral_friend_perms"
+ | { auth_referral_default_activity_privacy } -> "auth_referral_default_activity_privacy"
+ | { auth_referral_enabled } -> "auth_referral_enabled"
+ | { auth_referral_extended_perms } -> "auth_referral_extended_perms"
+ | { auth_referral_response_type } -> "auth_referral_response_type"
+ | { canvas_fluid_height } -> "canvas_fluid_height"
+ | { canvas_fluid_width } -> "canvas_fluid_width"
+ | { canvas_url } -> "canvas_url"
+ | { contact_email } -> "contact_email"
+ | { created_time } -> "created_time"
+ | { creator_uid } -> "creator_uid"
+ | { deauth_callback_url } -> "deauth_callback_url"
+ | { iphone_app_store_id } -> "iphone_app_store_id"
+ | { hosting_url } -> "hosting_url"
+ | { mobile_web_url } -> "mobile_web_url"
+ | { page_tab_default_name } -> "page_tab_default_name"
+ | { page_tab_url } -> "page_tab_url"
+ | { privacy_policy_url } -> "privacy_policy_url"
+ | { secure_canvas_url } -> "secure_canvas_url"
+ | { secure_page_tab_url } -> "secure_page_tab_url"
+ | { server_ip_whitelist } -> "server_ip_whitelist"
+ | { social_discovery } -> "social_discovery"
+ | { terms_of_service_url } -> "terms_of_service_url"
+ | { user_support_email } -> "user_support_email"
+ | { user_support_url } -> "user_support_url"
+ | { website_url } -> "website_url"
+
+ property_of_string(s:string) : option(Facebook.property) =
+ match s with
+ | "id" -> {some={ id }}
+ | "name" -> {some={ name }}
+ | "description" -> {some={ description }}
+ | "category" -> {some={ category }}
+ | "company" -> {some={ company }}
+ | "icon_url" -> {some={ icon_url }}
+ | "subcategory" -> {some={ subcategory }}
+ | "link" -> {some={ link }}
+ | "logo_url" -> {some={ logo_url }}
+ | "daily_active_users" -> {some={ daily_active_users }}
+ | "weekly_active_users" -> {some={ weekly_active_users }}
+ | "monthly_active_users" -> {some={ monthly_active_users }}
+ | "migrations" -> {some={ migrations }}
+ | "namespace" -> {some={ namespace }}
+ | "restrictions" -> {some={ restrictions }}
+ | "app_domains" -> {some={ app_domains }}
+ | "auth_dialog_data_help_url" -> {some={ auth_dialog_data_help_url }}
+ | "auth_dialog_description" -> {some={ auth_dialog_description }}
+ | "auth_dialog_headline" -> {some={ auth_dialog_headline }}
+ | "auth_dialog_perms_explanation" -> {some={ auth_dialog_perms_explanation }}
+ | "auth_referral_user_perms" -> {some={ auth_referral_user_perms }}
+ | "auth_referral_friend_perms" -> {some={ auth_referral_friend_perms }}
+ | "auth_referral_default_activity_privacy" -> {some={ auth_referral_default_activity_privacy }}
+ | "auth_referral_enabled" -> {some={ auth_referral_enabled }}
+ | "auth_referral_extended_perms" -> {some={ auth_referral_extended_perms }}
+ | "auth_referral_response_type" -> {some={ auth_referral_response_type }}
+ | "canvas_fluid_height" -> {some={ canvas_fluid_height }}
+ | "canvas_fluid_width" -> {some={ canvas_fluid_width }}
+ | "canvas_url" -> {some={ canvas_url }}
+ | "contact_email" -> {some={ contact_email }}
+ | "created_time" -> {some={ created_time }}
+ | "creator_uid" -> {some={ creator_uid }}
+ | "deauth_callback_url" -> {some={ deauth_callback_url }}
+ | "iphone_app_store_id" -> {some={ iphone_app_store_id }}
+ | "hosting_url" -> {some={ hosting_url }}
+ | "mobile_web_url" -> {some={ mobile_web_url }}
+ | "page_tab_default_name" -> {some={ page_tab_default_name }}
+ | "page_tab_url" -> {some={ page_tab_url }}
+ | "privacy_policy_url" -> {some={ privacy_policy_url }}
+ | "secure_canvas_url" -> {some={ secure_canvas_url }}
+ | "secure_page_tab_url" -> {some={ secure_page_tab_url }}
+ | "server_ip_whitelist" -> {some={ server_ip_whitelist }}
+ | "social_discovery" -> {some={ social_discovery }}
+ | "terms_of_service_url" -> {some={ terms_of_service_url }}
+ | "user_support_email" -> {some={ user_support_email }}
+ | "user_support_url" -> {some={ user_support_url }}
+ | "website_url" -> {some={ website_url }}
+ | _ -> {none}
+
+ is_editable_property(property:Facebook.property) : bool =
+ match property with
+ | { id } -> false
+ | { name } -> false
+ | { description } -> false
+ | { category } -> false
+ | { company } -> false
+ | { icon_url } -> false
+ | { subcategory } -> false
+ | { link } -> false
+ | { logo_url } -> false
+ | { daily_active_users } -> false
+ | { weekly_active_users } -> false
+ | { monthly_active_users } -> false
+ | { created_time } -> false
+ | { creator_uid } -> false
+ | { iphone_app_store_id } -> false
+ | { hosting_url } -> false
+ | _ -> true
empty_feed = {
from = ""
View
424 lib/stdlib/apis/facebook/graph/graph.opa
@@ -1,3 +1,4 @@
+package facebook
/*
Copyright © 2011 MLstate
@@ -22,8 +23,8 @@
*/
import stdlib.apis.common
-import stdlib.apis.facebook
-import stdlib.apis.facebook.lib
+//import stdlib.apis.facebook
+//import stdlib.apis.facebook.lib
/**
* {1 About this module}
@@ -95,6 +96,13 @@ type FbGraph.Read.object =
/ { error : Facebook.error } /** Request failed */
/**
+ * Result of an raw request, just the response content.
+ */
+type FbGraph.Read.raw =
+ { content : string location : string content_type : string}
+ / { error : Facebook.error }
+
+/**
* Result of a multiple object request
*/
type FbGraph.Read.objects =
@@ -204,6 +212,14 @@ type FbGraph.event = {
}
/**
+ * Type of a Facebook achievement(instance)
+ */
+type FbGraph.achievement = {
+ achievement : string
+ message : string
+}
+
+/**
* Type of a Facebook album
*/
type FbGraph.album = {
@@ -214,6 +230,36 @@ type FbGraph.album = {
}
/**
+ * Type of a Facebook photo
+ */
+type FbGraph.photo = {
+ filename : string
+ content_type : string
+ source : string
+ message : string
+}
+
+/**
+ * Type of a Facebook video
+ */
+type FbGraph.video = {
+ filename : string
+ content_type : string
+ source : string
+ title : string
+ description : string
+}
+
+/**
+ * Type of a Facebook picture
+ */
+type FbGraph.picture = {
+ filename : string
+ content_type : string
+ source : string
+}
+
+/**
* Type of a Facebook link
* Default value is [FbGraph.Post.default_link]
* - [to] ID or username of the profile that this story will be published
@@ -286,11 +332,28 @@ type FbGraph.Insight.insights_res =
{ insights : FbGraph.Insight.insights }
/ { error : Facebook.error }
+type FbGraph.property_value0('a) =
+ { string : string }
+ / { int : int }
+ / { bool : bool }
+ / { object : list((string,'a)) }
+ / { array : list('a) }
+type FbGraph.property_value = FbGraph.property_value0(FbGraph.property_value)
+
+type FbGraph.property = (string,FbGraph.property_value)
+
+type FbGraph.properties = list(FbGraph.property)
+
+type FbGraph.object_type = {user} / {permissions} / {page}
+
+type FbGraph.order_status = {placed} / {settled} / {refunded} / {disputed} / {cancelled}
+
FbGraph = {{
/* Static */
@private graph_url = "https://graph.facebook.com"
+ @private video_url = "https://graph-video.facebook.com"
/* Generic private functions */
@@ -374,9 +437,8 @@ FbGraph = {{
check_for_error(r, on_ok, (x -> { error = x }))
| _ -> { error = Facebook.data_error }
- @private @publish generic_action(path, data, token) : FbGraph.Post.result =
- data = List.add(("access_token", token), data)
- match FbLib.fb_post(graph_url, path, data) with
+ generic_return(res) : FbGraph.Post.result =
+ match res with
| {none} -> { error = Facebook.network_error }
| {some=r} ->
match Json.of_string(r) with
@@ -389,9 +451,37 @@ FbGraph = {{
| {some={Bool=r}} ->
if r then { success = "" }
else { error = Facebook.data_error }
+ | {some={Int=number}} -> {success="{number}"}
| _ -> { error = Facebook.data_error }
end
+ @private @publish generic_action(path, data, token) : FbGraph.Post.result =
+ data = List.add(("access_token", token), data)
+ generic_return(FbLib.fb_post(graph_url, path, data))
+
+ @private @publish generic_action_multi(path, forms, token) : FbGraph.Post.result =
+ forms = List.add({form=("access_token", token)}, forms)
+ generic_return(FbLib.fb_post_multi(graph_url, path, forms))
+
+ @private @publish generic_action_multi_base(base, path, forms, token) : FbGraph.Post.result =
+ forms = List.add({form=("access_token", token)}, forms)
+ generic_return(FbLib.fb_post_multi(base, path, forms))
+
+ @private @publish generic_delete(path, data, token) : FbGraph.Post.result =
+ data = List.add(("access_token", token), data)
+ generic_return(FbLib.fb_delete(graph_url, path, data))
+
+ string_of_object_type(ot:FbGraph.object_type) =
+ match ot with
+ | {user} -> "user"
+ | {permissions} -> "permissions"
+ | {page} -> "page"
+
+ multiuser(id, users, pathname, fieldname) =
+ match users with
+ | [user_id] -> ("/{id}/{pathname}/{user_id}",[])
+ | _ -> ("/{id}/{pathname}",[(fieldname,String.concat(",",users))])
+
/* Submodules */
Delete = {{
@@ -400,13 +490,65 @@ FbGraph = {{
* Deletes object [id]
*/
object(id, token) =
- generic_action("/{id}", [("method","delete")], token)
+ generic_delete("/{id}", [], token)
+
+ /**
+ * Delete achievement(instance) object [id]
+ */
+ achievement(id, token) =
+ generic_delete("/{id}/achievements", [], token)
/**
- * Unlike object [id]
+ * Unlike object [id] (works with various types of id)
*/
unlike(id, token) =
- generic_action("/{id}/likes", [("method","delete")], token)
+ generic_delete("/{id}/likes", [], token)
+
+ /**
+ * Unban a user from an application. The token must be an application access token.
+ */
+ unban(user_id, token) =
+ generic_delete("/{user_id}", [], token)
+
+ /** Remove currency association from app. */
+ payment_currency(app_id, currency_url, token) =
+ generic_delete("/{app_id}", [("currency_url",currency_url)], token)
+
+ /** Remove user role from app. */
+ role(app_id, user, token) =
+ generic_delete("/{app_id}/roles", [("user",user)], token)
+
+ /** Delete subscriptions. */
+ subscriptions(app_id, object:option(FbGraph.object_type), token) =
+ data = FbLib.add_if_filled_opt("object", string_of_object_type, object, [])
+ generic_delete("/{app_id}/subscriptions", data, token)
+
+ /** Delete translations.
+ * The native_hashes actually come from the "Translations" app.
+ */
+ translations(app_id, native_hashes:list((string,string)), token) =
+ data = [("native_hashes",List.to_string_using("[","]",",",List.map(((s,d) -> "\{\"{s}\":\"{d}\"}"),native_hashes)))]
+ generic_delete("/{app_id}/translations", data, token)
+
+ /** Delete all scores. */
+ scores(app_id, token) = generic_delete("/{app_id}/scores", [], token)
+
+ /** Delete a comment. */
+ comment(comment_id, token) = generic_delete("/{comment_id}", [], token)
+
+ /** Uninvite a user. */
+ invited(event_id, user_id, token) = generic_delete("/{event_id}/invited/{user_id}", [], token)
+
+ /** Delete picture. */
+ picture(id, token) = generic_delete("/{id}/picture", [], token)
+
+ /** Delete friendlist. */
+ friendlist = object
+
+ /** Delete members. */
+ members(id, users, token) =
+ (path, data) = multiuser(id, users, "members", "members")
+ generic_delete(path, data, token)
}}
@@ -504,6 +646,205 @@ FbGraph = {{
Post = {{
+ string_of_property_value(pv:FbGraph.property_value) =
+ match pv with
+ | {~string} -> "\"{string}\""
+ | {~int} -> "{int}"
+ | {~bool} -> "{bool}"
+ | {~object} -> List.to_string_using("\{","}",",",List.map(((n,v) -> "\"{n}\":{string_of_property_value(v)}"),object))
+ | {~array} -> List.to_string_using("[","]",",",List.map(string_of_property_value,array))
+
+ options_of_properties(properties:FbGraph.properties) =
+ List.map(((n,pv) -> (n,string_of_property_value(pv))),properties)
+
+ generic_properties(id, properties, token) =
+ generic_action("/{id}", options_of_properties(properties), token)
+
+ /**
+ * Create achievement(instance) for [user_id]
+ */
+ achievement(user_id, achievement:FbGraph.achievement, token) =
+ data = FbGraph_to_string.achievement_to_data(achievement)
+ generic_action("/{user_id}/achievements", data, token)
+
+ /**
+ * Create migration for [app_id], [name]:[value]
+ */
+ migration(app_id, name, value:int, token) =
+ properties = [("migrations",{object=[(name,{int=(if value == 0 then 0 else 1)})]})]
+ generic_properties(app_id, properties, token)
+
+ /**
+ * Create restriction for [app_id], [name]:"[value]"
+ */
+ restriction(app_id, name, value:string, token) =
+ properties = [("restrictions",{object=[(name,{string=value})]})]
+ generic_properties(app_id, properties, token)
+
+ /**
+ * Modify properties for [app_id]
+ */
+ properties(app_id, properties, token) =
+ generic_properties(app_id, properties, token)
+
+ /**
+ * Create a test user for [app_id].
+ * NOTE: uses the application access token *NOT* the application Page access token.
+ */
+ test_user(app_id, installed:option(bool), permissions:list(Facebook.permission), name:string, token) =
+ data =
+ FbLib.add_if_filled("installed", Option.default("",Option.map(Bool.to_string,installed)), [])
+ |> FbLib.add_if_filled("permissions", String.concat(",",List.map(Facebook.permission_to_string,permissions)), _)
+ |> FbLib.add_if_filled("name", name, _)
+ generic_action("/{app_id}/accounts/test-users", data, token)
+
+ ban(app_id, users, token) =
+ data = [("uid",String.concat(",",users))]
+ generic_action("/{app_id}/banned", data, token)
+
+ simple_link(app_id, link, message, token) =
+ data =
+ [("link", link)]
+ |> FbLib.add_if_filled("message", message, _)
+ generic_action("/{app_id}/feed", data, token)
+
+ payment_currency(app_id, currency_url, token) =
+ data = [("currency_url", currency_url)]
+ generic_action("/{app_id}/payment_currencies", data, token)
+
+ /**
+ * Create a post on an application's profile page.
+ * Token needs [publish_stream] permissions.
+ * Works on various ids.
+ */
+ post(id, p:Facebook.post, token) =
+ data =
+ [("message",p.message),("link", p.link)]
+ |> FbLib.add_if_filled("picture", p.picture, _)
+ |> FbLib.add_if_filled("name", p.name, _)
+ |> FbLib.add_if_filled("caption", p.caption, _)
+ |> FbLib.add_if_filled("description", p.description, _)
+ |> FbLib.add_array_if_filled("actions", FbLib.actions_to_json, p.actions, _)
+ |> FbLib.add_if_filled("privacy", p.privacy, _)
+ generic_action("/{id}/feed", data, token)
+
+ /** Add user role for app. */
+ role(app_id, user, role, token) =
+ data = [("user",user),("role", role)]
+ generic_action("/{app_id}/roles", data, token)
+
+ /** Post a status message on an object. Various objects supported. */
+ status(id, message, token) =
+ data = [("message",message)]
+ generic_action("/{id}/feed", data, token)
+
+ /**
+ * Set up a subscription.
+ * Needs application page access token.
+ */
+ subscriptions(app_id, ot:FbGraph.object_type, fields:Facebook.properties, callback_url:string, verify_token:string, token) =
+ data =
+ [("object",string_of_object_type(ot))]
+ |> FbLib.add_json("fields", FbLib.fb_properties_to_json, fields, _)
+ |> List.add(("callback_url",callback_url),_)
+ |> FbLib.add_if_filled("verify_token", verify_token, _)
+ generic_action("/{app_id}/subscriptions", data, token)
+
+ /**
+ * Upload application strings for translation.
+ * Needs application page access token.
+ */
+ native_strings_to_json(native_strings:list({text:string; description:string})) : RPC.Json.json =
+ aux(ns) : RPC.Json.json =
+ {Record=[("text", {String=ns.text}:RPC.Json.json),
+ ("description", {String=ns.description}:RPC.Json.json)]}
+ {List=List.map(aux, native_strings)}
+
+ translations(app_id, native_strings:list({text:string; description:string}), token) =
+ data = FbLib.add_json("native_strings",native_strings_to_json,native_strings,[])
+ generic_action("/{app_id}/translations", data, token)
+
+ /**
+ * Requires multipart/form-data forms.
+ * NOTE: should also work with USER_ID and EVENT_ID (and maybe others).
+ * NOTE: this currently doesn't work because of facebook internal errors...
+ */
+ photos(album_id, photo, token) =
+ forms = FbGraph_to_string.photo_to_form(photo)
+ generic_action_multi("/{album_id}/photos", forms, token)
+
+ /**
+ * Publish a video to an Application.
+ * Also works with event_id.
+ * Requires multipart/form-data forms.
+ * NOTE: this currently doesn't work because of facebook internal errors...
+ */
+ videos(page_id, v:FbGraph.video, token) =
+ forms =
+ [{file=("source", v.filename, v.content_type, v.source)}]
+ |> FbLib.add_form_if_filled("title", v.title, _)
+ |> FbLib.add_form_if_filled("description", v.description, _)
+ generic_action_multi_base(video_url, "/{page_id}/videos", forms, token)
+
+ /**
+ * Requires multipart/form-data forms.
+ * NOTE: this currently doesn't work because of facebook internal errors...
+ */
+ picture(id, p:FbGraph.picture, token) =
+ forms = [{file=("source", p.filename, p.content_type, p.source)}]
+ generic_action_multi("/{id}/picture", forms, token)
+
+ users_generic(id, users:list(string), pathname, fieldname, token) =
+ if users == []
+ then {error=Facebook.make_error("FbGraph.Post.{pathname}","No users")}
+ else
+ (path,data) = multiuser(id, users, pathname, fieldname)
+ generic_action(path, data, token)
+
+ /**
+ * Invite users to an event.
+ * Needs [create_event] permission.
+ */
+ invited(event_id, invited:list(string), token) = users_generic(event_id, invited, "invited", "users", token)
+
+ /**
+ * Create a FriendList for a user.
+ * Maximum name length is 25 chars.
+ * Needs manage_friendlists permission.
+ */
+ friendlist(profile_id, name, token) =
+ if String.length(name) > 25
+ then {error=Facebook.make_error("friendlist","Name longer than 25 characters")}
+ else
+ data = [("name",name)]
+ generic_action("/{profile_id}/friendlists", data, token)
+
+ /**
+ * Invite users to an event.
+ * Needs [create_event] permission.
+ */
+ members(friendlist_id, members:list(string), token) = users_generic(friendlist_id, members, "members", "members", token)
+
+ string_of_order_status(os:FbGraph.order_status) =
+ match os with
+ | {placed} -> "placed"
+ | {settled} -> "settled"
+ | {refunded} -> "refunded"
+ | {disputed} -> "disputed"
+ | {cancelled} -> "cancelled"
+
+ /**
+ * Update an order.
+ * Docs don't say which kind of token/permission is needed.
+ * The params value is: "optional JSON-encoded dictionary {'comment' => }", however that is encoded.
+ */
+ order(id, status:FbGraph.order_status, message:string, params:string, token) =
+ data =
+ [("status",string_of_order_status(status))]
+ |> List.add(("message",message),_)
+ |> FbLib.add_if_filled("params", params, _)
+ generic_action("/{id}", data, token)
+
/**
* Post a new element in user's feed
* You can control the target of the feed with [feed.to].
@@ -521,7 +862,7 @@ FbGraph = {{
generic_action("/{object_id}/comments", data, token)
/**
- * Like [object_id] element on behalf of logger user
+ * Like [object_id] element on behalf of logger user (works with various types of id)
*/
like(object_id, token) =
generic_action("/{object_id}/likes", [], token)
@@ -613,17 +954,13 @@ FbGraph = {{
}
/**
- * Post a field
+ * Post an album
*/
album(profile_id, album, token) =
data = FbGraph_to_string.album_to_data(album)
generic_action("/{profile_id}/albums", data, token)
- /* Requires multipart/form-data forms
- photos(album_id, photo)
- */
-
- /* Quite recent feature and extremely poorly documented, so TODO later
+ /* NOTE: Publishing a Checkin object is deprecated in favor of creating a Post with a location attached.
checkins(profile_id, checkin)
*/
@@ -703,6 +1040,20 @@ FbGraph = {{
| _ -> { error = Facebook.data_error }
end
+ redirect(id, options) =
+ data = prepare_object_option(options)
+ FbLib.fb_get_redirect(graph_url, "/{id}", data)
+
+ /**
+ * Return the raw content of a request.
+ * Eg. profile pictures return jpeg data.
+ */
+ raw(id, options) : FbGraph.Read.raw =
+ data = prepare_object_option(options)
+ match FbLib.fb_get_ct(graph_url, "/{id}", data) with
+ | {none} -> { error = Facebook.network_error }
+ | {some=(content_type,location,content)} -> ~{ content; location; content_type }
+
/**
* Get information about objects with given ids, Results depends of options
* If no token is provided, only public information is available. Else,
@@ -776,6 +1127,41 @@ FbGraph = {{
data = [("type",FbGraph_to_string.pic_size_to_string(size))]
FbLib.generic_build_path("{graph_url}/{id}/picture", data)
+ /**
+ * Performs a read on [app_id] with added fields="migrations".
+ */
+ migrations(app_id, options) = object(app_id, {options with fields=List.add("migrations",options.fields)})
+
+ /**
+ * Performs a read on [app_id] with added fields="restrictions".
+ */
+ restrictions(app_id, options) = object(app_id, {options with fields=List.add("restrictions",options.fields)})
+
+ /**
+ * Returns a list of properties for an app.
+ */
+ properties(app_id, options, properties:list(Facebook.property)) =
+ props = String.concat(",",List.map(Facebook.string_of_property,properties))
+ object(app_id, {options with fields=List.add(props,options.fields)})
+
+ banned(app_id, options) = object("{app_id}/banned", options)
+ is_banned(app_id, user_id, options) = object("{app_id}/banned/{user_id}", options)
+ payment_currency(app_id, options) = object("{app_id}/payment_currencies", options)
+ roles(app_id, options) = object("{app_id}/roles", options)
+ scores(app_id, options) = object("{app_id}/scores", options)
+ invited(event_id, options) = object("{event_id}/invited", options)
+ is_invited(event_id, user_id, options) = object("{event_id}/invited/{user_id}", options)
+ attending(event_id, options) = object("{event_id}/attending", options)
+ is_attending(event_id, user_id, options) = object("{event_id}/attending/{user_id}", options)
+ maybe(event_id, options) = object("{event_id}/maybe", options)
+ is_maybe(event_id, user_id, options) = object("{event_id}/maybe/{user_id}", options)
+ declined(event_id, options) = object("{event_id}/declined", options)
+ is_declined(event_id, user_id, options) = object("{event_id}/declined/{user_id}", options)
+ noreply(event_id, options) = object("{event_id}/noreply", options)
+ photos(id, options) = object("{id}/photos", options)
+ picture(id, options) = redirect("{id}/photos", options)
+ friendlist = object
+
}}
Search = {{
@@ -894,10 +1280,18 @@ FbGraph = {{
|> FbLib.add_if_filled("start_time", aux_date(e.start_time), _)
|> FbLib.add_if_filled("end_time", aux_date(e.end_time), _)
+ achievement_to_data(a:FbGraph.achievement) =
+ [("achievement", a.achievement)]
+ |> FbLib.add_if_filled("message", a.message, _)
+
album_to_data(a:FbGraph.album) =
[("name", a.name)]
|> FbLib.add_if_filled("message", a.message, _)
|> FbLib.add_if_filled("location", a.location, _)
|> FbLib.add_if_filled("link", a.link, _)
+ photo_to_form(p:FbGraph.photo) =
+ [{file=("source", p.filename, p.content_type, p.source)}]
+ |> FbLib.add_form_if_filled("message", p.message, _)
+
}}
View
130 lib/stdlib/apis/facebook/lib/lib.opa
@@ -1,3 +1,4 @@
+package facebook
/*
Copyright © 2011 MLstate
@@ -22,7 +23,7 @@
*/
import stdlib.apis.common
-import stdlib.apis.facebook
+//import stdlib.apis.facebook
/**
* {1 About this module}
@@ -40,27 +41,102 @@ FbLib = {{
/**
* Make a HTTP GET on [path] at [base] with [data]
*/
- fb_get(base, path, data) =
+ @private fb_get_(base, path, data, process) =
final_path = generic_build_path("{base}{path}", data)
+ do jlog("GET {final_path}")
match Uri.of_string(final_path) with
| {none} -> none
- | {some=uri} ->
- match WebClient.Get.try_get(uri) with
- | {failure=_} -> none
- | {success=s} -> {some=s.content}
- end
+ | {some=uri} -> process(WebClient.Get.try_get(uri))
+
+ @private content_only(res) =
+ match res with
+ | {failure=_} -> none
+ | {success=s} -> do jlog("HTTP {s.code}\n{s.content}") {some=s.content}
+
+ // header_get doesn't work on node.
+ find_header(name,headers) =
+ List.fold((h, acc ->
+ if String.has_prefix(name,h)
+ then
+ len = String.length(name)
+ {some=String.sub(len+2,String.length(h)-(len+2),h)}
+ else acc),headers,none)
+
+ @private content_with_type(res) =
+ match res with
+ | {failure=_} -> none
+ | {success=s} ->
+ do jlog("hdrs=\n{String.concat("\n",s.headers)}")
+ content_type = Option.default("unknown/unknown",find_header("content-type",s.headers))
+ location = Option.default("",find_header("location",s.headers))
+ do jlog("HTTP {s.code} type={content_type} location={location}")
+ {some=(content_type,location,s.content)}
+
+ @private redirect(res) =
+ match res with
+ | {failure=_} -> none
+ | {success=s} ->
+ do jlog("HTTP {s.code}")
+ if s.code == 302
+ then find_header("location",s.headers)
+ else none
+
+ fb_get(base, path, data) = fb_get_(base, path, data, content_only)
+ fb_get_ct(base, path, data) = fb_get_(base, path, data, content_with_type)
+ fb_get_redirect(base, path, data) = fb_get_(base, path, data, redirect)
/**
- * Make a HTTP GET on [path] at [base] with [data]
+ * Make a HTTP POST on [path] at [base] with [data]
*/
fb_post(base, path, data) =
txtdata = API_libs.form_urlencode(data)
+ do jlog("POST {base}{path}\n{txtdata}\n")
match Uri.of_string("{base}{path}") with
| {none} -> none
| {some=uri} ->
match WebClient.Post.try_post(uri,txtdata) with
| {failure=_} -> none
- | {success=s} -> {some=s.content}
+ | {success=s} -> do jlog("HTTP {s.code}\n{s.content}") {some=s.content}
+ end
+
+ @private memdump = (%% BslPervasives.memdump %%: string -> string)
+
+ /**
+ * Make a HTTP POST on [path] at [base] with [forms] form data
+ */
+ fb_post_multi(base, path, forms) =
+ bound = Random.string(20)
+ mimetype = "multipart/form-data; boundary={bound}"
+ forms = List.map((f ->
+ match f with
+ | {form=(name, content)} ->
+ "--{bound}\r\nContent-Disposition: form-data; name=\"{name}\"\r\n\r\n{content}\r\n"
+ | {file=(name, filename, content_type, content)} ->
+ "--{bound}\r\nContent-Disposition: form-data; name=\"{name}\"; filename=\"{filename}\"\r\nContent-Type={content_type}\r\n\r\n{content}\r\n"
+ ),forms)
+ content = some(String.concat("",List.append(forms,["--{bound}--\r\n"])))
+ options = ~{ WebClient.Post.default_options with mimetype content }
+ do jlog("POST {base}{path}\n{memdump(Option.get(content))}\n")
+ match Uri.of_string("{base}{path}") with
+ | {none} -> none
+ | {some=uri} ->
+ match WebClient.Post.try_post_with_options(uri,options) with
+ | {failure=_} -> none
+ | {success=s} -> do jlog("HTTP {s.code}\n{s.content}") {some=s.content}
+ end
+
+ /**
+ * Make a HTTP DELETE on [path] at [base] with [data]
+ */
+ fb_delete(base, path, data) =
+ final_path = generic_build_path("{base}{path}", data)
+ do jlog("DELETE {final_path}")
+ match Uri.of_string(final_path) with
+ | {none} -> none
+ | {some=uri} ->
+ match WebClient.Delete.try_delete(uri) with
+ | {failure=_} -> none
+ | {success=s} -> do jlog("HTTP {s.code}\n{s.content}") {some=s.content}
end
/* Generic JSON functions */
@@ -76,12 +152,44 @@ FbLib = {{
| _ -> ""
add_if_filled(name, v, data) =
- if v == "" then data
+ if v == ""
+ then data
else List.add((name, v), data)
+ add_if_filled_opt(name, tostr, v, data) =
+ if Option.is_none(v)
+ then data
+ else List.add((name, tostr(Option.get(v))), data)
+
+ add_if_filled_generic(name, tostr, v, data) =
+ str = tostr(v)
+ if str == ""
+ then data
+ else List.add((name, str), data)
+
+ add_bool_if_filled(name, v:option(bool), data) = add_if_filled_opt(name, Bool.to_string, v, data)
+
+ add_int_if_filled(name, v:option(int), data) = add_if_filled_opt(name, Int.to_string, v, data)
+
+ add_array_if_filled(name, tojson:list('a)->RPC.Json.json, v:list('a), data) =
+ if v == []
+ then data
+ else List.add((name, Json.serialize(tojson(v))), data)
+
+ add_json(name, tojson:'a->RPC.Json.json, v:'a, data) =
+ List.add((name, Json.serialize(tojson(v))), data)
+
+ add_form_if_filled(name, v, data) =
+ if v == ""
+ then data
+ else List.add({form=(name, v)}, data)
+
/* Feed to data */
- @private actions_to_json(actions) : RPC.Json.json =
+ fb_properties_to_json(properties:Facebook.properties) : RPC.Json.json =
+ {List=List.map((p -> {String=Facebook.string_of_property(p)}),properties)}
+
+ actions_to_json(actions) : RPC.Json.json =
aux(l:Facebook.feed_link) : RPC.Json.json =
{Record=[("name", {String=l.text}:RPC.Json.json),
("link", {String=l.href}:RPC.Json.json)]}
View
11 lib/stdlib/apis/facebook/rest/rest.opa
@@ -1,3 +1,4 @@
+package facebook
/*
Copyright © 2011 MLstate
@@ -28,7 +29,8 @@
* @stability Work in progress
*/
-import stdlib.apis.{common, facebook, facebook.lib}
+//import stdlib.apis.{common, facebook, facebook.lib}
+import stdlib.apis.common
import stdlib.crypto
/**
@@ -1044,6 +1046,13 @@ FbRest = {{
List.fold(aux, List.tail(permissions), "&ext_perm={FbRest_private._perm_to_string(List.head(permissions))}")
"http://www.facebook.com/connect/prompt_permissions.php?api_key={api_key}&v=1.0&next={next_url}{perms_text}&enable_profile_selector=1"
+ oauth_dialog_url(api_key:string, permissions, next_url:string) =
+ perms_text = if permissions == [] then ""
+ else
+ aux(elt, acc:string) = "{acc},{FbRest_private._perm_to_string(elt)}"
+ List.fold(aux, List.tail(permissions), "&scope={FbRest_private._perm_to_string(List.head(permissions))}")
+ "http://www.facebook.com/dialog/oauth/?client_id={api_key}&redirect_uri={next_url}&state={Random.string(20)}{perms_text}"
+
/**
* Helper for construction of event_info
*
View
9 lib/stdlib/apis/github/auth/auth.opa
@@ -21,7 +21,7 @@
* @destination public
*/
-//package stdlib.apis.github.auth
+package stdlib.apis.github.auth
import stdlib.apis.common
import stdlib.apis.github.lib
@@ -34,6 +34,9 @@ type GHAuth.scope =
{user} /** DB read/write access to profile info only. */
/ {public_repo} /** DB read/write access, and Git read access to public repos. */
/ {repo} /** DB read/write access, and Git read access to public and private repos */
+ / {repo_status} /** Read/write access to public and private repo statuses.
+ Does not include access to code - use repo for that. */
+ / {delete_repo} /** Delete access to adminable repositories. */
/ {gist} /** Write access to gists. */
@private GHAp = {{
@@ -43,6 +46,8 @@ type GHAuth.scope =
| {user} -> "user"
| {public_repo} -> "public_repo"
| {repo} -> "repo"
+ | {repo_status} -> "repo:status"
+ | {delete_repo} -> "delete_repo"
| {gist} -> "gist"
}}
@@ -72,7 +77,7 @@ GHAuth(conf:GHAuth.conf) = {{
("code", code)]
match GHLib.full_post(base, path, data, some) with
| {some=c} ->
- token = AL.get_field(AL.get_data(c), "access_token")
+ token = AL.get_field(AL.get_data(c.content), "access_token")
if token == "" then {none}
else {some=token}
| _ -> {none}
View
161 lib/stdlib/apis/github/commit/commit.opa
@@ -1,161 +0,0 @@
-/*
- Copyright © 2011 MLstate
-
- This file is part of Opa.
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-/*
- * Author : Nicolas Glondu <nicolas.glondu@mlstate.com>
- **/
-
-/**
- * GitHub commit API module
- *
- * @category api
- * @author Nicolas Glondu, 2011
- * @destination public
- */
-
-//package stdlib.apis.github.commit
-import stdlib.apis.github
-import stdlib.apis.github.lib
-
-/* Types returned by API */
-
-type GitHub.commit = {
- id : string
- parents : list(string)
- author : GitHub.commit_user
- message : string
- url : string
- commited_date : Date.date
- authored_date : Date.date
- tree : string
- committer : GitHub.commit_user
-}
-
-type GitHub.commit_more = {
- base : GitHub.commit
- modified : list((string,string))
- removed : list(string)
-}
-
-@private GHCp = {{
-
- @private GP = GHParse
-
- get_commit_internal(m) =
- parents = List.filter_map(
- j -> match j:RPC.Json.json with
- | {Record=r} ->
- match List.assoc("id",r) with
- | {some={String=s}} -> some(s)
- | {some=v} -> some(Json.serialize(v))
- | {none} -> none
- end
- | _ -> none,
- m.list("parents"))
- { id = m.str("id")
- parents = parents
- author = GP.get_commit_user(m.record("author"))
- message = m.str("message")
- url = m.str("url")
- commited_date = m.date("commited_date")
- authored_date = m.date("authored_date")
- tree = m.str("tree")
- committer = GP.get_commit_user(m.record("committer"))
- } : GitHub.commit
-
- get_commit(srcmap) =
- m = GP.map_funs(srcmap)
- if m.exists("id") then
- some(get_commit_internal(m))
- else none
-
- get_commit_more(srcmap) =
- m = GP.map_funs(srcmap)
- if m.exists("id") then
- base = get_commit_internal(m)
- removed = m.list("removed")
- |> List.filter_map(
- x ->
- match x with
- | {String=s} -> some(s)
- | _ -> none,
- _ )
- modified = m.list("modified")
- |> List.fold(
- e, acc ->
- match e:RPC.Json.json with
- | {Record=r} ->
- List.fold(
- (k,v), acc ->
- vv = match v:RPC.Json.json with
- | {String=s} -> s
- | _ -> Json.serialize(v)
- List.add((k,vv),acc),
- r, acc
- )
- | _ -> acc,
- _, [])
- some(~{base modified removed}:GitHub.commit_more)
- else none
-
- multiple_commits(res) =
- GP.dewrap_list(res, "commits", get_commit)
-
- one_commit_more(res) =
- GP.dewrap_obj(res, "commit", get_commit_more)
-
-}}
-
-GHCommit = {{
-
- @private p(o:string,r:string) = "{o}/{r}"
-
- /**
- * Gets a list of commits on a branch of a repo
- *
- * @param owner Owner of the repo
- * @param repo Repository to get commits from
- * @param branch Branch to get commits from
- * @param page Page of commits displayed. First page is 1. If a value inferior to 1 is provided, it is considered as 1.
- */
- get_commits(owner, repo, branch:string, page:int) =
- path = "/commits/list/{p(owner,repo)}/{branch}"
- /* Force the min value of page to 1, GitHub also does
- it on its side anyway. */
- page = if page < 1 then 1 else page
- data = [("page",Int.to_string(page))]
- GHLib.api_get(path, data, GHCp.multiple_commits)
-
- /**
- * Gets a list of commit on a file on a branch of a repo
- *
- * @param owner Owner of the repo
- * @param repo Repository to get commits from
- * @param branch Branch to get commits from
- * @param file File to follow
- * @param page Page of commits displayed. First page is 1. If a value inferior to 1 is provided, it is considered as 1.
- */
- get_file_commits(owner, repo, branch:string, file:string, page) =
- path = "/commits/list/{p(owner,repo)}/{branch}/{file}"
- /* Force the min value of page to 1, GitHub also does
- it on its side anyway. */
- page = if page < 1 then 1 else page
- data = [("page",Int.to_string(page))]
- GHLib.api_get(path, data, GHCp.multiple_commits)
-
- /**
- * Gets detailled information about one commit
- */
- get_commit(owner, repo, sha:string) =
- path = "/commits/show/{p(owner,repo)}/{sha}"
- GHLib.api_get(path, [], GHCp.one_commit_more)
-
-}}
View
416 lib/stdlib/apis/github/events/events.opa
@@ -0,0 +1,416 @@
+/*
+ Copyright © 2011 MLstate
+
+ This file is part of Opa.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/*
+ * Author : Nicolas Glondu <nicolas.glondu@mlstate.com>
+ **/
+
+package stdlib.apis.github.events
+import stdlib.apis.github
+import stdlib.apis.github.lib
+
+/**
+ * GitHub user API module
+ *
+ * @category api
+ * @author Nicolas Glondu, 2011
+ * @destination public
+ */
+
+type GitHub.page = {
+ page_name : string
+ title : string
+ action : string
+ sha : string
+ html_url : string
+}
+
+type GitHub.push_event = {
+ head : string
+ ref : string
+ size : int
+ commits : list({sha : string
+ message : string
+ author : { name : string
+ email : string
+ }
+ url : string
+ distinct : bool
+ })
+}
+
+type GitHub.payload =
+ { repo_comment:GitHub.repo_comment } // CommitCommentEvent
+ / { ref_type:string ref:string master_branch:string description:string } // CreateEvent
+ / { ref_type:string ref:string } // DeleteEvent
+ / { download:GitHub.download } // DownloadEvent
+ / { target:GitHub.user } // FollowEvent
+ / { forkee:GitHub.repository } // ForkEvent
+ / { head:string before:string after:string } // ForkApplyEvent
+ / { action:string gist:GitHub.gist } // GistEvent
+ / { pages:list(GitHub.page) } // GollumEvent
+ / { action:string issue:GitHub.issue comment:GitHub.issue_comment } // IssueCommentEvent
+ / { action:string issue:GitHub.issue } // IssuesEvent
+ / { member:GitHub.user action:string } // MemberEvent
+ / { empty } // PublicEvent - empty payload
+ / { action:string number:int pull_request:GitHub.pull_req } // PullRequestEvent
+ / { prr_comment:GitHub.repo_comment } // PullRequestReviewCommentEvent // ??? check this, is this repo_comment?
+ / { push_event : GitHub.push_event } // PushEvent
+ / { team : GitHub.id_name_url user:GitHub.user repo:GitHub.repository } // TeamAddEvent
+ / { action:string } // WatchEvent
+ / { raw : list((string,RPC.Json.json)) }
+
+type GitHub.event = {
+ `type` : string
+ `public` : bool
+ payload : GitHub.payload
+ repo : GitHub.id_name_url
+ actor : GitHub.short_user
+ org : GitHub.short_user
+ created_at : Date.date
+ id : int
+}
+
+@private GHEp = {{
+
+ @private GP = GHParse
+
+// { comment:GitHub.repo_comment } // CommitCommentEvent
+
+ get_commitcommentevent(srcmap) : option(GitHub.payload) =
+ m = GP.map_funs(srcmap)
+ match (GP.get_rec(m, "comment", GP.get_repo_comment)) with
+ | {some=repo_comment} ->
+ res = {
+ repo_comment = repo_comment
+ } : GitHub.payload
+ {some=res}
+ | _ -> none
+
+// / { ref_type:string ref:string master_branch:string description:string } // CreateEvent
+
+ get_createevent(srcmap) : option(GitHub.payload) =
+ m = GP.map_funs(srcmap)
+ if m.exists("ref")
+ then
+ res = {
+ ref = m.str("ref")
+ master_branch = m.str("master_branch")
+ ref_type = m.str("ref_type")
+ description = m.str("description")
+ } : GitHub.payload
+ {some=res}
+ else none
+
+// / { ref_type:string ref:string } // DeleteEvent
+
+ get_deleteevent(srcmap) : option(GitHub.payload) =
+ m = GP.map_funs(srcmap)
+ if m.exists("ref")
+ then
+ res = {
+ ref = m.str("ref")
+ ref_type = m.str("ref_type")
+ } : GitHub.payload
+ {some=res}
+ else none
+
+// / { download:GitHub.download } // DownloadEvent
+
+ get_downloadevent(srcmap) : option(GitHub.payload) =
+ m = GP.map_funs(srcmap)
+ match (GP.get_rec(m, "download", GP.get_download)) with
+ | {some=download} ->
+ res = {
+ download = download
+ } : GitHub.payload
+ {some=res}
+ | _ -> none