Archive

Author Archive

#Docmail #API part 2 #Custom #envelopes

dmlogo_b

I wrote an earlier post on Docmail, where I demonstrated how to send physical mail via C#, one of the things I found, was that it sends a windowed envelope, and overlays the address on the first page of the document you want to send. If you’ve designed your document around this, it shouldn’t be a problem – and you can always add an extra blank page to the start of your PDF (at an extra cost), however, the correct solution, is to send a custom envelope, with the address on the outside.

    public class DocMailAddress
    {
        public string FirstName;
        public string Surname;
        public string Address1;
        public string Address2;
        public string Address3;
        public string Address4;
        public string FullName {
            get
            {
                return FirstName + " " + Surname;
            }
        }
    }

    public class DocMailHandler
    {

        static string sUsr = "username";

        static string sPwd = "password";

        static string sReturnMessageFormat = "Text";

        static string sAppName = "your app";
        static string sMailingName = "your app";

        static string sMailingDesc = "your app";
  

        static string sEmailOnError = "info@you.com";
        static string sEmailOnSuccess = "info@you.com";


        public static void SendFile(DocMailAddress Address, string PDF)
        {
            DMWS.DMWSSoapClient oService = new DMWS.DMWSSoapClient();
            Hashtable oResultHash = default(Hashtable);
            Guid gMailingGUID = default(Guid);
            Guid gTemplateGUID = default(Guid);
     
            // Create a mailing
            oResultHash = ResultHashTable(oService.CreateMailing(sUsr, sPwd, sAppName, "A4Letter", sMailingName, sMailingDesc, false, false, "StandardProofPerAddress", false,
            true, DateTime.Now, "", "Full Name", "", "CustomNoPanel", sReturnMessageFormat));
            CheckError(oResultHash);
            //get MailingGUID - required to continue the mailing
            gMailingGUID = GetResultGUID(oResultHash, "MailingGUID");

            // Add envelope
            oResultHash =
                ResultHashTable(oService.AddTemplateFromLibrary(sUsr, sPwd, gMailingGUID, "Outer envelope", 1,
                    sReturnMessageFormat));
            CheckError(oResultHash);

            // Add a template
            oResultHash = ResultHashTable(oService.AddTemplateFile(sUsr, sPwd, gMailingGUID, "Deemtree", "Deemtree", OpenFileAsByteArray(PDF), "A4Letter", true, "Arial 10", "",
            "", false, false, "", "", false, 1, 1, "", false,
            sReturnMessageFormat));
            CheckError(oResultHash);
            //get templateGUID  - can be passed in to other calls
            gTemplateGUID = GetResultGUID(oResultHash, "TemplateGUID");

           
            oResultHash = ResultHashTable(oService.AddAddress(sUsr, sPwd, gMailingGUID, Address.Address1, Address.Address2, Address.Address3, Address.Address4, "", "", true, "", Address.FirstName, Address.Surname, Address.FullName, "", "", "", "", "", "", "", "", "", "", "", 0, 0, 0, "", "", "", "", "", "", "", "", "", "", ""));
            CheckError(oResultHash);
           
            //The following code submits a mailing for processing, automatically approving the order (Submit=true, PartialProcess=false)
            oResultHash = ResultHashTable(oService.ProcessMailing(sUsr, sPwd, gMailingGUID, sAppName, true, false, 0, "", "Topup", true,
            sEmailOnError, sEmailOnSuccess, "", "", sReturnMessageFormat));
            CheckError(oResultHash);

            //The following code checks the status, looping until the proof is ready and then saves the proof file to disk
            do
            {
                oResultHash = ResultHashTable(oService.GetStatus(sUsr, sPwd, gMailingGUID, sReturnMessageFormat));
                CheckError(oResultHash);
                var strStatus = Convert.ToString(oResultHash["Status"]);
                bool blnDone = false;
                switch (strStatus)
                {
                    case "Error in processing":
                        blnDone = true;
                        // Error trapping code add here ...
                        break;
                    case "Mailing submitted":
                    case "Mailing processed":
                    case "Partial processing complete":
                        // You Save the proof to disk
                        blnDone = true;
                        break;
                }
                if (blnDone) break;
                System.Threading.Thread.Sleep(1000);
                // Wait one second between each poll
            } while (true);

        }

      
        #region "Support Functions"
        //The following function convertes a text result string into a hash table for easy access to the return data: 
        private static Hashtable ResultHashTable(string ResultData)
        {
            Hashtable oHashTable = new Hashtable();
            if (!string.IsNullOrEmpty(ResultData))
            {
                foreach (string sLine in ResultData.Split(new[] { '\n' }))
                {
                    if (!string.IsNullOrEmpty(sLine))
                    {
                        int iIndex = sLine.IndexOf(": ");
                        string sKey = sLine.Substring(0, iIndex);
                        string sData = sLine.Substring(iIndex + 2, sLine.Length - iIndex - 2);

                        oHashTable.Add(sKey, sData);
                    }
                }
            }
            return oHashTable;
        }

        private static void CheckError(Hashtable oResultHash)
        {
            if (oResultHash.ContainsKey("Error code"))
                throw new Exception(string.Format("Error {0}: {1} - {2}", oResultHash["Error code"], oResultHash["Error code string"], oResultHash["Error message"]));
        }

        private static Guid GetResultGUID(Hashtable oResultHash, string sField)
        {
            Guid functionReturnValue = default(Guid);
            functionReturnValue = new System.Guid(Convert.ToString(oResultHash[sField]));
            if (functionReturnValue == Guid.Empty)
                throw new Exception(sField + " Contained a blank or invalid GUID");
            return functionReturnValue;
        }

        //The following function opens a file as a byte array: 
        private static byte[] OpenFileAsByteArray(string FilePath)
        {
            System.IO.FileStream oFileStream = System.IO.File.OpenRead(FilePath);
            int iBytes = Convert.ToInt32(oFileStream.Length);
            byte[] oByteArray = new byte[iBytes];
            oFileStream.Read(oByteArray, 0, iBytes);
            oFileStream.Close();
            return oByteArray;
        }

        //The following sub routine saves a byte array to a file: 
        private static void SaveFromByteArray(byte[] FileData, string FilePath)
        {
            using (System.IO.FileStream oFileStream = new System.IO.FileStream(FilePath, System.IO.FileMode.Create))
            {
                oFileStream.Write(FileData, 0, FileData.Length);
                oFileStream.Close();
            }
        }

        #endregion
    }
Categories: Uncategorized

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

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