Completed
Pull Request — master (#125)
by Jasper
01:05
created

niprov.MongoRepository.deflate()   A

Complexity

Conditions 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 2
dl 0
loc 5
rs 9.4285
1
import pymongo, copy
2
from datetime import timedelta
3
from niprov.dependencies import Dependencies
4
5
6
class MongoRepository(object):
7
8
    def __init__(self, dependencies=Dependencies()):
9
        self.config = dependencies.getConfiguration()
10
        self.factory = dependencies.getFileFactory()
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 knowsByLocation(self, locationString):
34
        """Whether the file at this location has provenance associated with it.
35
36
        Returns:
37
            bool: True if provenance is available for that path.
38
        """
39
        return self.db.provenance.find_one(
40
            {'location':locationString}) is not None
41
42
    def knows(self, image):
43
        """Whether this file has provenance associated with it.
44
45
        Returns:
46
            bool: True if provenance is available for this image.
47
        """
48
        return self.knowsByLocation(image.location.toString())
49
50
    def getSeries(self, image):
51
        """Get the object that carries provenance for the series that the image 
52
        passed is in. 
53
54
        Args:
55
            image (:class:`.DicomFile`): File that is part of a series.
56
57
        Returns:
58
            :class:`.DicomFile`: Image object that caries provenance for the series.
59
        """
60
        seriesUid = image.getSeriesId()
61
        record = self.db.provenance.find_one({'seriesuid':seriesUid})
62
        return self.inflate(record)
63
64
    def knowsSeries(self, image):
65
        """Whether this file is part of a series for which provenance 
66
        is available.
67
68
        Args:
69
            image (:class:`.BaseFile`): File for which the series is sought.
70
71
        Returns:
72
            bool: True if provenance is available for this series.
73
        """
74
        seriesUid = image.getSeriesId()
75
        if seriesUid is None:
76
            return False
77
        return self.db.provenance.find_one({'seriesuid':seriesUid}) is not None
78
79
    def add(self, image):
80
        """Add the provenance for one file to storage.
81
82
        Args:
83
            image (:class:`.BaseFile`): Image file to store.
84
        """
85
        self.db.provenance.insert_one(self.deflate(image))
86
87
    def update(self, image):
88
        """Save changed provenance for this file..
89
90
        Args:
91
            image (:class:`.BaseFile`): Image file that has changed.
92
        """
93
        self.db.provenance.update({'location':image.location.toString()}, 
94
            self.deflate(image))
95
96
    def updateApproval(self, locationString, approvalStatus):
97
        self.db.provenance.update({'location':locationString}, 
98
            {'$set': {'approval': approvalStatus}})
99
100
    def all(self):
101
        """Retrieve all known provenance from storage.
102
103
        Returns:
104
            list: List of provenance for known files.
105
        """
106
        records = self.db.provenance.find()
107
        return [self.inflate(record) for record in records]
108
109
110
    def bySubject(self, subject):
111
        """Get the provenance for all files of a given participant. 
112
113
        Args:
114
            subject (str): The name or other ID string.
115
116
        Returns:
117
            list: List of provenance for known files imaging this subject.
118
        """
119
        records = self.db.provenance.find({'subject':subject})
120
        return [self.inflate(record) for record in records]
121
122
    def byApproval(self, approvalStatus):
123
        records = self.db.provenance.find({'approval':approvalStatus})
124
        return [self.inflate(record) for record in records]
125
126
127
    def latest(self):
128
        records = self.db.provenance.find().sort('added', -1).limit(20)
129
        return [self.inflate(record) for record in records]
130
131
    def statistics(self):
132
        grps = self.db.provenance.aggregate(
133
           [{'$group':
134
                 {
135
                   '_id': None,
136
                   'totalsize': { '$sum': '$size' },
137
                   'count': { '$sum': 1 }
138
                 }
139
            }])
140
        groups = list(grps)
141
        if len(list(groups)) == 0:
142
            return {'count':0}
143
        return list(groups)[0]
144
145
    def byId(self, uid):
146
        record = self.db.provenance.find_one({'id':uid})
147
        return self.inflate(record)
148
149
    def byParents(self, listOfParentLocations):
150
        records = self.db.provenance.find({'parents':{
151
            '$in':listOfParentLocations}})
152
        return [self.inflate(record) for record in records]
153
154
    def deflate(self, img):
155
        record = copy.deepcopy(img.provenance)
156
        if 'duration' in record:
157
            record['duration'] = record['duration'].total_seconds()
158
        return record
159
160
    def inflate(self, record):
161
        if 'duration' in record:
162
            record['duration'] = timedelta(seconds=record['duration'])
163
        return self.factory.fromProvenance(record)
164
165
166