Quantcast
Channel: Tech – Andy Balaam's Blog
Viewing all 154 articles
Browse latest View live

ZX Spectrum BASIC Web Server

$
0
0

Finally, you can write your web sites in ZX Spectrum BASIC, using my new project, ZX Spectrum BASIC CGI server .

How it works

Here’s what happens when a request comes in:

  • Apache HTTPD receives the request, and runs the CGI script that does the magic.
  • The CGI script (written in Bash) generates some BASIC code that provides the HTTP meta-vars (e.g. PATH_INFO for the path of the request) as DATA statements and wraps some other boilerplate around the code of the .basic file asked for in the request, and writes out another .basic file which is ready to be executed.
  • Then it uses BAS2TAP (my mirror here) to create an audio tape file representing the program.
  • Next it launches the Fuse spectrum emulator (inside an Xvfb wrapper to make it think it has a display), telling it to load from the audio tape and run the program.
  • The program runs, and writes its HTTP responses to the Spectrum printer using LPRINT statements.
  • Fuse uses very basic OCR to understand what characters are printed, and writes them into a text file.
  • The CGI script monitors the output file, waiting for a line containing an end marker (“ENDSPECTRUMBASIC”). When it finds it, it kills the emulator (since it can’t made to auto-exit, I think).
  • The CGI script sends the contents of the output file (minus the end marker) back to Apache, which returns it as a response.

Simple.

Why?

Originally designed to demonstrate how Docker can help isolate other services from “interesting” dependencies, this became a bit of a labour of love.

I’ll never stop being grateful to the designers of the ZX Spectrum, or the authors of “Further Programming for the ZX Spectrum”.


Difficult merges in Git – don’t panic!

$
0
0

A video in which I try to explain what merging and rebasing really are, to help you understand what is going on when Git presents you with scary-looking conflict messages. I also explain why you shouldn’t panic because it’s hard to lose your work, and how to get you work back if you really mess up:

Slides here: Difficult Merges in Git.

A commit represents the state of the world (and the history leading up to that state). A commit is not a diff.

Merging means making a new commit with two (or more) “parents” (previous commits) that represents the result of merging the changes from two different threads of development that happened separately. None of the already-committed commits are modified – you just get a new commit on top. History is more complicated, but true.

Rebasing means modifying the history of one thread of development so it looks like it happened after the other one. This involves modifying all the commits in that thread. There is no extra merge commit, so you lose the history of the merge that happened. History is simple, but it’s a lie, and if you messed up the rebasing process, you can’t get back to where you were (once your old commits have been garbage-collected).

Android: using a TextView to show rich text in an AlertDialog

$
0
0

If you want to display a link or basic formatting in an AlertDialog on Android, you can do it by providing HTML.

The key parts you need are Html.fromHtml and TextView.setMovementMethod.

Make sure you pass the dialog’s context in to the constructor of the TextView, not the context of the current activity. Otherwise the colours in your TextView will be wrong and you may well end up with black text on a dark grey background.

AlertDialog dialog = new AlertDialog.Builder( activity )
    .setTitle( t( world.name ) )
    .setPositiveButton( "Yes!" )
    .setNeutralButton( "Maybe?" )
    .create();

TextView view = new TextView( dialog.getContext() );
view.setText( Html.fromHtml( "<b>foo</b> <a href='#'>bar</a>" ) );
view.setMovementMethod( LinkMovementMethod.getInstance() );
view.setPadding( 10, 10, 10, 10 );

dialog.setView( view );
dialog.show();

If you are on API level 11+, you can use AlertDialog.Builder’s getContext() method, so you don’t have to create the dialog until the end.

Finding the download count of GitHub releases

$
0
0

You can use the GitHub API to find out how many times the files in your releases have been downloaded.

For example, to find out how many downloads there have been of my Rabbit Escape project you can do:

curl -s https://api.github.com/repos/andybalaam/rabbit-escape/releases | egrep '"name"|"download_count"'

Or you can look through the information manually by visiting a URL like https://api.github.com/repos/andybalaam/rabbit-escape/releases in your browser.

To get the total I came up with this beautiful incantation:

curl -s https://api.github.com/repos/andybalaam/rabbit-escape/releases | egrep 'download_count'  | cut '-d:' -f 2 | sed 's/,/+/' | xargs echo | xargs -I N echo N 0  | bc

Avoiding postfix error “status=deferred (unable to look up host”

$
0
0

My emails wouldn’t send when I was working from home, giving me this message in /var/log/mail.log:

Nov 11 12:38:16 machinename postfix/smtp[20672]: CF5D6D41CE2: to=, relay=none, delay=14416, delays=14416/0.01/0.07/0, dsn=4.3.5, status=deferred (Host or domain name not found. Name service error for name=relay.example.com type=AAAA: Host not found)

It turned out I was telling postfix not to use DNS to resolve the domain name of my mail relay server. There were several postfix config options I needed to remove to make this work:

# Make sure all of these are commented out or removed!
#default_transport = smtp
#relay_transport = smtp
#inet_protocols = ipv4
#smtp_host_lookup = native

The default values for these options are fine, but the ones shown above stop it working, so remove them or comment out with a # at the beginning of the line.

More at Postfix configuration parameters.

Using GitHub and GitLab

$
0
0

Taking all the Git understanding we’ve developed through the series on Git and applying it to how to work on and contribute to projects on GitHub and similar systems like GitLab:

Vim as editor for Claws Mail

$
0
0

I got sick of not having Vim as my text editor for emails in Claws Mail but GVim makes my eyes bleed so I wanted proper Vim-in-a-terminal as my editor, which was not particularly straightforward.

The proper incantation was to make a script in my PATH called terminal-vim like this:

#!/bin/bash

mate-terminal --disable-factory -x vim -f "$@"

(gnome-terminal should work similarly if you’re in GNOME.)

and to set it as my external editor in Claws Mail by going to Configuration, Preferences, External Programs, and setting Text Editor to terminal-vim '%s'.

Then under Writing in Preferences, I ticked the box “Automatically launch the external editor” and all is well.

New open source project on work time – git-history-data

$
0
0

Announcing a little open source project that I have built at work and been allowed to publish Freely.

git-history-data analyses a Git source code repository and dumps out data in a form that is easy to analyse.

I wrote an article demonstrating how to use it to find out some interesting information about the codebase of Git itself and got it published on IBM DeveloperWorks Open: Learning about the Git codebase using git-history-data.


What’s new in Java 8

$
0
0

Java 8 makes some functional programming ideas available to the rest of us, using Lambda, function references and a streaming style (map, filter, replace etc.):

Slides: What’s new in Java 8

Elm makes me happy

$
0
0

Elm lets you write interactive web sites in a really clean and safe-feeling way, which is a contrast to the feeling I get when using JavaScript and HTML. It’s functional, but instead of that making everything seem hard, it makes me happy.

Slides: Elm makes me happy

Elm Basics Video

$
0
0

Series: Snake in Elm, Elm makes me happy, Elm Basics

A lot of the documentation about the new language I am really excited about, Elm focusses on the Elm Architecture and the ideas of Functional Reactive Programming, and while those are the fundamental reasons I am interested in Elm, I found myself stuck on the syntax quite often.

So, in this video I review almost all the syntax and basic ideas you need to be able to read and write Elm code, treating it as a general programming language.

Update: forgot to add the slides – here they are:
Slides: Elm Basics

Gracefully shutting down Firefox, to avoid the crash/session dialog

$
0
0

I normally have several Firefox profiles open, and when I log out without closing the Firefox windows I get the “session restore” dialog on my next login.

This is because of Bug 336193 which says that Firefox should shut down gracefully when it receives a SIGTERM signal, which is what happens when I log out (in Ubuntu MATE anyway). At the moment, it shuts down ungracefully, meaning it is treated as if Firefox crashed when it restarts.

So, instead of my normal shutdown button, I have one that launches a script that closes all my Firefoxes first, like this:

#!/bin/bash

# Prerequisites:
# sudo apt-get install sysvinit-utils xdotool

set -x
set -u

function close_firefoxes()
{
    local PID
    local WID

    PID=$(pidof -s firefox)
    FOUND=$?

    while [ $FOUND ]; do
    {
        WID=$(xdotool search --pid "$PID" | tail -1)
        xdotool windowactivate --sync "$WID"
        xdotool key --clearmodifiers 'ctrl+q'
        sleep 1
        PID=$(pidof firefox)
        FOUND=$?
    }; done
}

close_firefoxes

mate-session-save --shutdown-dialog

How to write a programming language – Part 1, The Lexer

Mousedown events delayed or sluggish on mobile

$
0
0

I am learning about Elm and web apps by writing a little game called sootl.

It’s all SVGs animated with requestAnimationFrame(), and you control your player by clicking or touch the screen.

Everything seemed good on desktop browsers, but on mobile it took an age for the mousedown event to trigger when you touched.

Update: Thanks to @zatnosk on mastodon.social for letting me know there is a better way: 300ms tap delay, gone away. Short answer: add a <meta name="viewport" content="width=device-width"> tag inside your <head> tag.

It turns out that under certain circumstances, some mobile devices wait after the first touch happens to see whether you are going to swipe before they emit the mousedown event.

So, the short answer was to listen for touchstart events as well as mousedown ones. In Elm that looked like this change: e77e055e470c38489657ecaf5edc54a4e5f85782.

How to write a programming language – Part 2, The Parser


How to write a programming language – Part 3, The Evaluator

Writing a unit test in Elm

Setting up a sane Maven project

$
0
0

Today I have spent hours trying to get wrangle Maven into letting me set up a sane Java project. The hardest parts were enforcing warnings-as-errors, and getting Maven to shut up a bit.

Some code that warns

My first problem was writing some Java code that causes the compiler to emit warnings. For some reason I can’t understand, my Java 1.8 compiler was not emitting warnings (even with -Xlint:all) for unused variables, use of deprecated methods, or unknown @SuppressWarnings types (suggestions from SO 1752607).

Instead, I had to use an unnecessary cast:

$ cat src/tast/java/ExampleTest.java
public class ExampleTest {
    public void warn() {
        String fixmePlease = (String)"Hello";
    }
}

Now, finally, I got a warning:

$ javac -Xlint:all src/test/ExampleTest.java
src/test/ExampleTest.java:3: warning: [cast] redundant cast to String
        String s = (String) "Hello!";
                   ^
1 warning

Maven compiler settings for warnings-as-errors

I tried a vast set of combinations of properties like maven.compiler.failOnWarning and maven.compiler.fork (as specified in the maven compiler plugin docs) before giving up on properties. Making a property called maven.compiler.failOnWarning seems to have no effect whatsoever, ever.

So I decided I must try the (very verbose) plugin tag containing a configuration tag, as also specified in the maven compiler plugin docs. After a lot of messing about with flags that seemed incompatible, and Maven silently ignoring things it didn’t understand, I came to a working config.

On the way, I discovered that setting the “fork” property to true is a non-starter, because Maven simply drops the compiler output in that case, meaning you can’t see what is going wrong when it does.

Finally, I had a pom file like this:

cat pom.xml
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>Example</artifactId>
    <packaging>jar</packaging>
    <version>0.0.1</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <failOnWarning>true</failOnWarning>
                    <showWarnings>true</showWarnings>
                    <compilerArgs>
                        <arg>-Xlint:all</arg>
                    </compilerArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>
     <dependencies>
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <version>4.12</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
</project>

Which manages successfully to tell the compiler to show all warnings, and to fail when it sees one. (Thanks to SO 9192613, among others.)

I dare not change anything, for fear that it will stop working again without any explanation.

Quieting Maven

If you tell Maven to be quiet with -q or -e it will merrily fail the build because of a warning, but not tell you what the warning was.

Maven does not appear to have a command line option to set the log level to display warnings and errors only, but you can force it to do so by setting the environment variable MAVEN_OPTS like this:

MAVEN_OPTS=MAVEN_OPTS=-Dorg.slf4j.simpleLogger.defaultLogLevel=warn mvn clean test-compile

(Thanks to SO 4782089.)

And, with some guesswork (partly based on Configuring Maven) I found that if I put something similar in .mvn/jvm.config I didn’t have to type it every time:

$ cat .mvn/jvm.config 
-Dorg.slf4j.simpleLogger.defaultLogLevel=warn

Failing on warnings, and seeing them!

I don’t know whether to feel triumphant or defeated, but, it works!

$ mvn clean test-compile 
[WARNING] COMPILATION WARNING : 
[WARNING] src/test/java/ExampleTest.java:[3,20] redundant cast to java.lang.String
[ERROR] COMPILATION ERROR : 
[ERROR] src/test/java/ExampleTest.java: warnings found and -Werror specified
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.6.0:testCompile (default-testCompile) on project unmatcheddrrepair: Compilation failure
[ERROR] src/test/java/ExampleTest.java: warnings found and -Werror specified
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

I wish I could suppress double-reporting of the error, and the extra rubbish at the end (and the super-long absolute paths of each file that push the actual errors off the side of the screen), but at this point, I must try and do what I was trying to do in the first place.

Guess how much I am liking Maven at this point.

Resources for year 6 teachers on coding and programming

$
0
0

I have been introducing some year 6 (UK) teachers to coding by showing them how to lay out a simple web page by writing HTML. I promised I would find some links to resources for them, so here it is:

HTML and JavaScript

My examples of how to write HTML are at github.com/andybalaam/html-examples

There are several web sites that allow you to experiment with writing HTML and JavaScript and seeing the results immediately:

I also made some videos about how to make a snowflake animation in both JavaScript and Scratch here: Snowflake Christmas card.

Raspberry Pi

The Raspberry Pi is a cheap education-focussed computer that looks like a piece of circuit board the size of a credit card.

Their educational resources are at: raspberrypi.org/resources.

There are lots of great videos about how to do different things with the Raspberry Pi, including the ones by The Raspberry Pi Guy.

There are also my (boring, but comprehensive) videos teaching you to write a simple game in Python, from a starting point of no programming experience at all: My First Raspberry Pi Game.

Graphical programming

There are several tools and sites for learning programming by dragging and dropping blocks instead of typing code:

  • Scratch – creative, unguided, a bit old-fashined looking but tried-and-trusted
  • code.org – fun, attractive guided tasks featuring Disney characters, Minecraft etc.
  • blockly – guided tasks with good progression
  • codeforlife.education – I’ve not used this, but it looks like it could have potential

Other languages

Submitting a package to F-Droid

$
0
0

Here’s what I needed to get a dev environment for F-Droid up and running on Ubuntu 16.10, using F-Droid server version 0.7.0 (commit id 8147f9235), so that I could submit a package for inclusion in the F-Droid repository.

Doing this is apparently the best way to get your own package into the repository, since you can provide a direct merge request for the metadata about your package, making it easy for the maintainers.

References:

Setup

Before you start, manually install the Android SDK at ~/Android/Sdk/ – see Download Android Studio. I installed version 23.0.2, but you will probably have a later one and may need to adjust the version number below.

Note: If you’re only planning to contribute a package I’m fairly certain you don’t need to install the Android SDK at all – you can just use the build server by running ./makebuildserver as I outline below.

Also before you start, if you want to contribute to the server project you should fork the F-Droid server project by going to gitlab.com/fdroid/fdroidserver and clicking Fork. When you’ve done that, the git clone command below will need to change to clone your own fork via SSH, instead of the HTTPS one cloning the main repo that is shown below. Do the same for the F-Droid data project, which holds the information about the packages in F-Droid. It’s the data project where you will want to make changes if you are submitting a package.

Run these commands:

# Prerequisites
sudo apt-get install openjdk-8-jdk subversion git git-svn mercurial bzr virtualbox ruby ruby-dev vagrant python3 python3-paramiko python3-pil python3-pyasn1-modules python3-clint
vagrant plugin install vagrant-cachier
ln -s ~/Android/Sdk/build-tools/23.0.2/aapt ~/Android/Sdk/platform-tools/

# Get the code
cd ~/code
git clone https://gitlab.com/fdroid/fdroidserver.git
git clone https://gitlab.com/fdroid/fdroiddata.git
echo 'export PATH="~/code/fdroidserver:$PATH"' >> ~/.profile
source ~/.profile

# Config
cd fdroiddata
cp ../fdroidserver/examples/config.py ./
chmod 0600 config.py
echo 'sdk_path = "$HOME/Android/Sdk"' >> config.py

# Set up Vagrant build box
cd ../fdroidserver
cp ./examples/makebuildserver.config.py ./
./makebuildserver
# Now wait several hours for this to finish

# Build a package (the F-Droid client) just to check it works
cd ../fdroiddata
mkdir repo
fdroid update --create-key
fdroid readmeta  # Should give no output if it worked
fdroid build --server org.fdroid.fdroid

Make your own package

Below I’m using my own package, Rabbit Escape, as an example. Its Android code is inside rabbit-escape-ui-android/app, whereas many programs will just have it directly in a directory called “app”.

Rabbit Escape also builds non-Android-specific Java and other things during its build, so your package may be simpler.

cd ../fdroiddata
fdroid import --url https://github.com/andybalaam/rabbit-escape --subdir rabbit-escape-ui-android/app

Now edit the new file that was created – in my case it was called metadata/net.artificialworlds.rabbitescape.txt.

I set the following info:

Provides:net.artificialworlds.rabbitescape
Categories:Games
License:GPLv2+
Author Name:Andy Balaam and the Rabbit Escape developers
Author Email:rabbitescape@artificialworlds.net
Web Site:http://artificialworlds.net/rabbit-escape
Source Code:https://github.com/andybalaam/rabbit-escape
Issue Tracker:https://github.com/andybalaam/rabbit-escape/issues

Name:Rabbit Escape
Summary:Lemmings-like puzzle/action game
Description:
140 levels of puzzling action!

blah blah blah
.

Repo Type:git
Repo:https://github.com/andybalaam/rabbit-escape
Binaries:https://github.com/andybalaam/rabbit-escape/releases/download/v%v/rabbit-escape-%v.apk

Build:0.10.1,101
    commit=v0.10.1
    subdir=rabbit-escape-ui-android/app
    gradle=paid
    build=cd ../.. && make android-pre

Auto Update Mode:Version v%v
Update Check Mode:Tags v\d+\.\d+(\.\d+)?
Current Version:0.10.1
Current Version Code:101

For more info, see the F-Droid manual.

And then checked it all worked with:

cd ../fdroiddata
fdroid lint net.artificialworlds.rabbitescape
fdroid readmeta
fdroid checkupdates net.artificialworlds.rabbitescape
fdroid rewritemeta net.artificialworlds.rabbitescape

When I got the version stuff right the checkupdates command printed:

INFO: Processing net.artificialworlds.rabbitescape...
INFO: ...updating to version 0.10.1 (101)
INFO: Finished.

Then I made sure it built OK:

fdroid build --server -v -l net.artificialworlds.rabbitescape

Actually, it didn’t work, and I decided I had to request a new package (sox) be installed in the build machine environment (in the fdroidserver project). The relevant commit is here: 19e372026. Actually though, after discussion with the F-Droid devs we agreed I’d be better off not using sox during the build, so I didn’t need this.

Side note: if you do end up needing to modify the build environment for F-Droid, make sure you delete the fdroiddata/buildserver directory when you re-try your build. That one had me stuck for a few days, with the old environment being used no matter what caches I cleared and vagrant commands I ran.

And now I was ready to request my package be included in F-Droid by committing and pushing the changes I had made to the fdroiddata project to my forked repo, and clicking the Merge Request button in the gitlab UI.

Viewing all 154 articles
Browse latest View live




Latest Images