Skip to content

Commit

Permalink
Added kMDItemFSIsStationery, #18
Browse files Browse the repository at this point in the history
  • Loading branch information
RhetTbull committed Jul 9, 2021
1 parent ff09509 commit 4db1819
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 4 deletions.
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,25 @@ keywords kMDItemKeywords, com.apple.metadata:kMDItemKeywords;
(_kMDItemUserTags) which are keywords/tags shown in the
Finder and searchable in Spotlight using "tag:tag_name". A
list of strings.
participants kMDItemParticipants, com.apple.metadata:kMDItemParticipants;
The list of people who are visible in an image or movie or
written about in a document. A list of strings.
projects kMDItemProjects, com.apple.metadata:kMDItemProjects; The
list of projects that this file is part of. For example, if
you were working on a movie all of the files could be marked
as belonging to the project “My Movie”. A list of strings.
rating kMDItemStarRating, com.apple.metadata:kMDItemStarRating;
User rating of this item. For example, the stars rating of
an iTunes track. An integer.
stationary kMDItemFSIsStationery,
com.apple.metadata:kMDItemFSIsStationery; Boolean indicating
if this file is stationery.
tags _kMDItemUserTags, com.apple.metadata:_kMDItemUserTags;
Finder tags; searchable in Spotlight using "tag:tag_name".
If you want tags/keywords visible in the Finder, use this
instead of kMDItemKeywords. A list of Tag objects.
version kMDItemVersion, com.apple.metadata:kMDItemVersion; The
version number of this file. A string.
wherefroms kMDItemWhereFroms, com.apple.metadata:kMDItemWhereFroms;
Describes where the file was obtained from (e.g. URL
downloaded from). A list of strings.
Expand All @@ -198,8 +210,12 @@ Information about commonly used MacOS metadata attributes is available from [App
|FinderInfo|finderinfo|com.apple.FinderInfo|Color tag set by the Finder. Colors can also be set by _kMDItemUserTags. This is controlled by the Finder and it's recommended you don't directly access this attribute. If you set or remove a color tag via _kMDItemUserTag, osxmetadata will automatically handle processing of FinderInfo color tag.|
|kMDItemHeadline|headline|com.apple.metadata:kMDItemHeadline|A publishable entry providing a synopsis of the contents of the file. A string.|
|kMDItemKeywords|keywords|com.apple.metadata:kMDItemKeywords|Keywords associated with this file. For example, “Birthday”, “Important”, etc. This differs from Finder tags (_kMDItemUserTags) which are keywords/tags shown in the Finder and searchable in Spotlight using "tag:tag_name". A list of strings.|
|kMDItemStarRating|rating|com.apple.metadata:kMDItemStarRating|User rating of this item. For example, the stars rating of an iTunes track. An int.|
|kMDItemParticipants|participants|com.apple.metadata:kMDItemParticipants|The list of people who are visible in an image or movie or written about in a document. A list of strings.|
|kMDItemProjects|projects|com.apple.metadata:kMDItemProjects|The list of projects that this file is part of. For example, if you were working on a movie all of the files could be marked as belonging to the project “My Movie”. A list of strings.|
|kMDItemStarRating|rating|com.apple.metadata:kMDItemStarRating|User rating of this item. For example, the stars rating of an iTunes track. An integer.|
|kMDItemFSIsStationery|stationary|com.apple.metadata:kMDItemFSIsStationery|Boolean indicating if this file is stationery.|
|_kMDItemUserTags|tags|com.apple.metadata:_kMDItemUserTags|Finder tags; searchable in Spotlight using "tag:tag_name". If you want tags/keywords visible in the Finder, use this instead of kMDItemKeywords. A list of Tag objects.|
|kMDItemVersion|version|com.apple.metadata:kMDItemVersion|The version number of this file. A string.|
|kMDItemWhereFroms|wherefroms|com.apple.metadata:kMDItemWhereFroms|Describes where the file was obtained from (e.g. URL downloaded from). A list of strings.|

## Example uses of the package
Expand Down
2 changes: 1 addition & 1 deletion osxmetadata/_version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
""" osxmetadata version """

__version__ = "0.99.18"
__version__ = "0.99.19"
20 changes: 20 additions & 0 deletions osxmetadata/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,19 @@
"The version number of this file. A string.",
None,
),
"stationary": Attribute(
"stationary",
"kMDItemFSIsStationery",
kMDItemFSIsStationery,
bool,
False,
False,
bool,
False,
False,
"Boolean indicating if this file is stationery.",
None,
),
}

# used for formatting output of --list
Expand Down Expand Up @@ -379,6 +392,13 @@ def validate_attribute_value(attribute, value):
raise TypeError(
f"{val} cannot be converted to expected type {attribute.type_}"
)
elif attribute.type_ == bool:
try:
new_val = bool(val)
except ValueError:
raise TypeError(
f"{val} cannot be converted to expected type {attribute.type_}"
)
elif attribute.type_ == datetime.datetime:
if isinstance(val, datetime.datetime):
new_val = val
Expand Down
2 changes: 2 additions & 0 deletions osxmetadata/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
kMDItemParticipants = "com.apple.metadata:kMDItemParticipants"
kMDItemProjects = "com.apple.metadata:kMDItemProjects"
kMDItemVersion = "com.apple.metadata:kMDItemVersion"
kMDItemFSIsStationery = "com.apple.metadata:kMDItemFSIsStationery"


# Special handling for Finder comments
Expand Down Expand Up @@ -108,4 +109,5 @@
"kMDItemParticipants",
"kMDItemProjects",
"kMDItemVersion",
"kMDItemFSIsStationery",
]
6 changes: 4 additions & 2 deletions osxmetadata/osxmetadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
kMDItemUserTags,
kMDItemVersion,
kMDItemWhereFroms,
kMDItemFSIsStationery,
)
from .datetime_utils import (
datetime_naive_to_utc,
Expand Down Expand Up @@ -81,7 +82,7 @@
"kMDItemParticipants",
"kMDItemProjects",
"kMDItemVersion",
"_FINDER_COMMENT_NAMES",
"kMDItemFSIsStationery",
]


Expand Down Expand Up @@ -137,6 +138,7 @@ class OSXMetaData:
"participants",
"projects",
"version",
"stationary",
]

def __init__(self, fname, tz_aware=False):
Expand All @@ -159,7 +161,7 @@ def __init__(self, fname, tz_aware=False):
# ATTRIBUTES contains both long and short names, want only the short names (attribute.name)
for name in {attribute.name for attribute in ATTRIBUTES.values()}:
attribute = ATTRIBUTES[name]
if attribute.class_ not in [str, float, int, datetime.datetime]:
if attribute.class_ not in [str, float, int, bool, datetime.datetime]:
super().__setattr__(
name, attribute.class_(attribute, self._attrs, self)
)
Expand Down
122 changes: 122 additions & 0 deletions tests/test_bool_attributes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
""" Test bool attributes """

import platform
from tempfile import NamedTemporaryFile, TemporaryDirectory

import pytest
from osxmetadata.attributes import ATTRIBUTES


@pytest.fixture(params=["file", "dir"])
def temp_file(request):

# TESTDIR for temporary files usually defaults to "/tmp",
# which may not have XATTR support (e.g. tmpfs);
# manual override here.
TESTDIR = None
if request.param == "file":
tempfile = NamedTemporaryFile(dir=TESTDIR)
tempfilename = tempfile.name
yield tempfilename
tempfile.close()
else:
tempdir = TemporaryDirectory(dir=TESTDIR)
tempdirname = tempdir.name
yield tempdirname
tempdir.cleanup()


test_data = [
(attr)
for attr in sorted(list(ATTRIBUTES.keys()))
if ATTRIBUTES[attr].class_ == bool
]
ids = [
attr for attr in sorted(list(ATTRIBUTES.keys())) if ATTRIBUTES[attr].class_ == bool
]

test_data2 = [
(attribute_name)
for attribute_name in {
ATTRIBUTES[attr].name
for attr in sorted(ATTRIBUTES)
if ATTRIBUTES[attr].class_ == bool
}
]
ids2 = [
attribute_name
for attribute_name in {
ATTRIBUTES[attr].name
for attr in sorted(ATTRIBUTES)
if ATTRIBUTES[attr].class_ == bool
}
]


@pytest.mark.parametrize("attribute", test_data, ids=ids)
def test_str_attribute(temp_file, attribute):
"""test set_attribute, get_attribute, etc"""
from osxmetadata import OSXMetaData
from osxmetadata.constants import _FINDER_COMMENT_NAMES

meta = OSXMetaData(temp_file)
expected = True
meta.set_attribute(attribute, expected)
got = meta.get_attribute(attribute)
assert expected == got

meta.set_attribute(attribute, not expected)
assert not meta.get_attribute(attribute)

meta.clear_attribute(attribute)
assert meta.get_attribute(attribute) is None

# test setting empty string
# setting finder comment to empty string clears it
# but other fields get set to empty string
# this mirrors the way finder comments work in mdls
meta.set_attribute(attribute, "")
assert not meta.get_attribute(attribute)

with pytest.raises(AttributeError):
meta.update_attribute(attribute, "foo")

with pytest.raises(TypeError):
meta.discard_attribute(attribute, "foo")

with pytest.raises(TypeError):
meta.remove_attribute(attribute, "foo")


@pytest.mark.parametrize("attribute", test_data2, ids=ids2)
def test_str_attribute_2(temp_file, attribute):
"""test getting and setting attribute by name"""
from osxmetadata import OSXMetaData

meta = OSXMetaData(temp_file)
setattr(meta, attribute, True)
test_attr = getattr(meta, attribute)
assert test_attr
assert meta.get_attribute(attribute)


def test_stationary(temp_file):
"""test string functions on one of the bool attributes"""
from osxmetadata import OSXMetaData

meta = OSXMetaData(temp_file)
meta.stationary = True
assert meta.stationary
assert meta.get_attribute("stationary")

meta.stationary = not meta.stationary
assert not meta.stationary
assert not meta.get_attribute("stationary")

meta.stationary = None
assert meta.stationary is None
assert meta.get_attribute("stationary") is None

meta.stationary = True
assert meta.stationary
assert meta.get_attribute("stationary")

0 comments on commit 4db1819

Please sign in to comment.