|
| 1 | +import requests |
| 2 | + |
| 3 | +from pydomo.DomoAPIClient import DomoAPIClient |
| 4 | +from pydomo.Transport import HTTPMethod |
| 5 | + |
| 6 | +PAGE_DESC = "Page" |
| 7 | +COLLECTION_DESC = "Collection" |
| 8 | +URL_BASE = '/v1/pages' |
| 9 | + |
| 10 | +PAGE_CREATION_KWARGS = [ |
| 11 | + 'parentId', |
| 12 | + 'locked', |
| 13 | + 'cardIds', |
| 14 | + 'visibility' |
| 15 | +] |
| 16 | + |
| 17 | +PAGE_UPDATE_KWARGS = [ |
| 18 | + 'id', |
| 19 | + 'name', |
| 20 | + 'parentId', |
| 21 | + 'ownerId', |
| 22 | + 'locked', |
| 23 | + 'collectionIds', |
| 24 | + 'cardIds', |
| 25 | + 'visibility' |
| 26 | +] |
| 27 | + |
| 28 | +COLLECTION_CREATION_KWARGS = [ |
| 29 | + 'description', |
| 30 | + 'cardIds' |
| 31 | +] |
| 32 | + |
| 33 | +COLLECTION_UPDATE_KWARGS = [ |
| 34 | + 'id', |
| 35 | + 'description', |
| 36 | + 'cardIds', |
| 37 | + 'title' |
| 38 | +] |
| 39 | + |
| 40 | + |
| 41 | +class PageClient(DomoAPIClient): |
| 42 | + """ |
| 43 | + Pages |
| 44 | + - Programmatically manage Domo Pages |
| 45 | + - Docs: https://developer.domo.com/docs/data-apis/pages |
| 46 | + """ |
| 47 | + |
| 48 | + def create(self, name, **kwargs): |
| 49 | + """Create a new page. |
| 50 | +
|
| 51 | + >>> page = {'name':'New Page'} |
| 52 | + >>> new_page = domo.pages.create(**page) |
| 53 | + >>> print(new_page) |
| 54 | + {'id': 123456789, 'parentId': 0, 'name': 'My Page', |
| 55 | + 'locked': False, 'ownerId': 12345, 'cardIds': [], |
| 56 | + 'visibility': {'userIds': 12345}} |
| 57 | +
|
| 58 | + :Parameters: |
| 59 | + - `name`: The name of the new page |
| 60 | + - `parentId`: (optional) If present create page as subpage |
| 61 | + - `locked`: (optional) whether to lock the page |
| 62 | + - `cardIds`: (optional) cards to place on the page |
| 63 | + - `visibility`: (optional) dict of userIds and/or groupIds to |
| 64 | + give access to |
| 65 | +
|
| 66 | + :Returns: |
| 67 | + - A dict representing the page |
| 68 | + """ |
| 69 | + |
| 70 | + self._validate_params(kwargs, PAGE_CREATION_KWARGS) |
| 71 | + |
| 72 | + page_request = {'name': name} |
| 73 | + page_request.update(kwargs) |
| 74 | + return self._create(URL_BASE, page_request, {}, PAGE_DESC) |
| 75 | + |
| 76 | + def get(self, page_id): |
| 77 | + """Get a page. |
| 78 | +
|
| 79 | + >>> page = domo.pages.get(page_id) |
| 80 | + >>> print(page) |
| 81 | + {'id': 123456789, 'parentId': 0, 'name': 'My Page', |
| 82 | + 'locked': False, 'ownerId': 12345, 'cardIds': [], |
| 83 | + 'visibility': {'userIds': 12345}} |
| 84 | +
|
| 85 | + :Parameters: |
| 86 | + - `page_id`: ID of the page to get |
| 87 | +
|
| 88 | + :returns: |
| 89 | + - A dict representing the page |
| 90 | + """ |
| 91 | + url = '{base}/{page_id}'.format(base=URL_BASE, page_id=page_id) |
| 92 | + return self._get(url, PAGE_DESC) |
| 93 | + |
| 94 | + def list(self, per_page=50, offset=0, limit=0): |
| 95 | + """List pages. |
| 96 | + Returns a generator that will call the API multiple times |
| 97 | + If limit is supplied and non-zero, returns up to limit pages |
| 98 | +
|
| 99 | + >>> list(domo.pages.list()) |
| 100 | + [{'id': 123456789, 'name': 'My Page', 'children': []}, ...] |
| 101 | +
|
| 102 | + :returns: |
| 103 | + - A list of dicts (with nesting possible) |
| 104 | + """ |
| 105 | + # API uses pagination with a max of 50 per page |
| 106 | + if per_page not in range(1, 51): |
| 107 | + raise ValueError('per_page must be between 1 and 50 (inclusive)') |
| 108 | + # Don't pull 50 values if user requests 10 |
| 109 | + if limit: |
| 110 | + per_page = min(per_page, limit) |
| 111 | + |
| 112 | + params = { |
| 113 | + 'limit': per_page, |
| 114 | + 'offset': offset, |
| 115 | + } |
| 116 | + page_count = 0 |
| 117 | + |
| 118 | + pages = self._list(URL_BASE, params, PAGE_DESC) |
| 119 | + while pages: |
| 120 | + for page in pages: |
| 121 | + yield page |
| 122 | + page_count += 1 |
| 123 | + if limit and page_count >= limit: |
| 124 | + return |
| 125 | + |
| 126 | + params['offset'] += per_page |
| 127 | + if limit and params['offset'] + per_page > limit: |
| 128 | + # Don't need to pull more than the limit |
| 129 | + params['limit'] = limit - params['offset'] |
| 130 | + pages = self._list(URL_BASE, params, PAGE_DESC) |
| 131 | + |
| 132 | + def update(self, page_id=None, **kwargs): |
| 133 | + """Update a page. |
| 134 | +
|
| 135 | + >>> print(domo.pages.get(page_id)) |
| 136 | + {'id': 123456789, 'parentId': 0, 'name': 'My Page', |
| 137 | + 'locked': False, 'ownerId': 12345, 'cardIds': [], |
| 138 | + 'visibility': {'userIds': 12345}} |
| 139 | + >>> domo.pages.update(page_id, locked=True, |
| 140 | + cardIds=[54321, 13579]) |
| 141 | + >>> print(domo.pages.get(page_id)) |
| 142 | + {'id': 123456789, 'parentId': 0, 'name': 'My Page', |
| 143 | + 'locked': True, 'ownerId': 12345, 'cardIds': [54321, 13579], |
| 144 | + 'visibility': {'userIds': 12345}} |
| 145 | +
|
| 146 | + # Using **kwargs: |
| 147 | + >>> page = domo.pages.get(page_id) |
| 148 | + >>> page['cardIds'].append(new_card_id) |
| 149 | + >>> domo.pages.update(**page) |
| 150 | +
|
| 151 | + :Parameters: |
| 152 | + - `page_id`: ID of the page to update. Can also be provided |
| 153 | + by supplying `id` to **kwargs. This allows for calling get, |
| 154 | + updating the returned object, then passing it to update. |
| 155 | + - `name`: (optional) rename the page |
| 156 | + - `parentId`: (optional) turn page into subpage, or subpage |
| 157 | + into top-level page if parentId is present and falsey |
| 158 | + - `ownerId`: (optional) change owner of the page |
| 159 | + - `locked`: (optional) lock or unlock the page |
| 160 | + - `collectionIds`: (optional) reorder collections on page |
| 161 | + - `cardIds`: (optional) specify which cards to have on page |
| 162 | + - `visibility`: (optional) change who can see the page |
| 163 | + """ |
| 164 | + |
| 165 | + self._validate_params(kwargs, PAGE_UPDATE_KWARGS) |
| 166 | + if page_id is None and 'id' not in kwargs: |
| 167 | + raise TypeError("update() missing required argument: 'page_id'") |
| 168 | + elif 'id' in kwargs: |
| 169 | + if page_id is not None and page_id != kwargs['id']: |
| 170 | + raise ValueError('ambiguous page ID - page_id and id both ' |
| 171 | + 'supplied but do not match') |
| 172 | + page_id = kwargs['id'] |
| 173 | + del kwargs['id'] |
| 174 | + if not kwargs.get('parentId', True): |
| 175 | + # Check if parentId is present and falsey |
| 176 | + kwargs['parentId'] = 0 |
| 177 | + |
| 178 | + url = '{base}/{page_id}'.format(base=URL_BASE, page_id=page_id) |
| 179 | + return self._update(url, |
| 180 | + HTTPMethod.PUT, |
| 181 | + requests.codes.NO_CONTENT, |
| 182 | + kwargs, |
| 183 | + PAGE_DESC) |
| 184 | + |
| 185 | + def delete(self, page_id): |
| 186 | + """Delete a page. |
| 187 | +
|
| 188 | + :Parameters: |
| 189 | + - `page_id`: ID of the page to delete |
| 190 | + """ |
| 191 | + url = '{base}/{page_id}'.format(base=URL_BASE, page_id=page_id) |
| 192 | + return self._delete(url, PAGE_DESC) |
| 193 | + |
| 194 | + def create_collection(self, page_id, title, **kwargs): |
| 195 | + """Create a collection on a page. |
| 196 | +
|
| 197 | + >>> collection = domo.pages.create_collection(page_id, |
| 198 | + 'Collection') |
| 199 | + >>> print(collection) |
| 200 | + {'id': 1234321, 'title': 'Collection', 'description': '', |
| 201 | + 'cardIds': []} |
| 202 | +
|
| 203 | + :Parameters: |
| 204 | + - `page_id`: ID of the page to create a collection on |
| 205 | + - `title`: The title of the collection |
| 206 | + - `description`: (optional) The description of the collection |
| 207 | + - `cardIds`: (optional) cards to place in the collection |
| 208 | +
|
| 209 | + :Returns: |
| 210 | + - A dict representing the collection |
| 211 | + """ |
| 212 | + |
| 213 | + self._validate_params(kwargs, COLLECTION_CREATION_KWARGS) |
| 214 | + collection_request = {'title': title} |
| 215 | + collection_request.update(kwargs) |
| 216 | + |
| 217 | + url = '{base}/{page_id}/collections'.format( |
| 218 | + base=URL_BASE, page_id=page_id) |
| 219 | + return self._create(url, collection_request, {}, COLLECTION_DESC) |
| 220 | + |
| 221 | + def get_collections(self, page_id): |
| 222 | + """Get a collections of a page |
| 223 | +
|
| 224 | + >>> print(domo.pages.get_collections(page_id)) |
| 225 | + [{'id': 1234321, 'title': 'Collection', 'description': '', |
| 226 | + 'cardIds': []}] |
| 227 | +
|
| 228 | + :Parameters: |
| 229 | + - `page_id`: ID of the page |
| 230 | +
|
| 231 | + :Returns: |
| 232 | + - A list of dicts representing the collections |
| 233 | + """ |
| 234 | + url = '{base}/{page_id}/collections'.format(base=URL_BASE, |
| 235 | + page_id=page_id) |
| 236 | + return self._get(url, COLLECTION_DESC) |
| 237 | + |
| 238 | + def update_collection(self, page_id, collection_id=None, **kwargs): |
| 239 | + """Update a collection of a page. |
| 240 | +
|
| 241 | + >>> collections = domo.pages.get_collections(page_id) |
| 242 | + >>> print(collections) |
| 243 | + [{'id': 1234321, 'title': 'Collection', 'description': '', |
| 244 | + 'cardIds': []}] |
| 245 | + >>> collection_id = collections[0]['id'] |
| 246 | + >>> domo.pages.update_collection(page_id, collection_id, |
| 247 | + description='description', |
| 248 | + cardIds=[54321, 13579]) |
| 249 | + >>> print(domo.pages.get_collections(page_id)) |
| 250 | + [{'id': 1234321, 'title': 'Collection', |
| 251 | + 'description': 'description', 'cardIds': [54321, 13579]}] |
| 252 | +
|
| 253 | + # Using **kwargs: |
| 254 | + >>> collections = domo.pages.get_collections(page_id) |
| 255 | + >>> collections[0]['description'] = 'Description' |
| 256 | + >>> domo.pages.update_collection(page_id, **collections[0]) |
| 257 | +
|
| 258 | + :Parameters: |
| 259 | + - `page_id`: ID of the page the collection is on |
| 260 | + - `collection_id`: ID of the collection. Can also be provided |
| 261 | + by supplying `id` to **kwargs. This allows for calling |
| 262 | + get_collections, updating one of the returned collections, |
| 263 | + then passing it to update_collection. |
| 264 | + - `title`: (optional) update the title |
| 265 | + - `description`: (optional) update the description |
| 266 | + - `cardIds`: (optional) update cards in the collection |
| 267 | +
|
| 268 | + :Returns: |
| 269 | + - A dict representing the collection |
| 270 | + """ |
| 271 | + |
| 272 | + self._validate_params(kwargs, COLLECTION_UPDATE_KWARGS) |
| 273 | + if collection_id is None and 'id' not in kwargs: |
| 274 | + raise TypeError("update() missing required argument: " |
| 275 | + "'collection_id'") |
| 276 | + elif 'id' in kwargs: |
| 277 | + if collection_id is not None and collection_id != kwargs['id']: |
| 278 | + raise ValueError('ambiguous collection ID - collection_id and' |
| 279 | + ' id both supplied but do not match') |
| 280 | + collection_id = kwargs['id'] |
| 281 | + del kwargs['id'] |
| 282 | + |
| 283 | + url = '{base}/{page_id}/collections/{collection_id}'.format( |
| 284 | + base=URL_BASE, page_id=page_id, collection_id=collection_id) |
| 285 | + return self._update(url, |
| 286 | + HTTPMethod.PUT, |
| 287 | + requests.codes.NO_CONTENT, |
| 288 | + kwargs, |
| 289 | + COLLECTION_DESC) |
| 290 | + |
| 291 | + def delete_collection(self, page_id, collection_id): |
| 292 | + """Delete a collection from a page. |
| 293 | +
|
| 294 | + :Parameters: |
| 295 | + - `page_id`: ID of the page the collection is on |
| 296 | + - `collection_id`: ID of the collection to delete |
| 297 | + """ |
| 298 | + url = '{base}/{page_id}/collections/{collection_id}'.format( |
| 299 | + base=URL_BASE, page_id=page_id, collection_id=collection_id) |
| 300 | + return self._delete(url, COLLECTION_DESC) |
0 commit comments