Ubuntu Developer Desktop Survey 2019

It’s clear that a lot of people develop software using Ubuntu. What’s less clear is exactly what sort of software is being built. We see reports of people developing Linux apps, Android apps, web services, self driving cars… the list is huge. We need to get better clarity; to understand how that relates to Ubuntu desktop.

We can get some reasonable insights from the Stack Overflow Developer Survey, but I’m keen to really dig down in to the Ubuntu community specifically.

When I was chatting with Barton George a few weeks back he expressed the same interest; what are people doing with the Sputnik machines from Dell? We want to learn more about the sorts of software projects that you’re working on so that we can make the Ubuntu developer experience as good as possible.

To that end we put together the Ubuntu Developer Desktop Survey to help us understand more about what you’re doing and how you’re doing it. This survey is aimed primarily at people who are using Ubuntu to develop software targeting any platform. It doesn’t matter if you do that at work, at home, at school – if you’re building software then we’re glad to hear from you. To be clear: this doesn’t mean we’re abandoning our mantra of Ubuntu being for human beings, software developers are human beings too. Right now I want to get a better view in to what software developers are doing.

The survey will close on Friday 31st May 2019 and we will publish the results very shortly afterwards. We’ll then follow that up with some further analysis and some ideas as to how this will influence the desktop product roadmap in the future. Please take this opportunity to help shape Ubuntu for the better.

You can find the survey here:

http://desktopdevelopersurvey2019.ubuntu.com/

You don’t need to register or sign in to complete the form.

Ubuntu Desktop goings on. Friday 19th May 2017

Ubuntu Desktop Newsletter

I’m going to start a weekly newsletter style update to keep people abreast of what’s been going on with Ubuntu Desktop as we move to GNOME Shell and build the foundations for 18.04 LTS.  Here’s the first instalment:

Friday 19th May 2017

GNOME

We’re on to the last few MIR (https://wiki.ubuntu.com/MainInclusionProcess) reviews for the packages needed to update the seeds in order to deliver the GNOME desktop by default.
We still have some security questions to answer about how we deal with updates to mozjs/gjs in an LTS release (where mozjs has a support period of 12 months but we need to offer support for a full five years). This is being looked at now, but for 17.10 we are set.
We are aiming to have the seeds updated next week, and this will be the first milestone on the road to a fantastic GNOME experience in 17.10 Artful.

We’ve been fixing bugs in the Ambiance & Radiance themes to make them look crisp on GNOME Shell.
http://www.omgubuntu.co.uk/2017/05/install-improved-ambiance-gnome-theme

We’ve also triaged over 400 GNOME Shell bugs in Launchpad to allow us to more easily focus on the important issues.

We have been working on removing Ubuntu’s custom “aptdaemon” plugin in GNOME Software in favour of the upstream solution which uses PackageKit. This allows us to share more code with other distributions.

LivePatch

https://www.ubuntu.com/server/livepatch

LivePatch delivers essential kernel security updates to Ubuntu machines without having to reboot to apply them. As an Ubuntu user you can sign up for a free account.
We’re working on integrating LivePatch in to the supported LTS desktops to provide a friendly way to setup and configure the service.
This week we started to investigate the APIs provided by the LivePatch services so we can report LivePatch activity to the user, obtain an API key on behalf of the user & set up the service. Work has also started on the software-properties-gtk dialogs (aka Software & Updates in System Settings) to add the options required for LivePatch.

QA

Added upgrade tests from Zesty to Artful for Ubuntu and flavours. Working on making all these tests pass now so that everyone will have a solid and reliable upgrade path.
Work is being done on the installer tests. This will extend the current installer tests to check that not only has the install completed successfully but that all desktop environment is working as expected, this had previously been covered with manual tests.

Package Updates

  • GStreamer is now at 1.12 final in 17.10.
  • Chromium: stable 58.0.3029.110, beta 59.0.3071.47, dev 60.0.3095.5
  • LibreOffice 5.3.3 is being tested.
  • CUPS-filters: 1.14.0
  • Snapd-glib: 1.12

Snaps

More GNOME applications are being packaged as Snaps. There is still some work to do to get them fully confined and fully integrated into the desktop. We’re working on adding Snap support to Gtk’s Portals to allow desktop Snaps to access resources outside their sandbox.
We will start tracking the Snaps here:
https://wiki.ubuntu.com/DesktopTeam/GNOME/Snaps

In the news

Interview with Ken VanDine on the GNOME Desktop in Ubuntu:  http://www.omgubuntu.co.uk/2017/05/ubuntu-switch-to-gnome-questions-answered

There’s also a survey running to get feedback on some extensions which could be shipped with Ubuntu Desktop: http://www.omgubuntu.co.uk/2017/05/ubuntu-desktop-gnome-extensions-survey-1710

This was picked up by the Linux Unplugged podcast as their headline story: http://www.jupiterbroadcasting.com/114701/that-new-user-smell-lup-197/

 

Retrieving user profile data from Login With Amazon on Alexa

In my previous post about How To Add OAUTH to your Alexa app in 10 minutes a couple of people commented that they couldn’t actually access the users information once they had linked their account.  I didn’t actually try and access any of the user information because the only user of my skill is me, and I already know my name and email address.  Nevertheless, I had a quick play with it over the weekend and here’s a simple skill to show you how to access the user’s profile information from a Python skill running in AWS Lambda.

First of all you need to make sure your skill is set up to use Login With Amazon.  I’ve covered this for Smart Home skills here but it works just the same for normal skills.

You also need to make sure your skill is configured to use the scopes “profile” and “postal_code“.  This is done in the Configuration tab in the developer console for your skill:

The Interaction Model for this skill is as follows:

{
  "intents": [
    {
      "intent": "AMAZON.HelpIntent"
    },
    {
      "intent": "AMAZON.CancelIntent"
    },
    {
      "intent": "AMAZON.StopIntent"
    },
    {
      "slots": [
        {
          "name": "Options",
          "type": "Options"
        }
      ],
      "intent": "GreetIntent"
    }
  ]
}

The Custom Slot type “Options” is:

First name
Last name
Post code
email address
user id

And the Sample Utterances are:

GreetIntent Tell me my {Options}
GreetIntent What is my {Options}

And here’s the code (also on GitHub here):

#!/usr/bin/python

import requests

def build_speechlet_response(title, output, reprompt_text, should_end_session):
    return {
        'outputSpeech': {
            'type': 'PlainText',
            'text': output
        },
        'card': {
            'type': 'Simple',
            'title': "Greeter",
            'content': output
        },
        'reprompt': {
            'outputSpeech': {
                'type': 'PlainText',
                'text': reprompt_text
            }
        },
        'shouldEndSession': should_end_session
    }


def build_response(session_attributes, speechlet_response):
    return {
        'version': '1.0',
        'sessionAttributes': session_attributes,
        'response': speechlet_response
    }
    

def get_user_info(access_token):
    #print access_token
    amazonProfileURL = 'https://api.amazon.com/user/profile?access_token='
    r = requests.get(url=amazonProfileURL+access_token)
    if r.status_code == 200:
        return r.json()
    else:
        return False

def handle_end():
    return build_response({}, build_speechlet_response("Session ended", "Goodbye!", "", True))

def launch_request(access_token):
    session_attributes = {}
    card_title = "Welcome"
    if access_token is None:
        speech_output = "Your user details are not available at this time.  Have you completed account linking via the Alexa app?"
        reprompt_text = ""
        should_end_session = True
    else:
        user_details = get_user_info(access_token)
        if user_details is None:
            speech_output = "There was a problem getting your user details."
            should_end_sesion = True
        else:
            print user_details
            speech_output = "Hello "+user_details['name'].split(" ")[0]+"!  I know all about you now.  We can be friends!"
            reprompt_text = "What can I tell you about your user information?  First name, last name, email address or postcode?"
            should_end_session = False
    return build_response(session_attributes, build_speechlet_response(
        card_title, speech_output, reprompt_text, should_end_session))

def intent_request(intent_request, access_token):
    intent = intent_request['intent']
    intent_name = intent['name']
    
    if intent_name == "GreetIntent":           
        if access_token is not None:
            user_details = get_user_info(access_token)
            if user_details is None:
                query_type = False
            else:
                query_type = intent['slots']['Options']['value']
        else:
            return handle_end()
        
        if query_type == "post code":
            speech_output = "Your post code is "+user_details['postal_code']+"."
        elif query_type == "first name":
            speech_output = "Your first name is "+user_details['name'].split(" ")[0]+"."
        elif query_type == "last name":
            speech_output = "Your last name is "+user_details['name'].split(" ")[1]+"."
        elif query_type == "email address":
            speech_output = "Your email address is "+user_details['email']+"."
        elif query_type == "user id":
            speech_output = "Your user id is "+user_details['user_id']+"."
        else:
            speech_output = "Something went wrong.  Goodbye."
        card_title = "What I know about you"
        return build_response({}, build_speechlet_response(card_title, speech_output, None, True))
        
    if intent_name == "AMAZON.HelpIntent":
        print "Help intent"
        card_title = "No help available!"
        speech_output = "Sorry, I can't help you."
        return build_response({}, build_speechlet_response(card_title, speech_output, None, True))
        
    if intent_name == "AMAZON.CancelIntent" or intent_name == "AMAZON.StopIntent":
        card_title = "Session Ended"
        speech_output = "Good bye!"
        return build_response({}, build_speechlet_response(card_title, speech_output, None, True))
    


def lambda_handler(event, context):
    print event
    try:
        access_token = event['context']['System']['user']['accessToken']
    except:
        access_token = None
    if event['request']['type'] == "LaunchRequest":
        return launch_request(access_token)
    elif event['request']['type'] == "IntentRequest":
        return intent_request(event['request'],access_token)

The important part is:

event['context']['System']['user']['accessToken']

Once that is available to your Lambda script then you know that the user has done the OAUTH account linking, and then you can query the Amazon APIs for the user’s info.

I’m not proud of this code, so I will tidy it up in to a better demo at some point and update this post accordingly.

Here’s a quick video of what it does: