Friday, December 31, 2010

PHP Script to send PDF file as attachment (requires FPDF object)

function mail_pdf_as_attachment($pdfobj,$faxnumber) {
$pdfdoc = $pdfobj->Output("", "S");
$attachment = chunk_split(base64_encode($pdfdoc));
$to = "destinationaddress@destination.com";
$from = "sourceaddress@source.com";
$subject = $faxnumber;
$message = "See attached pdf file";
$separator = md5(time());
$eol = PHP_EOL;
$filename = "medfax6.pdf";
//headers
$headers = "From: ".$from.$eol;
$headers .= "MIME-Version: 1.0".$eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"".$separator."\"".$eol.$eol;
$headers .= "Content-Transfer-Encoding: 7bit".$eol;
$headers .= "This is a MIME encoded message.".$eol.$eol;
// message
$headers .= "--".$separator.$eol;
$headers .= "Content-Type: text/html; charset=\"iso-8859-1\"".$eol;
$headers .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
$headers .= $message.$eol.$eol;
// attachment
$headers .= "--".$separator.$eol;
$headers .= "Content-Type: application/octet-stream; name=\"".$filename."\"".$eol;
$headers .= "Content-Transfer-Encoding: base64".$eol;
$headers .= "Content-Disposition: attachment".$eol.$eol;
$headers .= $attachment.$eol.$eol;
$headers .= "--".$separator."--";
mail($to, $subject, "", $headers);
}

Dual Formatting of External Hard Drives (PC and MAC)

You can do that?? It turns out, yes.

Plug the drive into a USB port on the mac. Go into Disk Utility (You can find the utility fastest by clicking on the "magnifying glass" shaped icon on the far upper right corner of the screen, which is called Spotlight, and typing Disk Utility.

Then partition the drive, selecting the option to create 2 partitions. This will format the external drive. Select mac formatting for one and MS-DOS FAT for the other. The trick is go go into "Options" after you enter the Partitions tabs and under options select the bottom of the three options, which allows you to create a root directory that will allow the MS-DOS partition. Otherwise, it isn't even an option.

After being done formatting, you will see both partitions on the mac with their assigned names, and if you plug into a PC you will only see the PC partition with its name and letter, like E: as assigned by the PC.

Hosting Content on the World Wide Web on a Laptop

I have a Macbook Pro (MBP) running Snow Leopard. It is connected to the internet through a wireless router. I am running MAMP on it and using it as a server, and I access the server from the iPhone, or the iPad, from WITHIN the LAN (behind the router) via the Wi-Fi connection to that router. Wouldn't it be nice to be able access that same server remotely, from OUTSIDE the LAN, via, say, a 3G connection?

Three steps to doing this:
1. Find out what the IP address is (whatismyip.com)
2. Tell the ROUTER to assign a static IP address to the MBP within the LAN
login to router as admin ->LAN setup->Use Router as DHCP Server->Address Reservation
In my case, I just selected the address it had randomly assigned to make it permanent (192.168.1.18)
You need to know your computer's name and/or mac address to do this, so that you select the correct computer.
3. Then you need to go to port forwarding (still in admin in the ROUTER settings), and assign start port 8888 to forward to end port 8888 on 192.168.1.18.

Finally, step outside the LAN and browse to:
ipaddress:8888/homefolder/index.php
and you are there.

CAUTION: if you do this and leave your server on, your precious MBP is on the world wide web, and can be subject to cyber attack. It helps that the port is not 80, or 8080, which are far more common, but still, take precautions.

Saturday, November 6, 2010

AHK (AutoHotKey) Script to control Dialog Box

iWeb_Init()
SetTitleMatchMode,2
ControlGet,hWnd,Hwnd,,Internet Explorer_Server1,ahk_class Internet Explorer_TridentDlgFrame
pDoc:=IE_GetDocument(hWnd)
pWin := iWeb_DomWin(pDoc)
COM_Invoke(pWin,"Document.all.item['btnID'].click")
COM_Release(pwin)
WinWaitClose, Web Page Dialog
SoundPlay, *64
Com_Release(pDoc)
iWeb_Term()
return

Note: the three indented lines can be replaced with
iWeb_clickDomObj(pDoc,"btnCancel")
accomplishes the same thing but I left the three lines in as a demonstration of how to inject javascript into an AHK script.(There isn't an iWeb function for everything)

Note: You have to #include COM.ahk and iWeb.ahk for this to work, and I commented out the MsgBox line in the COM_Error() function within COM.ahk in order to stop useless error messages from popping up. These libraries were not designed for dialog boxes, but they work, and the error messages just get in the way. Normally calling COM_Error(0) does the same thing except the iWeb functions keep calling COM_Error(1)

Note: ['btnID'] can be replaced with ['387'] or whatever the element index number is.
Notice the WinWaitClose to wait for the Dialog to close, and the Sound alert command. You can also use WinWait to just wait for the Web Browser Object to get focus.

Monday, November 1, 2010

Access to Snow Leopard MAMP server and AHK server from a Windows Domain

For months I have been using a MacBook Pro with OSX 10.4 as a server at work to house my MAMP scripts and AHK scripts. In a previous post I described how to network a MacBook Pro with OS X 10.4 to a windows domain. IT TURNS OUT THOSE INSTRUCTIONS DO NOT WORK FOR SNOW LEOPARD (OS X 10.6). I brought in a back up MacBook Pro and much internet research did not generate a solution for weeks. Until Now.

The secret: On the Mac go to System Preferences>Network>Advanced>WINS>NETBIOS Name. This is where the name of the computer resides. I had been putting the name of the computer into my windows domain machines as specified in System Preferences>Sharing>File Sharing for weeks in a futile effort to connect. It was the wrong name. Thus, for MAMP server the URL is http://netbiosname:8888/MAMP and for the AHK scripts the server is \\netbiosname\macusername. It's that simple. I swear, nobody in the universe knows this little factoid.

Whether it made a difference or not, some other system adjustments were made according to "internet advice". They may be necessary too, I am not sure. All I know is I did them before I found that last little secret and the whole system works very nicely. Those other things included setting the workgroup to to MACPC (not sure why that would matter, all of the windows machines are in a domain, not a workgroup), of course making sure the mac is connected to the correct wireless router with the same network as the other machines (again, not sure if it matters, since most of the machines are connected by ethernet to the network), and I used my "Launcher" on my mac to run "Directory Utility" and put a checkmark in the "Activate Directory" box. For what it's worth. And I went into aforementioned sharing and did everything in my previous post, plus activated privileges for guests, added myself as a user, activated ftp, etc. (Note- the "Windows Sharing" pane present in 10.4 doesn't exist in 10.6) Have fun with this. Networking is a real bear.

Sunday, September 5, 2010

Examine Mouse Positions in AHK

A truly useful script to have running while writing Mousey Scripts.
I have mine set to z

CoordMode, Mouse, Screen
MouseGetPos, X, Y
MsgBox %X%, %Y%
return

AHK, Mouse Clicks, and Remote Desktop Connection (RDC)

I was having fits with mouse clicks in AutoHotKey scripts not clicking on the right spot on the screen. I originally "solved" this by including the all - important line

CoordMode, Mouse, Screen

at the beginning of each AHK script, which tells the script to override the default behavior (coordinates relative to active window) and uses coordinates relative to the actual monitor dimensions. This eliminates errors due to the wrong window (like WebDiagLog Boxes) stealing the focus. But here is another factor to consider:

When you RDC to a computer and run AHK scripts on the server computer, the coordinates of mouse clicks will vary based on the screen resolution settings on the client computer. The converse is true as well: if you author a script remotely on a client computer using RDC, when to go to run the script locally on the server without RDC the coordinates revert to the local monitor.

Here is how I deal with this:

CoordMode, Mouse, Screen
WinGetPos,,,currentw,curretnh,Program Manager
authorw := 1280
authorh := 800
wfactor := currentw/authorw
hfactor := currenth/authorh
x := 36
y := 170
xfinal := x*wfactor
yfinal := y*hfactor
Click %xfinal%, %yfinal%

Now any Client computer can author a script on a server, and it will run locally on the server and on any other client, no matter what the screen resolution is.

Addendum:
You can also examine the screen resolution using this javascript bookmarklet:
alert(screen.width);
alert(screen.height);

Sunday, August 15, 2010

Windows and Mac on same Network

I have a MAMP Server on my LAN. Browsing to it from within the network, or FTPing to from within the network can be done using the IP address, but that could be dynamic and change (particularly if I take the server home and use it on a different LAN). I browse or FTP to the server from various devices (Windows Vista, Windows XP, iPod, iPhone, iPad. I was going crazy because the apparent computer name was unrecognized in a pattern that I didn't understand. UNTIL NOW !!

Here is the great secret: MAC PROVIDES 2 DIFFERENT COMPUTER NAMES FOR ONE SERVER: ONE FOR WINDOWS DEVICE CLIENTS AND ONE FOR APPLE DEVICE CLIENTS. You find this in Mac System Preferences --> Sharing --> Windows Sharing. At the top it says "Other computers on your local subnet can access this computer at lowername.local". That's for Apple clients. For Windows clients, use the computer name in text field above that message, which can be totally different, which I will call uppername. Even if you force it to be the same, it is still without the ".local".

For FTP, if you highlight Windows Sharing, it says "Windows users can access your computer at \\ipaddress\firstnamelastname". You can substitute the computername for the ipaddress, and now when you browse to the device on the network it prompts you for username and password. Your username is firstnamelastname, which corresponds to the name of your user folder on your mac inside the "Users" folder, and your password is your mac password. Highlighting the various other checkbox sharing options gives you all kinds of useful information for networking in addition to this.

So in summary:
Apple devices browse to: lowername.local:8888
Windows devices browse to: http://uppername:8888

Apple devices ftp to: Surf to uppername within Finder
(Finder --> [Command]-K --> afp://uppername._afpovertcp._tcp.local)
Window devices ftp to: \\uppername\firstnamelastname from either networks, browser, or Windows -->Run.

And of course, you can browse to the MAMP server from the server itself within Safari:
http://localhost:8888

Addendum: MAMP installation puts the root directory by default inside the Applications Folder, in subdirectory MAMP/htdocs. Everything inside Applications folder is inaccessible over FTP. To change the root, go into that little MAMP window and there is a big "preferences" button on the lower right (below Stop Servers, Open Start Page). Go to Apache tab. Change document root to /Users/firstnamelastname/htdocs and of course move the entire htdocs folder to that location. Also note that the default port is 8888 with MAMP. That can be changed to a different port if necessary, but you have to include the port after a colon in MAMP. (Be aware that WAMP uses a different port by default, I think 8080, and you can get away with omitting the colon and port number in WAMP).

Tuesday, July 27, 2010

Debugbar, Autohotkey, Javascript

Great discoveries this past week. First of all, Debugbar is a great plugin for Internet Explorer for examining the DOM of websites, especially those that have complex dynamically created DOM with javascript. Also you can run javascript in the Debugbar console on the website without resorting to "navigating" out of the URL (you don't have to type the script into the URL input field, or navigate out of the native URL using links or favorites), which makes running these scripts possible when you have Web Controls/Agents on your source URL.

You can access the data within a frame in the DOM using the following javascript syntax:

str = top.myframename.document.GetElementById('myelementid').innerHTML;

and then use javascript REGULAR EXPRESSIONS (Regex) functions to parse the data into usable formats

Autohotkey is capable of launching javascript, but it is trickey. You have to either use the URL input field or Debugbar Javascript Console to do it, neither of which is elegant, or you have to use the COM library which is documented on the Autohotkey forum, again, which will require a learning curve. A better solution is to use Autohotkey to reliably click the correct objects in the browser, and the two tricks I have learned are:

CoordMode, Mouse, Screen

That line allows you to accurately base Mouse Movements and Click Coordinates to be relative to the screen instead of to the window, which helps when the script is popping up windows all over the place. The other trick is

Sleep, 100

Between each Click, it's good to pause the program for 1/10th of a second to let the computer catch up with itself. Prevents errors.

Monday, July 5, 2010

PHP Script accept query string data and place onto PDF form

require_once('fpdf.php');
require_once('fpdi.php');
$pdf = new FPDI();
$pdf->AddPage();
$pdf->setSourceFile('../pdfdoc\MedSolMRICTheadneck.pdf');
$tplIdx = $pdf->importPage(1);
$pdf->useTemplate($tplIdx, 10, 10, 200);

$pdf->SetFont('Arial','B',10);
$pdf->SetTextColor(0,0,255);
$pdf->SetXY(56, 50);
$pdf->Write(0, $_GET['lastname'].'---'.$_GET['firstname'].'---'.$_GET['dob']);

$pdf->Output();
?>

Notes:
-The $_GET[] array names are in quotes to make WAMP happy and match the query string names the the javascript bookmarklet that sent the query
-The main work in writing this is finding the XY coordinates in the third to last line
-Copy and paste the 4 line block for each data entry point on the form, each with its own XY coordinates
-Note the color 0,0,255 (blue). Other useful colors: 0,0,0 - black and 255,0,0 - red.
-Note the 'B' parameter in font for bold: helpful when filling out forms.
-Note the source file path with the backslashes again to make WAMP happy.

So, big picture: You've invoked a bookmarklet to navigate from a website with data to a PHP script on WAMP which pulls up a PDF document in your localhost directory tree and inserts the data on the form. Now you run your AutoHotKey script to print or fax it.

AutoHotKey Script for Emailing a PDF File

:*:][::

Send {Click 1228,100}
Send {Click 1145,254}
SetKeyDelay,700,100
Send !a
SetKeyDelay,50,100
Send doc@scanr.com
Send {Tab}{Tab}{tab}^a
SendRaw +18005551212
Send !s

return

The keystrokes ][ trigger two mouseclicks to pull "send page" from EI7, followed by keystrokes that send the attachment to an online faxing service.

(Note: the asterisk near the beginning causes the script to execute immediately with the ][ trigger, without a following spacebar. Sometimes, you need to precede the execution with a spacebar keystroke to "clear" previous keystrokes.)

Javascript to fetch and submit data

This script will fetch data from the input fields of a web site and submit the data as a query string to a URL of your choosing:

javascript:
var lastname_elem = document.getElementById
('ctl00_ContentPlaceHolder1_txtLName');
var lastname = lastname_elem.value;
alert(lastname);

var firstname_elem = document.getElementById
('ctl00_ContentPlaceHolder1_txtFName');
var firstname = firstname_elem.value;
alert(firstname);

var dob_elem = document.getElementById
('ctl00_ContentPlaceHolder1_txtDOB');
var dob = dob_elem.value;
alert(dob);

open('http://example.com?lastname='+lastname+
'&firstname='+firstname+
'&dob='+dob,
'_self',
'resizable,location,menubar,toolbar,scrollbars,status');

You just need to find out the element id for the input fields. This example pops the data from the input fields into alert text boxes before submitting the get request to the next web site, for debugging purposes.

Sunday, July 4, 2010

More on MAMP to WAMP migration - fpdf Scripts

Not sure if this is a MAMP to WAMP issue or a PHP 5.2 to 5.3 issue, since both changed at the same time but here is what I found while migrating fpdf scripts:

1. MAMP likes the &= syntax. Change to = in WAMP. If you don't, you will get a lengthy error message.
2. If you open a pdf file and view it in the Internet Explorer Browser, and get a whole lot of gibberish characters, if you close your browser and reopen it and try again, the pdf will open normally. It either has something to do with cacheing or with IE security settings in tying browser objects to Adobe Reader, a third-party application. I have also read that it is a IE6 bug, although it happened to me in IE7. If it persists, perhaps switching to firefox would help, I never did that experiment.

Sunday, June 27, 2010

Strategy Session

I have re-thought the overall strategy for a particular kind of application. Here are the steps that I think will be successful:

1. Use javascript bookmarklets to run customized code within the browser that interacts with the infomation within the browser window from the server. (Trigger the bookmarklets by setting up icons in the "links bar" for IE or the "bookmarks bar" for Safari.)

2. Use javascript cookies (within the document object) to store and retrieve data from the server, and to monitor the client for subscription expiration dates. Encrypt and delete the relevent information after use.

3. Use javascript to trigger 'autohotkey scripts' for windows or 'language&text shortcuts' for mac. This allows screentouch activation of specific shortcuts without needing a platform-specific keyboard, or a keyboard at all.

4. Use VNC to allow cross-platform access to the browser (such as from a mobile phone or tablet device). Use VPN to allow remote desktop connections to potential customers for set-up and troubleshooting.

5. Market the product/service via Twitter ( instead of by mail / email / phone / meeting / advertising / facebook ). Start with the major blog-style twitterers with large followings (within the appropriate subject matter), and then enter their "following lists" for ever expanding names of leaders for targeted populations.

Monday, June 21, 2010

Migrating PHP/SQL from MAMP to WAMP

1. Exported my database to a .sql file, using phpmyadmin. Created a new database with the same name in WAMP and left it empty. Then imported it within the phpmyadmin environment using the import function from within the empty database. Initially got error message because the database exceeded the 2MB size limit (it was 7.5MB) but followed the directions as prompted to change the php.ini file so that the max_filesize parameter was 8MB.

2. PHP scripts that ran in MAMP initially wouldn't run in WAMP. Got error messages saying I had to initiallize array variables before using them, and "undefined constant blah, assumed 'blah' " meaning put array component names in quotes, as in $array["blah"] not $array[blah].

3. Various allowable permutations of embedding SQL commands within PHP using different orders of double or single quotes behave erratically in WAMP, much testing and debugging necessary.

4. Default user/password to access mysql in MAMP ("root"/"root") changed to "root"/"" in WAMP.

Sunday, March 21, 2010

Import PDF file into PHP script and superimpose text

The last post neglected to mention that the license to remove the PDF watermark costs over $500 (for PDFLib). I thought that since all the "native" php functions for php were activated the license would be free, or at least below $100. NOT.

So I switched to what turns out to be a three pronged solution using free libraries:

FPDF - from fpdf.org
FPDI - from setasign.de
FPDF_TPL - from setasign.de

Recipe:
1. FPDF Put fpdf.php into script folder. Put the font folder in there too.
2. FPDI Put entire contents of FPDI download (including fpdi.php) in the same folder.
3. FPDF_TPL Put fpdf_tlp.php into the same folder.

Now the sample scripts that come with FPDI and FPDF work!!

Friday, March 19, 2010

Adding PDFlib to MAMP

(1) Download PDFLib 8.0
Don't install. Instead, enter the downloaded disk image, and surf to:
/bind/php/php-520/libpdf_php.so
Copy that file into:
/Applications/MAMP/bin/php5/lib/php/extensions/no-debug-non-zts-20060613

(2) Open Terminal and:
chmod +x /Applications/MAMP/bin/php5/lib/php/extensions/no-debug-non-zts-20060613/libpdf_php.so

(3) REM out
#DYLD_LIBRARY_PATH="/Applications/MAMP/Library/lib:$DYLD_LIBRARY_PATH"
#export DYLD_LIBRARY_PATH
in the file
/Applications/MAMP/Library/bin/envvars
by adding # to the beginning of those two lines.

(4) Add
extension=libpdf_php.so
to extension section of php.ini for php5

REBOOT APACHE AND CHECK THAT PDFLIB IS ENABLED IN PHPINFO.
CREDITS TO JAMES WRIGHT IN THE MAMP FORUM. THANKS YOU JAMES WHERE EVER YOU ARE.

Saturday, January 2, 2010

AppleScript and JavaScript

1. You can actually insert JavaScript commands inside AppleScript. The syntax is "do JavaScript", as in:
tell application "Safari" to do JavaScript "alert('Hello, world!')" in document 1
or
do JavaScript "window.print()" in document 1

2. You can write blocks of JavaScript code and then save the code as a bookmark, and then call the bookmark from a browser, and the JavaScript code will run. There is a lot on the web on this trick, which even has a name: Bookmarklet. There are all kinds of Bookmarklets out there for public consumption, like widgets. You can have an onscreen calculator, you can change the color scheme of a web page, you can fill out a web page, etc. etc.

3. You can pass variables from an AppleScript to a web server by inserting the variables into an HTML GET, as in:
set the URL of document 1 to "http://localhost:8888/foo.php?key1=" & val1 & "&key2=" & val2

4. You can use your iPhone as a dictaphone by using the free Dragan App (trick: "send to clipboard")
You can automatically send the clipboard contents to MobileMe email (trick: use free ClipMail app)
MobileMe email is push email, and can be used to launch an AppleScript on a MacBook Pro (trick: use Apple Mail Rules)
AppleScript can retrieve the contents of the email, parse it, and send it to a web server by calling a php script which inserts the contents into an SQL database.
Thus, following these steps, you can DICTATE into your phone and the text is instantly available in a REMOTE SQL SERVER, already parsed, with individual words and phrases sorted and inserted into records.

5. You can debug AppleScripts by having the script SPEAK the variable values or DISPLAY the variable values in dialog boxes:
display dialog var1
set speakString to "The value of var1 is" & var1
say speakString