alexdej / puzpy

Python library for reading and writing across lite crossword puzzle .puz files.
MIT License
112 stars 32 forks source link

Creating brand new .puz files #12

Open ricksladkey opened 7 years ago

ricksladkey commented 7 years ago

Alternate title of this issue: calling Puzzle.save without having called Puzzle.load

I may be the first consumer of puzpy to try to create a .puz file from scratch using the provided API. The idea is to create a "blank" new Puzzle object and fill in the puzzle metatadata (title, rows, cols, etc.) the puzzle solution and the puzzle clues. My specific use case is converting another puzzle format to .puz format.

In attempting this, I ran into a few problems:

  1. The default value of the preamble attribute cannot be written out
  2. There is no provided API to populate rebus table or rebus solution
  3. The rebus helper produces invalid .puz files because it forces the inclusion of the (unnecessary) RebuFill extension and decodes/encodes it incorrectly
  4. Round-trip testing of puzzles with rebus entries does not exercise the encoding of any of the rebus extension sections because loading a .puz file with rebus extensions does not cause the rebus helper to be added

These are relatively easy issues to fix and I would be willing to try submit a pull request to address these issues, assuming you agree in spirit with the issues I described.

alexdej commented 7 years ago

Hi Rick thanks for this report! This should be a supported case for this lib but you're right that it wasn't well tested. We'd welcome a pull request to address any or all of the issues you found.

kberg commented 6 years ago

I'm having new problems as well. Using Python 2.7, trying to save the new puzzle, I get

np.save(output_file)

File "/Users/kberg/git/puzpy/puz.py", line 226, in save f.write(self.tobytes()) File "/Users/kberg/git/puzpy/puz.py", line 275, in tobytes return s.tobytes() File "/Users/kberg/git/puzpy/puz.py", line 451, in tobytes return b''.join(self.data) UnicodeDecodeError: 'ascii' codec can't decode byte 0xd6 in position 0: ordinal not in range(128)

This is most likely the second entry in the PuzzleBuffer list, generated by this line:

    s.pack(HEADER_FORMAT,
           self.global_cksum(), ACROSSDOWN.encode(ENCODING),
           self.header_cksum(), self.magic_cksum(),
           self.fileversion, self.unk1, self.scrambled_cksum,
           self.unk2, self.width, self.height,
           len(self.clues), self.puzzletype, self.solution_state)

Looking, looking.

kberg commented 6 years ago

Yeah, apparently b''.join(self.data), and more specifically, this value of 0xd6 comes from the global checksum (which is 59094, and 59094 % 256 is 214, which is 0xd6.)

kberg commented 6 years ago

Oh my goodness, it's because I had a preamble. PLS IGNORE.

mixographer commented 2 years ago

I was just trying to get a NYT puzzle and I had a similar error. I think the Times was using 'en-dashes' instead of regular dashes and I got :

UnicodeEncodeError: 'latin-1' codec can't encode character '\u2013' from 'text_cksum'

Don't know if it's related, it was the NYT puzzle 9/22/2021. Maybe I should start a new issue, but maybe it's in the code I'm using not in puz?

alexdej commented 2 years ago

@mixographer could you post a snippet of code where you see the issue?

alexdej commented 2 weeks ago

This might be fixed. I just downloaded the nytimes 9/22/21 puzzle and had no trouble loading it and saving it.

nytimes-20210922.zip

mixographer commented 2 weeks ago

Thanks! I'll try to think what I was trying to do at the time and check it out.