Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow querying by kind #310

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions khard/carddav_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,9 @@ def anniversary(self, date: Date) -> None:
anniversary.params['VALUE'] = ['text']
anniversary.value = value
elif self.version == "4.0":
self.vcard.add('anniversary').value = value
self.vcard.add('ANNIVERSARY').value = value
else:
self.vcard.add('x-anniversary').value = value
self.vcard.add('X-ANNIVERSARY').value = value

def _get_ablabel(self, item: vobject.base.ContentLine) -> str:
"""Get an ABLABEL for a specified item in the vCard.
Expand Down Expand Up @@ -451,9 +451,17 @@ def _prepare_birthday_value(self, date: Date) -> Tuple[Optional[str],

@property
def kind(self) -> str:
kind = self._get_string_field("kind") or self._default_kind
kind = self._get_string_field(self._kind_attribute_name().lower()) or self._default_kind
return kind if kind != "org" else "organisation"

@kind.setter
def kind(self, value: str) -> None:
value = value if value != "organisation" else "org"
self.vcard.add(self._kind_attribute_name()).value = value

def _kind_attribute_name(self) -> str:
return "{}KIND".format("" if self.version == "4.0" else "X-")

@property
def formatted_name(self) -> str:
return self._get_string_field("fn")
Expand Down Expand Up @@ -1078,6 +1086,13 @@ def update(self, input: str) -> None:
self._set_string_list(self._add_organisation, "Organisation",
contact_data)

# kind
self._delete_vcard_object(self._kind_attribute_name())
try:
self.kind = contact_data["Kind"]
except KeyError:
pass

# role
self._delete_vcard_object("ROLE")
self._set_string_list(self._add_role, "Role", contact_data)
Expand Down Expand Up @@ -1418,6 +1433,11 @@ def pretty(self, verbose: bool = True) -> str:
self._get_additional_names() + self._get_last_names() + \
self._get_name_suffixes()
strings.append("Full name: {}".format(list_to_string(names, " ")))

# kind
if self.kind:
strings.append("Kind: {}".format(self.kind))

# organisation
if self.organisations:
strings += helpers.convert_to_yaml(
Expand Down
4 changes: 4 additions & 0 deletions khard/data/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
# from the full name below if not given.
Formatted name :

# kind (requires vcard 4.0)
# one of: individual, group, org, location, application, device
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where did you get "application" and "device" from? I can not see them in the rfc

Suggested change
# one of: individual, group, org, location, application, device
# one of: individual, group, org, location

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ "vCard KIND:application" is from RFC 6473 and "vCard KIND:device" from RFC 6869

Copy link
Owner

@lucc lucc Jul 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would reference these rfcs in that comment and also at the top of the file.

Kind :

# name components
# every entry may contain a string or a list of strings
# format:
Expand Down
22 changes: 22 additions & 0 deletions test/test_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ def test_empty_note_in_yaml_input(self):
x = parse_yaml(empty_note)
self.assertListEqual(x.notes, [])

def test_empty_kind_in_yaml_input(self):
empty_kind = "First name: foo\nKind:"
with mock.patch("khard.carddav_object.logger"):
x = parse_yaml(empty_kind)
self.assertEqual(x.kind, 'individual')


class yaml_ablabel(unittest.TestCase):

Expand Down Expand Up @@ -226,6 +232,22 @@ def test_update_fn(self):
card.update(data)
self.assertEqual(card.formatted_name, fn)

def test_update_kind(self):
card = create_test_card(version="4.0")
self.assertEqual(card.kind, 'individual')
data = {'Kind': 'organisation'}
data = to_yaml(data)
card.update(data)
self.assertEqual(card.kind, 'organisation')

def test_update_kind_on_3_0_card(self):
card = create_test_card()
self.assertEqual(card.kind, 'individual')
data = {'Kind': 'organisation'}
data = to_yaml(data)
card.update(data)
self.assertEqual(card.kind, 'organisation')

def test_parse_field(self):
"""Test round-trip of a field to/from YAML"""
card = create_test_card()
Expand Down
1 change: 0 additions & 1 deletion todo.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
ToDo list for khard

1. Add support for vcard attributes kind and member
- option to filter contact table (--kind)
- member action to list all members of an organisation

2. Implement impp attribute, see #105 for more information
Expand Down