def load_from_file(f): try: print 'GOT HERE' puzzle = puz.load(f.read()) pcnum = puzzle.clue_numbering() psolution = '' if puzzle.solution_state == puz.SolutionState.Unlocked: psolution = puzzle.solution print psolution puzobj = { 'height': pcnum.height, 'width': pcnum.width, 'size': pcnum.height * pcnum.width, 'grid': pcnum.grid, 'clues': { 'across': pcnum.across, 'down': pcnum.down }, 'markup': puzzle.markup().get_markup_squares(), 'solution': psolution } uid = hash(json.dumps(puzobj, sort_keys=True)) puzobj['uid'] = str(uid) return puzobj except: print "Unexpected error:", sys.exc_info()[0]
def load_from_file(f): try: print 'GOT HERE' puzzle = puz.load(f.read()) pcnum = puzzle.clue_numbering() psolution = '' if puzzle.solution_state==puz.SolutionState.Unlocked: psolution = puzzle.solution print psolution puzobj = {'height': pcnum.height, 'width': pcnum.width, 'size': pcnum.height*pcnum.width, 'grid': pcnum.grid, 'clues': { 'across': pcnum.across, 'down': pcnum.down }, 'markup': puzzle.markup().get_markup_squares(), 'solution': psolution } uid = hash(json.dumps(puzobj, sort_keys=True)) puzobj['uid'] = str(uid) return puzobj except: print "Unexpected error:", sys.exc_info()[0]
def initialize(puzdata): global puzzle global clues global numbering global row_strs global marked_cells puzzle = puz.load(puzdata) clues = puzzle.clue_numbering() numbering = [[0] * puzzle.width for _ in range(puzzle.height)] for clue in clues.across + clues.down: x, y = pos(clue['cell']) numbering[y][x] = clue['num'] row_strs = [] for row in range(puzzle.height): cell = row * puzzle.width row = puzzle.fill[cell:cell + puzzle.width] row_str = ''.join(row.replace("-", " ").replace(".", "#")) row_strs.append(row_str) marked_cells = [[False] * puzzle.width for _ in range(puzzle.height)] for marked_cell in puzzle.markup().get_markup_squares(): x, y = pos(marked_cell) marked_cells[y][x] = True
def impPUZdata(file_contents, publisher): pz = puz.load(file_contents) p = xwcore.Puzzle.fromPUZ(pz) if publisher: p.publisher = publisher try: setter = User.objects.get(username=p.author) except Exception, e: setter = User(username=p.author, puzzle_pref=PuzzleType.objects.get(type='US'), user_type=UserType.objects.get(type='Setter'), joined=date.today()) setter.save()
def from_puz(request): t = get_template('puzzle.html') if request.POST.has_key("puzurl"): puz_handle = urllib.urlopen(request.POST["puzurl"]) puz_data = puz_handle.read() else: puz_data = request.FILES["puzfile"].read() p = puz.load(puz_data) pz = Puzzle.fromPUZ(p) html = t.render(RequestContext(request, {'puzzle': pz})) return HttpResponse(html)
async def import_puz(data_in,link,url): data={"across":{}, "down":{}} #puzzle = f.read('beans.puz') # link='../src/beans.puz' p = puz.load(data_in) numbering = p.clue_numbering() # print(numbering.across) # print('GRID') # print([p.width,p.height]) # print([numbering.width,numbering.height]) # print ('Across') for clue in numbering.across: answer = ''.join( p.solution[clue['cell'] + i] for i in range(clue['len'])) #print (clue['num'], clue['clue'], '-', answer) # print (clue) row = clue['cell'] // (numbering.width-1) col = clue['cell'] % numbering.width data["across"][str(clue['num'])] = {"clue":clue['clue'],"answer":answer.lower(),"row":row,"col":col} for clue in numbering.down: answer = ''.join( p.solution[clue['cell'] + i * numbering.width] for i in range(clue['len'])) #print (clue['num'], clue['clue'], '-', answer) # print (clue) row = clue['cell'] // (numbering.width-1) col = clue['cell'] % numbering.width data["down"][str(clue['num'])] = {"clue":clue['clue'],"answer":answer.lower(),"row":row,"col":col} # print(data["across"]) # print("=================================================") # print(data["down"]) final = { "import_id":uuid.uuid4().hex, "title":p.title, "author":p.author, "copyright":p.copyright, "copyright_link":url, "data":data, "difficulty":2, "country":"US", "link":link } await save_crossword(final) print("==================SAVED===============================")
def handle_direct_download(link): record = {} filename = '' headers = {'User-Agent': 'Automatt'} if 'drive.google.com/file' in link: google_id = link.split('/')[5] link = 'https://drive.google.com/uc?export=download&id=' + google_id elif 'dropbox.com' in link: link = link.split('?')[0] + '?dl=1' res = requests.get(link, headers=headers) res.raise_for_status() if link.split('?')[0].endswith('.puz') or link.split('?')[0].endswith('.jpz'): filename = link.split('/')[-1].split('?')[0] filename = urllib.parse.unquote(filename) elif res.headers.get('Content-Disposition', ''): cd = res.headers.get('Content-Disposition') filename = re.findall('filename=(.+)', cd)[0].split(';')[0].strip('"') if filename.endswith('.puz'): try: p = puz.load(res.content) print('Saving puz as {}'.format(filename)) p.save(filename) record['puzfile'] = filename except: raise Exception('Apparently malformed puzzle file at', link) elif filename.endswith('.jpz'): with open(filename, 'wb') as f: f.write(res.content) record['puzfile'] = filename return record
def parse_puz(contents, filename): rebus_shorthands = list("⚷⚳♇♆⛢♄♃♂♁♀☿♹♸♷♶♵♴♳⅘⅗⅖⅕♚♛♜♝♞♟⚅⚄⚃⚂⚁⚀♣♦♥♠+&%$@?*zyxwvutsrqponmlkjihgfedcba0987654321") try: puzobj = puz.load(contents) puzzle = crossword.from_puz(puzobj) except puz.PuzzleFormatError as e: emsg = e.message if "<html>" in contents.decode('utf-8').lower(): emsg += " (looks like html)" raise xdfile.PuzzleParseError(emsg) grid_dict = dict(list(zip(string.ascii_uppercase, string.ascii_uppercase))) xd = xdfile.xdfile('', filename) xd.set_header("Author", puzobj.author) xd.set_header("Copyright", puzobj.copyright) xd.set_header("Notes", puzobj.notes) xd.set_header("Postscript", "".join(x for x in puzobj.postscript if ord(x) >= ord(' '))) xd.set_header("Preamble", puzobj.preamble) xd.set_header("Title", puzobj.title) used_rebuses = {} # [puz_rebus_gridvalue_as_string] -> our_rebus_gridvalue rebus = {} # [our_rebus_gridvalue] -> full_cell r = puzobj.rebus() if r.has_rebus(): grbs = puzobj.extensions[b"GRBS"] if sum(x for x in grbs if x != 0) > 0: # check for an actual rebus for pair in puzobj.extensions[b"RTBL"].decode("cp1252").split(";"): pair = pair.strip() if not pair: continue key, value = pair.split(":") rebuskey = rebus_shorthands.pop() used_rebuses[key] = rebuskey rebus[rebuskey] = decode(value) rebustr = xdfile.REBUS_SEP.join([("%s=%s" % (k, v)) for k, v in sorted(rebus.items())]) xd.set_header("Rebus", rebustr) for r, row in enumerate(puzzle): rowstr = "" for c, cell in enumerate(row): if puzzle.block is None and cell.solution == '.': rowstr += xdfile.BLOCK_CHAR elif cell.solution == puzzle.block: rowstr += xdfile.BLOCK_CHAR elif cell.solution == ':': rowstr += xdfile.OPEN_CHAR elif cell == puzzle.empty: rowstr += xdfile.UNKNOWN_CHAR else: n = r * puzobj.width + c reb = puzobj.rebus() if reb.has_rebus() and n in reb.get_rebus_squares(): ch = str(reb.table[n] - 1) rowstr += used_rebuses[ch] cell.solution = rebus[used_rebuses[ch]] else: ch = cell.solution if ch not in grid_dict: if ch in rebus_shorthands: cellch = ch rebus_shorthands.remove(ch) warn("%s: unknown grid character '%s', assuming rebus of itself" % (filename, ch)) else: cellch = rebus_shorthands.pop() warn("%s: unknown grid character '%s', assuming rebus (as '%s')" % (filename, ch, cellch)) xd.set_header("Rebus", xd.get_header("Rebus") + " %s=%s" % (cellch, ch)) grid_dict[ch] = cellch rowstr += grid_dict[ch] xd.grid.append(rowstr) assert xd.size() == (puzzle.width, puzzle.height), "non-matching grid sizes" # clues answers = {} for posdir, posnum, answer in xd.iteranswers(): answers[posdir[0] + str(posnum)] = answer try: for number, clue in puzzle.clues.across(): cluenum = "A" + str(number) if cluenum not in answers: raise xdfile.IncompletePuzzleParse(xd, "Clue number doesn't match grid: " + cluenum) xd.clues.append((("A", number), decode(clue), answers.get(cluenum, ""))) # xd.append_clue_break() for number, clue in puzzle.clues.down(): cluenum = "D" + str(number) if cluenum not in answers: raise xdfile.IncompletePuzzleParse(xd, "Clue doesn't match grid: " + cluenum) xd.clues.append((("D", number), decode(clue), answers.get(cluenum, ""))) except KeyError as e: raise xdfile.IncompletePuzzleParse(xd, "Clue doesn't match grid: " + str(e)) return xd
def parse_puz(contents, filename): rebus_shorthands = list( "⚷⚳♇♆⛢♄♃♂♁♀☿♹♸♷♶♵♴♳⅘⅗⅖⅕♚♛♜♝♞♟⚅⚄⚃⚂⚁⚀♣♦♥♠+&%$@?*zyxwvutsrqponmlkjihgfedcba0987654321" ) try: puzobj = puz.load(contents) puzzle = crossword.from_puz(puzobj) except puz.PuzzleFormatError as e: emsg = e.message if "<html>" in contents.decode('utf-8').lower(): emsg += " (looks like html)" raise xdfile.PuzzleParseError(emsg) grid_dict = dict(list(zip(string.ascii_uppercase, string.ascii_uppercase))) xd = xdfile.xdfile('', filename) xd.set_header("Author", puzobj.author) xd.set_header("Copyright", puzobj.copyright) xd.set_header("Notes", puzobj.notes) xd.set_header("Postscript", "".join(x for x in puzobj.postscript if ord(x) >= ord(' '))) xd.set_header("Preamble", puzobj.preamble) xd.set_header("Title", puzobj.title) used_rebuses = {} # [puz_rebus_gridvalue_as_string] -> our_rebus_gridvalue rebus = {} # [our_rebus_gridvalue] -> full_cell r = puzobj.rebus() if r.has_rebus(): grbs = puzobj.extensions[b"GRBS"] if sum(x for x in grbs if x != 0) > 0: # check for an actual rebus for pair in puzobj.extensions[b"RTBL"].decode("cp1252").split(";"): pair = pair.strip() if not pair: continue key, value = pair.split(":") rebuskey = rebus_shorthands.pop() used_rebuses[key] = rebuskey rebus[rebuskey] = decode(value) rebustr = xdfile.REBUS_SEP.join([ ("%s=%s" % (k, v)) for k, v in sorted(rebus.items()) ]) xd.set_header("Rebus", rebustr) for r, row in enumerate(puzzle): rowstr = "" for c, cell in enumerate(row): if puzzle.block is None and cell.solution == '.': rowstr += xdfile.BLOCK_CHAR elif cell.solution == puzzle.block: rowstr += xdfile.BLOCK_CHAR elif cell.solution == ':': rowstr += xdfile.OPEN_CHAR elif cell == puzzle.empty: rowstr += xdfile.UNKNOWN_CHAR else: n = r * puzobj.width + c reb = puzobj.rebus() if reb.has_rebus() and n in reb.get_rebus_squares(): ch = str(reb.table[n] - 1) rowstr += used_rebuses[ch] cell.solution = rebus[used_rebuses[ch]] else: ch = cell.solution if ch not in grid_dict: if ch in rebus_shorthands: cellch = ch rebus_shorthands.remove(ch) warn( "%s: unknown grid character '%s', assuming rebus of itself" % (filename, ch)) else: cellch = rebus_shorthands.pop() warn( "%s: unknown grid character '%s', assuming rebus (as '%s')" % (filename, ch, cellch)) xd.set_header( "Rebus", xd.get_header("Rebus") + " %s=%s" % (cellch, ch)) grid_dict[ch] = cellch rowstr += grid_dict[ch] xd.grid.append(rowstr) assert xd.size() == (puzzle.width, puzzle.height), "non-matching grid sizes" # clues answers = {} for posdir, posnum, answer in xd.iteranswers(): answers[posdir[0] + str(posnum)] = answer try: for number, clue in puzzle.clues.across(): cluenum = "A" + str(number) if cluenum not in answers: raise xdfile.IncompletePuzzleParse( xd, "Clue number doesn't match grid: " + cluenum) xd.clues.append( (("A", number), decode(clue), answers.get(cluenum, ""))) # xd.append_clue_break() for number, clue in puzzle.clues.down(): cluenum = "D" + str(number) if cluenum not in answers: raise xdfile.IncompletePuzzleParse( xd, "Clue doesn't match grid: " + cluenum) xd.clues.append( (("D", number), decode(clue), answers.get(cluenum, ""))) except KeyError as e: raise xdfile.IncompletePuzzleParse( xd, "Clue doesn't match grid: " + str(e)) return xd
def _load_data(self, game_str): """ Process the board string the board string. 1. Determine index of board start 2. Determine n 3. Create board and boxes """ p = puz.load(game_str) print p.__dict__.keys() # Get basic info self.width = p.width self.height = p.height self.title = p.title self.author = p.author # Get important vals fill = p.fill solution = p.solution clues = p.clues circ = p.extensions['GEXT'] if (p.extensions and 'GEXT' in p.extensions) else None idx = 0 clue_idx = 0 clue_count = 1 for row in range(self.height): new_row = [] for col in range(self.width): # Get box info is_blank = fill[idx] == BLANK is_circle = circ and circ[idx] == CIRCLE answer = None if is_blank else solution[idx] is_across = not is_blank and \ (col==0 or new_row[col-1].is_blank) is_down = not is_blank and \ (row==0 or self.board[row-1][col].is_blank) # Determine if box has number if is_across or is_down: number = clue_count if is_across: clue = Clue(clue=clues[clue_idx], start_position=(row,col), num=clue_count, clue_type=ACROSS_ID) self.clues.put(clue_count, ACROSS_ID, clue) clue_idx += 1 if is_down: clue = Clue(clue=clues[clue_idx], start_position=(row,col), num=clue_count, clue_type=DOWN_ID) self.clues.put(clue_count, DOWN_ID, clue) clue_idx += 1 clue_count += 1 else: number = None # Create and append box box = Box(answer=answer, is_blank=is_blank, number=number, is_circle=is_circle) new_row.append(box) idx += 1 self.board.append(new_row)
def parse_puz(contents): puz_object = puz.load(contents) puzzle = crossword.from_puz(puz_object) grid_dict = dict(zip(string.uppercase, string.uppercase)) xd = xdfile.xdfile() md = dict([ (hdr_renames.get(k.lower(), k), v) for k, v in puzzle.meta() if v ]) if " / " in md.get("author", ""): author, editor = md.get("author").split(" / ") editor = editor.strip() author = author.strip() author = author.lstrip("By ") editor = editor.lstrip("Edited by ") md["author"] = author md["editor"] = editor if "Washington Post" in md.get("copyright", ""): a = md["author"] if " - " in a: datestr, rest = a.split(" - ") md["date"] = reparse_date(datestr) if "By " in rest: md["title"], rest = rest.split(" By ") else: md["title"], rest = rest.split(" by ", 1) if "Edited by " in rest: md["author"], md["editor"] = rest.split(", Edited by ") elif "edited by " in rest: md["author"], md["editor"] = rest.split(", edited by ") else: md["author"] = rest md["copyright"] = md["copyright"].lstrip("Copyright") for k, v in sorted(md.items(), key=lambda x: hdr_order.index(x[0])): if v: k = k[0].upper() + k[1:].lower() v = decode(v.strip()) v = v.replace(u"© ", "") xd.headers.append((k, v)) answers = { } clue_num = 1 for r, row in enumerate(puzzle): rowstr = "" for c, cell in enumerate(row): if puzzle.block is None and cell.solution == '.': rowstr += xdfile.BLOCK_CHAR elif puzzle.block == cell.solution: rowstr += xdfile.BLOCK_CHAR elif cell == puzzle.empty: rowstr += "." else: if cell.solution not in grid_dict: grid_dict[cell.solution] = rebus_shorthands.pop() rowstr += grid_dict[cell.solution] # compute number shown in box new_clue = False if is_block(puzzle, c-1, r): # across clue start j = 0 answer = "" while not is_block(puzzle, c+j, r): answer += puzzle[c+j, r].solution j += 1 if len(answer) > 1: new_clue = True answers["A"+str(clue_num)] = answer if is_block(puzzle, c, r-1): # down clue start j = 0 answer = "" while not is_block(puzzle, c, r+j): answer += puzzle[c, r+j].solution j += 1 if len(answer) > 1: new_clue = True answers["D"+str(clue_num)] = answer if new_clue: clue_num += 1 xd.grid.append(rowstr) for number, clue in puzzle.clues.across(): xd.clues.append((("A", number), decode(clue), answers["A"+str(number)])) for number, clue in puzzle.clues.down(): xd.clues.append((("D", number), decode(clue), answers["D"+str(number)])) return xd
def parse_puz(contents, filename): rebus_shorthands = list(u"♚♛♜♝♞♟⚅⚄⚃⚂⚁⚀♣♦♥♠Фθиλπφя+&%$@?*zyxwvutsrqponmlkjihgfedcba0987654321") if not filename.lower().endswith('.puz'): return puz_object = puz.load(contents) puzzle = crossword.from_puz(puz_object) grid_dict = dict(zip(string.uppercase, string.uppercase)) xd = xdfile.xdfile() md = dict([ (k.lower(), v) for k, v in puzzle.meta() if v ]) author = md.get("creator", "") if " / " in author: author, editor = author.split(" / ") else: editor = "" author = author.strip() editor = editor.strip() for editsep in [ "edited by ", "ed. " ]: try: i = author.lower().index(editsep) if i == 0: editor = author[len(editsep):] author = editor.split(",")[1] elif i > 0: assert not editor editor = author[i+len(editsep):] author = author[:i] except: pass author = author.strip() editor = editor.strip() while author.lower().startswith("by "): author = author[3:] if author and author[-1] in ",.": author = author[:-1] md["creator"] = author md["editor"] = editor for k, v in sorted(md.items(), key=lambda x: hdr_order.index(x[0])): if v: k = k[0].upper() + k[1:].lower() v = decode(v.strip()) v = v.replace(u"©", "(c)") xd.headers.append((k, v)) answers = { } clue_num = 1 for r, row in enumerate(puzzle): rowstr = "" for c, cell in enumerate(row): if puzzle.block is None and cell.solution == '.': rowstr += xdfile.BLOCK_CHAR elif puzzle.block == cell.solution: rowstr += xdfile.BLOCK_CHAR elif cell == puzzle.empty: rowstr += "." else: if cell.solution not in grid_dict: grid_dict[cell.solution] = rebus_shorthands.pop() rowstr += grid_dict[cell.solution] # compute number shown in box new_clue = False if is_block(puzzle, c-1, r): # across clue start j = 0 answer = "" while not is_block(puzzle, c+j, r): answer += puzzle[c+j, r].solution j += 1 if len(answer) > 1: new_clue = True answers["A"+str(clue_num)] = answer if is_block(puzzle, c, r-1): # down clue start j = 0 answer = "" while not is_block(puzzle, c, r+j): answer += puzzle[c, r+j].solution j += 1 if len(answer) > 1: new_clue = True answers["D"+str(clue_num)] = answer if new_clue: clue_num += 1 xd.grid.append(rowstr) for number, clue in puzzle.clues.across(): xd.clues.append((("A", number), decode(clue), answers["A"+str(number)])) for number, clue in puzzle.clues.down(): xd.clues.append((("D", number), decode(clue), answers["D"+str(number)])) return xd