Rename rmapi rmapy

This commit is contained in:
Stijn Van Campenhout
2019-12-19 13:42:26 +01:00
parent 41ed56ace7
commit 00dc50550f
17 changed files with 90 additions and 91 deletions

View File

@@ -18,7 +18,7 @@ sys.path.insert(0, os.path.abspath('../..'))
# -- Project information ----------------------------------------------------- # -- Project information -----------------------------------------------------
project = 'rmapi' project = 'rmapy'
copyright = '2019, Stijn Van Campenhout' copyright = '2019, Stijn Van Campenhout'
author = 'Stijn Van Campenhout' author = 'Stijn Van Campenhout'

View File

@@ -1,9 +1,9 @@
.. rmapi documentation master file, created by .. rmapy documentation master file, created by
sphinx-quickstart on Tue Sep 17 19:24:29 2019. sphinx-quickstart on Tue Sep 17 19:24:29 2019.
You can adapt this file completely to your liking, but it should at least You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive. contain the root `toctree` directive.
Welcome to rmapi's documentation! Welcome to rmapy's documentation!
================================= =================================
This is an (unofficial) Remarkable Cloud API Client written in Python. This is an (unofficial) Remarkable Cloud API Client written in Python.
@@ -50,9 +50,9 @@ API Documentation
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
rmapi rmapy
.. automodule:: rmapi .. automodule:: rmapy
Indices and tables Indices and tables

View File

@@ -1,11 +1,11 @@
Pip Pip
=== ===
Like any other package, you can install rmapi using pip: Like any other package, you can install rmapy using pip:
.. code-block:: bash .. code-block:: bash
pip install rmapi pip install rmapy

View File

@@ -1,7 +1,7 @@
rmapi rmapy
===== =====
.. toctree:: .. toctree::
:maxdepth: 4 :maxdepth: 4
rmapi rmapy

View File

@@ -22,20 +22,20 @@ and use the code you see on the webpage
:linenos: :linenos:
from rmapi.api import Client from rmapy.api import Client
rmapi = Client() rmapy = Client()
# Shoud return False # Shoud return False
rmapi.is_authenticated() rmapy.is_authenticated()
# This registers the client as a new device. The received device token is # This registers the client as a new device. The received device token is
# stored in the users directory in the file ~/.rmapi, the same as with the # stored in the users directory in the file ~/.rmapi, the same as with the
# go rmapi client. # go rmapi client.
rmapi.register_device("fkgzzklrs") rmapy.register_device("fkgzzklrs")
# It's always a good idea to refresh the user token everytime you start # It's always a good idea to refresh the user token everytime you start
# a new session. # a new session.
rmapi.refresh_token() rmapy.refresh_token()
# Shoud return True # Shoud return True
rmapi.is_authenticated() rmapy.is_authenticated()
Working with items Working with items
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
@@ -50,21 +50,21 @@ We can list the items in the Cloud
.. code-block:: python .. code-block:: python
:linenos: :linenos:
>>> from rmapi.api import Client >>> from rmapy.api import Client
>>> rmapi = Client() >>> rmapy = Client()
>>> rmapi.renew_token() >>> rmapy.renew_token()
True True
>>> collection = rmapi.get_meta_items() >>> collection = rmapy.get_meta_items()
>>> collection >>> collection
<rmapi.collections.Collection object at 0x7fa1982d7e90> <rmapy.collections.Collection object at 0x7fa1982d7e90>
>>> len(collection) >>> len(collection)
181 181
>>> # Count the amount of documents >>> # Count the amount of documents
... from rmapi.document import Document ... from rmapy.document import Document
>>> len([f for f in collection if isinstance(f, Document)]) >>> len([f for f in collection if isinstance(f, Document)])
139 139
>>> # Count the amount of folders >>> # Count the amount of folders
... from rmapi.folder import Folder ... from rmapy.folder import Folder
>>> len([f for f in collection if isinstance(f, Folder)]) >>> len([f for f in collection if isinstance(f, Folder)])
42 42
@@ -74,7 +74,7 @@ DocumentType
```````````` ````````````
A DocumentType is a document. This can be a pdf, epub or notebook. A DocumentType is a document. This can be a pdf, epub or notebook.
These types are represented by the object :class:`rmapi.document.Document` These types are represented by the object :class:`rmapy.document.Document`
Changing the metadata is easy Changing the metadata is easy
@@ -83,28 +83,28 @@ Changing the metadata is easy
:linenos: :linenos:
>>> from rmapi.api import Client >>> from rmapy.api import Client
>>> rmapi = Client() >>> rmapy = Client()
>>> rmapi.renew_token() >>> rmapy.renew_token()
True True
>>> collection = rmapi.get_meta_items() >>> collection = rmapy.get_meta_items()
>>> doc = [ d for d in collection if d.VissibleName == 'ModernC'][0] >>> doc = [ d for d in collection if d.VissibleName == 'ModernC'][0]
>>> doc >>> doc
<rmapi.document.Document a969fcd6-64b0-4f71-b1ce-d9533ec4a2a3> <rmapy.document.Document a969fcd6-64b0-4f71-b1ce-d9533ec4a2a3>
>>> doc.to_dict() >>> doc.to_dict()
{'ID': 'a969fcd6-64b0-4f71-b1ce-d9533ec4a2a3', 'Version': 1, 'Message': '', 'Succes': True, 'BlobURLGet': '', 'BlobURLGetExpires': '0001-01-01T00:00:00Z', 'BlobURLPut': '', 'BlobURLPutExpires': '', 'ModifiedClient': '2019-09-18T20:12:07.206206Z', 'Type': 'DocumentType', 'VissibleName': 'ModernC', 'CurrentPage': 0, 'Bookmarked': False, 'Parent': ''} {'ID': 'a969fcd6-64b0-4f71-b1ce-d9533ec4a2a3', 'Version': 1, 'Message': '', 'Succes': True, 'BlobURLGet': '', 'BlobURLGetExpires': '0001-01-01T00:00:00Z', 'BlobURLPut': '', 'BlobURLPutExpires': '', 'ModifiedClient': '2019-09-18T20:12:07.206206Z', 'Type': 'DocumentType', 'VissibleName': 'ModernC', 'CurrentPage': 0, 'Bookmarked': False, 'Parent': ''}
>>> doc.VissibleName = "Modern C: The book of wisdom" >>> doc.VissibleName = "Modern C: The book of wisdom"
>>> # push the changes back to the Remarkable Cloud >>> # push the changes back to the Remarkable Cloud
... rmapi.update_metadata(doc) ... rmapy.update_metadata(doc)
True True
>>> collection = rmapi.get_meta_items() >>> collection = rmapy.get_meta_items()
>>> doc = [ d for d in docs if d.VissibleName == 'ModernC'][0] >>> doc = [ d for d in docs if d.VissibleName == 'ModernC'][0]
Traceback (most recent call last): Traceback (most recent call last):
File "<stdin>", line 1, in <module> File "<stdin>", line 1, in <module>
IndexError: list index out of range IndexError: list index out of range
>>> doc = [ d for d in docs if d.VissibleName == 'Modern C: The book of wisdom'][0] >>> doc = [ d for d in docs if d.VissibleName == 'Modern C: The book of wisdom'][0]
>>> doc >>> doc
<rmapi.document.Document a969fcd6-64b0-4f71-b1ce-d9533ec4a2a3> <rmapy.document.Document a969fcd6-64b0-4f71-b1ce-d9533ec4a2a3>
>>> doc.to_dict() >>> doc.to_dict()
{'ID': 'a969fcd6-64b0-4f71-b1ce-d9533ec4a2a3', 'Version': 1, 'Message': '', 'Succes': True, 'BlobURLGet': '', 'BlobURLGetExpires': '0001-01-01T00:00:00Z', 'BlobURLPut': '', 'BlobURLPutExpires': '', 'ModifiedClient': '2019-09-18T20:12:07.206206Z', 'Type': 'DocumentType', 'VissibleName': 'Modern C: The book of wisdom', 'CurrentPage': 0, 'Bookmarked': False, 'Parent': ''} {'ID': 'a969fcd6-64b0-4f71-b1ce-d9533ec4a2a3', 'Version': 1, 'Message': '', 'Succes': True, 'BlobURLGet': '', 'BlobURLGetExpires': '0001-01-01T00:00:00Z', 'BlobURLPut': '', 'BlobURLPutExpires': '', 'ModifiedClient': '2019-09-18T20:12:07.206206Z', 'Type': 'DocumentType', 'VissibleName': 'Modern C: The book of wisdom', 'CurrentPage': 0, 'Bookmarked': False, 'Parent': ''}
@@ -114,7 +114,7 @@ CollectionType
A CollectionType is a Folder. A CollectionType is a Folder.
These types are represented by the object :class:`rmapi.folder.Folder` These types are represented by the object :class:`rmapy.folder.Folder`
Working with folders is easy! Working with folders is easy!
@@ -122,42 +122,42 @@ Working with folders is easy!
:linenos: :linenos:
>>> from rmapi.api import Client >>> from rmapy.api import Client
>>> rmapi = Client() >>> rmapy = Client()
>>> rmapi.renew_token() >>> rmapy.renew_token()
True True
>>> collection = rmapi.get_meta_items() >>> collection = rmapy.get_meta_items()
>>> collection >>> collection
<rmapi.collections.Collection object at 0x7fc4718e1ed0> <rmapy.collections.Collection object at 0x7fc4718e1ed0>
>>> from rmapi.folder import Folder >>> from rmapy.folder import Folder
>>> # Get all the folders. Note that the fs of Remarkable is flat in the cloud >>> # Get all the folders. Note that the fs of Remarkable is flat in the cloud
... folders = [ f for f in collection if isinstance(f, Folder) ] ... folders = [ f for f in collection if isinstance(f, Folder) ]
>>> folders >>> folders
[<rmapi.folder.Folder 028400f5-b258-4563-bf5d-9a47c314668c>, <rmapi.folder.Folder 06a36729-f91e-47da-b334-dc088c1e73d2>, ...] [<rmapy.folder.Folder 028400f5-b258-4563-bf5d-9a47c314668c>, <rmapy.folder.Folder 06a36729-f91e-47da-b334-dc088c1e73d2>, ...]
>>> # Get the root folders >>> # Get the root folders
... root = [ f for f in folders if f.Parent == "" ] ... root = [ f for f in folders if f.Parent == "" ]
>>> root >>> root
[<rmapi.folder.Folder 028400f5-b258-4563-bf5d-9a47c314668c>, <rmapi.folder.Folder 5005a085-d7ee-4867-8859-4cd90dee0d62>, ...] [<rmapy.folder.Folder 028400f5-b258-4563-bf5d-9a47c314668c>, <rmapy.folder.Folder 5005a085-d7ee-4867-8859-4cd90dee0d62>, ...]
>>> # Create a new folder >>> # Create a new folder
... new_folder = Folder("New Folder") ... new_folder = Folder("New Folder")
>>> new_folder >>> new_folder
<rmapi.folder.Folder 579df08d-7ee4-4f30-9994-887e6341cae3> <rmapy.folder.Folder 579df08d-7ee4-4f30-9994-887e6341cae3>
>>> rmapi.create_folder(new_folder) >>> rmapy.create_folder(new_folder)
True True
>>> # verify >>> # verify
... [ f for f in rmapi.get_meta_items() if f.VissibleName == "New Folder" ] ... [ f for f in rmapy.get_meta_items() if f.VissibleName == "New Folder" ]
[<rmapi.folder.Folder 579df08d-7ee4-4f30-9994-887e6341cae3>] [<rmapy.folder.Folder 579df08d-7ee4-4f30-9994-887e6341cae3>]
>>> [ f for f in rmapi.get_meta_items() if f.VissibleName == "New Folder" ][0].ID == new_folder.ID >>> [ f for f in rmapy.get_meta_items() if f.VissibleName == "New Folder" ][0].ID == new_folder.ID
True True
>>> # Move a document in a folder >>> # Move a document in a folder
... doc = rmapi.get_doc("a969fcd6-64b0-4f71-b1ce-d9533ec4a2a3") ... doc = rmapy.get_doc("a969fcd6-64b0-4f71-b1ce-d9533ec4a2a3")
>>> doc >>> doc
<rmapi.document.Document a969fcd6-64b0-4f71-b1ce-d9533ec4a2a3> <rmapy.document.Document a969fcd6-64b0-4f71-b1ce-d9533ec4a2a3>
>>> doc.Parent = new_folder.ID >>> doc.Parent = new_folder.ID
>>> # Submit the changes >>> # Submit the changes
... rmapi.update_metadata(doc) ... rmapy.update_metadata(doc)
True True
>>> doc = rmapi.get_doc("a969fcd6-64b0-4f71-b1ce-d9533ec4a2a3") >>> doc = rmapy.get_doc("a969fcd6-64b0-4f71-b1ce-d9533ec4a2a3")
>>> doc.Parent == new_folder.ID >>> doc.Parent == new_folder.ID
True True
@@ -193,14 +193,14 @@ the remarkable file format:
:linenos: :linenos:
>>> from rmapi.document import ZipDocument >>> from rmapy.document import ZipDocument
>>> from rmapi.api import Client >>> from rmapy.api import Client
>>> rm = Client() >>> rm = Client()
>>> rm.renew_token() >>> rm.renew_token()
True True
>>> rawDocument = ZipDocument(doc="/home/svancampenhout/27-11-2019.pdf") >>> rawDocument = ZipDocument(doc="/home/svancampenhout/27-11-2019.pdf")
>>> rawDocument >>> rawDocument
<rmapi.document.ZipDocument b926ffc2-3600-460e-abfa-0fcf20b0bf99> <rmapy.document.ZipDocument b926ffc2-3600-460e-abfa-0fcf20b0bf99>
>>> rawDocument.metadata["VissibleName"] >>> rawDocument.metadata["VissibleName"]
'27-11-2019' '27-11-2019'

View File

@@ -1,77 +1,77 @@
rmapi package rmapy package
============= =============
Submodules Submodules
---------- ----------
rmapi.api module rmapy.api module
---------------- ----------------
.. automodule:: rmapi.api .. automodule:: rmapy.api
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
rmapi.collections module rmapy.collections module
------------------------ ------------------------
.. automodule:: rmapi.collections .. automodule:: rmapy.collections
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
rmapi.config module rmapy.config module
------------------- -------------------
.. automodule:: rmapi.config .. automodule:: rmapy.config
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
rmapi.const module rmapy.const module
------------------ ------------------
.. automodule:: rmapi.const .. automodule:: rmapy.const
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
rmapi.document module rmapy.document module
--------------------- ---------------------
.. automodule:: rmapi.document .. automodule:: rmapy.document
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
rmapi.exceptions module rmapy.exceptions module
----------------------- -----------------------
.. automodule:: rmapi.exceptions .. automodule:: rmapy.exceptions
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
rmapi.folder module rmapy.folder module
------------------- -------------------
.. automodule:: rmapi.folder .. automodule:: rmapy.folder
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
rmapi.meta module rmapy.meta module
----------------- -----------------
.. automodule:: rmapi.meta .. automodule:: rmapy.meta
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
rmapi.types module rmapy.types module
------------------ ------------------
.. automodule:: rmapi.types .. automodule:: rmapy.types
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
@@ -80,7 +80,7 @@ rmapi.types module
Module contents Module contents
--------------- ---------------
.. automodule:: rmapi .. automodule:: rmapy
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:

View File

@@ -1,7 +1,6 @@
import requests import requests
from logging import getLogger from logging import getLogger
from datetime import datetime from datetime import datetime
import json
from typing import Union, Optional from typing import Union, Optional
from uuid import uuid4 from uuid import uuid4
from .collections import Collection from .collections import Collection
@@ -20,10 +19,10 @@ from .const import (RFC3339Nano,
USER_TOKEN_URL, USER_TOKEN_URL,
DEVICE,) DEVICE,)
log = getLogger("rmapipy.rmapi") log = getLogger("rmapy")
DocumentOrFolder = Union[Document, Folder] DocumentOrFolder = Union[Document, Folder]
class Client(object): class Client(object):
"""API Client for Remarkable Cloud """API Client for Remarkable Cloud

View File

@@ -6,7 +6,7 @@ from typing import Dict
def load() -> dict: def load() -> dict:
"""Load the .rmapi config file""" """Load the .rmapy config file"""
config_file_path = Path.joinpath(Path.home(), ".rmapi") config_file_path = Path.joinpath(Path.home(), ".rmapi")
config: Dict[str, str] = {} config: Dict[str, str] = {}
@@ -18,7 +18,7 @@ def load() -> dict:
def dump(config: dict) -> None: def dump(config: dict) -> None:
"""Dump config to the .rmapi config file """Dump config to the .rmapy config file
Args: Args:
config: A dict containing data to dump to the .rmapi config: A dict containing data to dump to the .rmapi

View File

@@ -1,7 +1,7 @@
RFC3339Nano = "%Y-%m-%dT%H:%M:%SZ" RFC3339Nano = "%Y-%m-%dT%H:%M:%SZ"
USER_AGENT = "rmapipy" USER_AGENT = "rmapy"
BASE_URL = "https://document-storage-production-dot-remarkable-production.appspot.com" # noqa BASE_URL = "https://document-storage-production-dot-remarkable-production.appspot.com" # noqa
DEVICE_TOKEN_URL = "https://my.remarkable.com/token/json/2/device/new" DEVICE_TOKEN_URL = "https://my.remarkable.com/token/json/2/device/new"
USER_TOKEN_URL = "https://my.remarkable.com/token/json/2/user/new" USER_TOKEN_URL = "https://my.remarkable.com/token/json/2/user/new"
DEVICE = "desktop-windows" DEVICE = "desktop-windows"
SERVICE_MGR_URL = "https://service-manager-production-dot-remarkable-production.appspot.com" # noqa

View File

@@ -35,7 +35,7 @@ class RmPage(object):
def __str__(self) -> str: def __str__(self) -> str:
"""String representation of this object""" """String representation of this object"""
return f"<rmapi.document.RmPage {self.order} for {self.ID}>" return f"<rmapy.document.RmPage {self.order} for {self.ID}>"
def __repr__(self) -> str: def __repr__(self) -> str:
"""String representation of this object""" """String representation of this object"""
@@ -73,7 +73,7 @@ class Document(Meta):
def __str__(self): def __str__(self):
"""String representation of this object""" """String representation of this object"""
return f"<rmapi.document.Document {self.ID}>" return f"<rmapy.document.Document {self.ID}>"
def __repr__(self): def __repr__(self):
"""String representation of this object""" """String representation of this object"""
@@ -109,7 +109,7 @@ class ZipDocument(object):
zipfile: The raw zipfile in memory. zipfile: The raw zipfile in memory.
pdf: the raw pdf file if there is one. pdf: the raw pdf file if there is one.
epub: the raw epub file if there is one. epub: the raw epub file if there is one.
rm: A list of :class:rmapi.document.RmPage in this zip. rm: A list of :class:rmapy.document.RmPage in this zip.
""" """
# {"extraMetadata": {}, # {"extraMetadata": {},
@@ -216,7 +216,7 @@ class ZipDocument(object):
def __str__(self) -> str: def __str__(self) -> str:
"""string representation of this class""" """string representation of this class"""
return f"<rmapi.document.ZipDocument {self.ID}>" return f"<rmapy.document.ZipDocument {self.ID}>"
def __repr__(self) -> str: def __repr__(self) -> str:
"""string representation of this class""" """string representation of this class"""
@@ -355,7 +355,7 @@ def from_zip(ID: str, file: str) -> ZipDocument:
def from_request_stream(ID: str, stream: Response) -> ZipDocument: def from_request_stream(ID: str, stream: Response) -> ZipDocument:
"""Return a ZipDocument from a request stream containing a zipfile. """Return a ZipDocument from a request stream containing a zipfile.
This is used with the BlobGETUrl from a :class:`rmapi.document.Document`. This is used with the BlobGETUrl from a :class:`rmapy.document.Document`.
Args: Args:
ID: The object ID this zipfile represents. ID: The object ID this zipfile represents.

View File

@@ -72,7 +72,7 @@ class Folder(Meta):
return data return data
def __str__(self): def __str__(self):
return f"<rmapi.folder.Folder {self.ID}>" return f"<rmapy.folder.Folder {self.ID}>"
def __repr__(self): def __repr__(self):
return self.__str__() return self.__str__()

View File

@@ -29,7 +29,7 @@ setup(
# There are some restrictions on what makes a valid project name # There are some restrictions on what makes a valid project name
# specification here: # specification here:
# https://packaging.python.org/specifications/core-metadata/#name # https://packaging.python.org/specifications/core-metadata/#name
name='rmapi', # Required name='rmapy', # Required
# Versions should comply with PEP 440: # Versions should comply with PEP 440:
# https://www.python.org/dev/peps/pep-0440/ # https://www.python.org/dev/peps/pep-0440/
@@ -37,7 +37,7 @@ setup(
# For a discussion on single-sourcing the version across setup.py and the # For a discussion on single-sourcing the version across setup.py and the
# project code, see # project code, see
# https://packaging.python.org/en/latest/single_source_version.html # https://packaging.python.org/en/latest/single_source_version.html
version='0.2.0', # Required version='0.2.1', # Required
# This is a one-line description or tagline of what your project does. This # This is a one-line description or tagline of what your project does. This
# corresponds to the "Summary" metadata field: # corresponds to the "Summary" metadata field:
@@ -70,7 +70,7 @@ setup(
# #
# This field corresponds to the "Home-Page" metadata field: # This field corresponds to the "Home-Page" metadata field:
# https://packaging.python.org/specifications/core-metadata/#home-page-optional # https://packaging.python.org/specifications/core-metadata/#home-page-optional
url='https://github.com/subutux/rmapi', # Optional url='https://github.com/subutux/rmapy', # Optional
# This should be your name or the name of the organization which owns the # This should be your name or the name of the organization which owns the
# project. # project.
@@ -110,7 +110,7 @@ setup(
# project page. What does your project relate to? # project page. What does your project relate to?
# #
# Note that this is a string of words separated by whitespace, not a list. # Note that this is a string of words separated by whitespace, not a list.
keywords='remarkable rmapi cloud paper tablet', # Optional keywords='remarkable rmapy cloud paper tablet', # Optional
# You can just specify package directories manually here if your project is # You can just specify package directories manually here if your project is
# simple. Or you can use find_packages(). # simple. Or you can use find_packages().
@@ -197,9 +197,9 @@ setup(
# maintainers, and where to support the project financially. The key is # maintainers, and where to support the project financially. The key is
# what's used to render the link text on PyPI. # what's used to render the link text on PyPI.
project_urls={ # Optional project_urls={ # Optional
'Bug Reports': 'https://github.com/subutux/rmapi/issues', 'Bug Reports': 'https://github.com/subutux/rmapy/issues',
'Funding': 'https://donate.pypi.org', 'Funding': 'https://donate.pypi.org',
'Say Thanks!': 'https://www.paypal.me/subutux', 'Say Thanks!': 'https://www.paypal.me/subutux',
'Source': 'https://github.com/subutux/rmapi/', 'Source': 'https://github.com/subutux/rmapy/',
}, },
) )