Posts in Category: Articles

Getting to grips with the Facebook API with PHP and JavaScript SDK Part 1 

For a research project we are working with peoples Facebook data amongst other social data, this required writing an application to inspect user content utilising the public API. This process shone some light on the privacy of Facebook. A lot of stories in recent years have focused primarily on how Facebook changes its privacy settings but not enough has been focused on the vulnerability of apps to the privacy intentions of the user.

To give you an understanding I though I would work through an example of how you can easily create an app and access more than probably expected about your data and your friends. To note before anyone complains I realise that you are required to install the application for it to have any meaning, but I will give an example of where what happens is not possibly what you would expect to counter this.

During testing of our app for the project a collection of colleagues installed a test version to make sure when used in the wild it would perform as expected. A user had their privacy settings so that friends of the user could not see the their friends unless they were in common. This I am sure is common for a lot of people on Facebook, what happened with the app though is it got full access to her friends list, now may sound strange to highlight this since it asked for permission to do this, but when you consider that this user is sharing more with a random installed app than with their actual friends? I am doubtful this is was what was originally intended by this user.

Anyway, back to the example. This is worked through using Facebook Developer interface with Facebook PHP SDK.

The Facebook API is incredible simple but also incredible confusing at the same time -- what you would expect from a major corporation’s software. 

So I will break this down into several steps that I will cover over a series of articles in general I will try to address 2 aspects per article:

  1. Authenticating a user / Getting them to install your app
  2. What the app can see of my feed
  3. What the app can see of my friends
  4. Photos galore
  5. Having some fun with the API
  6. The monkey in the closet

A couple of notes on what this will tell you how to do and what it wont. I am writing this app as an external entity to Facebook and less intended to be nested into the Facebook site via their canvas approach. To achieve a nested app you will probably want to do things a little different and probably exploit javascript.

1. Authenticating a user / Getting them to install your app

Facebook apps are simple to write once you get a handle on the paths required is simple to adjust to do more. So to get someone to install your app you need a link[Ref: Facebook PHP SDK examples].

To get started, you need to direct the perspective user to Facebook

Firstly create an object with your app credentials and see if you have a user, this follows SDK example

require 'api/utils/facebook.php';
$facebook = new Facebook(array(
  'appId'  => 'xxxx',
  'secret' => 'xxxx',
));
$user = $facebook->getUser();
if ($user) {
  try {
    // Proceed knowing you have a logged in user who's authenticated.
    $user_profile = $facebook->api('/me');
  } catch (FacebookApiException $e) {
    error_log($e);
    $user = null;
  }
}

Now you can either do something with the $user or detect NULL and push them to add your app

if ($user) {
  $_GET["id"] = $user_profile['id'];
  $logoutUrl = $facebook->getLogoutUrl();
} else {
  $statusUrl = $facebook->getLoginStatusUrl();
  $pageURL = 'http';
  if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
  $pageURL .= "://";
  if ($_SERVER["SERVER_PORT"] != "80") {
    $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
  } else {
    $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
  }

  $params = array(
     scope => 'read_stream,user_photos',
     redirect_uri => $pageURL."?type=0"
  );
  $loginUrl = $facebook->getLoginUrl($params);
}

So to highlight a couple of differences between the PHP SDK example and the above code. This code requests permissions and secondly specifies redirect url. These are both useful since you need to request your permissions here as well as in the app settings. Here you can see we have requested read_stream and user_photos there is a list of available of facebook basic and extended permissions available at https://developers.facebook.com/docs/reference/login/extended-permissions/. Also to note by providing the return url you can specify any properties you want so in my example I had multiple modes of using the app requesting different permissions defined by type.

Ok so now we have done all this we can now push a user to the App using the $loginUrl. As I mentioned earlier my scenario is external to Facebook you would probably want to automatically request permissions if you are in the canvas.

<a class="btn" href="<?php echo $loginUrl; ?>">Install my app it’s awesome!</a>


2. What the app can see of my feed

To continue my previous rant I’ll give you some examples of what you can do with Facebook exposing more than you possible more than you expected.

Completely public details:

https://graph.facebook.com/706861067

or

https://graph.facebook.com/StuartAaronJames

Returns:

{
   "id": "706861067",
   "name": "Stuart James",
   "first_name": "Stuart",
   "last_name": "James",
   "link": "http://www.facebook.com/StuartAaronJames",
   "gender": "male",
   "locale": "en_GB",
   "username": "StuartAaronJames"
}

To get a bit further you need a token, easily acquired via making an app or the development site on Facebook. So now to get a grip with the api to get a user feed simple extend the url with /feed and your token. If you don’t have that user yet you can view their public feed.

https://graph.facebook.com/706861067/feed?access_token=XXXX

Facebook is great for JavaScript developers returning information in JSON format. So you can utilise

var jsonObject=JSON..parse(response);

Then iterate over the response contains two components an array of data items in the “data” tag and paging information to get the next and previous via the “paging” tag.

To get started with this and see what your profile will return follow these simple steps

  1. Sign up as Facebook Developer (Sadly my memory of this process is vague having done it several years ago, it is barely more than clicking yes on developers.facebook.com)
  2. Navigate to https://developers.facebook.com/tools/explorer/ and grab your key
  3. Navigate to https://graph.facebook.com/me/feed?access_token=XXXX
  4. Replace XXXX with your token

You will see the JSON response and you can figure out how to parse your profile feed into something more meaningful.

To Come…

The next article will cover:

  1. What the app can see of my friends
  2. Photos galore

And will hopefully include more pictures!

Gravatar
Posted by Stuart James Friday, January 31, 2014 12:01:00 PM Categories: API Articles HowTo Programming

Boost Serialization fast and easy Serialization of objects for C++ to XML,Text or Binary 

While coding I always try to learn new ways of writing old things. There are many many libraries out there for C++ all work in different ways, but the library I fell in love with is Boost. Ignoring the massive extension to the STL basic classes it bundles up matrix, graph, system functionality. But what beats all of that mainly because I write it to often is the ever allusive save and load functionality you have to write for all classes. Serialization is one of the things I really miss from my old C# writing days. So here goes a few examples of how to make serialization work!

In C++ there is no reflector so sadly we have to tell the compiler what to save. So an example class

 

1 class NodeDescriptor{ 2 public: 3 NodeDescriptor() {} ; 4 NodeDescriptor(int offset): 5 Offset(offset){} ; 6 ~NodeDescriptor() {} ; 7 int Offset; 8 private: 9 };

Very very basic, one public variable this is an internal of another object so is reasonable to allow a public property style access. So what we want to do is to do is allow Boost access to save out the variables.

 

1 class NodeDescriptor{ 2 public: 3 NodeDescriptor() {} ; 4 NodeDescriptor(int offset): 5 Offset(offset){} ; 6 ~NodeDescriptor() {} ; 7 int Offset; 8 private: 9 // Serialization Settings 10 friend class boost::serialization::access; 11 friend std::ostream & operator<<(std::ostream &os, const MotionGraphDesc &mgd); 12 template<class Archive> 13 void serialize(Archive & ar, const unsigned int /* file_version */) 14 { 15 ar & BOOST_SERIALIZATION_NVP(Offset); 16 } 17 };

So what we have added is allowing boost access via a friend operator. Then adding a class for serialize the data, unfortunately you have to define the data of which there is many ways todo, above is an example of the xml way, what this does is create a xml tag called Offset where it stores the value of Offset. Alternatively say we had a private member _offset, it wouldn’t be visually nice to read the xml so we can customise the name of the tag.

1 void serialize(Archive & ar, const unsigned int /* file_version */) 2 { 3 ar & boost::serialization::make_nvp("Offset",_offset); 4 }

This is actually what the BOOST_SERIALIZATION_NVP macro roles out into but BOOST_SERIALIZATION_NVP is slightly more convenient in a large amount of cases. So now the question is how do we save? Well if you add in a couple of methods to your class description for Load, Save you get something like this, to note I have defined an enum that will come in to play with the read write functions.

1 bool NodeDescriptor::Load(const char* path,SerializeAsType t){ 2 std::ifstream f(path); 3 if (f.is_open()){ 4 Read(f,t); 5 }else 6 return false; 7 } 8 9 bool NodeDescriptor::Save(const char* path,SerializeAsType t){ 10 std::ofstream f(path); 11 if (f.is_open()){ 12 Write(f,t); 13 }else 14 return false; 15 }

Now we define the read write:

1 bool NodeDescriptor::Read(std::istream& str,SerializeAsType t){ 2 switch(t){ 3 case XmlArc: 4 { 5 boost::archive::xml_iarchive ia(str); 6 ia >> boost::serialization::make_nvp("NodeDescriptor",(*this)); 7 } 8 break; 9 case TextArc: 10 { 11 boost::archive::text_iarchive ia(str); 12 ia >> *this; 13 } 14 break; 15 case BinaryArc: 16 { 17 boost::archive::binary_iarchive ia(str); 18 ia >> *this; 19 } 20 break; 21 } 22 return true; 23 } 24 25 bool NodeDescriptor::Write(std::ostream& str,SerializeAsType t){ 26 switch(t){ 27 case XmlArc: 28 { 29 boost::archive::xml_oarchive oa(str); 30 oa << boost::serialization::make_nvp("NodeDescriptor",(*this)); 31 } 32 break; 33 case TextArc: 34 { 35 boost::archive::text_oarchive oa(str); 36 oa << (*this); 37 } 38 break; 39 case BinaryArc: 40 { 41 boost::archive::binary_oarchive oa(str); 42 oa << (*this); 43 } 44 break; 45 } 46 return true; 47 }

How easy is that? Most of the space is taken up by making it more compatible allowing the save and load of XML, Text and Binary archives. One thing to note thought is that this is for the purpose of serialization not really a property config file. The other thing to consider is this is a lazy coder solution, it isn’t fast so don't create massive xml files or they will take a long time to read in and out!

Thursday, August 2, 2012 12:02:00 PM Categories: Articles C++ HowTo Programming

Map a point within a triangle from low dimensions to high 

The work I have been doing recently is to explore a mapping from a low dimensional space(10d) to a high dimensional space(160d). Although is not a particularly common problem is something that requires a little thinking.

The obvious solution is to measure the distance, from the point to the three, triangle points. This of course is difficult to rationalise to a ratio that sums to 1.

Barycentric-BasicMapping

This problem becomes more obvious when a point lies on one of the points on the triangle. For example, this could result in a distance of [0, 50 50]. This distance means that if you project this using this information even if normalised, the point will not lie on the triangle coordinate in the higher dimensional space.

To be able to map between two triangles accurately the best solution is to utilise Barycentric coordinates. This turns the 3 points of the triangle into three vertices. Using this information you are then able to solve to find the ratios to accurately map between the two spaces.

Barycentric-Mapping

Therefore to generate a new point in 2D, you have:

To get to this point we need to solve the equations for lambda, resulting in n equations for each of the different dimensions.

This can be solved relatively easily using a linear solver.

So now using this information it is easy to project the point from one triangle to the other. We have provided a Matlab solution to be able to easily map using two triangles.

1 A = []; 2 B = [] ; 3 for i=1:size(ntA,1) 4 line = [(ntA(i,1) - ntA(i,3)) (ntA(i,2) - ntA(i,3)) ]; 5 B = [ B ; (ntA(i,3) - Qn(i)) ] ; 6 A = [A ; line]; 7 end 8 Lambda = linsolve(A,-B);

Therefore you can map the new point using

1 Lambda = [Lambda ; ( 1 - Lambda(1) - Lambda(2) )]; 2 3 pB = sum(tB .* repmat(Lambda',[],size(tB,1)),2);

 

You can view a complete version of this code, as well as a test case Files.

See: Files –>  Barycentric Coordinates

Equations thanks to the ever wonderful Wikipedia

Saturday, April 21, 2012 3:19:00 PM Categories: Articles HowTo
Stuart James