Convert PostScript to PDF from D lang calling GhostScript ps2pdf.


• September 9, 2016 • Leave a Comment

I’m learning D. This provides working examples of getopts, concurrency, and a process call.

import std.getopt;
import std.stdio; 
import std.file;
import std.path;
import std.datetime;
import std.algorithm;
import std.array;
import std.conv;
import std.string;
import std.process;
import std.concurrency;

string[] listdir(string path)
{
    return dirEntries(path, "*.ps", SpanMode.shallow)
        .filter!(f => f.isFile)
        .map!(f => buildPath(path, f.name))
        .array;
}

void rip(string path, bool v=false) 
{
	//ps2pdf filename.ps filename.pdf
	string outpath = path.replace(".ps", ".pdf");
	if (v == true) {
		writefln("OUT: %s", outpath);
	}
	auto logFile = File("errors.log", "w");
	auto pid = spawnProcess(["/usr/bin/ps2pdf", path, outpath],
                        std.stdio.stdin,
                        std.stdio.stdout,
                        logFile);
	wait(pid);
}

void main(string[] arguments)
{

	// Get opts
	auto base_path = "/home/username/Documents/postscript";
    bool render = false;
    bool count = false;
    bool verbose = false;
    
	getopt(
		arguments,
		"p|path", &base_path,
		"r|render", &render,
		"c|count", &count,
		"v|verbose", &verbose
	); 
	
	// $./psmerge -p /home/username/Documents/postscript -r -c -v
	StopWatch sw;
	sw.start();
	
	int totalDocs = 0;
	int totalPages = 0;
	if (base_path.exists) {
		
		string[] psfiles = listdir(base_path);
		foreach(ps; psfiles){
			
			if (render == true) {

				auto tid = spawn(&rip, ps, verbose);
				
				if (verbose == true){
					writeln(tid, " \nIN: ", ps);
				}
			}
			
			totalDocs++;
			
			// Count pages.
			if (count == true) {
				// Read file.
				File fileHandle = File(ps, "r");
			   
				while (!fileHandle.eof()) 
				{
					string line = fileHandle.readln();
					if ( canFind(line, "(atend)") ) {
						continue;
					}
					if ( canFind(line, "%%Pages: ") ) {
						
						string[] s = line.split(":");
						auto pgNum = strip(s[1].replace("\r\n",""));
						
						if (verbose == true){
							writeln("Pages: ", pgNum);
						}
						
						auto pgCount = to!long(pgNum);
						totalPages += pgCount;
					}
				}
			}
		}
		writefln("Total Docs: %s", totalDocs);
		writefln("Total Pages: %s", totalPages);
		
		sw.stop();
		writefln("Elapsed: %f seconds", sw.peek().usecs / 1_000_000.0);
	}
}

Gambas 3 TreeView and TabStrip Example Code


• September 3, 2016 • Leave a Comment

I sometimes play around with Xojo and PureBasic for quick and simple GUI apps since the interface designers are convenient and the language makes for easy coding. I was checking out Gambas 3 and found it to be fairly good but lacking in a lot of examples. I was messing around with TreeView and TabStrip working together. It took a bit and I am sure there are better ways to approach this, but if you need examples of either of these controls this is working code.

I have a form with an HSplit. If the left side I have a TreeView and the right I have a TabStrip. I left names default and made the object expand to the window. I still haven’t figured out how to resize either side of the HStrip. This just loads some books off the file system to populate the treeview and creates a tab when clicked. I also added tab delete buttons. I have a module for the base path, but you can set it in form open. Screen shot here.

At this point I am thinking I will need to subclass and make my own form objects as this was a pain in the ass. Maybe this will help someone.

Public Sub TabStrip1_Close(idx As Integer)
  Try TabStrip1[idx].Text = Null
    TabStrip1[idx].Delete()
  Catch
    TabStrip1[idx].Text = Null
    TabStrip1.Closable = False
End

Public Sub TabStrip1_Click()
  Dim k As String
  If Len(TabStrip1[TabStrip1.Index].Text) > 0 Then
    Message(TabStrip1[TabStrip1.Index].Text)
  Endif
End

Public Sub TreeView1_Click()

  Dim counter As Integer

  If TreeView1.Item.Key Begins "root_" Or TreeView1.Item.Key Begins "parent_" Then
    'Do nothing For parent items or capture parent events.
    Return
  Endif
  
  If TreeView1.Item.Children = 0 Then
    
    If TabStrip1.Index = 0 And Len(TabStrip1[TabStrip1.Index].Text) = 0 Then
      If Len(TreeView1.Item.Text) > 0 Then
        If Len(TreeView1.Item.Text) > 0 Then
          TabStrip1[TabStrip1.Index].Text = TreeView1.Item.Text
          TabStrip1.Closable = True
          TabStrip1.Count = 1
        Endif
      Endif
    Endif
    
    For counter = 0 To TabStrip1.Count - 1
      If TreeView1.Item.Text = TabStrip1[counter].Text Then
        'Focus tree item on corresponding tab select.
        TabStrip1.Index = counter
      Endif
    Next

    If TreeView1.Item.Text = TabStrip1[TabStrip1.Index].Text Then
      Return
    Else
      'Add new tab if not in tabs.
      TabStrip1.Count += 1
      TabStrip1[TabStrip1.Index].Text = TreeView1.Item.Text
    Endif
  Endif
End


Public Sub Form_Open()

  Dim File As String
  Dim path_parts As String[]
  Dim file_parts As String[]
  Dim cat As String
  Dim cat_key As String
  Dim title As String
  Dim treeIndex As Integer
  
  'Dim img_book As New Picture(16, 16, False)
  'Dim img_cat As New Picture(16, 16, False)
  'Dim img_root As New Picture(16, 16, False)
  'img_book.Load("book.png")
  'img_cat.Load("cat.png")
  'img_root.Load("root.png")
  
  'Globals.basePath = "~/ebooks"
  If Not Exist(globals.basePath) Then
    Mkdir globals.basePath
  Else
    'TreeView1.Add("root_EBooks", "EBooks", img_root) 'With icon.
    TreeView1.Add("root_EBooks", "EBooks")
    For Each File In RDir(globals.basePath, "*.epub").Sort()
      
      path_parts = Split(File, "/")
      cat = path_parts[0]
      cat_key = "parent_" & cat
      file_parts = Split(path_parts[1], ".")
      title = file_parts[0]
      
      If Not TreeView1.Exist(cat_key) Then
        TreeView1.Add(cat_key, cat,, "root_EBooks")
      Endif
      
      treeIndex += 1
      TreeView1.Add(title, title,, cat_key)
    Next
  Endif

End   

Install Virtuoso 6.1.6 for use with Python 3 on LinuxMint 18


• August 27, 2016 • Leave a Comment

Install the following from the Software Manager (use apt if you prefer):

Virtuoso-opensource
Virtuoso-server
Virtuoso-vad-conductor
Virtuoso-vad-isparql
Virtuoso-vsp-startpage
Virtuoso-opensource-6.1
Virtuoso-opensource-6.1-bin
Virtuoso-opensource-61-common
Unixodbc
Libvirtodbc0

Download zip and Install PyODBC from

https://github.com/maparent/pyodbc/tree/v3-virtuoso

Unzip, cd into the expended folder, then type:

$ sudo python setup.py build install

Add the following in the odbc.ini:

$ sudo nano /etc/odbc.ini

Add the following and save it.

[Local Virtuoso]
Driver = /usr/lib/odbc/virtodbc_r.so
Address = localhost:1111

Start the database:

$ cd /etc/virtuoso-opensource-6.1
$ sudo virtuoso-t -fd

If you have problems delete virtuoso.lck:

$ sudo rm -r /var/lib/virtuoso-opensource-6.1/db/virtuoso.lck

Open the browser and point to: http://localhost:8890/conductor/

If this works, you’re good.

Assuming you haven’t changed them:
User = dba
Pass = dba

If you have trouble with the password, kill the db process, delete the db, and restart:

$ sudo rm -r /var/lib/virtuoso-opensource-6.1

The db ini is in: /etc/lib/virtuoso-opensource-6.1/virtuoso.ini

Console management:

$ isql-vt

Example Python3 code:

import decimal
import pyodbc

c = pyodbc.connect('DSN=Local Virtuoso;UID=dba;PWD=dba')

cursor = c.cursor()
print ([i for i in cursor.tables()])

Windows Authentication from CherryPy served from Apache 2.4/WSGI using Python 3.4 64bit.


• December 12, 2015 • Comments Off on Windows Authentication from CherryPy served from Apache 2.4/WSGI using Python 3.4 64bit.

Here’s an example with working code and all the modules to get CherryPy running in Apache via WSGI with Windows authentication. Just download and copy Apache24 and coolwhip to the C: drive, add your IP\domain to httpd.conf, and fire up the server. See the read me for more details, installing Apache yourself, and Python libraries needing to be installed.

This example will also show how to mount a static folder in CherryPy for your images, javascript, etc. and the basic use of a Jinja2 template. This is the beginning of a bigger project so it’s very basic with the intentions of growing into a MVC Ajax powered site. It’s going to be fun! Tested on latest Windows server (AD environment) and my local home machine (localdomain) running Windows 10.

If you have trouble with localhost access on Windows 10 try changing the port from 80 to 8000, 8080. Make sure you start Apache as an admin.

Download Apache24.zip (15.8mb) SHA: a193f0ecd6f2f88c908dab622304ce4163e17a21

Creating a DataMatrix GS1 barcode and saving to postscript, PDF, or image for free in C#.


• December 5, 2015 • Comments Off on Creating a DataMatrix GS1 barcode and saving to postscript, PDF, or image for free in C#.

I’ve been working on an interesting project where I had to learn Pitney Bowes Streamweaver in order to sort/merge and barcode postscript with very little knowledge of postscript and no training or knowledge of Streamweaver. I rolled my own in C# in order to understand how the product worked for parsing but didn’t know much about creating the data matrix barcode and placing it into the postscript, which left me relying on Streamweaver no matter what. My employer is continuing to use Streamweaver until we rewrite this functionality into Adobe ES (hopefully), but if you have small amounts of postscripts to barcode for printing or whatever maybe this will be helpful. Adobe has a free book to get you up to speed on the Postscript language and this post was helpful as well.

I wrote a small console app that will produce a barcode written out in Postscript, JPG, PDF, Hex and ASCII85 encoded. This program has few features and less options as I was just playing with different approaches, these turned out to be the best, but if you need more just ask and I can help as much as possible.

barcode

Download DataMatrix Barcode Generator

Before I go further I’d like to acknowledge and link the folks who did the real work!

Datamatrix.Net
Ghostscript
Ghostscript.Net
iTextSharp
Ascii85 encoding code

Here’s a sample of the code.

using System.Drawing;
using System.Drawing.Imaging;

using DataMatrix.net;
using Ghostscript.NET.Processor;

// Examples
namespace datamatrix
{
    class Program
    {

        public static void convertPDFToPs(string inputFile, string outputFile)
        {
            List<string> cmds = new List<string>();
            string postscriptOut = string.Format("-sOutputFile={0}", outputFile);

            using (GhostscriptProcessor processor = new GhostscriptProcessor())
            {
                cmds.Add("-ignored");
                cmds.Add("-q");
                cmds.Add("-dSAFER");
                cmds.Add("-sDEVICE=ps2write");
                cmds.Add("-dASCII85EncodePages=true");
                cmds.Add(postscriptOut);
                cmds.Add("-f");
                cmds.Add(inputFile);

                processor.StartProcessing(cmds.ToArray(), null);
            }
        }
		
	 public static string generateBarcode(string outputImageFile)
        {
	    string imageHexString = "";  // OUTPUT: Hexdecimal string.

            DmtxImageEncoder encoder = new DmtxImageEncoder();
            DmtxImageEncoderOptions options = new DmtxImageEncoderOptions();
            Bitmap encodedBitmap = new Bitmap(38, 38, PixelFormat.Format8bppIndexed);

            options.ModuleSize = 2; 
            options.MarginSize = 1;
            options.BackColor = Color.Transparent;
            options.ForeColor = Color.Black;
			
            options.Scheme = DmtxScheme.DmtxSchemeAsciiGS1;
 
            encodedBitmap = encoder.EncodeImage(gs1Code, options);
            encodedBitmap.SetResolution(96.0F, 96.0F);

            using (var stream = new MemoryStream())
            {
                encodedBitmap.Save(stream, ImageFormat.Jpeg);
                stream.Seek(0, SeekOrigin.Begin);
                buffer = stream.ToArray();

                // Get hexdecimal
                imageHexString = BitConverter.ToString(buffer).Replace("-", "");

                // Save the image to disk, save the barcode as Jpg,Png, whatever image.
                encodedBitmap.Save(outputImageFile, ImageFormat.Jpeg); // Save the barcode as Jpg,Png, whatever image.
            }  

	 return imageHexString
	 }
    }
}

Some conversions in Python.

from PIL import Image # Pillow : https://python-pillow.github.io/
import binascii
 
# Convert hex to jpg 
out_path  = r'c:\barcode\from_hex.jpg'
jpg_hex = u"the hex string" # Hex output from datamatrix in text file.

image_data = binascii.a2b_hex(jpg_hex)
with open(out_path, 'wb') as output:
    output.write(image_data)


# Convert jpg to eps 
jpg_file = r'c:\barcode\DarkArtistry.com.jpg'
eps_out = jpg_file.replace('jpg','eps')
image_data=Image.open(jpg_file)
image_data.save(eps_out)

Adding jpeg hex to an Adobe postscript. You should be able to paste this into an existing postscript, just be careful where you place it; directly after %%Page might be a good start.

%%BeginBarcode
%%PageBoundingBox: 0 0 38 38
DisplayImage
0 0 translate
20 20 scale
12
38 38   %% Width Height
1
1
1
8       %% Bit
F8FFFAFFE8FFFFF3FFEFFFFDF3F9FFF4FFF7FFF7FFFFFFFBF0FFFBFFFFFFFFF8FFFCFFF1
FFFFFFFF00F8FF0000FFF8000AFFFF0407FFFF0F00FFFF0000FFFF0000F2FF0004FFF817
00FFFBF6F2FA00FFF40200FFFF0D00ECFF0600FFFA0105FEFC0002F9FA0014FFFF0800FF
F90009FFFFEFFAFF00FFFF040CEBFC0000FFF900000103FFFAFFFF000406010600000000
04FCFFEFFB0001FAFFF800FFFA0000FFFF0500FFFF00160000FFFCFDFF00060000100700
030200FFFFFFFF0C00FCFAFF10FCFFFFE5FFF8FFF90006F8FF00020207060400030105F5
F600000000FFF2FDFFF1FBFFFFFF00FFFFF3FFFFFAFFFF0C00FFF8090011000004000000
09FFFF0507010CFBFFFFFBF4FFFAFEFF010003FFFF00060000FFFF0004FFFF0013FBFF07
03FEFD0000000CF3FE060000020007F9FFFE000B00FFF40E050008FCFF0000FFFF0009FF
FB000FFCF515000110F8FF020006000405FAFFEF00030AFBFF00000B00FFFCFFFF000004
00FFFFF6FE0007F5FFF4F9FFFB000AFFEBFFEDFFECFF010008F4FF0800030BFEFFF9FF00
001205EFFFF4FF0001F5FFFFFCF9FF0000F1FFFFFFFFFFF904F6FDFFFEF1FFF0FFFCF614
00FFFF000400000000FEFB100000030100FFFFFFFF0000FFFFE402FFFAFDFFFFECFFFFFD
FF0000FEFF000003010C00FFF1001A01001B08FFFFE5FF0800EFFEFF080000F8FF000FFF
FF00000311F8FF0300FFF700000219F8F40900000BFFFFFFF7F5FFFFFFF2050004FFF602
05F3F416000000FFF90012FFFF00000000FFEF0E031300F9F1FFF6FFEFFBFEFB000401F7
FFFAFF00030200FFFF0002FFF0F9FEFFFA04080000FFF7FAFFFFFF02000000FFF2FF0800
09FFEDFFF802100009F8FA0600FFEDFFFEF9F901000005F6FFFFFEFFFF08000900FFFFFF
050000000009070100F9FAFFFF040BFFFAF7FF08000B0BFFF2FFFFF3FD0000F8FFF7FFFF
FBED000900080700000109FFFDF5FF0000FFFAFEFF000F0006E4FFF1FDFCFF0016F9FFFF
FEFBFAFF00FFF600000C02FEECFFFF00020A00FFFFFFF40A00FFFCFFFFFFFFF4FFFFED07
000500F1FAFE06FEFF00000000FFFFF2FA07000000FFFAFBF60800F8FFF3F4FFFBFFF5FF
FF02000007FFFFF8070000FFFF0001FFEFFFFFF8FFFFF4F9FD070000090B00FFFF000209
00FBF6F2FFFFF9FFFBFF001809F2FF0200F4F2FFF5FFFFF5FFF8FF0700030C0006F5FF00
000307FFFFF4FFFFF3F4FFF416F1FF0500FCFFFCFF0001FEEFFFF8FFFF000EFCF9FFF5FF
F0FFFFF4F6FFF70100000BF5FFF010F0FF0200FFFAF9FF0000FCFFFDFFFAFF0300FDFEFF
F9FFF6FAFFFFF8FFFF00010000FFFFFF00FFF80014000C0800FBFFFBF00000FFF4FBFFF6
FFFCFF00001600000902000802FFF7FFFAF800FFFB010008000005FFFFFFFD0302F8FFFF
FFFFF4FFFF07000017000300040009F2FDF8FFFF0000080006FBFE11000000F5FFFFFF00
0A00000301FFF0FFFFFCF300020D0FE9FF0D0BF4FAFA0B00000001FFFF00040200FFFFFC
FF000002000002FFFFFFFFFEFF05000000FFF80600F7FFF800FFFF0000FBFF030B010000
05040011000106000DFDF4FFFB0000001FFDFFFFF3FFFFF9F3FF00FFFF1000FDEB0B0200
1D00090000050500020802F3FFF3FE110F0400F9E8FFFFF0FBFFFFFE0403000500FFFF00
11FAF6FFF0FFFF000006030000FFFCFFFC0000FFFB0D0E00000805FAFFFA030900010DF6
FF0000FFFEF3FFFAFF0200030A0000FCF7FFEC1002FDEB0D0200050000FFFEFA07FCFF07
000800FFF7FDEDFFFF0002FFFF000008050F08E8FF0000FFFF0001FFF7FFFFF9FFF509FF
FE00000006FFFFFFFFFFE70607F7F90A08000C0000FFFF0001FFF41006EEF8FFEEFFFEFF
0000030005010400000000001300000008000501040E000B0000090300000001100000FF
F7F5020507000000010901000E00000005000001010D00000000000A0700040000010000
0FF3F9FFFCFFF7F8FFFAFFFFF1EEFFF9FFFFF7FFFAFBFFF7FFFFFFFFFFFCEEFAFFF4F5FF
FFFFFEFF
%%EndBarcode 

If you need to convert XML to PostScript check out this excellent tool from Apache:

https://xmlgraphics.apache.org/fop/

Leucine calculator Windows, Mac, and Linux


• November 28, 2015 • Comments Off on Leucine calculator Windows, Mac, and Linux

I created a calculator to approximately calculate mg leucine and exchange based on serving size by grams of protein. You can save the calculation as a food and further calculate meal totals. it could be helpful for body builders or those with MSUD.

I provide this software free of charge and without any warranty expressed or implied. This software was tested but could contain errors or incorrect information. This software does not contain any security features and should not be used on public or insecure computers. Please e-mail me with “leucine calc” in the subject line to report any bugs or erroneous values, or to request features. 

Consult a physician before using this software and have your doctor or nutritionist evaluate whether this software will meet your individual needs.

Download for

Windows [12.7 mb] SHA1 : 44724d50afebeeb67d384c453ee3a028cd02b8c2

Mac [2.4 mb] SHA1: 93a9371b368cc3f3b887a1937deaefb4c3a591e3

Linux 32bit [9.1] SHA1: 3a45980bc0e9aba222aba82af74195147155dcea

If you have trouble running on 64bit Linux you will need to install 32bit libs. These three terminal commands should be what you need in modern Ubuntu. Worked for me on Ubuntu Gnome 15.10.

sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386

Sort list by column preserving index. 


• September 11, 2015 • Comments Off on Sort list by column preserving index. 

This is yet another reason I love Python! 

This is good for something like generating HTML tables with rowspans that you want sorted. Each tuple is a row, each item in the tuple is a cell. If you sort this data it will change the index so if you set a rowspan on the first row and sort, it will likely span on the wrong row. This resolves that problem.

# Sort by column, in this case the last column, and keep original list index.
rows = [('Fred', 'Flintstone', 46, 0),('Wilma', 'Flintstone', 45, 33),('Pebbles', 'Flintstone', 10, 55)]
for index,row in sorted(enumerate(rows), key=lambda item: item[-1], reverse=True):
    print (index, row)

Batch base64 encode PNGs in Python 3 for use in CSS.


• September 5, 2015 • Comments Off on Batch base64 encode PNGs in Python 3 for use in CSS.

I wrote a simple Python 3 script to base64 encode a series of PNG images for use in CSS, or whatever. If you’re learning Python add file output or even go a step further and generate the CSS lines. If you’re here I will assume you are wanting these for CSS but if not, here is an example of using base64 encoded images in CSS if you’re curious.

This script can be ran at the console, as a Python import, or simply as a script.

import os
import sys
import base64

def get_image_base64(base_image_path, image_types=['png']):
    """
    get_image_base64(base_image_path, image_types=['png']) -> dict
    Converts a folder list of images to base64.

    args:
        base_image_path = String path to files. Default 'png'
        image_types     = List of extension type to process.

    return -> Dict
    """
    encoded_strings = {}

    if os.path.exists(base_image_path):
        try:
            for img in os.listdir(base_image_path):
                
                # Only get images we care about.
                if os.path.splitext(img)[-1].replace('.','').lower() not in image_types:
                    continue
                
                # Set up the dict.                
                if img not in encoded_strings:
                    encoded_strings[img]=None
                # Get the image's full path.
                image_path = os.path.join(base_image_path,img)
                # Read and encode.
                with open(image_path, "rb") as stream:
                    raw = stream.read()
                    inc = base64.b64encode(raw)
                    encoded_strings[img]=inc
                    
        except Exception as e:
            print(e)
                
        return encoded_strings
    else:
        print ('%s not found.' %base_image_path)


# ==========================================================
# MAIN
"""
Use as Pyhton 3+ import.
Run as script.
Run from terminal: C:\> python img2base64 c:/images png,jpg
C. Nichols http://www.darkartistry.com/
"""
# ==========================================================
if __name__ in '__main__':
    """
    Exercises:
        Create a function to write results to disk.
        Add getopt and add an output file param.
    """

    image_filter = [] # Add a filter if you need to or alter the defaults in the function directly.

    script_base_path = '' # Set the path to images here to override interactive console run.
    #script_base_path = r'C:\pyprod\prod_web\static\images'
     
    img_path = None
    arg_path = None
    arg_filter = None

    # Determine if this script is executed from the console.
    # ======================================================
    # Run as script.
    # ======================================================
    if script_base_path:
        
        if len(image_filter) > 0:
            encoded = get_image_base64(script_base_path,image_types=image_filter)
        else:
            encoded = get_image_base64(script_base_path)

    # ======================================================
    # Run as interactive console app.
    # ======================================================
    else:

        usage = '\n\nUsage:\n\n img2base64 path_to_images png,gif\n\n Path is required.\n Comma delimited list, no spaces, of extensions is optional. Default is png.'
        argc = len(sys.argv)

        if argc == 1: print ('Too few arguments! This program requires at least a path and optional extensions to process.%s'%usage)
        if argc > 3: print ('Too many arguments! This program requires path and optional extensions to process.%s'%usage)

        if argc == 2:
            
            prog,arg_path = sys.argv
            print ('running interactively at %s'  %arg_path)
            encoded = get_image_base64(arg_path)
            
        if argc == 3:
            
            prog,arg_path,arg_filter = sys.argv
            arg_filter = [i.strip().lower() for i in arg_filter.split(',')]

            print ('running interactively at %s with filter %s'  %(arg_path,arg_filter))
            encoded = get_image_base64(arg_path, image_types=arg_filter)

    # Do something with the output, write to file, whatever...
    for img_name,enc_string in encoded.items():
        if enc_string:
            print ('\n', img_name, '->', enc_string)
        else:
            print ('\n', img_name, '-> Failed')

Ajax driven HTML 5 radial gauge.


• March 25, 2015 • Comments Off on Ajax driven HTML 5 radial gauge.

I’ve updated the JavaScript gauge example I created years ago. It takes a value between 0 and 100 and will automatically update using Ajax to pull the values in from a json file so no need to refresh the page or submit form data, just have a script or web programming language update the json data file to update the gauge live.

If you want to create a radial gauge, like a speedometer, but are not sure where to begin this will get you started. It uses the canvas tag and works well in the latest IE. I have not tested it in other browsers but any browser that supports the canvas tag will work, including Safari on iPhone/iPad. My old code works so I have no reason to believe this wouldn’t. I’ve made this as basic as possible so it’s not bogged down in over complication or clutter. I was going to write up a walk through, but there isn’t much to it that can’t be found elsewhere, like information on JQuery Ajax, json, canvas, or HTML 5.

Download the the files, place in your web server directory, change the paths to the json and the JQuery code in the index.html file and point your browser to it. I’ve included a Python script for testing, which will update the values so you can be mesmerized as the needle spins every 30 seconds on a randomly picked value, or not.

If you want it to just update on outside a server, on refresh, page load, or form submit just remove the Ajax call in the document.ready and provide the values yourself. My old code shows how to do this with a form submit and that can be found in the Flash gauges page.

If you need a web server, get this awesome prepackaged and configured Apache server here. If you need Python, get it here. Both are free.

Statusbar example with Swift in XCode 6.2


• February 17, 2015 • Comments Off on Statusbar example with Swift in XCode 6.2

I’ve created a simple Statusbar application that dynamically creates a menu of Applications in the Utilities folder and opens the Application when the corresponding menu item is clicked. I use simple NSThread for the collection and use image assets for the icon. Not a lot of error handling and could be tweaked for speed, and maybe the thread was over kill, but it should be enough to get most people started. Hope some one finds it useful.

Here’s a link to the full project.

Preview: