Skip to content

Instantly share code, notes, and snippets.

@kcleong
Created November 11, 2022 14:40
Show Gist options
  • Save kcleong/610e11d876caf38622850c22d2639f6e to your computer and use it in GitHub Desktop.
Save kcleong/610e11d876caf38622850c22d2639f6e to your computer and use it in GitHub Desktop.
Example script to get ikea article numbers from a kitchen plan
"""
Example output:
41x: 60205664 | METOD | grijs | 200 cm | Kitchen cabinets
38x: 80338413 | BAGGANÄS | zwart | 143 mm | Knobs and handles
24x: 40205599 | METOD | zwart | 8 cm | Kitchen cabinets
19x: 70338418 | BAGGANÄS | grijs | 143 mm | Knobs and handles
18x: 40327505 | FÖRBÄTTRA | wit | 220x8 cm | Kitchen fronts
8x: 00455161 | ÄLMAREN | Kitchen taps, sinks and sink accessories
6x: 20317852 | LILLVIKEN | grijs | Kitchen taps, sinks and sink accessories
6x: 00380590 | UTRUSTA | grijs | Kitchen fixed interiors
5x: 60411720 | ANRÄTTA | grijs | Cooking Appliances
5x: 70213569 | METOD | wit | 60x60x80 cm | Kitchen cabinets
5x: 50467883 | SMAKLIG | zwart | 59 cm | Cooking Appliances
4x: 90213573 | UTRUSTA | wit | 60x60 cm | Kitchen fixed interiors
4x: 60499954 | TINAD | wit | 210/79 l | Cooling Appliances
4x: 10311539 | LILLVIKEN | grijs | Kitchen taps, sinks and sink accessories
4x: 90311540 | LILLVIKEN | grijs | Kitchen taps, sinks and sink accessories
4x: 00518192 | VÅGLIG | Appliances Accessories
4x: 90250259 | NYTTIG TUB 150 | grijs | Appliances Accessories
4x: 80398058 | HÅLLBAR | grijs | 10 l | Sorting solutions
3x: 30221458 | METOD | grijs | 60 cm | Kitchen cabinets
3x: 40475572 | RENGÖRA | 60 cm | Dish Care Appliances
3x: 90421336 | NYTTIG FIL 120 | groen | 2 st. | Appliances Accessories
3x: 10389142 | UTDRAG | grijs | 60 cm | Cooking Appliances
2x: 40368770 | MATÄLSKARE | grijs | Cooking Appliances
2x: 10411765 | ANRÄTTA | grijs | Cooking Appliances
2x: 50462480 | UTRUSTA | wit | Kitchen fixed interiors
2x: 80433882 | HÅLLBAR | grijs | 10 l | Kitchen accessories
2x: 80422869 | HÅLLBAR | wit | 60 cm | Kitchen fixed interiors
1x: 40368765 | MATÄLSKARE | grijs | Cooking Appliances
1x: 30475233 | AXSTAD | blauw | 45x80 cm | Kitchen fronts
1x: 80524882 | UTRUSTA | 110 ° | Kitchen fixed interiors
1x: 00401955 | NYTTIG FIL 500 | zwart | 2 st. | Appliances Accessories
1x: 70389139 | UNDERVERK | grijs | 60 cm | Cooking Appliances
1x: 20204647 | UTRUSTA | grijs | 95 ° | Kitchen fixed interiors
1x: 20205543 | METOD | zwart | 60x60x80 cm | Kitchen cabinets
1x: 50215475 | METOD | wit | 80x60x80 cm | Kitchen cabinets
1x: 90475616 | RENODLAD | 60 cm | Dish Care Appliances
"""
from collections import Counter
from dataclasses import dataclass
from typing import Dict
import ikea_api
import requests
KITCHEN_URL = 'https://byme-ikea-prod.s3.eu-west-1.amazonaws.com/data/homebymeProjects/19E27F6B-470C-49CD-AB9A-221613A0A12F/19E27F6B-470C-49CD-AB9A-221613A0A12F.BMPROJ'
@dataclass
class IkeaProduct:
data: Dict
def __str__(self):
values = (
self.id,
self.name,
self.color,
self.data.get("itemMeasureReferenceText"),
self.type_name,
self.product_area_name,
)
return ' | '.join([
value for value in values if value
])
def __hash__(self) -> int:
return hash(self.id)
@property
def id(self):
return self.data['itemNo']
@property
def name(self):
return self.data['name']
@property
def type_name(self):
return self.data.get('type_name')
@property
def color(self):
for color in self.data.get('colors', []):
return color['name']
@property
def product_area_name(self):
return self.data['businessStructure']['productRangeAreaName']
@property
def is_kitchen_front(self):
raise NotImplementedError()
class KitchenDrawerExample:
def __init__(self, url):
self.url = url
self.api_constants = ikea_api.Constants(country="nl", language="nl")
def run(self):
response = requests.get(self.url)
response.raise_for_status()
kitchen_json = response.json()
article_numbers = list(self.recursively_get_article_number(kitchen_json))
products = [
item for item in map(self.get_product, article_numbers) if item
]
for product, count in Counter(products).most_common():
print(f'{count}x: {product}')
@classmethod
def recursively_get_article_number(cls, values):
if isinstance(values, dict):
for key, value in values.items():
yield from cls.recursively_get_article_number(value)
elif isinstance(values, list) or isinstance(values, tuple):
for child_value in values:
yield from cls.recursively_get_article_number(child_value)
elif isinstance(values, str) and values.startswith('ART-'):
yield values
def ikea_search(self, value):
search = ikea_api.Search(self.api_constants)
endpoint = search.search(value)
return ikea_api.run(endpoint)
def get_product(self, product_id):
product_id = product_id.replace('ART-', '').replace('-NL', '')
search_results = self.ikea_search(product_id)
search_response = search_results.get('searchResultPage')
product_items = search_response.get('products', {}).get('main', {}).get('items', [])
for product_item in product_items:
product_data = product_item.get('product')
if not product_data:
continue
product = IkeaProduct(data=product_data)
if product.id != product_id:
continue
return product
example = KitchenDrawerExample(KITCHEN_URL)
example.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment