icalcli 1.1.2__tar.gz → 1.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {icalcli-1.1.2 → icalcli-1.1.4}/PKG-INFO +9 -8
  2. {icalcli-1.1.2 → icalcli-1.1.4}/README.md +1 -1
  3. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli/icalcli.py +47 -36
  4. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli.egg-info/PKG-INFO +9 -8
  5. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli.egg-info/SOURCES.txt +1 -1
  6. icalcli-1.1.4/pyproject.toml +41 -0
  7. icalcli-1.1.2/setup.py +0 -37
  8. {icalcli-1.1.2 → icalcli-1.1.4}/LICENSE +0 -0
  9. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli/__init__.py +0 -0
  10. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli/argparsers.py +0 -0
  11. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli/etesync_backend/__init__.py +0 -0
  12. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli/etesync_backend/etebase_crud.py +0 -0
  13. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli/etesync_backend/etebase_interface.py +0 -0
  14. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli/etesync_backend/etesync_crud.py +0 -0
  15. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli/etesync_backend/etesync_interface.py +0 -0
  16. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli/file_backend/__init__.py +0 -0
  17. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli/file_backend/ics_interface.py +0 -0
  18. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli/printer.py +0 -0
  19. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli/utils.py +0 -0
  20. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli.egg-info/dependency_links.txt +0 -0
  21. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli.egg-info/entry_points.txt +0 -0
  22. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli.egg-info/requires.txt +0 -0
  23. {icalcli-1.1.2 → icalcli-1.1.4}/icalcli.egg-info/top_level.txt +0 -0
  24. {icalcli-1.1.2 → icalcli-1.1.4}/setup.cfg +0 -0
@@ -1,14 +1,14 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: icalcli
3
- Version: 1.1.2
3
+ Version: 1.1.4
4
4
  Summary: Icalendar Calendar Command Line Interface
5
- Home-page: https://github.com/jrvarma/icalcli
6
- Maintainer: Jayanth R. Varma
7
- Maintainer-email: jrvarma@gmail.com
8
- Classifier: Development Status :: 3 - Alpha
5
+ Author: Jayanth R. Varma
6
+ Maintainer-email: "Jayanth R. Varma" <jrvarma@gmail.com>
7
+ License: OSI Approved :: MIT License
8
+ Project-URL: Homepage, https://github.com/jrvarma/icalcli
9
+ Classifier: Development Status :: 4 - Beta
9
10
  Classifier: Environment :: Console
10
11
  Classifier: Intended Audience :: End Users/Desktop
11
- Classifier: License :: OSI Approved :: MIT License
12
12
  Classifier: Programming Language :: Python :: 3
13
13
  Requires-Python: >=3.6
14
14
  Description-Content-Type: text/markdown
@@ -19,6 +19,7 @@ Requires-Dist: icalendar
19
19
  Requires-Dist: recurring_ical_events
20
20
  Provides-Extra: parsedatetime
21
21
  Requires-Dist: parsedatetime; extra == "parsedatetime"
22
+ Dynamic: license-file
22
23
 
23
24
  # icalcli
24
25
 
@@ -66,7 +67,7 @@ pipx install icalcli
66
67
  ```sh
67
68
  git clone https://github.com/jrvarma/icalcli.git
68
69
  cd icalcli
69
- python setup.py install
70
+ python -m pip install .
70
71
  ```
71
72
 
72
73
  or via `pipx`:
@@ -44,7 +44,7 @@ pipx install icalcli
44
44
  ```sh
45
45
  git clone https://github.com/jrvarma/icalcli.git
46
46
  cd icalcli
47
- python setup.py install
47
+ python -m pip install .
48
48
  ```
49
49
 
50
50
  or via `pipx`:
@@ -72,14 +72,27 @@ NON_RECURRING_EVENTS = 2
72
72
  ORIGINAL_OF_RECURRING_EVENTS = 3
73
73
 
74
74
 
75
+ def decode_if_bytes(string_or_bytes):
76
+ # Version 7 of iCalendar made a breaking change
77
+ # The return type of text properties was changed from bytes to string
78
+ # To work with both old and new versions of iCalendar and to guard
79
+ # against any future change in the return value of calendar.to_ical()
80
+ # which still returns bytes, we apply decode only after confirming that
81
+ # the value is bytes
82
+ if isinstance(string_or_bytes, bytes):
83
+ return string_or_bytes.decode()
84
+ return string_or_bytes
85
+
86
+
75
87
  def safe_decode(x, field):
76
88
  try:
77
- return x.decoded(field)
89
+ result = x.decoded(field)
78
90
  except: # noqa: E722
79
91
  print("iCalendar error:", x.errors)
80
92
  print("iCalendar could not decode {:} field of \n{:}".format(
81
- field, x.to_ical().decode()))
93
+ field, decode_if_bytes(x.to_ical())))
82
94
  raise
95
+ return decode_if_bytes(result)
83
96
 
84
97
 
85
98
  Event.Decoded = safe_decode
@@ -152,7 +165,7 @@ class IcalendarInterface:
152
165
  @staticmethod
153
166
  def uid(event):
154
167
  """Return uid of event"""
155
- return event.Decoded('uid').decode()
168
+ return event.Decoded('uid')
156
169
 
157
170
  def check_duplicate_uids(self):
158
171
  # fixes https://github.com/jrvarma/icalcli/pull/8#issue-1310596831
@@ -180,7 +193,7 @@ class IcalendarInterface:
180
193
  ics_list = []
181
194
  for event in self.events:
182
195
  cal.add_component(event)
183
- ics_list += [cal.to_ical().decode()]
196
+ ics_list += [decode_if_bytes(cal.to_ical())]
184
197
  self.calendar = Calendar.from_ical("".join(ics_list))
185
198
  self.recurring_events = recurring_ical_events.of(
186
199
  self.calendar, keep_recurrence_attributes=True)
@@ -262,8 +275,8 @@ class IcalendarInterface:
262
275
  string
263
276
  """
264
277
  if 'summary' in event and (
265
- event.Decoded('summary').decode().strip()):
266
- return event.Decoded('summary').decode()
278
+ event.Decoded('summary').strip()):
279
+ return event.Decoded('summary')
267
280
  else:
268
281
  return "(No title)"
269
282
 
@@ -374,24 +387,23 @@ class IcalendarInterface:
374
387
  summary += ' AL: ??'
375
388
  if self.graphical_outputs.get('freebusy'):
376
389
  free = ('transp' in event and
377
- event.Decoded('transp').decode() == 'TRANSPARENT')
390
+ event.Decoded('transp') == 'TRANSPARENT')
378
391
  summary += (' free ' if free else ' busy ')
379
392
  if (
380
393
  self.graphical_outputs.get('location')
381
394
  and 'location' in event
382
- and event.Decoded('location').decode().strip()
395
+ and event.Decoded('location').strip()
383
396
  ):
384
- summary += " [%s]" % (event.Decoded('location').
385
- decode().strip())
397
+ summary += " [%s]" % (event.Decoded('location').strip())
386
398
  if self.graphical_outputs.get('uid'):
387
- summary += " <%s>" % (event.Decoded('uid').decode().strip())
399
+ summary += " <%s>" % (event.Decoded('uid').strip())
388
400
  if (
389
401
  self.graphical_outputs.get('description')
390
402
  and 'description' in event
391
- and event.Decoded('description').decode().strip()
403
+ and event.Decoded('description').strip()
392
404
  and self.outputs.get('description')
393
405
  ):
394
- summary += event.Decoded('description'). decode().strip()
406
+ summary += event.Decoded('description').strip()
395
407
  return summary
396
408
 
397
409
  def get_week_events(self, start_dt, end_dt, event_list):
@@ -878,7 +890,7 @@ class IcalendarInterface:
878
890
  self.printer.msg(' '*7)
879
891
  if self.outputs.get('freebusy'):
880
892
  free = ('transp' in event and
881
- event.Decoded('transp').decode() == 'TRANSPARENT')
893
+ event.Decoded('transp') == 'TRANSPARENT')
882
894
  self.printer.msg(' free ' if free else ' busy ',
883
895
  eventColor)
884
896
 
@@ -888,21 +900,20 @@ class IcalendarInterface:
888
900
  if (
889
901
  self.outputs.get('location')
890
902
  and 'location' in event
891
- and event.Decoded('location').decode().strip()
903
+ and event.Decoded('location').strip()
892
904
  ):
893
- xstr = " [%s]" % (event.Decoded('location').
894
- decode().strip())
905
+ xstr = " [%s]" % (event.Decoded('location').strip())
895
906
  self.printer.msg(xstr, 'default')
896
907
 
897
908
  if self.outputs.get('uid'):
898
- xstr = " <%s>" % (event.Decoded('uid').decode().strip())
909
+ xstr = " <%s>" % (event.Decoded('uid').strip())
899
910
  self.printer.msg(xstr, 'default')
900
911
 
901
912
  self.printer.msg('\n')
902
913
 
903
914
  if (
904
915
  self.outputs.get('description') and 'description' in event
905
- and event.Decoded('description').decode().strip()
916
+ and event.Decoded('description').strip()
906
917
  ):
907
918
  descrIndent = outputsIndent + ' '
908
919
  box = True # leave old non-box code for option later
@@ -923,7 +934,7 @@ class IcalendarInterface:
923
934
  outputsIndent,
924
935
  topMarker,
925
936
  formatDescr(event.Decoded('description').
926
- decode().strip(), descrIndent, box),
937
+ strip(), descrIndent, box),
927
938
  botMarker
928
939
  )
929
940
  else:
@@ -933,7 +944,7 @@ class IcalendarInterface:
933
944
  outputsIndent,
934
945
  marker,
935
946
  formatDescr(event.Decoded('description').
936
- decode().strip(), descrIndent, box),
947
+ strip(), descrIndent, box),
937
948
  marker
938
949
  )
939
950
  self.printer.msg(xstr, 'default')
@@ -1048,9 +1059,7 @@ class IcalendarInterface:
1048
1059
  elif event.decoded(field, None) is None:
1049
1060
  pat_match = False
1050
1061
  else:
1051
- s = event[field].to_ical()
1052
- if isinstance(s, bytes):
1053
- s = s.decode()
1062
+ s = decode_if_bytes(event[field].to_ical())
1054
1063
  pat_match = (
1055
1064
  re.search(pattern, s, flags=flags) is not None)
1056
1065
  return date_in_range and pat_match
@@ -1099,7 +1108,7 @@ class IcalendarInterface:
1099
1108
  uids = set(self.uid(e) for e in event_list) & self.recur_uids
1100
1109
  event_list = [e for e in self.events if self.uid(e) in uids]
1101
1110
  event_list.sort(key=lambda x: (self.decode_dtm(x, 'dtstart'),
1102
- x.Decoded('summary').decode()))
1111
+ x.Decoded('summary')))
1103
1112
  return event_list
1104
1113
 
1105
1114
  def save_last_search_spec(self, start, end, search=None, field='summary'):
@@ -1408,7 +1417,7 @@ class IcalendarInterface:
1408
1417
  for event in event_list:
1409
1418
  self.iterate_events(None, [event], print_count=False,
1410
1419
  ev_type=ev_type)
1411
- self.printer.msg(event.to_ical().decode() + '\n')
1420
+ self.printer.msg(decode_if_bytes(event.to_ical()) + '\n')
1412
1421
  if ev_type == ORIGINAL_OF_RECURRING_EVENTS:
1413
1422
  self.printer.msg(warn_recur)
1414
1423
  args = self.read_edit_args()
@@ -1455,16 +1464,18 @@ class IcalendarInterface:
1455
1464
  return self.raw_ics(original)
1456
1465
  default_event_duration = timedelta(minutes=30)
1457
1466
  old = None
1467
+ if args.summary:
1468
+ summary = args.summary
1458
1469
  if original:
1459
1470
  # simulate old = original.deepcopy()
1460
- old = Calendar.from_ical(original.to_ical().decode())
1461
- uid = old.Decoded('uid').decode()
1471
+ old = Calendar.from_ical(decode_if_bytes(original.to_ical()))
1472
+ uid = old.Decoded('uid')
1462
1473
  old_start = self.display_timezone(old.Decoded('dtstart'))
1463
1474
  old_duration = (
1464
1475
  ('duration' in old and old.Decoded('duration')) or
1465
1476
  (old.Decoded('dtend') - old.Decoded('dtstart')))
1466
1477
  if not args.summary:
1467
- args.summary = old.Decoded('summary').decode()
1478
+ summary = old.Decoded('summary')
1468
1479
  if (
1469
1480
  not args.time and not (args.start and 'T' in args.start)
1470
1481
  and self.isallday(old)
@@ -1478,7 +1489,7 @@ class IcalendarInterface:
1478
1489
  gethostname())
1479
1490
  # old_start = self.now
1480
1491
  # old_duration = None
1481
- if not args.summary:
1492
+ if not summary:
1482
1493
  raise Exception('Summary must be specified')
1483
1494
  day = args.day or self.now.day
1484
1495
  month = args.month or self.now.month + (
@@ -1549,7 +1560,7 @@ class IcalendarInterface:
1549
1560
  event = old
1550
1561
  else:
1551
1562
  s = re.sub(r'BEGIN:VALARM.*END:VALARM\s*', '',
1552
- old.to_ical().decode(), flags=re.DOTALL)
1563
+ decode_if_bytes(old.to_ical()), flags=re.DOTALL)
1553
1564
  event = Calendar.from_ical(s)
1554
1565
 
1555
1566
  def add_or_change(event, field, value):
@@ -1564,7 +1575,7 @@ class IcalendarInterface:
1564
1575
  add_or_change(event, field, parsed_value)
1565
1576
 
1566
1577
  add_or_change(event, 'last-modified', dtstamp)
1567
- add_or_change(event, 'summary', args.summary)
1578
+ add_or_change(event, 'summary', summary)
1568
1579
  add_or_change(event, 'dtstart', self.calendar_timezone(start))
1569
1580
  add_or_change(event, 'dtend', self.calendar_timezone(end))
1570
1581
  if args.free:
@@ -1590,7 +1601,7 @@ class IcalendarInterface:
1590
1601
  if not args.no_prompt:
1591
1602
  self.printer.msg("{:} Event Details\n".format(
1592
1603
  "Edited" if old else "New"))
1593
- self.printer.msg(event.to_ical().decode())
1604
+ self.printer.msg(decode_if_bytes(event.to_ical()))
1594
1605
  if is_recurring_event:
1595
1606
  self.preview_recurring_event(event)
1596
1607
  else:
@@ -1613,7 +1624,7 @@ class IcalendarInterface:
1613
1624
 
1614
1625
  def raw_ics(self, original=None):
1615
1626
  if original:
1616
- uid = original.Decoded('uid').decode()
1627
+ uid = original.Decoded('uid')
1617
1628
  else:
1618
1629
  uid = "%s (%s)" % (datetime.now().isoformat(),
1619
1630
  gethostname())
@@ -1631,7 +1642,7 @@ class IcalendarInterface:
1631
1642
  if event.errors:
1632
1643
  self.printer.err_msg("iCalendar could not parse raw ICS")
1633
1644
  raise Exception(str(event.errors))
1634
- out = event.to_ical().decode()
1645
+ out = decode_if_bytes(event.to_ical())
1635
1646
 
1636
1647
  def lines(s):
1637
1648
  return ("\n".join(s.splitlines())).splitlines(keepends=True)
@@ -1646,7 +1657,7 @@ class IcalendarInterface:
1646
1657
  self.printer.msg("Action cancelled\n")
1647
1658
  return False
1648
1659
  if 'uid' in event:
1649
- new_uid = event.decoded('uid').decode()
1660
+ new_uid = event.decoded('uid')
1650
1661
  if original and new_uid != uid:
1651
1662
  raise 'UID cannot be changed. Delete event and add new event'
1652
1663
  else:
@@ -1,14 +1,14 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: icalcli
3
- Version: 1.1.2
3
+ Version: 1.1.4
4
4
  Summary: Icalendar Calendar Command Line Interface
5
- Home-page: https://github.com/jrvarma/icalcli
6
- Maintainer: Jayanth R. Varma
7
- Maintainer-email: jrvarma@gmail.com
8
- Classifier: Development Status :: 3 - Alpha
5
+ Author: Jayanth R. Varma
6
+ Maintainer-email: "Jayanth R. Varma" <jrvarma@gmail.com>
7
+ License: OSI Approved :: MIT License
8
+ Project-URL: Homepage, https://github.com/jrvarma/icalcli
9
+ Classifier: Development Status :: 4 - Beta
9
10
  Classifier: Environment :: Console
10
11
  Classifier: Intended Audience :: End Users/Desktop
11
- Classifier: License :: OSI Approved :: MIT License
12
12
  Classifier: Programming Language :: Python :: 3
13
13
  Requires-Python: >=3.6
14
14
  Description-Content-Type: text/markdown
@@ -19,6 +19,7 @@ Requires-Dist: icalendar
19
19
  Requires-Dist: recurring_ical_events
20
20
  Provides-Extra: parsedatetime
21
21
  Requires-Dist: parsedatetime; extra == "parsedatetime"
22
+ Dynamic: license-file
22
23
 
23
24
  # icalcli
24
25
 
@@ -66,7 +67,7 @@ pipx install icalcli
66
67
  ```sh
67
68
  git clone https://github.com/jrvarma/icalcli.git
68
69
  cd icalcli
69
- python setup.py install
70
+ python -m pip install .
70
71
  ```
71
72
 
72
73
  or via `pipx`:
@@ -1,6 +1,6 @@
1
1
  LICENSE
2
2
  README.md
3
- setup.py
3
+ pyproject.toml
4
4
  icalcli/__init__.py
5
5
  icalcli/argparsers.py
6
6
  icalcli/icalcli.py
@@ -0,0 +1,41 @@
1
+ [build-system]
2
+ requires = ["setuptools"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "icalcli"
7
+ version = "1.1.4"
8
+ authors = [
9
+ {name = "Jayanth R. Varma"}
10
+ ]
11
+ maintainers = [
12
+ {name = "Jayanth R. Varma", email = "jrvarma@gmail.com"}
13
+ ]
14
+ description = "Icalendar Calendar Command Line Interface"
15
+ readme = "README.md"
16
+ dependencies = [
17
+ "python-dateutil",
18
+ "parsedatetime",
19
+ "icalendar",
20
+ "recurring_ical_events"
21
+ ]
22
+ license = {text = "OSI Approved :: MIT License"}
23
+ classifiers = [
24
+ "Development Status :: 4 - Beta",
25
+ "Environment :: Console",
26
+ "Intended Audience :: End Users/Desktop",
27
+ "Programming Language :: Python :: 3"
28
+ ]
29
+ requires-python = ">=3.6"
30
+
31
+ [project.optional-dependencies]
32
+ "parsedatetime"= ["parsedatetime"]
33
+
34
+ [project.scripts]
35
+ icalcli = "icalcli.icalcli:main"
36
+
37
+ [project.urls]
38
+ Homepage = "https://github.com/jrvarma/icalcli"
39
+
40
+ [tool.setuptools]
41
+ packages = ["icalcli", "icalcli.etesync_backend", "icalcli.file_backend"]
icalcli-1.1.2/setup.py DELETED
@@ -1,37 +0,0 @@
1
- #!/usr/bin/env python
2
- from setuptools import setup
3
-
4
- with open("README.md", "r") as fh:
5
- long_description = fh.read()
6
-
7
- setup(name='icalcli',
8
- version='1.1.2',
9
- maintainer='Jayanth R. Varma',
10
- maintainer_email='jrvarma@gmail.com',
11
- description='Icalendar Calendar Command Line Interface',
12
- long_description=long_description,
13
- long_description_content_type="text/markdown",
14
- url="https://github.com/jrvarma/icalcli",
15
- packages=['icalcli', 'icalcli.etesync_backend', 'icalcli.file_backend'],
16
- install_requires=[
17
- 'python-dateutil',
18
- 'parsedatetime',
19
- 'icalendar',
20
- 'recurring_ical_events',
21
- ],
22
- extras_require={
23
- 'parsedatetime': ["parsedatetime"],
24
- },
25
- entry_points={
26
- 'console_scripts':
27
- ['icalcli=icalcli.icalcli:main'],
28
- },
29
- classifiers=[
30
- "Development Status :: 3 - Alpha",
31
- "Environment :: Console",
32
- "Intended Audience :: End Users/Desktop",
33
- "License :: OSI Approved :: MIT License",
34
- "Programming Language :: Python :: 3",
35
- ],
36
- python_requires='>=3.6',
37
- ) # noqa E124
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes