Created
May 17, 2020 18:33
-
-
Save migurski/912f1556a7c3f3db85ab839b53441b77 to your computer and use it in GitHub Desktop.
Generate Codenames board in Google Sheets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import json | |
import random | |
import copy | |
import argparse | |
import oauth2client.service_account | |
import apiclient.discovery | |
parser = argparse.ArgumentParser() | |
parser.add_argument('players') | |
parser.add_argument('judges') | |
parser.add_argument('--clear', action='store_const', const=True) | |
parser.add_argument('--redfirst', action='store_const', const=False, dest='bluefirst') | |
parser.add_argument('--bluefirst', action='store_const', const=True, dest='bluefirst') | |
args = parser.parse_args() | |
SCOPES = ['https://www.googleapis.com/auth/spreadsheets'] | |
WORDS = "Africa", "Agent", "Air", "Alien", "Alps", "Amazon", "Ambulance", "America", "Angel", "Antarctica", "Apple", "Arm", "Atlantis", "Australia", "Aztec", "Back", "Ball", "Band", "Bank", "Bar", "Bark", "Bat", "Battery", "Beach", "Bear", "Beat", "Bed", "Beijing", "Bell", "Belt", "Berlin", "Bermuda", "Berry", "Bill", "Block", "Board", "Bolt", "Bomb", "Bond", "Boom", "Boot", "Bottle", "Bow", "Box", "Bridge", "Brush", "Buck", "Buffalo", "Bug", "Bugle", "Button", "Calf", "Canada", "Cap", "Capital", "Car", "Card", "Carrot", "Casino", "Cast", "Cat", "Cell", "Centaur", "Center", "Chair", "Change", "Charge", "Check", "Chest", "Chick", "China", "Chocolate", "Church", "Circle", "Cliff", "Cloak", "Club", "Code", "Cold", "Comic", "Compound", "Concert", "Conductor", "Contract", "Cook", "Copper", "Cotton", "Court", "Cover", "Crane", "Crash", "Cricket", "Cross", "Crown", "Cycle", "Czech", "Dance", "Date", "Day", "Death", "Deck", "Degree", "Diamond", "Dice", "Dinosaur", "Disease", "Doctor", "Dog", "Draft", "Dragon", "Dress", "Drill", "Drop", "Duck", "Dwarf", "Eagle", "Egypt", "Embassy", "Engine", "England", "Europe", "Eye", "Face", "Fair", "Fall", "Fan", "Fence", "Field", "Fighter", "Figure", "File", "Film", "Fire", "Fish", "Flute", "Fly", "Foot", "Force", "Forest", "Fork", "France", "Game", "Gas", "Genius", "Germany", "Ghost", "Giant", "Glass", "Glove", "Gold", "Grace", "Grass", "Greece", "Green", "Ground", "Ham", "Hand", "Hawk", "Head", "Heart", "Helicopter", "Himalayas", "Hole", "Hollywood", "Honey", "Hood", "Hook", "Horn", "Horse", "Horseshoe", "Hospital", "Hotel", "Ice", "Ice Cream", "India", "Iron", "Ivory", "Jack", "Jam", "Jet", "Jupiter", "Kangaroo", "Ketchup", "Key", "Kid", "King", "Kiwi", "Knife", "Knight", "Lab", "Lap", "Laser", "Lawyer", "Lead", "Lemon", "Leprechaun", "Life", "Light", "Limousine", "Line", "Link", "Lion", "Litter", "Loch Ness", "Lock", "Log", "London", "Luck", "Mail", "Mammoth", "Maple", "Marble", "March", "Mass", "Match", "Mercury", "Mexico", "Microscope", "Millionaire", "Mine", "Mint", "Missile", "Model", "Mole", "Moon", "Moscow", "Mount", "Mouse", "Mouth", "Mug", "Nail", "Needle", "Net", "New York", "Night", "Ninja", "Note", "Novel", "Nurse", "Nut", "Octopus", "Oil", "Olive", "Olympus", "Opera", "Orange", "Organ", "Palm", "Pan", "Pants", "Paper", "Parachute", "Park", "Part", "Pass", "Paste", "Penguin", "Phoenix", "Piano", "Pie", "Pilot", "Pin", "Pipe", "Pirate", "Pistol", "Pit", "Pitch", "Plane", "Plastic", "Plate", "Platypus", "Play", "Plot", "Point", "Poison", "Pole", "Police", "Pool", "Port", "Post", "Pound", "Press", "Princess", "Pumpkin", "Pupil", "Pyramid", "Queen", "Rabbit", "Racket", "Ray", "Revolution", "Ring", "Robin", "Robot", "Rock", "Rome", "Root", "Rose", "Roulette", "Round", "Row", "Ruler", "Satellite", "Saturn", "Scale", "School", "Scientist", "Scorpion", "Screen", "Scuba Diver", "Seal", "Server", "Shadow", "Shakespeare", "Shark", "Ship", "Shoe", "Shop", "Shot", "Sink", "Skyscraper", "Slip", "Slug", "Smuggler", "Snow", "Snowman", "Sock", "Soldier", "Soul", "Sound", "Space", "Spell", "Spider", "Spike", "Spine", "Spot", "Spring", "Spy", "Square", "Stadium", "Staff", "Star", "State", "Stick", "Stock", "Straw", "Stream", "Strike", "String", "Sub", "Suit", "Superhero", "Swing", "Switch", "Table", "Tablet", "Tag", "Tail", "Tap", "Teacher", "Telescope", "Temple", "Theater", "Thief", "Thumb", "Tick", "Tie", "Time", "Tokyo", "Tooth", "Torch", "Tower", "Track", "Train", "Triangle", "Trip", "Trunk", "Tube", "Turkey", "Undertaker", "Unicorn", "Vacuum", "Van", "Vet", "Wake", "Wall", "War", "Washer", "Washington", "Watch", "Water", "Wave", "Web", "Well", "Whale", "Whip", "Wind", "Witch", "Worm", "Yard" | |
FIELDS = ','.join([ | |
"userEnteredValue", | |
"userEnteredFormat.backgroundColor", | |
"userEnteredFormat.textFormat.foregroundColor", | |
"userEnteredFormat.textFormat.fontSize", | |
]) | |
def make_service(cred_data): | |
''' Create a Google service account instance from credentials object. | |
''' | |
creds = oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_dict(cred_data, SCOPES) | |
return apiclient.discovery.build('sheets', 'v4', credentials=creds) | |
with open('code-words-277404-828ee38406e7.json') as file: | |
cred_data = json.load(file) | |
service = make_service(cred_data) | |
def combined(format, text_format): | |
result = copy.deepcopy(format) | |
result['textFormat'].update(**text_format) | |
return result | |
def celldata(string, format): | |
return { | |
"userEnteredValue": {'stringValue': string}, | |
"userEnteredFormat": format | |
} | |
white = {"red": 1, "green": 1, "blue": 1, "alpha": 1} | |
black = {"red": 0, "green": 0, "blue": 0, "alpha": 1} | |
red = {"red": 0xD0/0xFF, "green": 0x02/0xFF, "blue": 0x1B/0xFF, "alpha": 1} | |
blue = {"red": 0x4A/0xFF, "green": 0x90/0xFF, "blue": 0xE2/0xFF, "alpha": 1} | |
gray = {"red": 0xD8/0xFF, "green": 0xD8/0xFF, "blue": 0xD8/0xFF, "alpha": 1} | |
text_word = {"fontSize": 14} | |
text_emoji = {"fontSize": 36} | |
colors_nothing = {"backgroundColor": white, "textFormat": {"foregroundColor": black}} | |
colors_assassin = {"backgroundColor": black, "textFormat": {"foregroundColor": white}} | |
colors_redspy = {"backgroundColor": red, "textFormat": {"foregroundColor": white}} | |
colors_bluespy = {"backgroundColor": blue, "textFormat": {"foregroundColor": white}} | |
colors_bystander = {"backgroundColor": gray, "textFormat": {"foregroundColor": black}} | |
if args.clear: | |
formats = [colors_bystander] * 25 | |
words = [''] * 25 | |
else: | |
formats = [colors_bluespy if args.bluefirst else colors_redspy] | |
formats += [colors_redspy] * 8 + [colors_bluespy] * 8 | |
formats += [colors_assassin] + [colors_bystander] * 7 | |
random.shuffle(formats) | |
words = random.choices(WORDS, k=25) | |
resp1 = service.spreadsheets().get(spreadsheetId=args.players).execute() | |
players_sheet = resp1['sheets'][0]['properties']['sheetId'] | |
resp2 = service.spreadsheets().get(spreadsheetId=args.judges).execute() | |
judges_sheet = resp2['sheets'][0]['properties']['sheetId'] | |
body1 = { | |
'requests': [ | |
{ | |
'updateCells': { | |
'rows': | |
[ | |
{ | |
'values': [ | |
celldata(words[index], combined(colors_nothing, text_word)) | |
for index in range(offset, len(words), 5) | |
] | |
} | |
for offset in range(5) | |
], | |
"fields": FIELDS, | |
"range": { | |
"sheetId": players_sheet, | |
"startRowIndex": 0, | |
"endRowIndex": 5, | |
"startColumnIndex": 0, | |
"endColumnIndex": 5 | |
} | |
} | |
}, | |
] | |
} | |
if args.bluefirst: | |
first_color, second_color = colors_bluespy, colors_redspy | |
else: | |
first_color, second_color = colors_redspy, colors_bluespy | |
body2 = { | |
'requests': [ | |
{ | |
'updateCells': { | |
'rows': | |
[ | |
{ | |
'values': [ | |
celldata(words[index], combined(formats[index], text_word)) | |
for index in range(offset, len(words), 5) | |
] | |
} | |
for offset in range(5) | |
], | |
"fields": FIELDS, | |
"range": { | |
"sheetId": judges_sheet, | |
"startRowIndex": 0, | |
"endRowIndex": 5, | |
"startColumnIndex": 0, | |
"endColumnIndex": 5 | |
} | |
} | |
}, | |
{ | |
'updateCells': { | |
'rows': | |
[ | |
#{ | |
# 'values': [ | |
# celldata('', combined(colors_nothing, text_word)) | |
# for i in range(5) | |
# ] | |
#}, | |
{ | |
'values': [ | |
celldata("\ud83d\udd75\ud83c\udfff", combined(first_color, text_emoji)), | |
celldata("\ud83d\udd75\ud83c\udffb\u200d\u2640\ufe0f", combined(second_color, text_emoji)), | |
celldata("\ud83e\udd26\ud83c\udffc\u200d\u2642\ufe0f", combined(colors_bystander, text_emoji)), | |
celldata("\ud83e\udd26\ud83c\udffe\u200d\u2640\ufe0f", combined(colors_bystander, text_emoji)), | |
celldata("\u2620\ufe0f", combined(colors_assassin, text_emoji)), | |
] | |
}, | |
], | |
"fields": FIELDS, | |
"range": { | |
"sheetId": judges_sheet, | |
"startRowIndex": 6, | |
"endRowIndex": 7, | |
"startColumnIndex": 0, | |
"endColumnIndex": 5 | |
} | |
} | |
}, | |
] | |
} | |
print(service.spreadsheets().batchUpdate(spreadsheetId=args.players, body=body1).execute()) | |
print(service.spreadsheets().batchUpdate(spreadsheetId=args.judges, body=body2).execute()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment