Archive

Author Archive

Access #UK government #database of food establishments

share-default

If you’re developing an app or software that lists places to eat in the UK, it’s great to have a definitive database of every official food vending establishment in the UK, and Food.gov.uk provides this. The API is free, and doesn’t even require authentication. Here’s a sample

https://ratings.food.gov.uk/search-address/belfast/rating/1/100/json

Here’s the official docs

Click to access api-guidance.pdf

And here’s some NodeJS code that I wrote to parse this; (It’s taken from an Alexa app)

module.exports.List = function(city, callback) {

var response = “”;
var strUrl = “https://ratings.food.gov.uk/search-address/” + city + “/rating/1/100/json”;
request(strUrl, function (error, response, body) {
console.log(‘error:’, error); // Print the error if one occurred
console.log(body);
if (error == null)
{
var jBody = JSON.parse(body);
if (typeof jBody.FHRSEstablishment.EstablishmentCollection == “undefined”)
{
response = text.dyn().RESTAURANT_NONE
.replace(“{city}”, city );
callback(response);
return;
}
// Filter
var restaurants = jBody.FHRSEstablishment.EstablishmentCollection.EstablishmentDetail.filter(function(el){
return ( (el.PostCode || “”).indexOf(“BT”) == 0
&& el.BusinessTypeID == 1
&& el.AddressLine3.toLowerCase() == city.toLowerCase()
);
});
if (restaurants.length == 0)
{
response = text.dyn().RESTAURANT_NONE
.replace(“{city}”, city );
callback(response);
return;
}
var restaurantList = [];
restaurants.forEach(function(element){
restaurantList.push(element.BusinessName);
});
var strRestaurantList = customJoin(restaurantList, ” , “, ” ” + text.dyn().AND + ” ” );

response = text.dyn().RESTAURANT_LIST
.replace(“{city}”, city )
.replace(“{restaurantList}”, strRestaurantList );
callback(response);
}
});
};

function customJoin(arr,s1,s2){
return(arr.slice(0,-1).join(s1).concat(arr.length > 1 ? s2 : ”, arr.slice(-1)));
}

Hope this is useful to somebody!

Categories: Uncategorized

Find #Twitter #Influencers in your area, using #linqtotwitter

twitter

If you are promoting a product or service that is relevant only to a certain geographic area, i.e. a cafe or restaurant, then you might want to reach out to local twitter influencers – that is, people that carry alot of followers, and some might be amenable to tweet about your restaurant in return for a free meal.

Check out the demo at http://twitter.derrycreativescollective.com/

Or, if you’re a c# developer, and don’t need the use-case spelled out to you, then read on…

Here, I’ve used Linq2Twitter, which is FAR more stable than Tweetsharp, even though I do find the linq syntax a bit back-to-front.

It’s installed via Nuget as follows

Install-Package linqtotwitter

Now, What I’ve done, is created a web form page that returns JSON, which will be consumed by an ajax call. The call takes a strGeo parameter, which effectively is LAT,LON,RADIUS where radius, I’ve hard-coded to 10mi (10 miles)

You’ll need a Twitter developer account, and an App set up to get your authentication details, and you can’t use mine .. so they are excluded from the example below;

var auth = new SingleUserAuthorizer
{
CredentialStore = new SingleUserInMemoryCredentialStore
{
ConsumerKey = “…”,
ConsumerSecret = “…”,
OAuthToken = “….”,
OAuthTokenSecret = “…”
},
};
var twitterCtx = new TwitterContext(auth);
Search(twitterCtx, strGeo);

And the search method is as follows

void Search(TwitterContext twitterCtx, string geo)
{
var searchResponse =
(from search in twitterCtx.Search
where search.Type == SearchType.Search &&
search.Query == “a” &&
search.GeoCode == geo &&
search.Count == 100

select search)
.FirstOrDefault();

if (searchResponse.Statuses.Count == 0)
{
return;
}

if (searchResponse != null && searchResponse.Statuses != null)
{
var users = searchResponse.Statuses.Select(s =>
s.User).GroupBy(u =>
u.ScreenNameResponse).Select(g =>
g.FirstOrDefault()).OrderByDescending(u =>
u.FollowersCount).ToArray();
var jsSerializer = new JavaScriptSerializer();
var strJson = jsSerializer.Serialize(users);
Response.AppendHeader(“Access-Control-Allow-Origin”, “*”);
Response.Headers.Add(“Content-type”, “text/json”);
Response.Write(strJson);
}
}

This, searches a given geographic area for tweets, and grabs 100 of them. It then takes all the users that posted the tweets, removes duplicates, and orders by follower count. It then spits the lot out as JSON, with a CORS header added.

On the web side, I use Google to reverse geocode the city typed by the user, to get a lat / lon, using the following code

var address = $(“#tbLocation”).val();
geocoder.geocode({ ‘address’: address }, function (results, status) {
if (status === ‘OK’) {
var geoResult = results[0].geometry.location;
var strGeo = geoResult.lat() + “,” + geoResult.lng() + “,10mi”;
callAPI(strGeo);
} else {
alert(‘Geocode was not successful for the following reason: ‘ + status);
}
});

And, then I have defined callAPI as follows;

function callAPI(geo) {
console.log(“searching: ” + geo);
$.getJSON(“/PopularAjax.aspx?geo=” + geo,
function (data) {
$(“#btnSearch”).removeClass(“disabled”);
var tpl = $(“#tplItem”).html();
var strHtml = Mustache.render(tpl, data);
$(“#divResults”).html(strHtml);
});
}

Where I take the raw JSON returned by the AJAX and render it against a Mustache template, which is then injected into a Bootrap-based page.

Quite simple, but hopefully, it is useful to someone.

 

Categories: Uncategorized

#Database of over 15,000 Medical practices

Categories: Uncategorized

#Photoshop fix, colours messed up when pasting onto existing PNG

Normally I don’t post Photoshop tips on this blog, but this really got me.

With version 5.0.1 of Cordova iOS, it comes with an iconset of images with optimised colour palettes. This is fine to keep the image sizes low, but it causes a problem, if you want to use your own icons by copy-pasting-resizing an existing icon onto the new icon, suddenly, the colours are all messed up. See the coloured football on the top right?, that becomes the weird grey football on the bottom right!

The fix?, to Change the Image Mode from Indexed Color to RGB Color, like shown below.

Screenshot 2019-05-02 at 12.50.40

Categories: Uncategorized

Support #HTTP2 in your C# Client code

http2

If you use code such as WebClient to make HTTP requests from C#, then you’re probably using HTTP 1.1. if you want to use HTTP/2 then you need to write some extra code.

First, let’s prove that you’re using HTTP 1.1

WebClient wc = new WebClient();
var check1 = wc.DownloadString(“https://http2.pro/api/v1”);

and the response is

{“http2″:0,”protocol”:”HTTP\/1.1″,”push”:0,”user_agent”:””}

Now, to use HTTP 2, you need to override a setting here;

public class Http2CustomHandler : WinHttpHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
request.Version = new Version(“2.0”);
return base.SendAsync(request, cancellationToken);
}
}

And we can make a GET request like so;

public static string GetHtmlFromUrl(string Url)
{
var httpClient = new HttpClient(new Http2CustomHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate });
var resTask = httpClient.GetAsync(new Uri(Url));
var response = resTask.Result;
var strTask = response.Content.ReadAsStringAsync();
var strResponse = strTask.Result;
return strResponse;
}

And check again;

var check2 = GetHtmlFromUrl(“https://http2.pro/api/v1&#8221;);

Which yields

{“http2″:1,”protocol”:”HTTP\/2.0″,”push”:0,”user_agent”:””}

Hope this helps!

 

 

 

Categories: Uncategorized

SMTPJS.com now supports #BCC in #Javascript #Email

smtpjs

SMTPJs.com is a Javascript library for sending email from client-side Javascript (not node), it offers plenty of features for sending email, but one was missing until this morning, the ability to send BCC emails. (Blind Carbon-Copy)

It’s used just like the “To” field as follows

 Email.send({
            SecureToken : “…..”,
            To : [“salesguy@gmail.com“, “boss@gmail.com“] ,
            Bcc : [“private_admin@hotmail.com“, “Auditors@private.es“],
If Bcc is sent as an array, it can send to multiple addresses, or can be just a string, if you just want to send to one BCC.
Happy mailing …
Categories: Uncategorized

Temporary failure in name resolution #Fix #Linux #PHP

Firefox-having-DNS-issues-Ubuntu-17.04

If you get this error message in PHP,

php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution

Then you are either calling a domain name that doesn’t exist, or your DNS resolution has failed on your server. Assuming you haven’t mistyped the API url, then you can check for a DNS issue by SSH’ing into your server and trying to ping http://www.google.com and see if you get a response. – If that fails, then you need to fix your resolving DNS servers, and perhaps contact your host company too.

Google offer their own DNS resolving servers for free, and you can use them as follows;

sudo echo nameserver 8.8.8.8 > /etc/resolv.conf
sudo /etc/init.d/httpd restart

Which changes the DNS resolver on your server to Google’s server with IP 8.8.8.8, and then restarts your web server. You may use apache2 here instead of httpd – depending on your flavour of linux.

 

Categories: Uncategorized

Charge a Credit card using #Stripe and #Node

stripe

Stripe makes it super-easy to charge a credit card, here is an example from the command line:

var stripe = require(‘stripe’)(‘sk_test_…..’);

stripe.tokens.create({
card: {
number: ‘4242424242424242’,
exp_month: 12,
exp_year: 2020,
cvc: ‘123’
}
}, function(err, token) {
if (err != null)
{
console.log(“err:” + err);
}
else
{
console.log(“tokenid:” + token.id);
stripe.charges.create({
amount: 2000,
currency: “usd”,
source: token.id,
description: “Charge for 4242424242424242”
}, function(err, charge) {
if (err != null)
{
console.log(“err:” + err);
}
else {
console.log(“charge:” + charge.id);
}
});
}
});

 

Categories: Uncategorized

Proxy testing script in #NodeJs

img_56f57e1899a0f

Not going to win any awards, but here is a little script in Node.js to test if a proxy is working or not

const request = require(‘request’);
request({
‘url’:’http://icanhazip.com&#8217;,
‘proxy’:process.argv[2]
}, function (error, response, body) {
console.log(‘error:’, error); // Print the error if one occurred
console.log(‘statusCode:’, response && response.statusCode); // Print the response status code if a response was received
console.log(‘ip:’, body); // Print the HTML for the Google homepage.
});

It requires npm install request 

and is run like node proxycheck.js <ProxyAddress>

Categories: Uncategorized

Unit testing a AWS #Lambda function with #Cloudwatch

schedule_lambda_functions

Unit testing is primarily used to detect breaking code changes, but it can also be used to detect breaking changes in external environments, if run periodically.

So, imagine your code connects to an external database, that is operated by a third party. Perhaps they might suddenly change something without telling you, and your code breaks in the middle of the night, with no warning. In fact the first alert you’ll get will be an irate customer.

I’m assuming a serverless environment running Node on Lambda.

So, firstly, I set up a special entry point for my Lambda function, so that it knows it’s under test;  In my case, was the following

exports.handler = function (event, context) {

if (typeof event.request == “undefined”)
{
console.log(“Lambda called via Cloudwatch”);
console.log(event);
console.log(event.test);
testing.selectTest(event.test,function(){
context.succeed();
});
return;
}

Which, in my case, was if the lambda function was being called via cloudwatch, rather than alexa, it wouldn’t have a event.request element, but would have a event.test element.

Now, “testing” is a javascript file, which selects a test as follows;

module.exports.selectTest = function(testName,callback)
{

var testMethod = null;
if (testName == “testA”) testMethod = testA;

testMethod(
function(pass)
{
console.log(pass);
console.log(testName + ” passed”);
},
function(fail)
{
console.log(fail);
console.log(testName + ” failed”);
email.send({..} )

}

In this case, it would just console.log the output, unless, it failed, it would email me with the warning.

An individual test would be defined as

function testA(pass, fail)
{
myIntent.Search(function(result)
{
if(result == “Fail“)
{
fail(result);
}
else
{
pass(result);
}
});
}

myIntent.Search is outside of the scope of this example, but in this example, imagine it returns “Fail” on Failure, and some other string on success.

test1

Now, to schedule this regularly, then you create a CloudWatch Rule, where you set the event source to a schedule of 1 day (in my case), and the target to your lambda function. You set the input to a constant JSON text of {“test”: “testA”}, or whatever the name of your test is.

Hopefully, this will mean if someone unplugs your database, you will get an alert before your customers discover it’s down.

 

Categories: Uncategorized