Canonical Voices

Posts tagged with 'ubuntuone'

Martin Albisetti

As previously announced, the file services for Ubuntu One will be discontinued starting today.
In order to make it easier for you to move your content away, we have rolled out a new feature that lets you download all your content with just one click.
As a reminder, on July 31st 2014, all content in the file services will be deleted.

Just log into our website, and you will see the button placed prominently on the page:

u1-shutdown

 

For those looking for another Cloud storage option we’ve talked to a number of companies that wanted to tell Ubuntu One users about their services.

Mover.io

Mover is a web service that helps you migrate and backup files between cloud storage providers. The Mover team tells us they process more than two billion files each month, so that users can migrate files of all shapes and sizes, from a personal photo collection, to all of a workgroups files.

With Mover you can transfer files between services such as Dropbox, Box, Google Drive, Amazon S3 and a range of others.

Mover is helping U1 users to move transfer files for free. Simply create a Mover account and any transfers made in or out of the U1 connector will be free.

To find out more about their service see the blog post.

SpiderOak

SpiderOak is a cloud file service that is similar to Ubuntu One with all files stored in the Cloud. They have a ‘Zero-Knowledge’ privacy environment that provides end-to-end encryption to ensure you – and only you – can view your data. The SpiderOak team tell us they’ve been natively supported Linux from the start in 2007.

SpiderOak is offering two special deals for Ubuntu One customers:

  • 20 GB for $24.99/year

  • 40 GB for for $29.99/year

To take advantage of one of these offers use the Promotion Code LongLiveUbuntu. The steps are:

1. Click here to create your account.
2. Download and install the client.
3. Click  ‘Buy More Space’ in the client itself, or via the web portal (which you can only access once you’ve downloaded the client). In the web portal, you will go to Account, and then choose Upgrade My Plan.
4. Choose YEARLY and enter the following promotion code: LongLiveUbuntu. (NOTE: You MUST type in the promotion code as it will not work if you cut & paste.)
5. Congratulations – SpiderOak now has your back(up)!

For some more information on SpiderOak’s Linux support see their blog post.

 

ownCloud

ownCloud is an Open Source managed file sync and sharing software that you install on your own servers. It’s a great option for those that want the Cloud storage capability but would like to control where the files are stored. The ownCloud team told us that their Community version is well supported under Ubuntu and they also support Windows and Mac desktop machines, while on the mobile side there are clients for Android and iPhone/iPad. For those that need advanced enterprises capabilities there’s also a commercial version that adds those features.

You can read about how to install ownCloud Server and the Desktop clients here.

 

Refunds and Support

For those of you who have been paying customers, we have started processing refunds, and you should see it reflected in your credit cards or Paypal accounts within the next 7-10 days.

 

Read more
Cristian Parrino

Today we are announcing plans to shut down the Ubuntu One file services.  This is a tough decision, particularly when our users rely so heavily on the functionality that Ubuntu One provides.  However, like any company, we want to focus our efforts on our most important strategic initiatives and ensure we are not spread too thin.

Our strategic priority for Ubuntu is making the best converged operating system for phones, tablets, desktops and more. In fact, our user experience, developer tools for apps and scopes, and commercial relationships have been constructed specifically to highlight third party content and services (as opposed to our own); this is one of our many differentiators from our competitors.  Additionally, the free storage wars aren’t a sustainable place for us to be, particularly with other services now regularly offering 25GB-50GB free storage.  If we offer a service, we want it to compete on a global scale, and for Ubuntu One to continue to do that would require more investment than we are willing to make. We choose instead to invest in making the absolute best, open platform  and to highlight the best of our partners’ services and content.

As of today, it will no longer be possible to purchase storage or music from the Ubuntu One store. The Ubuntu One file services will not be included in the upcoming Ubuntu 14.04 LTS release, and the Ubuntu One apps in older versions of Ubuntu and in the Ubuntu, Google, and Apple stores will be updated appropriately. The current services will be unavailable from 1 June 2014; user content will remain available for download until 31 July, at which time it will be deleted.

We will work to ensure that customers have an easy path to download all their content from Ubuntu One to migrate to other personal cloud services.  Additionally, we continue to believe in the Ubuntu One file services, the quality of the code, and the user experience, so will release the code as open source software to give others an opportunity to build on this code to create an open source file syncing platform.

Customers who have an active annual subscription will have their unused fees refunded. We will calculate the refund amount from today’s announcement, even though the service will remain available until 1 June and data available for a further two months.

We will contact customers separately with additional information about what to expect.  We will also publish further blog posts with advice on how to download content and with details on the open sourcing of the code.

The shutdown will not affect the Ubuntu One single sign on service, the Ubuntu One payment service, or the backend U1DB database service.

We’ve always been inspired by the support, feedback and enthusiasm of our users and want to thank you for the support you’ve shown for Ubuntu One. We hope that you’ll continue to support us as together we bring a revolutionary experience to new devices.

 

Read more
John Lenton

Yesterday marked the end-of-life for desktop support on the 10.04 release of Ubuntu. Consequently, as of next Monday 13 of May the Ubuntu One service will discontinue support for 10.04 clients. This does not affect the data stored in Ubuntu One in any way, and users who are unwilling or unable to upgrade to a supported version of Ubuntu can continue to access their data through the website.
In the three years since we released 10.04 both the Ubuntu operating system and the Ubuntu One service have improved in innumerable ways, and you should really give it a try if you can!

Read more
Joshua Hoover

Since launching the Ubuntu One music store on the web there has been a steady flow of traffic to the web store and away from the store embedded in Rhythmbox on Ubuntu. The music store in Rhythmbox is operated separately from the one on the web, which means it requires a fair amount of additional work to keep it running smoothly. In order to make the music store better for everyone, regardless of what device they may be using at any given moment, we’re focusing on the web music store and removing the store from Rhythmbox in Ubuntu 13.04 as well as from previous releases, Ubuntu 12.04 LTS and 12.10 via a stable release update. With this change, all Ubuntu One music purchases will be made at https://one.ubuntu.com/music-store instead of in Rhythmbox. Your purchases will still automatically be delivered to your cloud storage, download to your computer and be available in Rhythmbox. Of course, if you have a music streaming subscription, you can also stream all your music from the web, Android, or iOS.

Read more
Roberta Nilerud

Ubuntu Phone OS integrates with Orange and Deutsche Telekom in GSMA OneAPI initiative

Mobile World Congress kicks off today and we’re gearing up to show off Ubuntu running on multiple devices. We’ll be demonstrating phones, tablets and desktops at our stand, have Ubuntu developers flashing spare hardware, as well as be showing integration and interoperability with Orange and Deutsche Telekom through the GSMA’s One API initiative.

GSMA’s OneAPI initiative aims to provide application programming interfaces (APIs) that enable applications to exploit mobile network capabilities, such as messaging, authentication, payments and location-finding with a cross-operator reach. For example, a payment network API could be used to add an in-app purchase directly to the user’s mobile phone bill.

Ubuntu is the first smartphone operating system to be able to demonstrate integration and interoperability with a carrier’s authentication and billing systems. Working with Deutsche Telekom and Orange, we’ll show how a single API can be used to instantly log users in with their operator identity and seamlessly link that with Ubuntu One, Ubuntu’s identity and payments services, and provide carrier billing options upon purchase of music and eventually, apps.

This is a massive step forward for the industry as the GSMA and partners such as Canonical, are spearheading an initiative to standardise access to operator facilities via network APIs across all operators. The initiative will benefit operators, developers and consumers

- It puts operators in a position to forge stronger relationships with their customers.

- For developers, OneAPI reduces the time and effort needed to create applications for and content that is portable across mobile operators, increasing reach and ultimately enhancing the consumer experience.

- For consumers, it makes it really quick and easy to make application purchases directly from their phone. It’s also more secure because it’s not necessary to input credit card details for each purchase.

Also at Mobile World Congress:

  1. Mark Shuttleworth, founder of Ubuntu, will participate in a keynote panel discussion alongside Mozilla and Tizen on Tuesday 26th Feb at 18.00 at the MWC Conference Auditorium and broadcast live on Mobile World Live
  2. We’ll be taking part in the App Developer Day on Tuesday 26th Feb. Stuart Langridge, technical architect at Canonical will be presenting the Ubuntu phone, SDK, HTML5 and native apps as well as discussing app development for Ubuntu on phones and tablets.We’ll also have engineers available at the event to flash spare handsets with Touch Developer Preview of Ubuntu. This will take place from 9.00-9.30 and 11.40-11.55, and 13.30-14.00 in Hall 8.0, Theatre A.
  3. The GSMA Seminar on “Unlocking Value with Network APIs”  will run on Thursday 28th from 9am to 10.30 am in Room CC1.1. Canonical’s Stuart Langridge will present and demo the Ubuntu Phone during the session. We’ll also be demonstrating Ubuntu’s OneAPI solution at the GSMA stand daily.
  4. Look out for Ubuntu engineers who will flash spare hardware with developer images for phone and tablet throughout the show close to the Ubuntu stand.

See us at MWC at stand: 81D30, App Planet Hall 8.1.

Read more
Joshua Hoover

Notification about Notes

Throughout last year, as we invested heavily in our new data sync infrastructure, we gradually had to turn off services that were reliant on the old infrastructure and providing little value to our users. Our Notes service was one of these, so last year we removed Notes from the Ubuntu One web UI.

As part of that ongoing strategy to constantly make sure we are spending our time on the right things, we’ll continue to improve our services during 2013. One of these updates, an upcoming database change, will impact how we currently sync Tomboy Notes. By the end of February 2013 we will cease syncing Tomboy Notes to U1, meaning U1 won’t transfer your notes between computers. Those of you still using U1 to sync your notes will need to stop relying on the service to sync or restore notes after new installations.

We realize syncing notes to Ubuntu One was a nice feature for a small set of people, even so, we are contacting the Tomboy developers to help them support our new APIs which utilizes our new U1DB data sync service.

We are sorry for any inconvenience this causes and if you have any questions please contact us.

Update – February 5, 2013
The timing of our post and the deployment of some changes on the server side (unrelated to notes) yesterday couldn’t have been worse. Due to some unforeseen aftereffects of the deployment, notes sync was impacted, which meant when people synced their notes after this update the notes were deleted. We apologize for this. The good news is Tomboy does not delete notes but moves them to a backup folder. If your notes were deleted, please follow the steps in this FAQ. If you can’t restore your notes that way, please contact support for help.

Also, there are some alternatives for syncing notes in Tomboy. We’re providing two suggestions below.

1. Tomboy local backup
Backup your notes to a local folder and sync that folder with Ubuntu One. Note, if you are syncing notes between multiple computers, there may be some issues that arise due to conflicts. Here is how to sync notes with Ubuntu One and Tomboy’s local folder sync setup:

  1. Open Tomboy and open the Preferences menu
  2. Click on the “Synchronization” tab
  3. Click the “Clear” button
  4. Select “Local Folder” from the “Service” drop down menu
  5. Select a folder to sync your notes to from the “Folder Path” menu
  6. Click the “Save” button
  7. Open the Ubuntu One Control Panel and click the “Add a folder from this computer” button under the “Folders” tab and select the folder you chose in step 5

2. Rainy
Timo Dörr created Rainy, a note synchronisation/cloud server for Tomboy that can be used like Ubuntu One’s notes sync service. Rainy is a more advanced option and requires access to a server. If you’re interested, get started here.

Read more
Roberta Nilerud

Official Mac OS X client for Ubuntu One

A few months back we released the Ubuntu One Mac OS X client in beta, today we’re pleased to announce that we have released the official version. If you’ve been using the current beta you’ll need to install this new version manually as the beta version didn’t have automatic update functionality, however this has now been added to the official version.

Over the last few months we’ve been busy fixing bugs and making updates to the client, in this official version we’ve included;

  1. Client automatically checks and downloads latest updates
  2. Ubuntu One service stays running in the background (with menu bar icon) after  -  Ubuntu One (Control panel) app is quit.
  3. Status icon menu in the top menu bar now shows progress of current transfers
  4. Honors system proxy settings (*except for PAC files, which we don’t support on any platform)
  5. Translations included – localized for all the same languages as U1 on Ubuntu.

Ubuntu One is cross-platform and works on Windows, iOS, Android, Ubuntu, the web and now on Mac, so you can use Ubuntu One between all your favourite OSes and across devices. Files, photos, documents, music – all your precious stuff can be stored and managed in a single place with your Ubuntu One personal cloud. You can then access your stuff from anywhere, freeing up space on your other devices. Maybe you work on Mac or Windows PCs but use Ubuntu at home, and have an iPhone, iPad or Android device. Ubuntu One spreads your saved content to all of them and also enables more opportunities for sharing across platforms with family and friends

This will be our last major update in 2012, so we’d like to thank those of you who’ve been testing the Mac beta version and reporting bugs, we couldn’t have done it without you. We’d also especially like to thank all our loyal users for your continuing support during 2012. We hope you enjoy the holidays and wish you all the best for 2013.

See you in the New Year!

 

Read more
Roberta Nilerud

We’re thrilled that our latest Ubuntu One feature update comes just in time for the holidays, helping you enjoy and share all those precious memories on all your devices and between your family and friends.

The first thing you’ll notice when you log in is that your photos now appear in the dedicated photos tab, located in the U1 dashboard. This gives you a proper album view where all the photos you’ve ever saved to Ubuntu One will automatically appear as album thumbnails.

Ubuntu One photo album

This is great for reminding you of old favourites or even surfacing photos you thought were long lost. Some real gems from past Canonical parties have been re-discovered during our internal testing!

Use the U1 files app along with U1 photos and all your photos from your mobile device, even those from other apps like Instagram, are safe in one place and available to view and share easily with family and friends.

Ubuntu One slideshow

You can organise albums chronologically or alphabetically and images in albums can be clicked through individually or played as a slideshow. It’s super easy to download images and share albums, slideshows or single snaps with your friends and family. When you share an album, anyone with the URL will be able to view your album or slideshow. For quick sharing, you can choose to share a link or push to Facebook and Twitter simply by clicking on the icon. Try it now!

To celebrate this update we are asking users to tweet snaps of their holiday decorations using the Ubuntu One share URL and by including the hashtag #UbuntuOne, we’ll then pick our 20 favourites photos and the winners will get 5GB extra free storage in the new year. Should #UbuntuOne trend during that time we’ll increase the winners storage amount to 20GB!

Read more
Roberta Nilerud

What a year so far!

Busy times folks, last week we announced the launch of the Ubuntu One Mac OS X beta and today the latest Ubuntu release 12.10 went live. This latest Ubuntu release is packed with exciting features, included are some great updates for Ubuntu One and other online services, you can get the full 12.10 low-down on Ubuntu.com

One of the key focus areas has been to put a strong stake in the ground towards our vision to turn the Dash into being the fastest and most stylish way to instantly find things anywhere – whether on your machine or online. We’ve also added new lenses in the Dash including updated Music and Video lenses, making it easier to find your content, whether it’s stored on your hard drive or online.

Another addition is Web Apps, which let you pin commonly-used web applications like GMail, Amazon and Facebook to the Launcher. This lets you access your online applications just like your desktop apps and switch between them more easily when you have several open at the same time. They get their own desktop icon which can be seen in the application switcher and to launch one, there is no need to separately launch a browser and click on a bookmark or enter a URL and passwords.

The Ubuntu One Music Store is a great example of a Web app and is installed by default in 12.10.

Gaming on Ubuntu has been another focus for us and we’ve had a busy couple of months working with new partners such as Humble Bundle, Valve and Unity Technologies who are all investing in the Ubuntu Platform. Ubuntu is a powerful force in the game industry and with the Unity 4.0 release we can’t wait to play the games from their millions of game developers who can now easily publish right to Ubuntu. Watch this space and participate with Valve and Unity at UDS online, as together we continue to make Ubuntu gaming great!

Data Sync Services

For a while now we’ve talked about the need to overhaul our sync infrastructure, enabling us to build better products and deliver higher service levels to our users – well, that vision has been realised in this release with U1DB.

U1DB is a database API for synchronised databases of JSON documents. It’s simple to use in applications, and allows apps to store documents and synchronise them between machines and devices. U1DB itself is not a database: instead, it’s an API and data model which can be backed by any database for storage. This means that you can use U1DB on different platforms, from different languages, and backed on to different databases, and sync between all of them.
Data sync is an essential part of what we want to offer with Ubuntu One. We already offer file sync, and that’s also part of our developer story (the APIs for file sync and music streaming are documented at https://one.ubuntu.com/developer/);

U1DB is designed to offer data sync. Some information in your personal cloud is best done as files: your music, your photos, letters written in Word, things you want to back up. However, applications work with data: contacts, metadata about your files, todo lists, preferences and settings, and most stuff an application works with. We’re building U1DB to allow app developers to work with the same data on every platform and in every language; to save data and sync it between devices without having to manage that themselves.

The above coupled with all the other stuff we’ve had going on has made it quite a year so far, with lots of crunching and hard work, phew!  A few highlights being the recent Mac OS X beta, the U1 referrals program which lets users earn up to 20GB free storage by inviting family and friends. Our Web and mobile Music Store, Ubuntu One Filelink in Thunderbird mail,Ubuntu One Files Java library  and our Send to U1 preview.
Plus, continuing to fix bugs, regular updates for our Windows, Android and iOS apps, general speed and performance improvements and our commitment to speedy customer service, means no wonder we’re now on our way to serving nearly 3 million of you all over the world!

Read more
Roberta Nilerud

Ubuntu One for Mac OS X now in beta

We know many of you have been eagerly awaiting our Mac OS X client, so we’re pleased to tell you that the public beta is now available for download

 

Ubuntu One is a cross-platform personal cloud service already available on Windows , iOS, Android and Ubuntu – the new Mac beta completes that story.

So you can use Ubuntu One on your favourite OS or across a variety of devices and platforms.

The Ubuntu One Mac beta is easy to use, all you have to do is:

1. Download the .dmg file and open it on your machine.
2. Drag the Ubuntu One app icon from the .dmg into your Applications folder.

3. Feel free to unmount the .dmg and run the app.
4. Once you open the app, you’ll be asked to enter your administrator password to allow Ubuntu One to have administrator privileges.

5. Next you’ll be asked to sign in with your existing Ubuntu One account or create a new account.

 

 

 

 

 

 

 

 

 

 

 

 

6. After you sign in, follow the prompts to select any folders you’d like to sync to Ubuntu One and you’re ready to go!

As this is a beta we are still working hard fixing bugs to make the Mac client even slicker. Please be patient whilst we iron out the kinks over the coming weeks, and make sure to keep your eye on the download page or on our Facebook, Google+ pages or follow us on Twitter for information about the latest client updates.

Thank you to those of you who’ve been testing the alpha version and you can help us further by continuing to test the beta and reporting any bugs you find, you can see known issues here.

Read more
Roberta Nilerud

We’re pleased to tell you that today we’ve launched the new Ubuntu One Music Store.
This means you can now purchase all your favourite music from the Ubuntu One Music Store via the web or on your mobile. Watch as the tracks you buy are magically delivered straight to your Ubuntu One personal cloud in an instant. No clumsy downloading is needed, as soon as you complete the transactions your music will appear in your Ubuntu One music cloud folder ready for you to stream or automatically sync with your computer.

The Ubuntu One Music Store can be easily accessed via the music tab in the Ubuntu One web dash. From the music store home view you can browse new releases, top tracks and top albums, then add to your basket, checkout and you’re all set. Our new store offers all the same functionality as the Ubuntu One music store in Rhythmbox, only has a new slicker navigation that makes discovering and buying the music you love even easier.

To celebrate our new store we are running a special promotion. Everyone who makes any purchase from now until the end of October will automatically receive Ubuntu One Music Streaming free for 6 months. Music Streaming is normally $3.99 per month and includes 20GB of storage for all your files, photos and music. Plus you can stream music to your Android and iPhone and via the web, wherever you are free, for 6 months.

Read more
Roberta Nilerud

When you’re emailing files, photos and documents to friends, family and colleagues, attaching those files can often be inconvenient for you and for the people you’re sending them to. A common problem when sending and receiving email is that many email servers don’t accept messages with large file attachments. You may be able to send a message with a large attachment but the receiving mail server might refuse to accept it.

To solve these issues in June Mozilla Thunderbird added the Filelink feature. Today Thunderbird and the Ubuntu One team are pleased to tell you that we’ve added support for Ubuntu One in Filelink.This means that when you attach a large file to an email, that attachment is replaced with a link to the file in your Ubuntu One personal cloud.

That way, your friends and colleagues can access your content directly from Ubuntu One. Making it quicker and easier to forward on your files and documents to other people, and send files of any size even if the recipient’s email provider can’t handle large attachments.

The Ubuntu One Filelink feature is available in Thuderbird’s latest release out today and shortly available on Ubuntu through Ubuntu Software Center.

Read more
Roberta Nilerud

Last week we let you know via the Canonical blog that the third Humble Bundle for Android was released and available on Ubuntu. Today four additional titles are now part of the Humble Bundle for Android #3: World of Goo, Osmos, EDGE and Anomaly. Once again, the Humble Bundle is super-easy to download through the Ubuntu Software Center. The bundle deal is only available for two weeks on a name-your-price basis. If you already purchased the bundle last week and you paid more than the average pay-what-you-like price, then you’ll get all four new games added to your bundle.

What’s cool about buying from Humble Bundle is that you get to decide how much you pay and how your payment is divided between the developers, the Child’s Play Charity, or the Electronic Frontier Foundation.

So far over over $500,000 has been raised so there’s still time to add your contribution.

Read more
Roberta Nilerud

We’re excited to tell you we’ve just launched the Ubuntu One referrals program. Ubuntu One referrals are a way for you to earn even more free cloud storage by spreading the word and inviting your family and friends to join Ubuntu One.

Starting today, you’ll see a referrals invite link in your Ubuntu One web dash. It’s super easy, just send the referrals link to all your friends and family via email or Twitter and Facebook.

For each person you invite who signs up for an Ubuntu One account, we’ll give you 500MB of extra free cloud storage. Each of the people you told about Ubuntu One will also get 500MB of extra free cloud storage on top of the initial free 5GB they get by signing up to Ubuntu One. They can then invite more people and earn even more free storage.

 

Ubuntu One dashboard

 

Every Ubuntu One user can invite a maximum of 40 people, which will earn you an extra 20GB of cloud storage absolutely free! There’s no catch. The free storage you earn from referring your family and friends lasts for as long as you continue to use Ubuntu One. You can find more information about referrals on our FAQ.

Read more
Martin Albisetti

Ubuntu One Files Java library

We wanted to let you know that Ubuntu One is now releasing a Java library to access files stored in your personal cloud at Ubuntu One, to make them available for use in your own applications. You can bundle it with the Ubuntu SSO Java library and harness Ubuntu One cloud storage in your apps.

The Ubuntu One Files Java library allows you to talk to the Ubuntu One REST API from Java.
It has no Android dependencies, therefore it is suitable for use in Java SE 1.6 runtime applications as well as Android apps! Actually, it’s exactly the library used by our Ubuntu One Files app for Android.

The library has been built based on the documentation available at:
https://one.ubuntu.com/developer/files/store_files/cloud
and is documented itself at:
https://one.ubuntu.com/developer/files/store_files/android

Ubuntu One Files Java library project page:
http://launchpad.net/ubuntuone-files-java-library
Ubuntu SSO Java library project page:
https://launchpad.net/ubuntu-sso-java-library

To show you how neat this is we thought we’d give you a few examples of how to use the library, so you’ll be up and running in no time.

Sample CLI Ubuntu One app shows how to sign in and manipulate files in Ubuntu One:

$ bzr branch lp:~karni/ubuntuone-files-java-library/cli-ubuntuone

Go ahead and check out the code. Check out the README.md for more details.

Yet another CLI example shows how to sign up from scratch as well as sign in to Ubuntu One:
$ bzr branch lp:~karni/ubuntu-sso-java-library/sso-cli-example

Another example, although slightly more complex, is our Ubuntu One Files app for Android at https://launchpad.net/ubuntuone-android-files

$ bzr branch lp:ubuntuone-android-files

This example uses the library inside two services – MetaService for light operations like publishing and renaming files, and UpDownService for long lasting file transfers.

So, what can you use the library for?
- Implement backup to Ubuntu One in your Java and Android applications
- Use Ubuntu One as storage for your application data
- Generate public links to files stored in Ubuntu One, so you can send/share a link instead of a (possibly large) file
- You tell us! Join #ubuntuone on Freenode and tell us where you use our library!

For more info, refer to
- Documentation at https://one.ubuntu.com/developer/files/store_files/android
- READMEs available within project sources
- and lastly: ant -projecthelp

If you have any questions or feedback, join our IRC channel (#ubuntuone on Freenode; you can get to this channel from the web at http://webchat.freenode.net?channels=ubuntuone) and we will be happy to help.

Alternatively, feel free to ping (karni or aquarius) directly on IRC or you can also contact us   directly by email.

Read more
Roberta Nilerud

Changes to Contacts

The U1 team likes to make things that are useful to our users. That’s why we are always working hard towards improving our services, making updates and launching new features.

As we communicated back in December, we’re continuing to invest in our new data sync infrastructure U1DB. Therefore, we’ve been gradually turning off services that are reliant on the old infrastructure and providing little value to users in their current form.

As such, from today we have decided to remove Facebook contacts import & sync as a option from the U1 web dashboard.

Don’t worry, those of you who have added contacts already will still have them available in the U1 web dash and you’ll still be able to manually add and edit contacts.

Contacts will also be one of the first services that we will build on top of our upcoming new data sync infrastructure. The hackers among you who would like to contribute, please contact us.

Keep an eye on the blog for updates about the future of U1 contacts .

Read more
mandel

So yet again I have been confronted with broken tests in Ubuntu One. As I have already mentioned before I have spent a significant amount of time ensuring that the tests of Ubuntu One (which use twisted a lot) are deterministic and we do not leave a dirty reactor in the way. In order to do that a few week a go I wrote the following code that will help the rest of the team write such tests:

import os
import shutil
import tempfile
 
from twisted.internet import defer, endpoints, protocol
from twisted.spread import pb
 
from ubuntuone.devtools.testcases import BaseTestCase
 
# no init method +  twisted common warnings
# pylint: disable=W0232, C0103, E1101
 
 
def server_protocol_factory(cls):
    """Factory to create tidy protocols."""
 
    if cls is None:
        cls = protocol.Protocol
 
    class ServerTidyProtocol(cls):
        """A tidy protocol."""
 
        def connectionLost(self, *args):
            """Lost the connection."""
            cls.connectionLost(self, *args)
            # lets tell everyone
            # pylint: disable=W0212
            if (self.factory._disconnecting
                    and self.factory.testserver_on_connection_lost is not None
                    and not self.factory.testserver_on_connection_lost.called):
                self.factory.testserver_on_connection_lost.callback(self)
            # pylint: enable=W0212
 
    return ServerTidyProtocol
 
 
def client_protocol_factory(cls):
    """Factory to create tidy protocols."""
 
    if cls is None:
        cls = protocol.Protocol
 
    class ClientTidyProtocol(cls):
        """A tidy protocol."""
 
        def connectionLost(self, *a):
            """Connection list."""
            # pylint: disable=W0212
            if (self.factory._disconnecting
                    and self.factory.testserver_on_connection_lost is not None
                    and not self.factory.testserver_on_connection_lost.called):
                self.factory.testserver_on_connection_lost.callback(self)
            # pylint: enable=W0212
            cls.connectionLost(self, *a)
 
    return ClientTidyProtocol
 
 
class TidySocketServer(object):
    """Ensure that twisted servers are correctly managed in tests.
 
    Closing a twisted server is a complicated matter. In order to do so you
    have to ensure that three different deferreds are fired:
 
        1. The server must stop listening.
        2. The client connection must disconnect.
        3. The server connection must disconnect.
 
    This class allows to create a server and a client that will ensure that
    the reactor is left clean by following the pattern described at
    http://mumak.net/stuff/twisted-disconnect.html
    """
    def __init__(self):
        """Create a new instance."""
        self.listener = None
        self.server_factory = None
 
        self.connector = None
        self.client_factory = None
 
    def get_server_endpoint(self):
        """Return the server endpoint description."""
        raise NotImplementedError('To be implemented by child classes.')
 
    def get_client_endpoint(self):
        """Return the client endpoint description."""
        raise NotImplementedError('To be implemented by child classes.')
 
    @defer.inlineCallbacks
    def listen_server(self, server_class, *args, **kwargs):
        """Start a server in a random port."""
        from twisted.internet import reactor
        self.server_factory = server_class(*args, **kwargs)
        self.server_factory._disconnecting = False
        self.server_factory.testserver_on_connection_lost = defer.Deferred()
        self.server_factory.protocol = server_protocol_factory(
                                                 self.server_factory.protocol)
        endpoint = endpoints.serverFromString(reactor,
                                              self.get_server_endpoint())
        self.listener = yield endpoint.listen(self.server_factory)
        defer.returnValue(self.server_factory)
 
    @defer.inlineCallbacks
    def connect_client(self, client_class, *args, **kwargs):
        """Conect a client to a given server."""
        from twisted.internet import reactor
 
        if self.server_factory is None:
            raise ValueError('Server Factory was not provided.')
        if self.listener is None:
            raise ValueError('%s has not started listening.',
                             self.server_factory)
 
        self.client_factory = client_class(*args, **kwargs)
        self.client_factory._disconnecting = False
        self.client_factory.protocol = client_protocol_factory(
                                                 self.client_factory.protocol)
        self.client_factory.testserver_on_connection_lost = defer.Deferred()
        endpoint = endpoints.clientFromString(reactor,
                                                    self.get_client_endpoint())
        self.connector = yield endpoint.connect(self.client_factory)
        defer.returnValue(self.client_factory)
 
    def clean_up(self):
        """Action to be performed for clean up."""
        if self.server_factory is None or self.listener is None:
            # nothing to clean
            return defer.succeed(None)
 
        if self.listener and self.connector:
            # clean client and server
            self.server_factory._disconnecting = True
            self.client_factory._disconnecting = True
            self.connector.transport.loseConnection()
            d = defer.maybeDeferred(self.listener.stopListening)
            return defer.gatherResults([d,
                self.client_factory.testserver_on_connection_lost,
                self.server_factory.testserver_on_connection_lost])
        if self.listener:
            # just clean the server since there is no client
            self.server_factory._disconnecting = True
            return defer.maybeDeferred(self.listener.stopListening)
 
 
class TidyTCPServer(TidySocketServer):
    """A tidy tcp domain sockets server."""
 
    client_endpoint_pattern = 'tcp:host=127.0.0.1:port=%s'
    server_endpoint_pattern = 'tcp:0:interface=127.0.0.1'
 
    def get_server_endpoint(self):
        """Return the server endpoint description."""
        return self.server_endpoint_pattern
 
    def get_client_endpoint(self):
        """Return the client endpoint description."""
        if self.server_factory is None:
            raise ValueError('Server Factory was not provided.')
        if self.listener is None:
            raise ValueError('%s has not started listening.',
                                                          self.server_factory)
        return self.client_endpoint_pattern % self.listener.getHost().port
 
 
class TidyUnixServer(TidySocketServer):
    """A tidy unix domain sockets server."""
 
    client_endpoint_pattern = 'unix:path=%s'
    server_endpoint_pattern = 'unix:%s'
 
    def __init__(self):
        """Create a new instance."""
        super(TidyUnixServer, self).__init__()
        self.temp_dir = tempfile.mkdtemp()
        self.path = os.path.join(self.temp_dir, 'tidy_unix_server')
 
    def get_server_endpoint(self):
        """Return the server endpoint description."""
        return self.server_endpoint_pattern % self.path
 
    def get_client_endpoint(self):
        """Return the client endpoint description."""
        return self.client_endpoint_pattern % self.path
 
    def clean_up(self):
        """Action to be performed for clean up."""
        result = super(TidyUnixServer, self).clean_up()
        # remove the dir once we are disconnected
        result.addCallback(lambda _: shutil.rmtree(self.temp_dir))
        return result
 
 
class ServerTestCase(BaseTestCase):
    """Base test case for tidy servers."""
 
    @defer.inlineCallbacks
    def setUp(self):
        """Set the diff tests."""
        yield super(ServerTestCase, self).setUp()
 
        try:
            self.server_runner = self.get_server()
        except NotImplementedError:
            self.server_runner = None
 
        self.server_factory = None
        self.client_factory = None
        self.server_disconnected = None
        self.client_connected = None
        self.client_disconnected = None
        self.listener = None
        self.connector = None
        self.addCleanup(self.tear_down_server_client)
 
    def get_server(self):
        """Return the server to be used to run the tests."""
        raise NotImplementedError('To be implemented by child classes.')
 
    @defer.inlineCallbacks
    def listen_server(self, server_class, *args, **kwargs):
        """Listen a server.
 
        The method takes the server class and the arguments that should be
        passed to the server constructor.
        """
        self.server_factory = yield self.server_runner.listen_server(
                                                server_class, *args, **kwargs)
        self.server_disconnected = 
                self.server_factory.testserver_on_connection_lost
        self.listener = self.server_runner.listener
 
    @defer.inlineCallbacks
    def connect_client(self, client_class, *args, **kwargs):
        """Connect the client.
 
        The method takes the client factory  class and the arguments that
        should be passed to the client constructor.
        """
        self.client_factory = yield self.server_runner.connect_client(
                                                client_class, *args, **kwargs)
        self.client_disconnected = 
                self.client_factory.testserver_on_connection_lost
        self.connector = self.server_runner.connector
 
    def tear_down_server_client(self):
        """Clean the server and client."""
        if self.server_runner:
            return self.server_runner.clean_up()
 
 
class TCPServerTestCase(ServerTestCase):
    """Test that uses a single twisted server."""
 
    def get_server(self):
        """Return the server to be used to run the tests."""
        return TidyTCPServer()
 
 
class UnixServerTestCase(ServerTestCase):
    """Test that uses a single twisted server."""
 
    def get_server(self):
        """Return the server to be used to run the tests."""
        return TidyUnixServer()
 
 
class PbServerTestCase(ServerTestCase):
    """Test a pb server."""
 
    def get_server(self):
        """Return the server to be used to run the tests."""
        raise NotImplementedError('To be implemented by child classes.')
 
    @defer.inlineCallbacks
    def listen_server(self, *args, **kwargs):
        """Listen a pb server."""
        yield super(PbServerTestCase, self).listen_server(pb.PBServerFactory,
                                                              *args, **kwargs)
 
    @defer.inlineCallbacks
    def connect_client(self, *args, **kwargs):
        """Connect a pb client."""
        yield super(PbServerTestCase, self).connect_client(pb.PBClientFactory,
                                                              *args, **kwargs)
 
 
class TCPPbServerTestCase(PbServerTestCase):
    """Test a pb server over TCP."""
 
    def get_server(self):
        """Return the server to be used to run the tests."""
        return TidyTCPServer()
 
 
class UnixPbServerTestCase(PbServerTestCase):
    """Test a pb server over Unix domain sockets."""
 
    def get_server(self):
        """Return the server to be used to run the tests."""
        return TidyUnixServer()

The idea of the code is that developers do not need to worry about how to stop listening ports in their tests and just write tests like the following:

class TCPMultipleServersTestCase(TestCase):
    """Ensure that several servers can be ran."""
 
    timeout = 2
 
    @defer.inlineCallbacks
    def setUp(self):
        """Set the diff tests."""
        yield super(TCPMultipleServersTestCase, self).setUp()
        self.first_tcp_server = self.get_server()
        self.second_tcp_server = self.get_server()
        self.adder = Adder()
        self.calculator = Calculator(self.adder)
        self.echoer = Echoer()
 
    def get_server(self):
        """Return the server to be used to run the tests."""
        return TidyTCPServer()
 
    @defer.inlineCallbacks
    def test_single_server(self):
        """Test setting a single server."""
        first_number = 1
        second_number = 2
        yield self.first_tcp_server.listen_server(pb.PBServerFactory,
                                                              self.calculator)
        self.addCleanup(self.first_tcp_server.clean_up)
        calculator_c = yield self.first_tcp_server.connect_client(
                                                           pb.PBClientFactory)
        calculator = yield calculator_c.getRootObject()
        adder = yield calculator.callRemote('get_adder')
        result = yield adder.callRemote('add', first_number, second_number)
        self.assertEqual(first_number + second_number, result)
 
    @defer.inlineCallbacks
    def test_multiple_server(self):
        """Test setting multiple server."""
        first_number = 1
        second_number = 2
        # first server
        yield self.first_tcp_server.listen_server(pb.PBServerFactory,
                                                              self.calculator)
        self.addCleanup(self.first_tcp_server.clean_up)
 
        # second server
        yield self.second_tcp_server.listen_server(pb.PBServerFactory,
                                                   self.echoer)
        self.addCleanup(self.second_tcp_server.clean_up)
 
        # connect the diff clients
        calculator_c = yield self.first_tcp_server.connect_client(
                                                           pb.PBClientFactory)
        echoer_c = yield self.second_tcp_server.connect_client(
                                                           pb.PBClientFactory)
 
        calculator = yield calculator_c.getRootObject()
        adder = yield calculator.callRemote('get_adder')
        result = yield adder.callRemote('add', first_number, second_number)
        self.assertEqual(first_number + second_number, result)
        echoer = yield echoer_c.getRootObject()
        echo = yield echoer.callRemote('say', 'hello')
        self.assertEqual(self.echoer.remote_say('hello'), echo)

As you can see those tests do not give a rats ass about ensuring that the clients lose connection or we stop listening ports… Or so I though because the following code made such approach break in Mac OS X (although I suspect it was broken on Linux and Windows but we never experienced it):

class NullProtocol(protocol.Protocol):
    """A protocol that drops the connection."""
 
    def connectionMade(self):
        """Just drop the connection."""
        self.transport.loseConnection()
 
 
class PortDetectFactory(protocol.ClientFactory):
    """Will detect if something is listening in a given port."""
 
    protocol = NullProtocol
 
    def __init__(self):
        """Initialize this instance."""
        self.d = defer.Deferred()
 
    def is_listening(self):
        """A deferred that will become True if something is listening."""
        return self.d
 
    def buildProtocol(self, addr):
        """Connected."""
        p = protocol.ClientFactory.buildProtocol(self, addr)
        if not self.d.called:
            self.d.callback(True)
        return p
 
    def clientConnectionLost(self, connector, reason):
        """The connection was lost."""
        if not self.d.called:
            self.d.callback(False)
 
    def clientConnectionFailed(self, connector, reason):
        """The connection failed."""
        if not self.d.called:
            self.d.callback(False)

The code used to test the above was written as:

    @defer.inlineCallbacks
    def test_is_already_running(self):
        """The is_already_running method returns True if already started."""
        server = self.get_server()
        self.addCleanup(server.clean_up)
 
        class TestConnect(object):
 
            @defer.inlineCallbacks
            def connect(my_self, factory):
                connected_factory = yield server.connect_client(PortDetectFactory)
                self.patch(factory, 'is_listening', lambda:
                        connected_factory.is_listening())
                defer.returnValue(connected_factory)
 
        self.patch(tcpactivation, 'clientFromString', lambda *args: TestConnect())
 
        yield server.listen_server(protocol.ServerFactory)
 
        # pylint: disable=E1101
        ad = ActivationDetector(self.config)
        result = yield ad.is_already_running()
        self.assertTrue(result, "It should be already running.")

While in all the other platforms the tests passed with no problems on Mac OS X the tests would block in the clean_up method from the server because the deferred that was called in the connectionLost from the ServerTidyProtocol was never fired… Interesting.. After digging in the code I realized that the main issue with the approach of the clean_up code was wrong. The problem relies on the way in which the NullProtocol works. As you can see in the code the protocol loses its connections as soon as it made. This results in to possible things:

  1. The server does know that we have a client connected and calls buildProtocol.
  2. The connection is lost so fast that the buildProtocol on the ServerFactory does not get call.

When running the tests on Windows and Linux we were always facing the first scenario, buildProtocol was called which meant that connectionLost in the server protocol would be called. On the other hand, on Mac OS X, 1 out of 10 runs of the tests would block in the clean up because we would be in the second scenario, that is, no protocol would be build in the ServerFactory which results in the connectionLost never being called because it was no needed. The work around this issue is quite simple once you understand what is going on. The ServerFactory has to be modified to set the deferred when buildProtocol is called and not before ensuring that when we cleanup we check if the deferred is None and if it is not we wait for it to be fired. The fixed version of the helper code is the following:

import os
import shutil
import tempfile
 
from twisted.internet import defer, endpoints, protocol
from twisted.spread import pb
 
from ubuntuone.devtools.testcases import BaseTestCase
 
# no init method + twisted common warnings
# pylint: disable=W0232, C0103, E1101
 
 
def server_protocol_factory(cls):
    """Factory to create tidy protocols."""
 
    if cls is None:
        cls = protocol.Protocol
 
    class ServerTidyProtocol(cls):
        """A tidy protocol."""
 
        def connectionLost(self, *args):
            """Lost the connection."""
            cls.connectionLost(self, *args)
            # lets tell everyone
            # pylint: disable=W0212
            if (self.factory._disconnecting
                    and self.factory.testserver_on_connection_lost is not None
                    and not self.factory.testserver_on_connection_lost.called):
                self.factory.testserver_on_connection_lost.callback(self)
            # pylint: enable=W0212
 
    return ServerTidyProtocol
 
 
def server_factory_factory(cls):
    """Factory that creates special types of factories for tests."""
 
    if cls is None:
        cls = protocol.ServerFactory
 
    class TidyServerFactory(cls):
        """A tidy factory."""
 
        testserver_on_connection_lost = None
 
        def buildProtocol(self, addr):
            prot = cls.buildProtocol(self, addr)
            self.testserver_on_connection_lost = defer.Deferred()
            return prot
 
    return TidyServerFactory
 
 
def client_protocol_factory(cls):
    """Factory to create tidy protocols."""
 
    if cls is None:
        cls = protocol.Protocol
 
    class ClientTidyProtocol(cls):
        """A tidy protocol."""
 
        def connectionLost(self, *a):
            """Connection list."""
            cls.connectionLost(self, *a)
            # pylint: disable=W0212
            if (self.factory._disconnecting
                    and self.factory.testserver_on_connection_lost is not None
                    and not self.factory.testserver_on_connection_lost.called):
                self.factory.testserver_on_connection_lost.callback(self)
            # pylint: enable=W0212
 
    return ClientTidyProtocol
 
 
class TidySocketServer(object):
    """Ensure that twisted servers are correctly managed in tests.
 
    Closing a twisted server is a complicated matter. In order to do so you
    have to ensure that three different deferreds are fired:
 
        1. The server must stop listening.
        2. The client connection must disconnect.
        3. The server connection must disconnect.
 
    This class allows to create a server and a client that will ensure that
    the reactor is left clean by following the pattern described at
    http://mumak.net/stuff/twisted-disconnect.html
    """
    def __init__(self):
        """Create a new instance."""
        self.listener = None
        self.server_factory = None
 
        self.connector = None
        self.client_factory = None
 
    def get_server_endpoint(self):
        """Return the server endpoint description."""
        raise NotImplementedError('To be implemented by child classes.')
 
    def get_client_endpoint(self):
        """Return the client endpoint description."""
        raise NotImplementedError('To be implemented by child classes.')
 
    @defer.inlineCallbacks
    def listen_server(self, server_class, *args, **kwargs):
        """Start a server in a random port."""
        from twisted.internet import reactor
        tidy_class = server_factory_factory(server_class)
        self.server_factory = tidy_class(*args, **kwargs)
        self.server_factory._disconnecting = False
        self.server_factory.protocol = server_protocol_factory(
                                                 self.server_factory.protocol)
        endpoint = endpoints.serverFromString(reactor,
                                              self.get_server_endpoint())
        self.listener = yield endpoint.listen(self.server_factory)
        defer.returnValue(self.server_factory)
 
    @defer.inlineCallbacks
    def connect_client(self, client_class, *args, **kwargs):
        """Conect a client to a given server."""
        from twisted.internet import reactor
 
        if self.server_factory is None:
            raise ValueError('Server Factory was not provided.')
        if self.listener is None:
            raise ValueError('%s has not started listening.',
                             self.server_factory)
 
        self.client_factory = client_class(*args, **kwargs)
        self.client_factory._disconnecting = False
        self.client_factory.protocol = client_protocol_factory(
                                                 self.client_factory.protocol)
        self.client_factory.testserver_on_connection_lost = defer.Deferred()
        endpoint = endpoints.clientFromString(reactor,
                                                    self.get_client_endpoint())
        self.connector = yield endpoint.connect(self.client_factory)
        defer.returnValue(self.client_factory)
 
    def clean_up(self):
        """Action to be performed for clean up."""
        if self.server_factory is None or self.listener is None:
            # nothing to clean
            return defer.succeed(None)
 
        if self.listener and self.connector:
            # clean client and server
            self.server_factory._disconnecting = True
            self.client_factory._disconnecting = True
            d = defer.maybeDeferred(self.listener.stopListening)
            self.connector.transport.loseConnection()
            if self.server_factory.testserver_on_connection_lost:
                return defer.gatherResults([d,
                    self.client_factory.testserver_on_connection_lost,
                    self.server_factory.testserver_on_connection_lost])
            else:
                return defer.gatherResults([d,
                    self.client_factory.testserver_on_connection_lost])
        if self.listener:
            # just clean the server since there is no client
            # pylint: disable=W0201
            self.server_factory._disconnecting = True
            return defer.maybeDeferred(self.listener.stopListening)
            # pylint: enable=W0201
 
 
class TidyTCPServer(TidySocketServer):
    """A tidy tcp domain sockets server."""
 
    client_endpoint_pattern = 'tcp:host=127.0.0.1:port=%s'
    server_endpoint_pattern = 'tcp:0:interface=127.0.0.1'
 
    def get_server_endpoint(self):
        """Return the server endpoint description."""
        return self.server_endpoint_pattern
 
    def get_client_endpoint(self):
        """Return the client endpoint description."""
        if self.server_factory is None:
            raise ValueError('Server Factory was not provided.')
        if self.listener is None:
            raise ValueError('%s has not started listening.',
                                                          self.server_factory)
        return self.client_endpoint_pattern % self.listener.getHost().port
 
 
class TidyUnixServer(TidySocketServer):
    """A tidy unix domain sockets server."""
 
    client_endpoint_pattern = 'unix:path=%s'
    server_endpoint_pattern = 'unix:%s'
 
    def __init__(self):
        """Create a new instance."""
        super(TidyUnixServer, self).__init__()
        self.temp_dir = tempfile.mkdtemp()
        self.path = os.path.join(self.temp_dir, 'tidy_unix_server')
 
    def get_server_endpoint(self):
        """Return the server endpoint description."""
        return self.server_endpoint_pattern % self.path
 
    def get_client_endpoint(self):
        """Return the client endpoint description."""
        return self.client_endpoint_pattern % self.path
 
    def clean_up(self):
        """Action to be performed for clean up."""
        result = super(TidyUnixServer, self).clean_up()
        # remove the dir once we are disconnected
        result.addCallback(lambda _: shutil.rmtree(self.temp_dir))
        return result
 
 
class ServerTestCase(BaseTestCase):
    """Base test case for tidy servers."""
 
    @defer.inlineCallbacks
    def setUp(self):
        """Set the diff tests."""
        yield super(ServerTestCase, self).setUp()
 
        try:
            self.server_runner = self.get_server()
        except NotImplementedError:
            self.server_runner = None
 
        self.server_factory = None
        self.client_factory = None
        self.server_disconnected = None
        self.client_connected = None
        self.client_disconnected = None
        self.listener = None
        self.connector = None
        self.addCleanup(self.tear_down_server_client)
 
    def get_server(self):
        """Return the server to be used to run the tests."""
        raise NotImplementedError('To be implemented by child classes.')
 
    @defer.inlineCallbacks
    def listen_server(self, server_class, *args, **kwargs):
        """Listen a server.
 
        The method takes the server class and the arguments that should be
        passed to the server constructor.
        """
        self.server_factory = yield self.server_runner.listen_server(
                                                server_class, *args, **kwargs)
        self.server_disconnected = 
                self.server_factory.testserver_on_connection_lost
        self.listener = self.server_runner.listener
 
    @defer.inlineCallbacks
    def connect_client(self, client_class, *args, **kwargs):
        """Connect the client.
 
        The method takes the client factory  class and the arguments that
        should be passed to the client constructor.
        """
        self.client_factory = yield self.server_runner.connect_client(
                                                client_class, *args, **kwargs)
        self.client_disconnected = 
                self.client_factory.testserver_on_connection_lost
        self.connector = self.server_runner.connector
 
    def tear_down_server_client(self):
        """Clean the server and client."""
        if self.server_runner:
            return self.server_runner.clean_up()
 
 
class TCPServerTestCase(ServerTestCase):
    """Test that uses a single twisted server."""
 
    def get_server(self):
        """Return the server to be used to run the tests."""
        return TidyTCPServer()
 
 
class UnixServerTestCase(ServerTestCase):
    """Test that uses a single twisted server."""
 
    def get_server(self):
        """Return the server to be used to run the tests."""
        return TidyUnixServer()
 
 
class PbServerTestCase(ServerTestCase):
    """Test a pb server."""
 
    def get_server(self):
        """Return the server to be used to run the tests."""
        raise NotImplementedError('To be implemented by child classes.')
 
    @defer.inlineCallbacks
    def listen_server(self, *args, **kwargs):
        """Listen a pb server."""
        yield super(PbServerTestCase, self).listen_server(pb.PBServerFactory,
                                                              *args, **kwargs)
 
    @defer.inlineCallbacks
    def connect_client(self, *args, **kwargs):
        """Connect a pb client."""
        yield super(PbServerTestCase, self).connect_client(pb.PBClientFactory,
                                                              *args, **kwargs)
 
 
class TCPPbServerTestCase(PbServerTestCase):
    """Test a pb server over TCP."""
 
    def get_server(self):
        """Return the server to be used to run the tests."""
        return TidyTCPServer()
 
 
class UnixPbServerTestCase(PbServerTestCase):
    """Test a pb server over Unix domain sockets."""
 
    def get_server(self):
        """Return the server to be used to run the tests."""
        return TidyUnixServer()

I wonder if at some point I should share this code for the people out there… any opinions?

Read more
Roberta Nilerud

We’ve just released an updated version of our hugely popular Ubuntu One Files app for Android, making it even better – it’s ready  for download in the Play store now.

Our favorite new addition is that the U1 Files app now supports auto-upload from other photo apps you use. So if you’re into Instagram, the U1 Files app will automatically upload all those cool images to your Ubuntu One personal cloud, making them available on all your devices. We’ve also made sharing a link to Facebook, Twitter and other networks dead easy!

You’ll notice a number of UI improvements across the app, including some functional additions so you have more choice in determining how the U1 Files app performs.

The new settings functionality can help you save power and avoid incurring costly roaming charges.

  • * Auto-upload only when the device is charging
  • * Don’t auto-upload when roaming
  • * Gallery Auto Upload – you can now choose whole galleries to Auto upload
  • * ‘Cancel all uploads’ from the setting menu
  • * Cancelling file downloads from the context menu

Remember Ubuntu One works on Windows, Android, iOS and of course, Ubuntu. Don’t have an account? Sign up for free and get 5GB of cloud storage for all your files, photos and more.

Read more
Roberta Nilerud

A sneak peek of Send to Ubuntu One

Send to Ubuntu One buttonWe wanted to let you know that we are working on a new feature called Send to Ubuntu One. Send to Ubuntu One is a button you can insert on your website and once done, users simply click on it and it instantly delivers the content from your website to their Ubuntu One accounts . Your customers/users won’t have to waste time downloading files to their desktop or mobile, instead when they press ‘Send to Ubuntu One’ it will move the content they want directly to their Ubuntu One account. So when they log in to Ubuntu One the content is there and on all their devices ready to be synced or streamed at their convenience.

This feature is in the very early stages of development right now, but we wanted to give you  a sneak peak and to let you know that it will be coming soon for everyone. If you can’t wait and want early access or to learn more about this first version you can contact us and we will guide you through the implementation process.

Send to Ubuntu One on SCI-FI-LONDON

Other news is that we will also be sponsoring the SCI-FI-LONDON festival this year. SCI-FI-LONDON is an international film festival for sci-fi enthusiasts that runs from 1st-7th of May, in London.

This event coincided perfectly with the first version of Send to Ubuntu One and you can see the first live implementation of the feature used to support SCI-FI-LONDON here.

Read more
Roberta Nilerud

Thanks CES…hello MWC!

Ubuntu and Ubuntu One caused quite a stir at CES in Las Vegas back in January. Ubuntu TV was buzzing and even Walt Mossberg dropped by our stand to check up on our exciting developments.

For Ubuntu One the big story was bringing the convenience of the personal cloud to the connected car. Ubuntu One partnered with Visteon and Delphi, two of the largest companies in the automobile industry, as well as AllGo Systems to introduce prototypes of music streaming from personal cloud to automobiles. Visteon even implemented their prototype on top of Ubuntu Core, a version of Ubuntu designed for embedded devices.

This innovation in connected cars is yet another example of Ubuntu One leading the way in personal cloud services and helping users gain wider access to their personal media.

Our focus now shifts to Ubuntu One opportunities in wireless. From February 27th to the 1st of March we’ll be in Barcelona at Mobile World Congress, situated in Hall 7. Similar to our partnership with leading auto suppliers, we are working with mobile operators and handset manufacturers to further extend the personal cloud into the mobile world. Our recent experience with Vodafone is a first example in this direction.

As more and more consumers get switched on to the convenience of the could, handset manufacturers and wireless carriers are starting to create their own cloud solutions. Ubuntu One can power these efforts with a clear proposition:

1. Avoid creating another service silo – Separate services that are unique to a single device are confusing and frustrating to users. With its mobile apps for accessing files, streaming music and automatically sending photos to the cloud and other devices – Ubuntu One is already a favorite of millions of users.

2. Differrentiate by building your own new, branded features on top of Ubuntu One by using our APIs.

3. Revenue sharing across all Ubuntu One cloud services – Handset makers can earn post-sale revenue and carriers can increase ARPU to offset the costs of enhancing their networks for customers.

If you’re a handset maker or wireless carrier thinking about cloud services, we can help – so feel free to contact us.

Read more