I.T.
Solution for: “Microsoft office has stopped working” (applies to Office 2007 & 2010)
by musashi on Aug.18, 2010, under I.T.
Symptoms: Microsoft word/excel/powerpoint/etc. crash a few seconds after being opened with the error message:
As a few clients of mine have upgraded to MS Office 2010, this problem has appeared a few times and it seems damn near impossible to fix… but there is a fix. You ready?
Set your default printer to the “Microsoft XPS Document Writer”.
I don’t know why this works, but it’s going to have to do until M$ releases and update/patch/fix/etc.
jqueryFileTree connector script for python cgi
by musashi on Aug.10, 2010, under General, I.T.
If you use jquery and haven’t messed with the jqueryFileTree plugin, I’d highly recommend you do so. It’s pretty neat, and there are connector scripts already written in various languages for use with this plugin. However, there wasn’t one for python cgi (there was one for django however). So, I wrote my own! Try it out:
# jqueryFileTree connector script for python cgi
# Version: 1.0 / 10 August 2010
# Author: Charles Hamilton / musashi@nefaria.com
# Released under the GNU GPLv3
# Modifications and improvements are welcome (and encouraged!)
import os, cgi, cgitb, urllib
cgitb.enable()
form = cgi.FieldStorage()
print ’Content-Type: text/html\n\n‘
print ’<ul class="jqueryFileTree" style="display: none;">‘
path = urllib.unquote(form['dir'].value)
dirs = []
files = []
filelist = sorted(os.listdir(path))
for object in filelist:
if os.path.isfile(path + ‘/‘ + object):
ext = os.path.splitext(path + ‘/‘ + object)
files.append(‘<li class="file ext_‘ + ext[1] + ‘"><a href="#" rel="‘+ path + object + ‘">‘+ object + ‘</a></li>‘)
elif os.path.isdir(path + ‘/‘ + object):
dirs.append(‘<li class="directory collapsed"><a href="#" rel="‘+ path + object +’/">‘ + object + ‘</a></li>‘)
for d in dirs:
print d
for f in files:
print f
print ’</ul>‘
Python + Reportlab: example #1
by musashi on Aug.05, 2010, under General, I.T.
So I’ve been using reportlab lately and I have to say, it’s pretty neat. This post will (hopefully) be the first of many to follow. It’s just a simple example that shows how to take input from a web form and insert it into a PDF. First, the code:
2
3 import cgi, sys
4
5 form = cgi.FieldStorage()
6
7 if not "name" in form:
8 print """Content-Type: text/html\n\n
9 <html>
10 <head>
11 <title>Reportlab Example</title>
12 </head>
13 <body>
14 <form action="index2.cgi" method="post" enctype="multipart/form-data">
15 <fieldset>
16 <legend>Personal Info:</legend>
17 Name: <input type="text" name="name"><br />
18 Photo: <input type="file" name="photo"><br />
19 <input type="submit">
20 </fieldset>
21 </form>
22 </body>
23 </head>"""
24
25 else:
26
27 from reportlab.platypus import *
28 from reportlab.lib.styles import getSampleStyleSheet
29 from reportlab.lib.units import inch
30 from reportlab.lib import colors
31 doc = SimpleDocTemplate(sys.stdout)
32 styles = getSampleStyleSheet()
33 content = []
34
35 if form['photo'].filename:
36 image = Image(form['photo'].file)
37 image.drawHeight = 2*inch*image.drawHeight / image.drawWidth
38 image.drawWidth = 2*inch
39
40 if form['name'].value:
41 text1 = Paragraph(form['name'].value, styles['Heading1'])
42 text2 = Paragraph(form['name'].value, styles['Heading2'])
43 text3 = Paragraph(form['name'].value, styles['Heading3'])
44
45 content.append(text1)
46 content.append(text2)
47 content.append(text3)
48 content.append(image)
49 print "Content-Type: application/pdf"
50 print "Content-Disposition: attachment; filename=example.pdf\n\n"
51 doc.build(content)
Now the explanation:
Lines #1 – #5 handle specifying the interpreter, importing modules, and initializing the “FieldStorage” dictionary (as the variable ‘form’).
2
3 import cgi, sys
4
5 form = cgi.FieldStorage()
Line #7 tests whether the form has been submitted by checking to see if the ‘name’ field has been filled out. There’s many better ways to test for form submission, but for the purposes of our example, this will work just fine.
Lines #8 – #23 print the form
9 <html>
10 <head>
11 <title>Reportlab Example</title>
12 </head>
13 <body>
14 <form action="index2.cgi" method="post" enctype="multipart/form-data">
15 <fieldset>
16 <legend>Personal Info:</legend>
17 Name: <input type="text" name="name"><br />
18 Photo: <input type="file" name="photo"><br />
19 <input type="submit">
20 </fieldset>
21 </form>
22 </body>
23 </head>"""
Lines #26 – #29 import some more modules (i.e., reportlab related stuff).
27 from reportlab.lib.styles import getSampleStyleSheet
28 from reportlab.lib.units import inch
29 from reportlab.lib import colors
Now line #30 is important, this is where we decide where we want to write the output. We can either save the output to a file, or we can dump it to stdout (i.e., back to the web browser). In this example, we’re going to send the output back to the web browser.
Line #31 handles getting the style sheet that we’re going to use to format our text.
In line #32, we initialize the ‘content’ dictionary — this is where we’re going to keep the elements of our PDF until we’re ready to write it to stdout.
In lines #34 – #37, we test for the ‘photo’ field — if it has been submitted, we create an Image object out of it. We’re assuming that the user is going to submit a photo, but in reality, the user could submit anything so some further “hardening” of this form would be required in order to ensure that the only things that actually get submitted are image files.
34 if form['photo'].filename:
35 image = Image(form['photo'].file)
36 image.drawHeight = 2*inch*image.drawHeight / image.drawWidth
37 image.drawWidth = 2*inch
Lines #39 – #42 test to see if the ‘name’ field has been submitted; if it has, it creates some text objects to insert into our PDF.
40 text1 = Paragraph(form['name'].value, styles['Heading1'])
41 text2 = Paragraph(form['name'].value, styles['Heading2'])
42 text3 = Paragraph(form['name'].value, styles['Heading3'])
Lines #44 – #47 append all the objects that we want to appear in our PDF, to the ‘content’ dictionary we created earlier.
45 content.append(text2)
46 content.append(text3)
47 content.append(image)
Lines #48 – #49 send the appropriate headers to the web browser, before we send our completed PDF file.
49 print "Content-Disposition: attachment; filename=example.pdf\n\n"
And finally, line #50 builds our PDF and sends the output to stdout.
Test it out; you should end up with a PDF that looks something like this:
Of course, this example doesn’t even scratch the surface of what you can do with reportlab. Hopefully I’ll post some more examples later on
Configuring “Per User” licensing in Terminal Services, remotely *without* Remote Desktop access
by musashi on Jan.07, 2010, under I.T.
So the other day I was trying to connect to one of the terminal servers that I manage (for the purpose of this post, we’ll call the server ‘TERMSVR01′) and I got the following error message and was promptly disconnected:
At first glance, this seems as though the server ran out of TS CALS (Terminal Server Client Access Licenses). I was pretty sure that the server was configured to use the “Per User” licensing mode. However, a Windows Server 2003 Terminal Server operating in the “Per User” licensing mode can’t run out of licenses to the extent that it prevents the user from connecting (and instead, giving them the aforementioned error message). To the best of my knowledge, it can only do this when it is operating in “Per Device” mode. So this was the assumption that I ran with — that somehow, this server was never configured for “Per User” -or- it was, but the setting was either changed, reset, or corrupted somehow.
So, even though I wasn’t able to connect to TERMSVR01 via Remote Desktop, I was able to “Manage” it remotely by doing the following:
- Open “Active Directory Users and Computers” on any Domain Controller
- Expand the “Computers” node
- Right-click TERMSVR01 and select ‘Manage’
Now we can do a few things (not many) on the server. One thing I wanted was to have a look at the Event Viewer. There were a few error messages like the following:
Event Source: TermService
Event Category: None
Event ID: 1004
Date: 1/5/2010
Time: 6:18:23 PM
User: N/A
Computer: TERMSVR01
Description:
The terminal server cannot issue a client license. It was unable to issue the license due to a changed (mismatched) client license, insufficient memory, or an internal error. Further details for this problem may have been reported at the client’s computer.
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
The more of these I saw, the more confident I was that my assumption was correct — the server was operating in “Per Device” mode and it had finally run out of licenses. I had the following options:
- Wait for someone to go onsite and reconfigure the licensing mode (easy, but it would have to wait until tomorrow) or…
- Attempt to reconfigure this setting and restart the service remotely (so that the setting takes takes effect) … all without having “Remote Desktop” access to the server.
Care to guess which option I chose?
Step #1: Override the licensing mode setting using group policy
- Click ‘Start’
- Click ‘Run’
- Type the following command:
gpedit.msc /gpcomputer:TERMSVR01
- Click ‘OK’
Those four steps open the group policy (remotely) for TERMSVR01. Next we need to actually change the setting:
- In the left-hand panel, expand “Administrative Templates”
- Expand “Windows Components”
- Click on “Terminal Services”
- Locate the following setting in the right-hand panel:
Set the Terminal Server licensing mode
- Double-click the aforementioned setting
- Change the option (directly below the heading) to “Enabled”
- Select “Per User” from the drop-down box (below the heading: “Specify the licensing mode for the terminal server”.)
- Click ‘OK’
- Close the “Group Policy Object Editor” window
Great. The licensing mode has been changed but the setting won’t take effect until the service is restarted. We could open ‘services.msc’ and connect to ‘TERMSVR01′ by using the ‘Connect to another computer …’ option in the ‘Action’ menu. This will allow us to administer almost all running services on TERMSVR01 … almost all. You’ll notice immediately that you cannot start/stop the ‘Terminal Services’ service from this management console, so we need to find another way to do it.
The easiest way I know to accomplish this task is to use the WMIC command from the command prompt.
Step #2: Restart a remote service using WMIC
- Open a command prompt
- Type the following command (then hit enter) to stop the service:
wmic /node:TERMSVR01 service where “caption=’Terminal Services’” call StopService
- Then, type the following command to start the service:
wmic /node:TERMSVR01 service where “caption=’Terminal Services’” call StartService
- Close the command prompt
If everything was successful (and my assumption about the nature of the problem was correct), then I should be able to connect to the server using the Remote Desktop client. I fired up the client and voilà! It worked perfectly.
How to upgrade ClamAV on Ubuntu (Intrepid)
by musashi on Oct.08, 2009, under I.T.
On October 5th, the Clam Antivirus team announced that ClamAV 0.94.x is now entering its end-of-life phase. What’s worse, versions of ClamAV earlier than 0.95 will no longer be able to receive CVD updates; basically rendering any older versions of ClamAV nearly worthless. This is all supposed to happen by April 2010—soon. You can read more about it here.
Good news though, the upgrade process on Ubuntu is pretty easy:
If you haven’t already done so, enable the ‘backports‘ repo by editing your /etc/apt/sources.list file and uncommenting (or, inserting) the following two lines:
deb http://us.archive.ubuntu.com/ubuntu/ intrepid-backports main restricted universe multiverse deb-src http://us.archive.ubuntu.com/ubuntu/ intrepid-backports main restricted universe multiverse
Then, resynchronize the package index files with the following command:
sudo apt-get update
Next, upgrade ClamAV:
sudo apt-get install clamav-daemon
This command will [sometimes] install apparmor as well; I don’t use apparmor so I uninstall it afterwards:
/etc/init.d/apparmor stop update-rc.d -f apparmor remove apt-get remove apparmor apparmor-utils
That’s all there is to it!
root@localhost:~# clamd -V ClamAV 0.95.2/9874/Thu Oct 8 06:24:12 2009