• Yahoo! Acquisition AdMovate, Develop Mobile Advertising Service

    Comments Off on Yahoo! Acquisition AdMovate, Develop Mobile Advertising Service

    Internet giant head of Marissa Mayer, Yahoo!, recently rumored to re-acquire a startup working in the areas of mobile advertising, AdMovate. The umpteenth time that the acquisition by Yahoo! Yahoo! is regarded as an effort to improve service advertisements that are considered “lackluster” lately.

    Yahoo! via his blog on Tumblr, has officially announced the purchase AdMovate engaged in the mobile advertising services. AdMovate parties themselves have confirmed this issue by stating that they were aimed at helping advertisers to reach consumers at the right time and place via private message certainly be provide by AdMovate.

    Quoted from a news release The Next Web today (18/7), Yahoo! states that carried AdMovate personalization technology can improve the ability of Yahoo! in advertising through the mobile platform. In addition, after the acquisition of all employees AdMovate instantly brought to the Yahoo! offices are located in Silicon Valley, USA.

    Marissa Mayer as CEO of Yahoo!, concerning this acquisition had expressed interest in re-focusing the Yahoo! mobile services that could be left behind. According to him, the future of Yahoo! ‘s business models will be on the mobile segment in which this segment continues to experience a significant increase, “Yahoo’s future is on the phone. So we put the products for mobile phones, “he said.

    In a blog post on tumblr, Scott Burke who is SVP of Display Advertising and Advertising Technology Yahoo! said Yahoo! is now trying to focus on investments in the mobile segment, “Yahoo is currently investing more in the purchase program and advertising on mobile phones,” she called.

    Description Scott was indeed not a hoax. Yahoo! is just a period of four months was reported to have acquired 10 startup that Summly, Astrid, Milewise, Loki Studios, Go Poll Go, PlayerScale, Rondee, Ghostbird Software, Tumblr, and most recently Qwiki, and it is almost entirely a startup working in the mobile field. With the acquisition AdMovate which is a provider of mobile advertising services, then shopping “wholesale” a la Yahoo! The Yahoo! could be an attempt to break through the mobile industry is growing rapidly these days.

    Tags: , , , ,

  • Hacking with a Hacker

    Comments Off on Hacking with a Hacker
    April 28, 2020 /  Computer Technology, Programming

    What is it like to hack with one of the original hackers? It is certainly much different than what Appears to be the modern rendition of hacking. My experience was not getting really drunk with tons of junk food. It was not working on “beautiful” designs or “authentic” typography. It was not so much about sharing with the world as it was sharing with your peers. It had a very different feel to it than the “hacker culture” Promoted by some of the top technical Silicon Valley companies. It felt more “at home”, less dreamy, and more memorable.

    I meet with Bill Gosper every so Often; I had the pleasure of giving him a tour of Facebook when I worked there. (He was so surprised that they had Coke in the glass bottles there, just like the old days.)

    He is still very much a hacker, a thinker, a tinkerer, and a wonderer. Every time I meet up with him, he has a new puzzle for me, or someone around him, to solve, whether it’s really clever compass constructions, circle packing, block building, Game of Life automata solving, or even something more tangible like a Buttonhole homemade trap (which was affixed to my shirt for no less than two weeks!). He is also the bearer of interesting items, such as a belt buckle he gave me roomates depicts, in aluminum, a particular circle loose packing.
    Gosper succeeding in tricking me with the Buttonhole Trap
    When we meet up, all we do is hack. Along with him and one of his talented young students, we all work on something. Anything interesting, really. Last time we met up, we resurrected an old Lisp machine and did some software archeology. I brought over some of the manuals I own, like the great Chinual, and he brought over a dusty old 1U rackmount Alpha machine with OpenGenera installed. After passing a combination of Hurdles, such as that the keyboard was not interfacing with the computer Correctly, we finally got it to boot up. Now, I got to see with my own eyes, a time capsule containing a lot of Bill’s work from the 70s, 80s, and 90s, roomates could only be commanded and Examined through Zmacs dired and Symbolics Common Lisp. Our next goal was to get Symbolics Macsyma fired up on the old machine.

    There was trouble with starting it up. License issues were one problem, finding and loading all of the files were compiled another. Running applications on a Lisp machine is very different than what we do today on modern machines, Windows or UNIX. There’s no. Exe file to click, or. App bundle to start up, or even a single. / File to execute. Usually it’s a collection of compiled “fast loading” or “fasl” files that get loaded side-by-side with the operating system. The application, in essence, Becomes a part of the OS.

    In hacker tradition, we were Able to bypass the license issues by modifying the binary directly in Lisp. Fortunately, such as Lisp makes things easy disassembly. But how do we load the damn thing? Bill frustratingly muttered, “It’s been at least 20 years since I’ve done it. I just do not remember. “I, being an owner of MacIvory Symbolics Lisp machines, fortunately did remember how to load programs. “Bill, how about LOAD SYSTEM Macsyma?” He typed it into the native Lisp “Listener 2” window (we kept “Listener 1” for debugging), sometimes making a few typing mistakes, but finally succeeding, and then we saw the stream of files loading. We all Shouted in joy that progress was being made. I recall Bill was especially astounded at how fast everything was loading. This was on a fast Alpha machine with gobs of memory. It must have been much slower on the old 3600s they used back in the day.
    The Lisp Machine Manual, or Chinual
    It was all done after a few minutes, and Macsyma was loaded. To me, this was a sort of holy grail. I personally have Macsyma for Windows (which he uses in a VirtualBox machine on his 17 “MacBook), and I’ve definitely used Maxima. But Macsyma is something I’ve never seen. It was something that seems to have disappeared with history, something I have not been Able to find a copy of in the last decade.

    Bill said, “let’s see if it works.” And he typed 1 +1; in, and sure enough, the result was 2. He saw I was bubbling with excitement and asked me if I’d like to try anything. “I’d love to,” and he handed the keyboard over to me and I typed in my canonical computer algebra test: integrate (sqrt (tan (x)), x);, roomates computes the indefinite integral
    —- √ ∫ tanθ dθ
    Out came the four-term typeset result of logarithms and arctangents, plus a fifth term I’d never seen before. “I’ve never seen any computer algebra system add that fifth term,” I said, “but it does not look incorrect.” The fifth term was a floored expression, Whose Increased value with the period of the function preceding it. “Let’s plot it,” Bill said. He plotted it using Macsyma’s menu interface, and it was what appeared to be an increasing, non-periodic function. I think we determined it was properly handled Because Macsyma branch cuts, with other systems have been known to be unorthodox about. It definitely had a pragmatic feel to it.

    Now, Bill wanted to show us some interesting things; however all of Bill’s recent work Macsyma was on his laptop. How do we connect this ancient to a modern Macintosh hardware? We needed to get the machine onto the network, and networking with old machines is not my forte.

    Fortunately, Stephen Jones, a friend of Bill’s and seemingly an expert at a rare combination of technical tasks, showed up. He Was able to do things that Neither Bill nor I could do on such an old machine. In only a few moments, he Was able to get Bill’s Mac talking to the Alpha, roomates shared a portion of its file system with Genera. “Will there be enough space on the Alpha for Macsyma my files?” Bill asked Stephen. “Of course, there’s ton’s of space.” We finally got Bill’s recent work transferred onto the machine.
    Bill hacking in Macsyma in OpenGenera (Image courtesy of Stephen M. Jones)
    We spent the rest of the night hacking on math. He Demonstrated to us what it was like to do a real mathematician’s work at the machine. He debuted some of his recent work. He went though a long chain of reasoning, showing us the line-after-line in Macsyma, number theoretic amazing to do things I’ve never seen before.

    I did ask Bill why he does not publish more often. His previous publications have been landmarks: his algorithm for hypergeometric series and his summation algorithm for playing the Game of Life at light speed. He RESPONDED, “when there’s something interesting to publish, it’ll be published.” He seemed to have a sort of disdain for “salami science”, where scientific and mathematical papers present the thinnest possible “slice” or result possible.

    Bill is certainly a man that thinks in a different way than most of us do. He is still hacking at mathematics, and still as impressive as before. I’m very fortunate to have met him, and I was absolutely delighted to see that even at 70 years old, his mind is still as sharp as can be, and it’s still being used to do interesting, Gosper-like mathematics.

    And you would not believe it. We all were ready to head home at around 9 PM.

    Tags: , , , ,

  • Integrating C++ with QML

    Comments Off on Integrating C++ with QML
    April 28, 2020 /  Computer Technology, Programming

    Introduction

    Qt Quick’s QML language makes it easy to do many things, especially fancy animated user interfaces. However, some things either can’t be done or are not suitable for implementing in QML, such as:

    1. Getting access to functionality outside of the QML/JavaScript environment.
    2. Implementing performance critical functions where native code is desired for efficiency.
    3. Large and/or complex non-declarative code that would be tedious to implement in JavaScript.

    As we’ll see, Qt makes it quite easy to expose C++ code to QML. In this blog post I will show an example of doing this with a small but functional application.

    The example is written for Qt 5 and uses the Qt Quick Components so you will need at least Qt version 5.1.0 to run it.

    Overview

    To expose a C++ type having properties, methods, signals, and/or slots to the QML environment, the basic steps are:

    1. Define a new class derived from QObject.
    2. Put the Q_OBJECT macro in the class declaration to support signals and slots and other services of the Qt meta-object system.
    3. Declare any properties using the Q_PROPERTY macro.
    4. Call qmlRegisterType() in your C++ main program to register the type with the Qt Quick engine.

    For all the details I refer you to the Qt documentation section Exposing Attributes of C++ Types to QML and the Writing QML Extensions with C++ tutorial.

    Ssh Key Generator

    For our code example, we want a small application that will generate ssh public/private key pairs using a GUI. It will present the user with controls for the appropriate options and then run the program ssh-keygen to generate the key pair.

    I implemented the user interface using the new Qt Quick Controls since it was intended as a desktop application with a desktop look and feel. I initially developed the UX entirely by running the qmlscene program directly on the QML source.

    The UI prompts the user for the key type, the file name of the private key to generate and an optional pass phrase, which needs to be confirmed.

    The C++ Class

    Now that have the UI, we will want to implement the back end functionality. You can’t invoke an external program directly from QML so we have to write it in C++ (which is the whole point of this example application).

    First, we define a class that encapsulates the key generation functionality. It will be exposed as a new class KeyGenerator in QML. This is done in the header file KeyGenerator.h below.

    #ifndef KEYGENERATOR_H
    #define KEYGENERATOR_H
    
    #include <QObject>
    #include <QString>
    #include <QStringList>
    
    // Simple QML object to generate SSH key pairs by calling ssh-keygen.
    
    class KeyGenerator : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QString type READ type WRITE setType NOTIFY typeChanged)
        Q_PROPERTY(QStringList types READ types NOTIFY typesChanged)
        Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged)
        Q_PROPERTY(QString passphrase READ filename WRITE setPassphrase NOTIFY passphraseChanged)
    
    public:
        KeyGenerator();
        ~KeyGenerator();
    
        QString type();
        void setType(const QString &t);
    
        QStringList types();
    
        QString filename();
        void setFilename(const QString &f);
    
        QString passphrase();
        void setPassphrase(const QString &p);
    
    public slots:
        void generateKey();
    
    signals:
        void typeChanged();
        void typesChanged();
        void filenameChanged();
        void passphraseChanged();
        void keyGenerated(bool success);
    
    private:
        QString _type;
        QString _filename;
        QString _passphrase;
        QStringList _types;
    };
    #endif

    Next, we need to derive our class from QObject. We declare any properties that we want and the associated methods. Notify methods become signals. In our case, we want to have properties for the selected key type, the list of all valid ssh key types, file name and pass phrase. I arbitrarily made the key type a string. It could have been an enumerated type but it would have made the example more complicated.

    Incidentally, a new feature of the Q_PROPERTY macro in Qt 5.1.0 is the MEMBER argument. It allows specifying a class member variable that will be bound to a property without the need to implement the setter or getter functions. That feature was not used here.

    We declare methods for the setters and getters and for signals. We also declare one slot called generateKey(). These will all be available to QML. If we wanted to export a regular method to QML, we could mark it with Q_INVOCABLE. In this case I decided to make generateKey() a slot since it might be useful in the future but it could have just as easily been an invocable method.

    Finally, we declare any private member variables we will need.

    C++ Implementation

    Now let’s look at the implementation in KeyGenerator.cpp. Here is the source code:

    #include <QFile>
    #include <QProcess>
    #include "KeyGenerator.h"
    
    KeyGenerator::KeyGenerator()
        : _type("rsa"), _types{"dsa", "ecdsa", "rsa", "rsa1"}
    {
    }
    
    KeyGenerator::~KeyGenerator()
    {
    }
    
    QString KeyGenerator::type()
    {
        return _type;
    }
    
    void KeyGenerator::setType(const QString &t)
    {
        // Check for valid type.
        if (!_types.contains(t))
            return;
    
        if (t != _type) {
            _type = t;
            emit typeChanged();
        }
    }
    
    QStringList KeyGenerator::types()
    {
        return _types;
    }
    
    QString KeyGenerator::filename()
    {
        return _filename;
    }
    
    void KeyGenerator::setFilename(const QString &f)
    {
        if (f != _filename) {
            _filename = f;
            emit filenameChanged();
        }
    }
    
    QString KeyGenerator::passphrase()
    {
        return _passphrase;
    }
    
    void KeyGenerator::setPassphrase(const QString &p)
    {
        if (p != _passphrase) {
            _passphrase = p;
            emit passphraseChanged();
        }
    }
    
    void KeyGenerator::generateKey()
    {
        // Sanity check on arguments
        if (_type.isEmpty() or _filename.isEmpty() or
            (_passphrase.length() > 0 and _passphrase.length() < 5)) {
            emit keyGenerated(false);
            return;
        }
    
        // Remove key file if it already exists
        if (QFile::exists(_filename)) {
            QFile::remove(_filename);
        }
    
        // Execute ssh-keygen -t type -N passphrase -f keyfileq
        QProcess *proc = new QProcess;
        QString prog = "ssh-keygen";
        QStringList args{"-t", _type, "-N", _passphrase, "-f", _filename};
        proc->start(prog, args);
        proc->waitForFinished();
        emit keyGenerated(proc->exitCode() == 0);
        delete proc;
    }

    The constructor initializes some of the member variables. For fun, I used the new initializer list feature of C++11 to initialize the _types member variable which is of type QStringList. The destructor does nothing, at least for now, but is there for completeness and future expansion.

    Getter functions like type() simply return the appropriate private member variable. Setters set the appropriate variables, taking care to check that the new value is different from the old one and if so, emitting the appropriate signal. As always, please note that signals are created by the Meta Object Compiler and do not need to be implemented, only emitted at the appropriate times.

    The only non-trivial method is the slot generateKey(). It does some checking of arguments and then creates a QProcess to run the external ssh-keygen program. For simplicity and because it typically executes quickly, I do this synchronously and block on it to complete. When done, we emit a signal that has a boolean argument that indicates the key was generated and whether it succeeded or not.

    QML Code

    Now let’s look at the QML code in main.qml:

    // SSH key generator UI
    
    import QtQuick 2.1
    import QtQuick.Controls 1.0
    import QtQuick.Layouts 1.0
    import QtQuick.Dialogs 1.0
    import com.ics.demo 1.0
    
    ApplicationWindow {
        title: qsTr("SSH Key Generator")
    
        statusBar: StatusBar {
        RowLayout {
            Label {
                id: status
                }
            }
        }
    
        width: 369
        height: 166
    
        ColumnLayout {
            x: 10
            y: 10
    
            // Key type
            RowLayout {
                Label {
                    text: qsTr("Key type:")
                }
                ComboBox {
                    id: combobox
                    Layout.fillWidth: true
                    model: keygen.types
                    currentIndex: 2
                }
            }
    
            // Filename
            RowLayout {
                Label {
                    text: qsTr("Filename:")
                }
                TextField {
                    id: filename
                    implicitWidth: 200
                    onTextChanged: updateStatusBar()
                }
                Button {
                    text: qsTr("&Browse...")
                    onClicked: filedialog.visible = true
                }
            }
    
            // Passphrase
            RowLayout {
                Label {
                    text: qsTr("Pass phrase:")
                }
                TextField {
                    id: passphrase
                    Layout.fillWidth: true
                    echoMode: TextInput.Password
                    onTextChanged: updateStatusBar()
                }
    
            }
    
            // Confirm Passphrase
            RowLayout {
                Label {
                    text: qsTr("Confirm pass phrase:")
                }
                TextField {
                    id: confirm
                    Layout.fillWidth: true
                    echoMode: TextInput.Password
                    onTextChanged: updateStatusBar()
                }
            }
    
            // Buttons: Generate, Quit
            RowLayout {
                Button {
                    id: generate
                    text: qsTr("&Generate")
                    onClicked: keygen.generateKey()
                }
                Button {
                    text: qsTr("&Quit")
                    onClicked: Qt.quit()
                }
            }
    
        }
    
        FileDialog {
            id: filedialog
            title: qsTr("Select a file")
            selectMultiple: false
            selectFolder: false
            nameFilters: 
            selectedNameFilter: "All files (*)"
            onAccepted: {
                filename.text = fileUrl.toString().replace("file://", "")
            }
        }
    
        KeyGenerator {
            id: keygen
            filename: filename.text
            passphrase: passphrase.text
            type: combobox.currentText
            onKeyGenerated: {
                if (success) {
                    status.text = qsTr('<font color="green">Key generation succeeded.</font>')
                } else {
                    status.text = qsTr('<font color="red">Key generation failed</font>')
                }
            }
        }
    
        function updateStatusBar() {
            if (passphrase.text != confirm.text) {
                status.text = qsTr('<font color="red">Pass phrase does not match.</font>')
                generate.enabled = false
            } else if (passphrase.text.length > 0 && passphrase.text.length < 5) {
                status.text = qsTr('<font color="red">Pass phrase too short.</font>')
                generate.enabled = false
            } else if (filename.text == "") {
                status.text = qsTr('<font color="red">Enter a filename.</font>')
                generate.enabled = false
            } else {
                status.text = ""
                generate.enabled = true
            }
        }
    
        Component.onCompleted: updateStatusBar()
    }

    The preceding code is a little long, however, much of the work is laying out the GUI components. The code should be straightforward to follow.

    Note that we import com.ics.demo version 1.0. We’ll see where this module name comes from shortly. This makes a new QML type KeyGeneratoravailable and so we declare one. We have access to it’s C++ properties as QML properties, can call it’s methods and act on signals like we do withonKeyGenerated.

    A more complete program should probably do a little more error checking and report meaningful error messages if key generation fails (we could easily add a new method or property for this). The UI layout could also be improved to make it properly resizable.

    Our main program is essentially a wrapper like qmlscene. All we need to do to register our type with the QML engine is to call:

        qmlRegisterType<KeyGenerator>("com.ics.demo", 1, 0, "KeyGenerator");

    This makes the C++ type KeyGenerator available as the QML type KeyGenerator in the module com.ics.demo version 1.0 when it is imported.

    Typically, to run QML code from an executable, in the main program you would create a QGuiApplication and a QQuickView. Currently, to use the Qt Quick Components there is some additional work needed if the top level element is an ApplicationWindow or Window. You can look at the source code to see how I implemented this. I basically stripped down the code from qmlscene to the minimum of what was needed for this example.

    Here is the full listing for the main program, main.cpp:

    #include <QApplication>
    #include <QObject>
    #include <QQmlComponent>
    #include <QQmlEngine>
    #include <QQuickWindow>
    #include <QSurfaceFormat>
    #include "KeyGenerator.h"
    
    // Main wrapper program.
    // Special handling is needed when using Qt Quick Controls for the top window.
    // The code here is based on what qmlscene does.
    
    int main(int argc, char ** argv)
    {
        QApplication app(argc, argv);
    
        // Register our component type with QML.
        qmlRegisterType<KeyGenerator>("com.ics.demo", 1, 0, "KeyGenerator");
    
        int rc = 0;
    
        QQmlEngine engine;
        QQmlComponent *component = new QQmlComponent(&engine);
    
        QObject::connect(&engine, SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));
    
        component->loadUrl(QUrl("main.qml"));
    
        if (!component->isReady() ) {
            qWarning("%s", qPrintable(component->errorString()));
            return -1;
        }
    
        QObject *topLevel = component->create();
        QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
    
        QSurfaceFormat surfaceFormat = window->requestedFormat();
        window->setFormat(surfaceFormat);
        window->show();
    
        rc = app.exec();
    
        delete component;
        return rc;
    }

    In case it is not obvious, when using a module written in C++ with QML you cannot use the qmlscene program to execute your QML code because the C++ code for the module will not be linked in. If you try to do this you will get an error message that the module is not installed.

    Tags: , , , ,