Completed
Push — master ( 982edc...614fe0 )
by Edward
22s
created

ResultSets   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 106
Duplicated Lines 0 %
Metric Value
dl 0
loc 106
rs 8.3396
wmc 44

14 Methods

Rating   Name   Duplication   Size   Complexity  
C parseEC2Object() 0 25 7
A parseEC2Zone() 0 3 2
A parseAddress() 0 3 2
A parseRecord() 0 3 2
A parseR53Zone() 0 3 2
A parseReservation() 0 7 2
A parseVolume() 0 3 2
A parseR53Status() 0 3 2
A parseBucket() 0 3 2
A __init__() 0 2 1
A parseBlockDeviceType() 0 3 2
A parseInstance() 0 3 2
B formatter() 0 7 5
F selector() 0 23 11

How to fix   Complexity   

Complex Class

Complex classes like ResultSets often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import boto
2
import six
3
4
5
class FieldLists():
6
    ADDRESS = [
7
        'allocation_id',
8
        'association_id',
9
        'domain',
10
        'instance_id',
11
        'network_interface_id',
12
        'network_interface_owner_id',
13
        'private_ip_address',
14
        'public_ip'
15
    ]
16
17
    BLOCK_DEVICE_TYPE = [
18
        'attach_time',
19
        'delete_on_termination',
20
        'encrypted',
21
        'ephemeral_name',
22
        'iops',
23
        'size',
24
        'snapshot_id',
25
        'status',
26
        'volume_id',
27
        'volume_type'
28
    ]
29
30
    BUCKET = [
31
        'connection',
32
        'creation_date',
33
        'LoggingGroup',
34
        'name'
35
    ]
36
37
    EC2ZONE = [
38
        'messages',
39
        'name',
40
        'region_name',
41
        'state'
42
    ]
43
44
    INSTANCE = [
45
        'ami_launch_index',
46
        'architecture',
47
        'hypervisor',
48
        'id',
49
        'image_id',
50
        'instance_type',
51
        'ip_address',
52
        'kernel',
53
        'key_name',
54
        'launch_time',
55
        'monitored',
56
        'monitoring_state',
57
        'placement',
58
        'placement_group',
59
        'placement_tenancy',
60
        'platform',
61
        'previous_state',
62
        'previous_state_code',
63
        'private_dns_name',
64
        'private_ip_address',
65
        'public_dns_name',
66
        'ramdisk',
67
        'root_device_name',
68
        'root_device_type',
69
        'spot_instance_request_id',
70
        'state',
71
        'state_code',
72
        'state_reason',
73
        'subnet_id',
74
        'virtualization_type',
75
        'vpc_id',
76
    ]
77
78
    RECORD = [
79
        'alias_dns_name',
80
        'alias_evaluate_target_health',
81
        'alias_hosted_zone_id',
82
        'failover',
83
        'health_check',
84
        'identifier',
85
        'name',
86
        'region',
87
        'resource_records',
88
        'ttl',
89
        'type',
90
        'weight'
91
    ]
92
93
    R53ZONE = [
94
        'callerreference',
95
        'config',
96
        'id',
97
        'name',
98
        'resourcerecordsetcount'
99
    ]
100
101
    R53STATUS = [
102
        'comment',
103
        'id',
104
        'status',
105
        'submittedat'
106
    ]
107
108
    VOLUME = [
109
        'create_time',
110
        'encrypted',
111
        'id',
112
        'iops',
113
        'size',
114
        'snapshot_id',
115
        'status',
116
        'type',
117
        'zone'
118
    ]
119
120
121
class ResultSets(object):
122
123
    def __init__(self):
124
        self.foo = ''
125
126
    def selector(self, output):
127
        if isinstance(output, boto.ec2.instance.Reservation):
128
            return self.parseReservation(output)
129
        elif isinstance(output, boto.ec2.instance.Instance):
130
            return self.parseInstance(output)
131
        elif isinstance(output, boto.ec2.volume.Volume):
132
            return self.parseVolume(output)
133
        elif isinstance(output, boto.ec2.blockdevicemapping.BlockDeviceType):
134
            return self.parseBlockDeviceType(output)
135
        elif isinstance(output, boto.ec2.zone.Zone):
136
            return self.parseEC2Zone(output)
137
        elif isinstance(output, boto.ec2.address.Address):
138
            return self.parseAddress(output)
139
        elif isinstance(output, boto.route53.record.Record):
140
            return self.parseRecord(output)
141
        elif isinstance(output, boto.route53.zone.Zone):
142
            return self.parseR53Zone(output)
143
        elif isinstance(output, boto.route53.status.Status):
144
            return self.parseR53Status(output)
145
        elif isinstance(output, boto.ec2.ec2object.EC2Object):
146
            return self.parseEC2Object(output)
147
        else:
148
            return output
149
150
    def formatter(self, output):
151
        if isinstance(output, list):
152
            return [self.formatter(item) for item in output]
153
        elif isinstance(output, dict):
154
            return {key: self.formatter(value) for key, value in six.iteritems(output)}
155
        else:
156
            return self.selector(output)
157
158
    def parseReservation(self, output):
159
        instance_list = []
160
        for instance in output.instances:
161
            instance_data = self.parseInstance(instance)
162
            instance_data['owner_id'] = output.owner_id
163
            instance_list.append(instance_data)
164
        return instance_list
165
166
    def parseAddress(self, output):
167
        instance_data = {field: getattr(output, field) for field in FieldLists.ADDRESS}
168
        return instance_data
169
170
    def parseInstance(self, output):
171
        instance_data = {field: getattr(output, field) for field in FieldLists.INSTANCE}
172
        return instance_data
173
174
    def parseVolume(self, output):
175
        volume_data = {field: getattr(output, field) for field in FieldLists.VOLUME}
176
        return volume_data
177
178
    def parseBlockDeviceType(self, output):
179
        data = {field: getattr(output, field) for field in FieldLists.BLOCK_DEVICE_TYPE}
180
        return data
181
182
    def parseEC2Zone(self, output):
183
        zone_data = {field: getattr(output, field) for field in FieldLists.EC2ZONE}
184
        return zone_data
185
186
    def parseRecord(self, output):
187
        record_data = {field: getattr(output, field) for field in FieldLists.RECORD}
188
        return record_data
189
190
    def parseR53Zone(self, output):
191
        zone_data = {field: getattr(output, field) for field in FieldLists.R53ZONE}
192
        return zone_data
193
194
    def parseR53Status(self, output):
195
        status_data = {field: getattr(output, field) for field in FieldLists.R53STATUS}
196
        return status_data
197
198
    def parseBucket(self, output):
199
        bucket_data = {field: getattr(output, field) for field in FieldLists.BUCKET}
200
        return bucket_data
201
202
    def parseEC2Object(self, output):
203
        # Looks like everything that is an EC2Object pretty much only has these extra
204
        # 'unparseable' properties so handle region and connection specially.
205
        output = vars(output)
206
        del output['connection']
207
        # special handling for region since name here is better than id.
208
        region = output.get('region', None)
209
        output['region'] = region.name if region else ''
210
        # now anything that is an EC2Object get some special marshalling care.
211
        for k, v in six.iteritems(output):
212
            if isinstance(v, boto.ec2.ec2object.EC2Object):
213
                # Better not to assume each EC2Object has an id. If not found
214
                # resort to the str of the object which should have something meaningful.
215
                output[k] = getattr(v, 'id', str(v))
216
            # Generally unmarshallable object might be hiding in list so better to
217
            if isinstance(v, list):
218
                v_list = []
219
                for item in v:
220
                    # avoid touching the basic types.
221
                    if isinstance(item, (basestring, bool, int, long, float)):
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'basestring'
Loading history...
Comprehensibility Best Practice introduced by
Undefined variable 'long'
Loading history...
222
                        v_list.append(v)
223
                    else:
224
                        v_list.append(str(item))
225
                output[k] = v_list
226
        return output
227