Canonical Voices

UbuntuTouch

在这篇文章中,我们来介绍如何判断一个QML应用被推到后台或前台。我们知道,在Ubuntu手机平台中,它是一个单应用的操作系统。当一个应用被推到后台后,应用就被挂起,不能运行。我们有时需要这个标志来判断我们的应用什么时候是在前台,什么时候是在后台。


我们用Ubuntu SDK创建一个简单的QML应用:


import QtQuick 2.0
import Ubuntu.Components 1.1

/*!
    \brief MainView with a Label and Button elements.
*/

MainView {
    id: main
    // objectName for functional testing purposes (autopilot-qt5)
    objectName: "mainView"

    // Note! applicationName needs to match the "name" field of the click manifest
    applicationName: "com.ubuntu.developer.liu-xiao-guo.foregrounddetect"

    /*
     This property enables the application to change orientation
     when the device is rotated. The default is false.
    */
    //automaticOrientation: true

    // Removes the old toolbar and enables new features of the new header.
    useDeprecatedToolbar: false

    width: units.gu(100)
    height: units.gu(75)


    Page {
        title: i18n.tr("ForegroundDetect")

        Connections {
             target: Qt.application
             onActiveChanged: {
                 console.log("Qt.application.active: " + Qt.application.active);
             }
         }
    }
}

在这里,我们使用Qt.application这个变量的"active"属性来判断一个应用是否被推到后台或前台。我们运行应用结果如下:




当我们在手机上把应用推到后台时,就会显示false;当我们把应用推到前台时,就会显示true。

整个应用的源码在:bzr branch lp:~liu-xiao-guo/debiantrial/foregrounddetect


作者:UbuntuTouch 发表于2015-1-5 10:56:25 原文链接
阅读:215 评论:0 查看评论

Read more
UbuntuTouch

在这个视频里,我们从“0”开始来开发一个mini的RSS阅读器。通过这个练习,开发者可以对QML的编程有一个基本的了解,并了解在Ubuntu平台上的一些开发的流程。应用的图片如下:


  



作者:UbuntuTouch 发表于2015-1-13 15:08:31 原文链接
阅读:146 评论:0 查看评论

Read more
UbuntuTouch

[原]如何制作Ubuntu SDK Live USB盘

对于一些想开发Ubuntu手机应用或Scope的开发者来说,不想重新买一个电脑安装Ubuntu操作系统或在自己的硬盘上重新安装一个Ubuntu系统,那么可以考虑制作一个Ubuntu系统的Live USB盘。这个USB包括如下的部分:


  • Ubuntu Kylin 14.10操作系统
  • Ubuntu SDK (包括已经安装好的SDK,模拟器及编译环境)

使用这个Live USB盘,开发者就不用安装任何的东西,直接插入电脑的USB口中。在电脑启动的过程中,选择我们制作好的USB启动盘进行启动(在电脑启动的过程中,按下“F12”键)。在启动的过程中选择“Try Ubuntu Kylin without installing




虽然这是一个Ubuntu OS的启动盘,但是它可以保存我们在开发过程中所创建的项目(存于Home目录中)及一些设置(比如wifi设置密码等)。


当我们选择USB时,我们最好是选择USB 3.0并把USB盘放入到电脑USB 3.0的口中。一般来说,电脑上的USB 3.0口是用蓝色标示的。建议使用质量较好,速度较快一点的USB这样可以使得系统的启动和运行更快更流畅。目前我们使用SanDisk CZ80来做测试,效果还是不错的。USB需要有16G的存储。


为了使得我们的模拟器能够更加流畅及模拟器不会出现黑色的屏幕,我们需要在电脑的BIOS里启动硬件虚拟化功能。开发者需要到自己的电脑的BIOS里的设置启动VT-X/AMD-V。开发者可以参考文章“Ubuntu SDK 安装”来检查自己的电脑是否支持virtualization。




如果开发者想要在自己的电脑上安装Ubuntu系统并在上面开发的话,可以参考文章“Ubuntu SDK 安装”来一步一步地安装Ubuntu SDK。



1)如何在Ubuntu系统下制作Live USB盘


启动Ubuntu操作系统,打开浏览器并在如下的地址下载最新的image:


https://mega.co.nz/#F!S8QSRZyI!2HBWgXk4kmc_2bcCcpBR3Q


下载的文件包含:

  • kylin-live-20150133.iso (md5sum 13cd61270bf98eb462dc0497df8eee33) 
  • casper-rw-20150113.tar.bz2  (md5sum 8c69f94a03481275bf66aa883b69ae1b)
  • post-usb-creator-window.sh(在Windows下制作需要这个)
  • README.md (简单的说明文件)

我们把下载的文件存于到我们想要的一个目录中,比如在自己的Home下的“usb”目录中。


在Dash中输入“usb”,并启动“Startup Disk Creator/启动盘创建器”






我们按照如下的方法来制作我们的USB启动盘。





在设置“储存在额外保留空间”时,它的值应该为非零的值。等USB盘已经制作好以后,你将会看到如下的画面:







重新挂载USB盘,因为在前一步会自动卸载USB盘,或者在Ubuntu中的文件浏览器中点击USB所在的device。这样就可以完成重新挂载USB:





然后按下面运行自带的脚本,参数为 USB 盘挂载的路径。


解压已经下载的casper-rw-2015xxxx.tar.bz2文件


等文件都被解压完后,进入解压文件所在的目录,并在shell中执行如下的指令:


liuxg@liuxg:~/usb$ ./post-usb-creator-linux.sh /media/liuxg/BD52-7153/


这里“/liuxg/BD52-7153”为USB盘挂载的路径。根据自己USB盘所在的路径替换。


2)如何在Windows 平台下制作启动盘


http://www.ubuntu.com/download/desktop/create-a-usb-stick-on-windows

下载制作工具,与 Linux 平台的工具相似。




单我们在选择“Persistent file”时,它的大小应该是非零的一个值。在我们填入“Step 2”时,我们不应该把拷贝好的字符串拷到该输入框中,否则在“Step 3”中的输入框就会是灰色的。我们应该点击“Browse”按钮,并按照如下的方式进行输入image的路径:




在这之后把 casper-rw 文件拷贝到USB的主目录下即可。


:如果只想使用英文版的Ubuntu系统就不需要进行下面的步骤。如果想要支持中文版,请把 post-usb-creator-window.sh 也拷贝到 USB盘的根目录下。从USB 盘启动Ubuntu系统后,在shell中执行如下的指令:


$ cd /cdrom/

$ sudo ./post-usb-creator-window.sh


再次重新启动后,会进入中文版的Ubuntu系统。


3)测试已经制作好的USB启动盘


我们可以把我们的Live USB盘插入电脑,我们可以通文章“创建第一个Ubuntu for phone应用”来检验我们是否有一个完好的Ubuntu SDK。


在我们启动模拟器时,如果需要输入密码,请使用默认的密码“0000”。如果开发者需要自己修改这个密码,请到Ubuntu SDK模拟器中的“系统设置”中去修改。


对于应用开发者来说,在Qt Creator中的热键组合“Ctrl + Space”键有它独特的用处。可是,在Ubuntu系统中,“Ctrl + Space”被用来转换中英文输入法。建议开发者参考文章“怎么在Ubuntu OS上面安装搜狗输入法及对Qt Creator的支持”来重新定义键的组合。


已知问题 (known issues)

如果你在使用的过程中,发现有如下的乱码的情况(极少情况下出现),请重新启动你的机器来纠正这个问题。




在个别电脑上不能启动的问题


我们发现在联想 E455 出现不能启动的问题,目前怀疑是和 AMD 显卡驱动有关,问题仍在调查中,如果遇到些问题,请在系统上安装14.04 LTS版本并安装相应的ubuntu-sdk包来尝试学习ubuntu phone的开发知识,其中的基本概念都是一样。


注:如果想长时间致力于ubuntu phone的开发建议在电脑上安装一个ubuntu系统,最好是utopic (14.10),而不是在Live环境下进行学习,一是以防数据的丢失,二是在使用性能上有更快速的体验。



作者:UbuntuTouch 发表于2015-1-22 15:35:55 原文链接
阅读:182 评论:0 查看评论

Read more
Colin Ian King

During idle moments in the final few weeks of 2014 I have been adding some more stressors and features to stress-ng as well as tidying up the code and fixing some small bugs that have crept in during the last development spin.   Stress-ng aims to stress a machine with various simple torture tests to trip overheating and kernel race conditions.

The mmap stressor now has the '--mmap-file' to use synchronous file backed memory mapping instead of the default anonymous mapping, and the '--mmap-async' option enables asynchronous file mapping if desired.

For socket stressing, the '--sock-domain unix' option now allows AF_UNIX (aka AF_LOCAL) sockets to be used. This compliments the existing AF_INET and AF_INET6 IPv4 and IPv6 protocols available with this stress test.

The CPU stressor now includes mixed integer and floating point stressors, covering 32 and 64 bit integer mixes with the float, double and long double floating point types. The generated object code contains a nice mix of operations which should exercise various functional units in the CPU.  For example, when running on a hyper-threaded CPU one notices a performance hit because these cpu stressor methods heavily contend on the CPU math functional blocks.

File based locking has been extended with the new lockf stressor, this stresses multiple locking and unlocking on portions of a small file and the default blocking mode can be turned into a CPU consuming rapid polling retry with the '--lockf-nonblock' option.

The dup(2) system call is also now stressed with the new dup stressor. This just repeatedly dup's a file opened on /dev/zero until all the free file slots are full, and then closes these. It is very much like the open stressors.

The fcntl(2) F_SETLEASE command is stress tested with the new lease stressor. This has a parent process that rapidly locks and unlocks a file based lease and 1 or more child processes try to open this file and cause lease breaking signal notifications to the parent.

For x86 CPUs, the cache stressor includes two new cache specific options. The '--cache-fence' option forces write serialization on each store operation, while the '--cache-flush' option forces flush cache on each store operation. The code has been specifically written to not incur any overhead if these options are not enabled or are not available on non-x86 CPUs.

This release also includes the stress-ng project mascot too; a humble CPU being tortured and stressed by a rather angry flame.

For more information, visit the stress-ng project page, or check out the stress-ng manual.

Read more
UbuntuTouch

在这个视频里介绍了Ubuntu OS上的online account探讨。online account可以应用于Web,QML及Scope的开发。更多介绍请参阅developer.ubuntu.com


http://v.youku.com/v_show/id_XODU0Njk4MTA4.html

作者:UbuntuTouch 发表于2014-12-25 9:40:46 原文链接
阅读:331 评论:0 查看评论

Read more
UbuntuTouch

在这篇文章中,我们将介绍如何开发一个快递邮件查询的Scope。我们知道Scope很方便地把我们Web上的服务快速地集成到我们的系统中,并使之成为我们用户体验的一部分。我在先前的文章中重点介绍了如何使用点评Scope的开发,也介绍了中国天气的Scope的开。在这篇文章中,我们将从另外一个角度介绍一个新的Scope的开发。这个Scope和先前的使用的架构是不同的。它的department是从一个本地的文件中读出来的。希望对大家的开发有帮助。我们的最终Scope的显示如下:


     


1)创建一个最基本的Scope

在这个章节里,我们来创建一个最基本的Scope。大家一起来跟着我的步骤一步一步地来:



  






在这个例子里,我们选择使用的是“Empty Scope”。这样我们不必要去删除很多的文件。我们在Desktop上运行一下我们刚刚创建的Scope。没有什么是特殊的。我们使用能够热键Ctrl + R或SDK左下角的绿色的运行按钮,运行Scope:



如果你运行你的Scope,并看见如上图所示的画面,请按照如下的画面来重新设置你的configuration。




这是一个最基本的Scope,没有任何特殊的东西,因为这是个非常简单的Empty Scope。




2)加入Qt支持


由于“Empty Scope”模版对Qt没有进行支持。在这个章节里,我们教大家怎么把Qt加入到项目中。我们希望在项目中使用Qt来解析我们得到的数据。我们在项目中加入对Qt的支持。我们首先打开在“src”中的CMakeLists.txt文件,并加入如下的句子:

find_package(Qt5Core REQUIRED)     
find_package(Qt5Xml REQUIRED)      

include_directories(${Qt5Core_INCLUDE_DIRS})   
include_directories(${Qt5Network_INCLUDE_DIRS})

....

# Build a shared library containing our scope code.
# This will be the actual plugin that is loaded.
add_library(
  scope SHARED
  $<TARGET_OBJECTS:scope-static>
)

qt5_use_modules(scope Core Network) 

# Link against the object library and our external library dependencies
target_link_libraries(
  scope
  ${SCOPE_LDFLAGS}
  ${Boost_LIBRARIES}
)

)

我们可以看到,我们加入了对Qt Core库的调用。同时,我们也打开"tests/unit/CMakeLists.txt"文件,并加入“qt5_use_modules(scope-unit-tests Core Network)"


# Our test executable.
# It includes the object code from the scope
add_executable(
  scope-unit-tests
  scope/test-scope.cpp
  $<TARGET_OBJECTS:scope-static>
)

# Link against the scope, and all of our test lib dependencies
target_link_libraries(
  scope-unit-tests
  ${GTEST_BOTH_LIBRARIES}
  ${GMOCK_LIBRARIES}
  ${SCOPE_LDFLAGS}
  ${TEST_LDFLAGS}
  ${Boost_LIBRARIES}
)

qt5_use_modules(scope-unit-tests Core Network)

# Register the test with CTest
add_test(
  scope-unit-tests
  scope-unit-tests
)

我们再重新编译我们的应用,如果我们没有错误的话,我们的Scope可以直接在desktop下直接运行。这样我们就完成了我们项目对Qt的支持。

3)快件查询API

我们可以在网址:http://www.kuaidi100.com/提供的服务来查询我们的快件。我们将使用如下的API来查询我们的快件的信息:

http://www.kuaidi100.com/query?type=shunfeng&postid=592833849048

这里type可以是任何其它的公司。postid是快件的单号。我们在这里也分别列出其它的快件公司的查询API接口:

[
    {
        "title": "顺丰",
	"pinyin": "shunfeng",
        "url": "http://www.kuaidi100.com/query?type=shunfeng&postid=%1"
    },
    {
        "title": "全峰",
	"pinyin": "quanfeng",
        "url": "http://www.kuaidi100.com/query?type=quanfengkuaidi&postid=%1"
    },
    {
        "title": "申通",
	"pinyin": "shentong",
        "url": "http://www.kuaidi100.com/query?type=shentong&postid=%1"
    },
    {
        "title": "EMS",
	"pinyin": "ems",
        "url": "http://www.kuaidi100.com/query?type=ems&postid=%1"
    },
    {
        "title": "圆通",
	"pinyin": "yuantong",
        "url": "http://www.kuaidi100.com/query?type=yuantong&postid=%1"
    },
    {
        "title": "中通",
	"pinyin": "zhongtong",
        "url": "http://www.kuaidi100.com/query?type=zhongtong&postid=%1"
    },
    {
        "title": "韵达",
	"pinyin": "yunda",
        "url": "http://www.kuaidi100.com/query?type=yunda&postid=%1"
    },
    {
        "title": "天天",
	"pinyin": "tiantian",
        "url": "http://www.kuaidi100.com/query?type=tiantian&postid=%1"
    },
    {
        "title": "汇通",
	"pinyin": "huitong",
        "url": "http://www.kuaidi100.com/query?type=huitongkuaidi&postid=%1"
    },
    {
        "title": "德邦",
	"pinyin": "debang",
        "url": "http://www.kuaidi100.com/query?type=debangwuliu&postid=%1"
    },
    {
        "title": "宅急送",
 	"pinyin": "zhaijisong",
       	"url": "http://www.kuaidi100.com/query?type=zhaijisong&postid=%1"
    }
]

这里我们使用了一个json结构的文件“departments.json”来存储这些信息,并把这个文件存于项目的“data”目录下。这里的“pinyin”项将被用作Scope中的department id。就像我们在这篇文章一开始的位置显示的那样,我们想把该Scope设计为一个department Scope。这样我们可以对所有的快递公司进行查询。我们可以对我们的一个实验性的API进行展示如下:

{"nu":"592833849048","companytype":"shunfeng","com":"shunfeng","updatetime":"2014-12-23 18:13:16","signname":"","condition":"F00","status":"200","codenumber":"592833849048","signedtime":"","data":[{"time":"2014-11-29 13:19:43","location":"","context":"已签收,感谢使用顺丰,期待再次为您服务","ftime":"2014-11-29 13:19:43"},{"time":"2014-11-29 13:19:43","location":"","context":"在官网\"运单资料&签收图\", 可查看签收人信息","ftime":"2014-11-29 13:19:43"},{"time":"2014-11-29 11:14:23","location":"","context":"正在派送途中,请您准备签收(派件人:孙连杰,电话:13810320784)","ftime":"2014-11-29 11:14:23"},{"time":"2014-11-29 10:00:30","location":"","context":"快件到达 北京北苑集散中心","ftime":"2014-11-29 10:00:30"},{"time":"2014-11-29 08:45:55","location":"","context":"快件在 北京顺义集散中心, 正转运至 北京北苑集散中心","ftime":"2014-11-29 08:45:55"},{"time":"2014-11-29 06:29:29","location":"","context":"快件在 北京集散中心, 正转运至 北京顺义集散中心","ftime":"2014-11-29 06:29:29"},{"time":"2014-11-28 20:46:26","location":"","context":"快件在 厦门总集散中心, 正转运至 北京集散中心","ftime":"2014-11-28 20:46:26"},{"time":"2014-11-28 19:32:18","location":"","context":"快件在 厦门集美集散中心, 正转运至 厦门总集散中心","ftime":"2014-11-28 19:32:18"},{"time":"2014-11-28 17:26:37","location":"厦门莲岳服务点","context":"[厦门莲岳服务点]快件在 厦门莲岳服务点, 正转运至 厦门集美集散中心","ftime":"2014-11-28 17:26:37"}],"state":"3","departure":"厦门市","addressee":"","destination":"北京市","message":"ok","ischeck":"1","pickuptime":""}

在下面的章节中,我们将介绍如何使用这个API来对内容在Scope中进行显示。

为了在下面的练习中能够更加好地完成,我们可以在如下的地址下载


下载“images”,“renderer”目录及“departments.json”文件,并放到项目中的“data”目录中。为了能够在Desktop上进行运行,我们也创建了如下的script文件“setup.sh”,并把该文件置于项目的根目录中:

#!/bin/bash

if [ $# -eq 0 ]; then
    DEST="../build-mailcheck-Desktop-Default/src/"

    mkdir -p $DEST
    cp -r data/departments.json $DEST/
    cp -r data/renderer $DEST/
    cp -r data/images $DEST/
    
    echo "Setup complete."
    exit 0;
fi

我们在我们项目的目录下打入如下的命令:



这样做的目的是把我们所需要在Desktop下运行所需要的文件拷到相应的目录中,以便我们在下面的程序中用到。通过这样的方法,我们把我们所需要的文件拷贝到如下的目录中以便我们在如下的练习中使用到。




重新运行编译我们的Scope以确保我们没有任何的错误。整个项目的源码在如下的地址:

bzr branch lp:~liu-xiao-guo/debiantrial/mailcheck1


4)为Scope加入department

在这个章节中,我们准备为我们的Scope加入所需要的department。



我们知道我们所需要的department信息存在于一个叫做“deparments.json”的文件中。我们需要得到Scope的路径才可以得到这个文件。我们对scope.cpp做如下的修改:

sc::SearchQueryBase::UPtr Scope::search(const sc::CannedQuery &query,
                                        const sc::SearchMetadata &metadata) {
    const QString scopePath = QString::fromStdString(scope_directory());
    // Boilerplate construction of Query
    return sc::SearchQueryBase::UPtr(new Query(query, metadata, scopePath, config_));
}

通过得到的scopePath,我们把它传入到query.cpp中以便使用。记得在scope.cpp中加入

#include <QString>

以使得项目可以得到编译。

我们也对query.cpp要做相应的修改:

   Query(const unity::scopes::CannedQuery &query,
          const unity::scopes::SearchMetadata &metadata,  QString scopePath,
          api::Config::Ptr config);


我们在query.cpp中也存储了一些相应的全局变量来保存我们的状态:

QString g_scopePath;
QString g_rootDepartmentId;
QMap<QString, std::string> g_renders;
QString g_userAgent;
QString g_imageDefault;
QString g_imageError;
QMap<QString, QString> g_depts;
QString g_curScopeId;
static QMap<QString, QString> g_deptLayouts;

我们的Query类的构造函数如下:

#define LOAD_RENDERER(which) g_renders.insert(which, getRenderer(g_scopePath, which))

Query::Query( const sc::CannedQuery &query, const sc::SearchMetadata &metadata,
             QString scopePath, Config::Ptr config ) :
    sc::SearchQueryBase( query, metadata ), client_( config ) {
    g_scopePath = scopePath;
    g_userAgent = QString("%1 (Ubuntu)").arg(SCOPE_PACKAGE);
    g_imageDefault = QString("file://%1/images/%2").arg(scopePath).arg(IMG_DEFAULT);
    g_imageError = QString("file://%1/images/%2").arg(scopePath).arg(IMG_ERROR);

    // Load all of the predefined rederers. You can comment out the renderers
    // you don't use.
    LOAD_RENDERER( "journal" );
    LOAD_RENDERER( "wide-art" );
    LOAD_RENDERER( "hgrid" );
    LOAD_RENDERER( "carousel" );
    LOAD_RENDERER( "large" );
}

std::string Query::getRenderer( QString scopePath, QString name ) {
    QString renderer = readFile( QString("%1/renderer/%2.json" )
                                .arg(scopePath).arg(name));
    return renderer.toStdString();
}

QString Query::readFile(QString path) {
    QFile file(path);
    file.open(QIODevice::ReadOnly | QIODevice::Text);
    QString data = file.readAll();
    // qDebug() << "JSON file: " << data;
    file.close();
    return data;
}

我们通过如下的方法来解析“departments.json",并把“pinyin”项作为department id以便以后进行查询。虽然deparment id可以为任何一个字符串,只要保证它们之间是互相不同的。我们把得到的url数据存于一个叫做g_depts的全局变量中。

DepartmentList Query::getDepartments(QJsonArray data) {
    qDebug() << "entering getDepartments";

    DepartmentList depts;

    // Clear the previous departments since the URL may change according to settings
    g_depts.clear();
    qDebug() << "m_depts is being cleared....!";

    int index = 0;
    FOREACH_JSON( json, data ) {
        auto feed = (*json).toObject();
        QString title = feed["title"].toString();
//        qDebug() << "title: " << title;

        QString url = feed["url"].toString();
//        qDebug() << "url: " << url;

        QString pinyin = feed["pinyin"].toString();
//        qDebug() << "pinyin: " << pinyin;

        // This is the default layout otherwise it is defined in the json file
        QString layout = SURFACING_LAYOUT;

        if ( feed.contains( "layout" ) ) {
            layout = feed[ "layout" ].toString();
        }

        g_depts.insert( pinyin, url );
        g_deptLayouts.insert( pinyin, layout );

        CannedQuery query( SCOPENAME.toStdString() );
        query.set_department_id( url.toStdString() );
        query.set_query_string( url.toStdString() );

        Department::SPtr dept( Department::create(
                               pinyin.toStdString(), query, title.toStdString() ) );

        depts.push_back(dept);

        index++;
    }

    // Dump the departments. The map has been sorted out
    QMapIterator<QString, QString> i(g_depts);
    while (i.hasNext()) {
        i.next();
        qDebug() << "scope id: " << i.key() << ": " << i.value();
    }

    qDebug() << "Going to dump tthe department layouts";

    QMapIterator<QString, QString> j( g_deptLayouts );
    while (j.hasNext()) {
        j.next();
        qDebug() << "scope id: " << j.key() << ": " << j.value();
    }

    return depts;
}

为了能够使得我们的Scope能在手机或emulator上运行,我们还得对“data”目录下的“CMakeLists.txt”做如下的修改:

# Install the scope ini file
install(
  FILES "com.ubuntu.developer.liu-xiao-guo.mailcheck_mailcheck.ini"
  DESTINATION ${SCOPE_INSTALL_DIR}
)

# Install the scope images
install(
  FILES
    "icon.png"
    "logo.png"
    "screenshot.png"
    "departments.json"
  DESTINATION
    "${SCOPE_INSTALL_DIR}"
)

INSTALL(
    DIRECTORY "images"
    DESTINATION ${SCOPE_INSTALL_DIR}
)

INSTALL(
    DIRECTORY "renderer"
    DESTINATION ${SCOPE_INSTALL_DIR}
)

这样把“departments.json”,“images”及“render”都加入到项目中。

最终我们的结果如下:

   

我们可以看到我们的deparment了。所有的源码在如下的地址:

bzr branch lp:~liu-xiao-guo/debiantrial/mailcheck2


5)完成surfacing及查询

上面我们已经产生了department列表,但是,我们还是不能使用它或查询到什么结果。下面我们添加如下的Search方法来得到查询的结果:

void Query::search(sc::SearchReplyProxy const& reply) {
    CategoryRenderer renderer(g_renders.value("journal", ""));
    auto search = reply->register_category(
                "search", RESULTS.toStdString(), "", renderer);

    CannedQuery cannedQuery = SearchQueryBase::query();

    QString deptId = QString::fromStdString(cannedQuery.department_id());
    qDebug() << "deptId: " << deptId;

    qDebug() << "m_rootDepartmentId: " << g_rootDepartmentId;
    QString url;

    qDebug() << "m_curScopeId: " << g_curScopeId;

    if ( !deptId.isEmpty() ) {
        g_curScopeId = deptId;
    }

    if ( deptId.isEmpty() && !g_rootDepartmentId.isEmpty()
         && g_curScopeId == g_rootDepartmentId ) {

        QMapIterator<QString, QString> i(g_depts);
        qDebug() << "m_depts count: "  << g_depts.count();

        qDebug() << "Going to set the surfacing content";

        const CannedQuery &query(sc::SearchQueryBase::query());
        // Trim the query string of whitespace
        string query_string = alg::trim_copy(query.query_string());
        QString queryString = QString::fromStdString(query_string);

        if ( queryString.isEmpty()) {
            url = QString(g_depts[g_rootDepartmentId]).arg(592833849048);
        } else {
            url = QString(g_depts[g_rootDepartmentId]).arg(queryString);
        }
    } else {
        QString queryString = QString::fromStdString(cannedQuery.query_string());
        qDebug() << "queryString: " << queryString;

        // Dump the departments. The map has been sorted out
        QMapIterator<QString, QString> i(g_depts);
        qDebug() << "m_depts count: "  << g_depts.count();

        while (i.hasNext()) {
            i.next();
            qDebug() << "scope id: " << i.key() << ": " << i.value();
        }

        url = g_depts[g_curScopeId].arg(queryString);
    }

    qDebug() << "url: "  << url;
    qDebug() << "m_curScopeId: " << g_curScopeId;

    try {
        QByteArray data = get(reply, QUrl(url));
        getMailInfo(data, reply);
    } catch (domain_error &e ) {
        cerr << e.what() << endl;
        reply->error(current_exception());
    }
}

void Query::getMailInfo(QByteArray &data, SearchReplyProxy const& reply) {
    QJsonParseError e;
    QJsonDocument document = QJsonDocument::fromJson(data, &e);
    if (e.error != QJsonParseError::NoError) {
        throw QString("Failed to parse response: %1").arg(e.errorString());
    }

    // This creates a big picture on the top
    CategoryRenderer rssCAR(CAR_GRID);
    auto catCARR = reply->register_category("A", "", "", rssCAR);
    CategorisedResult res_car(catCARR);
    res_car.set_uri("frontPage");
    QString defaultImage1 ="file://"+ g_scopePath + "/images/" + g_curScopeId + ".jpg";
    qDebug() << "defaultImage1: "  << defaultImage1;
    res_car["largepic"] = defaultImage1.toStdString();
    res_car["art2"] =  res_car["largepic"];
    reply->push(res_car);

    QJsonObject obj = document.object();

    qDebug() << "***********************\r\n";

    if ( obj.contains("data") ) {
        qDebug() << "it has data!";

        QJsonValue data1 = obj.value("data");

        QJsonArray results = data1.toArray();

        qDebug() << "g_curScopeId: " << g_curScopeId;
        QString layout = g_deptLayouts.value( g_curScopeId );
        std::string renderTemplate;

        if (g_renders.contains( layout )) {
            qDebug() << "it has layout: " << layout;
            renderTemplate = g_renders.value( layout, "" );
            // qDebug() << "renderTemplate: " << QString::fromStdString(renderTemplate);
        }
        else {
            qDebug() << "it does not have layout!";
            renderTemplate = g_renders.value( "journal" );
            // qDebug() << "renderTemplate: " << QString::fromStdString(renderTemplate);
        }

        CategoryRenderer grid(renderTemplate);
        std::string categoryId = "root";
        std::string categoryTitle = " "; // #1330899 workaround
        std::string icon = "";
        auto tracking = reply->register_category(categoryId, categoryTitle, icon, grid);

        FOREACH_JSON(result, results) {
            QJsonObject o = (*result).toObject();

            QString time = o.value("time").toString();
//            qDebug() << "time: " << time;

            QString context = o.value("context").toString();
//            qDebug() << "context: " << context;

            QString link = "http://www.kuaidi100.com/";
            QString defaultImage ="file://"+ g_scopePath + "/images/" + g_curScopeId + ".jpg";

            CategorisedResult result(tracking);

            SET_RESULT("uri", link);
            SET_RESULT("image", defaultImage);
            //            SET_RESULT("video", video);
            SET_RESULT("title", time);
            //            SET_RESULT("subtitle", context);
            SET_RESULT("summary", context);
            //            SET_RESULT("full_summary", fullSummary);
            //            result["actions"] = actions.end();

            if (!reply->push(result)) break;
        }
    }
}

QByteArray Query::get(sc::SearchReplyProxy const& reply, QUrl url) const {
    QNetworkRequest request(url);
    QByteArray data = makeRequest(reply, request);
    return data;
}

“Search”在“run”方法中被调用:

void Query::run(sc::SearchReplyProxy const& reply) {
    try {
        // Start by getting information about the query
        const CannedQuery &query(sc::SearchQueryBase::query());

        // Trim the query string of whitespace
        string query_string = alg::trim_copy(query.query_string());
        QString queryString = QString::fromStdString(query_string);

        qDebug() << "queryString: " << queryString;

        // Only push the departments when the query string is null
        if ( queryString.length() == 0 ) {
            qDebug() << "it is going to push the departments...!";
            pushDepartments( reply );
        }

        search(reply);

    } catch ( domain_error &e ) {
        // Handle exceptions being thrown by the client API
        cerr << e.what() << endl;
        reply->error( current_exception() );
    }
}

我们通过如下的方式向网路发出一个请求:

QByteArray Query::makeRequest(SearchReplyProxy const& reply,QNetworkRequest &request) const {
    int argc = 1;
    char *argv = const_cast<char*>("rss-scope");
    QCoreApplication *app = new QCoreApplication( argc, &argv );

    QNetworkAccessManager manager;
    QByteArray response;
    QNetworkDiskCache *cache = new QNetworkDiskCache();
    QString cachePath = g_scopePath + "/cache";
    //qDebug() << "Cache dir: " << cachePath;
    cache->setCacheDirectory(cachePath);

    request.setRawHeader( "User-Agent", g_userAgent.toStdString().c_str() );
    request.setRawHeader( "Content-Type", "application/rss+xml, text/xml" );
    request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );

    QObject::connect(&manager, SIGNAL(finished(QNetworkReply*)), app, SLOT(quit()));
    QObject::connect(&manager, &QNetworkAccessManager::finished,
                     [this, &reply, &response](QNetworkReply *msg) {
        if (msg->error() != QNetworkReply::NoError) {
            qCritical() << "Failed to get data: " << msg->error();
            pushError( reply, NO_CONNECTION );
        } else {
            response = msg->readAll();
        }

        msg->deleteLater();
    });

    manager.setCache( cache );
    manager.get( request );
    app->exec();

    delete cache;
    return response;
}

这个请求得到的数据将被“getMailInfo”使用并解析。最终被展示出来。我们希望对用户所输入的数据有所提示,所以我们对.ini文件做了如下的修改:

[ScopeConfig]
DisplayName = 快递查询
Description = This is a Mailcheck scope
Art = screenshot.png
Author = Firstname Lastname
Icon = icon.png
SearchHint = 请输入单号

[Appearance]
PageHeader.Logo = logo.png

这里的“SearchHint”显示的是提示的信息。

另外一个值得注意的是:当我们点击Scope中的每一项时,我们发现没有相应的Preview页面。这是通过修改“renderer”目录下的文件实现的,尽管在Desktop上是可以看到preview页面的。

{
    "schema-version": 1,
    "template": {
        "category-layout": "vertical-journal",
        "card-layout": "horizontal",
        "card-size": "medium",
        "collapsed-rows": 0,
	"non-interactive":"true"
    },
    "components": {
        "art": "image",
        "title": "title",
        "subtitle": "subtitle",
        "summary": "summary"
    }
}

我可以打开“data/render”目录下的“journal.json”。我们看见上面的“non-interactive”项被置为“true”。这项表明它不希望有交互。

所有项目的源码在如下的地址可以找到:


bzr branch lp:~liu-xiao-guo/debiantrial/mailcheckfinal

或在地址:git clone https://gitcafe.com/ubuntu/mailcheck.git


作者:UbuntuTouch 发表于2014-12-23 16:07:06 原文链接
阅读:208 评论:0 查看评论

Read more
UbuntuTouch

[原]如何使用Ubuntu手机

在这个视频里,我们介绍了如何使用Ubuntu手机。Ubuntu手机对很多的使用者来说还不是很熟悉。特别是他没有任何的物理键(菜单键,home键,返回键)。那么用户该如何操控手机呢?Ubuntu手机以其出色的操控性,使我个人非常喜欢。尽管UI还在不断地演化中,它的流畅的操控及快速地切换,将会深深地打动许多最终的使用者。视频的地址在:


http://v.youku.com/v_show/id_XODU0NjcyMjc2.html

作者:UbuntuTouch 发表于2014-12-23 10:38:39 原文链接
阅读:448 评论:0 查看评论

Read more
Colin Ian King

Controlling data flow using sluice

Earlier this year I was instrumenting wifi power consumption and needed a way to produce and also consume data at a specific rate to pipe over netcat for my measurements.  I had some older crufty code around to do this but it needed some polishing up so I eventually got around to turning this into a more usable tool called "sluice".  (A sluice gate controls flow of water,  the sluice tool controls rate of data though a pipe).

The sluice package is currently available in PPA:colin-king/white and is built for Ubuntu Trusty, Utopic and Vivid, but there the git repository and tarballs are available too if one wants to build this from source.

The following starts a netcat 'server' to send largefile at a rate of 1MB a second using 1K buffers and reports the transfer stats to stderr with the -v verbose mode enabled:

cat largefile | sluice -r 1MB -i 1K -v | nc -l 127.0.0.1 1234 

Sluice also allows one to adjust the read/write buffer sizes dynamically to try to avoid buffer underflow or overflows while trying to match the specified transfer rate.

Sluice can be used as a data sink on the receiving side and also has an option to throw the data away if one just wants to stream data and test the data link rates, e.g., get data from somehost.com on port 1234 and throw it away at 2MB a second:

nc somehost.com 1234 | sluice -d -r 2MB -i 8K

And finally, sluice as a "tee" mode, where data is copied to stdout and to a specified output file using the -t option.

For more details, refer to the sluice project page.

Read more
facundo


Hace rato que debía este post, pero no fue hasta la semana pasada que pasé a buscar todos los audios por la biblioteca de ETER.

El curso estuvo bueno, dio un pantallazo general y superficial de mucho contenido que se profundiza en la carrera de Locución. La mayoría de mis compañeros estaban ahí porque no se decidían si encarar la carrera o no, o (como yo) porque les interesaba la temática en sí, con actividades en mayor o menor medida relacionadas al hablar en público, o la radio.

Estaba dividido en dos patas principales: la de Foniatría (dada por Ariel Aguirre), donde básicamente uno aprende a preparar y usar el instrumento (que no es sólo la boca, o cuerdas vocales, sino todo el cuerpo), y la de Locución (dada por Cristina Taboada), donde íbamos realizando distintas actividades en un estudio de verdad, aprendiendo no sólo a locutar sino también a interactuar con el operador, usar el estudio, y muchos detalles más.

De la parte de Foniatría no me queda más que algunas fotocopias a modo de apunte, pero de la parte de Locución tengo todos los audios que fuimos realizando, porque el operador los grababa:

  • Presentación: la primera vez que entramos en un estudio, con la idea de contar un poco de uno mismo y por qué estábamos ahí.
  • Cuento para niños: había que llevar un cuento infantil, para practicar lo que es una lectura muy colorida, con muchas inflexiones, apuntando a un público infantil.
  • Hablando raro: un juego donde había que leer un determinado texto con distintas voces (a mí me tocó 'gangoso', 'sensual' y 'neutro', pero habían muchos más como 'riéndose', o 'gritando', o 'enojada/o', etc.)
  • Que profesional: las mismas palabras con muchos significados distintos.
  • Texto difícil: un texto bastante complicado de leer... no llega a ser un trabalenguas, pero hay mil trampitas por ahí.
  • Leyenda Sioux: Un radioteatro, donde entre varios representábamos una historia bastante conocida; a mí me tocó ser el Relator.
  • Vecinos: Otro radioteatro, pero este sólo entre dos personas, representando una situación en el pasillo de un departamento.
  • Publicidades: Varios textos cortos que había que leer con el punto neutro pero alegre de las publicidades, hecho a dúo con la profesora.
  • Recitado: la consignar era llevar la letra de una canción con la idea de recitarla, y también una música (que no sea de esa canción) para poner de fondo.

Este último se lo dedico a mi hermana, porque es una letra que a nosotros siempre nos gustó mucho, ella hizo un grabado con esa temática (tengo una impresión colgada en la pared, y tuve una remera mucho tiempo), y también porque ella está cumpliendo un poco con la consigna de la canción, lo que me llena de alegría.

Read more
UbuntuTouch

[原]如何在Ubuntu上本地化一个Scope

在这篇文章中,我们将介绍如何本地化一个Scope。本地化对有些Scope是非常重要的。正确地使用本地化,可以使得我们的Scop很方便地支持多个国家的语言。


1)创建一个基本的Scope

打开我们的Ubuntu SDK,并按如下的步骤生成:




     


    

等我们已经创建好我们的一个最基本的Scope后,我们可以可以在如下的目录中发现:




这里有一个叫做“localizedscope.pot”文件,我们可以尝试打开该文件。它是一个空文件。我们选择desktop先运行一次我们的Scope,然后再重新打开该文件。




我们可以看到在该文件中有一些字符串,在它们的下面有一些空的串。这些字符串都是从我们的项目中源文件中提取出来的。比如在文件“com.ubuntu.developer.liu-xiao-guo.localizedscope_localizedscope.ini.in”中我们可以找到“Localizedscope Scope”。它实际上是我们的Scope的标题。在query.cpp文件中,我们可以找到如下的定义:

        // Register a category for the forecast
        auto forecast_cat = reply->register_category("forecast",
                                                     _("7 day forecast"), "", sc::CategoryRenderer(WEATHER_TEMPLATE));

通过这个例子,我们可以看出,如果我们想要本地化自己的字符串,我们使用“_("string")”的形式来让我们的工具来提取相应的需要本地化的字符串。这里的“string”应该写成英文。

在localizedscope.pot文件中,我们可以看到:

#: ../data/com.ubuntu.developer.liu-xiao-guo.localizedscope_localizedscope.ini.in.h:2
msgid "This is a Localizedscope scope"
msgstr ""

上面的地一行字显示了字符串出自哪个文件及在该文件中的行数。

2)本地化字符串


我们为了达到本地化该Scope,我们首先把.pot文件拷贝到该目录下的另外一个文件“zh_CN.po”,并做相应的翻译的工作。同时要记得把里面的

charset=CHARSET

修改为

charset=UTF-8

整个zh_CN.po文件的内容如下:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-12-22 12:13+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: ../src/scope/query.cpp:144
msgid "7 day forecast"
msgstr "7天天气预测"

#: ../data/com.ubuntu.developer.liu-xiao-guo.localizedscope_localizedscope.ini.in.h:1
msgid "Localizedscope Scope"
msgstr "本地化Scope"

#: ../data/com.ubuntu.developer.liu-xiao-guo.localizedscope_localizedscope.ini.in.h:2
msgid "This is a Localizedscope scope"
msgstr "这是一个本地化Scope"

我们可以选择在手机上安装并运行我们的Scope。最终显示如下:

         

我们也可以查看具体的操作步骤在项目中的"readme.txt"文件中。通过这样的方法,我们完成了对中文简体语言的本地化。整个项目的源码在如下地址找到:

bzr branch lp:~liu-xiao-guo/debiantrial/localizedscope

作者:UbuntuTouch 发表于2014-12-22 11:37:52 原文链接
阅读:221 评论:0 查看评论

Read more
rvr

In the last years I've been using an iPhone and I recently wanted to transfer the contact list to my phone with Ubuntu Touch. These are the steps I followed.

What is required:

  • iPhone.
  • Mac OSX.
  • Ubuntu Desktop.
  • Ubuntu Touch device.

How to do it:

  1. Export Contacts from the iPhone.
  2. Transfer the contact file to Ubuntu Touch.
  3. Import the contact file.

Let's go step by step.

Exporting the Contact list

There are different ways to export the Contact list from the iPhone to elsewhere. One option is to install an application like My Contacts Backup, and then to transfer the file containing the contacts to the computer. This option is preferred because avoids the need of a Mac desktop.

In my case, I already had my iPhone contacts synchronized with iCloud (option that I don't remember to have activated) and had the MacBook Air at hand. So these are the steps that I followed. First, the iCloud account must be setup to synchronize Contacts. Open Contacts in OSX, go to application menu and press to Accounts...

Screen Shot 2014-12-19 at 15.57.11Then select iCloud and introduce your account credentials.

Screen Shot 2014-12-19 at 15.57.21Finally, enable Contacts synchronization.

Screen Shot 2014-12-19 at 15.59.15After sync is done, the contacts are available in the application. Next step is to export all the list to a vCard file. To do that, select all contacts.

Screen Shot 2014-12-19 at 11.42.39

And export them.

Screen Shot 2014-12-19 at 11.43.07

Give a name to the file, and we are done in OSX.

Screen Shot 2014-12-19 at 11.43.41

The /Users/<user>/Documents/phone-contacts.vcf is a text file in vCard format that contains all the details of our contacts. Use a USB key to copy that file and copy it to an Ubuntu desktop.

Re-formatting

Once the file is in Ubuntu desktop, we need to tweak it a little bit, since the import tool in Ubuntu Touch doesn't like the vcf file as exported directly by OSX. The problem is that each contact entry in the file is not separated by a new line, so it must be added afterward. Open a Terminal and type this command:

Screenshot from 2014-12-19 16:38:49

In text:

$ cat phone-contacts.vcf | sed -e "s/END:VCARD/END:VCARD\n/" > phone-contacts-touch.vcf

A new (and correct) file will be created, phone-contacts-touch.vcf.

Transfer to Ubuntu Touch

Now connect the Ubuntu Touch device to Ubuntu desktop and install some packages:

Screenshot from 2014-12-19 16:49:19

$ sudo apt-get install phablet-tools android-tools-adb

In the Ubuntu Touch phone, go to System Settings > About this phone > Developer Mode and  enable the developer mode. Connect the phone to Ubuntu via USB and type this command to transfer the file to Ubuntu Touch:

Screenshot from 2014-12-19 16:56:31

$ adb push phone-contacts-touch.vcf /home/phablet/Documents

And log into Ubuntu Touch:

$ phablet-shell

Importing the contacts

Screenshot from 2014-12-19 17:01:58

And now, the final step that will import the contacts. That will be done using SyncEvolution tool that comes by default in Ubuntu Touch.

Screenshot from 2014-12-19 17:04:52

$ syncevolution --import ~/Documents/phone-contacts-touch.vcf backend=evolution-contacts database=Personal

And that's it. Now, all the contacts are imported and available in the Address Book app in Ubuntu Touch. Enjoy!

Wrap up

Of course, with some development effort this task could be much easier. A path that I don't know whether it is possible are direct calls to iCloud API's from Ubuntu Touch, but I doubt it. I've took a quick look to  libimobiledevice library. Many years ago there was a tool, python-idevicesync, that was based on it and provided a contact export feature. It's now out of sync with the library API. Another good step would be an Ubuntu Touch app that could read vCard files, and avoid the need to call SyncEvolution using the command line. I'm sure the community will be looking into this features soon.

Read more
Dustin Kirkland


Awww snap!

That's right!  Snappy Ubuntu images are now on AWS, for your EC2 computing pleasure.

Enjoy this screencast as we start a Snappy Ubuntu instance in AWS, and install the xkcd-webserver package.


And a transcript of the commands follows below.

kirkland@x230:/tmp⟫ cat cloud.cfg
#cloud-config
snappy:
ssh_enabled: True
kirkland@x230:/tmp⟫ aws ec2 describe-images \
> --region us-east-1 \
> --image-ids ami-5c442634

{
"Images": [
{
"ImageType": "machine",
"Description": "ubuntu-core-devel-1418912739-141-amd64",
"Hypervisor": "xen",
"ImageLocation": "ucore-images/ubuntu-core-devel-1418912739-141-amd64.manifest.xml",
"SriovNetSupport": "simple",
"ImageId": "ami-5c442634",
"RootDeviceType": "instance-store",
"Architecture": "x86_64",
"BlockDeviceMappings": [],
"State": "available",
"VirtualizationType": "hvm",
"Name": "ubuntu-core-devel-1418912739-141-amd64",
"OwnerId": "649108100275",
"Public": false
}
]
}
kirkland@x230:/tmp⟫
kirkland@x230:/tmp⟫ # NOTE: This AMI will almost certainly have changed by the time you're watching this ;-)
kirkland@x230:/tmp⟫ clear
kirkland@x230:/tmp⟫ aws ec2 run-instances \
> --region us-east-1 \
> --image-id ami-5c442634 \
> --key-name id_rsa \
> --instance-type m3.medium \
> --user-data "$(cat cloud.cfg)"
{
"ReservationId": "r-c6811e28",
"Groups": [
{
"GroupName": "default",
"GroupId": "sg-d5d135bc"
}
],
"OwnerId": "357813986684",
"Instances": [
{
"KeyName": "id_rsa",
"PublicDnsName": null,
"ProductCodes": [],
"StateTransitionReason": null,
"LaunchTime": "2014-12-18T17:29:07.000Z",
"Monitoring": {
"State": "disabled"
},
"ClientToken": null,
"StateReason": {
"Message": "pending",
"Code": "pending"
},
"RootDeviceType": "instance-store",
"Architecture": "x86_64",
"PrivateDnsName": null,
"ImageId": "ami-5c442634",
"BlockDeviceMappings": [],
"Placement": {
"GroupName": null,
"AvailabilityZone": "us-east-1e",
"Tenancy": "default"
},
"AmiLaunchIndex": 0,
"VirtualizationType": "hvm",
"NetworkInterfaces": [],
"SecurityGroups": [
{
"GroupName": "default",
"GroupId": "sg-d5d135bc"
}
],
"State": {
"Name": "pending",
"Code": 0
},
"Hypervisor": "xen",
"InstanceId": "i-af43de51",
"InstanceType": "m3.medium",
"EbsOptimized": false
}
]
}
kirkland@x230:/tmp⟫
kirkland@x230:/tmp⟫ aws ec2 describe-instances --region us-east-1 | grep PublicIpAddress
"PublicIpAddress": "54.145.196.209",
kirkland@x230:/tmp⟫ ssh -i ~/.ssh/id_rsa ubuntu@54.145.196.209
ssh: connect to host 54.145.196.209 port 22: Connection refused
255 kirkland@x230:/tmp⟫ ssh -i ~/.ssh/id_rsa ubuntu@54.145.196.209
The authenticity of host '54.145.196.209 (54.145.196.209)' can't be established.
RSA key fingerprint is 91:91:6e:0a:54:a5:07:b9:79:30:5b:61:d4:a8:ce:6f.
No matching host key fingerprint found in DNS.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '54.145.196.209' (RSA) to the list of known hosts.
Welcome to Ubuntu Vivid Vervet (development branch) (GNU/Linux 3.16.0-25-generic x86_64)

* Documentation: https://help.ubuntu.com/

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

Welcome to the Ubuntu Core rolling development release.

* See https://ubuntu.com/snappy

It's a brave new world here in snappy Ubuntu Core! This machine
does not use apt-get or deb packages. Please see 'snappy --help'
for app installation and transactional updates.

To run a command as administrator (user "root"), use "sudo ".
See "man sudo_root" for details.

ubuntu@ip-10-153-149-47:~$ mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
udev on /dev type devtmpfs (rw,relatime,size=1923976k,nr_inodes=480994,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=385432k,mode=755)
/dev/xvda1 on / type ext4 (ro,relatime,data=ordered)
/dev/xvda3 on /writable type ext4 (rw,relatime,discard,data=ordered)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,mode=755)
tmpfs on /etc/fstab type tmpfs (rw,nosuid,noexec,relatime,mode=755)
/dev/xvda3 on /etc/systemd/system type ext4 (rw,relatime,discard,data=ordered)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k)
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd)
pstore on /sys/fs/pstore type pstore (rw,nosuid,nodev,noexec,relatime)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset,clone_children)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
tmpfs on /etc/machine-id type tmpfs (ro,relatime,size=385432k,mode=755)
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=22,pgrp=1,timeout=300,minproto=5,maxproto=5,direct)
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
mqueue on /dev/mqueue type mqueue (rw,relatime)
fusectl on /sys/fs/fuse/connections type fusectl (rw,relatime)
/dev/xvda3 on /etc/hosts type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /etc/sudoers.d type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /root type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /var/lib/click/frameworks type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /usr/share/click/frameworks type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /var/lib/systemd/snappy type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /var/lib/systemd/click type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /var/lib/initramfs-tools type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /etc/writable type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /etc/ssh type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /var/tmp type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /var/lib/apparmor type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /var/cache/apparmor type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /etc/apparmor.d/cache type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /etc/ufw type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /var/log type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /var/lib/system-image type ext4 (rw,relatime,discard,data=ordered)
tmpfs on /var/lib/sudo type tmpfs (rw,relatime,mode=700)
/dev/xvda3 on /var/lib/logrotate type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /var/lib/dhcp type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /var/lib/dbus type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /var/lib/cloud type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /var/lib/apps type ext4 (rw,relatime,discard,data=ordered)
tmpfs on /mnt type tmpfs (rw,relatime)
tmpfs on /tmp type tmpfs (rw,relatime)
/dev/xvda3 on /apps type ext4 (rw,relatime,discard,data=ordered)
/dev/xvda3 on /home type ext4 (rw,relatime,discard,data=ordered)
/dev/xvdb on /mnt type ext3 (rw,relatime,data=ordered)
tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=385432k,mode=700,uid=1000,gid=1000)
ubuntu@ip-10-153-149-47:~$ mount | grep " / "
/dev/xvda1 on / type ext4 (ro,relatime,data=ordered)
ubuntu@ip-10-153-149-47:~$ sudo touch /foo
touch: cannot touch ‘/foo’: Read-only file system
ubuntu@ip-10-153-149-47:~$ sudo apt-get update
Ubuntu Core does not use apt-get, see 'snappy --help'!
ubuntu@ip-10-153-149-47:~$ sudo snappy --help
Usage:snappy [-h] [-v]
{info,versions,search,update-versions,update,rollback,install,uninstall,tags,build,chroot,framework,fake-version,nap}
...

snappy command line interface

optional arguments:
-h, --help show this help message and exit
-v, --version Print this version string and exit

Commands:
{info,versions,search,update-versions,update,rollback,install,uninstall,tags,build,chroot,framework,fake-version,nap}
info
versions
search
update-versions
update
rollback undo last system-image update.
install
uninstall
tags
build
chroot
framework
fake-version ==SUPPRESS==
nap ==SUPPRESS==
ubuntu@ip-10-153-149-47:~$ sudo snappy info
release: ubuntu-core/devel
frameworks:
apps:
ubuntu@ip-10-153-149-47:~$ sudo snappy versions -a
Part Tag Installed Available Fingerprint Active
ubuntu-core edge 141 - 7f068cb4fa876c *
ubuntu@ip-10-153-149-47:~$ sudo snappy search docker
Part Version Description
docker 1.3.2.007 The docker app deployment mechanism
ubuntu@ip-10-153-149-47:~$ sudo snappy install docker
docker 4 MB [=============================================================================================================] OK
Part Tag Installed Available Fingerprint Active
docker edge 1.3.2.007 - b1f2f85e77adab *
ubuntu@ip-10-153-149-47:~$ sudo snappy versions -a
Part Tag Installed Available Fingerprint Active
ubuntu-core edge 141 - 7f068cb4fa876c *
docker edge 1.3.2.007 - b1f2f85e77adab *
ubuntu@ip-10-153-149-47:~$ sudo snappy search webserver
Part Version Description
go-example-webserver 1.0.1 Minimal Golang webserver for snappy
xkcd-webserver 0.3.1 Show random XKCD compic via a build-in webserver
ubuntu@ip-10-153-149-47:~$ sudo snappy install xkcd-webserver
xkcd-webserver 21 kB [=====================================================================================================] OK
Part Tag Installed Available Fingerprint Active
xkcd-webserver edge 0.3.1 - 3a9152b8bff494 *
ubuntu@ip-10-153-149-47:~$ exit
logout
Connection to 54.145.196.209 closed.
kirkland@x230:/tmp⟫ ec2-instances
i-af43de51 ec2-54-145-196-209.compute-1.amazonaws.com
kirkland@x230:/tmp⟫ ec2-terminate-instances i-af43de51
INSTANCE i-af43de51 running shutting-down
kirkland@x230:/tmp⟫

Cheers!
Dustin

Read more
Colin Ian King

Smackerel of Opinion

It is approaching the Christmas Holiday season, so it's that time again to write some slightly obfuscated C in a seasonal way.  This year I thought I would try some coloured ASCII art for the output for a little variety.


#define r(s) s[e%(sizeof s-1)]
#include /* */
#define S "%s"/* Have */
#define u printf(/* a */
#define c )J/* Merry */
#define W "H"/* Christmas */
#define e rand()/* and */
#define U(i) v[i]/* a */
#define C(q) q[]=/* Happy */
#define J ;;/* New Year */
#define O [v]/* Colin.I.King */


typedef a
; a m, v[6] ,
H;a main(
){char C(
o){033,91,0},C(D)
"*Oo", C(t
)"^~#",Q[ ]=
"13747516",C(s
)".x+*";u S"2"
"J%s0;0H%s0"
";37;40"
"m",o,o, o
c while(U(!!m)
<22)u S"%dm%39s\n" ,
o,0 O++>19?42:',',""
c while(0 O++<'~') u S
"%d;%dH%s44m%c",o,e%21,e
%39,o,r(s)c for(J){1 O=1
-U(1),srand(v),u S"0;0"W S
"0;2;%dm",o,o,' 'c for(m=0
;m>>4<1;++m){u S"%d;%d"W,o
, m+2,20-m c;for(H=0;H<1+(m
<<1);H++){4 O=!H|H==m<<1 ,
2 O=!(e&05),U(3)=H>m*5/
3,5 O=r(D)J if(4 O|U(
2)){u S"%d;%d;3%cm"
"%c",o,U(4)?','
:'*',3 O?2:1+(U(1)^(1&e;)),r(Q),U(5)c}else u S"42;32\
;%dm%c",o,1+3 O,r(t)c u S"0m",o c} }while(m<19)u S"\
%d;19"W S"33;2;7m #\n",o,1+ ++m,o c sleep(m>=-H c}}

The source can be downloaded from here and compiled and run as follows:

gcc snowman.c -o snowman
./snowman

and press control-C to exit when you have seen enough.

Read more
UbuntuTouch

——“和你圆梦”百万青年创业就业计划最新赛事公布

中国移动联合产业链合作伙伴Canonical,合作举办“Ubuntu开发者创新大赛”。旨为让青年开发者率先接触新兴的移动生态系统,从而获得崭新的创业机遇。“Ubuntu开发者创新大赛”是中国移动“和你圆梦”百万青年创业就业计划最新开启的子赛事。

赛事面向学生群体、职业开发者和开源社区,共设置6个奖项,奖励包括7万人民币现金和手机等奖品,并为学生组的获奖参赛者提供Canonical实习机会。开发者可访问“和你圆梦”百万青年创业就业计划官网报名参赛,报名截止时间为2015年4月30日,2015年6月进行决赛评选。

本次比赛作品提交可为Scopes和应用(包括HTML5和QML原生两种形式),参赛者将分为学生组和职业组进行评审。相关Ubuntu开发工具、网上教程和资料信息请登陆cn.developer.ubuntu.com

本次赛事活动将使开发者接触到Ubuntu所带来的新一代移动体验。这将打破自第一款iphone以来所形成的对于应用为王的固定模式,也将突破屏幕上惟有应用图标排列组成的单一视觉效果和使用上的局限。Ubuntu系统实现了内容和服务的前置,可直接呈现于屏幕上,从而有效的为用户创造一个丰富、快速且不碎片化的体验。而开发者只需花费相对于传统应用开发和维护而言很小的成本,便可在系统级别上创造出与应用同样的用户体验。这些独特体验是通过使用Ubuntu Scopes来完成的,它是Ubuntu独有的全新UI工具,可通过Ubuntu SDK获取。想了解更多Ubuntu Scopes和Ubuntu手机的信息,请访问cn.ubuntu.com/phone

“和你圆梦”百万青年创业就业计划由共青团中央和中国移动于2010年联合启动,旨在为青年学生提供全流程的创业就业扶持。其中丰富的赛事活动是中国移动“和你圆梦”百万青年创业就业计划的亮点,除此次Ubuntu开发者创新大赛之外,第四届的系列赛事活动共包含原创内容类、应用开发类、专项能力类三个类别,13个子赛事,设置了660个奖项,共计提供550万元现金奖金及培训、创业、就业等奖励扶持。>>更多赛事活动和扶持政策请访问“和你圆梦”百万青年创业就业计划官网(dream.10086.cn

该文章的出自:http://dev.10086.cn/news/mmnews/12145.html

作者:UbuntuTouch 发表于2014-12-18 22:01:54 原文链接
阅读:219 评论:0 查看评论

Read more
Michael Hall

There’s a saying in American political debate that is as popular as it is wrong, which happens when one side appeals to our country’s democratic ideal, and the other side will immediately counter with “The United States is a Republic, not a Democracy”. I’ve noticed a similar misunderstanding happening in open source culture around the phrase “meritocracy” and the negatively-charged “oligarchy”. In both cases, though, these are not mutually exclusive terms. In fact, they don’t even describe the same thing.

Authority

One of these terms describes where the authority to lead (or govern) comes from. In US politics, that’s the term “republic”, which means that the authority of the government is given to it by the people (as opposed to divine-right, force of arms, of inheritance). For open source, this is where “meritocracy” fits in, it describes the authority to lead and make decisions as coming from the “merit” of those invested with it. Now, merit is hard to define objectively, and in practice it’s the subjective opinion of those who can direct a project’s resources that decides who has “merit” and who doesn’t. But it is still an important distinction from projects where the authority to lead comes from ownership (either by the individual or their employer) of a project.

Enfranchisement

History can easily provide a long list of Republics which were not representative of the people. That’s because even if authority comes from the people, it doesn’t necessarily come from all of the people. The USA can be accurately described as a democracy, in addition to a republic, because participation in government is available to (nearly) all of the people. Open source projects, even if they are in fact a meritocracy, will vary in what percentage of their community are allowed to participate in leading them. As I mentioned above, who has merit is determined subjectively by those who can direct a project’s resources (including human resource), and if a project restricts that to only a select group it is in fact also an oligarchy.

Balance and Diversity

One of the criticisms leveled against meritocracies is that they don’t produce diversity in a project or community. While this is technically true, it’s not a failing of meritocracy, it’s a failing of enfranchisement, which as has been described above is not what the term meritocracy defines. It should be clear by now that meritocracy is a spectrum, ranging from the democratic on one end to the oligarchic on the other, with a wide range of options in between.

The Ubuntu project is, in most areas, a meritocracy. We are not, however, a democracy where the majority opinion rules the whole. Nor are we an oligarchy, where only a special class of contributors have a voice. We like to use the term “do-ocracy” to describe ourselves, because enfranchisement comes from doing, meaning making a contribution. And while it is limited to those who do make contributions, being able to make those contributions in the first place is open to anybody. It is important for us, and part of my job as a Community Manager, to make sure that anybody with a desire to contribute has the information, resources, and access to to so. That is what keeps us from sliding towards the oligarchic end of the spectrum.

 

Read more
Joseph Salisbury

Meeting Minutes

IRC Log of the meeting.

Meeting minutes.

Agenda

20141216 Meeting Agenda


Release Metrics and Incoming Bugs

Release metrics and incoming bug data can be reviewed at the following link:

  • http://people.canonical.com/~kernel/reports/kt-meeting.txt


Status: Vivid Development Kernel

The master-next branch of our Vivid kernel remains rebased to the
final v3.18 upstream kernel. We have pushed uploads to our team’s PPA
for preliminary testing. We are still debating on uploading to the
archive after Alpha1 releases this week. However, we may opt to wait
until everyone returns from holiday after the new year.
—–
Important upcoming dates:
Thurs Dec 18 – Vivid Alpha 1 (~2 days away)
Fri Jan 9 – 14.04.2 Kernel Freeze (~3 weeks away)
Thurs Jan 22 – Vivid Alpha 2 (~5 weeks away)
Thurs Feb 5 – 14.04.2 Point Release (~7 weeks away)


Status: CVE’s

The current CVE status can be reviewed at the following link:

http://people.canonical.com/~kernel/cve/pkg/ALL-linux.html


Status: Stable, Security, and Bugfix Kernel Updates – Utopic/Trusty/Precise/Lucid

Status for the main kernels, until today:

  • Lucid – Prep
  • Precise – Prep
  • Trusty – Prep
  • Utopic – Prep

    Current opened tracking bugs details:

  • http://kernel.ubuntu.com/sru/kernel-sru-workflow.html

    For SRUs, SRU report is a good source of information:

  • http://kernel.ubuntu.com/sru/sru-report.html

    Schedule:

    cycle: 12-Dec through 10-Jan
    ====================================================================
    12-Dec Last day for kernel commits for this cycle
    14-Dec – 20-Dec Kernel prep week.
    21-Dec – 10-Jan Bug verification; Regression testing; Release


Open Discussion or Questions? Raise your hand to be recognized

No open discussion.

Read more
Dustin Kirkland


As promised last week, we're now proud to introduce Ubuntu Snappy images on another of our public cloud partners -- Google Compute Engine.
In the video below, you can join us walking through the instructions we have published here.
Snap it up!
:-Dustin

Read more
Daniel Holbach

For some time we have had training materials available for learning how to write Ubuntu apps.  We’ve had a number of folks organising App Dev School events in their LoCo team. That’s brilliant!

What’s new now are training materials for developing scopes!

It’s actually not that hard. If you have a look at the workshop, you can prepare yourself quite easily for giving the session at a local event.

As we are working on an updated developer site, right now, for now take a look at the following pages if you’re interested in running such a session yourself:

I would love to get feedback, so please let me know how the materials work out for you!

Read more
Daniel Holbach

I’m very happy that folks took notes during and after the meeting to bring up their ideas, thoughts, concerns and plans. It got a bit unwieldy, so Elfy put up a pad which summarises it and is meant to discuss actions and proposals.

Today we are going to have a meeting to discuss what’s on the “actions” pad. That’s why I thought it’d be handy to put together a bit of a summary of what people generally brought up. They’re not my thoughts, I’m just putting them up for further discussion.

Problem statements

  • Feeling that people innovate *with* Ubuntu, not *in* Ubuntu.
  • Perception of contributor drop in “older” parts of the community.
    • Less activity at UDS/vUDS/UOS events (was discussed at UOS too, maybe we need a committee which finds a new vision for Ubuntu Community Planning)?
    • Less activity in LoCos (lacking a sense of purpose?)
    • No drop in members/developers.
  • Less activity in Canonical-led projects.
  • We don’t spend marketing money on social media. Build a pavement online.
  • Downloading a CD image is too much of a barrier for many.
  • Our “community infrastructure” did not scale with the amount of users.
  • Some discussion about it being hard becoming a LoCo team. Bureaucracy from the LoCo Council.
  • We don’t have enough time to train newcomers.
  • Language barriers make it hard for some to get involved.
  • Canonical does a bad job announcing their presence at events.

Questions

  • Why are less people innovating in Ubuntu? Is Canonical driving too much of Ubuntu?
  • Why aren’t more folks stepping up into leadership positions? Mentoring? Lack of opportunities? More delegation? Do leaders just come in and lead because they’re interested?
  • Lack of planning? Do we re-plan things at UOS events, because some stuff never gets done? Need more follow-through? More assessment?

Proposals

  • community.ubuntu.com: More clearly indicate Canonical-led projects? Detail active projects, with point of contact, etc? Clean up moribund projects.
  • Make Ubuntu events more about “doing things with Ubuntu”?
  • Ubuntu Leadership Mentoring programme.
  • Form more of an Ubuntu ecosystem, allowing to earn money with Ubuntu.

Join the hangout on ubuntuonair.com on Friday, 12th December 2014, 16 UTC.

Read more
UbuntuTouch

[原]Ubuntu Scope简介及开发流程

在这个视频里,我们介绍了在Ubuntu平台上的Scope,并讲解了如何开发Scope。


视频地址:http://v.youku.com/v_show/id_XODQ3MDY5NTQ0.html

视频中的源码: bzr branch lp:~liu-xiao-guo/debiantrial/openmap

作者:UbuntuTouch 发表于2014-12-12 15:13:38 原文链接
阅读:351 评论:0 查看评论

Read more