Search the API Reference:
Top Companies News
This tutorial walks you thru the creation of the Acre app contained in the Acre Introduction Screencast that can display the latest news about the 3 companies with the highest market cap in any given industry. We will query Freebase for these top companies given an industry, and then retrieve news articles about them from Google News, and display those articles together in a web page. You might even find this little app very useful, because if you were to type something like "top 3 pharmaceutical companies" into any existing news search engine, you would be unlikely to get the result you were looking for.
Setting up the App
The Acre IDE is called "App Editor" and it's a client side web application usable in any modern browser. To start a new application after having signed in, you just need to provide a name and an ID for your app. We'll call this one "newsworthy". Our new app contains a single file called "index", the typical default entry page for any web app.
Querying for Data
An app can contain several types of files. In fact, we will leave "index" now and come back to it later. Let's start with a query file instead.
- click "New File"
- pick "Query"
- type "top_companies"
- click "Create New File"
Acre embeds the Freebase query editor which was designed to help you easily construct queries of Freebase data. We'll start out by specifying that we want to query for topics of the type 'company', to do this just type
type:
at the cursor, inside the curly brakets. As we might not remember the exact ID of the 'company' type used inside Freebase, we can simply hit the Tab key to invoke the query assist feature and search for "company"
- hit Tab
- type "compa"
- hit Enter
Next, again using the query assist feature, we specify that we only want companies from, say, the pharmaceutical industry. We will support any arbitrary industry later.
- hit Tab, type "ind", hit Enter
- type "{ id:"
- hit Tab
- type "pharm", hit Enter
- type "}"
Then we request for the name and id of these companies by adding
name: null,
id: null
to the query. Now we can run the query by clicking the run button and check the results on the right pane.
We can also switch to the interactive 'Tree view' to get previews of the companies.
Next, we'll query for the market capitalization of each company. For each company, however, there may be several records for its market capital, for different combinations of year and currency. We want only those in US dollars. And we want to pick only the latest record by sorting them newest to oldest and picking the first one. Let's add the following to the query:
"market_capitalization" : [{
"amount" : null,
"currency" : { id: "/en/us" },
"valid_date" : null,
"sort" : "-invalid_date",
"limit" : 1
}]
Then we also sort the companies by their market cap in descending order, and pick only the top 3
"sort": "-market_capitalization.amount",
"limit": 3
Finally, we want to query for the companies' stock ticker symbol as well as the first associated image
"ticker_symbol": [{
"ticker_symbol": null,
"stock_exchange": {
"name": null
}
}],
"/common/topic/image": [{
"id": null,
"limit": 1,
"optional": true
}]
Here is how the full query should look like:
[{
"type": "/business/company",
"name": null,
"id": null,
"ticker_symbol": [{
"ticker_symbol": null,
"stock_exchange": {
"name": null
}
}],
"/common/topic/image": [{
"id": null,
"limit": 1,
"optional": true
}],
"industry": {
"id": "/en/pharmaceutical_company"
},
"market_capitalization": [{
"amount": null,
"valid_date": null,
"currency": {
"id": "/en/us"
},
"sort": "-valid_date",
"limit": 1
}],
"sort": "-market_capitalization.amount",
"limit": 3
}]
Rendering the Query
Having written the query for the top 3 pharmaceutical companies, and verified that the results were what we wanted we now want to display these query results in a web page. This is quite easy, because the embedded query editor provides a Create Template feature that will create a new server-side template file for us that includes all the code necessary to retrieve the query file, dispatch the query to Freebase, and then generate HTML from the results. It even includes default styles to make the web page look reasonably nice.
All we have to do then is to click View to see this automatically-generated web page directly from the MQL query.
Getting Stock Info
So far we have only used data from Freebase. The next step is to include data from an external source, such as stock quotes from Google Finance. We'll want do this for every company, so first we need a for loop over the results like so:
for (var i = 0; i < o.result.length; i++) {
getStockQuote(o.result[i]);
}
and then a function that actually retrieves the stock quote:
function getStockQuote(company) {
var ticker = company.ticker_symbol[0];
var exchange = ticker.stock_exchange.name;
var symbol = ticker.ticker_symbol;
}
This is done by constructing a url to the google finance api service, and then performing an HTTP GET.
var url = "http://www.google.com/finance/info?q=" + exchange + ":" + symbol;
To find the acre api for fetching a url, we can invoke the code assist feature by pressing alt-space (on the Mac) or ctrl-space elsewhere. When we type in "fetch" the first suggestion looks like what we want so we hit enter. Now we get hints about the parameters of this function, and can fill them in, resulting in:
var body = acre.urlfetch(url).body;
Since we don't know exactly what Google Finance will return to us, let's just log the result for now and inspect it with this:
console.log(body).
Instead of just viewing the page this time, let's view it with the console by pressing the View with Console button. In the console, we get to see the result of the urlfetch as an interactive tree. The body of the HTTP response is a JSON string representing an array of 1 object, but it has two slashes in front that we need to remove. So let's go back to the app editor, remove the slashes, parse the JSON, and get the first element in the array.
var stock = JSON.parse(acre.urlfetch(url).body.substr(2))[0];
company.stock = stock;
console.log(stock);
Now that we know what Google Finance returns for each company, we can include those values in our template and render them.
Getting News
Finally, we need to retrieve news articles for each company. This is done by fetching a URL composed with the name of the company, parsing the returned RSS feed as an XML document, picking out XML elements named "item", and then retrieving their attributes. This can be achieved by this function (note the use of the acre.xml.parse API call):
function getNews(textQuery) {
var items = [];
try {
var url = "http://news.google.com/news?output=rss&q=" + encodeURIComponent(textQuery);
var newsResult = acre.xml.parse(acre.urlfetch(url).body);
var itemNodes = newsResult.getElementsByTagName("item");
var getAttr = function(node, name) {
return node.getElementsByTagName(name)[0].firstChild.nodeValue;
};
for (var i = 0; i < itemNodes.length; i++) {
var itemNode = itemNodes[i];
var item = {
title: getAttr(itemNode, "title"),
link: getAttr(itemNode, "link"),
pubDate: getAttr(itemNode, "pubDate"),
description: getAttr(itemNode, "description")
};
items.push(item);
}
} catch (e) {
console.log(e);
}
return items;
}
Supporting any Industry
So our app works for top 3 pharmaceutical companies but now let's generalize it... letting the user pick any industry that Freebase knows about. We will now return to the file "index", our app's homepage, and make it support industry selection.
First, we add a text input box where the user can enter the industry he or she wants. Next, we need to augment that input box with the Freebase Suggest service that knows how to resolve what a user types to a specific topic in Freebase. We do so by including jQuery and the Freebase Suggest jQuery plugin:
$(function() {
$("#the-textbox").suggest();
});
Now we need to configure the extension further, specifying that we only want industry topics
{ type: "/business/industry", strict: "any" }
And that we want to be notified when the user selects a suggested topic
.bind("fb-select", function(e, data) {
});
Whenever that event does happen, we'll extract the id of the matched industry, and navigate the browser to the "go" page, passing along the ID as a URL parameter
document.location.href = "go?industry=" + encodeURIComponent(data.id);
Then in the "go" page, we retrieve that parameter
var industry = acre.environ.params["industry"];
and use it to customize our query to Freebase
q[0].industry.id = industry;
Now let's view the "index" page and try the "automobile" industry. Here are the recent news articles about the top 3 car companies.
One neat thing about this app is that as companies rise and fall, the data in Freebase gets updated by contributors much as Wikipedia gets updated, and our app will automatically show the top companies at the current time.
It's not hard to imagine far more complex queries than just the top 3 companies of a given industry. For example, you might want news about companies in the pharmaceutical industry whose board members are also on the boards of the top 3 companies in the oil industry. Storing and querying intricate connections between topics is one of Freebase's greatest strengths, and combining that data with external data and services was one of the main reasons we developed Acre.
Conclusion
The Acre app resulting from this tutorial can be found here. Feel free to clone it and play with it yourself. We can't wait to see what you come up with.