Skip to content

Commit add5e60

Browse files
authored
Merge pull request #50 from seatable/add-table-api-columns
Add table api columns
2 parents f8f3e0c + 7e25d0e commit add5e60

File tree

4 files changed

+83
-37
lines changed

4 files changed

+83
-37
lines changed

demo/airtable_importer.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@
33
import sys
44
from seatable_api import Base, AirtableConvertor
55
from airtable_importer_settings import server_url, api_token, airtable_api_key, airtable_base_id, \
6-
table_names, links
6+
table_names, first_columns, links
77

88

99
def get_convertor():
1010
base = Base(api_token, server_url)
1111
base.auth()
1212
convertor = AirtableConvertor(
13-
airtable_api_key,
14-
airtable_base_id,
15-
base,
16-
table_names,
17-
links,
13+
airtable_api_key=airtable_api_key,
14+
airtable_base_id=airtable_base_id,
15+
base=base,
16+
table_names=table_names,
17+
first_columns=first_columns,
18+
links=links,
1819
)
1920
return convertor
2021

demo/airtable_importer_settings.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,20 @@
1414
airtable_base_id = 'airtable base id'
1515

1616

17-
# table names in Airtable [('name_of_table_1', 'name_of_table_2', '...'])
17+
# table names in Airtable ['name_of_table_1', 'name_of_table_2', '...']
1818
table_names = ['Design projects', 'Tasks', 'Clients']
1919

2020

21+
# first columns in Airtable [('table_name', 'first_column_name')]
22+
# The first column ensures the correct display of the links
23+
# if there are no links in all tables, you still have to provide "first_columns = []"
24+
first_columns = [
25+
('Design projects', 'Name'),
26+
('Tasks', 'Name'),
27+
('Clients', 'Name'),
28+
]
29+
30+
2131
# links in Airtable: [('table_name', 'column_name', 'other_table_name')]
2232
# if there are no links in all tables, you still have to provide "links = []"
2333
links = [

seatable_api/convert_airtable.py

Lines changed: 61 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
TEXT_COLOR = '#FFFFFF'
1717
DATE_FORMAT = '%Y-%m-%d'
1818
DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ'
19+
FIRST_COLUMN_TYPES = [
20+
ColumnTypes.TEXT, ColumnTypes.NUMBER, ColumnTypes.DATE, ColumnTypes.SINGLE_SELECT, ColumnTypes.AUTO_NUMBER]
1921
AIRTABLE_API_URL = 'https://api.airtable.com/v0/'
2022
ColumnTypes.BARCODE = 'barcode'
2123

@@ -221,21 +223,21 @@ def get_value_map(self, airtable_rows):
221223
value_map[column_name].append(value)
222224
return value_map
223225

224-
def get_select_data(self, select_list):
225-
return {'options': [{
226+
def get_select_options(self, select_list):
227+
return [{
226228
'name': str(value),
227229
'id': self.random_num_id(),
228230
'color': self.random_color(),
229231
'textColor': TEXT_COLOR,
230-
} for value in select_list]}
232+
} for value in select_list]
231233

232234
def get_column_data(self, link_map, table_name, column_name, column_type, values):
233235
column_data = None
234236
try:
235237
if column_type == ColumnTypes.BARCODE:
236238
column_type = ColumnTypes.TEXT
237-
# elif column_type == ColumnTypes.DATE and len(values[0]) == 24:
238-
# column_data = {'format': 'YYYY-MM-DD HH:mm'}
239+
elif column_type == ColumnTypes.DATE:
240+
column_data = {'format': 'YYYY-MM-DD'}
239241
elif column_type == ColumnTypes.LINK:
240242
other_table_name = link_map[table_name][column_name]
241243
column_data = {'other_table': other_table_name}
@@ -246,7 +248,7 @@ def get_column_data(self, link_map, table_name, column_name, column_type, values
246248
item = str(item)
247249
if item not in select_list:
248250
select_list.append(item)
249-
column_data = self.get_select_data(select_list)
251+
column_data = {'options': self.get_select_options(select_list)}
250252
elif column_type == ColumnTypes.COLLABORATOR:
251253
if isinstance(values[0], dict):
252254
column_type = ColumnTypes.SINGLE_SELECT
@@ -255,7 +257,7 @@ def get_column_data(self, link_map, table_name, column_name, column_type, values
255257
name = value['name']
256258
if name not in select_list:
257259
select_list.append(name)
258-
column_data = self.get_select_data(select_list)
260+
column_data = {'options': self.get_select_options(select_list)}
259261
elif isinstance(values[0], list):
260262
column_type = ColumnTypes.MULTIPLE_SELECT
261263
select_list = []
@@ -264,9 +266,9 @@ def get_column_data(self, link_map, table_name, column_name, column_type, values
264266
name = item['name']
265267
if name not in select_list:
266268
select_list.append(name)
267-
column_data = self.get_select_data(select_list)
269+
column_data = {'options': self.get_select_options(select_list)}
268270
except Exception as e:
269-
print('[Warning] get column data error:', e)
271+
print('[Warning] get', column_type.value, 'column data error:', e)
270272
return column_type, column_data
271273

272274
def get_column_type(self, values):
@@ -378,18 +380,10 @@ def get_select_value_map(self, columns, airtable_rows):
378380
select_value_map[column_name].append(item)
379381
return select_value_map
380382

381-
def get_select_options(self, select_list):
382-
return [{
383-
'name': str(value),
384-
'id': self.random_num_id(),
385-
'color': self.random_color(),
386-
'textColor': TEXT_COLOR,
387-
} for value in select_list]
388-
389383
def gen_select_columns(self, select_value_map):
390384
select_columns = []
391-
for column_name, values in select_value_map.items():
392-
options = self.get_select_options(values)
385+
for column_name, select_list in select_value_map.items():
386+
options = self.get_select_options(select_list)
393387
column = {
394388
'name': column_name,
395389
'options': options,
@@ -441,7 +435,7 @@ def list_all_rows(self, table_name):
441435

442436
class AirtableConvertor(object):
443437

444-
def __init__(self, airtable_api_key, airtable_base_id, base, table_names, links=[]):
438+
def __init__(self, airtable_api_key, airtable_base_id, base, table_names, first_columns=[], links=[]):
445439
"""
446440
airtable_api_key: str
447441
airtable_base_id: str
@@ -452,15 +446,18 @@ def __init__(self, airtable_api_key, airtable_base_id, base, table_names, links=
452446
self.airtable_api = AirtableAPI(airtable_api_key, airtable_base_id)
453447
self.base = base
454448
self.table_names = table_names
449+
self.first_columns = first_columns
455450
self.links = links
456451
self.columns_parser = ColumnsParser()
457452
self.rows_convertor = RowsConvertor()
458453
self.links_convertor = LinksConvertor()
454+
self.get_first_column_map()
459455
self.get_link_map()
460456

461457
def convert_metadata(self):
462-
self.convert_tables()
463458
self.get_airtable_row_map(is_demo=True)
459+
self.get_airtable_column_map()
460+
self.convert_tables()
464461
self.convert_columns()
465462
self.convert_rows(is_demo=True)
466463
self.convert_links(is_demo=True)
@@ -478,20 +475,38 @@ def convert_tables(self):
478475
for table_name in self.table_names:
479476
table = self.table_map.get(table_name)
480477
if not table:
481-
self.add_table(table_name)
482-
print('[Info] Added table [ %s ]' % table_name)
478+
airtable_columns = self.airtable_column_map[table_name]
479+
first_column_name = self.first_column_map.get(table_name) or \
480+
airtable_columns[0]['name']
481+
columns = []
482+
for column in airtable_columns:
483+
if column['type'] == ColumnTypes.LINK:
484+
continue
485+
item = {
486+
'column_name': column['name'],
487+
'column_type': column['type'].value,
488+
'column_data': column['data'],
489+
}
490+
if column['name'] == first_column_name:
491+
if column['type'] not in FIRST_COLUMN_TYPES:
492+
item['column_type'] = ColumnTypes.TEXT.value
493+
item['column_data'] = None
494+
columns.insert(0, item)
495+
else:
496+
columns.append(item)
497+
self.add_table(table_name, columns)
498+
print(
499+
'[Info] Added table [ %s ] with %s columns' % (table_name, len(columns)))
483500
print('[Info] Success\n')
484501
time.sleep(1)
485502

486503
def convert_columns(self):
487504
print('[Info] Convert columns')
488505
self.get_table_map()
489506
for table_name in self.table_names:
490-
airtable_rows = self.airtable_row_map[table_name]
491-
columns = self.columns_parser.parse(
492-
self.link_map, table_name, airtable_rows)
507+
airtable_columns = self.airtable_column_map[table_name]
493508
table = self.table_map.get(table_name)
494-
for column in columns:
509+
for column in airtable_columns:
495510
column_name = column['name']
496511
exists_column = table.get(column_name)
497512
if not exists_column:
@@ -560,6 +575,14 @@ def convert_select_columns(self):
560575
print('[Info] Success\n')
561576
time.sleep(1)
562577

578+
def get_first_column_map(self):
579+
self.first_column_map = {}
580+
for column in self.first_columns:
581+
table_name = column[0]
582+
column_name = column[1]
583+
self.first_column_map[table_name] = column_name
584+
return self.first_column_map
585+
563586
def get_link_map(self):
564587
self.link_map = {}
565588
for link in self.links:
@@ -583,6 +606,15 @@ def get_airtable_row_map(self, is_demo=False):
583606
print('[Info] Success\n')
584607
return self.airtable_row_map
585608

609+
def get_airtable_column_map(self):
610+
self.airtable_column_map = {}
611+
for table_name in self.table_names:
612+
airtable_rows = self.airtable_row_map[table_name]
613+
columns = self.columns_parser.parse(
614+
self.link_map, table_name, airtable_rows)
615+
self.airtable_column_map[table_name] = columns
616+
return self.airtable_column_map
617+
586618
def get_table_map(self):
587619
self.table_map = {}
588620
self.column_map = {}
@@ -598,8 +630,8 @@ def get_table_map(self):
598630
time.sleep(0.1)
599631
return self.table_map
600632

601-
def add_table(self, table_name):
602-
table = self.base.add_table(table_name)
633+
def add_table(self, table_name, columns):
634+
table = self.base.add_table(table_name, columns=columns)
603635
time.sleep(0.1)
604636
return table
605637

seatable_api/main.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,16 +185,19 @@ def get_metadata(self):
185185
data = parse_response(response)
186186
return data.get('metadata')
187187

188-
def add_table(self, table_name, lang='en'):
188+
def add_table(self, table_name, lang='en', columns=[]):
189189
"""
190190
:param table_name: str
191191
:param lang: str, currently 'en' for English, and 'zh-cn' for Chinese
192+
:param columns: list
192193
"""
193194
url = self._table_server_url()
194195
json_data = {
195196
'table_name': table_name,
196197
'lang': lang,
197198
}
199+
if columns:
200+
json_data['columns'] = columns
198201
response = requests.post(url, json=json_data, headers=self.headers, timeout=self.timeout)
199202
return parse_response(response)
200203

0 commit comments

Comments
 (0)