Skip to content

Commit a821a19

Browse files
author
Oliver Schrenk
committed
✨ Filter for calendar sources
1 parent 781a627 commit a821a19

File tree

4 files changed

+104
-2
lines changed

4 files changed

+104
-2
lines changed

Sources/Cli/Main.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ enum Main {
1313
let calendarFilter = CalendarFilter.build(
1414
selectCalendars: opts.selectCalendars,
1515
ignoreCalendars: opts.ignoreCalendars,
16+
selectCalendarSources: opts.selectCalendarSources,
17+
ignoreCalendarSources: opts.ignoreCalendarSources,
1618
selectCalendarTypes: opts.selectCalendarTypes,
1719
ignoreCalendarTypes: opts.ignoreCalendarTypes
1820
)

Sources/Cli/SharedOptions.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ struct SharedOptions: ParsableArguments {
3030
valueName: "v"
3131
)) var ignoreCalendars: [String] = []
3232

33+
@Option(help: ArgumentHelp(
34+
"Select calendar sources <s>. A comma separated list of calendar sources",
35+
valueName: "s"
36+
)) var selectCalendarSources: [String] = []
37+
38+
@Option(help: ArgumentHelp(
39+
"Ignore calendar sources <s>. A comma separated list of calendar sources",
40+
valueName: "s"
41+
)) var ignoreCalendarSources: [String] = []
42+
3343
@Option(help: ArgumentHelp(
3444
"Select calendar types <v>. A comma separated list of calendar types. " +
3545
"Available: [local|caldav|exchange|subscription|birthday]",

Sources/Filters/CalendarFilter.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,37 @@ class CalendarFilter {
3636
}
3737
}
3838

39+
static func selectSources(sources: [String]) -> ((PlanCalendar?) -> Bool) {
40+
{ calendar in
41+
// if no selection, allow everything
42+
if sources.isEmpty {
43+
return true
44+
}
45+
// if event has no valid calendar, don't show
46+
if calendar == nil {
47+
return false
48+
}
49+
50+
return sources.contains(calendar!.source)
51+
}
52+
}
53+
54+
static func ignoreSources(sources: [String]) -> ((PlanCalendar?) -> Bool) {
55+
{ calendar in
56+
// if no selection, allow everything
57+
if sources.isEmpty {
58+
return true
59+
}
60+
61+
// if event has no valid calendar, don't show
62+
if calendar == nil {
63+
return false
64+
}
65+
66+
return !sources.contains(calendar!.source)
67+
}
68+
}
69+
3970
static func selectTypes(types: [EKCalendarType]) -> ((PlanCalendar?) -> Bool) {
4071
{ calendar in
4172
// if no selection, allow everything
@@ -79,6 +110,8 @@ class CalendarFilter {
79110
static func build(
80111
selectCalendars: [String] = [],
81112
ignoreCalendars: [String] = [],
113+
selectCalendarSources: [String] = [],
114+
ignoreCalendarSources: [String] = [],
82115
selectCalendarTypes: [EKCalendarType] = [],
83116
ignoreCalendarTypes: [EKCalendarType] = []
84117
) -> ((PlanCalendar) -> Bool) {
@@ -96,6 +129,18 @@ class CalendarFilter {
96129
Log.write("added filter before: ignoreCalendars(\(ignoreCalendars))")
97130
}
98131

132+
if !selectCalendarSources.isEmpty {
133+
let f: (PlanCalendar) -> Bool = CalendarFilter.selectSources(sources: selectCalendarSources)
134+
filters.append(f)
135+
Log.write("added filter before: selectSources(\(selectCalendarSources))")
136+
}
137+
138+
if !ignoreCalendarSources.isEmpty {
139+
let f: (PlanCalendar) -> Bool = CalendarFilter.ignoreSources(sources: ignoreCalendarSources)
140+
filters.append(f)
141+
Log.write("added filter before: ignoreSources(\(ignoreCalendarSources))")
142+
}
143+
99144
if !selectCalendarTypes.isEmpty {
100145
let sct: (PlanCalendar) -> Bool = CalendarFilter.selectTypes(types: selectCalendarTypes)
101146
filters.append(sct)

Tests/CalendarFilterTest.swift

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import EventKit
44
import XCTest
55

66
final class CalendarFilterTests: XCTestCase {
7-
private func genCalendar(type: EKCalendarType = EKCalendarType.calDAV) -> PlanCalendar {
7+
private func genCalendar(
8+
type: EKCalendarType = EKCalendarType.calDAV,
9+
source: String = "Test"
10+
) -> PlanCalendar {
811
let id = "5E28ECB5-A07D-4FC8-82E4-5F37C38C786F"
912
let label = "Test"
10-
let source = "Test"
1113
let color = "#FFB3E4"
1214

1315
return PlanCalendar(
@@ -59,6 +61,49 @@ final class CalendarFilterTests: XCTestCase {
5961
XCTAssertEqual(actual, expected, "The calendar was not accepted")
6062
}
6163

64+
func testIgnoreCalendarSourcesMatching() {
65+
let source = "Personal"
66+
let calendar = genCalendar(source: source)
67+
let expected = false
68+
let actual = CalendarFilter.ignoreSources(sources: [source])(calendar)
69+
70+
XCTAssertEqual(actual, expected, "The calendar was accepted")
71+
}
72+
73+
func testIgnoreCalendarSourcesEmptyArray() {
74+
let calendar = genCalendar()
75+
let expected = true
76+
let actual = CalendarFilter.ignoreSources(sources: [])(calendar)
77+
78+
XCTAssertEqual(actual, expected, "The calendar was rejected")
79+
}
80+
81+
func testSelectCalendarSourcesMatching() {
82+
let source = "Personal"
83+
let calendar = genCalendar(source: source)
84+
let expected = true
85+
let actual = CalendarFilter.selectSources(sources: [source])(calendar)
86+
87+
XCTAssertEqual(actual, expected, "The calendar was rejected")
88+
}
89+
90+
func testSelectCalendarSourcesNotMatching() {
91+
let source = "Personal"
92+
let calendar = genCalendar(source: source)
93+
let expected = false
94+
let actual = CalendarFilter.selectSources(sources: ["not-existing"])(calendar)
95+
96+
XCTAssertEqual(actual, expected, "The calendar was accepted")
97+
}
98+
99+
func testSelectCalendarSourcesEmptyArray() {
100+
let calendar = genCalendar()
101+
let expected = true
102+
let actual = CalendarFilter.selectSources(sources: [])(calendar)
103+
104+
XCTAssertEqual(actual, expected, "The calendar was rejected")
105+
}
106+
62107
func testIgnoreCalendarTypesMatching() {
63108
let type = EKCalendarType.birthday
64109
let calendar = genCalendar(type: type)

0 commit comments

Comments
 (0)