~ubuntu-branches/ubuntu/karmic/quodlibet/karmic

« back to all changes in this revision

Viewing changes to quodlibet/parse/_match.py

  • Committer: Bazaar Package Importer
  • Author(s): Luca Falavigna
  • Date: 2009-01-30 23:55:34 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20090130235534-l4e72ulw0vqfo17w
Tags: 2.0-1ubuntu1
* Merge from Debian experimental (LP: #276856), remaining Ubuntu changes:
  + debian/patches/40-use-music-profile.patch:
    - Use the "Music and Movies" pipeline per default.
* Refresh the above patch for new upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2004-2005 Joe Wreschnig, Michael Urman
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License version 2 as
 
5
# published by the Free Software Foundation
 
6
#
 
7
# $Id: _match.py 4330 2008-09-14 03:19:26Z piman $
 
8
 
 
9
import time
 
10
 
 
11
TIME_KEYS = ["added", "mtime", "lastplayed", "laststarted"]
 
12
 
 
13
# True if the object matches any of its REs.
 
14
class Union(object):
 
15
    def __init__(self, res):
 
16
        self.__res = res
 
17
 
 
18
    def search(self, data):
 
19
        for re in self.__res:
 
20
            if re.search(data): return True
 
21
        return False
 
22
 
 
23
    def __repr__(self):
 
24
        return "<Union %r>" % self.__res
 
25
 
 
26
# True if the object matches all of its REs.
 
27
class Inter(object):
 
28
    def __init__(self, res):
 
29
        self.__res = res
 
30
 
 
31
    def search(self, data):
 
32
        for re in self.__res:
 
33
            if not re.search(data): return False
 
34
        return True
 
35
 
 
36
    def __repr__(self):
 
37
        return "<Inter %r>" % self.__res
 
38
 
 
39
# True if the object doesn't match its RE.
 
40
class Neg(object):
 
41
    def __init__(self, re):
 
42
        self.__re = re
 
43
 
 
44
    def search(self, data):
 
45
        return not self.__re.search(data)
 
46
 
 
47
    def __repr__(self):
 
48
        return "<Neg %r>" % self.__re
 
49
 
 
50
# Numeric comparisons
 
51
class Numcmp(object):
 
52
    def __init__(self, tag, op, value):
 
53
        if isinstance(tag, unicode): self.__tag = tag.encode("utf-8")
 
54
        else: self.__tag = tag
 
55
        self.__ftag = "~#" + self.__tag
 
56
        self.__shortcircuit = tag.startswith("playlist")
 
57
        self.__op = op
 
58
        value = value.strip()
 
59
 
 
60
        if tag in TIME_KEYS:
 
61
            if self.__op == ">": self.__op = "<"
 
62
            elif self.__op == "<": self.__op = ">"
 
63
            elif self.__op == "<=": self.__op = ">="
 
64
            elif self.__op == ">=": self.__op = "<="
 
65
 
 
66
        if value in ["now"]: value = int(time.time())
 
67
        elif value in ["today"]: value = int(time.time() - 24 * 60 * 60)
 
68
        else:
 
69
            parts = value.split()
 
70
            try: value = round(float(parts[0]), 2)
 
71
            except ValueError:
 
72
                try:
 
73
                    hms = map(int, value.split(":"))
 
74
                    value = 0
 
75
                    for t in hms:
 
76
                        value *= 60
 
77
                        value += t
 
78
                except ValueError:
 
79
                    value = 0
 
80
            if len(parts) > 1:
 
81
                unit = parts[1].strip("s")
 
82
                if unit == "minute": value *= 60
 
83
                if unit == "hour": value *= 60 * 60
 
84
                elif unit == "day": value *= 24 * 60 * 60
 
85
                elif unit == "week": value *= 7 * 24 * 60 * 60
 
86
                elif unit == "year": value *= 365 * 24 * 60 * 60
 
87
 
 
88
                if tag in TIME_KEYS:
 
89
                    value = int(time.time() - value)
 
90
        self.__value = value
 
91
 
 
92
    def search(self, data):
 
93
        if self.__shortcircuit: num = data.get(self.__ftag, 0)
 
94
        else: num = data(self.__ftag, 0)
 
95
        num = round(num, 2)
 
96
        if   self.__op == ">":  return num >  self.__value
 
97
        elif self.__op == "<":  return num <  self.__value
 
98
        elif self.__op == "=":  return num == self.__value
 
99
        elif self.__op == ">=": return num >= self.__value
 
100
        elif self.__op == "<=": return num <= self.__value
 
101
        elif self.__op == "!=": return num != self.__value
 
102
        else: raise ValueError("Unknown operator %s" % self.__op)
 
103
 
 
104
    def __repr__(self):
 
105
        return "<Numcmp tag=%r, op=%r, value=%d>"%(
 
106
            self.__tag, self.__op, self.__value)
 
107
 
 
108
# See if a property of the object matches its RE.
 
109
class Tag(object):
 
110
 
 
111
    # Shorthand for common tags.
 
112
    ABBRS = { "a": "artist",
 
113
              "b": "album",
 
114
              "v": "version",
 
115
              "t": "title",
 
116
              "n": "tracknumber",
 
117
              "d": "date",
 
118
              }
 
119
    def __init__(self, names, res):
 
120
        self.__names = [Tag.ABBRS.get(n.lower(), n.lower()) for n in names]
 
121
        self.__res = res
 
122
        if not isinstance(self.__res, list): self.__res = [self.__res]
 
123
        if len([name for name in self.__names if name.startswith('~')]):
 
124
            self.search = self.__search_synth
 
125
 
 
126
    def __search_synth(self, data):
 
127
        for name in self.__names:
 
128
            for re in self.__res:
 
129
                if name.startswith('~'):
 
130
                    if re.search(data(name, "")):
 
131
                        return True
 
132
                elif re.search(data.get(name, data.get("~"+name, ""))):
 
133
                    return True
 
134
        return False
 
135
 
 
136
    def search(self, data):
 
137
        for name in self.__names:
 
138
            for re in self.__res:
 
139
                if re.search(data.get(name, data.get("~"+name, ""))):
 
140
                    return True
 
141
        return False
 
142
 
 
143
    def __repr__(self):
 
144
        return ("<Tag names=%r, res=%r>" % (self.__names, self.__res))