The Friends Service provides an API for interacting with your social
networks. The friends service uses microblogging accounts configured in
Ubuntu Online Accounts.
Currently there are friends plugins for facebook, twitter, flickr,
foursquare and identica.
Sound familiar? Friends is actually a rewrite of the Gwibber service. It
began as an attempt to port gwibber-service to python3 and add testing, but
it quickly became obvious that it would be easier to start over. Credit for
the rewrite goes to Barry Warsaw and Robert Park, they rocked friends!
Impressively, Barry got the rewrite started by writing the test suite and using test
driven development, what a hero! Friends now has an extensive test suite and truly
beautiful code.
The service provides a Dee.SharedModel that contains the aggregated feed
from all of your enabled accounts. Any application can connect to this
model and provide a user interface to display the feed. You can create
filtered models off that shared model to sort or limit the results to specific
accounts, types, etc. Your application never actually talks directly to the
web API provided by the social network, it would just interact with Friends.
This Dee model is currently used in the Friends lens, People lens and Gwibber.
The Friends service also provides APIs for sharing images, posting status
updates, replies, liking posts, retweet, contact sync, etc.
GObject APIs are provided by libfriends, including vala and GIR bindings (plus some GTK widgets). There is also a QML plugin, qml-friends.
All the packages are available in universe for raring, and for quantal in the super-friends PPA.
Here’s an example using Friends from QML posting a status update:
import QtQuick 2.0
import Ubuntu.Components 0.1
import Friends 0.1
MainView {
applicationName: "poster"
width: units.gu(50)
height: units.gu(20)
FriendsDispatcher {
id: friends
// use this to check if the send was successfull
onSendComplete: {
if (success) {
activitySpinner.visible = false;
entry.text = "";
console.log ("Send completed successfully");
} else {
activitySpinner.visible = false;
console.log ("Send failed: " + errorMessage);
}
}
}
Column {
anchors.centerIn: parent
width: units.gu(40)
spacing: units.gu(2)
TextArea {
id: entry
objectName: "entry"
anchors {
left: parent.left
leftMargin: units.gu(1)
right: sendButton.left
rightMargin: units.gu(1)
bottomMargin: units.gu(1.5)
}
focus: true
font.pixelSize: FontUtils.sizeToPixels("medium")
font.family: "Ubuntu"
// send message if return was pressed
Keys.onReturnPressed: sendButton.clicked(null)
Keys.onEscapePressed: text = ""
height: units.gu(4)
placeholderText: i18n.tr("Compose")
autoSize: true
maximumLineCount: 0
ActivityIndicator {
id: activitySpinner
objectName: "activitySpinner"
anchors.centerIn: entry
visible: false
running: visible
}
}
Button {
id: sendButton
objectName: "sendButton"
anchors {
right: parent.right
rightMargin: units.gu(1)
left: entry.right
bottom: entry.bottom
}
width: units.gu(9)
height: units.gu(4)
color: "#dd4814"
text: i18n.tr("Send")
onClicked: {
console.log ("Post: " + entry.text);
activitySpinner.visible = true
friends.sendAsync(entry.text);
}
}
}
}