pdf2remarkable (5238B)
1 #!/usr/bin/env bash 2 # Transfer PDF file(s) to a reMarkable 3 # Adrian Daerr 2017/2018 - public domain 4 # 5 # - The files will appear in reMarkable's top-level "My Files" directory, 6 # - After finishing all transfers, you have to restart the xochitl 7 # service on the tablet in order to force a scan of its document 8 # directory ${xochitldir} (so that you see the newly transferred 9 # files), e.g. by sending the tablet the following command: 10 # ssh remarkable systemctl restart xochitl 11 # 12 # Disclaimer and liability limitation: 13 # [see also all-caps text borrowed from GPL below] 14 # - This is a dirty hack based on superficial reverse-engineering. 15 # - Expect this script to break at any time, especially upon a 16 # reMarkable system upgrade 17 # - I am not responsible for any damage caused by this script, 18 # including (but not limited to) bricking your reMarkable, erasing 19 # your documents etc. YOU ARE USING THIS SOFTWARE ON YOUR OWN RISK. 20 # 21 # Disclaimer of Warranty. 22 # 23 # THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 24 # APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE 25 # COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM 26 # “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, 27 # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 28 # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE 29 # RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. 30 # SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL 31 # NECESSARY SERVICING, REPAIR OR CORRECTION. 32 # 33 # Limitation of Liability. 34 # 35 # IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 36 # WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO 37 # MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE 38 # LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, 39 # INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR 40 # INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 41 # DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 42 # YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE 43 # WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS 44 # BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 45 # 46 # Prerequisites: 47 # 48 # * The ssh access has to be configured under the host alias 'remarkable', 49 # e.g. by putting the following in .ssh/config : 50 # | host remarkable 51 # | Hostname 10.11.99.1 52 # | User root 53 # | ForwardX11 no 54 # | ForwardAgent no 55 # See also the variable "xochitldir" below 56 # 57 # * Beyond core utilities (date, basename,...), the following software 58 # has to be installed on the host computer: 59 # - uuidgen 60 # - imagemagick (or graphicsmagick) 61 62 set -e 63 64 # This is where ssh will try to copy the files associated with the document 65 xochitldir=remarkable:.local/share/remarkable/xochitl/ 66 67 # Check if we have something to do 68 if [ $# -lt 1 ]; then 69 echo "Transfer PDF document to a reMarkable tablet" 70 echo "usage: $(basename $0) path-to-pdf-file [path-to-pdf-file]..." 71 exit 1 72 fi 73 74 # Create directory where we prepare the files as the reMarkable expects them 75 tmpdir=$(mktemp -d) 76 77 # Loop over the command line arguments, 78 # which we expect are paths to the PDF files to be transfered 79 for pdfname in "$@" ; do 80 81 # reMarkable documents appear to be identified by universally unique IDs (UUID), 82 # so we generate one for the document at hand 83 uuid=$(uuidgen) 84 85 # Copy the PDF file itself 86 cp "$pdfname" "${tmpdir}/${uuid}.pdf" 87 88 # Add metadata 89 # The lastModified item appears to contain the date in milliseconds since Epoch 90 cat <<EOF >>"${tmpdir}/${uuid}.metadata" 91 { 92 "deleted": false, 93 "lastModified": "$(date +%s)000", 94 "metadatamodified": false, 95 "modified": false, 96 "parent": "", 97 "pinned": false, 98 "synced": false, 99 "type": "DocumentType", 100 "version": 1, 101 "visibleName": "$(basename "$pdfname" .pdf)" 102 } 103 EOF 104 105 # Add content information 106 cat <<EOF >"${tmpdir}/${uuid}.content" 107 { 108 "extraMetadata": { 109 }, 110 "fileType": "pdf", 111 "fontName": "", 112 "lastOpenedPage": 0, 113 "lineHeight": -1, 114 "margins": 100, 115 "pageCount": 1, 116 "textScale": 1, 117 "transform": { 118 "m11": 1, 119 "m12": 1, 120 "m13": 1, 121 "m21": 1, 122 "m22": 1, 123 "m23": 1, 124 "m31": 1, 125 "m32": 1, 126 "m33": 1 127 } 128 } 129 EOF 130 131 # Add cache directory 132 mkdir "${tmpdir}/${uuid}.cache" 133 134 # Add highlights directory 135 mkdir "${tmpdir}/${uuid}.highlights" 136 137 # Add thumbnails directory 138 mkdir "${tmpdir}/${uuid}.thumbnails" 139 140 # Generate preview thumbnail for the first page 141 # Different sizes were found (possibly depending on whether created by 142 # the reMarkable itself or some synchronization app?): 280x374 or 143 # 362x512 pixels. In any case the thumbnails appear to be baseline 144 # jpeg images - JFIF standard 1.01, resolution (DPI), density 228x228 145 # or 72x72, segment length 16, precision 8, frames 3 146 # 147 # The following will look nice only for PDFs that are higher than about 32mm. 148 convert -limit thread 1 -density 300 "$pdfname"'[0]' -colorspace Gray -separate -average -shave 5%x5% -resize 280x374 "${tmpdir}/${uuid}.thumbnails/0.jpg" 149 150 # Transfer files 151 echo "Transferring $pdfname$ as $uuid$" 152 scp -r "${tmpdir}"/* ${xochitldir} 153 rm -rf "${tmpdir:?}"/* 154 done 155 156 rm -rf "${tmpdir}"