Completed
Push — master ( b66745...9821e6 )
by Jasper
02:18 queued 58s
created

MongoRepository   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 133
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 133
rs 10
wmc 29

16 Methods

Rating   Name   Duplication   Size   Complexity  
A byLocations() 0 3 2
A byLocation() 0 14 1
A byId() 0 3 1
A latest() 0 3 2
A add() 0 7 1
A inflate() 0 7 3
A all() 0 8 2
A updateApproval() 0 3 1
A deflate() 0 6 2
A __init__() 0 6 1
A search() 0 7 3
A getSeries() 0 16 2
A update() 0 8 1
A byParents() 0 4 2
A inquire() 0 8 3
A statistics() 0 13 2
1
import pymongo, copy, bson
2
from niprov.dependencies import Dependencies
3
4
5
class MongoRepository(object):
6
7
    def __init__(self, dependencies=Dependencies()):
8
        self.config = dependencies.getConfiguration()
9
        self.factory = dependencies.getFileFactory()
10
        self.pictures = dependencies.getPictureCache()
11
        client = pymongo.MongoClient(self.config.database_url)
12
        self.db = client.get_default_database()
13
14
    def byLocation(self, locationString):
15
        """Get the provenance for a file at the given location. 
16
17
        In the case of a dicom series, this returns the provenance for the 
18
        series.
19
20
        Args:
21
            locationString (str): Location of the image file.
22
23
        Returns:
24
            dict: Provenance for one image file.
25
        """
26
        record = self.db.provenance.find_one({'location':locationString})
27
        return self.inflate(record)
28
29
    def byLocations(self, listOfLocations):
30
        records = self.db.provenance.find({'location':{'$in':listOfLocations}})
31
        return [self.inflate(record) for record in records]
32
33
    def getSeries(self, image):
34
        """Get the object that carries provenance for the series that the image 
35
        passed is in. 
36
37
        Args:
38
            image (:class:`.DicomFile`): File that is part of a series.
39
40
        Returns:
41
            :class:`.DicomFile`: Image object that caries provenance for 
42
                         the series.
43
        """
44
        seriesUid = image.getSeriesId()
45
        if seriesUid is None:
46
            return None
47
        record = self.db.provenance.find_one({'seriesuid':seriesUid})
48
        return self.inflate(record)
49
50
    def add(self, image):
51
        """Add the provenance for one file to storage.
52
53
        Args:
54
            image (:class:`.BaseFile`): Image file to store.
55
        """
56
        self.db.provenance.insert_one(self.deflate(image))
57
58
    def update(self, image):
59
        """Save changed provenance for this file..
60
61
        Args:
62
            image (:class:`.BaseFile`): Image file that has changed.
63
        """
64
        self.db.provenance.update({'location':image.location.toString()}, 
65
            self.deflate(image))
66
67
    def updateApproval(self, locationString, approvalStatus):
68
        self.db.provenance.update({'location':locationString}, 
69
            {'$set': {'approval': approvalStatus}})
70
71
    def all(self):
72
        """Retrieve all known provenance from storage.
73
74
        Returns:
75
            list: List of provenance for known files.
76
        """
77
        records = self.db.provenance.find()
78
        return [self.inflate(record) for record in records]
79
80
    def latest(self):
81
        records = self.db.provenance.find().sort('added', -1).limit(20)
82
        return [self.inflate(record) for record in records]
83
84
    def statistics(self):
85
        grps = self.db.provenance.aggregate(
86
           [{'$group':
87
                 {
88
                   '_id': None,
89
                   'totalsize': { '$sum': '$size' },
90
                   'count': { '$sum': 1 }
91
                 }
92
            }])
93
        groups = list(grps)
94
        if len(list(groups)) == 0:
95
            return {'count':0}
96
        return list(groups)[0]
97
98
    def byId(self, uid):
99
        record = self.db.provenance.find_one({'id':uid})
100
        return self.inflate(record)
101
102
    def byParents(self, listOfParentLocations):
103
        records = self.db.provenance.find({'parents':{
104
            '$in':listOfParentLocations}})
105
        return [self.inflate(record) for record in records]
106
107
    def inquire(self, query):
108
        field = query.getFields()[0]
109
        if field.all:
110
            records = self.db.provenance.distinct(field.name)
111
            return records
112
        else:
113
            records = self.db.provenance.find({field.name:field.value})
114
            return [self.inflate(record) for record in records]
115
116
    def search(self, text):
117
        searchfields = ['location','user','subject','project','protocol',
118
                  'transformation','technique','modality']
119
        indexspec = [(field, pymongo.TEXT) for field in searchfields]
120
        self.db.provenance.create_index(indexspec, name='textsearch')
121
        records = self.db.provenance.find({'$text':{'$search': text}})
122
        return [self.inflate(record) for record in records]
123
124
    def deflate(self, img):
125
        record = copy.deepcopy(img.provenance)
126
        snapshotData = self.pictures.getBytes(for_=img)
127
        if snapshotData:
128
            record['_snapshot-data'] = bson.Binary(snapshotData)
129
        return record
130
131
    def inflate(self, record):
132
        if record is None:
133
            return None
134
        img = self.factory.fromProvenance(record)
135
        if '_snapshot-data' in record:
136
            self.pictures.keep(record['_snapshot-data'], for_=img)
137
        return img
138
139