~m-buck/+junk/gtk-desktop-info

« back to all changes in this revision

Viewing changes to plugin_pidgin.py

  • Committer: Mark Buck (Kaivalagi)
  • Date: 2009-06-19 17:13:00 UTC
  • Revision ID: m_buck@hotmail.com-20090619171300-5cbhr90xwg62z27y
Added --backgroundblend and --backgroundcolour options for visual seperation of output from wallpaper if required, Fixed song length output in the rhythmbox plugin when songs are an hour long or more, Added copy option to right click, enabling the copying of html content to the clipboard for testing, Moved common functions into a plugin_common module

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
#
7
7
#  Author: Kaivalagi
8
8
# Created: 23/11/2008
9
 
from htmlentitydefs import name2codepoint, codepoint2name
10
9
from datetime import datetime
11
10
from optparse import OptionParser
 
11
from plugin_common import getHTMLText, getCleanText, getTypedValue
12
12
import codecs
 
13
import fileinput
 
14
import logging
 
15
import os
13
16
import re
14
 
import os
 
17
import shutil
15
18
import stat
16
 
import shutil
17
19
import traceback
18
 
import logging
19
 
import fileinput
20
20
import urllib
21
21
 
22
22
try:
43
43
module_name = __file__.replace(os.path.dirname (__file__) + "/", "").replace(".pyc","").replace(".py", "")
44
44
 
45
45
class PidginData:
46
 
    
 
46
 
47
47
    def __init__(self, name, alias, group, status, status_message, icon, activitydatetime):
48
48
        self.name = name
49
49
        self.alias = alias
55
55
 
56
56
    def __cmp__(self, other):
57
57
        return cmp(str(self.status)+self.group.lower()+self.alias.lower(), str(other.status)+other.group.lower()+other.alias.lower())
58
 
    
 
58
 
59
59
    def __str__(self):
60
60
        return str(self.name+"("+self.alias+")")
61
61
 
70
70
    LIMIT = 0
71
71
    SORTBYLOGACTIVITY = False
72
72
    DEFAULTBUDDYICON = None
73
 
    
 
73
 
74
74
class Output:
75
75
 
76
76
    STATUS_OFFLINE = 1
81
81
    STATUS_EXTENDED_AWAY = 6
82
82
    STATUS_MOBILE = 7
83
83
    STATUS_TUNE = 8
84
 
        
 
84
 
85
85
    ICON_CHATTING = 1
86
86
    ICON_AVAILABLE = 2
87
87
    ICON_UNAVAILABLE = 3
91
91
    ICON_OFFLINE = 7
92
92
 
93
93
    PIDGIN_LOGS_PATH = "~/.purple/logs"
94
 
    
 
94
 
95
95
    options = None
96
 
    
 
96
 
97
97
    def __init__(self, options):
98
98
        self.options = options
99
99
        self.logger = logging.getLogger(app_name+"."+module_name)
100
100
        self.loadConfigData()
101
 
                      
 
101
 
102
102
    def loadConfigData(self):
103
 
        try:         
 
103
        try:
104
104
 
105
105
            self.config = PidginConfig()
106
 
            
 
106
 
107
107
            if self.options.config != None:
108
108
                # load the config based on options passed in from the main app
109
109
                configfilepath = self.options.config
110
110
            else:
111
111
                # load plugin config from home directory of the user
112
112
                configfilepath = os.path.join(os.path.expanduser('~'), ".config/"+app_name+"/"+module_name+".config")
113
 
                            
 
113
 
114
114
            if os.path.exists(configfilepath):
115
 
                
 
115
 
116
116
                self.logger.info("Loading config settings from \"%s\""%configfilepath)
117
117
 
118
118
                for line in fileinput.input(os.path.expanduser(configfilepath)):
119
119
                    line = line.strip()
120
120
                    if len(line) > 0 and line[0:1] != "#": # ignore commented lines or empty ones
121
 
    
 
121
 
122
122
                        name = line.split("=")[0].strip().upper() # config setting name on the left of =
123
123
                        value = line.split("=")[1].split("#")[0].strip() # config value on the right of = (minus any trailing comments)
124
 
    
 
124
 
125
125
                        if len(value) > 0:
126
126
                            if name == "HEADERTEMPLATE":
127
 
                                self.config.HEADERTEMPLATE = self.getTypedValue(value, "string")
 
127
                                self.config.HEADERTEMPLATE = getTypedValue(value, "string")
128
128
                            elif name == "TEMPLATE":
129
 
                                self.config.TEMPLATE = self.getTypedValue(value, "string")
 
129
                                self.config.TEMPLATE = getTypedValue(value, "string")
130
130
                            elif name == "ONLINEONLY":
131
 
                                self.config.ONLINEONLY = self.getTypedValue(value, "boolean")
 
131
                                self.config.ONLINEONLY = getTypedValue(value, "boolean")
132
132
                            elif name == "OFFLINEONLY":
133
 
                                self.config.OFFLINEONLY = self.getTypedValue(value, "boolean")
 
133
                                self.config.OFFLINEONLY = getTypedValue(value, "boolean")
134
134
                            elif name == "AVAILABLEONLY":
135
 
                                self.config.AVAILABLEONLY = self.getTypedValue(value, "boolean")                                  
 
135
                                self.config.AVAILABLEONLY = getTypedValue(value, "boolean")
136
136
                            elif name == "INCLUDELIST":
137
 
                                self.config.INCLUDELIST = self.getTypedValue(value, "string")
 
137
                                self.config.INCLUDELIST = getTypedValue(value, "string")
138
138
                            elif name == "IGNORELIST":
139
 
                                self.config.IGNORELIST = self.getTypedValue(value, "string")
 
139
                                self.config.IGNORELIST = getTypedValue(value, "string")
140
140
                            elif name == "LIMIT":
141
 
                                self.config.LIMIT = self.getTypedValue(value, "integer")
 
141
                                self.config.LIMIT = getTypedValue(value, "integer")
142
142
                            elif name == "SORTBYLOGACTIVITY":
143
 
                                self.config.SORTBYLOGACTIVITY = self.getTypedValue(value, "boolean")
 
143
                                self.config.SORTBYLOGACTIVITY = getTypedValue(value, "boolean")
144
144
                            elif name == "DEFAULTBUDDYICON":
145
 
                                self.config.DEFAULTBUDDYICON = self.getTypedValue(value, "string")                                             
 
145
                                self.config.DEFAULTBUDDYICON = getTypedValue(value, "string")
146
146
                            else:
147
147
                                self.logger.error("Unknown option in config file: " + name)
148
148
            else:
149
149
                self.logger.info("Config data file %s not found, using defaults and setting up config file for next time" % configfilepath)
150
 
                
 
150
 
151
151
                userconfigpath = os.path.join(os.path.expanduser('~'), ".config/"+app_name+"/")
152
152
                configsource = os.path.join(app_path, "config/"+module_name+".config")
153
 
                
 
153
 
154
154
                if os.path.exists(userconfigpath) == False:
155
155
                    os.makedirs(userconfigpath)
156
156
 
157
157
                shutil.copy(configsource, configfilepath)
158
 
                
 
158
 
159
159
        except Exception, e:
160
160
            self.logger.error(e.__str__()+"\n"+traceback.format_exc())
161
161
 
162
 
    def getTypedValue(self, value, expectedtype):
163
 
        
164
 
        try:
165
 
            if len(value.strip(" ")) == 0:
166
 
                return None
167
 
            
168
 
            elif value.lower() == "true":
169
 
                if expectedtype == "boolean":
170
 
                    return True
171
 
                else:
172
 
                    self.logger.error("Expected type was '%s', but the value '%s' was given"%(expectedtype, value))
173
 
                    
174
 
            elif value.lower() == "false":
175
 
                if expectedtype == "boolean":
176
 
                    return False
177
 
                else:
178
 
                    self.logger.error("Expected type was '%s', but the value '%s' was given"%(expectedtype, value))
179
 
                    
180
 
            elif self.isNumeric(value) == True:
181
 
                if expectedtype == "integer":
182
 
                    return int(value)
183
 
                else:
184
 
                    self.logger.error("Expected type was '%s', but the value '%s' was given"%(expectedtype, value))
185
 
                    
186
 
            else:
187
 
                return value
188
 
 
189
 
        except (TypeError, ValueError):
190
 
            self.logger.error("Cannot convert '%s' to expected type of '%s'"%(value,expectedtype))
191
 
            return value
192
 
        
193
162
    def testDBus(self, bus, interface):
194
163
        obj = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
195
164
        dbus_iface = dbus.Interface(obj, 'org.freedesktop.DBus')
197
166
        return interface in avail
198
167
 
199
168
    def getOutputFromTemplate(self, template, name, alias, group, status, status_message, icon):
200
 
        
 
169
 
201
170
        try:
202
 
            
 
171
 
203
172
            output = template
204
 
    
 
173
 
205
174
            output = output.replace("[name]",name)
206
175
            output = output.replace("[alias]",alias)
207
176
            output = output.replace("[group]",group)
211
180
 
212
181
            # get rid of any excess crlf's
213
182
            output = output.rstrip(" \n")
214
 
            
 
183
 
215
184
            return output
216
 
        
 
185
 
217
186
        except Exception,e:
218
187
            self.logger.error(e.__str__()+"\n"+traceback.format_exc())
219
188
            return ""
220
 
    
 
189
 
221
190
    def getPidginData(self):
222
 
        
 
191
 
223
192
        pidginDataList = []
224
 
        
 
193
 
225
194
        if DBUS_AVAIL == True:
226
 
            
 
195
 
227
196
            try:
228
 
                    
 
197
 
229
198
                bus = dbus.SessionBus()
230
 
    
 
199
 
231
200
                if self.testDBus(bus, 'im.pidgin.purple.PurpleService'):
232
 
                    
 
201
 
233
202
                        self.logger.info("Setting up dbus interface")
234
 
                        
 
203
 
235
204
                        remote_object = bus.get_object("im.pidgin.purple.PurpleService","/im/pidgin/purple/PurpleObject")
236
205
                        iface = dbus.Interface(remote_object, "im.pidgin.purple.PurpleService")
237
 
                        
 
206
 
238
207
                        self.logger.info("Setting up defaults for all buddies...")
239
208
 
240
209
                        # default icon path for all buddies
242
211
                            defaultbuddyicon = "file://%s"%os.path.expanduser(self.config.DEFAULTBUDDYICON)
243
212
                        else:
244
213
                            defaultbuddyicon = ""
245
 
                                                                        
 
214
 
246
215
                        self.logger.info("Calling dbus interface for IM data")
247
 
                            
 
216
 
248
217
                        # Iterate through every active account
249
218
                        for acctID in iface.PurpleAccountsGetAllActive():
250
 
                            
 
219
 
251
220
                            # get all the buddies associated with that account
252
221
                            buddies = iface.PurpleFindBuddies(acctID,"")
253
 
    
 
222
 
254
223
                            for buddyid in buddies:
255
 
                                
 
224
 
256
225
                                groupid = iface.PurpleBuddyGetGroup(buddyid)
257
 
                                
 
226
 
258
227
                                # get initial data
259
228
                                alias = iface.PurpleBuddyGetAlias(buddyid)
260
229
                                name = iface.PurpleBuddyGetName(buddyid)
261
230
                                online = iface.PurpleBuddyIsOnline(buddyid)
262
231
                                group = iface.PurpleGroupGetName(groupid)
263
 
    
 
232
 
264
233
                                if self.ignoreGroup(group) == False:
265
 
    
 
234
 
266
235
                                    if self.includeGroup(group) == True:
267
236
 
268
237
                                        addBuddy = False
269
 
                                                   
 
238
 
270
239
                                        if self.config.ONLINEONLY == True:
271
240
                                            if online == 1:
272
241
                                                addBuddy = True
275
244
                                                addBuddy = True
276
245
                                        else:
277
246
                                            addBuddy = True
278
 
                                        
 
247
 
279
248
                                        if addBuddy == True:
280
249
 
281
250
                                        # determine whether to show this buddies details based on onlineonly option
282
251
                                        #if online == 1 or self.config.ONLINEONLY == False:
283
 
    
 
252
 
284
253
                                            available = 0
285
 
                                            
 
254
 
286
255
                                            # retrieve buddy status
287
256
                                            presenceid = iface.PurpleBuddyGetPresence(buddyid)
288
257
                                            status = iface.PurplePresenceGetActiveStatus(presenceid)
289
 
                                            
 
258
 
290
259
                                            # get extended message if set
291
 
                                            status_message = self.getCleanText(iface.PurpleStatusGetAttrString(status, "message")) # getCleanText needed for google encoded text
292
 
                                            
 
260
                                            status_message = getCleanText(iface.PurpleStatusGetAttrString(status, "message")) # getCleanText needed for google encoded text
 
261
 
293
262
                                            # get the status type, id and text
294
263
                                            statustype = iface.PurpleStatusGetType(status)
295
264
                                            statusid = iface.PurpleStatusTypeGetPrimitive(statustype)
296
 
                                            statustypetext = iface.PurpleStatusTypeGetId(statustype)                                      
297
 
                                            
 
265
                                            statustypetext = iface.PurpleStatusTypeGetId(statustype)
 
266
 
298
267
                                            if online == 1:
299
268
                                                if self.isBuddyChatting(name,iface):
300
269
                                                    statusicon = self.ICON_CHATTING
301
270
                                                    available = 1
302
 
                                                else:                                         
 
271
                                                else:
303
272
                                                    if statusid == self.STATUS_AVAILABLE:
304
273
                                                        statusicon = self.ICON_AVAILABLE
305
274
                                                        available = 1
306
 
                                                        
 
275
 
307
276
                                                    elif statusid == self.STATUS_UNAVAILABLE:
308
277
                                                        statusicon = self.ICON_UNAVAILABLE
309
 
                                                        
 
278
 
310
279
                                                    elif statusid == self.STATUS_INVISIBLE:
311
280
                                                        statusicon = self.ICON_INVISIBLE
312
 
                                                        
 
281
 
313
282
                                                    elif statusid == self.STATUS_AWAY or statusid == self.STATUS_EXTENDED_AWAY:
314
283
                                                        statusicon = self.ICON_AWAY
315
 
                                                        
 
284
 
316
285
                                                    elif statusid == self.STATUS_MOBILE:
317
286
                                                        statusicon = self.ICON_MOBILE
318
 
                                                        
 
287
 
319
288
                                                    elif statusid == self.STATUS_TUNE:
320
289
                                                        #TODO: need icon for STATUS_TUNE whatever that is...
321
290
                                                        statusicon = self.ICON_AVAILABLE
322
 
                                                        
 
291
 
323
292
                                                    else: # catch all in case no match on statustype, guess available
324
293
                                                        statusicon = self.ICON_AVAILABLE
325
294
                                            else:
326
 
                                                statusicon = self.ICON_OFFLINE    
 
295
                                                statusicon = self.ICON_OFFLINE
327
296
 
328
297
                                            status = "file://%s/images/pidginicons/%s.png"%(app_path, statusicon)
329
 
                                            
 
298
 
330
299
                                            # determine whether to show this buddies details based on availableonly option
331
300
                                            if available == 1 or self.config.AVAILABLEONLY == False:
332
 
                                                                                               
 
301
 
333
302
                                                # get buddies icon, if not there then default icon used if setup
334
303
                                                icon = defaultbuddyicon
335
304
                                                iconid = iface.PurpleBuddyGetIcon(buddyid)
344
313
                                                    if purplestoredimageid <> 0:
345
314
                                                        pass
346
315
                                                        #iconpath = iface.PurpleImgstoreGetFilename(purplestoredimageid)
347
 
                                                        #icon = "file://"+urllib.quote(iconpath)   
348
 
                                                                                             
 
316
                                                        #icon = "file://"+urllib.quote(iconpath)
 
317
 
349
318
                                                # get latest activity datetime
350
319
                                                activitydatetime = self.getBuddyActivityDatetime(self.PIDGIN_LOGS_PATH, name)
351
 
                                                                                                
 
320
 
352
321
                                                self.logger.info("Adding IM data for buddy: '%s', group: '%s', status: '%s'"%(alias, group, statustypetext))
353
 
                                                
 
322
 
354
323
                                                # ready text for html output
355
 
                                                name = self.getHTMLText(name)
356
 
                                                alias = self.getHTMLText(alias)
357
 
                                                group = self.getHTMLText(group)
358
 
                                                status_message = self.getHTMLText(status_message)
359
 
                                                
 
324
                                                name = getHTMLText(name)
 
325
                                                alias = getHTMLText(alias)
 
326
                                                group = getHTMLText(group)
 
327
                                                status_message = getHTMLText(status_message)
 
328
 
360
329
                                                pidginData = PidginData(name, alias, group, status, status_message, icon, activitydatetime)
361
330
                                                pidginDataList.append(pidginData)
362
 
    
 
331
 
363
332
                        # tidy up
364
333
                        del iface
365
334
                        del remote_object
370
339
                            pidginDataList.sort(key=lambda obj: obj.activitydatetime,reverse=True)
371
340
                        else:
372
341
                            pidginDataList.sort()
373
 
                    
 
342
 
374
343
            except Exception, e:
375
344
                self.logger.error(e.__str__()+"\n"+traceback.format_exc())
376
 
        
 
345
 
377
346
        return pidginDataList
378
 
                
 
347
 
379
348
    def getOutput(self):
380
 
        
 
349
 
381
350
        if self.options.noheader == True:
382
351
            headertemplatefilepath = app_path+"/templates/nullheader.template"
383
352
            self.logger.info("Using custom header template file '%s'"%headertemplatefilepath)
390
359
        else:
391
360
            headertemplatefilepath = app_path+"/templates/pidginheader.template"
392
361
            self.logger.info("Using default header template")
393
 
            
 
362
 
394
363
        # load the file
395
364
        try:
396
365
            inputfile = codecs.open(os.path.expanduser(headertemplatefilepath), encoding='utf-8')
400
369
            headertemplate = inputfile.read()
401
370
        finally:
402
371
            inputfile.close()
403
 
            
 
372
 
404
373
        if self.options.template != None:
405
374
            templatefilepath = self.options.template
406
375
            self.logger.info("Using custom template file '%s'"%templatefilepath)
410
379
        else:
411
380
            templatefilepath = app_path+"/templates/pidgin.template"
412
381
            self.logger.info("Using default summary template")
413
 
             
 
382
 
414
383
        # load the file
415
384
        try:
416
385
            inputfile = codecs.open(os.path.expanduser(templatefilepath), encoding='utf-8')
420
389
            template = inputfile.read()
421
390
        finally:
422
391
            inputfile.close()
423
 
                   
 
392
 
424
393
        try:
425
 
             
 
394
 
426
395
            pidginDataList = self.getPidginData()
427
 
            
 
396
 
428
397
            self.logger.info("Outputting buddy information...")
429
 
            
 
398
 
430
399
            output = headertemplate
431
 
            
 
400
 
432
401
            buddyCount = 0
433
 
            
 
402
 
434
403
            for pidginData in pidginDataList:
435
404
 
436
405
                # keep a tally of buddies output, if past the limit then exit
452
421
 
453
422
        basefolder = os.path.expanduser(basefolder)
454
423
        latestmodifieddatetime = datetime(2000, 1, 1, 0, 0)
455
 
        
 
424
 
456
425
        # if the folder passed in is non existent return an empty list
457
426
        if os.path.exists(basefolder):
458
 
        
 
427
 
459
428
            # for each file or folder
460
429
            for root, dirs, files in os.walk(basefolder):
461
 
                
 
430
 
462
431
                for dir in dirs:
463
432
                    if dir == buddyname:
464
 
                        
 
433
 
465
434
                        buddypath = os.path.join(root,dir)
466
435
                        moddatetime = self.getLatestLogFileModificationDatetime(buddypath, latestmodifieddatetime)
467
436
                        if moddatetime > latestmodifieddatetime:
468
437
                            latestmodifieddatetime = moddatetime
469
438
                        return latestmodifieddatetime
470
 
    
 
439
 
471
440
        return latestmodifieddatetime
472
 
            
 
441
 
473
442
    def getLatestLogFileModificationDatetime(self, folderpath, latestmodifieddatetime):
474
 
        
 
443
 
475
444
        for file in os.listdir(folderpath):
476
445
            filepath = os.path.join(folderpath,file)
477
446
            if os.path.isfile(filepath):
478
447
                modifieddate = datetime.fromtimestamp(os.stat(filepath)[stat.ST_MTIME])
479
448
                if modifieddate > latestmodifieddatetime:
480
449
                    latestmodifieddatetime = modifieddate
481
 
                
 
450
 
482
451
        return latestmodifieddatetime
483
452
 
484
453
    def isBuddyChatting(self,name,iface):
487
456
            convname = iface.PurpleConversationGetName(imid)
488
457
            if convname == name:
489
458
                return True
490
 
            
 
459
 
491
460
        return False
492
 
    
 
461
 
493
462
    def ignoreBuddy(self, name, alias):
494
 
        
 
463
 
495
464
        if self.config.IGNORELIST != None:
496
 
                    
 
465
 
497
466
            # for each text in the ignore list, should we be ignoring the buddy
498
467
            for ignore in self.config.IGNORELIST.split(","):
499
468
                # has the buddy been found in the list item
500
469
                if name.lower().find(ignore.lower()) != -1 or alias.lower().find(ignore.lower()) != -1:
501
470
                    return True
502
 
        
 
471
 
503
472
            return False
504
 
        
 
473
 
505
474
        else:
506
475
            return False
507
476
 
508
477
    def includeBuddy(self, name, alias):
509
 
        
 
478
 
510
479
        if self.config.INCLUDELIST != None:
511
 
            
 
480
 
512
481
            # for each text in the ignore list, should we be ignoring the buddy
513
482
            for include in self.config.INCLUDELIST.split(","):
514
483
                # has the buddy been found in the list item
515
484
                if name.lower().find(include.lower()) != -1 or alias.lower().find(include.lower()) != -1:
516
485
                    return True
517
 
        
 
486
 
518
487
            return False
519
 
        
 
488
 
520
489
        else:
521
490
            return True
522
491
 
523
492
    def ignoreGroup(self, group):
524
 
        
 
493
 
525
494
        if self.config.IGNORELIST != None:
526
 
                    
 
495
 
527
496
            # for each text in the ignore list, should we be ignoring the buddy in the group
528
497
            for ignore in self.config.IGNORELIST.split(","):
529
498
                # has the group been found in the list item
530
499
                if group.lower().find(ignore.lower()) != -1:
531
500
                    return True
532
 
        
 
501
 
533
502
            return False
534
 
        
 
503
 
535
504
        else:
536
505
            return False
537
506
 
538
507
    def includeGroup(self, group):
539
 
        
 
508
 
540
509
        if self.config.INCLUDELIST != None:
541
 
            
 
510
 
542
511
            # for each text in the ignore list, should we be ignoring the buddy in the group
543
512
            for include in self.config.INCLUDELIST.split(","):
544
513
                # has the group been found in the list item
545
514
                if group.lower().find(include.lower()) != -1:
546
515
                    return True
547
 
        
 
516
 
548
517
            return False
549
 
        
 
518
 
550
519
        else:
551
520
            return True
552
 
        
553
 
    def getHTMLText(self,text):
554
 
        try:
555
 
            htmlentities = []               
556
 
            for char in text: #html:
557
 
                if ord(char) < 128:
558
 
                    htmlentities.append(char)
559
 
                else:
560
 
                    htmlentities.append('&%s;' % codepoint2name[ord(char)])
561
 
            html = "".join(htmlentities)
562
 
            
563
 
            html = html.replace("\n","<br>\n") # switch out new line for html breaks
564
 
            return html            
565
 
        except:
566
 
            return text
567
521
 
568
 
    def getCleanText(self,html):
569
 
        try:
570
 
            text = str(html)
571
 
            text = text.replace("\n","") # remove new lines from html
572
 
            text = text.replace("&apos;","'") # workaround for shitty xml codes not compliant with html
573
 
            text = text.replace("<br>","\n") # switch out html breaks for new line
574
 
            text = re.sub('<(.|\n)+?>','',text) # remove any html tags
575
 
            text =  re.sub('&(%s);' % '|'.join(name2codepoint), lambda m: chr(name2codepoint[m.group(1)]), text)
576
 
            return text            
577
 
        except:
578
 
            return html
579
 
                   
580
 
    def isNumeric(self, string):
581
 
        try:
582
 
            dummy = float(string)
583
 
            return True
584
 
        except:
585
 
            return False
586
 
        
587
522
def getHTML(options):
588
523
    output = Output(options)
589
524
    html = output.getOutput()
592
527
 
593
528
# to enable testing in isolation
594
529
if __name__ == "__main__":
595
 
    
 
530
 
596
531
    parser = OptionParser()
597
 
    parser.add_option("--noheader", dest="noheader", default=False, action="store_true", help=u"Turn off header output. This will override any header template setting to be nothing")        
 
532
    parser.add_option("--noheader", dest="noheader", default=False, action="store_true", help=u"Turn off header output. This will override any header template setting to be nothing")
598
533
    parser.add_option("--headertemplate", dest="headertemplate", type="string", metavar="FILE", help=u"Override the header template for the plugin, default or config based template ignored.")
599
534
    parser.add_option("--template", dest="template", type="string", metavar="FILE", help=u"Override the template for the plugin, default or config based template ignored.")
600
535
    parser.add_option("--verbose", dest="verbose", default=False, action="store_true", help=u"Outputs verbose info to the terminal")
601
536
    parser.add_option("--version", dest="version", default=False, action="store_true", help=u"Displays the version of the script.")
602
 
    parser.add_option("--logfile", dest="logfile", type="string", metavar="FILE", help=u"If a filepath is set, the script logs to the filepath.")                
603
 
    
 
537
    parser.add_option("--logfile", dest="logfile", type="string", metavar="FILE", help=u"If a filepath is set, the script logs to the filepath.")
 
538
 
604
539
    (options, args) = parser.parse_args()
605
 
        
 
540
 
606
541
    output = Output(options)
607
542
    html = output.getOutput()
608
543
    del output