[SOLVED] tv_grab_nl_py works with python 2.6.5, fails on 3.1.2

Hi All,
I have updated my mediacenter. Now tv_grab_nl_py does not work anymore:
[cedric@tv ~]$ tv_grab_nl_py --output ~/listings.xml --fast
File "/usr/bin/tv_grab_nl_py", line 341
print 'tv_grab_nl_py: A grabber that grabs tvguide data from tvgids.nl\n'
^
SyntaxError: invalid syntax
[cedric@tv ~]$
the version of python on the mediacenter (running arch linux):
[cedric@tv ~]$ python
Python 3.1.2 (r312:79147, Oct 4 2010, 12:35:40)
[GCC 4.5.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
I have copied the file to my laptop, there it looks like it's working:
./tv_grab_nl_py --output ~/listings.xml --fast
Config file /home/cedric/.xmltv/tv_grab_nl_py.conf not found.
Re-run me with the --configure flag.
cedric@laptop:~$
the version of python on my laptop (running arch linux):
cedric@laptop:~$ python
Python 2.6.5 (r265:79063, Apr 1 2010, 05:22:20)
[GCC 4.4.3 20100316 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
the script I'm trying to run:
[cedric@tv ~]$ cat tv_grab_nl_py
#!/usr/bin/env python
# $LastChangedDate: 2009-11-14 10:06:41 +0100 (Sat, 14 Nov 2009) $
# $Rev: 104 $
# $Author: pauldebruin $
SYNOPSIS
tv_grab_nl_py is a python script that trawls tvgids.nl for TV
programming information and outputs it in XMLTV-formatted output (see
http://membled.com/work/apps/xmltv). Users of MythTV
(http://www.mythtv.org) will appreciate the output generated by this
grabber, because it fills the category fields, i.e. colors in the EPG,
and has logos for most channels automagically available. Check the
website below for screenshots. The newest version of this script can be
found here:
http://code.google.com/p/tvgrabnlpy/
USAGE
Check the web site above and/or run script with --help and start from there
HISTORY
tv_grab_nl_py used to be called tv_grab_nl_pdb, first released on
2003/07/09. The name change was necessary because more and more people
are actively contributing to this script and I always disliked using my
initials (I was just too lazy to change it). At the same time I switched
from using CVS to SVN and as a result the version numbering scheme has
changed. The lastest official release of tv_grab_nl_pdb is 0.48. The
first official release of tv_grab_nl_py is 6.
QUESTIONS
Questions (and patches) are welcome at: paul at pwdebruin dot net.
IMPORTANT NOTES
If you were using tv_grab_nl from the XMLTV bundle then enable the
compat flag or use the --compat command-line option. Otherwise, the
xmltvid's are wrong and you will not see any new data in MythTV.
CONTRIBUTORS
Main author: Paul de Bruin (paul at pwdebruin dot net)
Michel van der Laan made available his extensive collection of
high-quality logos that is used by this script.
Michael Heus has taken the effort to further enhance this script so that
it now also includes:
- Credit info: directors, actors, presenters and writers
- removal of programs that are actually just groupings/broadcasters
(e.g. "KETNET", "Wild Friday", "Z@pp")
- Star-rating for programs tipped by tvgids.nl
- Black&White, Stereo and URL info
- Better detection of Movies
- and much, much more...
Several other people have provided feedback and patches (these are the
people I could find in my email archive, if you are missing from this
list let me know):
Huub Bouma, Roy van der Kuil, Remco Rotteveel, Mark Wormgoor, Dennis van
Onselen, Hugo van der Kooij, Han Holl, Ian Mcdonald, Udo van den Heuvel.
# Modules we need
import re, urllib2, getopt, sys
import time, random
import htmlentitydefs, os, os.path, pickle
from string import replace, split, strip
from threading import Thread
from xml.sax import saxutils
# Extra check for the datetime module
try:
import datetime
except:
sys.stderr.write('This script needs the datetime module that was introduced in Python version 2.3.\n')
sys.stderr.write('You are running:\n')
sys.stderr.write('%s\n' % sys.version)
sys.exit(1)
# XXX: fix to prevent crashes in Snow Leopard [Robert Klep]
if sys.platform == 'darwin' and sys.version_info[:3] == (2, 6, 1):
try:
urllib2.urlopen('http://localhost.localdomain')
except:
pass
# do extra debug stuff
debug = 1
try:
import redirect
except:
debug = 0
pass
# globals
# compile only one time
r_entity = re.compile(r'&(#x[0-9A-Fa-f]+|#[0-9]+|[A-Za-z]+);')
tvgids = 'http://www.tvgids.nl/'
uitgebreid_zoeken = tvgids + 'zoeken/'
# how many seconds to wait before we timeout on a
# url fetch, 10 seconds seems reasonable
global_timeout = 10
# Wait a random number of seconds between each page fetch.
# We want to be nice and not hammer tvgids.nl (these are the
# friendly people that provide our data...).
# Also, it appears tvgids.nl throttles its output.
# So there, there is not point in lowering these numbers, if you
# are in a hurry, use the (default) fast mode.
nice_time = [1, 2]
# Maximum length in minutes of gaps/overlaps between programs to correct
max_overlap = 10
# Strategy to use for correcting overlapping prgramming:
# 'average' = use average of stop and start of next program
# 'stop' = keep stop time of current program and adjust start time of next program accordingly
# 'start' = keep start time of next program and adjust stop of current program accordingly
# 'none' = do not use any strategy and see what happens
overlap_strategy = 'average'
# Experimental strategy for clumping overlapping programming, all programs that overlap more
# than max_overlap minutes, but less than the length of the shortest program are clumped
# together. Highly experimental and disabled for now.
do_clump = False
# Create a category translation dictionary
# Look in mythtv/themes/blue/ui.xml for all category names
# The keys are the categories used by tvgids.nl (lowercase please)
cattrans = { 'amusement' : 'Talk',
'animatie' : 'Animated',
'comedy' : 'Comedy',
'documentaire' : 'Documentary',
'educatief' : 'Educational',
'erotiek' : 'Adult',
'film' : 'Film',
'muziek' : 'Art/Music',
'informatief' : 'Educational',
'jeugd' : 'Children',
'kunst/cultuur' : 'Arts/Culture',
'misdaad' : 'Crime/Mystery',
'muziek' : 'Music',
'natuur' : 'Science/Nature',
'nieuws/actualiteiten' : 'News',
'overige' : 'Unknown',
'religieus' : 'Religion',
'serie/soap' : 'Drama',
'sport' : 'Sports',
'theater' : 'Arts/Culture',
'wetenschap' : 'Science/Nature'}
# Create a role translation dictionary for the xmltv credits part
# The keys are the roles used by tvgids.nl (lowercase please)
roletrans = {'regie' : 'director',
'acteurs' : 'actor',
'presentatie' : 'presenter',
'scenario' : 'writer'}
# We have two sources of logos, the first provides the nice ones, but is not
# complete. We use the tvgids logos to fill the missing bits.
logo_provider = [ 'http://visualisation.tudelft.nl/~paul/logos/gif/64x64/',
'http://static.tvgids.nl/gfx/zenders/' ]
logo_names = {
1 : [0, 'ned1'],
2 : [0, 'ned2'],
3 : [0, 'ned3'],
4 : [0, 'rtl4'],
5 : [0, 'een'],
6 : [0, 'canvas_color'],
7 : [0, 'bbc1'],
8 : [0, 'bbc2'],
9 : [0,'ard'],
10 : [0,'zdf'],
11 : [1, 'rtl'],
12 : [0, 'wdr'],
13 : [1, 'ndr'],
14 : [1, 'srsudwest'],
15 : [1, 'rtbf1'],
16 : [1, 'rtbf2'],
17 : [0, 'tv5'],
18 : [0, 'ngc'],
19 : [1, 'eurosport'],
20 : [1, 'tcm'],
21 : [1, 'cartoonnetwork'],
24 : [0, 'canal+red'],
25 : [0, 'mtv-color'],
26 : [0, 'cnn'],
27 : [0, 'rai'],
28 : [1, 'sat1'],
29 : [0, 'discover-spacey'],
31 : [0, 'rtl5'],
32 : [1, 'trt'],
34 : [0, 'veronica'],
35 : [0, 'tmf'],
36 : [0, 'sbs6'],
37 : [0, 'net5'],
38 : [1, 'arte'],
39 : [0, 'canal+blue'],
40 : [0, 'at5'],
46 : [0, 'rtl7'],
49 : [1, 'vtm'],
50 : [1, '3sat'],
58 : [1, 'pro7'],
59 : [1, 'kanaal2'],
60 : [1, 'vt4'],
65 : [0, 'animal-planet'],
73 : [1, 'mezzo'],
86 : [0, 'bbc-world'],
87 : [1, 'tve'],
89 : [1, 'nick'],
90 : [1, 'bvn'],
91 : [0, 'comedy_central'],
92 : [0, 'rtl8'],
99 : [1, 'sport1_1'],
100 : [0, 'rtvu'],
101 : [0, 'tvwest'],
102 : [0, 'tvrijnmond'],
103 : [1, 'tvnoordholland'],
104 : [1, 'bbcprime'],
105 : [1, 'spiceplatinum'],
107 : [0, 'canal+yellow'],
108 : [0, 'tvnoord'],
109 : [0, 'omropfryslan'],
114 : [0, 'omroepbrabant']}
# A selection of user agents we will impersonate, in an attempt to be less
# conspicuous to the tvgids.nl police.
user_agents = [ 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)',
'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.9) Gecko/20071025 Firefox/2.0.0.9',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)',
'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)',
'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.9) Gecko/20071105 Firefox/2.0.0.9',
'Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.9) Gecko/20071025 Firefox/2.0.0.9',
'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.8) Gecko/20071022 Ubuntu/7.10 (gutsy) Firefox/2.0.0.8'
# Work in progress, the idea is to cache program categories and
# descriptions to eliminate a lot of page fetches from tvgids.nl
# for programs that do not have interesting/changing descriptions
class ProgramCache:
A cache to hold program name and category info.
TVgids stores the detail for each program on a separate URL with an
(apparently unique) ID. This cache stores the fetched info with the ID.
New fetches will use the cached info instead of doing an (expensive)
page fetch.
def __init__(self, filename=None):
Create a new ProgramCache object, optionally from file
# where we store our info
self.filename = filename
if filename == None:
self.pdict = {}
else:
if os.path.isfile(filename):
self.load(filename)
else:
self.pdict = {}
def load(self, filename):
Loads a pickled cache dict from file
try:
self.pdict = pickle.load(open(filename,'r'))
except:
sys.stderr.write('Error loading cache file: %s (possibly corrupt)' % filename)
sys.exit(2)
def dump(self, filename):
Dumps a pickled cache, and makes sure it is valid
if os.access(filename, os.F_OK):
try:
os.remove(filename)
except:
sys.stderr.write('Cannot remove %s, check permissions' % filename)
pickle.dump(self.pdict, open(filename+'.tmp', 'w'))
os.rename(filename+'.tmp', filename)
def query(self, program_id):
Updates/gets/whatever.
try:
return self.pdict[program_id]
except:
return None
def add(self, program):
Adds a program
self.pdict[program['ID']] = program
def clear(self):
Clears the cache (i.e. empties it)
self.pdict = {}
def clean(self):
Removes all cached programming before today.
Also removes erroneously cached programming.
now = time.localtime()
dnow = datetime.datetime(now[0],now[1],now[2])
for key in self.pdict.keys():
try:
if self.pdict[key]['stop-time'] < dnow or self.pdict[key]['name'].lower() == 'onbekend':
del self.pdict[key]
except:
pass
def usage():
print 'tv_grab_nl_py: A grabber that grabs tvguide data from tvgids.nl\n'
print 'and stores it in XMLTV-combatible format.\n'
print 'Usage:'
print '--help, -h = print this info'
print '--configure = create configfile (overwrites existing file)'
print '--config-file = name of the configuration file (default = ~/.xmltv/tv_grab_py.conf'
print '--capabilities = xmltv required option'
print '--desc-length = maximum allowed length of programme descriptions in bytes.'
print '--description = prints a short description of the grabber'
print '--output = file where to put the output'
print '--days = # number of days to grab'
print '--preferredmethod = returns the preferred method to be called'
print '--fast = do not grab descriptions of programming'
print '--slow = grab descriptions of programming'
print '--quiet = suppress all output'
print '--compat = append tvgids.nl to the xmltv id (use this if you were using tv_grab_nl)'
print '--logos 0/1 = insert urls to channel icons (mythfilldatabase will then use these)'
print '--nocattrans = do not translate the grabbed genres into MythTV-genres'
print '--cache = cache descriptions and use the file to store'
print '--clean_cache = clean the cache file before fetching'
print '--clear_cache = empties the cache file before fetching data'
print '--slowdays = grab slowdays initial days and the rest in fast mode'
print '--max_overlap = maximum length of overlap between programming to correct [minutes]'
print '--overlap_strategy = what strategy to use to correct overlaps (check top of source code)'
def filter_line_identity(m, defs=htmlentitydefs.entitydefs):
# callback: translate one entity to its ISO Latin value
k = m.group(1)
if k.startswith("#") and k[1:] in xrange(256):
return chr(int(k[1:]))
try:
return defs[k]
except KeyError:
return m.group(0) # use as is
def filter_line(s):
Removes unwanted stuff in strings (adapted from tv_grab_be)
# do the latin1 stuff
s = r_entity.sub(filter_line_identity, s)
s = replace(s,'&nbsp;',' ')
# Ik vermoed dat de volgende drie regels overbodig zijn, maar ze doen
# niet veel kwaad -- Han Holl
s = replace(s,'\r',' ')
x = re.compile('(<.*?>)') # Udo
s = x.sub('', s) #Udo
s = replace(s, '~Q', "'")
s = replace(s, '~R', "'")
# Hmm, not sure if I understand this. Without it, mythfilldatabase barfs
# on program names like "Steinbrecher &..."
# We most create valid XML -- Han Holl
s = saxutils.escape(s)
return s
def calc_timezone(t):
Takes a time from tvgids.nl and formats it with all the required
timezone conversions.
in: '20050429075000'
out:'20050429075000 (CET|CEST)'
Until I have figured out how to correctly do timezoning in python this method
will bork if you are not in a zone that has the same DST rules as 'Europe/Amsterdam'.
year = int(t[0:4])
month = int(t[4:6])
day = int(t[6:8])
hour = int(t[8:10])
minute = int(t[10:12])
#td = {'CET': '+0100', 'CEST': '+0200'}
#td = {'CET': '+0100', 'CEST': '+0200', 'W. Europe Standard Time' : '+0100', 'West-Europa (standaardtijd)' : '+0100'}
td = {0 : '+0100', 1 : '+0200'}
pt = time.mktime((year,month,day,hour,minute,0,0,0,-1))
timezone=''
try:
#timezone = time.tzname[(time.localtime(pt))[-1]]
timezone = (time.localtime(pt))[-1]
except:
sys.stderr.write('Cannot convert time to timezone')
return t+' %s' % td[timezone]
def format_timezone(td):
Given a datetime object, returns a string in XMLTV format
tstr = td.strftime('%Y%m%d%H%M00')
return calc_timezone(tstr)
def get_page_internal(url, quiet=0):
Retrieves the url and returns a string with the contents.
Optionally, returns None if processing takes longer than
the specified number of timeout seconds.
txtdata = None
txtheaders = {'Keep-Alive' : '300',
'User-Agent' : user_agents[random.randint(0, len(user_agents)-1)] }
try:
#fp = urllib2.urlopen(url)
rurl = urllib2.Request(url, txtdata, txtheaders)
fp = urllib2.urlopen(rurl)
lines = fp.readlines()
page = "".join(lines)
return page
except:
if not quiet:
sys.stderr.write('Cannot open url: %s\n' % url)
return None
class FetchURL(Thread):
A simple thread to fetch a url with a timeout
def __init__ (self, url, quiet=0):
Thread.__init__(self)
self.quiet = quiet
self.url = url
self.result = None
def run(self):
self.result = get_page_internal(self.url, self.quiet)
def get_page(url, quiet=0):
Wrapper around get_page_internal to catch the
timeout exception
try:
fu = FetchURL(url, quiet)
fu.start()
fu.join(global_timeout)
return fu.result
except:
if not quiet:
sys.stderr.write('get_page timed out on (>%s s): %s\n' % (global_timeout, url))
return None
def get_channels(file, quiet=0):
Get a list of all available channels and store these
in a file.
# store channels in a dict
channels = {}
# tvgids stores several instances of channels, we want to
# find all the possibile channels
channel_get = re.compile('<optgroup label=.*?>(.*?)</optgroup>', re.DOTALL)
# this is how we will find a (number, channel) instance
channel_re = re.compile('<option value="([0-9]+)" >(.*?)</option>', re.DOTALL)
# this is where we will try to find our channel list
total = get_page(uitgebreid_zoeken, quiet)
if total == None:
return
# get a list of match objects of all the <select blah station>
stations = channel_get.finditer(total)
# and create a dict of number, channel_name pairs
# we do this this way because several instances of the
# channel list are stored in the url and not all of the
# instances have all the channels, this way we get them all.
for station in stations:
m = channel_re.finditer(station.group(0))
for p in m:
try:
a = int(p.group(1))
b = filter_line(p.group(2))
channels[a] = b
except:
sys.stderr.write('Oops, [%s,%s] does not look like a valid channel, skipping it...\n' % (p.group(1),p.group(2)))
# sort on channel number (arbitrary but who cares)
keys = channels.keys()
keys.sort()
# and create a file with the channels
f = open(file,'w')
for k in keys:
f.write("%s %s\n" % (k, channels[k]))
f.close()
def get_channel_all_days(channel, days, quiet=0):
Get all available days of programming for channel number
The output is a list of programming in order where each row
contains a dictionary with program information.
now = datetime.datetime.now()
programs = []
# Tvgids shows programs per channel per day, so we loop over the number of days
# we are required to grab
for offset in range(0, days):
channel_url = 'http://www.tvgids.nl/zoeken/?d=%i&z=%s' % (offset, channel)
# For historic purposes, the old style url that gave us a full week in advance:
# channel_url = 'http://www.tvgids.nl/zoeken/?trefwoord=Titel+of+trefwoord&interval=0&timeslot='+\
# '&station=%s&periode=%i&genre=&order=0' % (channel,days-1)
# Sniff, we miss you...
if offset > 0:
time.sleep(random.randint(nice_time[0], nice_time[1]))
# get the raw programming for the day
total = get_page(channel_url, quiet)
if total == None:
return programs
# Setup a number of regexps
# checktitle will match the title row in H2 tags of the daily overview page, e.g.
# <h2>zondag 19 oktober 2008</h2>
checktitle = re.compile('<h2>(.*?)</h2>',re.DOTALL)
# getrow will locate each row with program details
getrow = re.compile('<a href="/programma/(.*?)</a>',re.DOTALL)
# parserow matches the required program info, with groups:
# 1 = program ID
# 2 = broadcast times
# 3 = program name
parserow = re.compile('(.*?)/.*<span class="time">(.*?)</span>.*<span class="title">(.*?)</span>', re.DOTALL)
# normal begin and end times
times = re.compile('([0-9]+:[0-9]+) - ([0-9]+:[0-9]+)?')
# Get the day of month listed on the page as well as the expected date we are grabbing and compare these.
# If these do not match, we skip parsing the programs on the page and issue a warning.
#dayno = int(checkday.search(total).group(1))
title = checktitle.search(total)
if title:
title = title.group(1)
dayno = title.split()[1]
else:
sys.stderr.write('\nOops, there was a problem with page %s. Skipping it...\n' % (channel_url))
continue
expected = now + datetime.timedelta(days=offset)
if (not dayno.isdigit() or int(dayno) != expected.day):
sys.stderr.write('\nOops, did not expect page %s to list programs for "%s", skipping it...\n' % (channel_url,title))
continue
# and find relevant programming info
allrows = getrow.finditer(total)
for r in allrows:
detail = parserow.search(r.group(1))
if detail != None:
# default times
start_time = None
stop_time = None
# parse for begin and end times
t = times.search(detail.group(2))
if t != None:
start_time = t.group(1)
stop_time = t.group(2)
program_url = 'http://www.tvgids.nl/programma/' + detail.group(1) + '/'
program_name = detail.group(3)
# store time, name and detail url in a dictionary
tdict = {}
tdict['start'] = start_time
tdict['stop'] = stop_time
tdict['name'] = program_name
if tdict['name'] == '':
tdict['name'] = 'onbekend'
tdict['url'] = program_url
tdict['ID'] = detail.group(1)
tdict['offset'] = offset
#Add star rating if tipped by tvgids.nl
tdict['star-rating'] = '';
if r.group(1).find('Tip') != -1:
tdict['star-rating'] = '4/5'
# and append the program to the list of programs
programs.append(tdict)
# done
return programs
def make_daytime(time_string, offset=0, cutoff='00:00', stoptime=False):
Given a string '11:35' and an offset from today,
return a datetime object. The cuttoff specifies the point where the
new day starts.
Examples:
In [2]:make_daytime('11:34',0)
Out[2]:datetime.datetime(2006, 8, 3, 11, 34)
In [3]:make_daytime('11:34',1)
Out[3]:datetime.datetime(2006, 8, 4, 11, 34)
In [7]:make_daytime('11:34',0,'12:00')
Out[7]:datetime.datetime(2006, 8, 4, 11, 34)
In [4]:make_daytime('11:34',0,'11:34',False)
Out[4]:datetime.datetime(2006, 8, 3, 11, 34)
In [5]:make_daytime('11:34',0,'11:34',True)
Out[5]:datetime.datetime(2006, 8, 4, 11, 34)
h,m = [int(x) for x in time_string.split(':')];
hm = int(time_string.replace(':',''))
chm = int(cutoff.replace(':',''))
# check for the cutoff, if the time is before the cutoff then
# add a day
extra_day = 0
if (hm < chm) or (stoptime==True and hm == chm):
extra_day = 1
# and create a datetime object, DST is handled at a later point
pt = time.localtime()
dt = datetime.datetime(pt[0],pt[1],pt[2],h,m)
dt = dt + datetime.timedelta(offset+extra_day)
return dt
def correct_times(programs, quiet=0):
Parse a list of programs as generated by get_channel_all_days() and
convert begin and end times to xmltv compatible times in datetime objects.
if programs == []:
return programs
# the start time of programming for this day, times *before* this time are
# assumed to be on the next day
day_start_time = '06:00'
# initialise using the start time of the first program on this day
if programs[0]['start'] != None:
day_start_time = programs[0]['start']
for program in programs:
if program['start'] == program['stop']:
program['stop'] = None
# convert the times
if program['start'] != None:
program['start-time'] = make_daytime(program['start'], program['offset'], day_start_time)
else:
program['start-time'] = None
if program['stop'] != None:
program['stop-time'] = make_daytime(program['stop'], program['offset'], day_start_time, stoptime=True)
# extra correction, needed because the stop time of a program may be on the next day, after the
# day cutoff. For example:
# 06:00 - 23:40 Long Program
# 23:40 - 00:10 Lala
# 00:10 - 08:00 Wawa
# This puts the end date of Wawa on the current, instead of the next day. There is no way to detect
# this with a single cutoff in make_daytime. Therefore, check if there is a day difference between
# start and stop dates and correct if necessary.
if program['start-time'] != None:
# make two dates
start = program['start-time']
stop = program['stop-time']
single_day = datetime.timedelta(1)
startdate = datetime.datetime(start.year,start.month,start.day)
stopdate = datetime.datetime(stop.year,stop.month,stop.day)
if startdate - stopdate == single_day:
program['stop-time'] = program['stop-time'] + single_day
else:
program['stop-time'] = None
def parse_programs(programs, offset=0, quiet=0):
Parse a list of programs as generated by get_channel_all_days() and
convert begin and end times to xmltv compatible times.
# good programs
good_programs = []
# calculate absolute start and stop times
correct_times(programs, quiet)
# next, correct for missing end time and copy over all good programming to the
# good_programs list
for i in range(len(programs)):
# Try to correct missing end time by taking start time from next program on schedule
if (programs[i]['stop-time'] == None and i < len(programs)-1):
if not quiet:
sys.stderr.write('Oops, "%s" has no end time. Trying to fix...\n' % programs[i]['name'])
programs[i]['stop-time'] = programs[i+1]['start-time']
# The common case: start and end times are present and are not
# equal to each other (yes, this can happen)
if programs[i]['start-time'] != None and \
programs[i]['stop-time'] != None and \
programs[i]['start-time'] != programs[i]['stop-time']:
good_programs.append(programs[i])
# Han Holl: try to exclude programs that stop before they begin
for i in range(len(good_programs)-1,-1,-1):
if good_programs[i]['stop-time'] <= good_programs[i]['start-time']:
if not quiet:
sys.stderr.write('Deleting invalid stop/start time: %s\n' % good_programs[i]['name'])
del good_programs[i]
# Try to exclude programs that only identify a group or broadcaster and have overlapping start/end times with
# the actual programs
for i in range(len(good_programs)-2,-1,-1):
if good_programs[i]['start-time'] <= good_programs[i+1]['start-time'] and \
good_programs[i]['stop-time'] >= good_programs[i+1]['stop-time']:
if not quiet:
sys.stderr.write('Deleting grouping/broadcaster: %s\n' % good_programs[i]['name'])
del good_programs[i]
for i in range(len(good_programs)-1):
# PdB: Fix tvgids start-before-end x minute interval overlap. An overlap (positive or
# negative) is halved and each half is assigned to the adjacent programmes. The maximum
# overlap length between programming is set by the global variable 'max_overlap' and is
# default 10 minutes. Examples:
# Positive overlap (= overlap in programming):
# 10:55 - 12:00 Lala
# 11:55 - 12:20 Wawa
# is transformed in:
# 10:55 - 11.57 Lala
# 11:57 - 12:20 Wawa
# Negative overlap (= gap in programming):
# 10:55 - 11:50 Lala
# 12:00 - 12:20 Wawa
# is transformed in:
# 10:55 - 11.55 Lala
# 11:55 - 12:20 Wawa
stop = good_programs[i]['stop-time']
start = good_programs[i+1]['start-time']
dt = stop-start
avg = start + dt / 2
overlap = 24*60*60*dt.days + dt.seconds
# check for the size of the overlap
if 0 < abs(overlap) <= max_overlap*60:
if not quiet:
if overlap > 0:
sys.stderr.write('"%s" and "%s" overlap %s minutes. Adjusting times.\n' % \
(good_programs[i]['name'],good_programs[i+1]['name'],overlap / 60))
else:
sys.stderr.write('"%s" and "%s" have gap of %s minutes. Adjusting times.\n' % \
(good_programs[i]['name'],good_programs[i+1]['name'],abs(overlap) / 60))
# stop-time of previous program wins
if overlap_strategy == 'stop':
good_programs[i+1]['start-time'] = good_programs[i]['stop-time']
# start-time of next program wins
elif overlap_strategy == 'start':
good_programs[i]['stop-time'] = good_programs[i+1]['start-time']
# average the difference
elif overlap_strategy == 'average':
good_programs[i]['stop-time'] = avg
good_programs[i+1]['start-time'] = avg
# leave as is
else:
pass
# Experimental strategy to make sure programming does not disappear. All programs that overlap more
# than the maximum overlap length, but less than the shortest length of the two programs are
# clumped.
if do_clump:
for i in range(len(good_programs)-1):
stop = good_programs[i]['stop-time']
start = good_programs[i+1]['start-time']
dt = stop-start
overlap = 24*60*60*dt.days + dt.seconds
length0 = good_programs[i]['stop-time'] - good_programs[i]['start-time']
length1 = good_programs[i+1]['stop-time'] - good_programs[i+1]['start-time']
l0 = length0.days*24*60*60 + length0.seconds
l1 = length1.days*24*60*60 + length0.seconds
if abs(overlap) >= max_overlap*60 <= min(l0,l1)*60 and \
not good_programs[i].has_key('clumpidx') and \
not good_programs[i+1].has_key('clumpidx'):
good_programs[i]['clumpidx'] = '0/2'
good_programs[i+1]['clumpidx'] = '1/2'
good_programs[i]['stop-time'] = good_programs[i+1]['stop-time']
good_programs[i+1]['start-time'] = good_programs[i]['start-time']
# done, nothing to see here, please move on
return good_programs
def get_descriptions(programs, program_cache=None, nocattrans=0, quiet=0, slowdays=0):
Given a list of programs, from get_channel, retrieve program information
# This regexp tries to find details such as Genre, Acteurs, Jaar van Premiere etc.
detail = re.compile('<li>.*?<strong>(.*?):</strong>.*?<br />(.*?)</li>', re.DOTALL)
# These regexps find the description area, the program type and descriptive text
description = re.compile('<div class="description">.*?<div class="text"(.*?)<div class="clearer"></div>',re.DOTALL)
descrtype = re.compile('<div class="type">(.*?)</div>',re.DOTALL)
descrline = re.compile('<p>(.*?)</p>',re.DOTALL)
# randomize detail requests
nprograms = len(programs)
fetch_order = range(0,nprograms)
random.shuffle(fetch_order)
counter = 0
for i in fetch_order:
counter += 1
if programs[i]['offset'] >= slowdays:
continue
if not quiet:
sys.stderr.write('\n(%3.0f%%) %s: %s ' % (100*float(counter)/float(nprograms), i, programs[i]['name']))
# check the cache for this program's ID
cached_program = program_cache.query(programs[i]['ID'])
if (cached_program != None):
if not quiet:
sys.stderr.write(' [cached]')
# copy the cached information, except the start/end times, rating and clumping,
# these may have changed.
tstart = programs[i]['start-time']
tstop = programs[i]['stop-time']
rating = programs[i]['star-rating']
try:
clump = programs[i]['clumpidx']
except:
clump = False
programs[i] = cached_program
programs[i]['start-time'] = tstart
programs[i]['stop-time'] = tstop
programs[i]['star-rating'] = rating
if clump:
programs[i]['clumpidx'] = clump
continue
else:
# be nice to tvgids.nl
time.sleep(random.randint(nice_time[0], nice_time[1]))
# get the details page, and get all the detail nodes
descriptions = ()
details = ()
try:
if not quiet:
sys.stderr.write(' [normal fetch]')
total = get_page(programs[i]['url'])
details = detail.finditer(total)
descrspan = description.search(total);
descriptions = descrline.finditer(descrspan.group(1))
except:
# if we cannot find the description page,
# go to next in the loop
if not quiet:
sys.stderr.write(' [fetch failed or timed out]')
continue
# define containers
programs[i]['credits'] = {}
programs[i]['video'] = {}
# now parse the details
line_nr = 1;
# First, we try to find the program type in the description section.
# Note that this is not the same as the generic genres (these are searched later on), but a more descriptive one like "Culinair programma"
# If present, we store this as first part of the regular description:
programs[i]['detail1'] = descrtype.search(descrspan.group(1)).group(1).capitalize()
if programs[i]['detail1'] != '':
line_nr = line_nr + 1
# Secondly, we add one or more lines of the program description that are present.
for descript in descriptions:
d_str = 'detail' + str(line_nr)
programs[i][d_str] = descript.group(1)
# Remove sponsored link from description if present.
sponsor_pos = programs[i][d_str].rfind('<i>Gesponsorde link:</i>')
if sponsor_pos > 0:
programs[i][d_str] = programs[i][d_str][0:sponsor_pos]
programs[i][d_str] = filter_line(programs[i][d_str]).strip()
line_nr = line_nr + 1
# Finally, we check out all program details. These are generically denoted as:
# <li><strong>(TYPE):</strong><br />(CONTENT)</li>
# Some examples:
# <li><strong>Genre:</strong><br />16 oktober 2008</li>
# <li><strong>Genre:</strong><br />Amusement</li>
for d in details:
type = d.group(1).strip().lower()
content_asis = d.group(2).strip()
content = filter_line(content_asis).strip()
if content == '':
continue
elif type == 'genre':
# Fix detection of movies based on description as tvgids.nl sometimes
# categorises a movie as e.g. "Komedie", "Misdaadkomedie", "Detectivefilm".
genre = content;
if (programs[i]['detail1'].lower().find('film') != -1 \
or programs[i]['detail1'].lower().find('komedie') != -1)\
and programs[i]['detail1'].lower().find('tekenfilm') == -1 \
and programs[i]['detail1'].lower().find('animatiekomedie') == -1 \
and programs[i]['detail1'].lower().find('filmpje') == -1:
genre = 'film'
if nocattrans:
programs[i]['genre'] = genre.title()
else:
try:
programs[i]['genre'] = cattrans[genre.lower()]
except:
programs[i]['genre'] = ''
# Parse persons and their roles for credit info
elif roletrans.has_key(type):
programs[i]['credits'][roletrans[type]] = []
persons = content_asis.split(',');
for name in persons:
if name.find(':') != -1:
name = name.split(':')[1]
if name.find('-') != -1:
name = name.split('-')[0]
if name.find('e.a') != -1:
name = name.split('e.a')[0]
programs[i]['credits'][roletrans[type]].append(filter_line(name.strip()))
elif type == 'bijzonderheden':
if content.find('Breedbeeld') != -1:
programs[i]['video']['breedbeeld'] = 1
if content.find('Zwart') != -1:
programs[i]['video']['blackwhite'] = 1
if content.find('Teletekst') != -1:
programs[i]['teletekst'] = 1
if content.find('Stereo') != -1:
programs[i]['stereo'] = 1
elif type == 'url':
programs[i]['infourl'] = content
else:
# In unmatched cases, we still add the parsed type and content to the program details.
# Some of these will lead to xmltv output during the xmlefy_programs step
programs[i][type] = content
# do not cache programming that is unknown at the time
# of fetching.
if programs[i]['name'].lower() != 'onbekend':
program_cache.add(programs[i])
if not quiet:
sys.stderr.write('\ndone...\n\n')
# done
def title_split(program):
Some channels have the annoying habit of adding the subtitle to the title of a program.
This function attempts to fix this, by splitting the name at a ': '.
if (program.has_key('titel aflevering') and program['titel aflevering'] != '') \
or (program.has_key('genre') and program['genre'].lower() in ['movies','film']):
return
colonpos = program['name'].rfind(': ')
if colonpos > 0:
program['titel aflevering'] = program['name'][colonpos+1:len(program['name'])].strip()
program['name'] = program['name'][0:colonpos].strip()
def xmlefy_programs(programs, channel, desc_len, compat=0, nocattrans=0):
Given a list of programming (from get_channels())
returns a string with the xml equivalent
output = []
for program in programs:
clumpidx = ''
try:
if program.has_key('clumpidx'):
clumpidx = 'clumpidx="'+program['clumpidx']+'"'
except:
print program
output.append(' <programme start="%s" stop="%s" channel="%s%s" %s> \n' % \
(format_timezone(program['start-time']), format_timezone(program['stop-time']),\
channel, compat and '.tvgids.nl' or '', clumpidx))
output.append(' <title lang="nl">%s</title>\n' % filter_line(program['name']))
if program.has_key('titel aflevering') and program['titel aflevering'] != '':
output.append(' <sub-title lang="nl">%s</sub-title>\n' % filter_line(program['titel aflevering']))
desc = []
for detail_row in ['detail1','detail2','detail3']:
if program.has_key(detail_row) and not re.search('[Gg]een detailgegevens be(?:kend|schikbaar)', program[detail_row]):
desc.append('%s ' % program[detail_row])
if desc != []:
# join and remove newlines from descriptions
desc_line = "".join(desc).strip()
desc_line.replace('\n', ' ')
if len(desc_line) > desc_len:
spacepos = desc_line[0:desc_len-3].rfind(' ')
desc_line = desc_line[0:spacepos] + '...'
output.append(' <desc lang="nl">%s</desc>\n' % desc_line)
# Process credits section if present.
# This will generate director/actor/presenter info.
if program.has_key('credits') and program['credits'] != {}:
output.append(' <credits>\n')
for role in program['credits']:
for name in program['credits'][role]:
if name != '':
output.append(' <%s>%s</%s>\n' % (role, name, role))
output.append(' </credits>\n')
if program.has_key('jaar van premiere') and program['jaar van premiere'] != '':
output.append(' <date>%s</date>\n' % program['jaar van premiere'])
if program.has_key('genre') and program['genre'] != '':
output.append(' <category')
if nocattrans:
output.append(' lang="nl"')
output.append ('>%s</category>\n' % program['genre'])
if program.has_key('infourl') and program['infourl'] != '':
output.append(' <url>%s</url>\n' % program['infourl'])
if program.has_key('aflevering') and program['aflevering'] != '':
output.append(' <episode-num system="onscreen">%s</episode-num>\n' % filter_line(program['aflevering']))
# Process video section if present
if program.has_key('video') and program['video'] != {}:
output.append(' <video>\n');
if program['video'].has_key('breedbeeld'):
output.append(' <aspect>16:9</aspect>\n')
if program['video'].has_key('blackwhite'):
output.append(' <colour>no</colour>\n')
output.append(' </video>\n')
if program.has_key('stereo'):
output.append(' <audio><stereo>stereo</stereo></audio>\n')
if program.has_key('teletekst'):
output.append(' <subtitles type="teletext" />\n')
# Set star-rating if applicable
if program['star-rating'] != '':
output.append(' <star-rating><value>%s</value></star-rating>\n' % program['star-rating'])
output.append(' </programme>\n')
return "".join(output)
def main():
# Parse command line options
try:
opts, args = getopt.getopt(sys.argv[1:], "h", ["help", "output=", "capabilities",
"preferredmethod", "days=",
"configure", "fast", "slow",
"cache=", "clean_cache",
"slowdays=","compat",
"desc-length=","description",
"nocattrans","config-file=",
"max_overlap=", "overlap_strategy=",
"clear_cache", "quiet","logos="])
except getopt.GetoptError:
usage()
sys.exit(2)
# DEFAULT OPTIONS - Edit if you know what you are doing
# where the output goes
output = None
output_file = None
# the total number of days to fetch
days = 6
# Fetch data in fast mode, i.e. do NOT grab all the detail information,
# fast means fast, because as it then does not have to fetch a web page for each program
# Default: fast=0
fast = 0
# number of days to fetch in slow mode. For example: --days 5 --slowdays 2, will
# fetch the first two days in slow mode (with all the details) and the remaining three
# days in fast mode.
slowdays = 6
# no output
quiet = 0
# insert url of channel logo into the xml data, this will be picked up by mythfilldatabase
logos = 1
# enable this option if you were using tv_grab_nl, it adjusts the generated
# xmltvid's so that everything works.
compat = 0
# enable this option if you do not want the tvgids categories being translated into
# MythTV-categories (genres)
nocattrans = 0
# Maximum number of characters to use for program description.
# Different values may work better in different versions of MythTV.
desc_len = 475
# default configuration file locations
hpath = ''
if os.environ.has_key('HOME'):
hpath = os.environ['HOME']
# extra test for windows users
elif os.environ.has_key('HOMEPATH'):
hpath = os.environ['HOMEPATH']
# hpath = ''
xmltv_dir = hpath+'/.xmltv'
program_cache_file = xmltv_dir+'/program_cache'
config_file = xmltv_dir+'/tv_grab_nl_py.conf'
# cache the detail information.
program_cache = None
clean_cache = 1
clear_cache = 0
# seed the random generator
random.seed(time.time())
for o, a in opts:
if o in ("-h", "--help"):
usage()
sys.exit(1)
if o == "--quiet":
quiet = 1;
if o == "--description":
print "The Netherlands (tv_grab_nl_py $Rev: 104 $)"
sys.exit(0)
if o == "--capabilities":
print "baseline"
print "cache"
print "manualconfig"
print "preferredmethod"
sys.exit(0)
if o == '--preferredmethod':
print 'allatonce'
sys.exit(0)
if o == '--desc-length':
# Use the requested length for programme descriptions.
desc_len = int(a)
if not quiet:
sys.stderr.write('Using description length: %d\n' % desc_len)
for o, a in opts:
if o == "--config-file":
# use the provided name for configuration
config_file = a
if not quiet:
sys.stderr.write('Using config file: %s\n' % config_file)
for o, a in opts:
if o == "--configure":
# check for the ~.xmltv dir
if not os.path.exists(xmltv_dir):
if not quiet:
sys.stderr.write('You do not have the ~/.xmltv directory,')
sys.stderr.write('I am going to make a shiny new one for you...')
os.mkdir(xmltv_dir)
if not quiet:
sys.stderr.write('Creating config file: %s\n' % config_file)
get_channels(config_file)
sys.exit(0)
if o == "--days":
# limit days to maximum supported by tvgids.nl
days = min(int(a),6)
if o == "--compat":
compat = 1
if o == "--nocattrans":
nocattrans = 1
if o == "--fast":
fast = 1
if o == "--output":
output_file = a
try:
output = open(output_file,'w')
# and redirect output
if debug:
debug_file = open('/tmp/kaas.xml','w')
blah = redirect.Tee(output, debug_file)
sys.stdout = blah
else:
sys.stdout = output
except:
if not quiet:
sys.stderr.write('Cannot write to outputfile: %s\n' % output_file)
sys.exit(2)
if o == "--slowdays":
# limit slowdays to maximum supported by tvgids.nl
slowdays = min(int(a),6)
# slowdays implies fast == 0
fast = 0
if o == "--logos":
logos = int(a)
if o == "--clean_cache":
clean_cache = 1
if o == "--clear_cache":
clear_cache = 1
if o == "--cache":
program_cache_file = a
if o == "--max_overlap":
max_overlap = int(a)
if o == "--overlap_strategy":
overlap_strategy = a
# get configfile if available
try:
f = open(config_file,'r')
except:
sys.stderr.write('Config file %s not found.\n' % config_file)
sys.stderr.write('Re-run me with the --configure flag.\n')
sys.exit(1)
#check for cache
program_cache = ProgramCache(program_cache_file)
if clean_cache != 0:
program_cache.clean()
if clear_cache != 0:
program_cache.clear()
# Go!
channels = {}
# Read the channel stuff
for blah in f.readlines():
blah = blah.lstrip()
blah = blah.replace('\n','')
if blah:
if blah[0] != '#':
channel = blah.split()
channels[channel[0]] = " ".join(channel[1:])
# channels are now in channels dict keyed on channel id
# print header stuff
print '<?xml version="1.0" encoding="ISO-8859-1"?>'
print '<!DOCTYPE tv SYSTEM "xmltv.dtd">'
print '<tv generator-info-name="tv_grab_nl_py $Rev: 104 $">'
# first do the channel info
for key in channels.keys():
print ' <channel id="%s%s">' % (key, compat and '.tvgids.nl' or '')
print ' <display-name lang="nl">%s</display-name>' % channels[key]
if (logos):
ikey = int(key)
if logo_names.has_key(ikey):
full_logo_url = logo_provider[logo_names[ikey][0]]+logo_names[ikey][1]+'.gif'
print ' <icon src="%s" />' % full_logo_url
print ' </channel>'
num_chans = len(channels.keys())
channel_cnt = 0
if program_cache != None:
program_cache.clean()
fluffy = channels.keys()
nfluffy = len(fluffy)
for id in fluffy:
channel_cnt += 1
if not quiet:
sys.stderr.write('\n\nNow fetching %s(xmltvid=%s%s) (channel %s of %s)\n' % \
(channels[id], id, (compat and '.tvgids.nl' or ''), channel_cnt, nfluffy))
info = get_channel_all_days(id, days, quiet)
blah = parse_programs(info, None, quiet)
# fetch descriptions
if not fast:
get_descriptions(blah, program_cache, nocattrans, quiet, slowdays)
# Split titles with colon in it
# Note: this only takes place if all days retrieved are also grabbed with details (slowdays=days)
# otherwise this function might change some titles after a few grabs and thus may result in
# loss of programmed recordings for these programs.
if slowdays == days:
for program in blah:
title_split(program)
print xmlefy_programs(blah, id, desc_len, compat, nocattrans)
# save the cache after each channel fetch
if program_cache != None:
program_cache.dump(program_cache_file)
# be nice to tvgids.nl
time.sleep(random.randint(nice_time[0], nice_time[1]))
if program_cache != None:
program_cache.dump(program_cache_file)
# print footer stuff
print "</tv>"
# close the outputfile if necessary
if output != None:
output.close()
# and return success
sys.exit(0)
# allow this to be a module
if __name__ == '__main__':
main()
# vim:tw=0:et:sw=4
[cedric@tv ~]$
Best regards,
Cedric
Last edited by cdwijs (2010-11-04 18:44:51)

Running the script by python2 solves it for me:
su - mythtv -c "nice -n 19 python2 /usr/bin/tv_grab_nl_py --output ~/listings.xml"
Best regards,
Cedric

Similar Messages

  • Page Style works with NYTimes home page but fails with articles.

    Page Style works with nytimes.com front page in that the Basic Page Style is displayed but when I select an article the display is that of No Style even though the Basic Page Style is selected.
    This is on a Mac computer.

    See [http://support.mozilla.com/en-US/kb/How+to+set+the+home+page How to set the homepage]

  • [FIX] Getting hda_analyzer to work with python

    Hi everyone,
    I meant to put this up some time ago, so I apologise if this ends up as just noise but maybe this will help some people:
    If you have problems running hda_analyzer with the new python updates heres how to solve it (without downgrading):
    Change the last line in run.py  from this:
    os.system("python %s" % TMPDIR + '/' + FILES[0] + ' ' + ' '.join(sys.argv[1:]))
    to this:
    os.system("python2 %s" % TMPDIR + '/' + FILES[0] + ' ' + ' '.join(sys.argv[1:]))
    Simple change, but it will ensure that this script calls the hda_analyzer script correctly (it requires python2, whilst the update puts the default python call to ver 3).
    Also, run the <run.py> script like this:
    python2 ~/run.py
    << the "~/" is optional and not always usefull (depending on where run.py resides) >>

    Have you tried searching/asking in the crossover forums?
    http://www.codeweavers.com/support/forums/general/?;t=27

  • [solved] Sudo works with user password instead of admin password.

    When i do a sudo command, it asks for a password. I enter my normal user password, and it works!
    It doesn't work if I enter root password. Is this normal?
    Last edited by trusktr (2010-07-27 10:14:15)

    gotcha! Thanks

  • CTR works with PXI 8196,PXIe 8102, fails with PXIe 8100 - why?

    My client has reported a problem.  
    For years he has used a PXI 8196 RT Controller with PXI 6602 Counter card and my software has given good results.  They have 20+ of these systems and they have worked well.
    Now they are moving to PXIe 810x controllers, for cost reasons.
    WIth a PXIe 8102, the same code also works perfectly, measuring total counts over a period, as well as instantaneous frequency.
    With a PXIe 8100 - the exact same code reports DIFFERENT answers. The reported frequency is always 1% HIGHER than actual (For example, a known 4500 Hz input is reported as 4500 Hz on 8102, but as 4545 Hz on 8100.
    This happens on any channel, and swapping just the controller will make the problem come and go.
    Here is the CONFIGURE code, where the channels are set up (again, this has worked for years).
    Here is the SAMPLE code:
    Basically the CONFIG code configures the thing to count edges.   I do this because they need an accurate count over a 20-minute period, in addition to instantaneous frequency readings.
    The AVG TIME is a user-settable number defining how long a period to average, when showing the "instantaneous" frequency.
    So, I create a buffer for N samples, corresponding to that period.
    At SAMPLE time, I read the counter.  I replace the oldest value in the buffer with the newest, then subtract the newest - oldest to get the total counts in the sample period.
    The PULSES PER COUNT item is a scaler, to account for a 60-tooth wheel, or something.
    So, this same code has worked perfectly for years, until I plug an 8100 code in.  Then the result changes by 1 %, and EXACTLY 1%?
    The CPU burden on the bad controller is 31%.
    Any ideas?
    Steve Bird
    Culverson Software - Elegant software that is a pleasure to use.
    Culverson.com
    Blog for (mostly LabVIEW) programmers: Tips And Tricks

    Well, the controllers are not in my own hands.  I have an 8196 controller and on that, the CPU time is between 2 and 4%.
    But the 8100 and 8102 controllers are in my client's hands.
    I haven't gotten any hard timing numbers other than I saw the 31% figure reported on the video monitor.
    It's hard to believe that it would be EXACTLY 1% if it was CPU overburden.
    My software includes a calibration facility; here is a run from the good 8102:
    Here is a run from the 8100:
    This was with a reference digital freq generator.  You can see the one case where everything is within 0.1 Hz.
    the other case has everything EXACTLY 1% higher.  My only explanation is that the scan engine is running 1% slower.
    Steve Bird
    Culverson Software - Elegant software that is a pleasure to use.
    Culverson.com
    Blog for (mostly LabVIEW) programmers: Tips And Tricks

  • [rxvt-unicode]pseudo-transparency not working with Awesome WM (solved)

    Hi all,
    first of all, let me tell you that I googled about this problem, I read the Archwiki, the rxvt FAQ and several threads in multiple forums but nothing that I found actually worked.
    I'm using Awesome WM and OpenBox and my rxvt is the standard rxvt-unicode from the repos.
    Since an update, rxvt is not transparent anymore (I was using pseudo-transparency). Actually, transparency works with OpenBox but it does not work with Awesome WM. I find it very weird.
    I tried increasing the shading value in .Xdefaults as suggested in an other thread in this form but it did not help at all. I thought the problem was that I needed libafterimage so I installed it but then, how to use it?
    Does someone have any idea about this? I'd be very thankfull!
    Last edited by Sherwood51 (2011-01-18 17:04:37)

    And how exactly did you get it to work with feh ? I keep failing to get pseudo-transparency.
    My theme.lua has this:
    awsetbg -f -u feh path/to/wallpaper
    and I also tried this:
    feh --bg-scale path/to/wallpaper
    and in Xdefaults:
    URxvt*background 0
    URxvt*depth 24 ( doesn't work with 32 either )
    URxvt*inheritPixmap true
    URxvt*transparent true
    EDIT:
    I got cairo working ( finally ), so I have true transparency, so don't mind my post.
    Last edited by Varg (2011-01-19 21:08:33)

  • Requesting some changes for xen PKGBUILD to work with --enable-ovmf

    For background about this issue, you may want to read these two E-Mails to edk2 Mailing List:
    http://sourceforge.net/p/edk2/mailman/e … sg32776907
    http://sourceforge.net/p/edk2/mailman/e … sg32793684
    Basically, it goes like this:
    - Xen can be compiled with the optional --enable-ovmf option, so it can make DomU VMs using UEFI Firmware. Instructions here:
    http://wiki.xen.org/wiki/OVMF
    This can be done in Arch Linux by adding in the ./configure line of PKGBUILD --enable-ovmf, adding an additional step where makepkg downloads Source Code from edk2 repository.
    - Currently, it fails to build that way with this error:
    http://lists.xen.org/archives/html/xen- … 02855.html
    This error is caused because the edk2 Source Code that xen pulls during build is fresh and doesn't include any patch to make it aware that Arch Linux has both Python 3 (python) and Python 2 (python2). By default, it tries to compile with Python 3, so it fails.
    - Assuming than the Python version issue was fixed (I did it in a non-elegant way, replacing /usr/bin/python with /usr/bin/python2), it will still fail with this error:
    https://bugs.archlinux.org/task/40277
    https://aur.archlinux.org/packages/ovmf-svn/ (Some of the latest comments)
    This error is caused by building with GCC 4.9, earlier versions seems unaffected.
    The AUR has also a very similar package (If not identical) that is based on edk2 Source Code, the same which xen downloads while building, ovmf-svn:
    https://aur.archlinux.org/packages/ovmf-svn/
    This one has a PKGBUILD which includes some lines that seem to point that it is aware of both the python version issue, and the GCC 4.9 build issue, by providing a patch:
    https://aur.archlinux.org/packages/ov/ovmf-svn/PKGBUILD
    Reelevant lines seems to be these ones:
        msg "Fix GenFw: ERROR 3000: Invalid, Unsupported section alignment"
        patch -Np1 -i "${srcdir}/edk2-basetools-add-gcc4.9-support.patch" || true
        patch -Np1 -i "${srcdir}/edk2-ovmfpkg-add-gcc4.9-support.patch" || true
        msg "Use python2 for UDK BaseTools"
        sed 's|python |python2 |g' -i "${EDK_TOOLS_PATH}/BinWrappers/PosixLike"/* || true
        sed 's|python |python2 |g' -i "${EDK_TOOLS_PATH}/Tests/GNUmakefile"
    I didn't found any info regarding if Xen can work with OVMF ready-to-use binaries, or either building ovmf-svn, which I didn't tested but I suppose should build properly. All instructions regarding using Xen with OVMF request that it is added as option during build time. This forces me to have to modify the edk2 Source Code that xen downloads.
    Basically, what I want to request is if xen PKGBUILD can be modified to include a statement that checks if --enable-ovmf is being used, then make the appropriate changes to the edk2 Source Code that gets downloaded while building Xen so it successfully builds. This could *POSSIBILY* be based on existing ovmf-svn PKGBUILD code.
    This change could also be applied to other xen-based packages that can also be builded with --enable-ovmf and presents the same issues.

    FINALLY managed to get this thing working:
    http://i.imgur.com/ZWTRcn0.png
    I tried to build xen with --with-system-ovmf= as suggested like ten times or so, with no success. While xen seemed to build fine, when I tried to create a UEFI DomU, it simply opens and inmediately closes, through if using SeaBIOS worked fine. On xen IRC there was another Arch Linux user claiming that he recently got Xen with OVMF working using that parameter and the bios.bin binary from the ovmf-bin package from AUR. Installing ovmf-bin then providing xen the full path (--with-system-ovmf=/usr/share/ovmf/bios.bin) didn't worked, neither building ovmf-svn myself then using ovmf_x64.bin (Or renaming it to OVMF.fd, ovmf.bin, etc). It always builded perfectly, yet it failed to make a UEFI DomU. Still, both Firmwares worked when using qemu from the official Arch Linux repository (Note that ovmf-bin bios.bin is 1 MiB in size while ovmf-svn ovmf_x64.bin is 2 MiB, not sure what accounts for the difference).
    So how I got it working? A bit complex:
    - While in my first post I mention that ovmf-svn had a patch for GCC 4.9, it seems than the patch was removed in the last two days. Without the patch, ovmf-svn still builded properly, so I expected than the GCC 4.9 fix got included in edk2 Source Repository. This was blocking me earlier, so decided to give --enable-ovmf another go.
    - Renamed python2 to python as a workaround to not have to touch the edk2 tree that xen downloads, which worked the last time.
    - Used makepkg with --enable-ovmf in the PKGBUILD ./configure line. I expected it to work due what I mentioned earlier, but it still fails with the GCC 4.9's GenFw: ERROR 3000.
    - As a last resort measure, I decided to try to merge into xen the source that ovmf-svn PKGBUILD modifies, as that one builds properly.
    - I replaced all the directories inside xen/src/xen-4.4.1/tools/firmware/ovmf-dir-remote/ with the ones from ovmf-svn/src/tianocore-edk2-svn_build/. Not all directories were replaced, seems than ovmf-svn just downloads the parts of the tree required for building the OVMF Firmware, not everything, which xen does.
    - Used makepkg again, which used the existing source to try to build again.
    - It builded, no python or GenFw error. Installed the new package, rebooted, tried to make the UEFI DomU and BAM! There it is, as you can see in the Screenshot.
    Why can some users get this running with just providing bios.bin from ovmf-bin while I have to do a walk around the globe is anyone guess...
    To not derail this request further, I can say the following:
    - Assuming than --with-system-ovmf= works consistently, which for me didn't, is currently possible to build Xen with OVMF, so making a more complex PKGBUILD to be able to use --enable-ovmf may not be needed.
    - --enable-ovmf is still useful because it may reduce a two-step process (Installing ovmf-bin or building ovmf-svn) into one, through I'm not sure if there are pros/cons for each approach besides than you will have latest OVMF version compared to the ready-to-use binary. It also makes xen package more compatible with the mainstream Xen instructions, as  --with-system-ovmf= is quite unknow.
    These decisions are for kantras to make.
    Last edited by zir_blazer (2014-09-06 06:54:02)

  • Fail2ban error with python 2.6

    hi there,
    I get funny error messages when trying to start fail2ban. after some playing around I found out that it works fine with python-2.5.2-5-x86_64.pkg.tar.gz but not with any python 2.6 version.
    here is the relevant part of the log file:
    http://paste.geekosphere.org/1061929
    is there a possibility to get it working with python 2.6 or do I have to stay with 2.5 if I want to use fail2ban?

    this problem seems a little specific to be asked here - I'd suggest you try the mailing list of fail2ban users which can be found here:
    https://lists.sourceforge.net/lists/lis … 2ban-users

  • Trying to install pgmagick with python 3

    Hello,
    I'm trying to get pgmagick to work with Python 3.
    First thing I had to do was linking to the Python 3 boost libraries, by changing lines 83 and following on setup.py from
    if _version >= (3, ):
    boost_lib_target_files.append("boost_python-py%s%s" % (_version[0], _version[1]))
    boost_lib_target_files.append("boost_python-mt-py%s%s" % (_version[0], _version[1]))
    #gentoo appends the python version numbers to the boost_python libraries
    boost_lib_target_files.append("boost_python-%s.%s" % (_version[0], _version[1]))
    boost_lib_target_files.append("boost_python-mt")
    to
    if _version >= (3, ):
    boost_lib_target_files.append("boost_python-py%s%s" % (_version[0], _version[1]))
    # ArchLinux uses boost_python3
    boost_lib_target_files.append("boost_python%s" % (_version[0]))
    boost_lib_target_files.append("boost_python-mt-py%s%s" % (_version[0], _version[1]))
    #gentoo appends the python version numbers to the boost_python libraries
    boost_lib_target_files.append("boost_python-%s.%s" % (_version[0], _version[1]))
    boost_lib_target_files.append("boost_python-mt")
    Now, when I launch setup.py, I get the following error:
    $ sudo python setup.py install
    include header path: /usr/include/GraphicsMagick/
    Found boost lib: /usr/lib64/libboost_python3
    boost lib: boost_python3
    library path: /usr/lib64/libGraphicsMagick++
    Libraries: ['boost_python3', 'GraphicsMagick++']
    GraphicsMagick version: 1.3.19
    running install
    Traceback (most recent call last):
    File "setup.py", line 174, in <module>
    keywords="GraphicsMagick ImageMagick graphics boost image")
    File "/usr/lib/python3.4/distutils/core.py", line 148, in setup
    dist.run_commands()
    File "/usr/lib/python3.4/distutils/dist.py", line 955, in run_commands
    self.run_command(cmd)
    File "/usr/lib/python3.4/distutils/dist.py", line 974, in run_command
    cmd_obj.run()
    File "/usr/lib/python3.4/site-packages/setuptools/command/install.py", line 67, in run
    self.do_egg_install()
    File "/usr/lib/python3.4/site-packages/setuptools/command/install.py", line 103, in do_egg_install
    cmd.ensure_finalized() # finalize before bdist_egg munges install cmd
    File "/usr/lib/python3.4/distutils/cmd.py", line 107, in ensure_finalized
    self.finalize_options()
    File "/usr/lib/python3.4/site-packages/setuptools/command/easy_install.py", line 313, in finalize_options
    self.index_url, search_path=self.shadow_path, hosts=hosts,
    File "/usr/lib/python3.4/site-packages/setuptools/package_index.py", line 269, in __init__
    Environment.__init__(self,*args,**kw)
    File "/usr/lib/python3.4/site-packages/pkg_resources.py", line 799, in __init__
    self.scan(search_path)
    File "/usr/lib/python3.4/site-packages/pkg_resources.py", line 829, in scan
    self.add(dist)
    File "/usr/lib/python3.4/site-packages/pkg_resources.py", line 849, in add
    dists.sort(key=operator.attrgetter('hashcmp'), reverse=True)
    TypeError: unorderable types: str() < NoneType()
    I am quite new to building Python packages, so I'm not sure about what is going wrong.
    Any help is appreciated.
    Thanks,
    gm

    I get the same issue installing another package using setuptools and python3 any solutions so far ?
    Thanks.

  • Labview 2012 (64bit) not working with ActiveX and MSAccess

    I have a program developed to open a MSAccess database file and import data using ActiveX commands. The program works with LabView 2012 (32bit) but fails on the ActiveX open command when using LabView 2012 (64bit). I also have the application built as an EXE and it works fine in a windows 32 bit environment (XP or Win 7-32bit) but fails when run on Win 7-64bit. I isolated the error down to the Active X automation Open VI.
    Anyone have a solution for the incompatibility?
    summary
    1.) VI and EXE works on XP and Win 7-32bit
    2.) EXE fail on Win 7-64bit.
    3.) VI works on Win 7-64 bit with LV 2012 (32bit)
    4.) VI fails on Win 7-64 bit with LV 2012 (64bit)

    It looks like you are trying to load a 32-bit DLL from a 64-bit OS. Do you have a 64-bit version of access installed? You'll need to change to that. On the other hand, ActiveX with Access is so slow. You can speed things up considerably by using ADO (i.e. NI's Database Connectivity Toolkit or something like LabSQL).

  • [SOLVED] python-efl: command 'gcc' failed with exit status 1

    Hi everyone! I'm running an x86_64 system with Enlightenment. I'm trying to install econnman from source to have a simpler life trying to connect to my University's wifi network. However, it misses the python-efl dependency. I downloaded it from the AUR, but I get the error message "error: command 'gcc' failed with exit status 1"  when running 'python setup.py build'. This is the complete terminology output:
    [dude@susan python-efl-1.8.0]$ sudo python setup.py build
    Checking for Eina: OK, found 1.11.2
    Checking for Eo: OK, found 1.11.2
    Checking for Evas: OK, found 1.11.2
    Checking for Ecore: OK, found 1.11.2
    Checking for EcoreFile: OK, found 1.11.2
    Checking for Edje: OK, found 1.11.2
    Checking for Emotion: OK, found 1.11.2
    Checking for DBus: OK, found 1.2.0
    Checking for Elementary: OK, found 1.11.2
    running build
    running build_py
    creating build/lib.linux-x86_64-3.4/e_dbus
    copying compat/e_dbus/__init__.py -> build/lib.linux-x86_64-3.4/e_dbus
    running build_ext
    building 'eo' extension
    gcc -pthread -Wno-unused-result -Werror=declaration-after-statement -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong --param=ssp-buffer-size=4 -fPIC -DEFL_BETA_API_SUPPORT -Iinclude/ -I/usr/include/python3.4m -c efl/eo/efl.eo.c -o build/temp.linux-x86_64-3.4/efl/eo/efl.eo.o -I/usr/include/efl-1 -I/usr/include/eo-1 -I/usr/include/efl-1 -I/usr/include/eina-1 -I/usr/include/eina-1/eina
    efl/eo/efl.eo.c: In function ‘__pyx_pf_3efl_2eo_4event_global_freeze_get’:
    efl/eo/efl.eo.c:1127:3: warning: implicit declaration of function ‘eo_event_global_freeze_get’ [-Wimplicit-function-declaration]
    eo_do(((const Eo *)eo_base_class_get()), eo_event_global_freeze_get((&__pyx_v_fcount)));
    ^
    efl/eo/efl.eo.c: In function ‘__pyx_f_3efl_2eo_object_from_instance’:
    efl/eo/efl.eo.c:1445:3: warning: implicit declaration of function ‘eo_base_data_get’ [-Wimplicit-function-declaration]
    eo_do(__pyx_v_obj, eo_base_data_get(__pyx_k_5, (&__pyx_v_data)));
    ^
    efl/eo/efl.eo.c: In function ‘__pyx_f_3efl_2eo__eo_event_del_cb’:
    efl/eo/efl.eo.c:2050:3: warning: implicit declaration of function ‘eo_base_data_del’ [-Wimplicit-function-declaration]
    eo_do(__pyx_v_self->obj, eo_base_data_del(__pyx_k_5));
    ^
    In file included from efl/eo/efl.eo.c:317:0:
    efl/eo/efl.eo.c: In function ‘__pyx_pf_3efl_2eo_2Eo_4__repr__’:
    efl/eo/efl.eo.c:2286:30: error: too many arguments to function ‘eo_parent_get’
    eo_do(__pyx_v_self->obj, eo_parent_get((&__pyx_v_parent)));
    ^
    /usr/include/eo-1/Eo.h:588:8: note: in definition of macro ‘_eo_do_common’
    __VA_ARGS__; \
    ^
    efl/eo/efl.eo.c:2286:5: note: in expansion of macro ‘eo_do’
    eo_do(__pyx_v_self->obj, eo_parent_get((&__pyx_v_parent)));
    ^
    In file included from /usr/include/eo-1/Eo.h:1112:0,
    from efl/eo/efl.eo.c:317:
    /usr/include/eo-1/eo_base.eo.h:37:12: note: declared here
    EOAPI Eo * eo_parent_get(void);
    ^
    efl/eo/efl.eo.c: In function ‘__pyx_f_3efl_2eo_2Eo__set_obj’:
    efl/eo/efl.eo.c:2496:3: warning: implicit declaration of function ‘eo_base_data_set’ [-Wimplicit-function-declaration]
    eo_do(__pyx_v_self->obj, eo_base_data_set(__pyx_k_5, ((void *)__pyx_v_self), NULL));
    ^
    In file included from efl/eo/efl.eo.c:317:0:
    efl/eo/efl.eo.c: In function ‘__pyx_pf_3efl_2eo_2Eo_14parent_get’:
    efl/eo/efl.eo.c:2963:28: error: too many arguments to function ‘eo_parent_get’
    eo_do(__pyx_v_self->obj, eo_parent_get((&__pyx_v_parent)));
    ^
    /usr/include/eo-1/Eo.h:588:8: note: in definition of macro ‘_eo_do_common’
    __VA_ARGS__; \
    ^
    efl/eo/efl.eo.c:2963:3: note: in expansion of macro ‘eo_do’
    eo_do(__pyx_v_self->obj, eo_parent_get((&__pyx_v_parent)));
    ^
    In file included from /usr/include/eo-1/Eo.h:1112:0,
    from efl/eo/efl.eo.c:317:
    /usr/include/eo-1/eo_base.eo.h:37:12: note: declared here
    EOAPI Eo * eo_parent_get(void);
    ^
    efl/eo/efl.eo.c: In function ‘__pyx_pf_3efl_2eo_2Eo_20event_freeze_get’:
    efl/eo/efl.eo.c:3104:3: warning: implicit declaration of function ‘eo_event_freeze_get’ [-Wimplicit-function-declaration]
    eo_do(__pyx_v_self->obj, eo_event_freeze_get((&__pyx_v_fcount)));
    ^
    error: command 'gcc' failed with exit status 1
    Can anyone help me? Please tell me every output you need. Thanks and a good day to you, sir!
    Last edited by HisDudeness (2014-10-02 08:47:15)

    You know what? You're right!
    I don't know how I exactly got that version... I got back to the AUR and downloaded the new one. The strange thing is, while that old version's tar.gz conained a lot of files like I'd expect from a source archive, the current version only contained the files .AURINFO and PKGBUILD. Guess that's the way it should be, I'm new to all of this so I was initially surprised. Obviously, running makepkg here worked like a charm and downloaded everything that was needed for it to install. Then, econnman installed just fine too. What I can't explain to myself is why 1.8.0's tar.gz contained all those files.
    In the end, I couldn't use nor connman cli nor econnman to connect to my Campus' WiFi but, after a lot of trouble, I got it to work with dhclient and wpa_supplicant like it's suggested. This hasn't been useless anyway, I saw how to install from the AUR for the first time.
    I'll mark the post as solved, but I got one last question: provided I don't need econnman anymore, do you suggest me to keep python-efl or to remove it? Is it needed for something else I'll certainly run into in the future?

  • [SOLVED] Xmonad: trasparency doesn't work with compton intel

    Dear All,
    I am having a strange issue with Xmonad and I am not sure whether it is a problem of my Arch or Xmonad configuration. I decided to ask on Arch forum first, as my other computer running Arch has exactly the same Xmonad setup and it works fine. I would appreciate assistance from some Xmonad or Arch proficient users on this.
    Basically, I have this piece of code in my xmonad.hs:
    myLogHook :: Handle -> X ()
    , logHook = myLogHook dzenLeftBar >> fadeInactiveLogHook 0.8
    On the other computer this makes all the unfocused windowses slightly transparent. I find this feature very useful as it helps me focus on the window I am working with.
    For some reason this doesn't work on my laptop. My laptop is using xf86-video-intel since the lspci gave me
    %lspci | grep VGA
    00:02.0 VGA compatible controller: Intel Corporation Mobile GM965/GL960 Integrated Graphics Controller (primary) (rev 03)
    Also I am invoking compton-git from AUR but I have also tried with xcompmgr in my xinitrc and it gave exactly the same result - no transparency whatsoever.
    I looked through my log file, but couldn't find anything relevant (please let me know if you can think of anything). How do I proceed with this issue? Do I try different composite managers? Do I try different drivers? Is there anyhting in X setup that I should include? Please let me know if you have any ideas.
    Last edited by AlmostSurelyRob (2013-06-18 10:18:08)

    I am very sorry. I've just discovered that neither compton nor xcompmgr were installed. It's not only solved, it should be marked as [NOT RAISED]. I was migrating my configuration and overlooked some erm... details.

  • Working with Outlook 2011 for Mac, my mails are slow and I can work only on-line, when off-line, mail cannot be opened because it is only partially downloaded. How to solve??

    working with Outlook 2011 for Mac, my mails are slow and I can work only on-line, when off-line, mail cannot be opened because it is only partially downloaded. How to solve??

    Try http://www.microsoft.com/mac/support.

  • I'm working with a Mac, with 10.10.2 system.  My Audition program has been working fine for years now.  But, there is a problem I can't solve.  All my markers on a given piece of audio allows me to left click to highlight the time signature until my audio

    I'm working with a Mac, with 10.10.2 system.  My Audition program has been working fine for years now.  But, there is a problem I can't solve.  All my markers on a given piece of audio allows me to left click to highlight the time signature until my audio reaches the one hour point.  From there on, the left click will not give me the drop down menu in order to copy and then paste into an Excel sheet I then have to submit for the proofing purposes.  After the one hour mark, I can only control/c in order to highlight, then when I slide up to my Excel sheet, I'm able to right click and paste.  Why is the program not, all of a su allowing me to left cllick the mouse and have a drop down menu give me the option to "copy, " as it does for any time signature markers up to 1:00:00.000?

    Which version of Audition? With the latest version of Audition running on a Windows 7 machine I can't get a dropdown menu at all when I left click on the time in Markers List. The only way to do it is with cntrl-c.

  • My cellcom line doesn't work with my iPhone here in Israel, why? Is there any way I can solve this issue?

    My cellcom line doesn't work with my iPhone here in Israel, why? Is there any way I can solve this issue?

    Please explain.
    What does "cellcom line doesn't work with my iPhone" mean?
    What are you trying?  What is happening?
    Where did you buy the iphone?
    Any info abnout your issue at all?

Maybe you are looking for