Friday, September 16, 2011

[Gd] Dev Channel Update

| More

Google Chrome Releases: Dev Channel Update


The Dev channel has been updated to 15.0.874.15 for Windows, Mac, Linux, and Chrome Frame.
  • Updated V8 3.5.10.9
  • JavaScript fullscreen API now enabled by default.
  • Bug fixes and visual improvements for the New Tab Page.
  • Fixed many known stability issues.
  • Known Issue: Linux-only: Chrome crashes with Ctrl+P. [Issue: 96734]
Full details about what changes are in this build are available in the SVN revision log.  Interested in switching to the Beta or Stable channels?  Find out how.  If you find a new issue, please let us know by filing a bug.

Dharani Govindan
Google Chrome
URL: http://googlechromereleases.blogspot.com/2011/09/dev-channel-update_15.html

[Gd] Three new APIs for Google Apps Script

| More

The official Google Code blog: Three new APIs for Google Apps Script

Jacob
Gustavo
By Jacob Moshenko and Gustavo Moura, Software Engineers

In January of this year we launched BigQuery integration with Google Apps Script. What we didn’t mention was that we were building this on top of our Google APIs Discovery Service. Thanks to the ease and flexibility of writing clients based on this API, today we’re announcing integration with three more APIs, and revamping our BigQuery support.

As of now, we have also integrated the Tasks API, Prediction API, and URL Shortener API in addition to the BigQuery API. You can now include these APIs in your scripts, apps, and sites pages. As with other Apps Script services, we handle all of the server communications as well as authorization, which makes this a great way to build mashups and workflows using our APIs.

To get started, simply enable the APIs you’re interested in from the "Use Google API services" menu in the script editor.


Using this feature will prompt you to save your script. Once you have done so, the Google APIs Services dialog will appear and you can choose which APIs to use, which versions to use, and what name to use when referencing them from your scripts.


After you complete this step, the API methods will be automatically populated as you type using the standard Apps Script autocomplete mechanism. For detailed information about each API, visit our reference documentation. We have also created a tutorial with a simple, fun application to help you get started using scripts.

As we iron out this new technology and listen to your feedback we plan to aggressively integrate even more APIs. If you have any questions or experience any problems let us know on our support forum.

Jacob Moshenko is a Software Engineer working on the Google APIs developer experience. He believes that Google APIs should be easy to use, especially from Google platforms.

Gustavo Moura has been a Software Engineer at Google since 2007. He has been part of the Google Docs team since 2009. Prior to that, he worked on AdWords.

Posted by Scott Knaster, Editor

URL: http://googlecode.blogspot.com/2011/09/three-new-apis-for-google-apps-script.html

[Gd] Getting started on the Google+ API

| More

The official Google Code blog: Getting started on the Google+ API


By Chris Chabot, Google+ Developer Relations

Cross-posted with the Google+ Platform Blog

The Google+ project brings the nuance and richness of real-life sharing to software. The Google+ platform brings that nuance and richness to all of the web. We started with Google’s own products, added the +1 button for site owners and content publishers, and introduced games from a handful of partners. That’s just the beginning though — we want every one of you who builds applications to be able to include rich sharing, identity, and conversations in your app. Today, we’re taking the next step on that journey by launching the first of the Google+ APIs.

Let's Go Public

Google+ gives users full control over their information, supporting everything from intimate conversations with family to public showcases and debates. This initial API release is focused on public data only — it lets you read information that people have shared publicly on Google+. For example, if you want to get my profile information, you can use the people.get method by sending the following HTTP request:

GET https://www.googleapis.com/plus/v1/people/108189587050871927619?key=yourAPIKey

which returns the following JSON encoded output (excerpted for brevity):
{
"kind": "plus#person",
"id": "108189587050871927619",
"displayName": "Chris Chabot",
"image": {
"url": "https://lh5.googleusercontent.com/-cQNLOQzkGpE/AAAAAAAAAAI/AAAAAAAAEjo/M9_pXL-ra4Q/photo.jpg"
},
"organizations": [
{
"name": "Google+ Developer Relations",
"title": "Developer Advocate & Manager",
"type": "work"
}
]
}
Similarly, you can get a list of my most recent public posts by using the activities.list method:

GET https://www.googleapis.com/plus/v1/people/108189587050871927619/activities/public?key=yourAPIKey

Because we’re starting with public data only, you simply need to register your app before making requests. And if you aren't yet sure which Google+ user is running your app (for example, because they're installing it for the first time), then you can use the new plus.me OAuth2 scope to ask the user who they are.

After your application has requested this scope, you can use the special “me” identifier rather than the long numeric identifier:

GET https://www.googleapis.com/plus/v1/people/me

On The Shoulders of Giants

We love the way the programmable web has evolved, so we’re using existing standards and best practices wherever we can:
  • Our API methods are RESTful HTTP requests which return JSON responses.
  • Our payload formats use standard syntax (e.g. PoCo for people info, ActivityStrea.ms for activities).
  • We use OAuth 2 for secure trusted access to user data.
In addition, since most of us no longer write raw HTTP requests these days, we provide libraries for your favorite language: Java, GWT, Python, Ruby, PHP, Objective-C, and .NET. These libraries are all open source, so we’d love to have your feedback and help with them.

developers.google.com

You can find more information about the Google+ platform, including today’s new APIs to public data, at developers.google.com/+ on our new Google Developers site. This site will be the place to go for access to documentation, terms and policies, discussions with other developers, tools that make development on the +Platform easier and more fun and, of course, the place where announcements concerning new releases will be made.

Included in our policies are three simple guidelines that we aspire to in our own products, and that we’d like all applications built on the Google+ platform to follow also: put the user first, be transparent, and respect user data. The goal behind these guidelines, as with all of the features and fine print, is to work together to build products that our users will love.

And now …

For all of you developers who have been asking for a Google+ API, this is the start. Experiment with it. Build apps on it. Give us your feedback and ideas. This is just the beginning; the Google+ platform will grow and we value your input as we move Google+ forward.

Follow the conversation on Google+.

Chris Chabot is a Developer Advocate on the Google+ Team.

Posted by Scott Knaster, Editor
URL: http://googlecode.blogspot.com/2011/09/getting-started-on-google-api.html

[Gd] Pagination with rel=“next” and rel=“prev”

| More

Official Google Webmaster Central Blog: Pagination with rel=“next” and rel=“prev”

Webmaster level: Intermediate to Advanced

Much like rel=”canonical” acts a strong hint for duplicate content, you can now use the HTML link elements rel=”next” and rel=”prev” to indicate the relationship between component URLs in a paginated series. Throughout the web, a paginated series of content may take many shapes—it can be an article divided into several component pages, or a product category with items spread across several pages, or a forum thread divided into a sequence of URLs. Now, if you choose to include rel=”next” and rel=”prev” markup on the component pages within a series, you’re giving Google a strong hint that you’d like us to:
  • Consolidate indexing properties, such as links, from the component pages/URLs to the series as a whole (i.e., links should not remain dispersed between page-1.html, page-2.html, etc., but be grouped with the sequence).
  • Send users to the most relevant page/URL—typically the first page of the series.


The relationship between component URLs in a series can now be indicated to Google through rel=”next” and rel=”prev”.

There’s an exception to the rel=”prev” and rel=”next” implementation: If, alongside your series of content, you also offer users a view-all page, or if you’re considering a view-all page, please see our post on View-all in search results for more information. Because view-all pages are most commonly preferred by searchers, we do our best to surface this version when appropriate in results rather than a component page (component pages are more likely to surface with rel=”next” and rel=”prev”).

If you don’t have a view-all page or you’d like to override Google returning a view-all page, you can use rel="next" and rel="prev" as described in this post.

For information on paginated configurations that include a view-all page, please see our post on View-all in search results.

Outlining your options

Here are three options for a series:
  1. Leave whatever you have exactly as-is. Paginated content exists throughout the web and we’ll continue to strive to give searchers the best result, regardless of the page’s rel=”next”/rel=”prev” HTML markup—or lack thereof.
  2. If you have a view-all page, or are considering a view-all page, see our post on View-all in search results.
  3. Hint to Google the relationship between the component URLs of your series with rel=”next” and rel=”prev”. This helps us more accurately index your content and serve to users the most relevant page (commonly the first page). Implementation details below.

Implementing rel=”next” and rel=”prev”

If you prefer option 3 (above) for your site, let’s get started! Let’s say you have content paginated into the URLs:

http://www.example.com/article?story=abc&page=1
http://www.example.com/article?story=abc&page=2
http://www.example.com/article?story=abc&page=3
http://www.example.com/article?story=abc&page=4

On the first page, http://www.example.com/article?story=abc&page=1, you’d include in the <head> section:
<link rel="next" href="http://www.example.com/article?story=abc&page=2/>

On the second page, http://www.example.com/article?story=abc&page=2:
<link rel="prev" href="http://www.example.com/article?story=abc&page=1" />
<link rel="next" href="http://www.example.com/article?story=abc&page=3" />

On the third page, http://www.example.com/article?story=abc&page=3:
<link rel="prev" href="http://www.example.com/article?story=abc&page=2" />
<link rel="next" href="http://www.example.com/article?story=abc&page=4" />

And on the last page, http://www.example.com/article?story=abc&page=4:
<link rel="prev" href="http://www.example.com/article?story=abc&page=3" />

A few points to mention:
  • The first page only contains rel=”next” and no rel=”prev” markup.
  • Pages two to the second-to-last page should be doubly-linked with both rel=”next” and rel=”prev” markup.
  • The last page only contains markup for rel=”prev”, not rel=”next”.
  • rel=”next” and rel=”prev” values can be either relative or absolute URLs (as allowed by the <link> tag). And, if you include a <base> link in your document, relative paths will resolve according to the base URL.
  • rel=”next” and rel=”prev” only need to be declared within the <head> section, not within the document <body>.
  • We allow rel=”previous” as a syntactic variant of rel=”prev” links.
  • rel="next" and rel="previous" on the one hand and rel="canonical" on the other constitute independent concepts. Both declarations can be included in the same page. For example, http://www.example.com/article?story=abc&page=2&sessionid=123 may contain:

    <link rel="canonical" href="http://www.example.com/article?story=abc&page=2”/>
    <link rel="prev" href="http://www.example.com/article?story=abc&page=1&sessionid=123" />
    <link rel="next" href="http://www.example.com/article?story=abc&page=3&sessionid=123" />

  • rel=”prev” and rel=”next” act as hints to Google, not absolute directives.
  • When implemented incorrectly, such as omitting an expected rel="prev" or rel="next" designation in the series, we'll continue to index the page(s), and rely on our own heuristics to understand your content.

Questions?
More information can be found in our Help Center, or join the conversation in our Webmaster Help Forum!

Written by Benjia Li & Joachim Kupke, Software Engineers, Indexing Team
URL: http://googlewebmastercentral.blogspot.com/2011/09/pagination-with-relnext-and-relprev.html

[Gd] View-all in search results

| More

Official Google Webmaster Central Blog: View-all in search results

Webmaster level: Intermediate to Advanced

User testing has taught us that searchers much prefer the view-all, single-page version of content over a component page containing only a portion of the same information with arbitrary page breaks (which cause the user to click “next” and load another URL).


Searchers often prefer the view-all vs. paginated content with arbitrary page breaks and worse latency.

Therefore, to improve the user experience, when we detect that a content series (e.g. page-1.html, page-2.html, etc.) also contains a single-page version (e.g. page-all.html), we’re now making a larger effort to return the single-page version in search results. If your site has a view-all option, there’s nothing you need to do; we’ll work to do it on your behalf. Also, indexing properties, like links, will be consolidated from the component pages in the series to the view-all page.

However, high latency can make the view-all less preferred

Interestingly, the cases when users didn’t prefer the view-all page were correlated with high latency (e.g., when the view-all page took a while to load, say, because it contained many images). This makes sense because we know users are less satisfied with slow results. So while a view-all page is commonly desired, as a webmaster it’s important to balance this preference with the page’s load time and overall user experience.

Best practices for a series of content
  1. If your site includes view-all pages

    We aim to detect the view-all version of your content and, if available, its associated component pages. There’s nothing more you need to do! However, if you’d like to make it more explicit to us, you can include rel=”canonical” from your component pages to your view-all to increase the likelihood that we detect your series of pages appropriately.


    rel=”canonical” can specify the superset of content (i.e. the view-all page) from the same information in a series of URLs.

    Why does this work?

    In the diagram, page-2.html of a series may specify the canonical target as page-all.html because page-all.html is a superset of page-2.html's content. When a user searches for a query term and page-all.html is selected in search results, even if the query most related to page-2.html, we know the user will still see page-2.html’s relevant information within page-all.html.


    On the other hand, page-2.html shouldn’t designate page-1.html as the canonical because page-2.html’s content isn’t included on page-1.html. It’s possible that a user’s search query is relevant to content on page-2.html, but if page-2.html’s canonical is set to page-1.html, the user could then select page-1.html in search results and find herself in a position where she has to further navigate to a different page to arrive at the desired information. That’s a poor experience for the user, a suboptimal result from us, and it could also bring poorly targeted traffic to your site.


    However, if you strongly desire your view-all page not to appear in search results: 1) make sure the component pages in the series don’t include rel=”canonical” to the view-all page, and 2) mark the view-all page as “noindex” using any of the standard methods.
  2. If you’d like to surface individual, component pages (or there’s no view-all available)

    It may be the case that one or both of the situations below apply to your site:

    • The view-all page is undesirable as a search result (e.g., load time too high or too difficult for users to navigate).
    • Your users prefer the multi-page experience and to be directed to a component page in search results, rather than the view-all page.

    If so, you can use standard HTML rel=”next” and rel=”prev” elements to specify a relationship between the component pages in your series of content. If done correctly, Google will generally strive to:

    • Consolidate indexing properties, such as links, between the component pages/URLs.
    • Send users to the most relevant page/URL from the component pages. Typically, the most relevant page is the first page of your content, but our algorithms may point users to one of the component pages in the series.

It’s not uncommon for webmasters to incorrectly use rel=”canonical” from component pages to the first page of their series (e.g. page-2.html with rel=”canonical” to page-1.html). We recommend against this implementation because the component pages don’t actually contain duplicate content. Using rel=”next” and rel=”prev” is far more appropriate.

Summary

Because users generally prefer the view-all option in search results, we’re making more of an effort to properly detect and serve this version to searchers. If you have a series of content, there’s nothing more you need to do. If you’d like to hint more to Google how best to serve users your information:
  1. To better optimize your view-all page, you can use rel=”canonical” from component pages to the single-page version; otherwise,
  2. If a view-all page doesn’t provide a good user experience for your site, you can use the rel=”next” and rel=”prev” attributes as a strong hint for Google to identify the series of pages and still surface a component page in results.

Questions?

As always, feel free to ask in our Webmaster Help Forum.

Written by Benjia Li & Joachim Kupke, Software Engineers, Indexing Team
URL: http://googlewebmastercentral.blogspot.com/2011/09/view-all-in-search-results.html

[Gd] Reconsideration requests get more transparent

| More

Official Google Webmaster Central Blog: Reconsideration requests get more transparent

Webmaster level: All

If your site isn't appearing in Google search results, or it's performing more poorly than it once did (and you believe that it does not violate our Webmaster Guidelines), you can ask Google to reconsider your site. Over time, we’ve worked to improve the reconsideration process for webmasters. A couple of years ago, in addition to confirming that we had received the request, we started sending a second message to webmasters confirming that we had processed their request. This was a huge step for webmasters who were anxiously awaiting results. Since then, we’ve received feedback that webmasters wanted to know the outcome of their requests. Earlier this year, we started experimenting with sending more detailed reconsideration request responses and the feedback we’ve gotten has been very positive!

Now, if your site is affected by a manual spam action, we may let you know if we were able to revoke that manual action based on your reconsideration request. Or, we could tell you if your site is still in violation of our guidelines. This might be a discouraging thing to hear, but once you know that there is still a problem, it will help you diagnose the issue.

If your site is not actually affected by any manual action (this is the most common scenario), we may let you know that as well. Perhaps your site isn’t being ranked highly by our algorithms, in which case our systems will respond to improvements on the site as changes are made, without your needing to submit a reconsideration request. Or maybe your site has access issues that are preventing Googlebot from crawling and indexing it. For more help debugging ranking issues, read our article about why a site may not be showing up in Google search results.

We’ve made a lot of progress on making the entire reconsideration request process more transparent. We aren’t able to reply to individual requests with specific feedback, but now many webmasters will be able to find out if their site has been affected by a manual action and they’ll know the outcome of the reconsideration review. In an ideal world, Google could be completely transparent about how every part of our rankings work. However, we have to maintain a delicate balance: trying to give as much information to webmasters as we can without letting spammers probe how to do more harm to users. We're happy that Google has set the standard on tools, transparency, and communication with site owners, but we'll keep looking for ways to do even better.

Posted by Tiffany Oberoi and Michael Wyszomierski, Search Quality Team
URL: http://googlewebmastercentral.blogspot.com/2011/09/reconsideration-requests-get-more.html

[Gd] Registration opens for Google Developer Day Tel Aviv

| More

The official Google Code blog: Registration opens for Google Developer Day Tel Aviv


By Amir Shevat, Developer Relations

Registration for Google Developer Day in Tel Aviv is now open! To sign up, visit the GDD Tel Aviv webpage , click Register Now, and fill out the form. We hope to see you at GDD 2011 in Israel.

Amir Shevat is a Developer Relations Program Manager for Google. He is an Open Source developer at heart and fully licensed geek.

Posted by Scott Knaster, Editor
URL: http://googlecode.blogspot.com/2011/09/registration-opens-for-google-developer.html

[Gd] Beta Channel Update for Chromebooks

| More

Google Chrome Releases: Beta Channel Update for Chromebooks

The Beta channel has been updated to 14.0.835.163 (Platform version: 811.105) for Chromebooks (Acer AC700, Samsung Series 5, and Cr-48).


Highlights:
  • Stability patches.
If you find new issues, please let us know by visiting our help site or filing a bug. You can also submit feedback using "Report an issue" under the wrench icon. Interested in switching to the Beta channel? Find out how.

Orit Mazor
Google Chrome
URL: http://googlechromereleases.blogspot.com/2011/09/beta-channel-update-for-chromebooks_14.html

[Gd] Beta Channel Update

| More

Google Chrome Releases: Beta Channel Update


The Beta channel has been updated to 14.0.835.163 for Windows, Mac, Linux, and Chrome Frame.

This release re-enables the enhanced completion functionality and takes some additional stability patches.



To see what other changes went into this release check out our change log.

If you find a new issue, please let us know by filing a bug.

Anthony Laforge
Google Chrome
URL: http://googlechromereleases.blogspot.com/2011/09/beta-channel-update_14.html

[Gd] Dev Channel Updates for Chromebooks

| More

Google Chrome Releases: Dev Channel Updates for Chromebooks

The Dev channel has been updated to 15.0.874.12 (Platform version: 1011.11) for Chromebooks (Acer AC700, Samsung Series 5, and Cr-48).


Highlights:
  • New Web UI login
  • Fix several functionality and stability issues
Known issues:
  • gmail : rendering issue seen on scrolling down long email thread (19931).
If you find new issues, please let us know by visiting our help site or filing a bug. You can also submit feedback using "Report an issue" under the wrench icon. Interested in switching to the Beta channel? Find out how.

Josafat Garcia
Google Chrome
URL: http://googlechromereleases.blogspot.com/2011/09/dev-channel-updates-for-chromebooks_13.html

[Gd] Dev Channel Update

| More

Google Chrome Releases: Dev Channel Update


The Dev channel has been updated to 15.0.874.12 for Windows, Mac, Linux, and Chrome Frame.
  • Updated V8 3.5.10.7
  • Print preview issues with self-closing popups have been fixed.
  • Fixed many known stability issues.
Full details about what changes are in this build are available in the SVN revision log.  Interested in switching to the Beta or Stable channels?  Find out how.  If you find a new issue, please let us know by filing a bug.

Dharani Govindan
Google Chrome
URL: http://googlechromereleases.blogspot.com/2011/09/dev-channel-update_13.html

[Gd] Introducing: Application Rich Snippets

| More

Official Google Webmaster Central Blog: Introducing: Application Rich Snippets

Webmaster level: All

Rich snippets help users determine more quickly if a particular web page has the information they're interested in. We've previously introduced rich snippets for shopping, recipes, reviews, video, and events, and most recently music.

Before you install a software application, users might want to check out what others think about it, and how much it costs. We are pleased to announce that starting today, you’ll be able to get this information right in search results.

Here's an example of what an application snippet looks like.

Image of application snippet

You can see application snippets from several marketplaces and review sites, including Android Market, Apple iTunes, and CNET. For information on how to add app markup on your site, please refer to our Webmaster central article and send any questions to our discussion help forum.

Posted by , Product Manager

URL: http://googlewebmastercentral.blogspot.com/2011/09/introducing-application-rich-snippets.html

[Gd] [Libraries][Update] jQuery 1.6.4 and MooTools 1.4.0

| More

Google AJAX API Alerts: [Libraries][Update] jQuery 1.6.4 and MooTools 1.4.0

jQuery has been updated to 1.6.4 and MooTools has been updated to 1.4.0
URL: http://ajax-api-alerts.blogspot.com/2011/09/librariesupdate-jquery-164-and-mootools.html

[Gd] Improved Analytics & New Staff Picks Section on the Apps Marketplace

| More

Google Apps Developer Blog: Improved Analytics & New Staff Picks Section on the Apps Marketplace

Like any Google service, we’re always working to refine the Google Apps Marketplace for our vendors and their customers. Normally we make small, incremental improvements and let the better experience speak for itself, but this week we think several of the new features are noteworthy enough to point out.

View Enhanced Analytics

A frequently requested feature has been improved analytics. If you have Google Analytics configured for your listing, your analytics profile will now receive the search terms and category selected by your customers.

When a customer searches on the Marketplace, the search results will all have two parameters attached: query and category. You’ll want to add these terms to your Google Analytics Website Profile. The query term will include all of the search terms the user entered into the search box, or it could be blank if the customer found your application through browsing. Similarly, the category parameter will be blank unless the customer narrowed his search or browse by picking the category you chose in your application listing, e.g. Accounting & Finance. Now you’ll have much better data about how a customer has reached your application, whether through browsing, searching, or a combination.

Count Installs

Another developer-focused enhancement we’ve made is adding a count of installs and uninstalls on each application’s listing when signed into the vendor account:

"Net install count" represents the number of current installs -- any uninstalls have already been deducted. If you add "Net install count" to "Uninstall count" you will have the total number of installations for the app since it launched. You are also able to retrieve this information from the Licensing API, but it is nice to have it easily accessible on your listing pages.

Sweep Away Those Dusty Apps

On the Vendor Profile page you’ll also that we’ve added the ability to hide unused applications (and show them again) so that you can manage your applications better and remove clutter on your dashboard. You still cannot delete applications, but you can sweep them under the rug! Note that Hiding and Unhiding are just for managing your list as a Vendor -- they do not change your Publish/Unpublish settings for each app. You can hide a published app as easily as an unpublished app.

Browse Staff Picks on the Home Page

Since announcing the Staff Picks program in May, we’ve featured a number of especially well-integrated and innovative applications on the @GoogleAtWork twitter stream and here on the Google Apps Developer Blog. Now we also feature Staff Picks on the front page of the Marketplace.

You can find four Staff Picks on the Marketplace landing page, chosen from the pool of apps selected as staff picks. See the Staff Picks page on code.google.com for more information on how we choose these apps.

Andy "Rufus" Rothfusz    blog

Rufus is a Developer Programs Engineer working on Google Apps APIs and the Google Apps Marketplace. He has over 14 years of experience in developer programs covering a wide range of applications including 3D graphics acceleration, natural language processing, device security, video games and video streaming.

URL: http://googleappsdeveloper.blogspot.com/2011/09/improved-analytics-new-staff-picks.html

[Gd] Create a custom CRM dashboard using Google Apps Script

| More

Google Apps Developer Blog: Create a custom CRM dashboard using Google Apps Script

Editors note: This is a guest post by Alex Steshenko. Alex is a core software engineer for Solve360, a highly-rated CRM in the Google Apps Marketplace which was recently chosen as a Staff Pick. Solve360 offers many points of useful integration with Google Apps. Today, in contrast to the conventional Data API integrations, Alex will showcase how he extended Solve360 using Google Apps Script. --- Ryan Boyd

Choosing Google Apps Script

Solve360 CRM integrates with Google services to provide a two-way contact & calendar sync, email sync and a comprehensive Gmail contextual gadget. We use the standard Google Data APIs. However, some of our use cases required us to use Google documents and spreadsheets. Enter Apps Script!. What brought our attention to Google Apps Script was that it allows you to run your application code right within the Google Apps platform itself, where documents can be manipulated using a wide range of native Google Apps Script functions, changing the perspective.

Our first experience with Google Apps Script was writing a "Contact Us" form. We decided to use the power and flexibility of Apps Script again to generate different kinds of reports.

Generating Solve360 Reports using Apps Script

Google Spreadsheets can produce rich reports leveraging features such as filters, pivot tables, built-in functions and charts. But where’s the data to report on? Using Google Apps Script, users can integrate Google Spreadsheets with a valuable source of data - the Solve360 CRM - completing the solution.

Solve360 Google Apps Reporting script lets users configure the reporting criteria while pulling reports into a Google Spreadsheet.

Here's a video demonstrating a real use case for Solve360 Reporting:

Designing Solve360 Reporting using Apps Script

User meet “Script”

For this script, we realized, simply providing spreadsheet functions would not be good enough. We needed a user interface to let users configure their account details and define what kind of data to fetch from the Solve360 CRM. Google Apps Script’s Ui Services came in handy. For instance, here is the function responsible for showing the “Solve360 account info” dialog:

/*
* Creates new UI application and opens setting window
*/
function settingsUi() {
var app = UiApp.createApplication();
app.setTitle('Solve360 account info')
.setWidth(260)
.setHeight(205);

var absolutePanel = app.createAbsolutePanel();

absolutePanel.add(authenticationPanel_(app));

app.add(absolutePanel);
SpreadsheetApp.getActiveSpreadsheet().show(app);
}

Working with Solve360’s API

Solve360 CRM has an external API available so the system can be integrated with custom business applications and processes. Reporting script use case is a good example of what it can be used for.

One of the first tricks learned was creating our own Google Apps-like “service” to encapsulate all those functions responsible for interacting with Solve360 CRM’s API. What is the most interesting is that this service’s code isn’t a part of the distributed Google Apps script. Instead the library is loaded from within the script itself directly from our servers. Why? Let’s say we found a bug or added new functions - if we had many copies of the service we would need to update them all, somehow notifying our clients, and so on. With one source, there’s no such problem. You may think of it as a way to distribute a Google Apps Script solution, or, in our case, a part of the solution. The service is called Solve360Service and its usage looks like this:

var contact = Solve360Service.addContact(contactData);

There were two problems with getting such an external service to work: Google Apps Script permissions restrictions and actually including it in the script.

The issue with permissions is that the Google Apps Script environment can’t see which Google Apps Script services are used inside the external service - that’s why it doesn’t ask you to grant special permissions for them. To force the authorization request for those permissions we added this to the onInstall function (called once when script is added to the spreadsheet):

function onInstall() {
// to get parseJS permissions
Xml.parseJS(['solve360', '1']);

// to get base64Encode permissions
Utilities.base64Encode('solve360');
// ...
}

Here is the solution we used to load our centralized code into the script:

eval(UrlFetchApp.fetch("https://secure.solve360.com/gadgets/resources/js/Solve360Service.js").getContentText());

The Solve360Service is loaded from a single source - no copy-paste. All the functions for accessing the Solve360 API aka “the plumbing” are abstracted and hidden in inside this service, while the essentials of the reports script itself can be modified and tweaked to a particular client’s case. Inside of Solve360Service we use UrlFetchApp:

/**
* Request to the Solve360 API server
* data should be an Array in Short Hand notation
*/
request : function(uri, restVerb, data) {
if (this._credentials == null) {
throw new Error('Solve360 credentials are not set');
}

if (typeof(data) != 'undefined') {
if (restVerb.toLowerCase() == 'get') {
var parameters = [];
for each(var parameter in data) {
parameters.push(encodeURIComponent(parameter[0]) + '=' + encodeURIComponent(parameter[1]));
}
uri += '?' + parameters.join('&');
data = '';
} else {
data.unshift('request');
data = Xml.parseJS(data).toXmlString();
}
} else {
data = '';
}

var options = {
"contentType" : "application/xml",
"method" : restVerb.toLowerCase(),
"payload" : data,
"headers" : {"Authorization" : "Basic " + this._credentials}
};
return Xml.parse(UrlFetchApp.fetch(this._url + uri, options).getContentText()).getElement();
}

As the result is always XML, in order to remove any extra work we call Xml.parse() right inside the request function and always return a XmlElement so you can iterate through it, access nodes and attributes. Here is a simplified version of how we load some items when building a report:

/*
* Builds a search config from user preferences and loads a slice of data from Solve360
* To configure how many items should be loaded at a time, change ITEMS_LOAD_REQUEST_LIMIT constant
*/
function retrieveItems_(parameter, offset) {
initSolve360Service_();
// ...
var searchParameters = [
['layout', '1'],
['sortdir', 'ASC'],
['sortfield', 'name'],
['start', '' + offset],
['limit', '' + ITEMS_LOAD_REQUEST_LIMIT],
['filtermode', filtermode],
['filtervalue', filtervalue],
['searchmode', searchmode],
['searchvalue', searchvalue],
['special', special],
['categories', '1']
];
if (parameter.showAllFieldsCheckbox != 'true' && fields.length > 0) {
searchParameters.push(['fieldslist', fields.join(',')]);
}
// ...
var items = Solve360Service.searchProjectBlogs(searchParameters);
// ...
return items;
}

To simplify the usage of the service we added another function which initializes the service object, named Solve360Service:

/*
* Loads external Solve360Service
* For the service functions available refer to the source code here:
* https://secure.solve360.com/gadgets/resources/js/Solve360Service.js
*/
var Solve360Service = null;
function initSolve360Service_() {
if (Solve360Service == null) {
eval(UrlFetchApp.fetch("https://secure.solve360.com/gadgets/resources/js/Solve360Service.js").getContentText());
var user = UserProperties.getProperty(USERPROPERTY_USER);
var token = UserProperties.getProperty(USERPROPERTY_TOKEN);
if (user == null || user.length == 0 || token == null || token.length == 0) {
throw new Error('Use Solve360 spreadsheet menu to set email and token first');
}
Solve360Service.setCredentials(user, token);
}
}

As you can see, it uses the email/token pair previously saved in the “Solve360 Account Info” dialog or signals an error if the credentials were not yet saved.

Conclusion

There are many use cases where you can apply the Google Apps Script. The fact that you can work and implement solutions right from “inside” one of the greatest and most universal web applications available is amazing.

You can integrate your own software with Google Docs or even learn from us and build a reporting script for any other system accessible online. Try to look at solving business tasks from a different perspective, from the Google Apps point of view. We encourage it!

The code of the new script is available for use and study here:
https://secure.solve360.com/docs/google-apps-reports.js.

Alex Steshenko profile | twitter | blog

Alex Steshenko is a core software engineer for Solve360, a CRM application on the Google Apps Marketplace.

URL: http://googleappsdeveloper.blogspot.com/2011/09/create-custom-crm-dashboard-using.html

[Gd] Thinking Like a Web Designer

| More

Android Developers Blog: Thinking Like a Web Designer

[This post is by Roman Nurik, who is passionate about icons, with input from me and a bunch of the Framework engineers. —Tim Bray]

The number of people working on mobile apps, and specifically Android, is growing fast. Since modern mobile software-development is a relatively new profession, the community is growing by sucking in experts from related domains, one being web design and development.

It turns out that familiarity with web UI development, particularly using modern HTML5 techniques, can be a great primer for Android UI development. The Android framework and SDK have many analogues to tools and techniques in the Web repertoire of HTML, CSS, and JavaScript.

In this blog post, we’ll walk through a few web development features and look for matches in the world of Android UI development.

Device resolutions and physical sizes

One of the most important aspects of both Android UI design and web design is support for multiple screen resolutions and physical sizes. Just as your web app needs to work on any physical display and inside any size browser window, your native app needs to run on a variety of form factors, ranging from 2.5” phones to 10” tablets to (possibly) 50” TVs.

Let’s look at some ways in which CSS and Android allow for flexible and adaptive layouts.

Providing custom layouts for different resolutions

CSS3 media queries allow developers to include additional stylesheets to target different viewport and screen configurations. For example, developers can provide additional style rules or override existing styles for mobile devices. Although the markup (layout hierarchy) remains the same, CSS3 has several sophisticated techniques for completely transforming the placement of elements with different stylesheets.

Android has long offered a similar mechanism in resource directory qualifiers. This extends to many different types of resources (layouts, images or ‘drawables’, styles, dimensions, etc). Thus you can customize the view hierarchy as well as styling depending on device form factor, A base set of layouts for handsets can be extended for tablets by placing additional layouts in res/layout-xlarge or res/layout-sw600dp (smallest width 600 density-independent pixels) directories. Note that the latter syntax requires Android 3.2 or later.

Below is a CSS3 example of how one could hide a ‘left pane’ on smaller devices and show it on screens at least 600 pixels wide:

#leftPane {
display: none;
}

@media screen and (min-device-width:600px) {
#leftPane {
display: block;
}
}

The same could be accomplished on Android using multiple layout directories:

res/layout/foo.xml:

<FrameLayout>
<!-- a single pane -->
<View android:id="main_pane">
</FrameLayout>

res/layout-sw600dp/foo.xml:

<LinearLayout android:orientation="horizontal">
<!-- two panes -->
<View android:id="left_pane">
<View android:id="main_pane">
</LinearLayout>

As a side note, if you plan on creating multi-pane layouts, consider using fragments, which help break up your screens into modular chunks of both layout and code.

There are also other neat ways of using resource directory qualifiers. For example, you could create values/dimens.xml and values-sw600dp/dimens.xml files specifying different font sizes for body text, and reference those values in your layouts by setting android:textSize="@dimen/my_body_text_size". The same could be done for margins, line spacing, or other dimensions to help manage whitespace on larger devices.

‘Holy grail’ layouts

Web developers have long dreamt of an easy way to build a ‘holy grail’ 5-pane layout (header/footer + 3 vertical columns). There are a variety of pre-CSS3 tricks including position:fixed, float:left, negative margins, and so on, to build such layouts but CSS3 introduced the flexible box module, which simplifies this tremendously.

Figure: An archetypal “holy grail” layout

It turns out that grail is pretty holy for Android tablet apps, too, and in particular for tablets held sideways in landscape mode. A good approach involves the use of LinearLayout, one of the simplest and most popular of the Android layouts.

LinearLayout has this neat way to stretch its children to fit the remaining space, or to distribute available space to certain children, using the android:layout_weight attribute. If a LinearLayout has two children with a fixed size, and another child with a nonzero layout_weight, that other child view will stretch to fill the remaining available space. For more on layout_weight and other ways to make layouts more efficient (like switching from nested LinearLayouts to RelativeLayout), check out Layout Tricks: Creating Efficient Layouts.

Let’s take a look at some example code for implementing such a ‘holy grail’ layout on Android and on the web:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<!-- top pane -->
<View android:id="@+id/top_pane"
android:layout_width="match_parent"
android:layout_height="50dp" />

<LinearLayout android:id="@+id/middle_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">

<!-- left pane -->
<View id="@+id/left_pane"
android:layout_width="300dp"
android:layout_height="match_parent" />

<!-- center pane -->
<View id="@+id/center_pane"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />

<!-- right pane -->
<View id="@+id/right_pane"
android:layout_width="300dp"
android:layout_height="match_parent" />

</LinearLayout>

<!-- bottom pane -->
<View android:id="@+id/bottom_pane"
android:layout_width="match_parent"
android:layout_height="50dp" />

</LinearLayout>

Note: Android tablet apps in landscape will generally show an action bar as the top pane and will usually have neither a right nor bottom pane. Also note that the action bar layout is automatically provided by the framework as of Android 3.0, and thus you don’t need to worry about positioning it.

And here’s an example implementation using the CSS3 flexible box model; notice the similarities:

<style>
html, body { margin: 0; height: 100%; }

#container {
height: 100%;
display: -webkit-box; /* like LinearLayout */
display: -moz-box;
-webkit-box-orient: vertical; /* like android:orientation */
-moz-box-orient: vertical;
}

#top, #bottom { height: 50px; }

#middle {
-webkit-box-flex: 1; /* like android:layout_weight */
-moz-box-flex: 1;
display: -webkit-box;
-webkit-box-orient: horizontal;
-moz-box-orient: horizontal;
}

#left, #right { width: 300px; }

#center {
-webkit-box-flex: 1;
-moz-box-flex: 1;
}
</style>

<div id="container">
<div id="top"></div>
<div id="middle">
<div id="left"></div>
<div id="center"></div>
<div id="right"></div>
</div>
<div id="bottom"></div>
</div>

Layered content

In CSS, with position:absolute, you can overlay your UI elements. On Android, you can use FrameLayout to achieve this. The child views in a frame layout are laid out on top of each other, with optional layout_gravity attributes indicating alignment with the parent frame layout.

Below is a contrived example of a FrameLayout with three children.

Figure: Example FrameLayout with three children (2 with top-left and 1 bottom-right alignment)

Figure: Isometric view of the example FrameLayout and its children.

The code for this example is as follows:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="300dp"
android:layout_height="200dp">

<!-- bottom-most child, with bottom-right alignment -->
<View android:layout_gravity="bottom|right"
android:layout_width="100dp"
android:layout_height="150dp" />

<!-- middle child, with top-left alignment -->
<View android:layout_gravity="top|left"
android:layout_width="200dp"
android:layout_height="175dp" />

<!-- top-most child, with top-left alignment →
<!-- also stretched to fill vertically -->
<View android:layout_gravity="top|left"
android:layout_width="100dp"
android:layout_height="match_parent" />

</FrameLayout>

Scrollable content

HTML, by default, flows in reading order and scrolls vertically. When content extends beyond the bottom of the browser, scrollbars automatically appear. Content panes can also be made individually scrollable using overflow:scroll or overflow:auto.

Android screen content isn’t scrollable by default. However, many content Views such as ListView and EditText offer scrolling, and any layout can be made scrollable by wrapping it in a ScrollView or HorizontalScrollView.

It’s also possible to add custom scrolling to views by using methods like View.scrollTo and helpers like Scroller in response to touch events. And for horizontal, snap-to-page-bounds scrolling, one can use the excellent new ViewPager class in the support library.

Below is an example of a ScrollView containing a single TextView child and the code needed to implement something like this.

Figure: A TextView inside a ScrollView, scrolled about half way.


<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<!-- the scrollable content -->
<TextView android:layout_gravity="bottom|right"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="32dp"
android:textSize="48sp"
android:text="The\nquick\nbrown\nfox\njumps\nover..." />

</ScrollView>

Custom layouts

Sometimes the positioning and layout behaviors you can achieve with CSS aren’t enough to achieve your desired layout. In those cases, developers fall back on JavaScript coupled with absolute positioning to place and size elements as needed.

Programmatically defined layouts are also possible on Android. In fact, they’re sometimes the most elegant and/or performant way of implementing a unique or otherwise tricky layout. Not happy with nesting LinearLayouts for implementing a 2x3 grid of navigation icons? Just extend ViewGroup and implement your own layout logic! (see an example DashboardLayout here). All the built-in layouts such as LinearLayout, FrameLayout, and RelativeLayout are implemented this way, so there generally aren’t the same performance implications with custom layouts as there are with scripted layout on the web.

Device densities

Web designers have long dealt with the reality that display densities vary, and that there wasn’t much they could do about it. This meant that for a long time web page graphics and UI elements had different physical sizes across different displays. Your 100px wide logo could be 1” wide on a desktop monitor or ¾” on a netbook. This was mostly OK, given that (a) pointing devices such as mice offered generally good precision in interacting with such elements and (b) browsers allowed visually-impaired users to zoom pages arbitrarily.

However, on touch-enabled mobile devices, designers really need to begin thinking about physical screen size, rather than resolution in pixels. A 100px wide button on a 120dpi (low density) device is ~0.9” wide while on a 320dpi (extra-high density) screen it’s only ~0.3” wide. You need to avoid the fat-finger problem, where a crowded space of small touch targets coupled with an imprecise pointing tool (your finger) leads to accidental touches. The Android framework tries really hard to take your layout and scale elements up or down as necessary to work around device-density differences and get a usable result on a wide range of them. This includes the browser, which scales a 160px <img> at 100% browser zoom up to 240px on a 240dpi screen, such that its physical width is always 1”.

Developers can achieve finer-grained control over this browser scaling by providing custom stylesheets and images for different densities, using CSS3 media query filters such as -webkit-max-device-pixel-ratio and <meta> viewport arguments such as target-densitydpi=device-dpi. For an in-depth discussion on how to tame this mobile browser behavior see this blog post: Pixel-perfect Android web UIs.

For native Android apps, developers can use resource directory qualifiers to provide different images per density (such as drawable-hdpi and drawable-mdpi). In addition, Android offers a special dimension unit called ‘density independent pixels’ (dp) which can (and should!) be used in layout definitions to offset the density factors and create UI elements that have consistent physical sizes across screens with different densities.

Features you don’t have out of the box

There are a few features that web designers and developers rely on that aren’t currently available in the Android UI toolkit.

Developers can defer to user-driven browser zooming and two-dimensional panning for content that is too small or too large for its viewport, respectively. Android doesn’t currently provide an out-of-the-box mechanism for two-dimensional layout zooming and panning, but with some extra legwork using existing APIs, these interactions are possible. However, zooming and panning an entire UI is not a good experience on mobile, and is generally more appropriate for individual content views such as lists, photos, and maps.

Additionally, vector graphics (generally implemented with SVG) are gaining in popularity on the Web for a number of reasons: the need for resolution independence, accessibility and ‘indexability’ for text-heavy graphics, tooling for programmatic graphic generation, etc. Although you can’t currently drop an SVG into an Android app and have the framework render it for you, Android’s version of WebKit supports SVG as of Android 3.0. As an alternative, you can use the very robust Canvas drawing methods, similar to HTML5’s canvas APIs, to render vector graphics. There are also community projects such as svg-android that support rendering a subset of the SVG spec.

Conclusion

Web developers have a number of different tools for frontend layout and styling at their disposal, and there are analogues for almost all of these in the world of Android UI engineering. If you’re wondering about analogues to other web- or CSS-isms, start a conversation out there in the Android community; you’ll find you’re not alone.

URL: http://android-developers.blogspot.com/2011/09/thinking-like-web-designer.html

[Gd] App Engine 1.5.4 SDK Release

| More

Google App Engine Blog: App Engine 1.5.4 SDK Release

It’s been a busy four weeks for us (you may have heard), but we are still on track with our new monthly release schedule. Today we have new SDKs for you, with some new features as well as some bug fixes.


Overall Changes



  • Blobstore API - We’ve introduced an option to specify a limit on your blob upload size. This feature will allow you to expose blob uploads to your users, while still being able to ensure that their uploads won't exceed your preferred limits.

  • Datastore Query Improvements - We’re also continuing our theme from the past few releases to tune our Datastore query planner to give users more flexibility. Starting with 1.5.4, queries with equality filters on multiple properties will now continue scanning up to the 30 second Datastore query deadline. Many of these queries that used to generate an error due to inefficient indexes will now succeed.

  • Datastore Write Ops in the SDK - In response to the feedback from our recent Side By Side Bills release, we are now displaying the number of write ops needed to store an entity in the SDK dataviewer. Write ops include both the entity write as well as the index writes that are executed when an entity is added. You can always reduce the number of write ops by turning your indexed properties into unindexed properties, just make sure you don’t reference those properties in any of your queries! (Java, Python).


Java



  • Prospective Search API - We’ve released the experimental Java version of our Prospective Search API. Prospective Search lets you detect and take action on datastore entities that match certain criteria when they are written.



Python



  • Memcache - You can now make calls asynchronously with the Memcache API. With Asynchronous Memcache, your application does not need to block on calls to the Memcache API and can continue processing a request instead of waiting for a response from Memcache. Fear not Java friends, we’ll have matching functionality for you in an upcoming release.


Full release notes can be found in the usual location (Java, Python), and we’re always listening for your feedback in the groups. Happy coding!



Posted by The App Engine Team
URL: http://googleappengine.blogspot.com/2011/09/app-engine-154-sdk-release.html