├── .editorconfig
├── .flake8
├── .github
└── workflows
│ ├── ci.yml
│ └── release.yml
├── .gitignore
├── .readthedocs.yaml
├── CONTRIBUTING.rst
├── LICENSE.txt
├── README.rst
├── docs
├── Makefile
├── api.rst
├── appendix.rst
├── conf.py
├── contributing.rst
├── index.rst
└── quickstart.rst
├── pycaching
├── __init__.py
├── cache.py
├── errors.py
├── geo.py
├── geocaching.py
├── log.py
├── trackable.py
└── util.py
├── pyproject.toml
├── test
├── __init__.py
├── cassettes
│ ├── advanced_search.json
│ ├── advanced_search_caches_owned_by_hq.json
│ ├── cache_PMO.json
│ ├── cache_author_deleted.json
│ ├── cache_author_normal.json
│ ├── cache_explicit_load.json
│ ├── cache_guidload_PMO.json
│ ├── cache_guidload_fallback.json
│ ├── cache_guidload_normal.json
│ ├── cache_hint_lazy_loading.json
│ ├── cache_hint_load_by_guid.json
│ ├── cache_logbook.json
│ ├── cache_logpage.json
│ ├── cache_non-ascii.json
│ ├── cache_normal_fail.json
│ ├── cache_normal_normal.json
│ ├── cache_quick_normal.json
│ ├── cache_quickload_fail.json
│ ├── cache_setup.json
│ ├── cache_status_archived.json
│ ├── cache_status_disabled.json
│ ├── cache_status_enabled.json
│ ├── cache_status_enabled_load_quick.json
│ ├── cache_status_locked.json
│ ├── cache_trackables.json
│ ├── cache_type_gigaevent.json
│ ├── cache_type_headquarters.json
│ ├── cache_type_hq_celebration.json
│ ├── cache_type_locationless.json
│ ├── cache_type_projectape.json
│ ├── geo_location_empty.json
│ ├── geo_location_existing.json
│ ├── geo_location_nonexisting.json
│ ├── geo_point_utfgrid.json
│ ├── geocaching__try_getting_cache_from_guid.json
│ ├── geocaching__try_getting_cache_from_guid_pm_only.json
│ ├── geocaching_api_rate_limit.json
│ ├── geocaching_api_rate_limit_with_none.json
│ ├── geocaching_my_dnfs.json
│ ├── geocaching_my_finds.json
│ ├── geocaching_quick_search.json
│ ├── geocaching_search.json
│ ├── geocaching_search_pagination.json
│ ├── geocaching_search_rect.json
│ ├── geocaching_shortcut_geocode.json
│ ├── geocaching_shortcut_getcache.json
│ ├── geocaching_shortcut_getcache_by_guid.json
│ ├── geocaching_shortcut_gettrackable.json
│ ├── trackable_kml.json
│ ├── trackable_load__existing_type.json
│ ├── trackable_load__missing_type.json
│ ├── trackable_load_page.json
│ ├── trackable_load_tid.json
│ ├── trackable_load_url.json
│ ├── trackable_setup.json
│ └── util_attributes.json
├── helpers.py
├── sample_caches.csv
├── sample_utfgrid.json
├── test_cache.py
├── test_geo.py
├── test_geocaching.py
├── test_log.py
├── test_trackable.py
└── test_util.py
└── tests_new
├── __init__.py
├── cassettes
├── tests_new.test_geocaching.TestLoadCredentials.test.json
├── tests_new.test_geocaching.TestLoadCredentials.test_file_empty.json
├── tests_new.test_geocaching.TestLoadCredentials.test_file_invalid_json.json
├── tests_new.test_geocaching.TestLoadCredentials.test_file_multiuser_empty.json
├── tests_new.test_geocaching.TestLoadCredentials.test_file_multiuser_empty_item.json
├── tests_new.test_geocaching.TestLoadCredentials.test_file_nonexisting.json
├── tests_new.test_geocaching.TestLoadCredentials.test_file_string.json
├── tests_new.test_geocaching.TestLoadCredentials.test_multiuser.json
├── tests_new.test_geocaching.TestLoadCredentials.test_multiuser_with_nonexisting_username.json
├── tests_new.test_geocaching.TestLoadCredentials.test_multiuser_with_username.json
├── tests_new.test_geocaching.TestLoadCredentials.test_password_cmd.json
├── tests_new.test_geocaching.TestLoadCredentials.test_password_cmd_ambiguous.json
├── tests_new.test_geocaching.TestLoadCredentials.test_password_cmd_invalid.json
├── tests_new.test_geocaching.TestLoadCredentials.test_with_nonexisting_username.json
├── tests_new.test_geocaching.TestLoadCredentials.test_with_username.json
├── tests_new.test_geocaching.test_get_logged_user.json
├── tests_new.test_geocaching.test_login.json
├── tests_new.test_geocaching.test_login_bad_credentials.json
├── tests_new.test_geocaching.test_login_failed_because_of_load_credentials_failed.json
├── tests_new.test_geocaching.test_login_twice_with_valid_credentials.json
├── tests_new.test_geocaching.test_logout.json
├── tests_new.test_geocaching.test_logout_when_relogin_is_attempted_with_invalid_credentials.json
├── tests_new.test_geocaching.test_unauthorized_request.json
└── tests_new.test_shortcuts.test_login.json
├── conftest.py
├── test_geocaching.py
└── test_shortcuts.py
/.editorconfig:
--------------------------------------------------------------------------------
1 | ; This is an ini style configuration. See http://editorconfig.org/ for more information on this file.
2 |
3 | root = true
4 |
5 | [*]
6 | end_of_line = lf
7 | charset = utf-8
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.py]
12 | indent_style = space
13 | indent_size = 4
14 |
--------------------------------------------------------------------------------
/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | max-line-length = 120
3 | exclude = .venv,dist,docs,build,*.egg,.git,__pycache__,venv
4 | count = true
5 | show-source = true
6 | statistics = true
7 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on: [push, pull_request]
3 | jobs:
4 | build:
5 | runs-on: ${{ matrix.os }}
6 | strategy:
7 | fail-fast: false
8 | matrix:
9 | os: [ ubuntu-latest, macos-latest, windows-latest ]
10 | python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
11 | steps:
12 | - uses: actions/checkout@v3
13 | - name: Set up Python ${{ matrix.python-version }}
14 | uses: actions/setup-python@v4
15 | with:
16 | python-version: ${{ matrix.python-version }}
17 | - name: Install dependencies
18 | run: |
19 | pip install --upgrade pip setuptools flit
20 | flit install --symlink
21 | - name: isort
22 | run: isort --check --diff .
23 | - name: black
24 | run: black --check --diff .
25 | - name: flake8
26 | run: flake8
27 | - name: pytest
28 | run: pytest --cov-report=html
29 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Upload Python Package
2 |
3 | on:
4 | release:
5 | types: [published]
6 |
7 | jobs:
8 | deploy:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v3
12 | - name: Set up Python
13 | uses: actions/setup-python@v4
14 | with:
15 | python-version: '3.x'
16 | - name: Install dependencies
17 | run: |
18 | pip install --upgrade pip setuptools flit
19 | flit install --symlink
20 | - name: Build package
21 | run: flit build
22 | - name: Publish a Python distribution to PyPI
23 | uses: pypa/gh-action-pypi-publish@release/v1
24 | with:
25 | user: __token__
26 | password: ${{ secrets.PYPI_API_TOKEN }}
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # CUSTOM ===========================================================
2 |
3 | # tmp file for testing some snippets of code
4 | test.py
5 |
6 | # testing IPython notebooks
7 | *.ipynb
8 |
9 |
10 |
11 | # DEFAULT ==========================================================
12 |
13 | # IPythonNotebook temporary data
14 | .ipynb_checkpoints/
15 |
16 | # Byte-compiled / optimized / DLL files
17 | __pycache__/
18 | *.py[cod]
19 |
20 | # C extensions
21 | *.so
22 |
23 | # Distribution / packaging
24 | .Python
25 | env/
26 | build/
27 | develop-eggs/
28 | dist/
29 | eggs/
30 | lib/
31 | lib64/
32 | parts/
33 | sdist/
34 | var/
35 | *.egg-info/
36 | .installed.cfg
37 | *.egg
38 | .eggs/
39 |
40 | # PyInstaller
41 | # Usually these files are written by a python script from a template
42 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
43 | *.manifest
44 | *.spec
45 |
46 | # Installer logs
47 | pip-log.txt
48 | pip-delete-this-directory.txt
49 |
50 | # Unit test / coverage reports
51 | htmlcov/
52 | .tox/
53 | .coverage
54 | .cache
55 | nosetests.xml
56 | coverage.xml
57 | .pytest_cache/
58 |
59 | # Sphinx documentation
60 | docs/_build/
61 | docs/_build_html/
62 |
63 | # Virtualenv
64 | .Python
65 | [Bb]in
66 | [Ii]nclude
67 | [Ll]ib
68 | [Ll]ib64
69 | [Ll]ocal
70 | [Ss]cripts
71 | pyvenv.cfg
72 | .venv
73 | pip-selfcheck.json
74 |
75 | # OS X
76 | .DS_Store
77 | .AppleDouble
78 | .LSOverride
79 | Icon
80 | ._*
81 | .Spotlight-V100
82 | .Trashes
83 | .AppleDB
84 | .AppleDesktop
85 | Network Trash Folder
86 | Temporary Items
87 | .apdisk
88 |
89 | # Windows
90 | Thumbs.db
91 | Desktop.ini
92 | $RECYCLE.BIN/
93 |
94 | # Editor
95 | *.sublime-*
96 |
--------------------------------------------------------------------------------
/.readthedocs.yaml:
--------------------------------------------------------------------------------
1 | # Read the Docs configuration file
2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3 |
4 | version: 2
5 |
6 | # Enforce *pip*-based build to install package from *pyproject.toml* file.
7 | build:
8 | os: ubuntu-22.04
9 | tools:
10 | python: '3'
11 |
12 | python:
13 | install:
14 | - method: pip
15 | path: .
16 | extra_requirements:
17 | - docs
18 |
19 | sphinx:
20 | configuration: docs/conf.py
21 |
22 | formats:
23 | - pdf
24 |
--------------------------------------------------------------------------------
/CONTRIBUTING.rst:
--------------------------------------------------------------------------------
1 | ===============================================================================
2 | Contributing
3 | ===============================================================================
4 |
5 |
6 | First time
7 | -------------------------------------------------------------------------------
8 |
9 | 1. Clone a repository from GitHub:
10 |
11 | .. code-block:: bash
12 |
13 | git clone https://github.com/tomasbedrich/pycaching.git
14 | cd pycaching
15 |
16 | 2. Create a virtualenv:
17 |
18 | .. code-block:: bash
19 |
20 | python3 -m venv .venv
21 | source .venv/bin/activate # Unix
22 | .venv\Scripts\activate # Windows
23 |
24 | 3. Install `Flit `_:
25 |
26 | .. code-block:: bash
27 |
28 | pip install flit
29 |
30 | 4. Install Pycaching package + dependencies in development mode:
31 |
32 | .. code-block:: bash
33 |
34 | flit install --symlink
35 |
36 |
37 | Typical workflow
38 | -------------------------------------------------------------------------------
39 |
40 | 1. Pick an issue labeled as `"contributors friendly"
41 | `_
42 | or create a new one. Please **notify others** that you will solve this problem (write a comment
43 | on GitHub).
44 |
45 | 2. Activate the virtualenv:
46 |
47 | .. code-block:: bash
48 |
49 | source .venv/bin/activate # Unix
50 | .venv\Scripts\activate # Windows
51 |
52 | 3. Write some **code and tests**. After that, don't forget to update the **docs**. See coding style below.
53 |
54 | 4. Sort imports using `isort `_,
55 | format the code using `Black `_,
56 | lint it using `Flake `_ and
57 | run the tests using `pytest `_:
58 |
59 | .. code-block:: bash
60 |
61 | isort .
62 | black .
63 | flake8
64 | pytest
65 |
66 | Make sure that:
67 |
68 | - there are no lint errors,
69 | - all tests are passing,
70 | - the coverage is above 90%.
71 |
72 | 6. Push your work and create a **pull request**. Yay!
73 |
74 |
75 | Testing
76 | -------------------------------------------------------------------------------
77 |
78 | Pycaching uses `Betamax `__ for testing, which speeds
79 | it up by recording network requests so that they can be mocked.
80 |
81 | If you haven't written or modified any tests, tests can be run just like:
82 |
83 | .. code-block:: bash
84 |
85 | pytest
86 |
87 | If you have written or modified tests, you must provide a username and password for testing. Don't
88 | worry, these will not leave your computer. Betamax will insert a placeholder when it records any
89 | new cassettes. To run new tests, first set up the following environment variables:
90 |
91 | .. code-block:: bash
92 |
93 | PYCACHING_TEST_USERNAME="yourusername" PYCACHING_TEST_PASSWORD="yourpassword" pytest
94 |
95 | Substitute your username for ``yourusername`` and your password for ``yourpassword``.
96 | This requires you to use a basic member account, otherwise you might see unexpected test failures.
97 |
98 | To re-record a specific cassette in case of site changes, delete the corresponding JSON file and
99 | provide username and password as explained above. The missing cassette will be recorded for future
100 | usages.
101 |
102 |
103 | Coding style
104 | -------------------------------------------------------------------------------
105 |
106 | - Use `.format()` for string formatting. Black will guide you with the rest. :)
107 | - For docs, please follow `PEP257 `_.
108 | - **Importing modules** is okay for modules from standard library. If you want to include a
109 | third-party module, please consult it on GitHub before.
110 | - `Please use regular expressions only as a last resort. `_ When possible, use string manipulations,
111 | such as :code:`split()` and then list operations. It is more readable.
112 |
113 |
114 | Release process
115 | -------------------------------------------------------------------------------
116 |
117 | 1. Pick a suitable semantic version number. We adhere to `generic rules `_ with an exception of our `specific deprecation policy `_.
118 | 2. If the deprecation policy triggers, remove the deprecated methods. Create a separate PR in that case.
119 | 3. Bump the version number in ``pycaching/__init__.py`` (`example `_). Feel free to push this bump directly to ``master``, or create a regular PR.
120 | 4. Once the version bump commit equals HEAD of ``master``, `draft a new release `_ using Github. Using that form, create a new tag corresponding to the version number (no prefixes). Leave release title empty, let Github generate the release notes. Update release notes manually if needed.
121 | 5. Publish the Github release. There is a Github action which publishes the release to Pypi. There are Webhooks which update Readthedocs and Coveralls.
122 |
123 | Should there be any issue with the above (most likely stuck release pipeline), please create a Github issue.
124 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | ===================================================================================================
2 | pycaching - Geocaching for Python
3 | ===================================================================================================
4 |
5 | Complete documentation can be found at `Read the Docs `_.
6 |
7 | .. _features:
8 |
9 | Features
10 | ===================================================================================================
11 |
12 | - **login** to Geocaching.com
13 | - **search** caches
14 |
15 | - normal search (unlimited number of caches from any point)
16 | - quick search (all caches inside some area) - currently not working, see below
17 |
18 | - **get cache** and its details
19 |
20 | - normal loading (can load all details)
21 | - quick loading (can load just basic info but very quickly)
22 | - load logbook for given cache
23 |
24 | - **get trackable** details by tracking code
25 | - **post log** for a cache or a trackable
26 | - **geocode** given location
27 |
28 | .. _installation:
29 |
30 | Installation
31 | ===================================================================================================
32 |
33 | Stable version - using pip:
34 |
35 | .. code-block:: bash
36 |
37 | pip install pycaching
38 |
39 | Dev version - manually from GIT:
40 |
41 | .. code-block:: bash
42 |
43 | git clone https://github.com/tomasbedrich/pycaching.git
44 | cd pycaching
45 | pip install .
46 |
47 | Pycaching has following requirements:
48 |
49 | .. code::
50 |
51 | Python>=3.5
52 | requests>=2.8
53 | beautifulsoup4>=4.9
54 | geopy>=1.11
55 |
56 | Pycaching tests have the following additional requirements:
57 |
58 | .. code::
59 |
60 | betamax >=0.8, <0.9
61 | betamax-serializers >=0.2, <0.3
62 |
63 | Examples
64 | ===================================================================================================
65 |
66 | Login
67 | ---------------------------------------------------------------------------------------------------
68 |
69 | Simply call `pycaching.login()
70 | `__
71 | method and it will do everything for you.
72 |
73 | .. code-block:: python
74 |
75 | import pycaching
76 | geocaching = pycaching.login("user", "pass")
77 |
78 | If you won't provide an username or password, pycaching will try to load ``.gc_credentials`` file
79 | from current directory or home folder. It will try to parse it as JSON and use the keys ``username``
80 | and ``password`` from that file as login credentials.
81 |
82 | .. code-block:: json
83 |
84 | { "username": "myusername", "password": "mypassword" }
85 |
86 |
87 | You can also provide multiple username and password tuples in a file as login credentials.
88 | The tuple to be used can be chosen by providing its username when calling ``pycaching.login()``,
89 | e.g. ``pycaching.login("myusername2")``. The first username and password tuple specified will be
90 | used as default if ``pycaching.login()`` is called without providing a username.
91 |
92 | .. code-block:: json
93 |
94 | [ { "username": "myusername1", "password": "mypassword1" },
95 | { "username": "myusername2", "password": "mypassword2" } ]
96 |
97 |
98 | .. code-block:: python
99 |
100 | import pycaching
101 | geocaching = pycaching.login() # assume the .gc_credentials file is presented
102 |
103 | In case you have a password manager in place featuring a command line interface
104 | (e.g. `GNU pass `__) you may specify a password retrieval command
105 | using the ``password_cmd`` key instead of ``password``.
106 |
107 | .. code-block:: json
108 |
109 | { "username": "myusername", "password_cmd": "pass geocaching.com/myUsername" }
110 |
111 | Note that the ``password`` and ``password_cmd`` keys are mutually exclusive.
112 |
113 |
114 |
115 | Load a cache details
116 | ---------------------------------------------------------------------------------------------------
117 |
118 | .. code-block:: python
119 |
120 | cache = geocaching.get_cache("GC1PAR2")
121 | print(cache.name) # cache.load() is automatically called
122 | print(cache.location) # stored in cache, printed immediately
123 |
124 | This uses lazy loading, so the `Cache `__
125 | object is created immediately and the page is loaded when needed (accessing the name).
126 |
127 | You can use a different method of loading cache details. It will be much faster, but it will load less
128 | details:
129 |
130 | .. code-block:: python
131 |
132 | cache = geocaching.get_cache("GC1PAR2")
133 | cache.load_quick() # takes a small while
134 | print(cache.name) # stored in cache, printed immediately
135 | print(cache.location) # NOT stored in cache, will trigger full loading
136 |
137 | You can also load a logbook for cache:
138 |
139 | .. code-block:: python
140 |
141 | for log in cache.load_logbook(limit=200):
142 | print(log.visited, log.type, log.author, log.text)
143 |
144 | Or its trackables:
145 |
146 | .. code-block:: python
147 |
148 | for trackable in cache.load_trackables(limit=5):
149 | print(trackable.name)
150 |
151 | Post a log to cache
152 | ---------------------------------------------------------------------------------------------------
153 |
154 | .. code-block:: python
155 |
156 | geocaching.post_log("GC1PAR2", "Found cache in the rain. Nice place, TFTC!")
157 |
158 | It is also possible to call ``post_log`` on `Cache
159 | `__ object, but you would have to create
160 | `Log `__ object manually and pass it to
161 | this method.
162 |
163 | Search for all traditional caches around
164 | ---------------------------------------------------------------------------------------------------
165 |
166 | .. code-block:: python
167 |
168 | from pycaching import Point
169 | from pycaching.cache import Type
170 |
171 | point = Point(56.25263, 15.26738)
172 |
173 | for cache in geocaching.search(point, limit=50):
174 | if cache.type == Type.traditional:
175 | print(cache.name)
176 |
177 | Notice the ``limit`` in the search function. It is because `geocaching.search()
178 | `__
179 | returns a generator object, which would fetch the caches forever in case of a simple loop.
180 |
181 | Geocode address and search around
182 | ---------------------------------------------------------------------------------------------------
183 |
184 | .. code-block:: python
185 |
186 | point = geocaching.geocode("Prague")
187 |
188 | for cache in geocaching.search(point, limit=10):
189 | print(cache.name)
190 |
191 | Find caches in some area
192 | ---------------------------------------------------------------------------------------------------
193 |
194 | .. code-block:: python
195 |
196 | from pycaching import Point, Rectangle
197 |
198 | rect = Rectangle(Point(60.15, 24.95), Point(60.17, 25.00))
199 |
200 | for cache in geocaching.search_rect(rect):
201 | print(cache.name)
202 |
203 | If you want to search in a larger area, you could use the ``limit`` parameter as described above.
204 |
205 | Load trackable details
206 | ---------------------------------------------------------------------------------------------------
207 |
208 | .. code-block:: python
209 |
210 | trackable = geocaching.get_trackable("TB3ZGT2")
211 | print(trackable.name, trackable.goal, trackable.description, trackable.location)
212 |
213 |
214 | Post a log for trackable
215 | ---------------------------------------------------------------------------------------------------
216 |
217 | .. code-block:: python
218 |
219 | from pycaching.log import Log, Type as LogType
220 | import datetime
221 |
222 | log = Log(type=LogType.discovered_it, text="Nice TB!", visited=datetime.date.today())
223 | tracking_code = "ABCDEF"
224 | trackable.post_log(log, tracking_code)
225 |
226 | Get geocaches by log type
227 | ---------------------------------------------------------------------------------------------------
228 |
229 | .. code-block:: python
230 |
231 | from pycaching.log import Type as LogType
232 |
233 | for find in geocaching.my_finds(limit=5):
234 | print(find.name)
235 |
236 | for dnf in geocaching.my_dnfs(limit=2):
237 | print(dnf.name)
238 |
239 | for note in geocaching.my_logs(LogType.note, limit=6):
240 | print(note.name)
241 |
242 |
243 | .. _appendix:
244 |
245 | Appendix
246 | ===================================================================================================
247 |
248 | Legal notice
249 | ---------------------------------------------------------------------------------------------------
250 |
251 | Be sure to read `Geocaching.com's terms of use `__.
252 | By using this piece of software you break them and your Geocaching account may be suspended or *even
253 | deleted*. To prevent this, I recommend you to load the data you really need, nothing more. This
254 | software is provided "as is" and I am not responsible for any damage possibly caused by it.
255 |
256 | Inspiration
257 | ---------------------------------------------------------------------------------------------------
258 |
259 | Original version was inspired by these packages:
260 |
261 | - `Geocache Grabber `__ (by Fuad Tabba)
262 | - `geocaching-py `__ (by Lev Shamardin)
263 |
264 | Although the new version was massively rewritten, I'd like to thank to their authors.
265 |
266 | Authors
267 | ---------------------------------------------------------------------------------------------------
268 |
269 | Authors of this project are `all contributors
270 | `__. Maintainer is `Tomáš Bedřich
271 | `__.
272 |
273 | .. _build_status:
274 |
275 | |PyPI monthly downloads|
276 |
277 | .. |PyPI monthly downloads| image:: http://img.shields.io/pypi/dm/pycaching.svg
278 | :target: https://pypi.python.org/pypi/pycaching
279 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | PAPER =
8 | BUILDDIR = _build
9 |
10 | # User-friendly check for sphinx-build
11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
13 | endif
14 |
15 | # Internal variables.
16 | PAPEROPT_a4 = -D latex_paper_size=a4
17 | PAPEROPT_letter = -D latex_paper_size=letter
18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
19 | # the i18n builder cannot share the environment and doctrees with the others
20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
21 |
22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
23 |
24 | help:
25 | @echo "Please use \`make ' where is one of"
26 | @echo " html to make standalone HTML files"
27 | @echo " dirhtml to make HTML files named index.html in directories"
28 | @echo " singlehtml to make a single large HTML file"
29 | @echo " pickle to make pickle files"
30 | @echo " json to make JSON files"
31 | @echo " htmlhelp to make HTML files and a HTML help project"
32 | @echo " qthelp to make HTML files and a qthelp project"
33 | @echo " applehelp to make an Apple Help Book"
34 | @echo " devhelp to make HTML files and a Devhelp project"
35 | @echo " epub to make an epub"
36 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
37 | @echo " latexpdf to make LaTeX files and run them through pdflatex"
38 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
39 | @echo " text to make text files"
40 | @echo " man to make manual pages"
41 | @echo " texinfo to make Texinfo files"
42 | @echo " info to make Texinfo files and run them through makeinfo"
43 | @echo " gettext to make PO message catalogs"
44 | @echo " changes to make an overview of all changed/added/deprecated items"
45 | @echo " xml to make Docutils-native XML files"
46 | @echo " pseudoxml to make pseudoxml-XML files for display purposes"
47 | @echo " linkcheck to check all external links for integrity"
48 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
49 | @echo " coverage to run coverage check of the documentation (if enabled)"
50 |
51 | clean:
52 | rm -rf $(BUILDDIR)/*
53 |
54 | html:
55 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
56 | @echo
57 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
58 |
59 | dirhtml:
60 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
61 | @echo
62 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
63 |
64 | singlehtml:
65 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
66 | @echo
67 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
68 |
69 | pickle:
70 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
71 | @echo
72 | @echo "Build finished; now you can process the pickle files."
73 |
74 | json:
75 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
76 | @echo
77 | @echo "Build finished; now you can process the JSON files."
78 |
79 | htmlhelp:
80 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
81 | @echo
82 | @echo "Build finished; now you can run HTML Help Workshop with the" \
83 | ".hhp project file in $(BUILDDIR)/htmlhelp."
84 |
85 | qthelp:
86 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
87 | @echo
88 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
89 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
90 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pycaching.qhcp"
91 | @echo "To view the help file:"
92 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pycaching.qhc"
93 |
94 | applehelp:
95 | $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
96 | @echo
97 | @echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
98 | @echo "N.B. You won't be able to view it unless you put it in" \
99 | "~/Library/Documentation/Help or install it in your application" \
100 | "bundle."
101 |
102 | devhelp:
103 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
104 | @echo
105 | @echo "Build finished."
106 | @echo "To view the help file:"
107 | @echo "# mkdir -p $$HOME/.local/share/devhelp/pycaching"
108 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pycaching"
109 | @echo "# devhelp"
110 |
111 | epub:
112 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
113 | @echo
114 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
115 |
116 | latex:
117 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
118 | @echo
119 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
120 | @echo "Run \`make' in that directory to run these through (pdf)latex" \
121 | "(use \`make latexpdf' here to do that automatically)."
122 |
123 | latexpdf:
124 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
125 | @echo "Running LaTeX files through pdflatex..."
126 | $(MAKE) -C $(BUILDDIR)/latex all-pdf
127 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
128 |
129 | latexpdfja:
130 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
131 | @echo "Running LaTeX files through platex and dvipdfmx..."
132 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
133 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
134 |
135 | text:
136 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
137 | @echo
138 | @echo "Build finished. The text files are in $(BUILDDIR)/text."
139 |
140 | man:
141 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
142 | @echo
143 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
144 |
145 | texinfo:
146 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
147 | @echo
148 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
149 | @echo "Run \`make' in that directory to run these through makeinfo" \
150 | "(use \`make info' here to do that automatically)."
151 |
152 | info:
153 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
154 | @echo "Running Texinfo files through makeinfo..."
155 | make -C $(BUILDDIR)/texinfo info
156 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
157 |
158 | gettext:
159 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
160 | @echo
161 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
162 |
163 | changes:
164 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
165 | @echo
166 | @echo "The overview file is in $(BUILDDIR)/changes."
167 |
168 | linkcheck:
169 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
170 | @echo
171 | @echo "Link check complete; look for any errors in the above output " \
172 | "or in $(BUILDDIR)/linkcheck/output.txt."
173 |
174 | doctest:
175 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
176 | @echo "Testing of doctests in the sources finished, look at the " \
177 | "results in $(BUILDDIR)/doctest/output.txt."
178 |
179 | coverage:
180 | $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
181 | @echo "Testing of coverage in the sources finished, look at the " \
182 | "results in $(BUILDDIR)/coverage/python.txt."
183 |
184 | xml:
185 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
186 | @echo
187 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
188 |
189 | pseudoxml:
190 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
191 | @echo
192 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
193 |
--------------------------------------------------------------------------------
/docs/api.rst:
--------------------------------------------------------------------------------
1 | ===============================================================================
2 | API reference
3 | ===============================================================================
4 |
5 | Here you can find an overview of all available classes and methods.
6 |
7 | .. warning::
8 | Deprecated methods will be removed in next minor version.
9 |
10 | For example: if you rely on some non-deprecated method in version 3.3, then it's fine to update
11 | once to 3.4. If the method gets deprecated in 3.4, then it will be removed in 3.5!
12 |
13 | .. automodule:: pycaching
14 | :members: login
15 |
16 |
17 | Geocaching
18 | -------------------------------------------------------------------------------
19 |
20 | .. automodule:: pycaching.geocaching
21 | :members:
22 |
23 |
24 | Cache
25 | -------------------------------------------------------------------------------
26 |
27 | .. autoclass:: pycaching.cache.Cache
28 | :members:
29 |
30 | .. autoclass:: pycaching.cache.Waypoint
31 | :members:
32 | :undoc-members:
33 | :inherited-members:
34 |
35 | .. autoclass:: pycaching.cache.Type
36 | :members:
37 | :undoc-members:
38 | :inherited-members:
39 |
40 | .. autoclass:: pycaching.cache.Size
41 | :members:
42 | :undoc-members:
43 | :inherited-members:
44 |
45 |
46 | Logs
47 | -------------------------------------------------------------------------------
48 |
49 | .. autoclass:: pycaching.log.Log
50 | :members:
51 |
52 | .. autoclass:: pycaching.log.Type
53 | :members:
54 | :undoc-members:
55 | :inherited-members:
56 |
57 |
58 | Trackables
59 | -------------------------------------------------------------------------------
60 |
61 | .. automodule:: pycaching.trackable
62 | :members:
63 |
64 |
65 | Geo utilities
66 | -------------------------------------------------------------------------------
67 |
68 | .. automodule:: pycaching.geo
69 | :members: to_decimal
70 |
71 | .. autoclass:: pycaching.geo.Point
72 | :members: from_location, from_string
73 |
74 | .. autoclass:: pycaching.geo.Polygon
75 | :members: bounding_box, mean_point
76 |
77 | .. autoclass:: pycaching.geo.Rectangle
78 | :members: __contains__, diagonal
79 |
80 |
81 | Errors
82 | -------------------------------------------------------------------------------
83 |
84 | .. automodule:: pycaching.errors
85 | :members:
86 |
--------------------------------------------------------------------------------
/docs/appendix.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../README.rst
2 | :start-after: _appendix:
3 | :end-before: _build_status:
4 |
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 | #
4 | # pycaching documentation build configuration file, created by
5 | # sphinx-quickstart on Sun Nov 15 15:53:50 2015.
6 | #
7 | # This file is execfile()d with the current directory set to its
8 | # containing dir.
9 | #
10 | # Note that not all possible configuration values are present in this
11 | # autogenerated file.
12 | #
13 | # All configuration values have a default; values that are commented out
14 | # serve to show the default.
15 |
16 | import sys
17 | from datetime import date
18 | from pathlib import Path
19 |
20 | import sphinx_rtd_theme
21 |
22 | # If extensions (or modules to document with autodoc) are in another directory,
23 | # add these directories to sys.path here. If the directory is relative to the
24 | # documentation root, use os.path.abspath to make it absolute, like shown here.
25 |
26 | sys.path.append(str(Path("..").resolve()))
27 |
28 | import pycaching
29 |
30 | # -- General configuration ------------------------------------------------
31 |
32 | # If your documentation needs a minimal Sphinx version, state it here.
33 | # needs_sphinx = '1.0'
34 |
35 | # Add any Sphinx extension module names here, as strings. They can be
36 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
37 | # ones.
38 | extensions = [
39 | "sphinx.ext.autodoc",
40 | # 'sphinx.ext.doctest',
41 | "sphinx.ext.intersphinx",
42 | # 'sphinx.ext.coverage',
43 | ]
44 |
45 | # Add any paths that contain templates here, relative to this directory.
46 | templates_path = ["_templates"]
47 |
48 | # The suffix(es) of source filenames.
49 | # You can specify multiple suffix as a list of string:
50 | # source_suffix = ['.rst', '.md']
51 | source_suffix = ".rst"
52 |
53 | # The encoding of source files.
54 | # source_encoding = 'utf-8-sig'
55 |
56 | # The master toctree document.
57 | master_doc = "index"
58 |
59 | # General information about the project.
60 | project = "pycaching"
61 | copyright = "2015-{}, pycaching contributors".format(date.today().year)
62 | author = "pycaching contributors"
63 |
64 | # The version info for the project you're documenting, acts as replacement for
65 | # |version| and |release|, also used in various other places throughout the
66 | # built documents.
67 | #
68 | configured_version = pycaching.__version__
69 | # The short X.Y version.
70 | version = ".".join(configured_version.split(".")[:2])
71 | # The full version, including alpha/beta/rc tags.
72 | release = configured_version
73 |
74 | # The language for content autogenerated by Sphinx. Refer to documentation
75 | # for a list of supported languages.
76 | #
77 | # This is also used if you do content translation via gettext catalogs.
78 | # Usually you set "language" from the command line for these cases.
79 | language = "en"
80 |
81 | # There are two options for replacing |today|: either, you set today to some
82 | # non-false value, then it is used:
83 | # today = ''
84 | # Else, today_fmt is used as the format for a strftime call.
85 | # today_fmt = '%B %d, %Y'
86 |
87 | # List of patterns, relative to source directory, that match files and
88 | # directories to ignore when looking for source files.
89 | exclude_patterns = ["_build"]
90 |
91 | # The reST default role (used for this markup: `text`) to use for all
92 | # documents.
93 | # default_role = None
94 |
95 | # If true, '()' will be appended to :func: etc. cross-reference text.
96 | # add_function_parentheses = True
97 |
98 | # If true, the current module name will be prepended to all description
99 | # unit titles (such as .. function::).
100 | # add_module_names = True
101 |
102 | # If true, sectionauthor and moduleauthor directives will be shown in the
103 | # output. They are ignored by default.
104 | # show_authors = False
105 |
106 | # The name of the Pygments (syntax highlighting) style to use.
107 | pygments_style = "sphinx"
108 |
109 | # A list of ignored prefixes for module index sorting.
110 | # modindex_common_prefix = []
111 |
112 | # If true, keep warnings as "system message" paragraphs in the built documents.
113 | # keep_warnings = False
114 |
115 | # If true, `todo` and `todoList` produce output, else they produce nothing.
116 | todo_include_todos = False
117 |
118 |
119 | # -- Options for HTML output ----------------------------------------------
120 |
121 | # The theme to use for HTML and HTML Help pages. See the documentation for
122 | # a list of builtin themes.
123 | html_theme = "sphinx_rtd_theme"
124 |
125 | # Theme options are theme-specific and customize the look and feel of a theme
126 | # further. For a list of options available for each theme, see the
127 | # documentation.
128 | # html_theme_options = {}
129 |
130 | # Add any paths that contain custom themes here, relative to this directory.
131 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
132 |
133 | # The name for this set of Sphinx documents. If None, it defaults to
134 | # " v documentation".
135 | # html_title = None
136 |
137 | # A shorter title for the navigation bar. Default is the same as html_title.
138 | # html_short_title = None
139 |
140 | # The name of an image file (relative to this directory) to place at the top
141 | # of the sidebar.
142 | # html_logo = None
143 |
144 | # The name of an image file (within the static path) to use as favicon of the
145 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
146 | # pixels large.
147 | # html_favicon = None
148 |
149 | # Add any paths that contain custom static files (such as style sheets) here,
150 | # relative to this directory. They are copied after the builtin static files,
151 | # so a file named "default.css" will overwrite the builtin "default.css".
152 | html_static_path = ["_static"]
153 |
154 | # Add any extra paths that contain custom files (such as robots.txt or
155 | # .htaccess) here, relative to this directory. These files are copied
156 | # directly to the root of the documentation.
157 | # html_extra_path = []
158 |
159 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
160 | # using the given strftime format.
161 | # html_last_updated_fmt = '%b %d, %Y'
162 |
163 | # If true, SmartyPants will be used to convert quotes and dashes to
164 | # typographically correct entities.
165 | # html_use_smartypants = True
166 |
167 | # Custom sidebar templates, maps document names to template names.
168 | # html_sidebars = {}
169 |
170 | # Additional templates that should be rendered to pages, maps page names to
171 | # template names.
172 | # html_additional_pages = {}
173 |
174 | # If false, no module index is generated.
175 | # html_domain_indices = True
176 |
177 | # If false, no index is generated.
178 | # html_use_index = True
179 |
180 | # If true, the index is split into individual pages for each letter.
181 | # html_split_index = False
182 |
183 | # If true, links to the reST sources are added to the pages.
184 | # html_show_sourcelink = True
185 |
186 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
187 | # html_show_sphinx = True
188 |
189 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
190 | # html_show_copyright = True
191 |
192 | # If true, an OpenSearch description file will be output, and all pages will
193 | # contain a tag referring to it. The value of this option must be the
194 | # base URL from which the finished HTML is served.
195 | # html_use_opensearch = ''
196 |
197 | # This is the file name suffix for HTML files (e.g. ".xhtml").
198 | # html_file_suffix = None
199 |
200 | # Language to be used for generating the HTML full-text search index.
201 | # Sphinx supports the following languages:
202 | # 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'
203 | # 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr'
204 | # html_search_language = 'en'
205 |
206 | # A dictionary with options for the search language support, empty by default.
207 | # Now only 'ja' uses this config value
208 | # html_search_options = {'type': 'default'}
209 |
210 | # The name of a javascript file (relative to the configuration directory) that
211 | # implements a search results scorer. If empty, the default will be used.
212 | # html_search_scorer = 'scorer.js'
213 |
214 | # Output file base name for HTML help builder.
215 | htmlhelp_basename = "pycachingdoc"
216 |
217 | # -- Options for LaTeX output ---------------------------------------------
218 |
219 | latex_elements = {
220 | # The paper size ('letterpaper' or 'a4paper').
221 | #'papersize': 'letterpaper',
222 | # The font size ('10pt', '11pt' or '12pt').
223 | #'pointsize': '10pt',
224 | # Additional stuff for the LaTeX preamble.
225 | #'preamble': '',
226 | # Latex figure (float) alignment
227 | #'figure_align': 'htbp',
228 | }
229 |
230 | # Grouping the document tree into LaTeX files. List of tuples
231 | # (source start file, target name, title,
232 | # author, documentclass [howto, manual, or own class]).
233 | latex_documents = [
234 | (master_doc, "pycaching.tex", "pycaching Documentation", "Tomáš Bedřich", "manual"),
235 | ]
236 |
237 | # The name of an image file (relative to this directory) to place at the top of
238 | # the title page.
239 | # latex_logo = None
240 |
241 | # For "manual" documents, if this is true, then toplevel headings are parts,
242 | # not chapters.
243 | # latex_use_parts = False
244 |
245 | # If true, show page references after internal links.
246 | # latex_show_pagerefs = False
247 |
248 | # If true, show URL addresses after external links.
249 | # latex_show_urls = False
250 |
251 | # Documents to append as an appendix to all manuals.
252 | # latex_appendices = []
253 |
254 | # If false, no module index is generated.
255 | # latex_domain_indices = True
256 |
257 |
258 | # -- Options for manual page output ---------------------------------------
259 |
260 | # One entry per manual page. List of tuples
261 | # (source start file, name, description, authors, manual section).
262 | man_pages = [(master_doc, "pycaching", "pycaching Documentation", [author], 1)]
263 |
264 | # If true, show URL addresses after external links.
265 | # man_show_urls = False
266 |
267 |
268 | # -- Options for Texinfo output -------------------------------------------
269 |
270 | # Grouping the document tree into Texinfo files. List of tuples
271 | # (source start file, target name, title, author,
272 | # dir menu entry, description, category)
273 | texinfo_documents = [
274 | (
275 | master_doc,
276 | "pycaching",
277 | "pycaching Documentation",
278 | author,
279 | "pycaching",
280 | "One line description of project.",
281 | "Miscellaneous",
282 | ),
283 | ]
284 |
285 | # Documents to append as an appendix to all manuals.
286 | # texinfo_appendices = []
287 |
288 | # If false, no module index is generated.
289 | # texinfo_domain_indices = True
290 |
291 | # How to display URL addresses: 'footnote', 'no', or 'inline'.
292 | # texinfo_show_urls = 'footnote'
293 |
294 | # If true, do not generate a @detailmenu in the "Top" node's menu.
295 | # texinfo_no_detailmenu = False
296 |
297 |
298 | # Example configuration for intersphinx: refer to the Python standard library.
299 | intersphinx_mapping = {"python": ("https://docs.python.org/3", None)}
300 |
301 |
302 | # -- Options for autodoc -----------------------------------------------
303 |
304 | autodoc_member_order = "groupwise"
305 |
--------------------------------------------------------------------------------
/docs/contributing.rst:
--------------------------------------------------------------------------------
1 | .. include:: ../CONTRIBUTING.rst
2 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | ===================================================================================================
2 | pycaching - Geocaching for Python
3 | ===================================================================================================
4 |
5 | Source codes can be found at `GitHub repository `_.
6 |
7 | .. include:: ../README.rst
8 | :start-after: _features:
9 | :end-before: _installation:
10 |
11 |
12 | Documentation contents
13 | ===============================================================================
14 |
15 |
16 | .. toctree::
17 | :maxdepth: 2
18 |
19 | quickstart
20 | api
21 | contributing
22 | appendix
23 |
--------------------------------------------------------------------------------
/docs/quickstart.rst:
--------------------------------------------------------------------------------
1 | ===============================================================================
2 | Quickstart
3 | ===============================================================================
4 |
5 |
6 | .. include:: ../README.rst
7 | :start-after: _installation:
8 | :end-before: _appendix:
9 |
--------------------------------------------------------------------------------
/pycaching/__init__.py:
--------------------------------------------------------------------------------
1 | from pycaching.cache import Cache # NOQA
2 | from pycaching.geo import Point, Rectangle # NOQA
3 | from pycaching.geocaching import Geocaching # NOQA
4 | from pycaching.log import Log # NOQA
5 | from pycaching.trackable import Trackable # NOQA
6 |
7 | __version__ = "4.4.3" # PEP 440
8 |
9 |
10 | def login(username=None, password=None):
11 | """A shortcut for user login.
12 |
13 | Create a :class:`.Geocaching` instance and try to login a user. See :meth:`.Geocaching.login`.
14 |
15 | :return: Created :class:`.Geocaching` instance.
16 | """
17 | g = Geocaching()
18 | g.login(username, password)
19 | return g
20 |
--------------------------------------------------------------------------------
/pycaching/errors.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 |
4 | class Error(Exception):
5 | """General pycaching error.
6 |
7 | .. note:
8 | This class is a superclass of all errors produced by pycaching module, so you can use it to
9 | catch all pycaching related errors.
10 | """
11 |
12 |
13 | class NotLoggedInException(Error):
14 | """Tried to perform an operation which requires logging in first."""
15 |
16 |
17 | class LoginFailedException(Error, ValueError):
18 | """Login failed.
19 |
20 | The provided credentials probably doesn't work to log in.
21 | """
22 |
23 |
24 | class GeocodeError(Error, ValueError):
25 | """Geocoding failed.
26 |
27 | Probably because of non-existing location.
28 | """
29 |
30 |
31 | class LoadError(Error, OSError):
32 | """Object loading failed.
33 |
34 | Probably because of non-existing object or missing informations required to load it.
35 | """
36 |
37 |
38 | class PMOnlyException(Error):
39 | """Requested cache is PM only."""
40 |
41 |
42 | class BadBlockError(Error):
43 | pass
44 |
45 |
46 | class ValueError(Error, ValueError):
47 | """Wrapper for Pythons native ValueError.
48 |
49 | Can be raised in various situations, but most commonly when unexpected property value is set.
50 | """
51 |
52 |
53 | class TooManyRequestsError(Error):
54 | """Geocaching API rate limit has been reached."""
55 |
56 | def __init__(self, url: str, rate_limit_reset: int = 0):
57 | """
58 | Initialize TooManyRequestsError.
59 |
60 | :param url: Requested url.
61 | :param rate_limit_reset: Number of seconds to wait before rate limit reset.
62 | """
63 | self.url = url
64 | self.rate_limit_reset = rate_limit_reset
65 |
66 | def wait_for(self):
67 | """Wait enough time to release Rate Limits."""
68 | import time
69 |
70 | time.sleep(self.rate_limit_reset + 5)
71 |
--------------------------------------------------------------------------------
/pycaching/log.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import datetime
4 | import enum
5 |
6 | from pycaching import errors
7 | from pycaching.util import parse_date
8 |
9 | # prefix _type() function to avoid colisions with log type
10 | _type = type
11 |
12 |
13 | class Log(object):
14 | """Represents a log record with its properties."""
15 |
16 | def __init__(self, *, uuid=None, type=None, text=None, visited=None, author=None):
17 | if uuid is not None:
18 | self.uuid = uuid
19 | if type is not None:
20 | self.type = type
21 | if text is not None:
22 | self.text = text
23 | if visited is not None:
24 | self.visited = visited
25 | if author is not None:
26 | self.author = author
27 |
28 | def __str__(self):
29 | """Return log text."""
30 | return self.text
31 |
32 | @property
33 | def uuid(self):
34 | """The log unique identifier.
35 |
36 | :type: :class:`str`
37 | """
38 | return self._uuid
39 |
40 | @uuid.setter
41 | def uuid(self, uuid):
42 | self._uuid = uuid
43 |
44 | @property
45 | def type(self):
46 | """The log type.
47 |
48 | :type: :class:`.log.Type`
49 | """
50 | return self._type
51 |
52 | @type.setter
53 | def type(self, type):
54 | self._type = type
55 |
56 | @property
57 | def text(self):
58 | """The log text.
59 |
60 | :type: :class:`str`
61 | """
62 | return self._text
63 |
64 | @text.setter
65 | def text(self, text):
66 | text = str(text).strip()
67 | self._text = text
68 |
69 | @property
70 | def visited(self):
71 | """The log date.
72 |
73 | :setter: Set a log date. If :class:`str` is passed, then :meth:`.util.parse_date`
74 | is used and its return value is stored as a date.
75 | :type: :class:`datetime.date`
76 | """
77 | return self._visited
78 |
79 | @visited.setter
80 | def visited(self, visited):
81 | if _type(visited) is str:
82 | visited = parse_date(visited)
83 | elif _type(visited) is not datetime.date:
84 | raise errors.ValueError("Passed object is not datetime.date instance nor string containing a date.")
85 | self._visited = visited
86 |
87 | @property
88 | def author(self):
89 | """The log author.
90 |
91 | :type: :class:`str`
92 | """
93 | return self._author
94 |
95 | @author.setter
96 | def author(self, author):
97 | self._author = author.strip()
98 |
99 |
100 | class Type(enum.Enum):
101 | """Enum of possible log types.
102 |
103 | Values are log type IDs (as used in HTML