forked from canada-ca/tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathorganization.py
More file actions
184 lines (159 loc) · 6.36 KB
/
organization.py
File metadata and controls
184 lines (159 loc) · 6.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
"""This module defines the Domain class, which models organizations monitored by Tracker
and offers methods to get data about them."""
import json
from slugify import slugify
import domain as dom
from formatting import format_summary
import queries
class Organization:
"""Class that represents an organization in Tracker.
Instance variables provide access to scalar fields for the organization in the GraphQL schema,
while methods return JSON data for non-scalar fields. Users should not typically
instantiate this class manually, instead use methods provided by
:class:`~tracker_client.client.Client` to get Organizations.
The naming irregularity between :meth:`__init__` parameters and instance variables is to match
parameter names to the keys contained in the API responses. This allows easy
use of dict unpacking when creating an Organization instance. Instance variable names instead
adhere to Python convention.
:ivar Client client: the :class:`~tracker_client.client.Client` that created
this object. Provides a way for Organization methods to execute queries.
:ivar str name: full name of the organization.
:ivar str acronym: acronym for the organization.
:ivar str zone: the zone the organization belongs to.
:ivar str sector: the sector the organization belongs to.
:ivar str country: country the organization resides in.
:ivar str province: province the organization resides in.
:ivar str city: city the organization resides in.
:ivar bool verified: if the organization is verified or not.
:ivar int domainCount: number of domains controlled by the organization.
:ivar int domain_count: the instance variable containing the domainCount value.
"""
def __init__(
self,
client,
name,
acronym,
zone,
sector,
country,
province,
city,
verified,
domainCount,
):
"""
:param Client client: see class docstring.
:param str name: see class docstring.
:param str acronym: see class docstring.
:param str zone: see class docstring.
:param str sector: see class docstring.
:param str country: see class docstring.
:param str province: see class docstring.
:param str city: see class docstring.
:param bool verified: see class docstring.
:param int domainCount: sets domain_count.
"""
self.client = client
self.name = name
self.acronym = acronym
self.zone = zone
self.sector = sector
self.country = country
self.province = province
self.city = city
self.verified = verified
self.domain_count = domainCount
def __str__(self):
return self.acronym + " " + self.name
def __repr__(self):
return "Organization(client=%r, name=%r, acronym=%r, zone=%r, sector=%r, country=%r, province=%r, city=%r, verified=%r, domain_count=%r)" % (
self.client,
self.name,
self.acronym,
self.zone,
self.sector,
self.country,
self.province,
self.city,
self.verified,
self.domain_count,
)
def get_summary(self):
"""Get summary metrics for this Organization.
:return: formatted JSON data containing summary metrics for an organization.
:rtype: str
:Example:
>>> from tracker_client.client import Client
>>> client = Client()
>>> my_orgs = client.get_organizations()
>>> print(my_orgs[0].get_summary())
{
"FOO": {
"domainCount": 10,
"summaries": {
"web": {
"total": 10,
"categories": [
{
"name": "pass",
"count": 1,
"percentage": 10
},
{
"name": "fail",
"count": 9,
"percentage": 90
}
]
},
"mail": {
"total": 10,
"categories": [
{
"name": "pass",
"count": 5,
"percentage": 50
},
{
"name": "fail",
"count": 5,
"percentage": 50
}
]
}
}
}
}
"""
params = {"orgSlug": slugify(self.name)}
result = self.client.execute_query(queries.SUMMARY_BY_SLUG, params)
if "error" not in result:
result = format_summary(result)
return json.dumps(result, indent=4)
# Consider changing to generator
def get_domains(self):
"""Get a list of Domains controlled by this Organization.
:return: list of :class:`domains <tracker_client.domain.Domain>` controlled by
this Organization.
:rtype: List[Domain]
"""
params = {"orgSlug": slugify(self.name), "after": ""}
has_next = True
domain_list = []
# The maximum number of domains that can be requested at once is 100
# This loop gets 100 domains, checks if there are more, and if there are
# it gets another 100 starting after the last domain it got
while has_next:
result = self.client.execute_query(queries.GET_ORG_DOMAINS, params)
if "error" in result:
print("Server error: ", result)
raise ValueError("Unable to get domains for " + self.name)
for edge in result["findOrganizationBySlug"]["domains"]["edges"]:
domain_list.append(dom.Domain(self.client, **edge["node"]))
has_next = result["findOrganizationBySlug"]["domains"]["pageInfo"][
"hasNextPage"
]
params["after"] = result["findOrganizationBySlug"]["domains"]["pageInfo"][
"endCursor"
]
return domain_list