~ubuntu-branches/ubuntu/raring/apt-xapian-index/raring-proposed

« back to all changes in this revision

Viewing changes to plugins/relations.py

  • Committer: Bazaar Package Importer
  • Author(s): Michael Vogt
  • Date: 2011-06-17 10:51:30 UTC
  • mfrom: (15.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20110617105130-zrb03qthrg3l51mv
Tags: 0.43ubuntu1
* Merge from debian unstable.  Remaining changes:
  - when upgrading, ensure the index is fully rebuild (in the
    background) to ensure that we get updated information in
    /var/lib/apt-xapian-index/{index.values} and that the index
    fully utilizes the new plugins (LP: #646018)
  - use ionice for the index building
  - do not crash if the DB is already locked (LP: #590998)
  - data/org.debian.AptXapianIndex.conf: fix policy
  - move to dh_python2
  - update-apt-xapian-index-dbus:
    + fix type of "start-time" for policykit (LP: #675533)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
try:
 
2
    import apt
 
3
    import apt_pkg
 
4
    HAS_APT=True
 
5
except ImportError:
 
6
    HAS_APT=False
 
7
import os, os.path
 
8
import re
 
9
 
 
10
class Relations:
 
11
    def __init__(self):
 
12
        self.prefix_desc=[
 
13
            dict(idx="XRD", qp="reldep:", type="bool",
 
14
                 desc="Relation: depends",
 
15
                 ldesc="Depends: relationship, package names only"),
 
16
            dict(idx="XRR", qp="relrec:", type="bool",
 
17
                 desc="Relation: recommends",
 
18
                 ldesc="Recommends: relationship, package names only"),
 
19
            dict(idx="XRS", qp="relsug:", type="bool",
 
20
                 desc="Relation: suggests",
 
21
                 ldesc="Suggests: relationship, package names only"),
 
22
            dict(idx="XRE", qp="relenh:", type="bool",
 
23
                 desc="Relation: ehnances",
 
24
                 ldesc="Enhances: relationship, package names only"),
 
25
            dict(idx="XRP", qp="relpre:", type="bool",
 
26
                 desc="Relation: pre-depends",
 
27
                 ldesc="Pre-Depends: relationship, package names only"),
 
28
            dict(idx="XRB", qp="relbre:", type="bool",
 
29
                 desc="Relation: breaks",
 
30
                 ldesc="Breaks: relationship, package names only"),
 
31
            dict(idx="XRC", qp="relcon:", type="bool",
 
32
                 desc="Relation: conflicts",
 
33
                 ldesc="Conflicts: relationship, package names only"),
 
34
        ]
 
35
        self.prefixes = [(d["idx"], d["ldesc"][:d["ldesc"].find(":")]) for d in self.prefix_desc]
 
36
        self.re_split = re.compile(r"\s*[|,]\s*")
 
37
 
 
38
    def info(self, **kw):
 
39
        """
 
40
        Return general information about the plugin.
 
41
 
 
42
        The information returned is a dict with various keywords:
 
43
 
 
44
         timestamp (required)
 
45
           the last modified timestamp of this data source.  This will be used
 
46
           to see if we need to update the database or not.  A timestamp of 0
 
47
           means that this data source is either missing or always up to date.
 
48
         values (optional)
 
49
           an array of dicts { name: name, desc: description }, one for every
 
50
           numeric value indexed by this data source.
 
51
 
 
52
        Note that this method can be called before init.  The idea is that, if
 
53
        the timestamp shows that this plugin is currently not needed, then the
 
54
        long initialisation can just be skipped.
 
55
        """
 
56
        res = dict(
 
57
                timestamp=0,
 
58
                prefixes=self.prefix_desc,
 
59
        )
 
60
        if kw.get("system", True):
 
61
            if not HAS_APT: return res
 
62
            file = apt_pkg.config.find_file("Dir::Cache::pkgcache")
 
63
            if not os.path.exists(file):
 
64
                return res
 
65
            ts = os.path.getmtime(file)
 
66
        else:
 
67
            file = "(stdin)"
 
68
            ts = 0
 
69
        res["sources"] = [dict(path=file, desc="APT index")]
 
70
        res["timestamp"] = ts
 
71
        return res
 
72
 
 
73
    def init(self, info, progress):
 
74
        """
 
75
        If needed, perform long initialisation tasks here.
 
76
 
 
77
        info is a dictionary with useful information.  Currently it contains
 
78
        the following values:
 
79
 
 
80
          "values": a dict mapping index mnemonics to index numbers
 
81
 
 
82
        The progress indicator can be used to report progress.
 
83
        """
 
84
        pass
 
85
 
 
86
    def doc(self):
 
87
        """
 
88
        Return documentation information for this data source.
 
89
 
 
90
        The documentation information is a dictionary with these keys:
 
91
          name: the name for this data source
 
92
          shortDesc: a short description
 
93
          fullDoc: the full description as a chapter in ReST format
 
94
        """
 
95
        return dict(
 
96
            name = "Package relationships",
 
97
            shortDesc = "Debian package relationships",
 
98
            fullDoc = """
 
99
            Indexes one term per relationship declared with other packages. All
 
100
            relationship terms have prefixes starting with XR plus an extra
 
101
            prefix letter per relationship type.
 
102
 
 
103
            Terms are built using only the package names in the relationship
 
104
            fields: versioning and boolean operators are ignored.
 
105
            """
 
106
        )
 
107
 
 
108
    def _index_rel(self, pfx, val, doc):
 
109
        """
 
110
        Extract all package names from @val and index them as terms with prefix
 
111
        @pfx
 
112
        """
 
113
        for name in self.re_split.split(val):
 
114
            doc.add_term(pfx + name.split(None, 1)[0])
 
115
 
 
116
    def index(self, document, pkg):
 
117
        """
 
118
        Update the document with the information from this data source.
 
119
 
 
120
        document  is the document to update
 
121
        pkg       is the python-apt Package object for this package
 
122
        """
 
123
        ver = pkg.candidate
 
124
        if ver is None: return
 
125
        rec = ver.record
 
126
        if rec is None: return
 
127
        for pfx, field in self.prefixes:
 
128
            val = rec.get(field, None)
 
129
            if val is None: continue
 
130
            self._index_rel(pfx, val, document)
 
131
 
 
132
    def indexDeb822(self, document, pkg):
 
133
        """
 
134
        Update the document with the information from this data source.
 
135
 
 
136
        This is alternative to index, and it is used when indexing with package
 
137
        data taken from a custom Packages file.
 
138
 
 
139
        document  is the document to update
 
140
        pkg       is the Deb822 object for this package
 
141
        """
 
142
        for pfx, field in self.prefixes:
 
143
            val = pkg.get(field, None)
 
144
            if val is None: continue
 
145
            self._index_rel(pfx, val, document)
 
146
 
 
147
def init(**kw):
 
148
    """
 
149
    Create and return the plugin object.
 
150
    """
 
151
    return Relations()