Showcase
Showcase admin 10 July, 2009 - 14:57Showcase of tips and tricks that make programming easier. Some say that this is where I put everything that otherwise gets lost and re-created often...
A years worth of browser screen resolutions
A years worth of browser screen resolutions admin 11 July, 2009 - 13:44A very non definitive list of browser screen resolution in terms of height, but possibly useful as it's from www.frenchpropertysearch.com which attracts a large cross section of users. Table is of course sortable by the headers.
x | y | count |
---|---|---|
1024 | 768 | 18762 |
1280 | 800 | 10964 |
1280 | 1024 | 6681 |
1440 | 900 | 4238 |
1680 | 1050 | 2472 |
800 | 600 | 2064 |
1920 | 1200 | 1343 |
1152 | 864 | 1212 |
1280 | 768 | 668 |
1300 | 2300 | 497 |
1280 | 960 | 392 |
1400 | 1050 | 272 |
1600 | 1200 | 221 |
1300 | 1300 | 215 |
1280 | 720 | 199 |
1024 | 600 | 147 |
1366 | 768 | 145 |
1280 | 854 | 116 |
1600 | 900 | 75 |
1360 | 768 | 70 |
320 | 396 | 66 |
1024 | 640 | 35 |
1152 | 720 | 30 |
1920 | 1080 | 29 |
1536 | 960 | 28 |
1344 | 840 | 27 |
800 | 480 | 24 |
200 | 100 | 23 |
640 | 480 | 19 |
2560 | 1600 | 18 |
969 | 768 | 17 |
2560 | 1024 | 17 |
1600 | 1024 | 16 |
1120 | 840 | 14 |
960 | 600 | 13 |
1024 | 1280 | 13 |
1152 | 870 | 13 |
240 | 320 | 12 |
1152 | 768 | 10 |
320 | 240 | 9 |
3840 | 1024 | 9 |
1280 | 994 | 8 |
236 | 320 | 7 |
819 | 614 | 7 |
1024 | 614 | 7 |
1600 | 1000 | 7 |
1024 | 738 | 6 |
1024 | 819 | 6 |
1440 | 960 | 6 |
832 | 624 | 5 |
2048 | 768 | 5 |
124 | 160 | 4 |
480 | 272 | 4 |
922 | 691 | 4 |
1000 | 1000 | 4 |
1200 | 1600 | 4 |
50 | 2000 | 3 |
124 | 96 | 3 |
240 | 218 | 3 |
480 | 320 | 3 |
768 | 1024 | 3 |
800 | 1038 | 3 |
900 | 1440 | 3 |
1224 | 768 | 3 |
1360 | 1024 | 3 |
1408 | 1126 | 3 |
1512 | 945 | 3 |
2048 | 1152 | 3 |
2048 | 1536 | 3 |
3072 | 768 | 3 |
176 | 220 | 2 |
236 | 300 | 2 |
236 | 400 | 2 |
720 | 576 | 2 |
800 | 352 | 2 |
1010 | 700 | 2 |
1010 | 708 | 2 |
1024 | 711 | 2 |
1024 | 720 | 2 |
1024 | 742 | 2 |
1050 | 1680 | 2 |
1152 | 900 | 2 |
1274 | 970 | 2 |
1280 | 600 | 2 |
1280 | 900 | 2 |
1440 | 852 | 2 |
1680 | 945 | 2 |
1836 | 1174 | 2 |
86 | 35 | 1 |
124 | 140 | 1 |
170 | 180 | 1 |
170 | 220 | 1 |
172 | 208 | 1 |
172 | 220 | 1 |
234 | 282 | 1 |
240 | 160 | 1 |
240 | 276 | 1 |
316 | 240 | 1 |
360 | 480 | 1 |
640 | 384 | 1 |
794 | 322 | 1 |
800 | 472 | 1 |
800 | 570 | 1 |
800 | 628 | 1 |
800 | 5000 | 1 |
848 | 480 | 1 |
853 | 683 | 1 |
896 | 717 | 1 |
980 | 720 | 1 |
981 | 613 | 1 |
990 | 693 | 1 |
990 | 714 | 1 |
998 | 701 | 1 |
1007 | 693 | 1 |
1008 | 710 | 1 |
1010 | 707 | 1 |
1024 | 767 | 1 |
1045 | 836 | 1 |
1056 | 792 | 1 |
1148 | 836 | 1 |
1152 | 922 | 1 |
1159 | 927 | 1 |
1168 | 847 | 1 |
1176 | 664 | 1 |
1192 | 668 | 1 |
1200 | 668 | 1 |
1200 | 1920 | 1 |
1203 | 671 | 1 |
1220 | 970 | 1 |
1224 | 691 | 1 |
1232 | 770 | 1 |
1268 | 951 | 1 |
1272 | 960 | 1 |
1272 | 964 | 1 |
1272 | 989 | 1 |
1274 | 962 | 1 |
1276 | 960 | 1 |
1280 | 820 | 1 |
1280 | 896 | 1 |
1280 | 964 | 1 |
1344 | 1008 | 1 |
1360 | 764 | 1 |
1360 | 765 | 1 |
1376 | 768 | 1 |
1400 | 1020 | 1 |
1408 | 880 | 1 |
1432 | 1122 | 1 |
1444 | 1130 | 1 |
1588 | 1200 | 1 |
1600 | 1050 | 1 |
1688 | 964 | 1 |
1920 | 1440 | 1 |
2304 | 864 | 1 |
2880 | 900 | 1 |
2960 | 1050 | 1 |
3072 | 1280 | 1 |
5120 | 1024 | 1 |
Generate SQL to identify duplicates
Generate SQL to identify duplicates admin 6 October, 2012 - 15:50A small tool that javascript to generate SQL that will identify duplicated records in a table
Guru and User1
Guru and User1 admin 3 January, 2011 - 16:55ASCII cartoon strip, because I can't draw.
Today Guru tackles the difficulties of choosing an architecture.
1 .--------------------------------. |Guru, should I use Ruby or Java | |for web apps in the cloud? | `------.------------------------------. |Well User1 it depends on your | |skillset and the requirements.| :-----------------------------.' |Analyse your requirements | |perform some evaluations and | |come to a conclusion. | ($) `-----------------------------'(#) /|\ /|\ / \ / \
2 .-------------------------. |Can't you just tell me? | `-------------------------' .----------------------------. |You need to do the analysis.| `----------------------------' .---------------------------. |Don't be obstructive, we're| |all on the same team | `---------------------------' ($) '(#) /|\ /|\ / \ / \
3 .----------------------------------. |Please tell me, I know you know...| `-------------.--------------------------. |Do you like chilli sauce? | .--------------------.------------------' |Yeah I love it, why?|.---------------. `--------------------'| Use Ruby then | .---------------------------.-----' |That's not very analytical | ($)`---------------------------' '(#) /|\ /|\ / \ / \
4 .------------------------------. |My analysis shows that 68% of | |projects using Ruby are | |successfully developed by a | |team who love chilli sauce. | .----------------.---------------------' |Ruby it is then | `----------------' .------------------------------. |Isn't there a more scientific | |way of doing this? | `------------------.---------------------. |You'd have thought...| `---------------------' ($) (#) /|\ /|\ / \ / \
How to import a SQL Server .bak file into MySQL
How to import a SQL Server .bak file into MySQL admin 26 August, 2009 - 10:46The .BAK files from SQL server are in Microsoft Tape Format (MTF) ref: http://www.fpns.net/willy/msbackup.htm
The bak file will probably contain the LDF and MDF files that SQL server uses to store the database.
You will need to use SQL server to extract these. SQL Server Express is free and will do the job.
So, install SQL Server 2008 Express edition, use sqlcmd -S \SQLExpress (whilst logged in as administrator)
then issue the following command.
restore filelistonly from disk='c:\temp\mydbName-2009-09-29-v10.bak';
GO
This will list the contents of the backup - what you need is the first fields that tell you the logical names - one will be the actual database and the other the log file.
RESTORE DATABASE mydbName FROM disk='c:\temp\mydbName-2009-09-29-v10.bak'
WITH
MOVE 'mydbName' TO 'c:\temp\mydbName_data.mdf',
MOVE 'mydbName_log' TO 'c:\temp\mydbName_data.ldf';
GO
At this point you have extracted the database - then install Microsoft's "Sql Web Data Administrator". together with this export tool and you will have an SQL script that contains the database.
Reverse engineered AmiBack (Amiga) extraction utility.
Reverse engineered AmiBack (Amiga) extraction utility. admin 11 July, 2009 - 18:32This is really a quick hack to read AmiBack backups - I don't know if it works with floppy based backups - but probably the source below is most useful for understanding the format.
I used it succesfully to restore all of my backups that were stored on QIC Tape (45/150mb).
/*--------------------------------------------------------------------------- * * Title: AmiBack extraction utility * * File: amiread.cpp * * Date: May 2005 * * Description: * Reads/extracts files from a dumped amibackup format archive. * * Rev By Description Date * 1.0 R.J.Harrison Implement 05-05-2005 * * Copyright © 2005 R.J.Harrison *---------------------------------------------------------------------------*/ #pragma warning(disable : 4786) #include <stdio.h> #include <stdlib.h> #include <string.h> #include <direct.h> #include <io.h> #include <fcntl.h> #include <vector> #include <string> #pragma pack(1) typedef struct { char header[4]; // FHDR char name[108];// fname long aa; //??? long filesize; long ee; long ff; long gg; long hh; char depth; char type; // content follows. (unless filesize 0); }AmiHeader; void check_path(const char *path) { FILE *q; static char *ptr,*name, *end, tmp [200]; strcpy (tmp,path); end = ptr = tmp+strlen(tmp); while (*--ptr && *ptr != '/'); if(*ptr) { *++ptr = 0; /* Remove file name */ name = ptr = tmp; do { while (*ptr && *ptr != '/') ptr++; if(*ptr) { *ptr = 0; if(!(q=fopen(name,"r"))) { mkdir (name); } else { fclose (q); } *ptr++ = '/'; } }while (*ptr && ptr < end); } } main() { FILE *f = fopen("N:/Users/Richard/tape/Tapes/amiga_wb_work.amiback","rb"); std::vector<std::string> dirz(100); #define BUFFER_SIZE 1000 /* k */ int buffer_size = BUFFER_SIZE; buffer_size *= 1024; void *file_buffer = malloc(buffer_size + 10); if (!f) { fprintf (stderr, "Not found\n"); exit(-1); } char hdr[512]; #define SWAP_LONG(v) (((v & 0xff000000) >> 24) | ((v & 0xff0000) >> 8) | ((v & 0xff00) << 8) | ((v & 0xff) << 24)) fread(hdr,1,sizeof(hdr),f); printf ("%d\n",sizeof(AmiHeader)); int fc=0; std::string fname; chdir("C:/temp/amiga/"); while(!feof(f)) { AmiHeader fhdr; fread (&fhdr, 1, sizeof(fhdr),f); fhdr.filesize = SWAP_LONG(fhdr.filesize); if (fc == 9175) printf("%x\n", ftell(f)); //? Colon in name is new device... if (strncmp(fhdr.header, "FHDR", 4)) printf ("???Header???"); printf ("%5d: %10d - ",fc++,fhdr.filesize); fname = std::string(); switch (fhdr.type) { case 0x2: { char *s = strchr(fhdr.name, ':'); if (s) *s = 0; // zoink colon from devname dirz[0] = fhdr.name; } break; case 0x0: dirz[fhdr.depth] = fhdr.name; break; default: for (size_t i = 0; i < fhdr.depth; i++) { // printf ("%s/",dirz[i].c_str()); fname = fname + dirz[i] + "/"; } break; } fname = fname + fhdr.name; printf ("%s\n",fname.c_str()); if (fhdr.filesize) { bool list = false; int size = fhdr.filesize; int of; if(!list) { check_path(fname.c_str()); of = open(fname.c_str(), O_BINARY | O_CREAT | O_WRONLY | O_TRUNC, 0x666);// need mode..hdr.mode); if(!of) fprintf(stderr,"unable to open %s\n", fname.c_str()); } while(size >= buffer_size) { fread(file_buffer, 1, buffer_size, f); if(!list) write(of, file_buffer, buffer_size); size -= buffer_size; } if(size > 0) { fread(file_buffer, 1, size, f); if(!list ) write(of, file_buffer, size); } if (!list ) close(of); // if (fseek(f, fhdr.filesize, SEEK_CUR)) // { // fprintf (stderr,"Seek failed\n"); // exit(-1); // } } else { printf ("Directory\n"); if (fhdr.type) printf ("Type %d\n", fhdr.type); } //ii[0] - 0x2 = device; //ii[0] - 0x0 = dir; //ii[0] - 0x1 = file? } }
SQL server 2005. SQL to create table structure
SQL server 2005. SQL to create table structure admin 11 July, 2009 - 18:30The following isn't mine, it was written by David. I include it here for the usual reason.
select 'create table [' + so.name + '] (' + o.list + ')' + CASE WHEN tc.Constraint_Name IS NULL THEN '' ELSE 'ALTER TABLE ' + so.Name + ' ADD CONSTRAINT ' + tc.Constraint_Name + ' PRIMARY KEY ' + ' (' + LEFT(j.List, Len(j.List)-1) + ')' END from sysobjects so cross apply (SELECT ' ['+column_name+'] ' + data_type + case data_type when 'sql_variant' then '' when 'text' then '' when 'decimal' then '(' + cast(numeric_precision_radix as varchar) + ', ' + cast(numeric_scale as varchar) + ')' else coalesce('('+case when character_maximum_length = -1 then 'MAX' else cast(character_maximum_length as varchar) end +')','') end + ' ' + case when exists ( select id from syscolumns where object_name(id)=so.name and name=column_name and columnproperty(id,name,'IsIdentity') = 1 ) then 'IDENTITY(' + cast(ident_seed(so.name) as varchar) + ',' + cast(ident_incr(so.name) as varchar) + ')' else '' end + ' ' + (case when IS_NULLABLE = 'No' then 'NOT ' else '' end ) + 'NULL ' + case when information_schema.columns.COLUMN_DEFAULT IS NOT NULL THEN 'DEFAULT '+ information_schema.columns.COLUMN_DEFAULT ELSE '' END + ', ' from information_schema.columns where table_name = so.name order by ordinal_position FOR XML PATH('')) o (list) left join information_schema.table_constraints tc on tc.Table_name = so.Name AND tc.Constraint_Type = 'PRIMARY KEY' cross apply (select '[' + Column_Name + '], ' FROM information_schema.key_column_usage kcu WHERE kcu.Constraint_Name = tc.Constraint_Name ORDER BY ORDINAL_POSITION FOR XML PATH('')) j (list) where xtype = 'U' AND name NOT IN ('dtproperties')
Simple batch file (CMD) for deploying a .NET aspx site from a SVN controlled directory.
Simple batch file (CMD) for deploying a .NET aspx site from a SVN controlled directory. admin 11 July, 2009 - 18:34What follows is in the quick hack category - I'm sure there is a much better of doing this - but this works and keeps my servers cleaner by not copying the .aspx.* files (e.g. .aspx.vb .aspx.rex) and the project files.
Before running this for the first time you will need to
svn co www-svn
net stop w3svc
svn update www-svn
rd/s www
xcopy/t/e/y www-svn www
xcopy/s/y www-svn\*.aspx www\
xcopy/s/y www-svn\*.ascx www\
xcopy/s/y www-svn\*.config www\
xcopy/s/y www-svn\bin\*.* www\bin\
xcopy/s/y www-svn\*.jpg www\
xcopy/s/y www-svn\*.png www\
xcopy/s/y www-svn\*.gif www\
xcopy/s/y www-svn\*.js www\
xcopy/s/y www-svn\*.css www\
xcopy/y www-svn\global*.* www\
net start w3svc
Simple method to make a site multi-lingual in PHP
Simple method to make a site multi-lingual in PHP admin 11 July, 2009 - 18:36Firstly do this from the start of the project - it's a lot easier and quicker than editing at the end.
Wherever you need text that is to be translated use the simple sequence ~PHnnnn~, where nnnn is a four digit number. It slows you down a little at first - however the benefits later on are massive - for one thing you can edit the English text and you therefore get a simple CMS for free.
For example:
phrase_op("<h1>~PH2228~</h1>");
phrase_op is a simple routine that takes phrases from a database and replaces all of the tokens found.
/** * outputs a string changing all the ~PH####~ into the corresponding phrase */ function phrase_op($txt) { preg_match_all("/\~PH[0-9][0-9][0-9][0-9]\~/",$txt,$regs,PREG_SET_ORDER); foreach($regs as $result) { $phc = substr($result[0],1,strlen($result[0])-2); $ph = get_phrase($phc); $txt = str_replace($result[0],$ph,$txt); } echo $txt; } function load_phrases() { global $phrases; global $config; $phrases = array(); $sql = "SELECT * FROM tb_phrases where iso='".mysql_real_escape_string($config['cur_lang'])."'"; $result = mysql_query($sql) or die('exec_query failed: [ '.$sql.' ]'.mysql_error()); while ($row = mysql_fetch_array($result,MYSQL_ASSOC)) { $phrases[$row['phrase_code']] = $row['text']; } }
All you need to do now is to create the sql to create the phrases, and a quick page to allow editing.
Useful regex's to verify email, alphanumeric, numeric (to ensure that an entire string matches)
Useful regex's to verify email, alphanumeric, numeric (to ensure that an entire string matches) admin 27 August, 2009 - 14:54Regex is a black art, with the usual rule being the smaller the better.
The following are a basic collection that I use quite often:
- Regex to validate email - i.e. of the form x@a.tld
^[a-zA-Z0-9_\.\-]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\.\-]+$
- Regex to match only alphanumeric
^([a-zA-Z0-9]+)$
- Regex to match only alpha
^([a-zA-Z]+)$
- Regex to match only numeric
^([0-9]+)$
- Regex to match only numeric (decimal or floating point)
^([0-9.]+)$
- Regex to match only numeric (international)
^([0-9.,]+)$
Using Wordpress 4.1.7, Woocommerce to create a furniture store
Using Wordpress 4.1.7, Woocommerce to create a furniture store admin 10 October, 2015 - 18:06It’s been a while since I did any Wordpress development, but recently I was asked to build a straightforwards, clean, site to act as a shop front / ecommerce for a retailer of special and refurbished furniture.
As always with these sites, the URL caused a considerable discussion, until it was decided that zunika-interiors.co.uk fitted nicely into their target niche market.
The last site I built was using Wordpress 4.1.7 with Woocommerce, so I started off with a direct copy of this (it’s always easier to drop the whole lot onto the ftp server and then upgrade later. Mostly these days it’s a case of choosing your plugins wisely, and hopefully the theme will play along. Unfortunately the last site was using the excellent Barberry theme, but for a new site that’s not an option as I didn’t buy this plugin (it was the last client), and as always budgets are tight so I had to settle for the almost as good (and still excellent) mystile theme.
The logo was already done, so it was a case of setting up the catalogs, configuring the menus and sidebars, and overall I reckon that the effective development time was less than a day (in reality it was longer despite my best efforts to avoid problems with versioning I still managed to confuse myself, when eventually I just went back to my known good configuration of plugins and themes).
Wordpress, Woocommerce configuration and plugins
As with most things on my site I’m writing this down so that next time I don’t have to find my notes.
These are the plugins that I used
- Breadcrumb NavXT
- Contact Form 7
- Envato WordPress Toolkit
- Regenerate Thumbnails
- Revolution Slider
- Search By SKU – for Woocommerce
- WooCommerce
- WooCommerce Quickview
- WooSidebars
- WP Retina 2x
Theme niceness
It’s only really been a few years since I properly did a Wordpress site and I have to say that I’m impressed by all of the niceness that the mystile theme gives me.
It’s clean
It’s responsive.
Conclusion
Although the site development is finished there is still a lot of admin for the site owner to finish off (he’s got to go through his warehouse which I’ve seen and it’s full to the brim with some really good quality, solid, furniture. I suspect that this will take a while as the warehouse is quite dark and all of the pieces need to have good photographs to really show them off at their best). There was one piece that had a really lovely walnut veneer, that was hardly visible when I used my cheap and nasty camera (that’s attached to my cheap and nasty phone)). He’s got a good camera, and I hope his muscles are up to all of the hefting, but it’ll be worth it.
Until he’s got all of the furniture loaded the site will be quite bare (apart from my obligatory inclusion of an F-15 as a test product); but if anyone’s interested it’s here good quality furniture .