mirror of
https://github.com/dgelessus/python-rsrcfork.git
synced 2024-06-24 23:30:04 +00:00
Rename resource_type and resource_id attributes to type and id
The old names were chosen to avoid conflicts with Python's type and id builtins, but for attribute names this is not necessary.
This commit is contained in:
parent
f4c2717720
commit
c6337bdfbd
|
@ -56,7 +56,7 @@ Simple example
|
||||||
>>> rf
|
>>> rf
|
||||||
<rsrcfork.ResourceFile at 0x1046e6048, attributes ResourceFileAttrs.0, containing 4 resource types: [b'utxt', b'utf8', b'TEXT', b'drag']>
|
<rsrcfork.ResourceFile at 0x1046e6048, attributes ResourceFileAttrs.0, containing 4 resource types: [b'utxt', b'utf8', b'TEXT', b'drag']>
|
||||||
>>> rf[b"TEXT"]
|
>>> rf[b"TEXT"]
|
||||||
<rsrcfork.ResourceFile._LazyResourceMap at 0x10470ed30 containing one resource: rsrcfork.Resource(resource_type=b'TEXT', resource_id=256, name=None, attributes=ResourceAttrs.0, data=b'Here is some text')>
|
<rsrcfork.ResourceFile._LazyResourceMap at 0x10470ed30 containing one resource: rsrcfork.Resource(type=b'TEXT', id=256, name=None, attributes=ResourceAttrs.0, data=b'Here is some text')>
|
||||||
|
|
||||||
Automatic selection of data/resource fork
|
Automatic selection of data/resource fork
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -133,6 +133,7 @@ Version 1.2.1 (next version)
|
||||||
* Added a ``--sort`` command line option to output resources sorted by type and ID, instead of using the order stored in the file.
|
* Added a ``--sort`` command line option to output resources sorted by type and ID, instead of using the order stored in the file.
|
||||||
* Added a ``--group`` command line option to group resources in list format by type (the default), ID, or with no grouping.
|
* Added a ``--group`` command line option to group resources in list format by type (the default), ID, or with no grouping.
|
||||||
* Added a ``dump-text`` output format to the command line tool. This format is identical to ``dump``, but instead of a hex dump, it outputs the resource data as text. The data is decoded as MacRoman and classic Mac newlines (``\r``) are translated. This is useful for examining resources that contain mostly plain text.
|
* Added a ``dump-text`` output format to the command line tool. This format is identical to ``dump``, but instead of a hex dump, it outputs the resource data as text. The data is decoded as MacRoman and classic Mac newlines (``\r``) are translated. This is useful for examining resources that contain mostly plain text.
|
||||||
|
* Renamed the ``rsrcfork.Resource`` attributes ``resource_type`` and ``resource_id`` to ``type`` and ``id``, respectively. The old names have been deprecated and will be removed in the future, but are still supported for now.
|
||||||
* Changed ``--format=dump`` output to match ``hexdump -C``'s format - spacing has been adjusted, and multiple subsequent identical lines are collapsed into a single ``*``.
|
* Changed ``--format=dump`` output to match ``hexdump -C``'s format - spacing has been adjusted, and multiple subsequent identical lines are collapsed into a single ``*``.
|
||||||
|
|
||||||
Version 1.2.0
|
Version 1.2.0
|
||||||
|
|
|
@ -93,7 +93,7 @@ def _filter_resources(rf: api.ResourceFile, filters: typing.Sequence[str]) -> ty
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for res in resources.values():
|
for res in resources.values():
|
||||||
matching[res.resource_type, res.resource_id] = res
|
matching[res.type, res.id] = res
|
||||||
elif filter[0] == filter[-1] == "'":
|
elif filter[0] == filter[-1] == "'":
|
||||||
try:
|
try:
|
||||||
resources = rf[_bytes_unescape(filter[1:-1])]
|
resources = rf[_bytes_unescape(filter[1:-1])]
|
||||||
|
@ -101,7 +101,7 @@ def _filter_resources(rf: api.ResourceFile, filters: typing.Sequence[str]) -> ty
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for res in resources.values():
|
for res in resources.values():
|
||||||
matching[res.resource_type, res.resource_id] = res
|
matching[res.type, res.id] = res
|
||||||
else:
|
else:
|
||||||
pos = filter.find("'", 1)
|
pos = filter.find("'", 1)
|
||||||
if pos == -1:
|
if pos == -1:
|
||||||
|
@ -134,7 +134,7 @@ def _filter_resources(rf: api.ResourceFile, filters: typing.Sequence[str]) -> ty
|
||||||
|
|
||||||
for res in resources.values():
|
for res in resources.values():
|
||||||
if res.name == name:
|
if res.name == name:
|
||||||
matching[res.resource_type, res.resource_id] = res
|
matching[res.type, res.id] = res
|
||||||
break
|
break
|
||||||
elif ":" in resid:
|
elif ":" in resid:
|
||||||
if resid.count(":") > 1:
|
if resid.count(":") > 1:
|
||||||
|
@ -143,15 +143,15 @@ def _filter_resources(rf: api.ResourceFile, filters: typing.Sequence[str]) -> ty
|
||||||
start, end = int(start), int(end)
|
start, end = int(start), int(end)
|
||||||
|
|
||||||
for res in resources.values():
|
for res in resources.values():
|
||||||
if start <= res.resource_id <= end:
|
if start <= res.id <= end:
|
||||||
matching[res.resource_type, res.resource_id] = res
|
matching[res.type, res.id] = res
|
||||||
else:
|
else:
|
||||||
resid = int(resid)
|
resid = int(resid)
|
||||||
try:
|
try:
|
||||||
res = resources[resid]
|
res = resources[resid]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
continue
|
continue
|
||||||
matching[res.resource_type, res.resource_id] = res
|
matching[res.type, res.id] = res
|
||||||
|
|
||||||
return list(matching.values())
|
return list(matching.values())
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ def _translate_text(data: bytes) -> str:
|
||||||
return data.decode(_TEXT_ENCODING).replace("\r", "\n")
|
return data.decode(_TEXT_ENCODING).replace("\r", "\n")
|
||||||
|
|
||||||
def _describe_resource(res: api.Resource, *, include_type: bool, decompress: bool) -> str:
|
def _describe_resource(res: api.Resource, *, include_type: bool, decompress: bool) -> str:
|
||||||
id_desc_parts = [f"{res.resource_id}"]
|
id_desc_parts = [f"{res.id}"]
|
||||||
|
|
||||||
if res.name is not None:
|
if res.name is not None:
|
||||||
name = _bytes_escape(res.name, quote='"')
|
name = _bytes_escape(res.name, quote='"')
|
||||||
|
@ -214,7 +214,7 @@ def _describe_resource(res: api.Resource, *, include_type: bool, decompress: boo
|
||||||
|
|
||||||
desc = f"({id_desc}): {content_desc}"
|
desc = f"({id_desc}): {content_desc}"
|
||||||
if include_type:
|
if include_type:
|
||||||
restype = _bytes_escape(res.resource_type, quote="'")
|
restype = _bytes_escape(res.type, quote="'")
|
||||||
desc = f"'{restype}' {desc}"
|
desc = f"'{restype}' {desc}"
|
||||||
return desc
|
return desc
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ def _show_filtered_resources(resources: typing.Sequence[api.Resource], format: s
|
||||||
if None in attr_descs:
|
if None in attr_descs:
|
||||||
attr_descs[:] = [f"${res.attributes.value:02X}"]
|
attr_descs[:] = [f"${res.attributes.value:02X}"]
|
||||||
|
|
||||||
parts = [str(res.resource_id)]
|
parts = [str(res.id)]
|
||||||
|
|
||||||
if res.name is not None:
|
if res.name is not None:
|
||||||
name = _bytes_escape(res.name, quote='"')
|
name = _bytes_escape(res.name, quote='"')
|
||||||
|
@ -335,7 +335,7 @@ def _show_filtered_resources(resources: typing.Sequence[api.Resource], format: s
|
||||||
|
|
||||||
parts += attr_descs
|
parts += attr_descs
|
||||||
|
|
||||||
restype = _bytes_escape(res.resource_type, quote="'")
|
restype = _bytes_escape(res.type, quote="'")
|
||||||
print(f"data '{restype}' ({', '.join(parts)}{attrs_comment}) {{")
|
print(f"data '{restype}' ({', '.join(parts)}{attrs_comment}) {{")
|
||||||
|
|
||||||
for i in range(0, len(data), 16):
|
for i in range(0, len(data), 16):
|
||||||
|
@ -380,7 +380,7 @@ def _list_resource_file(rf: api.ResourceFile, *, sort: bool, group: str, decompr
|
||||||
for reses in rf.values():
|
for reses in rf.values():
|
||||||
all_resources.extend(reses.values())
|
all_resources.extend(reses.values())
|
||||||
if sort:
|
if sort:
|
||||||
all_resources.sort(key=lambda res: (res.resource_type, res.resource_id))
|
all_resources.sort(key=lambda res: (res.type, res.id))
|
||||||
print(f"{len(all_resources)} resources:")
|
print(f"{len(all_resources)} resources:")
|
||||||
for res in all_resources:
|
for res in all_resources:
|
||||||
print(_describe_resource(res, include_type=True, decompress=decompress))
|
print(_describe_resource(res, include_type=True, decompress=decompress))
|
||||||
|
@ -402,13 +402,13 @@ def _list_resource_file(rf: api.ResourceFile, *, sort: bool, group: str, decompr
|
||||||
all_resources = []
|
all_resources = []
|
||||||
for reses in rf.values():
|
for reses in rf.values():
|
||||||
all_resources.extend(reses.values())
|
all_resources.extend(reses.values())
|
||||||
all_resources.sort(key=lambda res: res.resource_id)
|
all_resources.sort(key=lambda res: res.id)
|
||||||
resources_by_id = {resid: list(reses) for resid, reses in itertools.groupby(all_resources, key=lambda res: res.resource_id)}
|
resources_by_id = {resid: list(reses) for resid, reses in itertools.groupby(all_resources, key=lambda res: res.id)}
|
||||||
print(f"{len(resources_by_id)} resource IDs:")
|
print(f"{len(resources_by_id)} resource IDs:")
|
||||||
for resid, resources in resources_by_id.items():
|
for resid, resources in resources_by_id.items():
|
||||||
print(f"{resid}: {len(resources)} resources:")
|
print(f"{resid}: {len(resources)} resources:")
|
||||||
if sort:
|
if sort:
|
||||||
resources.sort(key=lambda res: res.resource_type)
|
resources.sort(key=lambda res: res.type)
|
||||||
for res in resources:
|
for res in resources:
|
||||||
print(_describe_resource(res, include_type=True, decompress=decompress))
|
print(_describe_resource(res, include_type=True, decompress=decompress))
|
||||||
print()
|
print()
|
||||||
|
@ -444,7 +444,7 @@ def main():
|
||||||
resources.extend(reses.values())
|
resources.extend(reses.values())
|
||||||
|
|
||||||
if ns.sort:
|
if ns.sort:
|
||||||
resources.sort(key=lambda res: (res.resource_type, res.resource_id))
|
resources.sort(key=lambda res: (res.type, res.id))
|
||||||
|
|
||||||
_show_filtered_resources(resources, format=ns.format, decompress=ns.decompress)
|
_show_filtered_resources(resources, format=ns.format, decompress=ns.decompress)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -96,15 +96,15 @@ class ResourceAttrs(enum.Flag):
|
||||||
class Resource(object):
|
class Resource(object):
|
||||||
"""A single resource from a resource file."""
|
"""A single resource from a resource file."""
|
||||||
|
|
||||||
__slots__ = ("resource_type", "resource_id", "name", "attributes", "data_raw", "_data_decompressed")
|
__slots__ = ("type", "id", "name", "attributes", "data_raw", "_data_decompressed")
|
||||||
|
|
||||||
def __init__(self, resource_type: bytes, resource_id: int, name: typing.Optional[bytes], attributes: ResourceAttrs, data_raw: bytes):
|
def __init__(self, resource_type: bytes, resource_id: int, name: typing.Optional[bytes], attributes: ResourceAttrs, data_raw: bytes):
|
||||||
"""Create a new resource with the given type code, ID, name, attributes, and data."""
|
"""Create a new resource with the given type code, ID, name, attributes, and data."""
|
||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.resource_type: bytes = resource_type
|
self.type: bytes = resource_type
|
||||||
self.resource_id: int = resource_id
|
self.id: int = resource_id
|
||||||
self.name: typing.Optional[bytes] = name
|
self.name: typing.Optional[bytes] = name
|
||||||
self.attributes: ResourceAttrs = attributes
|
self.attributes: ResourceAttrs = attributes
|
||||||
self.data_raw: bytes = data_raw
|
self.data_raw: bytes = data_raw
|
||||||
|
@ -126,7 +126,17 @@ class Resource(object):
|
||||||
if not decompress_ok:
|
if not decompress_ok:
|
||||||
data_repr = f"<decompression failed - compressed data: {data_repr}>"
|
data_repr = f"<decompression failed - compressed data: {data_repr}>"
|
||||||
|
|
||||||
return f"{type(self).__module__}.{type(self).__qualname__}(resource_type={self.resource_type}, resource_id={self.resource_id}, name={self.name}, attributes={self.attributes}, data={data_repr})"
|
return f"{type(self).__module__}.{type(self).__qualname__}(type={self.type}, id={self.id}, name={self.name}, attributes={self.attributes}, data={data_repr})"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def resource_type(self) -> bytes:
|
||||||
|
warnings.warn(DeprecationWarning("The resource_type attribute has been deprecated and will be removed in a future version. Please use the type attribute instead."))
|
||||||
|
return self.type
|
||||||
|
|
||||||
|
@property
|
||||||
|
def resource_id(self) -> int:
|
||||||
|
warnings.warn(DeprecationWarning("The resource_id attribute has been deprecated and will be removed in a future version. Please use the id attribute instead."))
|
||||||
|
return self.id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def data(self) -> bytes:
|
def data(self) -> bytes:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user