Sunday, December 7, 2014

Python dialog boxes and system call for launching Windows Photo Viewer

Here is the Python 2.7 code for my program that displays user prompts to create an XML file of text to accompany the files in a directory as part of my process for creating photo albums. I originally wrote this to run in a different environment that had an older version of Python and a different tool kit for user prompts, so to make this version I read a bunch of examples of how to use the Tkinter module; the links to the different examples follow the code. The system call for displaying the Photo viewer was all figured out a long time ago so I don't have the links for those examples, but when I migrated to MS-DOS python it took me forever to get the right command syntax to spawn that system call as a background task with no wait, so the links from that research are also attached.

import os
import sys
import array
import string
from Tkinter import *
import tkFileDialog
from tkFileDialog import askopenfilename
import tkSimpleDialog
from tkSimpleDialog import askstring
import tkMessageBox
from tkMessageBox import askquestion
import subprocess
import glob

default_gof_path = "C:/Users/Charles2/Documents/GOF2014"

# MS-DOS Python 2.7 compatible version
#
# Program structure:
#
# Prompt for any file in the directory to be analyzed
# Get directory name as the prefix to the .xls files to be produced
# Prompt for page title dates
# Prompt for page title text
# Open a .xls file and write the page header
# Read list of files in the directory
# For each file in list:
# Get the file name
# Pop up preview
# Pop up Y/N question for portrait
# Ask for a title
# Ask for text
# Write out the .xls info
# Close page tags and close file

def MakeGOF():
global default_gof_path

print('Starting MakeGOF')

samplefile = askopenfilename(initialdir=default_gof_path, title="Select any file in the directory to make into an album")
default_gof_path = os.path.dirname(samplefile)
gofdir = os.path.dirname(samplefile)

# Need a function to trim end of gofdir to make foldername.
foldername = gofdir.split("/")[-1]
print('MakeGOF: Source directory is %s in %s' %(foldername, gofdir))

outfilename = gofdir + "/" + foldername + ".xls"
outfile = open(outfilename, "a")

GOFnumber = askstring("GOF","For " + foldername + ", enter GOF number to use in title")
title = askstring("GOF","For " + foldername + ", enter album title")
subtitle = askstring("GOF","For " + foldername + ", enter album subtitle")
datestring = askstring("GOF","For " + foldername + ", enter album date string")
header_title = "GOFx: TITLE\n"
header_title = header_title.replace('GOFx',GOFnumber)
header_title = header_title.replace('TITLE',title)
header_subtitle = "meaning\n"
header_subtitle = header_subtitle.replace('meaning',subtitle)
header_datestring = "DATE\n"
header_datestring = header_datestring.replace('DATE',datestring)
outfile.write(header_title)
outfile.write(header_subtitle)
outfile.write(header_datestring)
outfile.close()

# Note: Need to use glob here to get only JPG files
globlist = gofdir + "/*.[J,j][P,p][G,g]"
files = glob.glob(globlist)
for f in files:
file = os.path.split(f)[1]
filenamestring = f.replace('/','\\')
systemstring= '%SystemRoot%\\System32\\rundll32.exe \"%ProgramFiles%\\Windows Photo Viewer\\PhotoViewer.dll\", ImageView_Fullscreen ' + filenamestring
subprocess.Popen(systemstring, shell=True)
is_port = askquestion("GOF","Is picture portrait orientation Y/N?")
name = askstring("GOF","Enter name for this picture")
text = askstring("GOF","Enter text for this picture")
outfile = open(outfilename, "a")
outfile.write("\n")
if (is_port == "yes"):
outfile.write("\t"+file+"\n")
else:
outfile.write("\t"+file+"\n")
outfile.write("\t"+name+"\n")
outfile.write("\t"+text+"\n")
outfile.write("<\Friend>\n")
outfile.close()
systemstring2 = 'TASKKILL /FI "WINDOWTITLE eq ' + file + '*"'
print systemstring2
os.system(systemstring2)
print('MakeGOF: Processing complete')
MakeGOF()



Links:

The first key migration to tKinter was the file selection dialog. The tookit that I had originally just had only one file selection tool that returned a file path. So in tKinter, I had to use askopenfilename(). askopenfile actually opens the file and returns the file handle, so although that's nice I didn't use that because I wanted to do a 1-to-1 migration.

http://stackoverflow.com/questions/10993089/tkinter-opening-and-reading-a-file

http://tkinter.unpythonic.net/wiki/tkFileDialog

http://stackoverflow.com/questions/20725056/get-a-files-directory-in-a-string-selected-by-askopenfilename

The next task was to migrate the text entry widget to tKinter. No problem. The first link that I tried was mostly a hilarious story of bad loop construction, but one of the later replies had the syntax for tkSimpleDialog.askstring()

http://stackoverflow.com/questions/15522336/text-input-in-tkinter

The next thing was an ask box with Yes/No buttons. No problem, tkMessageBox.askyesno(). It's a little funny though because it returns the strings "yes" or "no" rather than the more obvious True/False.

http://stackoverflow.com/questions/1052420/tkinter-message-box

Now the real challenge, forming the system call for Windows Photo Viewer in such a way that it's a background task with NOWAIT. spawn() is apparently discontinued in python 2.7, and I had a devil of a time getting subprocess to work the way I wanted. A plain old os.system() would always work but of course halted the program waiting for the viewer to be dismissed, and subprocess.call() and subprocess.Popen() kept giving me a "couldn't find executable" error. Eventually I figured it out: use subprocess.Popen(), and set shell=True so that it use can the DOS path and all of the windows environment shortcuts that I had in my command string. It really didn't help that a lot of the below examples didn't have shell=True or didn't emphasise the reason for having it set.

http://stackoverflow.com/questions/24974761/running-command-line-programs-in-background-using-python-os-or-subprocess-module

https://docs.python.org/2/library/subprocess.html

http://stackoverflow.com/questions/20069080/process-spawning-in-python

http://stackoverflow.com/questions/1196074/starting-a-background-process-in-python

This link supposed a problem with extra quotes in the command string, but that didn't turn out to be my problem. I took out the quotes in my command string, but got other errors and put them back in.
http://stackoverflow.com/questions/14655629/subprocess-call-vs-os-system-python

Likewise, this hint for the COMSPEC environment variable didn't have anything to do with my issue, but did get me thinking about the environment and trying setting the shell option:
http://stackoverflow.com/questions/20330385/cannot-find-the-file-specified-when-using-subprocess-calldir-shell-true-in

The final challenge was to get it to run. Clicking on the .py file didn't produce any results, but that's because the code was still full of bugs. I ran it from the command line in a DOS window to get the error messages until it actually ran the way it was supposed to.

I tried import at one point from the command line to try to run the file, and it totally didn't work the way I had hoped, but interestingly it created a .pyd file (which I also don't understand how to use yet, but it's probably worth remembering).
http://stackoverflow.com/questions/13621540/import-a-file-from-different-directory



Sunday, November 16, 2014

Memory for Acer Aspire One

Needed to upgrade the Acer Aspire One netbook, it only has 2G in it and was running quite slowly after some Windows updates. I did some research and was briefly alarmed that this model might have a 2G memory limit. However, it turns out that the model that I have, the AO756, can go up to 8G (these are apparently processor limits?). This Wikipedia page was very helpful in placing my netbook model number among the entire series of Acer Aspire One's, which is vast:

http://en.wikipedia.org/wiki/Acer_Aspire_One

Here are the detailed instructions on how to do the replacement. This model is well designed; it is super easy to open the case and access the SIMM slots.

http://acer.custhelp.com/app/answers/detail/a_id/19264/~/how-do-i-replace-the-ram-on-my-acer-aspire-one-756%3F

A couple of different sites advised that I get memory of type 204p PC3-10600 DDR3-1333 SODIMM.

http://forum.notebookreview.com/hardware-components-aftermarket-upgrades/677565-need-upgrade-my-new-acer-aspireone-ao756.html

I ordered a 4G SIMM from this vendor:

http://www.memorystock.com/memory/AcerAspireOne756.html

When the memory arrived and I opened the case of the netbook, I found that it had two SIMM slots, and only one was populated (obviously a 2G SIMM). I added the new SIMM to the other slot and when I booted the netbook, it registered all 10G.

Thursday, November 13, 2014

command line SVN in Windows

I have a system with TortoiseSVN installed, and a windows program that is running python that can make DOS system calls. I needed a way to do an SVN checkout from our repository from a python script.

TortoiseSVN has a command line interface, but it turns out that what this interface actually does is control the Tortoise GUI, not directly issue SVN commands. What I needed was to perform checkouts of specific files from a list of repository locations and revision levels. It turns out that using the Tortoise command line interface it is possible to check out folders, but not individual files. Also, the GUI pops up and you have to his OK or CANCEL, etc.

In the end, I installed a different SVN client. I recall that there weren't all that many options; I chose "Slik Subversion" despite it's lack of documentation.

https://www.sliksvn.com/en/support/using-subversion/basic-subversion-usage

I had a ton of problems getting the command line for performing the SlikSvn export to work, I was getting a message 'C:\Program' is not recognized as an internal or external command, operable program or batch file.' As one forum thread I consulted noted, this is obviously because "Program Files" has a space. By now, I am not sure exactly why this was a problem now and not with any of the other GNU routines that I am command-line calling from other parts of my python code. However, I did use the "shortened" version of Program Files in the final code. The final code also had a bunch of nice neatening and trimming of the SVN location pointer from each line of the configuration file. Here is the result:

svn_command = "C:/Progra~1/SlikSvn/bin/svn.exe export --force -r %s %s %s" % (svn_level, checkout_url, buildDir)
status = 0
try:
status = os.system('"C:/Progra~1/SlikSvn/bin/svn.exe" export --force -r %s %s %s' % (svn_level, checkout_url, buildDir) )
except:
print "Svn checkout command %s failed. Exiting." % svn_command
manifest_file.close()
return
if (status != 0):
print "Svn checkout command %s failed. Exiting." % svn_command
manifest_file.close()
return


Here is a forum thread about using alternatives to os.system to get status back from system calls. Again, I am not sure why I was over on this page, since os.system ended up verifiably returning status very nicely in my final code.

http://stackoverflow.com/questions/3503879/assign-output-of-os-system-to-a-variable-and-prevent-it-from-being-displayed-on

Here is the Wikipedia page listing all the SVN clients available. There's plenty of Windows ones here even after the Linux clients are ruled out. Not sure why I picked SlikSVN except that somebody must have mentioned it favorably in a forum thread somewhere.

http://en.wikipedia.org/wiki/Comparison_of_Subversion_clients


Here's the "money link" where it states that there is no way to do a single file checkout from the TortoiseSVN command line controller
http://subversion.1072662.n5.nabble.com/Ask-question-gt-Can-checkout-only-single-file-td138991.html


Links to the TortoiseSVN Command Line controller documentation:
http://stackoverflow.com/questions/1625406/using-tortoisesvn-via-the-command-line
http://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-automation.html
Note: I checked out using Export instead of Checkout, but that GUI control for this command is even less helpful:
http://tortoisesvn.net/docs/nightly/TortoiseSVN_en/tsvn-dug-export.html
However, knowing that single-file checkouts just don't happen in SVN (from the below link) was the knowledge that enabled me to format my SlikSubversion command as an Export:
http://stackoverflow.com/questions/122107/checkout-one-file-from-subversion

When I was thrashing about with the "C:\Program is not recognized as an internal or external command" error, I found a few links about something called the Command Processor AutoRun setting. This turned out to not have anything to do with my problem, but was interesting anyways:
http://www.donationcoder.com/forum/index.php?topic=33462.0;prev_next=prev
http://blogs.msdn.com/b/oldnewthing/archive/2007/11/21/6447771.aspx
http://www.herongyang.com/Windows-Security/PWS-Command-Processor-AutoRun-Registry-Value.html



bypassing ssh keys

I have a system that has ssh keys setup, but there's something wrong with them. It tries to use the keys, fails, and doesn't allow a regular login.

The way to get around this is to use the -o option with special keywords to tell it not to use the ssh keys.

ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no user@host

The page where I got this hint from is this one:

http://linuxcommando.blogspot.com/2008/10/how-to-disable-ssh-host-key-checking.html

Update 11/17/2018: Looking into this a few months later, I got some oddly different suggestions. These are interesting but strangely they didn't solve my problem at the time. Here they are anyhow in hopes that I was just missing something and they are still useful.

Mainly, I found this suggestion compelling:
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no example.com
From here:https://unix.stackexchange.com/questions/15138/how-to-force-ssh-client-to-use-only-password-auth

From the same page, this suggestion is fascinating, also didn't work in my case. Username, colon, no password:
ssh user:@example.com


Here is a slight variation on the above:
ssh -o PreferredAuthentications=keyboard-interactive,password -o PubkeyAuthentication=no host.example.org
From here:https://serverfault.com/questions/130346/ssh-use-only-my-password-ignore-my-ssh-key-dont-prompt-me-for-a-passphrase



Wednesday, November 5, 2014

How to remove a watermark in a Word document

This info is pretty helpful in generally understanding where to find the watermark controls in Word 2010:

https://support.office.com/en-US/Article/Remove-a-watermark-636cc588-489d-46c4-a03f-07f3f4820029?ui=en-US&rs=en-US&ad=US

How to add a check mark to a box in a Word document

It turns out that this is really easy and fun to do, because there are Wingdings that are checked boxes! Here's the info:

http://www.wikihow.com/Add-a-Check-Mark-to-a-Word-Document

Where to find coal in the minecraft demo world

T and I have been playing the Minecraft demo over and over. One of our biggest problems is not being able to make torches. I entered the above query in Google and didn't really get useful results, but a couple of the links that I got back were fun reads. They were:

Yahoo Answers: I have downloaded the demo of minecraft and I don't know how to play?
https://answers.yahoo.com/question/index?qid=20110612070505AAJoxNv

How To: Get Started in Minecraft
http://features.en.softonic.com/how-to-get-started-in-minecraft

Eventually I learned that the quick method is to harvest a bunch of wood, make a crafting table, make a pickaxe, harvest a bunch of cobblestone, make a furnace, cook a block of wood into charcoal, and make the torch out of that. The second link was the one that taught me that I had to use a pickaxe to get cobblestone, coal, and minerals to drop blocks.

I have been asking other similar questions about the minecraft demo; given the number of times that it has been played you'd think that some wise guy would have published a map of it or something, but I haven't found anything like that online. The minecraft wiki has a list of really major landmarks in the world:

http://minecraft.gamepedia.com/Demo_mode

Here is another, less detailed batch of information about the demo world:

http://www.minecraftforum.net/forums/minecraft-discussion/seeds/320613-demo-world-seed-now-with-co-ordinates?page=2

EpilogueThe eventual answer to my coal dilemma was obvious in retrospect; it's terribly easy once you have made a pickaxe to mine cobblestone, make a furnace, and reduce some wood down to charcoal which can also be used to make a torch. Duh!