things-py 0.0.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.
@@ -0,0 +1,137 @@
1
+ Metadata-Version: 2.1
2
+ Name: things.py
3
+ Version: 0.0.1
4
+ Summary: A simple Python 3 library to read your Things app data.
5
+ Home-page: https://github.com/thingsapi/things.py
6
+ Author: Alexander Willner, Michael B.
7
+ Author-email: alex@willner.ws
8
+ License: UNKNOWN
9
+ Description: # Things Python API
10
+
11
+ A simple Python 3 library to read your [Things app](https://culturedcode.com/things) data.
12
+
13
+ [![Build Status](https://github.com/thingsapi/things.py/workflows/Build-Test/badge.svg)](https://github.com/thingsapi/things.py/actions)
14
+ [![Coverage Status](https://codecov.io/gh/thingsapi/things.py/branch/main/graph/badge.svg?token=DBWGKAEYAP)](https://codecov.io/gh/thingsapi/things.py)
15
+ [![GitHub Release](https://img.shields.io/github/v/release/thingsapi/things.py?sort=semver)](https://github.com/thingsapi/things.py/releases)
16
+ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
17
+ [![PyPI - Downloads](https://img.shields.io/pypi/dm/things?label=pypi%20downloads)](https://pypi.org/project/things/)
18
+ [![GitHub Download Count](https://img.shields.io/github/downloads/thingsapi/things.py/total.svg)](https://github.com/thingsapi/things.py/releases)
19
+ [![GitHub Issues](https://img.shields.io/github/issues/thingsapi/things.py)](https://github.com/thingsapi/things.py/issues)
20
+ [![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/quality/g/thingsapi/things.py)](https://scrutinizer-ci.com/g/thingsapi/things.py/?branch=master)
21
+
22
+ ## Table of Contents
23
+
24
+ - [Install](#install)
25
+ - [Examples](#examples)
26
+ - [Background](#background)
27
+ - [Things URLs](#things-urls)
28
+
29
+ ## Install
30
+
31
+ ```sh
32
+ $ pip3 install things.py
33
+ # or
34
+ $ git clone https://github.com/thingsapi/things.py && cd things.py && make install
35
+ ```
36
+
37
+ ## Examples
38
+
39
+ ```python
40
+ >>> import things
41
+ >>> things.todos()
42
+ [{'uuid': '2Ukg8I2nLukhyEM7wYiBeb',
43
+ 'type': 'to-do',
44
+ 'title': 'Make reservation for dinner',
45
+ 'project': 'bNj6TPdKYhY6fScvXWVRDX',
46
+ ...},
47
+ {'uuid': 'RLZroza3jz0XPs3uAlynS7',
48
+ 'type': 'to-do',
49
+ 'title': 'Buy a whiteboard and accessories',
50
+ 'project': 'w8oSP1HjWstPin8RMaJOtB',
51
+ 'notes': "Something around 4' x 3' that's free-standing, two-sided, and magnetic.",
52
+ 'checklist': True,
53
+ ...
54
+ >>> things.todos('RLZroza3jz0XPs3uAlynS7')
55
+ {'uuid': 'RLZroza3jz0XPs3uAlynS7',
56
+ 'type': 'to-do',
57
+ 'title': 'Buy a whiteboard and accessories',
58
+ ...
59
+ 'checklist': [
60
+ {'title': 'Cleaning Spray', 'status': 'completed', ...},
61
+ {'title': 'Magnetic Eraser', 'status': 'incomplete', ...},
62
+ {'title': 'Round magnets', 'status': 'incomplete', ...}
63
+ ]
64
+ ...
65
+ }
66
+
67
+ >>> things.projects()
68
+ [{'uuid': 'bNj6TPdKYhY6fScvXWVRDX',
69
+ 'type': 'project',
70
+ 'title': 'Throw Birthday Party',
71
+ 'area': 'bNj6TPdKYhY6fScvXWVRDX',
72
+ ...},
73
+ {'uuid': 'w8oSP1HjWstPin8RMaJOtB',
74
+ 'type': 'project',
75
+ 'title': 'Set Up Home Office',
76
+ 'area': 'Gw9QefIdgR6nPEoY5hBNSh',
77
+ ...
78
+
79
+ >>> things.areas()
80
+ [{'uuid': 'ToLxnnBrWkfHC3tkx4vxdV',
81
+ 'type': 'area',
82
+ 'title': 'Family',
83
+ ...},
84
+ {'uuid': 'Gw9QefIdgR6nPEoY5hBNSh',
85
+ 'type': 'area',
86
+ 'title': 'Apartment',
87
+ ...
88
+
89
+ >>> things.tags()
90
+ [{'uuid': 'CKILg3kKF2jlCRisNFcqOj',
91
+ 'type': 'tag',
92
+ 'title': 'Home',
93
+ 'shortcut': None},
94
+ {'uuid': 'gfmpz8zxnyfqMDvRi3E8vo',
95
+ 'type': 'tag',
96
+ 'title': 'Office',
97
+ 'shortcut': None},
98
+ ...
99
+
100
+ >>> things.get('CKILg3kKF2jlCRisNFcqOj')
101
+ {'uuid': 'CKILg3kKF2jlCRisNFcqOj',
102
+ 'type': 'tag',
103
+ 'title': 'Home',
104
+ 'shortcut': None}
105
+
106
+ ```
107
+
108
+ ## Background
109
+
110
+ The task management app Things stores all your to-dos in a SQLite database file (details [here](https://culturedcode.com/things/support/articles/2982272/#get-the-things-3-database-file)). This format is machine-readable, not human-readable. The aim of this project is let you access all your data in a human-readable way. We thereby stay as true to the database as possible while doing SQL Joins and transformations to aid understanding of the data.
111
+
112
+ Here's the terminology used involving the database:
113
+
114
+ - area
115
+ - tag
116
+ - task
117
+ - type
118
+ - `'to-do'`: may have a checklist; may be in an area and have tags.
119
+ - `'project'`: may have to-dos and headings; may be in an area and have tags.
120
+ - `'heading'`: part of a project; groups "tasks".
121
+ - status: `"incomplete"`, `"canceled"`, or `"completed"`
122
+ - trashed: `True` or `False`
123
+ - start: `"Inbox"`, `"Anytime"`, or `"Someday"`
124
+ - checklist item (contained within a to-do)
125
+
126
+ ## Things URLs
127
+
128
+ You can make good use of the `uuid` to link to to-dos, areas, tags, and more from other apps. Read more [here](https://culturedcode.com/things/blog/2018/02/hey-things/).
129
+
130
+ Platform: UNKNOWN
131
+ Classifier: Development Status :: 3 - Alpha
132
+ Classifier: Programming Language :: Python :: 3
133
+ Classifier: License :: OSI Approved :: Apache Software License
134
+ Classifier: Operating System :: MacOS :: MacOS X
135
+ Classifier: Natural Language :: English
136
+ Requires-Python: >=3.6
137
+ Description-Content-Type: text/markdown
@@ -0,0 +1,120 @@
1
+ # Things Python API
2
+
3
+ A simple Python 3 library to read your [Things app](https://culturedcode.com/things) data.
4
+
5
+ [![Build Status](https://github.com/thingsapi/things.py/workflows/Build-Test/badge.svg)](https://github.com/thingsapi/things.py/actions)
6
+ [![Coverage Status](https://codecov.io/gh/thingsapi/things.py/branch/main/graph/badge.svg?token=DBWGKAEYAP)](https://codecov.io/gh/thingsapi/things.py)
7
+ [![GitHub Release](https://img.shields.io/github/v/release/thingsapi/things.py?sort=semver)](https://github.com/thingsapi/things.py/releases)
8
+ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
9
+ [![PyPI - Downloads](https://img.shields.io/pypi/dm/things?label=pypi%20downloads)](https://pypi.org/project/things/)
10
+ [![GitHub Download Count](https://img.shields.io/github/downloads/thingsapi/things.py/total.svg)](https://github.com/thingsapi/things.py/releases)
11
+ [![GitHub Issues](https://img.shields.io/github/issues/thingsapi/things.py)](https://github.com/thingsapi/things.py/issues)
12
+ [![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/quality/g/thingsapi/things.py)](https://scrutinizer-ci.com/g/thingsapi/things.py/?branch=master)
13
+
14
+ ## Table of Contents
15
+
16
+ - [Install](#install)
17
+ - [Examples](#examples)
18
+ - [Background](#background)
19
+ - [Things URLs](#things-urls)
20
+
21
+ ## Install
22
+
23
+ ```sh
24
+ $ pip3 install things.py
25
+ # or
26
+ $ git clone https://github.com/thingsapi/things.py && cd things.py && make install
27
+ ```
28
+
29
+ ## Examples
30
+
31
+ ```python
32
+ >>> import things
33
+ >>> things.todos()
34
+ [{'uuid': '2Ukg8I2nLukhyEM7wYiBeb',
35
+ 'type': 'to-do',
36
+ 'title': 'Make reservation for dinner',
37
+ 'project': 'bNj6TPdKYhY6fScvXWVRDX',
38
+ ...},
39
+ {'uuid': 'RLZroza3jz0XPs3uAlynS7',
40
+ 'type': 'to-do',
41
+ 'title': 'Buy a whiteboard and accessories',
42
+ 'project': 'w8oSP1HjWstPin8RMaJOtB',
43
+ 'notes': "Something around 4' x 3' that's free-standing, two-sided, and magnetic.",
44
+ 'checklist': True,
45
+ ...
46
+ >>> things.todos('RLZroza3jz0XPs3uAlynS7')
47
+ {'uuid': 'RLZroza3jz0XPs3uAlynS7',
48
+ 'type': 'to-do',
49
+ 'title': 'Buy a whiteboard and accessories',
50
+ ...
51
+ 'checklist': [
52
+ {'title': 'Cleaning Spray', 'status': 'completed', ...},
53
+ {'title': 'Magnetic Eraser', 'status': 'incomplete', ...},
54
+ {'title': 'Round magnets', 'status': 'incomplete', ...}
55
+ ]
56
+ ...
57
+ }
58
+
59
+ >>> things.projects()
60
+ [{'uuid': 'bNj6TPdKYhY6fScvXWVRDX',
61
+ 'type': 'project',
62
+ 'title': 'Throw Birthday Party',
63
+ 'area': 'bNj6TPdKYhY6fScvXWVRDX',
64
+ ...},
65
+ {'uuid': 'w8oSP1HjWstPin8RMaJOtB',
66
+ 'type': 'project',
67
+ 'title': 'Set Up Home Office',
68
+ 'area': 'Gw9QefIdgR6nPEoY5hBNSh',
69
+ ...
70
+
71
+ >>> things.areas()
72
+ [{'uuid': 'ToLxnnBrWkfHC3tkx4vxdV',
73
+ 'type': 'area',
74
+ 'title': 'Family',
75
+ ...},
76
+ {'uuid': 'Gw9QefIdgR6nPEoY5hBNSh',
77
+ 'type': 'area',
78
+ 'title': 'Apartment',
79
+ ...
80
+
81
+ >>> things.tags()
82
+ [{'uuid': 'CKILg3kKF2jlCRisNFcqOj',
83
+ 'type': 'tag',
84
+ 'title': 'Home',
85
+ 'shortcut': None},
86
+ {'uuid': 'gfmpz8zxnyfqMDvRi3E8vo',
87
+ 'type': 'tag',
88
+ 'title': 'Office',
89
+ 'shortcut': None},
90
+ ...
91
+
92
+ >>> things.get('CKILg3kKF2jlCRisNFcqOj')
93
+ {'uuid': 'CKILg3kKF2jlCRisNFcqOj',
94
+ 'type': 'tag',
95
+ 'title': 'Home',
96
+ 'shortcut': None}
97
+
98
+ ```
99
+
100
+ ## Background
101
+
102
+ The task management app Things stores all your to-dos in a SQLite database file (details [here](https://culturedcode.com/things/support/articles/2982272/#get-the-things-3-database-file)). This format is machine-readable, not human-readable. The aim of this project is let you access all your data in a human-readable way. We thereby stay as true to the database as possible while doing SQL Joins and transformations to aid understanding of the data.
103
+
104
+ Here's the terminology used involving the database:
105
+
106
+ - area
107
+ - tag
108
+ - task
109
+ - type
110
+ - `'to-do'`: may have a checklist; may be in an area and have tags.
111
+ - `'project'`: may have to-dos and headings; may be in an area and have tags.
112
+ - `'heading'`: part of a project; groups "tasks".
113
+ - status: `"incomplete"`, `"canceled"`, or `"completed"`
114
+ - trashed: `True` or `False`
115
+ - start: `"Inbox"`, `"Anytime"`, or `"Someday"`
116
+ - checklist item (contained within a to-do)
117
+
118
+ ## Things URLs
119
+
120
+ You can make good use of the `uuid` to link to to-dos, areas, tags, and more from other apps. Read more [here](https://culturedcode.com/things/blog/2018/02/hey-things/).
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,54 @@
1
+ """A simple Python 3 library to read your Things app data."""
2
+
3
+ import os
4
+ from setuptools import setup, find_packages # type: ignore
5
+
6
+
7
+ def package_files(directory):
8
+ """Automatically add data resources."""
9
+ paths = []
10
+ # pylint: disable=unused-variable
11
+ for (path, _directories, filenames) in os.walk(directory):
12
+ for filename in filenames:
13
+ paths.append((directory, [os.path.join(path, filename)]))
14
+ return paths
15
+
16
+
17
+ APP = ['']
18
+ APP_NAME = "Things"
19
+ AUTHOR = "Alexander Willner, Michael B."
20
+ AUTHOR_MAIL = "alex@willner.ws"
21
+ DESCRIPTON = "A simple Python 3 library to read your Things app data."
22
+ URL = "https://github.com/thingsapi/things.py"
23
+ VERSION = "0.0.1"
24
+ DATA_FILES = package_files('')
25
+ OPTIONS = {
26
+ 'argv_emulation': False,
27
+ }
28
+
29
+ with open("README.md", "r") as fh:
30
+ LONG_DESRIPTION = fh.read()
31
+
32
+ setup(
33
+ app=APP,
34
+ author=AUTHOR,
35
+ author_email=AUTHOR_MAIL,
36
+ name="things.py",
37
+ description=DESCRIPTON,
38
+ long_description=LONG_DESRIPTION,
39
+ long_description_content_type="text/markdown",
40
+ url=URL,
41
+ packages=find_packages(),
42
+ classifiers=[
43
+ "Development Status :: 3 - Alpha",
44
+ "Programming Language :: Python :: 3",
45
+ "License :: OSI Approved :: Apache Software License",
46
+ "Operating System :: MacOS :: MacOS X",
47
+ "Natural Language :: English"
48
+ ],
49
+ python_requires='>=3.6',
50
+ version=VERSION,
51
+ data_files=DATA_FILES,
52
+ options={'py2app': OPTIONS},
53
+ setup_requires=['py2app'],
54
+ )
File without changes
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """Module documentation goes here."""
5
+
6
+ import unittest
7
+
8
+ import things
9
+
10
+
11
+ FILEPATH = dict(filepath="tests/main.sqlite")
12
+
13
+
14
+ class ThingsCase(unittest.TestCase):
15
+ """Class documentation goes here."""
16
+
17
+ def test_search(self):
18
+ """Test search."""
19
+ tasks = things.search('wrong_query', **FILEPATH)
20
+ self.assertEqual(0, len(tasks))
21
+ tasks = things.search('To-Do % Heading', **FILEPATH)
22
+ self.assertEqual(1, len(tasks))
23
+
24
+ def test_inbox(self):
25
+ """Test inbox."""
26
+ tasks = things.inbox(**FILEPATH)
27
+ self.assertEqual(1, len(tasks))
28
+
29
+ def test_upcoming(self):
30
+ """Test upcoming."""
31
+ tasks = things.upcoming(**FILEPATH)
32
+ self.assertEqual(2, len(tasks))
33
+
34
+ def test_due(self):
35
+ """Test due."""
36
+ tasks = things.due(**FILEPATH)
37
+ self.assertEqual(1, len(tasks))
38
+
39
+ def test_today(self):
40
+ """Test today."""
41
+ tasks = things.today(**FILEPATH)
42
+ self.assertEqual(1, len(tasks))
43
+
44
+ def test_anytime(self):
45
+ """Test antime."""
46
+ tasks = things.anytime(**FILEPATH)
47
+ self.assertEqual(8, len(tasks))
48
+
49
+ def test_logbook(self):
50
+ """Test logbook."""
51
+ tasks = things.logbook(**FILEPATH)
52
+ self.assertEqual(21, len(tasks))
53
+
54
+ def test_canceled(self):
55
+ """Test canceled."""
56
+ tasks = things.canceled(**FILEPATH)
57
+ self.assertEqual(11, len(tasks))
58
+
59
+ def test_completed(self):
60
+ """Test completed."""
61
+ tasks = things.completed(**FILEPATH)
62
+ self.assertEqual(10, len(tasks))
63
+
64
+ def test_someday(self):
65
+ """Test someday."""
66
+ tasks = things.someday(**FILEPATH)
67
+ self.assertEqual(1, len(tasks))
68
+
69
+ def test_get(self):
70
+ """Test get."""
71
+ tasks = things.get("wrong_uuid", **FILEPATH)
72
+ self.assertEqual(None, tasks)
73
+ tasks = things.get("wrong_uuid", "NOT FOUND", **FILEPATH)
74
+ self.assertEqual("NOT FOUND", tasks)
75
+ tasks = things.get("Qt2AY87x2QDdowSn9HKTt1", **FILEPATH)
76
+ self.assertEqual(4, len(tasks))
77
+
78
+ def test_todos(self):
79
+ """Test all tasks."""
80
+ tasks = things.todos(start="Anytime", **FILEPATH)
81
+ self.assertEqual(5, len(tasks))
82
+ tasks = things.todos(start="Anytime", status="completed", **FILEPATH)
83
+ self.assertEqual(6, len(tasks))
84
+ tasks = things.todos(status="completed", **FILEPATH)
85
+ self.assertEqual(10, len(tasks))
86
+ tasks = things.todos(include_items=True, **FILEPATH)
87
+ self.assertEqual(9, len(tasks))
88
+ with self.assertRaises(ValueError):
89
+ things.todos(status="wrong_value", **FILEPATH)
90
+ tasks = things.tasks("A2oPvtt4dXoypeoLc8uYzY", **FILEPATH)
91
+ self.assertEqual(13, len(tasks))
92
+
93
+ def test_tags(self):
94
+ """Test all tags."""
95
+ tags = things.tags(**FILEPATH)
96
+ self.assertEqual(5, len(tags))
97
+
98
+ def test_projects(self):
99
+ """Test all projects."""
100
+ projects = things.projects(**FILEPATH)
101
+ self.assertEqual(2, len(projects))
102
+
103
+ def test_areas(self):
104
+ """Test all test_areas."""
105
+ test_areas = things.areas(**FILEPATH)
106
+ self.assertEqual(1, len(test_areas))
107
+
108
+ def test_database_version(self):
109
+ """Test database version."""
110
+ version = things.Database(**FILEPATH).get_version()
111
+ self.assertEqual(18, version)
112
+
113
+
114
+ if __name__ == "__main__":
115
+ unittest.main()
@@ -0,0 +1,23 @@
1
+ """A simple Python 3 library to read your Things app data."""
2
+
3
+ from things.api import ( # noqa
4
+ anytime,
5
+ areas,
6
+ canceled,
7
+ completed,
8
+ due,
9
+ get,
10
+ inbox,
11
+ link,
12
+ logbook,
13
+ projects,
14
+ search,
15
+ show,
16
+ someday,
17
+ tags,
18
+ tasks,
19
+ today,
20
+ todos,
21
+ upcoming,
22
+ )
23
+ from things.database import Database # noqa