You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Jun 15, 2021. It is now read-only.
Get release name from par2 file. Agan, needs someone to intergrate it as I'm not up to the task.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""A native python implementation of the par2 file format.
This is only intended to be able to read packets in par2, not execute
repair, verify, or create new par2 files.
Found on GitHubGist made some mods for python 3."""
import struct
PACKET_HEADER = ("<"
"8s" # MAGIC: PAR2\x00PKT
"Q" # unsigned 64bit length of entire packet in bytes
"16s" # md5 of entire packet except first 3 fields
"16s" # 'setid'; hash of the body of the main packet
"16s" # packet type
)
FILE_DESCRIPTION_PACKET = ("<64s" # PACKET_HEADER
"16s" # fileid, hash of [hash16k, length, name]
"16s" # hashfull; hash of the whole file (which?)
"16s" # hash16k; hash of the first 16k of the file (which?)
"Q" # length of the file
)
class Header(object):
fmt = PACKET_HEADER
def __init__(self, par2file, offset=0):
self.raw = par2file[offset:offset+struct.calcsize(self.fmt)]
parts = struct.unpack(self.fmt, self.raw)
self.magic = parts[0]
self.length = parts[1]
self.hash = parts[2]
self.setid = parts[3]
self.type = parts[4]
def verify(self):
return self.magic == 'PAR2\x00PKT'
class UnknownPar2Packet(object):
fmt = PACKET_HEADER
def __init__(self, par2file, offset=0):
self.raw = par2file[offset:offset+struct.calcsize(self.fmt)]
self.header = Header(self.raw)
class FileDescriptionPacket(object):
header_type = b'PAR 2.0\x00FileDesc'
fmt = FILE_DESCRIPTION_PACKET
def __init__(self, par2file, offset=0):
name_start = offset+struct.calcsize(self.fmt)
self.raw = par2file[offset:name_start]
parts = struct.unpack(self.fmt, self.raw)
self.header = Header(parts[0])
packet = par2file[offset:offset+self.header.length]
self.fileid = parts[1]
self.file_hashfull = parts[2]
self.file_hash16k = parts[3]
self.file_length = parts[4]
self.name = packet[struct.calcsize(self.fmt):].strip(b'\x00')
class Par2File(object):
def __init__(self, obj_or_path):
if isinstance(obj_or_path, (str, bytes)):
with open(obj_or_path, "rb") as binary_file:
# Read the whole file at once
self.contents = binary_file.read()
else:
self.contents = obj_or_path.read()
self.packets = self.read_packets()
def read_packets(self):
offset = 0
filelen = len(self.contents)
packets = []
while offset < filelen:
header = Header(self.contents, offset)
if header.type == FileDescriptionPacket.header_type:
packets.append(FileDescriptionPacket(self.contents, offset))
else:
packets.append(UnknownPar2Packet(self.contents, offset))
offset += header.length
return packets
def filenames(self):
return [p.name for p in self.packets if isinstance(p, FileDescriptionPacket)]
pf = Par2File(".\p.par2") # get a test par2 and put it in same folder as this module
fn = pf.filenames()
print(fn[0])
The text was updated successfully, but these errors were encountered:
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Get release name from par2 file. Agan, needs someone to intergrate it as I'm not up to the task.
The text was updated successfully, but these errors were encountered: