Ejemplo n.º 1
0
def sync(
    all_sheets: bool = False,
    output_folder: str = "_players",
    sheet_app_id: str = typer.Option(envvar="GOOGLE_SHEET_APP_ID", default=""),
    sheet_name: str = typer.Option(envvar="GOOGLE_SHEET_NAME",
                                   default="Sheet1"),
):
    typer.secho("sync-players", fg="yellow")
    try:
        sa = SpreadsheetApp(from_env=True)
    except AttributeError:
        print_expected_env_variables()
        raise typer.Exit()

    try:
        spreadsheet = sa.open_by_id(sheet_app_id)
    except Exception:
        typer.echo(
            f"We can't find that 'sheet_app_id'.\n"
            f"Please double check that 'GOOGLE_SHEET_APP_ID' is set. (Currently set to: '{sheet_app_id}')"
        )
        raise typer.Exit()

    if all_sheets:
        sheets = spreadsheet.get_sheets()
    else:
        try:
            sheets = [spreadsheet.get_sheet_by_name(sheet_name)]
        except Exception:
            typer.echo(
                f"We can't find that 'sheet_name' aka the tab.\n"
                f"Please double check that 'SHEET_NAME' is set. (Currently set to: '{sheet_name}')"
            )
            raise typer.Exit()

    for sheet in sheets:
        data_range = sheet.get_data_range()

        table = Table(data_range, backgrounds=True)

        metadata = {}
        for item in table:
            for key in item.header:
                value = item.get_field_value(key)
                metadata[key] = value

            player = Player(**metadata)

            if not Path(output_folder).exists():
                Path(output_folder).mkdir()

            player_filename = Path(output_folder, f"{player.slug}.md")
            if player_filename.exists():
                post = frontmatter.loads(player_filename.read_text())
            else:
                post = frontmatter.loads("")

            post.metadata.update(player.dict(by_alias=True))

            player_filename.write_text(frontmatter.dumps(post))
Ejemplo n.º 2
0
 def conseguir_valores(self):
     try:
         spreadsheet = SpreadsheetApp(JSON_FILE).open_by_id(self.id)
         sheet = spreadsheet.get_sheet_by_name(self.name)
         data_range = sheet.get_data_range()
         self.registros = data_range.get_values()
     except:
         print("No conecta con la sheet")
Ejemplo n.º 3
0
def readingfromgoogle(serviceaccountfile, googleid, sheetname):
    spreadsheet = SpreadsheetApp(serviceaccountfile).open_by_id(googleid)
    sheet = spreadsheet.get_sheet_by_name(sheetname) #access the wanted tab
    data_range = sheet.get_data_range()                 #extract range where the data is
    values = data_range.get_values()                    #get values
    values = pd.DataFrame(data = values[8:], columns = values[7]) #put the data into pandas dataframe
    excel = False
    return values, excel
Ejemplo n.º 4
0
def main():
    sa = SpreadsheetApp('secret.json')
    spreadsheet = sa.open_by_id(SPREADSHEET_ID)
    sheet = spreadsheet.get_sheet_by_name(SHEET_NAME)

    current_plot_cell = sheet.get_range_from_a1(a1_notification='A2')
    current_plot_cell.set_value(int(get_plot_count()))

    last_updated_cell = sheet.get_range_from_a1(a1_notification='B2')
    last_updated_cell.set_value(datetime.now().isoformat())
Ejemplo n.º 5
0
class TestSpreadsheetApp:

    http_sheets_mocks = mock_google_sheets_responses(['create.json', 'get_sheets.json'])
    client = SpreadsheetApp(http=http_sheets_mocks)

    def test_client(self):
        assert self.client.sheet_service is not None

    def test_create_spreadsheet(self):
        spreadsheet = self.client.create("test_spreadsheet")
        assert isinstance(spreadsheet, Spreadsheet)
Ejemplo n.º 6
0
def cli(ctx, gsheets_credentials, linkedin_username, linkedin_password,
        spreadsheet_id):
    ctx.ensure_object(dict)
    logging.basicConfig(level=logging.INFO)
    sa = SpreadsheetApp(gsheets_credentials)
    spreadsheet = sa.open_by_id(spreadsheet_id=spreadsheet_id)
    salesnav = Table.get_table_from_sheet(spreadsheet=spreadsheet,
                                          sheet_name='salesnav')
    li = LinkedIn()
    li.login(username=linkedin_username, password=linkedin_password)
    ctx.obj['li'] = li
    ctx.obj['salesnav'] = salesnav
Ejemplo n.º 7
0
class TestSpreadsheetAppInstances:

    http_sheets_mocks = mock_spreadsheet_instance()
    client = SpreadsheetApp(http=http_sheets_mocks)
    spreadsheet = client.open_by_id(spreadsheet_id='')

    def test_spreadsheet_instance(self):
        assert isinstance(self.spreadsheet, Spreadsheet)

    def test_sheet_instance(self):
        sheet = self.spreadsheet.get_sheet_by_name('people')
        assert isinstance(sheet, Sheet)
Ejemplo n.º 8
0
class TestTableDatetimeField:
    http_mocks = mock_google_sheets_responses([
        'table_get_sheets.json', 'table_values_datetime.json',
        'table_values_datetime.json'
    ])
    sa = SpreadsheetApp(http=http_mocks)
    sheet = sa.open_by_id('whatever').get_sheet_by_name('Sheet1')
    data_range = sheet.get_range_from_a1("A1:B3")
    table = Table(full_range=data_range)

    def test_table_size(self):
        assert len(self.table) == 2
        assert len(self.table.header) == 2

    def test_first_row(self):
        row = self.table[0]
        birthday = row.get_field_value("birthday")
        assert row.get_field_value("name") == "foo"
        assert isinstance(birthday, datetime.datetime)
        assert birthday.year == 2021
        assert birthday.month == 5
        assert birthday.day == 1

    def test_second_row(self):
        row = self.table[1]
        birthday = row.get_field_value("birthday")
        assert row.get_field_value("name") == "bar"
        assert isinstance(birthday, datetime.datetime)
        assert birthday.year == 2021
        assert birthday.month == 9
        assert birthday.day == 30

    def test_set_datetime_values(self):
        for row in self.table:
            birthday = row.get_field_value("birthday")
            new_birthday = birthday + datetime.timedelta(days=1)
            row.set_field_value("birthday", new_birthday)

        # we then check the request put in the batch
        first_request = self.table.batches[0]
        first_value = first_request["updateCells"]["rows"][0]["values"][0][
            "userEnteredValue"]["numberValue"]
        assert first_value == 44318.0

        second_request = self.table.batches[1]
        second_value = second_request["updateCells"]["rows"][0]["values"][0][
            "userEnteredValue"]["numberValue"]
        assert second_value == 44470.0

        for batch in self.table.batches:
            assert batch["updateCells"]["rows"][0]["values"][0][
                "userEnteredFormat"]["numberFormat"]["type"] == "DATE_TIME"
Ejemplo n.º 9
0
def test(ctx):
    credentials = ctx.obj['credentials']
    spreadsheet_id = ctx.obj['spreadsheet_id']
    logger.info('test called with credentials %s', credentials)
    sa = SpreadsheetApp(credentials)
    spreadsheet = sa.open_by_id(spreadsheet_id=spreadsheet_id)
    table = Table.get_table_from_sheet(spreadsheet=spreadsheet,
                                       sheet_name='salesnav')
    logger.info('header is %s', table.header)
    for row in table:
        logger.info('row %s', row.values)
        logger.info('name %s', row.get_field_value('first_name'))
        logger.info('invited_at %s',
                    dt_deserialize(row.get_field_value('invited_at')))
Ejemplo n.º 10
0
 def cargar_datos(self):
     try:
         spreadsheet = SpreadsheetApp(JSON_FILE).open_by_id(self.id)
         sheet = spreadsheet.get_sheet_by_name(self.nombre)
         data_range = sheet.get_data_range()
         self.registros = data_range.get_values()
     except:
         print("No conecta con la sheet")
     for num in range(1, len(self.registros)):
         deno = self.registros[num][0]
         id_d = self.registros[num][1]
         nom = self.registros[num][2]
         ini = self.registros[num][3]
         fin = self.registros[num][4]
         dat = dato(deno, id_d, nom, ini, fin)
         self.datos.append(dat)
Ejemplo n.º 11
0
def connect_to_sheet(
    requested_spreadsheet_id: str,
    requested_sheet_name: str = constants.sheets.Default,
) -> model.Sheet:
    """Connect to the specified Google Sheet and return the requested sheet (default is "Sheet1")."""
    # extract a logger
    logger = configure.configure_logging()
    # use sheetfu to load the spreadsheet with configuration in environment variables
    sa = SpreadsheetApp(from_env=True)
    # get the spreadsheet by its identifier and then extract the specific
    # worksheet from it, with Google Sheets making the default worksheet "Sheet1"
    spreadsheet = sa.open_by_id(requested_spreadsheet_id)
    sheet = spreadsheet.get_sheet_by_name(requested_sheet_name)
    # DEBUG: display details about the sheet
    logger.debug(type(sheet))
    logger.debug(sheet)
    return sheet
Ejemplo n.º 12
0
class TestItem:
    http_mocks = mock_google_sheets_responses([
        'table_get_sheets.json',
        'table_check_data_range.json',
        'table_values.json',
        'table_values.json',
        'table_notes.json',
        'table_backgrounds.json',
        'table_font_colors.json'
    ])
    sa = SpreadsheetApp(http=http_mocks)
    table_range = sa.open_by_id('whatever').get_sheet_by_name('Sheet1').get_data_range()
    table = Table(
        full_range=table_range,
        notes=True,
        backgrounds=True,
        font_colors=True
    )
    item = Item(
        parent_table=table,
        row_index=0,
        header=['name', 'surname'],
        values=['john', 'doe'],
        notes=['note name', 'note surname'],
        backgrounds=['#ffffff', '#fff000'],
        font_colors=['#000fff', '#000000']
    )

    def test_get_field_value(self):
        assert self.item.get_field_value('name') == 'john'
        assert self.item.get_field_value('surname') == 'doe'

    def test_get_field_note(self):
        assert self.item.get_field_note('name') == 'note name'
        assert self.item.get_field_note('surname') == 'note surname'

    def test_get_field_background(self):
        assert self.item.get_field_background('name') == '#ffffff'
        assert self.item.get_field_background('surname') == '#fff000'

    def test_get_field_font_colors(self):
        assert self.item.get_field_font_color('name') == '#000fff'
        assert self.item.get_field_font_color('surname') == '#000000'
Ejemplo n.º 13
0
        spreadsheet.create_sheets(sheet_name)
    except:
        pass

    sheet = spreadsheet.get_sheet_by_name(sheet_name)

    data_range = sheet.get_range(row=1,
                                 column=1,
                                 number_of_row=len(myoutput),
                                 number_of_column=(len(myoutput[0])))

    data_range.set_values(myoutput)


# Google Sheet
sa = SpreadsheetApp('secret.json')
spreadsheet = sa.open_by_id('12BDEIWO_85BN6egolnUqIpHQ6yRPyx35VnccSCQD2Ag')

# Full data set
output = []
output = set_header()

for slot in schedule.all(order_by=['datestamp']):
    output.append(list(slot.values()))
publish_data(output, 'FULL')

# By division data
for division in get_divisions():

    #if division is not "Upper Farm": continue
Ejemplo n.º 14
0
 def test_open_by_url(self):
     http_sheets_mocks = mock_spreadsheet_instance()
     spreadsheet = SpreadsheetApp(http=http_sheets_mocks).open_by_url(self.sheet_url)
     assert isinstance(spreadsheet, Spreadsheet)
     assert spreadsheet.id == "10egVLKcTR0AQuQdZKp-MgGgErUdzDI_nnZHAWTfXK3I"
Ejemplo n.º 15
0
def main(sheet_app_id, output_folder, sheet_name):

    output_folder = Path(output_folder)

    try:
        sa = SpreadsheetApp(from_env=True)
    except AttributeError:
        print_expected_env_variables()
        sys.exit(1)

    try:
        spreadsheet = sa.open_by_id(sheet_app_id)
    except Exception:
        click.echo(
            f"We can't find that 'sheet_app_id'. Please double check that 'LFK_GOOGLE_SHEET_APP_ID' is set. (Currently set to: '{sheet_app_id}')"
        )
        sys.exit(1)

    try:
        sheet = spreadsheet.get_sheet_by_name(sheet_name)
    except Exception:
        click.echo(
            f"We can't find that 'sheet_name' aka the tab. Please double check that 'LFK_SHEET_NAME' is set. (Currently set to: '{sheet_name}')"
        )
        sys.exit(1)

    # returns the sheet range that contains data values.
    data_range = sheet.get_data_range()

    table = Table(data_range, backgrounds=True)

    for item in table:
        name = item.get_field_value("name")
        address = item.get_field_value("address")
        slug = slugify(" ".join([name, address]))
        filename = f"{slug}.md"

        input_file = output_folder.joinpath(filename)
        if input_file.exists():
            post = frontmatter.load(input_file)
        else:
            post = frontmatter.loads("")

        place = {}

        # Our goal is to build a Place record without having to deal with
        # annoying errors if a field doesn't exist. We will still let you
        # know which field wasn't there though.

        if SHEETS_BOOL_FIELDS:
            for var in SHEETS_BOOL_FIELDS:
                try:
                    place[var] = string_to_boolean(item.get_field_value(var))
                except ValueError:
                    click.echo(f"A column named '{var}' was expected, but not found.")

        if SHEETS_STRING_FIELDS:
            for var in SHEETS_STRING_FIELDS:
                try:
                    place[var] = item.get_field_value(var)
                except ValueError:
                    click.echo(f"A column named '{var}' was expected, but not found.")

        if SHEETS_URL_FIELDS:
            for var in SHEETS_URL_FIELDS:
                try:
                    place[var] = verify_http(item.get_field_value(var))
                except ValueError:
                    click.echo(f"A column named '{var}' was expected, but not found.")

        post.content = item.get_field_value("notes")

        post.metadata.update(place)

        input_file.write_text(frontmatter.dumps(post))
Ejemplo n.º 16
0
 def test_one_line_range_instance(self):
     http_sheets_mocks = mock_spreadsheet_instance()
     sheet = SpreadsheetApp(http=http_sheets_mocks).open_by_id('some_id').get_sheet_by_name('people')
     sheet_range = sheet.get_range(row=1, column=1)
     assert isinstance(sheet_range, Range)
Ejemplo n.º 17
0
 def test_one_line_sheet_instance_different_case(self):
     http_sheets_mocks = mock_spreadsheet_instance()
     sheet = SpreadsheetApp(http=http_sheets_mocks).open_by_id('some_id').get_sheet_by_name('PeOpLe')
     assert isinstance(sheet, Sheet)
Ejemplo n.º 18
0
 def test_one_line_spreadsheet_instance(self):
     http_sheets_mocks = mock_spreadsheet_instance()
     spreadsheet = SpreadsheetApp(http=http_sheets_mocks).open_by_id('some_id')
     assert isinstance(spreadsheet, Spreadsheet)
Ejemplo n.º 19
0
def sync_places(sheet_app_id, output_folder, sheet_name):

    output_folder = Path(output_folder)

    try:
        sa = SpreadsheetApp(from_env=True)
    except AttributeError:
        print_expected_env_variables()
        sys.exit(1)

    try:
        spreadsheet = sa.open_by_id(sheet_app_id)
    except Exception:
        click.echo(
            f"We can't find that 'sheet_app_id'. Please double check that 'LFK_GOOGLE_SHEET_APP_ID' is set. (Currently set to: '{sheet_app_id}')"
        )
        sys.exit(1)

    try:
        sheet = spreadsheet.get_sheet_by_name(sheet_name)
    except Exception:
        click.echo(
            f"We can't find that 'sheet_name' aka the tab. Please double check that 'LFK_SHEET_NAME' is set. (Currently set to: '{sheet_name}')"
        )
        sys.exit(1)

    # returns the sheet range that contains data values.
    data_range = sheet.get_data_range()

    table = Table(data_range, backgrounds=True)

    for item in table:
        name = item.get_field_value("name")
        address = item.get_field_value("address")
        slug = slugify(" ".join([name, address]))
        filename = f"{slug}.md"

        input_file = output_folder.joinpath(filename)
        if input_file.exists():
            post = frontmatter.load(input_file)
        else:
            post = frontmatter.loads("")

        place = {}
        place["sitemap"] = False
        place["slug"] = slug

        # Our goal is to build a Place record without having to deal with
        # annoying errors if a field doesn't exist. We will still let you
        # know which field wasn't there though.

        if SHEETS_BOOL_FIELDS:
            for var in SHEETS_BOOL_FIELDS:
                try:
                    place[var] = string_to_boolean(item.get_field_value(var))
                except ValueError:
                    click.echo(
                        f"A column named '{var}' was expected, but not found.")

        if SHEETS_STRING_FIELDS:
            for var in SHEETS_STRING_FIELDS:
                try:
                    place[var] = item.get_field_value(var)
                except ValueError:
                    click.echo(
                        f"A column named '{var}' was expected, but not found.")

        if SHEETS_URL_FIELDS:
            for var in SHEETS_URL_FIELDS:
                try:
                    place[var] = verify_http(item.get_field_value(var))
                except ValueError:
                    click.echo(
                        f"A column named '{var}' was expected, but not found.")

        food_urls = []

        if "cuisine" in place and len(place["cuisine"]):
            place["cuisines"] = [
                cuisine.strip() for cuisine in place["cuisine"].split(",")
            ]
        else:
            place["cuisines"] = None

        if place["cuisines"] and len(place["cuisines"]):
            place["cuisine_slugs"] = [
                slugify(cuisine) for cuisine in place["cuisines"]
            ]
        else:
            place["cuisine_slugs"] = None

        if "neighborhood" in place and len(place["neighborhood"]):
            place["neighborhood_slug"] = slugify(place["neighborhood"])

        if "delivery_service_websites" in place and len(
                place["delivery_service_websites"]):
            food_urls.append({
                "name": "order online",
                "url": place["delivery_service_websites"]
            })

        if FOOD_SERVICE_URLS:
            for var in FOOD_SERVICE_URLS:
                try:
                    value = verify_http(item.get_field_value(var))
                    if len(value):
                        food_urls.append({
                            "name": FOOD_SERVICE_DICT.get(var),
                            "url": value
                        })
                except ValueError:
                    click.echo(
                        f"A column named '{var}' was expected, but not found.")

            place["food_urls"] = [
                food_url for food_url in food_urls if food_url
            ]

        post.content = item.get_field_value("notes")

        post.metadata.update(place)

        input_file.write_text(frontmatter.dumps(post))
Ejemplo n.º 20
0
def create():
    data = request.get_json()
    date = data['date']
    time = data['time']
    temperature = data['temperature']
    humility = data['humility']
    voltage = data['voltage']

    sheetname = 'Sheet1'
    file_name = date

    creds = False
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)

    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=8080)
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(creds.to_json())

    param = {'q': 'mimeType="application/vnd.google-apps.spreadsheet"'}
    service = build('drive', 'v3', credentials=creds)
    results = service.files().list(
        **param, pageSize=10,
        fields="nextPageToken, files(id, name)").execute()
    items = results.get('files', [])

    spreadsheet_app = SpreadsheetApp('secrets.json')
    sheet = None
    if items:
        for item in items:
            if item['name'] == file_name:
                sheet = spreadsheet_app.open_by_id(
                    item['id']).get_sheet_by_name(sheetname)

    if not sheet:
        sheet = spreadsheet_app.create(file_name, editor="<email>")
        selected_spread_sheet = spreadsheet_app.open_by_id(sheet.id)

        sheet = selected_spread_sheet.get_sheet_by_name(sheetname)
        sheet.get_range(1, 1).set_value('Date')
        sheet.get_range(1, 2).set_value('Time')
        sheet.get_range(1, 3).set_value('Temperature')
        sheet.get_range(1, 5).set_value('Voltage')

    last_row = sheet.get_data_range().coordinates.number_of_rows + 1

    sheet.get_range(last_row, 1).set_value(date)
    sheet.get_range(last_row, 2).set_value(time)
    sheet.get_range(last_row, 3).set_value(temperature)
    sheet.get_range(last_row, 4).set_value(humility)
    sheet.get_range(last_row, 5).set_value(voltage)

    resp = jsonify(success=True)

    return resp
Ejemplo n.º 21
0
from plaid import Client
from sheetfu import SpreadsheetApp

from . import accounts, db, events, settings, sheets

logger = logging.getLogger(__name__)

# Init Plaid client.
client = Client(client_id=settings.PLAID_CLIENT_ID,
                secret=settings.PLAID_SECRET,
                public_key=settings.PLAID_PUBLIC_KEY,
                environment=settings.PLAID_ENVIRONMENT)

# Init Sheetfu client and get spreadsheet.
sheet = (SpreadsheetApp(settings.SPREADSHEET_CREDS).open_by_id(
    spreadsheet_id=settings.SPREADSHEET_ID).get_sheet_by_name(
        settings.SHEET_NAME))

app = FastAPI()


def update():
    """
    This function updates the app's data by doing the following:
      - Get all account balances.
      - Push account data to google spreadsheet.
    """
    logger.info('~ getting account results')

    tokens = db.get_access_tokens()
    account_results = accounts.get_account_balances(client, tokens)
Ejemplo n.º 22
0
        env_vars = {k: os.environ.get(v) for k, v in env_vars.items() if v in os.environ}
        
    except KeyError:  
        print("A problem with one or more of the environment variables exists...EXITING")
        sys.exit()

# Create a dictionary subset of ENV_CONFIG for just the MySQL parameters
db_config = {k: env_vars[k] for k in env_vars.keys() & {'host', 'database', 'user', 'password'}}
print("COMPLETE")

# Add try block to handle case where SERVICE_ACCESS_FILE or SPREADSHEET_ID do not exist, or are incorrect?  
# Add a fileExists check for SERVICE_ACCESS_FILE ?
# Add HttpError if spreadsheet does not exist ?

print("Connecting to Spreadsheet..", end='.')
spreadsheet = SpreadsheetApp(env_vars.get('service_access_file')).open_by_id(env_vars.get('sheet_id'))
print("CONNECTED")

# If necessary to iterate through spreadsheet
#sheets = spreadsheet.get_sheets()
#for entries in sheets:print(entries)

# Deliberately hardcoding the Invoice sheet name
# Invoice Sheet
invoice_sheet = spreadsheet.get_sheet_by_name('Invoice')
invoice_sheet_range = invoice_sheet.get_data_range()
invoice_values = invoice_sheet_range.get_values()   # returns a 2d matrix of lists

# Faster than a slice (invoice_values[2:-1]).  It's necessary to remove the 3 header columns.
invoice_values.pop(0); invoice_values.pop(0); invoice_values.pop(0)
Ejemplo n.º 23
0
def sync_places(
        output_folder: str = "_places",
        sheet_app_id: str = typer.Argument(default="",
                                           envvar="LFK_GOOGLE_SHEET_APP_ID"),
        sheet_name: str = typer.Argument(default="", envvar="LFK_SHEET_NAME"),
):
    typer.secho("sync-places", fg="yellow")

    output_folder = Path(output_folder)
    if not output_folder.exists():
        output_folder.mkdir()

    cuisine_aliases = aliases_to_cuisine()

    aliases = load_aliases()
    try:
        unknown_cuisines = aliases["unknown-cuisines"][0]["aliases"]
    except:
        unknown_cuisines = None

    try:
        sa = SpreadsheetApp(from_env=True)
    except AttributeError:
        print_expected_env_variables()
        raise typer.Exit()

    try:
        spreadsheet = sa.open_by_id(sheet_app_id)
    except Exception:
        typer.echo(
            f"We can't find that 'sheet_app_id'. Please double check that 'LFK_GOOGLE_SHEET_APP_ID' is set. (Currently set to: '{sheet_app_id}')"
        )
        raise typer.Exit()

    try:
        sheet = spreadsheet.get_sheet_by_name(sheet_name)
    except Exception:
        typer.echo(
            f"We can't find that 'sheet_name' aka the tab. Please double check that 'LFK_SHEET_NAME' is set. (Currently set to: '{sheet_name}')"
        )
        raise typer.Exit()

    # returns the sheet range that contains data values.
    data_range = sheet.get_data_range()

    table = Table(data_range, backgrounds=True)

    for item in table:
        name = item.get_field_value("name")
        address = item.get_field_value("address")
        neighborhood = item.get_field_value("neighborhood")
        slug = slugify(" ".join([name, neighborhood or address]),
                       stopwords=STOPWORDS)
        filename = f"{slug}.md"

        input_file = output_folder.joinpath(filename)
        if input_file.exists():
            post = frontmatter.load(input_file)
        else:
            post = frontmatter.loads("")

        place = {}
        place["sitemap"] = False
        place["slug"] = slug

        # Our goal is to build a Place record without having to deal with
        # annoying errors if a field doesn't exist. We will still let you
        # know which field wasn't there though.

        if SHEETS_BOOL_FIELDS:
            for var in SHEETS_BOOL_FIELDS:
                try:
                    place[var] = string_to_boolean(item.get_field_value(var))
                except ValueError:
                    typer.echo(
                        f"A column named '{var}' was expected, but not found.")

        if SHEETS_STRING_FIELDS:
            for var in SHEETS_STRING_FIELDS:
                try:
                    place[var] = item.get_field_value(var)
                except ValueError:
                    typer.echo(
                        f"A column named '{var}' was expected, but not found.")

        if SHEETS_URL_FIELDS:
            for var in SHEETS_URL_FIELDS:
                try:
                    place[var] = verify_http(item.get_field_value(var))
                except ValueError:
                    typer.echo(
                        f"A column named '{var}' was expected, but not found.")

        food_urls = []

        if "cuisine" in place and len(place["cuisine"]):
            place["cuisines"] = [
                cuisine.strip() for cuisine in place["cuisine"].split(",")
            ]
            if unknown_cuisines:
                place["cuisines"] = [
                    cuisine for cuisine in place["cuisines"] if slugify(
                        cuisine, stopwords=STOPWORDS) not in unknown_cuisines
                ]

        else:
            place["cuisines"] = None

        if place["cuisines"] and len(place["cuisines"]):
            place["cuisine_slugs"] = []
            for cuisine in place["cuisines"]:
                cuisine_slug = slugify(cuisine, stopwords=STOPWORDS)
                place["cuisine_slugs"].append(cuisine_slug)
                if (cuisine_slug in cuisine_aliases
                        and cuisine_aliases[cuisine_slug]
                        not in place["cuisine_slugs"]):
                    place["cuisine_slugs"].append(
                        cuisine_aliases[cuisine_slug])

        else:
            place["cuisine_slugs"] = None

        if "neighborhood" in place and len(place["neighborhood"]):
            place["neighborhood_slug"] = slugify(place["neighborhood"],
                                                 stopwords=STOPWORDS)

        if "delivery_service_websites" in place and len(
                place["delivery_service_websites"]):
            food_urls.append({
                "name": "order online",
                "url": place["delivery_service_websites"]
            })

        if FOOD_SERVICE_URLS:
            for var in FOOD_SERVICE_URLS:
                try:
                    value = verify_http(item.get_field_value(var))
                    if len(value):
                        food_urls.append({
                            "name": FOOD_SERVICE_DICT.get(var),
                            "url": value
                        })
                except ValueError:
                    typer.echo(
                        f"A column named '{var}' was expected, but not found.")

            place["food_urls"] = [
                food_url for food_url in food_urls if food_url
            ]

        post.content = item.get_field_value("notes")

        post.metadata.update(place)

        typer.echo(dict(Place.validate(post.metadata)))

        input_file.write_text(frontmatter.dumps(post))