summaryrefslogtreecommitdiff
path: root/format.py
blob: a06d463ed9cf5f986fc1a416dc22a932683f6467 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import re
import os

def compile(string):
	"""Compile a string into a function which fills in correct values."""
	
	# This function will extract all variables and functions from $string
	# and convert these to functions. That way, it is much faster to run
	# than parse everytime $string.
	
	# we will split the string into sections; a section is either a string
	# or a variable.
	
	str, params=format_parse_rec(string.replace("%", "%%"), 0)
	ps=merge(params)
	func='lambda params: "%s" %% (%s)' % (str.replace('"', '\\"').replace("\n", ""), ps)
	return eval(func)

def merge(list):
	ret=""
	for l in list:
		ret="%s%s, "%(ret, l)
	return ret[:-2]

func=re.compile('\$[a-z_]+', re.IGNORECASE)
def format_parse_rec(string, start):
	"""Compiles a function. Returns [special str, params]."""
	match=func.search(string, start)
	if not match:
		return string[start:], []

	ret1=""	# string
	ret2=[]	# params
	# set fixed string
	ret1+=string[start:match.start()]
	name=string[match.start()+1:match.end()]
	
	# here are all functions defined
	if name in ['if', 'ifn', 'dirname']:
		try:
			end=match_bracket(string, string.find("(", match.start()))
		except:
			end=-1
		if end<0:
			raise Exception("No matching brackets")
		
	if name=='if' or name=='ifn':
		# print if something is true/false
		# $if($expr-true, $output)
		# $ifn($expr-false, $output)
		body=string[match.end():end]
		comma=body.find(',')
		s1,p1=format_parse_rec(body[1:comma], 0)	# get the if-part
		s2,p2=format_parse_rec(body[comma+1:-1], 0)	# if true!
		ret1+="%s"
		if name=='if':
			ret2.append("('%s' %% (%s) if (%s) else '')"%(s2, merge(p2), merge(p1)))
		elif name=='ifn':
			ret2.append("('%s' %% (%s) if not(%s) else '')"%(s2, merge(p2), merge(p1)))
	elif name=='dirname':
		# get the dir of a path
		# $dirname(path)
		s,p=format_parse_rec(string[match.end()+1:end-1], 0)
		ret1+="%s"
		ret2.append('os.path.dirname("%s"%%(%s))'%(s, merge(p)))
	else:
		end=match.end()
		# variable
		ret1+="%s"
		ret2.append('params["%s"]'%(name))
	
	ret=format_parse_rec(string, end)
	ret1+=ret[0]
	if len(ret[1]):
		ret2.extend(ret[1])
	return ret1, ret2

def match_bracket(string, start):
	"""Returns position of matching bracket."""
	assert(string[start:start+1]=="(")
	balance=1
	start+=1
	while balance>0:
		if start<=0:
			raise Exception("No matching bracket found")
		l=string.find("(", start)
		r=string.find(")", start)
		
		if l<0:
			if r>0:	balance-=1
			else:	return -1
			start=r+1
		else:
			if l<r:	balance+=1
			elif l>r:	balance-=1
			start=min(l,r)+1
	
	if balance==0:
		return r+1
	return max(l,r)+1
		
def params(song, overwrite={}, ensure={"title":"", "artist":""\
		, "album":"", "genre":"", "track":"", "length":"" \
		, "date":"", "time":""}):
	params={}
	for param in ensure:
		params[param]=ensure[param]
	if song:
		for param in song._data:
			params[param]=song._data[param]
	for param in overwrite:
		params[param]=overwrite[param]
	return params

#f=compile("$if($date, ($date) )")
#f=compile("a$if($title,$title)b$if($artist,$artist)c")
#f=compile('abc$dirname($title/$artist/$artist$state)ghi')
#print f({'state':'playing', 'title':'martha', 'artist':'waits'})
#f=compile("$artist $if($title, titeltje:$artist, $artist $title!) $album")
#print f({'artist':'artist', 'title':'title', 'album':'album'})
#print format_compile('now $title a $artist two');
#print format_compile('now $state$if($title,$if($artist, yeay$title $artist))check')