icalcli 1.0.6__tar.gz → 1.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: icalcli
3
- Version: 1.0.6
3
+ Version: 1.1
4
4
  Summary: Icalendar Calendar Command Line Interface
5
5
  Home-page: https://github.com/jrvarma/icalcli
6
6
  Maintainer: Jayanth R. Varma
@@ -28,7 +28,7 @@ Requires-Dist: parsedatetime; extra == "parsedatetime"
28
28
 
29
29
  Unlike [gcalcli](https://github.com/insanum/gcalcli) which is tied to Google Calendar, `icalcli` is agnostic to (abstracts away from) the actual backend calendar service. It relies on a backend interface which interacts with the backend calendar to perform all the CRUD (Create, Retrieve, Update and Delete) operations on the actual calendar. The package includes two backends:
30
30
 
31
- * The `etesync_backend` subpackage provides a backend interface to the [EteSync](https://www.etesync.com/) calendar. In fact, `icalcli` was created primarily to provide a command line interface to my self hosted `EteSync` calendar.
31
+ * The `etesync_backend` subpackage provides a backend interface to the [EteSync](https://www.etesync.com/) calendar (versions 1.0 and 2.0). In fact, `icalcli` was created primarily to provide a command line interface to my self hosted `EteSync` calendar.
32
32
 
33
33
  * The `file_backend` subpackage provides a backend interface to a calendar contained in a local `ics` file. This is useful as a viewer/editor of `ics` files. It is also useful to try out `icalci` without having any other backend configured.
34
34
 
@@ -55,6 +55,12 @@ The two included backends would also be useful to those who wish to write their
55
55
  pip install icalcli
56
56
  ```
57
57
 
58
+ or via `pipx`:
59
+
60
+ ```sh
61
+ pipx install icalcli
62
+ ```
63
+
58
64
  ### Install from source
59
65
 
60
66
  ```sh
@@ -62,6 +68,13 @@ git clone https://github.com/jrvarma/icalcli.git
62
68
  cd icalcli
63
69
  python setup.py install
64
70
  ```
71
+
72
+ or via `pipx`:
73
+
74
+ ```sh
75
+ pipx install . --editable
76
+ ```
77
+
65
78
  ## Usage
66
79
 
67
80
  ### Command line arguments
@@ -102,7 +115,7 @@ backend_interface = ICSInterface(["/path/to/ics-file-1", "/path/to/ics-file-2"])
102
115
 
103
116
  ```
104
117
 
105
- #### Example configuration for etesync_backend
118
+ #### Example configuration for etesync_backend (etesync 1.0)
106
119
 
107
120
  This configuration assumes that all the credentials are stored in a plain text (`json`) file. In practice, you would use a more secure storage (perhaps, the `Gnome keyring`) or just read it from the terminal.
108
121
 
@@ -121,6 +134,34 @@ backend_interface = EtesyncInterface(
121
134
  ```
122
135
  See the [Example code](https://github.com/jrvarma/icalcli/issues/1#issuecomment-979851222) for getting the `uid` and `authToken` for the `etesync` calendar.
123
136
 
137
+ #### Example configuration for etebase_backend (etesync 2.0)
138
+
139
+ This configuration assumes that all the credentials are stored in a plain text (`json`) file. In practice, you would use a more secure storage (perhaps, the `Gnome keyring`) or just read it from the terminal.
140
+
141
+ ```
142
+ from icalcli import EtebaseInterface
143
+ import json
144
+
145
+ conf_file = '/path/to/json-file'
146
+ with open(conf_file, 'r') as fp:
147
+ c = json.load(fp)
148
+
149
+ backend_interface = EtebaseInterface(c['user'], c['server_url'], c['password'],
150
+ c['calendar_uid'], silent=False)
151
+ ```
152
+
153
+ The `calendar_uid` can be obtained using the following code. This code assumes that the `dict c` has been populated with the credentials from the `json` file as above.
154
+
155
+ ```
156
+ from etebase import Client, Account, FetchOptions
157
+
158
+ client = Client(c['user'], c['server_url'])
159
+ etebase = Account.login(client, c['user'], c['password'])
160
+ col_mgr = etebase.get_collection_manager()
161
+ print({col.uid: col.meta
162
+ for col in col_mgr.list("etebase.vevent").data})
163
+ ```
164
+
124
165
  ## Recurring events and default search period
125
166
 
126
167
  `icalcli` understands the `RRULE`, `RDATE`, `EXRULE`, `EXDATE` elements of the `icalendar` specification. These elements can be added while creating or editing events using `--rrule`, `--rdate`, `--exrule` and `--exdate` options.
@@ -6,7 +6,7 @@
6
6
 
7
7
  Unlike [gcalcli](https://github.com/insanum/gcalcli) which is tied to Google Calendar, `icalcli` is agnostic to (abstracts away from) the actual backend calendar service. It relies on a backend interface which interacts with the backend calendar to perform all the CRUD (Create, Retrieve, Update and Delete) operations on the actual calendar. The package includes two backends:
8
8
 
9
- * The `etesync_backend` subpackage provides a backend interface to the [EteSync](https://www.etesync.com/) calendar. In fact, `icalcli` was created primarily to provide a command line interface to my self hosted `EteSync` calendar.
9
+ * The `etesync_backend` subpackage provides a backend interface to the [EteSync](https://www.etesync.com/) calendar (versions 1.0 and 2.0). In fact, `icalcli` was created primarily to provide a command line interface to my self hosted `EteSync` calendar.
10
10
 
11
11
  * The `file_backend` subpackage provides a backend interface to a calendar contained in a local `ics` file. This is useful as a viewer/editor of `ics` files. It is also useful to try out `icalci` without having any other backend configured.
12
12
 
@@ -33,6 +33,12 @@ The two included backends would also be useful to those who wish to write their
33
33
  pip install icalcli
34
34
  ```
35
35
 
36
+ or via `pipx`:
37
+
38
+ ```sh
39
+ pipx install icalcli
40
+ ```
41
+
36
42
  ### Install from source
37
43
 
38
44
  ```sh
@@ -40,6 +46,13 @@ git clone https://github.com/jrvarma/icalcli.git
40
46
  cd icalcli
41
47
  python setup.py install
42
48
  ```
49
+
50
+ or via `pipx`:
51
+
52
+ ```sh
53
+ pipx install . --editable
54
+ ```
55
+
43
56
  ## Usage
44
57
 
45
58
  ### Command line arguments
@@ -80,7 +93,7 @@ backend_interface = ICSInterface(["/path/to/ics-file-1", "/path/to/ics-file-2"])
80
93
 
81
94
  ```
82
95
 
83
- #### Example configuration for etesync_backend
96
+ #### Example configuration for etesync_backend (etesync 1.0)
84
97
 
85
98
  This configuration assumes that all the credentials are stored in a plain text (`json`) file. In practice, you would use a more secure storage (perhaps, the `Gnome keyring`) or just read it from the terminal.
86
99
 
@@ -99,6 +112,34 @@ backend_interface = EtesyncInterface(
99
112
  ```
100
113
  See the [Example code](https://github.com/jrvarma/icalcli/issues/1#issuecomment-979851222) for getting the `uid` and `authToken` for the `etesync` calendar.
101
114
 
115
+ #### Example configuration for etebase_backend (etesync 2.0)
116
+
117
+ This configuration assumes that all the credentials are stored in a plain text (`json`) file. In practice, you would use a more secure storage (perhaps, the `Gnome keyring`) or just read it from the terminal.
118
+
119
+ ```
120
+ from icalcli import EtebaseInterface
121
+ import json
122
+
123
+ conf_file = '/path/to/json-file'
124
+ with open(conf_file, 'r') as fp:
125
+ c = json.load(fp)
126
+
127
+ backend_interface = EtebaseInterface(c['user'], c['server_url'], c['password'],
128
+ c['calendar_uid'], silent=False)
129
+ ```
130
+
131
+ The `calendar_uid` can be obtained using the following code. This code assumes that the `dict c` has been populated with the credentials from the `json` file as above.
132
+
133
+ ```
134
+ from etebase import Client, Account, FetchOptions
135
+
136
+ client = Client(c['user'], c['server_url'])
137
+ etebase = Account.login(client, c['user'], c['password'])
138
+ col_mgr = etebase.get_collection_manager()
139
+ print({col.uid: col.meta
140
+ for col in col_mgr.list("etebase.vevent").data})
141
+ ```
142
+
102
143
  ## Recurring events and default search period
103
144
 
104
145
  `icalcli` understands the `RRULE`, `RDATE`, `EXRULE`, `EXDATE` elements of the `icalendar` specification. These elements can be added while creating or editing events using `--rrule`, `--rdate`, `--exrule` and `--exdate` options.
@@ -4,7 +4,9 @@ __author__ = 'Jayanth Varma (modified gcalcli by Eric Davis et al.)'
4
4
  from icalcli.icalcli import IcalendarInterface # noqa F401
5
5
  try:
6
6
  from icalcli.etesync_backend.etesync_crud import EtesyncCRUD # noqa F401
7
- from icalcli.etesync_backend.etesync_interface import EtesyncInterface # noqa F401
7
+ from icalcli.etesync_backend.etesync_interface import EtesyncInterface # noqa F
8
+ from icalcli.etesync_backend.etebase_crud import EtebaseCRUD # noqa F401
9
+ from icalcli.etesync_backend.etebase_interface import EtebaseInterface # noqa F401
8
10
  except ImportError:
9
11
  pass
10
12
 
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env python
2
+
3
+ # this is part of the etesync 2.0 backend
4
+ # for etesync 1.0 backend see etesync_crud.py
5
+
6
+ from etebase import Client, Account, FetchOptions
7
+ from time import sleep, time
8
+
9
+ # The EtesyncCRUD class exposes methods for each of the CRUD operations
10
+ # (Create, Retrieve, Update and Delete) and for sync with the server.
11
+ # It handles only one calendar
12
+
13
+ # The class is initialized with user details, authToken and
14
+ # EITHER the encryption password OR the cipher key.
15
+
16
+ # Intended usage is that a calling program (a CLI) obtains user credentials
17
+ # from terminal input or some secure storage (like a key ring)
18
+ # and then creates an instance of EtesyncCRUD as follows:
19
+
20
+ # crud = EtebaseCRUD(user, server_url, password, calendar_uid)
21
+
22
+ # The CLI program can then perform CRUD operations by calling
23
+ # crud.create_event, crud.retrieve_event,
24
+ # crud.update_event and crud.delete_event
25
+
26
+ # The CLI must explicitly call crud.sync when needed. For example:
27
+ # (a) if the server has been updated from another device
28
+ # (b) after any CRUD operation other than Retrieve
29
+
30
+ # No exception handling is done. That is left to the CLI.
31
+
32
+
33
+ class EtebaseCRUD:
34
+ def __init__(self, user, server_url, password, calendar_uid, silent=True):
35
+ """Initialize
36
+
37
+ Parameters
38
+ ----------
39
+ user : etebase username
40
+ password : etebase password
41
+ server_url : url of etebase server
42
+ calendar_uid : uid of calendar
43
+ """
44
+ client = Client(user, server_url)
45
+ etebase = Account.login(client, user, password)
46
+ col_mgr = etebase.get_collection_manager()
47
+ collection = col_mgr.fetch(calendar_uid)
48
+ self.item_mgr = col_mgr.get_item_manager(collection)
49
+ self.sync(silent)
50
+
51
+ def create_event(self, event, uid):
52
+ """Create event
53
+
54
+ Parameters
55
+ ----------
56
+ event : iCalendar file as bytes
57
+ (calendar containing one event to be added)
58
+ """
59
+ item = self.item_mgr.create(
60
+ {
61
+ "name": uid,
62
+ "mtime": int(round(time() * 1000))
63
+ },
64
+ event
65
+ )
66
+ self.item_mgr.batch([item])
67
+
68
+ def update_event(self, event, uid):
69
+ """Edit event
70
+
71
+ Parameters
72
+ ----------
73
+ event : iCalendar file as bytes
74
+ (calendar containing one event to be updated)
75
+ uid : uid of event to be updated
76
+ """
77
+ item = self.item_mgr.fetch(uid)
78
+ item.content = event
79
+ self.item_mgr.batch([item])
80
+
81
+ def retrieve_event(self, uid):
82
+ r"""Retrieve event by uid
83
+
84
+ Parameters
85
+ ----------
86
+ uid : uid of event to be retrieved
87
+
88
+ Returns
89
+ -------
90
+ iCalendar file (as a string)
91
+ """
92
+ return self.item_mgr.fetch(uid).content.decode()
93
+
94
+ def all_events(self):
95
+ """Retrieve all events in calendar
96
+
97
+ Returns
98
+ -------
99
+ List of iCalendar files (as strings)
100
+ """
101
+ return [e.content.decode() for e in self.items.data if not e.deleted]
102
+
103
+ def delete_event(self, uid):
104
+ """Delete event and sync calendar
105
+
106
+ Parameters
107
+ ----------
108
+ uid : uid of event to be deleted
109
+ """
110
+ item = self.item_mgr.fetch(uid)
111
+ item.delete()
112
+ self.item_mgr.batch([item])
113
+
114
+ def sync(self, silent=False):
115
+ """Initialize
116
+
117
+ Parameters
118
+ ----------
119
+ silent : boolean whether to report sync attempt and success
120
+ """
121
+ silent or print("Syncing with server. Please wait")
122
+ msg = "etebase fetch attempt {:} failed. Will retry after {:} seconds"
123
+ delay = 5
124
+ synced = False
125
+ for i in range(5):
126
+ try:
127
+ self.items = self.item_mgr.list(FetchOptions().limit(10**6))
128
+ synced = True
129
+ break
130
+ except Exception:
131
+ silent or print(msg.format(i+1, delay))
132
+ sleep(delay)
133
+ if synced:
134
+ silent or print("Syncing completed.")
135
+ self.all_events()
136
+ else:
137
+ print("Syncing with server failed after 5 attempts")
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env python
2
+
3
+ # this is part of the etesync 2.0 backend
4
+ # for etesync 1.0 backend see etesync_interface.py
5
+
6
+ from icalcli.etesync_backend.etebase_crud import EtebaseCRUD
7
+ from icalendar import Calendar
8
+
9
+
10
+ # The EtebaseInterface class is basically a wrapper around the
11
+ # EtebaseCRUD class from which it is derived
12
+ # The CRUD operations (Create, Retrieve, Update and Delete)
13
+ # work with icalendar events (VEVENT). While calling EtebaseCRUD methods,
14
+ # both inputs and return values are converted to/from
15
+ # ics calendar bytes/strings
16
+
17
+ # The class is initialized with user details and credentials.
18
+
19
+ # Intended usage is that a calling program obtains user credentials
20
+ # from terminal input or some secure storage (like a key ring)
21
+ # and then creates an instance of EtebaseCRUD as follows:
22
+
23
+ # etes = EtebaseInterface(user, server_url, password, calendar_uid)
24
+
25
+ # The calling program can then perform CRUD operations by calling
26
+ # etes.create_event, etes.retrieve_event,
27
+ # etes.update_event and etes.delete_event
28
+
29
+ # The calling program must explicitly call etes.sync when needed. For example:
30
+ # (a) if the server has been updated from another device
31
+ # (b) after any CRUD operation other than Retrieve
32
+
33
+ # No exception handling is done. That is left to the calling program.
34
+
35
+
36
+ class EtebaseInterface (EtebaseCRUD):
37
+ def __init__(self, user, server_url, password, calendar_uid, silent=True):
38
+ r"""Initialize EtebaseInterface
39
+
40
+ Parameters
41
+ ----------
42
+ user : etebase username
43
+ password : etebase password
44
+ server_url : url of etebase server
45
+ calendar_uid : uid of calendar
46
+ """
47
+ super(EtebaseInterface, self).__init__(
48
+ user, server_url, password, calendar_uid, silent)
49
+ self.all_events()
50
+
51
+ def all_events(self):
52
+ self.events = [Calendar.from_ical(ev).walk('VEVENT')[0]
53
+ for ev in EtebaseCRUD.all_events(self)]
54
+
55
+ def create_event(self, event, vtimezone=None):
56
+ r"""Create event
57
+
58
+ Parameters
59
+ ----------
60
+ event : event to be added (iCalendar object)
61
+ """
62
+ ics = self.event_to_ics(event, vtimezone)
63
+ EtebaseCRUD.create_event(self, ics)
64
+
65
+ def update_event(self, event, vtimezone=None):
66
+ r"""Update event
67
+
68
+ Parameters
69
+ ----------
70
+ event : event to be added (iCalendar object)
71
+ """
72
+ uid = event.decoded('uid').decode()
73
+ ics = self.event_to_ics(event, vtimezone)
74
+ EtebaseCRUD.update_event(self, ics, uid)
75
+
76
+ def event_to_ics(self, event, vtimezone=None):
77
+ r"""Make calendar byte array (ics) from event
78
+
79
+ Parameters
80
+ ----------
81
+ event : event to be added (iCalendar object)
82
+ """
83
+ cal = Calendar()
84
+ cal.add_component(event)
85
+ if vtimezone:
86
+ cal.add_component(vtimezone)
87
+ ics = cal.to_ical()
88
+ return ics
89
+
90
+ def sync(self, vtimezone=None):
91
+ r"""Sync with server and rebuild vevent list
92
+ """
93
+ EtebaseCRUD.sync(self)
94
+ self.all_events()
@@ -1,5 +1,8 @@
1
1
  #!/usr/bin/env python
2
2
 
3
+ # this is part of the etesync 1.0 backend
4
+ # for etesync 2.0 backend see etebase_crud.py
5
+
3
6
  import etesync as api
4
7
  from time import sleep
5
8
 
@@ -1,3 +1,8 @@
1
+ #!/usr/bin/env python
2
+
3
+ # this is part of the etesync 1.0 backend
4
+ # for etesync 2.0 backend see etebase_interface.py
5
+
1
6
  from icalcli.etesync_backend.etesync_crud import EtesyncCRUD
2
7
  from icalendar import Calendar
3
8
 
@@ -61,9 +61,9 @@ class ICSInterface:
61
61
  return
62
62
  if self.backup:
63
63
  with NamedTemporaryFile(mode='w',
64
- suffix=self.filepath.suffix,
65
- prefix=self.filepath.name,
66
- dir=self.filepath.parent,
64
+ suffix=self.filepaths[0].suffix,
65
+ prefix=self.filepaths[0].name,
66
+ dir=self.filepaths[0].parent,
67
67
  delete=False) as fp:
68
68
  fp.write(self.ics)
69
69
  cal = Calendar()
@@ -72,6 +72,6 @@ class ICSInterface:
72
72
  if vtimezone:
73
73
  cal.add_component(vtimezone)
74
74
  self.ics = cal.to_ical().decode()
75
- with open(self.filepath, 'w') as fp:
75
+ with open(self.filepaths[0], 'w') as fp:
76
76
  fp.write(self.ics)
77
77
  self.all_events()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: icalcli
3
- Version: 1.0.6
3
+ Version: 1.1
4
4
  Summary: Icalendar Calendar Command Line Interface
5
5
  Home-page: https://github.com/jrvarma/icalcli
6
6
  Maintainer: Jayanth R. Varma
@@ -28,7 +28,7 @@ Requires-Dist: parsedatetime; extra == "parsedatetime"
28
28
 
29
29
  Unlike [gcalcli](https://github.com/insanum/gcalcli) which is tied to Google Calendar, `icalcli` is agnostic to (abstracts away from) the actual backend calendar service. It relies on a backend interface which interacts with the backend calendar to perform all the CRUD (Create, Retrieve, Update and Delete) operations on the actual calendar. The package includes two backends:
30
30
 
31
- * The `etesync_backend` subpackage provides a backend interface to the [EteSync](https://www.etesync.com/) calendar. In fact, `icalcli` was created primarily to provide a command line interface to my self hosted `EteSync` calendar.
31
+ * The `etesync_backend` subpackage provides a backend interface to the [EteSync](https://www.etesync.com/) calendar (versions 1.0 and 2.0). In fact, `icalcli` was created primarily to provide a command line interface to my self hosted `EteSync` calendar.
32
32
 
33
33
  * The `file_backend` subpackage provides a backend interface to a calendar contained in a local `ics` file. This is useful as a viewer/editor of `ics` files. It is also useful to try out `icalci` without having any other backend configured.
34
34
 
@@ -55,6 +55,12 @@ The two included backends would also be useful to those who wish to write their
55
55
  pip install icalcli
56
56
  ```
57
57
 
58
+ or via `pipx`:
59
+
60
+ ```sh
61
+ pipx install icalcli
62
+ ```
63
+
58
64
  ### Install from source
59
65
 
60
66
  ```sh
@@ -62,6 +68,13 @@ git clone https://github.com/jrvarma/icalcli.git
62
68
  cd icalcli
63
69
  python setup.py install
64
70
  ```
71
+
72
+ or via `pipx`:
73
+
74
+ ```sh
75
+ pipx install . --editable
76
+ ```
77
+
65
78
  ## Usage
66
79
 
67
80
  ### Command line arguments
@@ -102,7 +115,7 @@ backend_interface = ICSInterface(["/path/to/ics-file-1", "/path/to/ics-file-2"])
102
115
 
103
116
  ```
104
117
 
105
- #### Example configuration for etesync_backend
118
+ #### Example configuration for etesync_backend (etesync 1.0)
106
119
 
107
120
  This configuration assumes that all the credentials are stored in a plain text (`json`) file. In practice, you would use a more secure storage (perhaps, the `Gnome keyring`) or just read it from the terminal.
108
121
 
@@ -121,6 +134,34 @@ backend_interface = EtesyncInterface(
121
134
  ```
122
135
  See the [Example code](https://github.com/jrvarma/icalcli/issues/1#issuecomment-979851222) for getting the `uid` and `authToken` for the `etesync` calendar.
123
136
 
137
+ #### Example configuration for etebase_backend (etesync 2.0)
138
+
139
+ This configuration assumes that all the credentials are stored in a plain text (`json`) file. In practice, you would use a more secure storage (perhaps, the `Gnome keyring`) or just read it from the terminal.
140
+
141
+ ```
142
+ from icalcli import EtebaseInterface
143
+ import json
144
+
145
+ conf_file = '/path/to/json-file'
146
+ with open(conf_file, 'r') as fp:
147
+ c = json.load(fp)
148
+
149
+ backend_interface = EtebaseInterface(c['user'], c['server_url'], c['password'],
150
+ c['calendar_uid'], silent=False)
151
+ ```
152
+
153
+ The `calendar_uid` can be obtained using the following code. This code assumes that the `dict c` has been populated with the credentials from the `json` file as above.
154
+
155
+ ```
156
+ from etebase import Client, Account, FetchOptions
157
+
158
+ client = Client(c['user'], c['server_url'])
159
+ etebase = Account.login(client, c['user'], c['password'])
160
+ col_mgr = etebase.get_collection_manager()
161
+ print({col.uid: col.meta
162
+ for col in col_mgr.list("etebase.vevent").data})
163
+ ```
164
+
124
165
  ## Recurring events and default search period
125
166
 
126
167
  `icalcli` understands the `RRULE`, `RDATE`, `EXRULE`, `EXDATE` elements of the `icalendar` specification. These elements can be added while creating or editing events using `--rrule`, `--rdate`, `--exrule` and `--exdate` options.
@@ -13,6 +13,8 @@ icalcli.egg-info/entry_points.txt
13
13
  icalcli.egg-info/requires.txt
14
14
  icalcli.egg-info/top_level.txt
15
15
  icalcli/etesync_backend/__init__.py
16
+ icalcli/etesync_backend/etebase_crud.py
17
+ icalcli/etesync_backend/etebase_interface.py
16
18
  icalcli/etesync_backend/etesync_crud.py
17
19
  icalcli/etesync_backend/etesync_interface.py
18
20
  icalcli/file_backend/__init__.py
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
  long_description = fh.read()
6
6
 
7
7
  setup(name='icalcli',
8
- version='1.0.6',
8
+ version='1.1',
9
9
  maintainer='Jayanth R. Varma',
10
10
  maintainer_email='jrvarma@gmail.com',
11
11
  description='Icalendar Calendar Command Line Interface',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes