def deliver_issue(self, absolute_path: str): """Deliver issues to the ReMarkable. :param absolute_path: An absolute path for the epub file. """ # Ensure a "News Assistant" folder exists collection = self.client.get_meta_items() root_folders = [ f for f in collection if isinstance(f, Folder) and f.Parent == "" ] delivery_folder_filter = [ f for f in root_folders if f.VissibleName == DELIVERY_FOLDER ] if len(delivery_folder_filter) == 0: folder = Folder(DELIVERY_FOLDER) self.client.create_folder(folder) delivery_folder_filter.append(folder) delivery_folder = delivery_folder_filter[0] # Upload the issue pdf_path = RemarkableDelivery.convert_issue_to_pdf(absolute_path) document = ZipDocument(doc=pdf_path) now = datetime.now() document.metadata["VissibleName"] = now.strftime("%d %B, %Y") self.client.upload(document, delivery_folder)
def upload_document(self, local_id, local_version, cloud_id, cloud_version, path): content_dir = ( self.sync_manager.push_dir(Remarkable) + f'/{local_id}/{local_version}' ) content_path = f'{content_dir}/{local_id}.pdf' if cloud_version: # reMarkable won't sync updates, need to delete # and re-add to_delete = Document(ID=cloud_id, Version=cloud_version) self.rm_api.delete(to_delete) doc = ZipDocument(doc=content_path) folder = self.get_or_create_folder(path) doc.metadata['VissibleName'] = get_pdf_title(content_path) doc.metadata['version'] = 1 mapping_info = SyncMapping( remote_id=doc.ID, remote_version = 1, remote_path=path ) print(f"push: document '{doc.metadata['VissibleName']}' {local_id} to {mapping_info.remote_path})") self.rm_api.upload(doc, folder) return mapping_info
def transfer_file_to_remarkable(fname: str, config_dict: dict = None): from rmapy.document import ZipDocument from rmapy.api import Client rm = Client(config_dict=config_dict) rm.renew_token() doc = ZipDocument(doc=fname) rm.upload(doc) return True
def transfer_file_to_remarkable(user_email: str, fname, fbytes): # logging.info(f"Asking for {user_email} credentials...") cfg = get_config_for_user(user_email) rm = Client(config_dict=cfg) # Annoychops; gotta save to disk. Bummski! tfile = tempfile.NamedTemporaryFile(prefix=fname, suffix=".pdf") tfile.write(fbytes) tfile.seek(0) doc = ZipDocument(doc=tfile.name) rm.upload(doc)
def upload(filepath=None, replace=False): if not filepath: parser = argparse.ArgumentParser( "Upload Goosepaper to reMarkable tablet") parser.add_argument( "file", default=None, help="The file to upload", ) args = parser.parse_args() filepath = args.file filepath = Path(filepath) client = Client() try: client.renew_token() except AuthError: print( "Looks like this if the first time you've uploaded, need to register the device" ) print( "Get the code from here: https://my.remarkable.com/connect/remarkable" ) code = input() print("registering") client.register_device(code) if not client.renew_token(): print("registration failed D:") else: print("registration successful") for item in client.get_meta_items(): if item.VissibleName == filepath.stem: if replace: client.delete(item) else: print("Honk! Paper already exists!") return False doc = ZipDocument(doc=str(filepath.resolve())) if client.upload(doc): print("Honk! Upload successful!") else: print("Honk! Error with upload!") return True
def main(): todo_manager = TodoManager() today = date.today() pdf_path = '/tmp/Today-{}.pdf'.format(today.strftime("%b-%d-%Y")) todo_string = todo_manager.getToDoListString() f = open(MARKDOWN_PATH, "w") f.write(todo_string) f.close() r = subprocess.run(['pandoc', '-s', MARKDOWN_PATH, '-o', pdf_path], stdout=subprocess.PIPE, universal_newlines=True) rm = Client() rm.renew_token() rawDocument = ZipDocument(doc=pdf_path) rm.upload(rawDocument) print(todo_string)
def upload_rm_doc(name, rms): empty_jpg = Path(__file__).parent / "empty.jpg" empty_jpg_bytes = empty_jpg.read_bytes() rmapy = Client() if not rmapy.is_auth(): raise Exception("Not authenticated") rmapy.renew_token() rmps = [] for rm in rms: layer_counter = count(1) buffer = BytesIO() rm.to_bytes(buffer) buffer.seek(0) uuid = str(uuid4()) rmp = RmPage( buffer, metadata={ "layers": [{ "name": layer.name if layer.name else f"Layer {next(layer_counter)}" } for layer in rm.objects] }, thumbnail=BytesIO(empty_jpg_bytes), order=uuid, ) rmps.append(rmp) zd = ZipDocument() zd.content["fileType"] = "notebook" zd.content["pages"] = [rmp.order for rmp in rmps] zd.content["pageCount"] = len(rmps) zd.metadata["VissibleName"] = name zd.pagedata = "\n".join(["Blank"] * len(rmps)) zd.rm.extend(rmps) rmapy.upload(zd)
def transfer_file_to_remarkable(user_email: str, fname, fbytes): plog(f"* Asking for {user_email} credentials...") cfg = renew_user_token(user_email) rm = Client(config_dict=cfg) # Annoychops; gotta save to disk. Bummski! tfile = tempfile.NamedTemporaryFile(prefix=fname, suffix=".pdf") tfile.write(fbytes) tfile.seek(0) plog(f"* Generating zip...") doc = ZipDocument(doc=tfile.name) plog(f"* Uploading to device.") rm.upload(doc) plog("Success.") send_email_if_enabled( user_email, subject="Your document is on the way!", message= f"Your document, '{fname}', has been successfully sent to your reMarkable.", )
def main(): wallabag = Wallabag() wallabag.wallabagLogin() rmapy = Remarkable() rmapy.renew_token() collection = rmapy.get_meta_items() unread = [ f for f in collection if isinstance(f, Folder) and f.VissibleName == UNREAD_FOLDER ][0] favourites = [ f for f in collection if isinstance(f, Folder) and f.VissibleName == FAVOURITES_FOLDER ][0] archive = [ f for f in collection if isinstance(f, Folder) and f.VissibleName == ARCHIVE_FOLDER ][0] titles = set(f.VissibleName for f in collection if f.Parent in [unread.ID, archive.ID, favourites.ID]) for w in wallabag.getEntries()[:50]: title = f"{w['title']} - {w['id']}" w_modifiedtime = datetime.strptime(w["updated_at"], "%Y-%m-%dT%H:%M:%S%z") if w["is_archived"] == 0: target = unread elif w["is_starred"] == 1: target = favourites else: target = archive if title not in titles: with tempfile.NamedTemporaryFile(suffix=".epub") as f: wallabag.export(w["id"], f.file) rawDocument = ZipDocument(doc=f.name) rawDocument.metadata["VissibleName"] = title rawDocument.metadata[ "ModifiedClient"] = w_modifiedtime.astimezone( tz=timezone.utc).strftime(RFC3339Nano) rmapy.upload(rawDocument, target) print(f"Uploaded {title} to {target.VissibleName}") else: rm_doc = [f for f in collection if f.VissibleName == title][0] try: rm_mod_time = datetime.strptime( rm_doc.ModifiedClient, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=timezone.utc) except ValueError: rm_mod_time = datetime.strptime( rm_doc.ModifiedClient, "%Y-%m-%dT%H:%M:%S.%fZ").replace(tzinfo=timezone.utc) if rm_doc.Parent == target.ID: continue elif w_modifiedtime >= rm_mod_time: print( f"{title} in wrong folder and more recent in Wallabag, moving to {target.VissibleName}..." ) rm_doc.Parent = target.ID rm_doc.ModifiedClient = w_modifiedtime.astimezone( tz=timezone.utc).strftime(RFC3339Nano) rmapy.update_metadata(rm_doc) else: # Wrong message, should be parents "vissiblename" print( f"{title} moved to {target.VissibleName}, updating Wallabag..." ) if rm_doc.Parent == archive.ID: wallabag.updateEntry(w, archive=True, starred=False) elif rm_doc.Parent == favourites.ID: wallabag.updateEntry(w, archive=True, starred=True) elif rm_doc.Parent == unread.ID: wallabag.updateEntry(w, archive=False) else: print( "Found some edge case when searching for Wallabag location." )
def do_upload(filepath, multiparser): filepath = Path(filepath) replace = (False if multiparser.argumentOrConfig("noreplace") else multiparser.argumentOrConfig("replace")) folder = multiparser.argumentOrConfig("folder") cleanup = multiparser.argumentOrConfig("cleanup") strictlysane = multiparser.argumentOrConfig("strictlysane") nocase = multiparser.argumentOrConfig("nocase") if strictlysane: nocase = True if multiparser.argumentOrConfig("showconfig"): print("\nParameters passed to do_upload\n----------------\n") print( "Replace:\t{0}\nFolder:\t\t{1}\nCleanup:\t{2}\nStrictlysane:\t{3}\nNocase:\t\t{4}\nFilepath:\t{5}\n" .format(replace, folder, cleanup, strictlysane, nocase, filepath)) client = auth_client() if not client: print("Honk Honk! Couldn't auth! Is your rmapy configured?") return False if not validateFolder(folder): return False # Added error handling to deal with possible race condition where the file is mangled # or not written out before the upload actually occurs such as an AV false positive. # 'pdf' is a simple throwaway file handle to make sure that we retain control of the # file while it's being imported. try: with open(filepath.resolve()) as pdf: doc = ZipDocument(doc=str(filepath.resolve())) except IOError as err: print(f"Error locating or opening {filepath}") return False paperCandidates = [] paperFolder = None for item in getallitems(client): # is it the folder we are looking for? if (folder and item.Type == "CollectionType" # is a folder and item.VissibleName.lower() == folder.lower() # has the name we're looking for and (item.Parent == None or item.Parent == "")): # is not in another folder paperFolder = item # is it possibly the file we are looking for? elif (item.Type == "DocumentType" and item.VissibleName.lower() == str( doc.metadata["VissibleName"]).lower()): paperCandidates.append(item) for paper in paperCandidates: parent = client.get_doc(paper.Parent) # if the folder was found, check if a paper candidate is in it paper = None if len(paperCandidates) > 0: if folder: filtered = list( filter(lambda item: item.Parent == paperFolder.ID, paperCandidates)) else: filtered = list( filter( lambda item: item.Parent != "trash" and client.get_doc( item.Parent) == None, paperCandidates, )) if len(filtered) > 1 and replace: print( f"multiple candidate papers with the same name {filtered[0].VissibleName}, don't know which to delete" ) return False if len(filtered) == 1: # found the outdated paper paper = filtered[0] if paper is not None: if replace: result = client.delete(paper) else: print("Honk! The paper already exists!") return False if folder and not paperFolder: paperFolder = Folder(folder) if not client.create_folder(paperFolder): print("Honk! Failed to create the folder!") return False # workarround rmapy bug: client.upload(doc) would set a non-existing parent # ID to the document if not paperFolder: paperFolder = Folder() paperFolder.ID = "" if isinstance(paperFolder, Folder): result = client.upload(doc, paperFolder) if result: print("Honk! Upload successful!") if cleanup: try: os.remove(filepath.resolve()) except: print( "Honk! Honk! Failed to remove file after upload: {0}". format(filepath.resolve())) return False else: print("Honk! Error with upload!") return result else: print("Honk! Could not upload: Document already exists.") return False
from rmapy.api import Client from rmapy.document import ZipDocument, Document FILENAME = 'notes.pdf' rmapy = Client() # 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 # go rmapi client. # rmapy.register_device("kmdfhcsf") rmapy.renew_token() rawDocument = ZipDocument(doc=FILENAME) collection = rmapy.get_meta_items() # Gather old versions to delete old = [ f for f in collection if isinstance(f, Document) and f.VissibleName == 'notes' ] rmapy.upload(rawDocument) for f in old: rmapy.delete(f)
def upload(filepath, replace=False, folder=None): client = auth_client() if not client: print("Honk Honk! Couldn't auth! Is your rmapy configured?") return False if not validateFolder(folder): return False filepath = Path(filepath) # Added error handling to deal with possible race condition where the file is mangled # or not written out before the upload actually occurs such as an AV false positive. # 'pdf' is a simple throwaway file handle to make sure that we retain control of the # file while it's being imported. try: with open(filepath.resolve()) as pdf: doc = ZipDocument(doc=str(filepath.resolve())) except IOError as err: print(f"Error locating or opening {filepath}") return False paperCandidates = [] paperFolder = None for item in getallitems(client): # is it the folder we are looking for? if (folder and item.Type == "CollectionType" # is a folder and item.VissibleName.lower() == folder.lower() # has the name we're looking for and (item.Parent == None or item.Parent == "")): # is not in another folder paperFolder = item # is it possibly the file we are looking for? elif item.Type == "DocumentType" and item.VissibleName.lower() == str( doc.metadata["VissibleName"]).lower(): paperCandidates.append(item) for paper in paperCandidates: if paper.Parent == "trash": continue parent = client.get_doc(paper.Parent) # if the folder was found, check if a paper candidate is in it paper = None if len(paperCandidates) > 0: if folder: filtered = list( filter(lambda item: item.Parent == paperFolder.ID, paperCandidates)) else: filtered = list( filter( lambda item: item.Parent != "trash" and client.get_doc( item.Parent) == None, paperCandidates)) if len(filtered) > 1 and replace: print( f"multiple candidate papers with the same name {filtered[0].VissibleName}, don't know which to delete" ) return False if len(filtered) == 1: # found the outdated paper paper = filtered[0] if paper is not None: if replace: result = client.delete(paper) else: print("Honk! The paper already exists!") return False if folder and not paperFolder: paperFolder = Folder(folder) if not client.create_folder(paperFolder): print("Honk! Failed to create the folder!") return False # workarround rmapy bug: client.upload(doc) would set a non-existing parent ID to the document if not paperFolder: paperFolder = Folder() paperFolder.ID = "" if isinstance(paperFolder, Folder): result = client.upload(doc, paperFolder) if result: print("Honk! Upload successful!") else: print("Honk! Error with upload!") return result else: print("Honk! Could not upload: Document already exists.") return False
#!/usr/bin/python3.7 from rmapy.document import ZipDocument from rmapy.api import Client from os import listdir rmapy = Client() # 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 # go rmapi client. # rmapy.register_device("ayvnpfoc") # It's always a good idea to refresh the user token every time you start # a new session. rmapy.renew_token() # Should return True # delete the old one collection = rmapy.get_meta_items() oldWapo = [d for d in collection if d.VissibleName == 'The Washington Post'] if len(oldWapo) > 0: rmapy.delete(oldWapo[0]) # rawDocument = ZipDocument(doc="wapo.pdf") # rawDocument.metadata["VissibleName"]="The Washington Post" uuid = listdir("ZipDocument")[0].split('.')[0] rawDocument = ZipDocument(uuid, file="wapo.zip") rawDocument.metadata["VissibleName"] = "The Washington Post" rmapy.upload(rawDocument)
def upload_file_to_folder(self, file: str, folder_name: str): folder = self._find_folder(folder_name) document = ZipDocument(doc=file) document.metadata["VissibleName"] = Path(file).stem self._rmapy.upload(document, folder)
import sys from rmapy.document import ZipDocument from rmapy.api import Client rmapy_client = Client() rmapy_client.renew_token() doc = ZipDocument(doc=sys.argv[1]) rmapy_client.upload(doc)