ics-query 0.3.1b0__py3-none-any.whl → 0.3.2b0__py3-none-any.whl

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.
ics_query/_version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.3.1b0'
16
- __version_tuple__ = version_tuple = (0, 3, 1)
15
+ __version__ = version = '0.3.2b0'
16
+ __version_tuple__ = version_tuple = (0, 3, 2)
ics_query/cli.py CHANGED
@@ -25,6 +25,7 @@ import zoneinfo
25
25
 
26
26
  import click
27
27
  from icalendar.cal import Calendar, Component
28
+ from tzlocal import get_localzone_name
28
29
 
29
30
  from . import parse
30
31
  from .query import Query
@@ -181,17 +182,18 @@ def opt_available_timezones(*param_decls: str, **kwargs: t.Any) -> t.Callable:
181
182
  """List available timezones.
182
183
 
183
184
  This is copied from the --help option.
185
+
186
+ Commonly used timezone names are added first.
184
187
  """
185
188
 
186
189
  def callback(ctx: click.Context, param: click.Parameter, value: bool) -> None: # noqa: FBT001, ARG001
187
190
  if not value or ctx.resilient_parsing:
188
191
  return
189
192
 
190
- first_zones = ["localtime", "UTC"]
193
+ click.echo("localtime") # special local time handle
194
+ click.echo(get_localzone_name())
195
+ click.echo("UTC")
191
196
  all_zones = zoneinfo.available_timezones()
192
- for zone in first_zones:
193
- if zone in all_zones:
194
- click.echo(zone)
195
197
  for zone in sorted(all_zones, key=str.lower):
196
198
  click.echo(zone)
197
199
  ctx.exit()
ics_query/query.py CHANGED
@@ -23,6 +23,7 @@ from typing import TYPE_CHECKING
23
23
 
24
24
  import x_wr_timezone
25
25
  from recurring_ical_events import CalendarQuery, Occurrence
26
+ from tzlocal import get_localzone
26
27
 
27
28
  if TYPE_CHECKING:
28
29
  from collections.abc import Sequence
@@ -38,7 +39,13 @@ class Query(CalendarQuery):
38
39
  components=components,
39
40
  skip_bad_series=True,
40
41
  )
41
- self.timezone = zoneinfo.ZoneInfo(timezone) if timezone else None
42
+ self.timezone = self.get_timezone(timezone)
43
+
44
+ def get_timezone(self, timezone: str) -> datetime.tzinfo | None:
45
+ """Return the local time tz."""
46
+ if timezone == "localtime":
47
+ return get_localzone()
48
+ return zoneinfo.ZoneInfo(timezone) if timezone else None
42
49
 
43
50
  def with_timezone(self, dt: datetime.date | datetime.datetime):
44
51
  """Add the timezone."""
@@ -18,7 +18,6 @@
18
18
  from __future__ import annotations
19
19
 
20
20
  import subprocess
21
- from copy import deepcopy
22
21
  from pathlib import Path
23
22
  from typing import Callable, NamedTuple
24
23
 
@@ -50,14 +49,28 @@ class TestRun(NamedTuple):
50
49
  )
51
50
 
52
51
 
53
- def run_ics_query(*command, cwd=CALENDARS_DIRECTORY) -> TestRun:
54
- """Run ics-qeury with a command."""
55
- cmd = ["ics-query", *command]
56
- print(" ".join(cmd))
52
+ def get_binary_path(request: pytest.FixtureRequest) -> str:
53
+ """Return the path to the ics-query command."""
54
+ command: str = request.config.getoption("--binary")
55
+ if command == "ics-query":
56
+ # The default command can be found on the command line
57
+ return command
58
+ # we must set the path to be absolute
59
+ return Path(command).absolute()
60
+
61
+
62
+ def run_ics_query(*command, cwd=CALENDARS_DIRECTORY, binary: str) -> TestRun:
63
+ """Run ics-qeury with a command.
64
+
65
+ - cwd is the working directory
66
+ - binary is the path to the command
67
+ """
68
+ cmd = [binary, *command]
69
+ print(" ".join(map(str, cmd)))
57
70
  completed_process = subprocess.run( # noqa: S603, RUF100
58
71
  cmd, # noqa: S603, RUF100
59
72
  capture_output=True,
60
- timeout=3,
73
+ timeout=10,
61
74
  check=False,
62
75
  cwd=cwd,
63
76
  )
@@ -71,35 +84,43 @@ class IOTestCase(NamedTuple):
71
84
  command: list[str]
72
85
  location: Path
73
86
  expected_output: str
87
+ binary: str
74
88
 
75
89
  @classmethod
76
- def from_path(cls, path: Path) -> IOTestCase:
90
+ def from_path(cls, path: Path, binary: str) -> IOTestCase:
77
91
  """Create a new testcase from the files."""
78
92
  expected_output = path.read_text(encoding="UTF-8").replace("\r\n", "\n")
79
- return cls(path.name, path.stem.split(), path.parent, expected_output)
93
+ return cls(path.name, path.stem.split(), path.parent, expected_output, binary)
80
94
 
81
95
  def run(self) -> TestRun:
82
96
  """Run this test case and return the result."""
83
- return run_ics_query(*self.command)
97
+ return run_ics_query(*self.command, binary=self.binary)
84
98
 
85
99
 
86
- io_test_cases = [
87
- IOTestCase.from_path(test_case_path)
100
+ io_test_case_paths = [
101
+ test_case_path
88
102
  for test_case_path in IO_DIRECTORY.iterdir()
89
103
  if test_case_path.is_file()
90
104
  ]
91
105
 
92
106
 
93
- @pytest.fixture(params=io_test_cases)
94
- def io_testcase(request) -> IOTestCase:
107
+ @pytest.fixture(params=io_test_case_paths)
108
+ def io_testcase(request: pytest.FixtureRequest) -> IOTestCase:
95
109
  """Go though all the IO test cases."""
96
- return deepcopy(request.param)
110
+ path: Path = request.param
111
+ binary = get_binary_path(request)
112
+ return IOTestCase.from_path(path, binary)
97
113
 
98
114
 
99
115
  @pytest.fixture
100
- def run() -> Callable[..., TestRun]:
116
+ def run(request: pytest.FixtureRequest) -> Callable[..., TestRun]:
101
117
  """Return a runner function."""
102
- return run_ics_query
118
+
119
+ def run(*args, **kw):
120
+ kw["binary"] = get_binary_path(request)
121
+ return run_ics_query(*args, **kw)
122
+
123
+ return run
103
124
 
104
125
 
105
126
  __all__ = ["IOTestCase", "TestRun"]
@@ -0,0 +1,14 @@
1
+ BEGIN:VCALENDAR
2
+ VERSION:2.0
3
+ PRODID:-//SabreDAV//SabreDAV//EN
4
+ CALSCALE:GREGORIAN
5
+ BEGIN:VEVENT
6
+ CREATED:20190303T111937
7
+ DTSTAMP:20190303T111937
8
+ LAST-MODIFIED:20190303T111937
9
+ UID:UYDQSG9TH4DE0WM3QFL2J
10
+ SUMMARY:test1
11
+ DTSTART:20190304T080000
12
+ DTEND:20190304T083000
13
+ END:VEVENT
14
+ END:VCALENDAR
@@ -15,6 +15,8 @@
15
15
  # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
16
  """Test the commmand line."""
17
17
 
18
+ from tzlocal import get_localzone_name
19
+
18
20
  from ics_query.version import version
19
21
 
20
22
  from .conftest import IOTestCase
@@ -51,3 +53,20 @@ def test_timezones(run):
51
53
  assert tz.index("Zulu") > tz.index("Pacific/Nauru")
52
54
  assert tz.index("Pacific/Nauru") > tz.index("UTC")
53
55
  assert tz.index("UTC") > tz.index("localtime")
56
+
57
+
58
+ def test_special_timezones(run):
59
+ """Make sure we show special timezones first."""
60
+ result = run("--available-timezones")
61
+ tz = result.output.split()
62
+ assert result.exit_code == 0
63
+ assert tz[0] == "localtime"
64
+ assert tz[1] == get_localzone_name()
65
+ assert tz[2] == "UTC"
66
+
67
+
68
+ def test_localtime_is_not_in_the_result_string(run):
69
+ """We do not want 'localtime' to turn up as the result tz name."""
70
+ result = run("first", "--tz", "localtime", "one-event-without-timezone.ics")
71
+ assert f"DTSTART;TZID={get_localzone_name()}:201903" in result.output
72
+ assert f"DTEND;TZID={get_localzone_name()}:201903" in result.output
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ics-query
3
- Version: 0.3.1b0
3
+ Version: 0.3.2b0
4
4
  Summary: Find out what happens in ICS calendar files - query and filter RFC 5545 compatible .ics files for events, journals, TODOs and more.
5
5
  Project-URL: Homepage, https://github.com/niccokunzmann/ics-query/
6
6
  Project-URL: Repository, https://github.com/niccokunzmann/ics-query/
7
- Project-URL: source_archive, https://github.com/niccokunzmann/ics-query/archive/985400ff5c4df0ea4ad62422ef5c5c5e98face07.zip
7
+ Project-URL: source_archive, https://github.com/niccokunzmann/ics-query/archive/594ac9795b0598b83ad10972c984519dfb3c7b12.zip
8
8
  Project-URL: Issues, https://github.com/niccokunzmann/ics-query/issues
9
9
  Project-URL: Documentation, https://github.com/niccokunzmann/ics-query/
10
10
  Project-URL: Changelog, https://github.com/niccokunzmann/ics-query/#changelog
@@ -699,6 +699,7 @@ Requires-Python: >=3.9
699
699
  Requires-Dist: click
700
700
  Requires-Dist: icalendar
701
701
  Requires-Dist: recurring-ical-events<4,>=3.2.0
702
+ Requires-Dist: tzlocal
702
703
  Requires-Dist: x-wr-timezone
703
704
  Provides-Extra: test
704
705
  Requires-Dist: pytest; extra == 'test'
@@ -723,6 +724,8 @@ You can install this package from the [PyPI].
723
724
  pip install ics-query
724
725
  ```
725
726
 
727
+ For **Windows**, you can download `ics-query.exe` from our [Releases].
728
+
726
729
  ## Support
727
730
 
728
731
  - Support using [GitHub Sponsors]
@@ -922,7 +925,7 @@ You can specify which components you would like to get using the
922
925
  -c VEVENT # only events
923
926
  -c VTODO # only TODOs
924
927
  -c VJOURNAL # only journal entries
925
- -c VEVENT -v VTODO # only events and journal entries
928
+ -c VEVENT -c VTODO # only events and journal entries
926
929
  ```
927
930
 
928
931
  This example returns the first event of a calendar.
@@ -1071,6 +1074,12 @@ To release new versions,
1071
1074
 
1072
1075
  ## Changelog
1073
1076
 
1077
+ - v0.3.2b
1078
+
1079
+ - Fix that `--tz localtime` would use `localtime` as timezone name instead of the local timezone name.
1080
+ - Fix tests on Windows
1081
+ - Add Windows .exe build artifact
1082
+
1074
1083
  - v0.3.1b
1075
1084
 
1076
1085
  - Add `--license` option
@@ -1148,3 +1157,4 @@ Examples:
1148
1157
  [Polar]: https://polar.sh/niccokunzmann/ics-query
1149
1158
  [GitHub Sponsors]: https://github.com/sponsors/niccokunzmann
1150
1159
  [thanks.dev]: https://thanks.dev
1160
+ [Releases]: https://github.com/niccokunzmann/ics-query/releases
@@ -1,13 +1,13 @@
1
1
  ics_query/__init__.py,sha256=BBd-FYDFf3jY_ApkMRkivqGti2uMeP4OT6KtgZDixic,917
2
2
  ics_query/__main__.py,sha256=1rFDbZZcd6llmQ-X_611jWdrua4HMOnpOclKRvf03Us,737
3
- ics_query/_version.py,sha256=c2CEW8svaXrg7VxTbX_h3WVVYqpNARBenswZBolcByk,413
4
- ics_query/cli.py,sha256=_Em8oiTtaTtK9H5ZvqB0-F2v3OibBBaDM6lmBPgaeq4,19918
3
+ ics_query/_version.py,sha256=hP_Hdbj34-4rXjvG9r1qSsOVZyNFfJ3DfZgn3Z3x0_g,413
4
+ ics_query/cli.py,sha256=VPXcSCjtaWZJtSzMsHqLfcTgStnJsoyY9K8Q0VZUs3o,19993
5
5
  ics_query/parse.py,sha256=AO2TBoe98exzfzTKsoF5ZAvJOg3hN2qRpP15DAQKZaM,2415
6
- ics_query/query.py,sha256=bmC0fcK-qHVj0tB4TPpwf4g6-qFmUyZxs_IjMovwBX8,2434
6
+ ics_query/query.py,sha256=9HSSWJ1y7avU6mRDXBQKKTkk9oeG9qEwhr3k0piHbaU,2692
7
7
  ics_query/version.py,sha256=Tx41PPl2wc6dQI6r93EzTANoUXjkFzUvwMYj5ARauNQ,1347
8
8
  ics_query/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- ics_query/tests/conftest.py,sha256=E4rN037kKJzrGUj4QggIv2LyaAGXnxNknnkcbheJplQ,2943
10
- ics_query/tests/test_command_line.py,sha256=iXLhdOOXb1I4MBsP82CSfTGu9kZM0s8PxNYLKO04PLw,1838
9
+ ics_query/tests/conftest.py,sha256=MmxzXtpXHN3pf8jDmVGXvxcNXfepRwrJ03EF68zRSrY,3668
10
+ ics_query/tests/test_command_line.py,sha256=mB_v-WqjpYRcxtROdi7GfvUGTEHYZ-3Z-sWevp7lFYc,2524
11
11
  ics_query/tests/test_parse_date.py,sha256=EGD06AtO_kNDcYEY7vhI9rN45HiZPbRm2LkGZoVW6iw,2785
12
12
  ics_query/tests/test_parse_timedelta.py,sha256=EpM013rw-G61wI0hyWjtFOtE7xXo2DNsU3vSIULGZ1k,1469
13
13
  ics_query/tests/runs/all --tz Singapore one-event.ics -.run,sha256=sWF9T4kKzhnZYrgidUX5sgdJ5q95q1gp9vd8X65bIdk,218
@@ -31,13 +31,14 @@ ics_query/tests/runs/calendars/empty-calendar.ics,sha256=78162P3KYUj6Qhbdnjsm3E8
31
31
  ics_query/tests/runs/calendars/empty-file.ics,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  ics_query/tests/runs/calendars/multiple-calendars.ics,sha256=lS1Q9eSPpzLs2TRDKUiwF9HmpnJMw8xqjLudA0-KtY4,1516
33
33
  ics_query/tests/runs/calendars/one-event-twice.ics,sha256=GZ5wE-U4kjO91N2nIaLsYZpSOLvQTjkoLPI6saMocOM,1450
34
+ ics_query/tests/runs/calendars/one-event-without-timezone.ics,sha256=0ZQBHz2RDxUIrub4ZWwcQPpUS_bvdl0GT-kaLDppMlc,282
34
35
  ics_query/tests/runs/calendars/one-event.ics,sha256=-uwohttEzg-jsTETNb6tQ5dO9PE3DXzlicwRiXJs1KQ,725
35
36
  ics_query/tests/runs/calendars/recurring-work-events.ics,sha256=4ASS_-xZl2pVv1kZ7nDOU9jpkmbo4zJC2KEAgHtpsNU,5115
36
37
  ics_query/tests/runs/calendars/simple-journal.ics,sha256=U6_YMQM6EHwPDaszWgJDo-pR4WIqbJx8CRlHg4iu9zA,457
37
38
  ics_query/tests/runs/calendars/simple-todo.ics,sha256=l9uHQD4eyiCE8STvd2tj5lAVaBrqUtpF_M8Pv6yf1es,327
38
39
  ics_query/tests/runs/calendars/three-events.ics,sha256=YvPfthOzMCR0DQhGR6uj_1Bltgax3uA1ETlkI4JUI08,828
39
- ics_query-0.3.1b0.dist-info/METADATA,sha256=pPdD_fvpGxjiWnkUYCpPCghCSnwMym-IwM8WViw5a00,53198
40
- ics_query-0.3.1b0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
41
- ics_query-0.3.1b0.dist-info/entry_points.txt,sha256=Jq_39vCKVOkNZjL7Wngf_04V_n_QRszLgLT2CbJKiH4,49
42
- ics_query-0.3.1b0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
43
- ics_query-0.3.1b0.dist-info/RECORD,,
40
+ ics_query-0.3.2b0.dist-info/METADATA,sha256=9MOLxp1rDhfK4VonU6T1I1OpmwAmafQiNNVy3ovmUnc,53535
41
+ ics_query-0.3.2b0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
42
+ ics_query-0.3.2b0.dist-info/entry_points.txt,sha256=Jq_39vCKVOkNZjL7Wngf_04V_n_QRszLgLT2CbJKiH4,49
43
+ ics_query-0.3.2b0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
44
+ ics_query-0.3.2b0.dist-info/RECORD,,