Archive

Archive for March, 2015

PUT Request with HttpWebRequest

try
{
string str = “test”;
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] arr = encoding.GetBytes(str);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(“url”);
request.Method = “PUT”;
request.ContentType = “text/plain”;
request.ContentLength = arr.Length;
request.KeepAlive = true;
Stream dataStream = request.GetRequestStream();
dataStream.Write(arr, 0, arr.Length);
dataStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string returnString = response.StatusCode.ToString();
}
catch {}

Credit to S.Vinothkumar for this code

Categories: Uncategorized

Manually installing Twitter Plugin for Cordova (ios)

I always wished that Cordova would have come as default with a whole kitchen-sink full of plugins pre-installed as default, as it used to in the early days, when it was still called Phonegap. But alas, you have to install a plethora of basic functionality as plugins now. I guess it keeps app lean and small, and It’s just the way it is.

Anyway, I normally start an app from the command line, and include every plugin I think I would need, then once I’m happy with a “Hello World”, build the app, and then start working from XCode instead of the command line.

However, this does lead to a problem, whenever I want to add a new plugin after moving to XCode. It is much much much easier to use the command line tools to add a plugin automatically, using something like

cordova plugin add https://github.com/etiennea/phonegap-twitter-plugin.git

However, this post is for people who can’t do this, and have to resort to manually installing a plugin

So, the first step is to look at the plugin.xml, and see what is required, which boils down to three parts

<js-module src=”www/TwitterPlugin.js” name=”TwitterPlugin”>
<clobbers target=”Twitter” />
</js-module>

Which equates to a change in cordova_plugins.js with this code:

{
“file” : “plugins/TwitterPlugin.js”,
“id” : “TwitterPlugin”,
“clobbers”: [
“Twitter”
]
}

Next, is you look at this bit of XML:

<feature name=”TwitterPlugin”>
<param name=”ios-package” value=”TwitterPlugin” />
</feature>

Which you copy verbatim into the config.xml

<header-file src=”src/ios/TwitterPlugin.h” />
<source-file src=”src/ios/TwitterPlugin.m” />

Those files, just mean that you add the header and module file into your project, in the plugins folder

<framework src=”Twitter.framework” />
<framework src=”Accounts.framework” weak=”true” />

Mean that you have to add those frameworks (see Build Phases > Linked libraries) before the code will compile

Now, the real gotcha, is that if you try to copy/paste the javascript file into the project, it will cause a JavaScript exception because it won’t recognise “require” or “module”… This is because you need to modify the Javascript file by adding the call

cordova.define("TwitterPlugin", function(require, exports, module) {. <file contents>..}

The experienced JavaScript developer will see where “require” and “module” come from now!

Categories: Uncategorized

Process stored proc data from within another in stored proc

Say you have one stored procedure, that returns a very wide table; i.e. lots of columns – or even worse, a variable number of columns and you want another stored procedure to process that data in some way before returning it.

you could create a temporary table, with all those columns, and insert the data into it. – an approach that won’t even work if you have a variable number of columns.

If you’re using SQL server 2012, then you can use dm_exec_describe_first_result_set_for_object  to help with this, but say, you’re  using SQL server 2008 …

This is where OPENROWSET comes in, where you can make SQL server call itself, as if it were a remote database.

EXEC sp_configure ‘Show Advanced Options’, 1
RECONFIGURE
EXEC sp_configure ‘Ad Hoc Distributed Queries’, 1
RECONFIGURE
declare @CityName varchar(200)
set @CityName = ‘Derry’
declare @SQL varchar(1000)
set @SQL = ‘SELECT distinct something FROM OPENROWSET(”SQLNCLI”, ”Server=(local);Trusted_Connection=yes;”,
”yourdb.dbo.sp_SearchResultsByCityName ””’ + @CityName + ”””’)
order by something’
print @SQL
exec(@SQL)

There’s about two levels of indirection in there, but it works … after an hour of trial and error!

ps: If you’re using temp tables in your stored procedure, you also have to use

SET FMTONLY OFF
SET NOCOUNT ON

Categories: Uncategorized

Changing the language of a Phonegap App.

IMG_0033

All my iOS apps have app store descriptions in multiple languages, the download increase from this simple step alone is enormous. However, I did notice that the increase in downloads doesn’t match the increase in actual app engagement, and it’s pretty obvious why, a Russian user might be tempted to download your app from your description in Russian, but then once downloaded, can’t use the app because he doesn’t speak english.

Earlier in this blog, I listed a way to determine the user’s language by using HTTP headers, however, I thought that it’s not a great solution, since I’m relying on a third party service, which could go offline tomorrow. So, I used a better solution as follows;

function checkLanguage()
{
navigator.globalization.getPreferredLanguage(
function (language)
{
console.log(‘language: ‘ + language.value + ‘\n’);
changelanguage(language.value);
},
function () {
console.log(‘Error getting language\n’);}
);
}

This only works in the context of PhoneGap, and not in the normal web. But that didn’t matter for me. The next trick, is to test this in a real device, not the simulator, since the emulator has a bug that prevents this from happening naturally (there’s a work around via edit-scheme > options > language). But with a real iPhone to hand, it works perfectly.

What I did is created a JSON object like this;

var translations = {
“en” : {
“#line1” : “In order to use this app, you will need to install the print spooler software available for purchase at”,
“#btnBuy” : “Download Software”,
“#line2” : “You can use this app to send photos from your photo gallery to print. To send other types of files, simply email them as an attachment to [username] @printfromipad.com, where [username] is your username that you have previously set up.”,
“#line3” : “If you have any problems using this printing system, please email us at support@openmerchantaccount.com, or phone us on (0044)2871226151”,
“#btnCreateAccount” : “Register”,
“#btnLogin” : “Login”,
“.ui-title” : “Print”,
“.ui-header .ui-btn” : “Help”
},
“fr” : {
“#line1” : “Pour utiliser cette application, vous aurez besoin d’installer le logiciel du gestionnaire d’impression disponible à l’achat au”,
“#btnBuy” : “Télécharger le logiciel”,
“#line2” : “Vous pouvez utiliser cette application pour envoyer des photos de votre galerie de photos à imprimer. Pour envoyer d’autres types de fichiers, il suffit de les envoyer par courriel en pièce jointe à [nom d’utilisateur] @ printfromipad.com, où [nom d’utilisateur] est votre nom d’utilisateur que vous avez précédemment créé.”,
“#line3” : “Si vous avez des problèmes avec ce système d’impression, se il vous plaît écrivez-nous à support@openmerchantaccount.com, ou appelez-nous au (0044) 2871226151”,
“#btnCreateAccount” : “Créer un compte”,
“#btnLogin” : “Connexion”,
“.ui-title” : “Imprimer”,
“.ui-header .ui-btn” : “Aide”
},

Where you can see a JQuery selector, and the localised text; and this is applied like this

function changelanguage(lang)
{
for(var i in translations[lang])
{
var translation = translations[lang][i];
console.log(i + “->” + translation);
$(i).html(translation);
}
}

Really happy with this. The only bug I found was that the element has to be present on-screen when changeLanguage is called, so in the next version, I’ll ensure that this is called on every page load.

Categories: Uncategorized

Subscribe to mailchimp via API in PHP

This is a handy little PHP script using CURL that adds an email address onto a MailChimp list
taken from: https://apidocs.mailchimp.com/api/1.3/listsubscribe.func.php

<?php
$apiKey = ‘xxxxxx’; // your mailchimp API KEY here
$listId = ‘xxxxx’; // your mailchimp LIST ID here
$double_optin=false;
$send_welcome=false;
$email_type = ‘html’;
$email = $_POST[’email’];
//replace us2 with your actual datacenter
$submit_url = “http://us10.api.mailchimp.com/1.3/?method=listSubscribe&#8221;;
$data = array(
’email_address’=>$email,
‘apikey’=>$apiKey,
‘id’ => $listId,
‘double_optin’ => $double_optin,
‘send_welcome’ => $send_welcome,
’email_type’ => $email_type
);
$payload = json_encode($data);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $submit_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, urlencode($payload));

$result = curl_exec($ch);
curl_close ($ch);
$data = json_decode($result);
if ($data->error){
echo $data->error;
} else {
echo ‘Got it, you\’ve been added to our email list.’;
}
?>

Categories: Uncategorized

Premature end of script headers

I’m not really used to fixing problems on Linux / Apache – but after a server crash, and a forced migration to a new server, I’ve had to get my hands dirty and try and get a new Linux server back up and running.

So, my problem was. I needed to install Perl, Python and Ruby on the server, I had existing scripts but nothing appeared to work, I just got the generic Http 500 Internal server error message. – Which isn’t enough to work with.

The first step with troubleshooting is to get more information on the error, which means in my case anyway, looking at the file /var/log/httpd/error_log (I’m on centOS), and looking at the last error.

Then fixing the error listed

Permission denied: exec of ‘….HelloWorld.py’ failed

This means you need to grant execute permissions to the file, – i.e. in WinSCP, right click the file, select properties, then click all the X checkboxes in permissions

Premature end of script headers: HelloWorld.py

This means, in my case anyway, was the shebang line was pointing to the wrong file – so instead of

#!usr/local/bin/python it was in fact #!usr/bin/python

You can type which python into the command prompt to find the location of your python executable

: undefined method `require_relative’ for main:Object

This was a ruby specific error I got, which was because I had an old version of Ruby installed (1.8.1), just replaced require_relative to require, and that went away.

Categories: Uncategorized

Localise a web page via Javascript

Here is a way to simply detect the user’s language,and switch the content for the local version. As a caveat, this system will show English before changing to the local language, and it’s not good for SEO. You can get rid of the change from english by removing visible text in the HTML, but this also serves as a failover for users who don’t speak any of the supported languages.

<span id=”btnBuy”>Download Software</span>

<script language=”javascript”>

var translations = {
“en” : {
“btnBuy” : “Download Software”
},
“fr” : {
“btnBuy” : “Télécharger le logiciel”,
}};

function changelanguage(httpheaders)

{
var lang=httpheaders[“Accept-Language”];
lang = lang.split(“,”)[0].substring(0,2);
console.log(lang);
for(var i in translations[lang])
{
var translation = translations[lang][i];
console.log(i + “->” + translation);
document.getElementById(i).innerHTML = translation;
}
}
</script>
<script src=”http://ajaxhttpheaders2.appspot.com/?callback=changelanguage”></script&gt;

Kudos to Dan Singerman for the appengine script.

Categories: Uncategorized