Archive

Archive for February, 2017

Own domain email #forwarding #API #MX

own-email

Just added a new feature to http://www.domaindeflect.com/ – the ability to set up a catch all email forwarder on your own domain, for free.

Although quite a number of Domain registrars offer this service for free, i.e namecheap, and there is a number of paid services that offer more customisation, (Postmark , Mailgun etc.) I’ve fond the ImprovMX offers a great simple option.

It offers you the ability to forward  *@youdomain.com to a single email address. There is no further options available, but that’s what I’d say most people would want.

All you do, is set your DNS MX records on your domain as follows;

Host Value Priority
@ mx1.improvmx.com 10
@ mx2.improvmx.com 20

And, once that’s done, you enter it into the website, and press “Submit”, and if the DNS has been set correctly, your email will forward immediately.

 

Categories: Uncategorized

Basic #HelloWorld for AWS #Lambda #NodeJS

aws_simple_icons_compute_awslambda-svg_

Amazon Lambda allows you to host NodeJS code (And python, Java and c#, I believe) – and expose this as an API. Excellent if you want a scalable back-end without worrying about servers.What they call a “serverless” environment

So, I wanted to create an API that echos back what is posted to it, in NodeJS.

I  created the following service with no authentication with an API gateway trigger

exports.handler = (event, context, callback) => {
if(event.body !== undefined)
{
event = JSON.parse(event.body);
}
var response = {
statusCode: 200,
body: event.key1
};
callback(null, response);
};

Then, you need to find the endpoint, which is under the Triggers tab.

You can then call the endpoint using CURL as follows

curl -H “Content-Type: application/json” -X POST -d “{\”key1\”: \”Echo\”}” https://0vuu0520rb.execute-api.eu-west-1.amazonaws.com/prod/Echo

And you get “Echo” as the response.

Note the line of code, where I check if event.body is null?, that’s because the test environment passes event as a top level element, where as if you use CURL, then event contains other data as follows;

{
  "resource": "\/Echo",
  "path": "\/Echo",
  "httpMethod": "POST",
  "headers": {
    "Accept": "*\/*",
    "CloudFront-Forwarded-Proto": "https",
    "CloudFront-Is-Desktop-Viewer": "true",
    "CloudFront-Is-Mobile-Viewer": "false",
    "CloudFront-Is-SmartTV-Viewer": "false",
    "CloudFront-Is-Tablet-Viewer": "false",
    "CloudFront-Viewer-Country": "GB",
    "Content-Type": "application\/json",
    "Host": "0vuu0520rb.execute-api.eu-west-1.amazonaws.com",
    "User-Agent": "curl\/7.44.0",
    "Via": "1.1 0742a501f4d29312ad9cbc7b7bf143c7.cloudfront.net (CloudFront)",
    "X-Amz-Cf-Id": "XSbyOJGd3tAQI7uSbCyXK_4hbl1gAgskB-bs_R2ICKiznMzxUMbVfw==",
    "X-Amzn-Trace-Id": "Root=1-58ac43b8-4d359d6d43b15ade30527656",
    "X-Forwarded-For": "xxx.xxx.xxx.xxx",
    "X-Forwarded-Port": "443",
    "X-Forwarded-Proto": "https"
  },
  "queryStringParameters": null,
  "pathParameters": null,
  "stageVariables": null,
  "requestContext": {
    "accountId": "005445879168",
    "resourceId": "uzexyk",
    "stage": "prod",
    "requestId": "8ea18e1c-f83b-11e6-9cd3-fdd324d2159e",
    "identity": {
      "cognitoIdentityPoolId": null,
      "accountId": null,
      "cognitoIdentityId": null,
      "caller": null,
      "apiKey": null,
      "sourceIp": "xxx.xxx.xxx.xxx",
      "accessKey": null,
      "cognitoAuthenticationType": null,
      "cognitoAuthenticationProvider": null,
      "userArn": null,
      "userAgent": "curl\/7.44.0",
      "user": null
    },
    "resourcePath": "\/Echo",
    "httpMethod": "POST",
    "apiId": "0vuu0520rb"
  },
  "body": "{event:{\"key1\": \"User\",\"key2\": \"User\",\"key3\": \"User\"}",
  "isBase64Encoded": false
}

All very interesting, now try a more real example, let’s say we want to wrap Google’s direction API within an AWS lamda; – which I’ve implemented as follows;

exports.handler = (event, context, callback) => {
if(event.body !== undefined)
{
event = JSON.parse(event.body);
}
var strUrl = “/maps/api/directions/json?”;
strUrl += “origin=” + event.from;
strUrl += “&destination=” + event.to;
strUrl += “&sensor=false”;
console.log(strUrl);
var https = require(‘https’);

var options = {
host: ‘maps.googleapis.com’,
port: 443,
path: strUrl,
method: ‘GET’,
accept: ‘*/*’
};

var req = https.request(options, function(res) {
var strData = “”;
res.on(‘data’, function(d) {
strData += d;
});
res.on(‘end’, function(d) {
var jData = JSON.parse(strData);
var strSteps = “”;
for(i =0; i<jData.routes[0].legs[0].steps.length;i++)
{
var step = jData.routes[0].legs[0].steps[i];
strSteps += step.html_instructions.replace(/(<([^>]+)>)/ig,” “) + “\r\n”;
}
var response = {
statusCode: 200,
body: strSteps
};
callback(null, response);
console.log(strSteps);
});
});
req.end();

req.on(‘error’, function(e) {
console.error(e);
callback(null, e);
});
};

Which would be called via CURL as follows

curl -H “Content-Type: application/json” -X POST -d “{\”from\”: \”Oxford\”,\”to\”: \”Bristol\”}” https://0vuu0520rb.execute-api.eu-west-1.amazonaws.com/prod/Directions

Which gives the following output

Head north on Shoe Ln
Turn left to stay on Shoe Ln
Turn right onto New Inn Hall St
Turn left onto George St
Continue onto Hythe Bridge St / A4144
At the roundabout, continue straight onto Park End St / A420 Continue to follow A420 Go through 1 roundabout
Turn right to stay on A420
At the roundabout, take the 2nd exit and stay on A420
At the roundabout, take the 2nd exit and stay on A420
At the roundabout, take the 2nd exit and stay on A420
At the roundabout, take the 3rd exit and stay on A420
At Gablecross , take the 2nd exit and stay on A420
At White Hart , take the 1st exit
Take the A419 (South) ramp on the right to M4 / Marlborough / A346 / Chisledon
Merge onto A419
At Badbury Roundabout , take the 3rd exit onto the M4 ramp to South Wales / Bristol / Swindon (W)
Merge onto M4
At junction 19 , exit onto M32 toward Bristol
Continue onto Newfoundland St / A4032 Continue to follow A4032
Slight left onto Temple Way / A4044 Continue to follow A4044
At the roundabout, take the 3rd exit onto Victoria St / B4053
Turn right onto Counterslip
Continue onto Passage St

Categories: Uncategorized

Indian Car loan database available for download

Categories: Uncategorized

Force touch #Javascript #3DTouch

force-touch-642x347

Force touch is a feature of iPhone 6S and above, and Android N devices (Huawei 7P) – it’s by no means widely supported, but if you fancy doing something special for your high-end users, then it’s an option to use for a “hidden feature” or shortcut. – A Peek to view master-detail anyone?

In Javascript it’s easily implemented; touchforcechange event, and ensure that “force” is set to 1 (maximum). If you don’t check the “force” value, then this will react to gentle clicks too – confusing the interface with the”click” event.

var element = document.getElementById(‘forceMe’);
function addForceTouchToElement(elem) {

elem.addEventListener(‘webkitmouseforcechanged’, onClickForceChange, false);
elem.addEventListener(‘touchforcechange‘, onTouchForceChange, false);
}

function onClickForceChange(e) {
alert(“onClickForceChange”);
}

function onTouchForceChange(e) {
if (e.changedTouches[0].force == 1)
{
alert(“onTouchForceChange”);
}
}
addForceTouchToElement(element);

 

Categories: Uncategorized

HTTP #Proxy #API by country

proxy1-neg

Looking to make your HTTP request appear to come from a particular country?, we’ve got an API for that…

http://proxy.apixml.net/

There’s no business model behind this yet, so it’s all free. But the proxies listed are checked daily, and must exceed 50% reliability and under 3 seconds latency before they are listed. – There’s an API, so you can request by country.

Here’s some sample data of US proxies:

Address Reliability (%) Last Checked
Address Reliability (%) Last Checked
http://104.199.146.27:3128 100 2/16/2017 2:05:27 AM
http://107.178.4.214:8181 80 2/16/2017 2:04:44 AM
http://138.197.21.105:8080 100 2/16/2017 2:05:04 AM
http://173.192.21.89:8123 100 2/16/2017 2:02:02 AM
http://205.234.15.12:80 60 2/15/2017 8:50:45 AM
http://35.162.243.238:8083 100 2/16/2017 2:05:38 AM
http://35.185.23.131:80 100 2/16/2017 2:04:32 AM
http://35.185.57.41:80 100 2/16/2017 2:05:43 AM
http://40.138.64.36:8080 60 2/15/2017 8:52:21 AM
http://47.52.2.135:8080 100 2/16/2017 2:02:58 AM
Categories: Uncategorized

Call an #ASMX #webservice with #Android

curso-android-net

This may not be the best way to call a Microsoft .NET ASMX webservice via Java for Android, but it seems to work OK for my needs. All you need to do, is call it asynchronously, and handle the data returned.

Here’s my class that I’m using to call the ASMX webservice;

package uk.org.regcheck.regcheck;

import android.os.AsyncTask;

import android.util.Log;

import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;



public class RegCheckAPI extends AsyncTask<String, String, String> {

    DataDownloadListener dataDownloadListener;
    public static interface DataDownloadListener {
        void dataDownloadedSuccessfully(String data);
        void dataDownloadFailed();
    }


    public void CheckUK(String RegistrationNumber,String username)
    {
        try {
            this.execute("https://www.regcheck.org.uk/api/reg.asmx/Check?" +
                    "&RegistrationNumber=" + URLEncoder.encode(RegistrationNumber, "utf-8") +
                    "&username=" + URLEncoder.encode(username, "utf-8"));
            Log.i(RegistrationNumber, username);
        }
        catch(UnsupportedEncodingException ex){
            Log.i("error",ex.getMessage());
        }
    }

    @Override
    protected String doInBackground(String... uri) {
        String responseString = "";
        try {
            URL url = new URL(uri[0]);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            InputStream in = new BufferedInputStream(urlConnection.getInputStream());
            responseString = new String(readFully(in), "utf-8");
        }
        catch(IOException ex)
        {
            responseString = ex.toString();
        }
        return responseString;
    }

    private byte[] readFully(InputStream inputStream)
            throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length = 0;
        while ((length = inputStream.read(buffer)) != -1) {
            baos.write(buffer, 0, length);
        }
        return baos.toByteArray();
    }

    @Override
    protected void onPostExecute(String result) {
        if(result != null)
        {
            try {
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = factory.newDocumentBuilder();
                Document doc = builder.parse(new InputSource(new StringReader(result)));
                NodeList nJson = doc.getElementsByTagName("vehicleJson");
                String strJson = nJson.item(0).getTextContent();
                JSONObject jObject = new JSONObject(strJson);
                String strDescription = jObject.getString("Description");
                dataDownloadListener.dataDownloadedSuccessfully(strDescription);
            }
            catch(Exception ex)
            {
                dataDownloadListener.dataDownloadFailed();
            }
        }
        else
            dataDownloadListener.dataDownloadFailed();

    }
}

 

Then my main activity is as follows;

package uk.org.regcheck.regcheck;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

TextView t = (TextView)findViewById(R.id.tbOutput);
t.setText(“Please wait…”);

RegCheckAPI api = new RegCheckAPI();
api.dataDownloadListener = (new RegCheckAPI.DataDownloadListener()
{
@SuppressWarnings(“unchecked”)
@Override
public void dataDownloadedSuccessfully(String data) {
TextView t = (TextView)findViewById(R.id.tbOutput);
t.setText(data);
}
@Override
public void dataDownloadFailed() {
// handler failure (e.g network not available etc.)
TextView t = (TextView)findViewById(R.id.tbOutput);
t.setText(“Failed”);
}
});
api.CheckUK(“{{valid UK plate}}”,”{{Your username here}}”);
}
}

Categories: Uncategorized

A simple app to learn #HTML and #CSS on your iPhone

175x175bb

Just starting to learn HTML and CSS? want an environment you can take with you in your pocket?

We’ve just re-launched our HTMl & CSS iOS app, with a fresh new interface; which you can download from here;

https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=464094473&mt=8

Categories: Uncategorized

Domain Deflect #app just launched #IOS

175x175bb

Domain deflect is a new app available for iOS, which allows you use a custom domain name on an existing website that you do not host – for example, it’s a free website provider, and they want you to pay to connect your own domain instead of using their freely allocated subdomain.

There are other applications too, like if you just don’t have full access to the webserver that is hosting your website – like many shared hosting environments may limit the number of domains you use, or want to charge extra for this.

Or simply, you don’t have the will or desire to figure out how to configure your Linux server via some archaic command line interface, but your website is running on the wrong domain name.

It’s SEO friendly, and this isn’t a 301 redirect, or cloak, it’s more akin to the CDN type systems employed by Amazon Cloudfront, although not geo-redundant.

If you think this would be useful – please download the app here: https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=521448034&mt=8

 

 

Categories: Uncategorized

Use your computer’s spare time to help #cure #diseases. @rosettaathome

rosetta

If  you leave your office PC on all night, whether to tun nightly tests, or long tasks, then there is something more useful you can do with your computer’s time, that can really give back to society.

By installing Rosetta@home (boinc.bakerlab.org) – your computer can be used to run virtual experiments on proteins that could one day lead to a cure to a disease.

It doesn’t  lock up your computer, your computer is still usable, and you can pause it whenever you want. It just means that your PC can do something truly useful during the night, when it would normally just be consuming electricity.

But what is the experiment?, I’m not a biologist, so I can just say in layman’s terms. – Our bodies have DNA in every cell. DNA is nature’s way of encoding millions of different types of Proteins. These are chemicals that do everything the body needs, literally.

Proteins are encoded in blocks called “Amino acids”, which are chained together, then curl up into complex 3D shapes. It is the shape of these chemicals that define the function of the Protein, and thus, what it does, and more importantly, if it can be modified to do something else – perhaps preventing a virus entering a cell, or recognising a cancer.

These complex shapes are often not experimentally view-able in the real world, if the protein cannot be made in enough quantity to be seen under under NMR or X-Rays – so it’s up to computers to take these long chains of amino acids, and fold them virtually, to a point where the shape is stable, and of least energy. It’s like having a thousand elastic bands tied together, and seeing what shape it would fall into when it fell.

So, It’s great work, and if your computer needs to be left on, then this is a great way to use it’s spare capacity for the betterment of society. Of course, if it doesn’t need to be left on, then turn it off, and stop contributing to global warming ! 🙂

 

Categories: Uncategorized

Create your own #AudioBooks with C#

audio-book

Say you’ve got a book in text format; for example a book from Gutenberg.org, and you’d like to convert it to mp3, so you can listen to the book – read by a machine, of course.

Here’s the code in C#

WebClient wc = new WebClient();
var strUrl = “{{Wherever your ebook text is}}”;
var strText = wc.DownloadString(strUrl);
var strPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
using (SpeechSynthesizer reader = new SpeechSynthesizer())
{
reader.Volume = 100;
reader.Rate = 0; //medium
MemoryStream ms = new MemoryStream();
reader.SetOutputToWaveStream(ms);//do speaking
reader.Speak(strText);
ConvertWavStreamToMp3File(ref ms, strPath + @”\54135.mp3″);
}

You need to install the Nuget package: Install-Package NAudio.Lame for the mp3 functionality. ConvertWavStreamToMp3File is defined as:

public static void ConvertWavStreamToMp3File(ref MemoryStream ms, string savetofilename)
{
//rewind to beginning of stream
ms.Seek(0, SeekOrigin.Begin);

using (var retMs = new MemoryStream())
using (var rdr = new WaveFileReader(ms))
using (var wtr = new LameMP3FileWriter(savetofilename, rdr.WaveFormat, LAMEPreset.VBR_90))
{
rdr.CopyTo(wtr);
}
}

To give an idea of filesizes, I used an input file of 33,790 words, which resulted in a WAV file on 705MB, and Mp3 file of 63 MB.

Which you can hear here:
https://app.box.com/s/vb5jsaria7sd9iaxdrbguz58ufqwo0co

Of course, if you prefer to read a Gutenberg book onscreen, then you can use our app:

https://itunes.apple.com/us/app/book-searcher/id464083711?mt=8

This can further be converted to a FLV using FFMPEG ;

ffmpeg -i audio-book.jpg -i 54135.mp3 final.flv

Which takes about 2 minutes, an generates a 73 MB FLV file.

Categories: Uncategorized