copy-to-remarkable 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #!/bin/sh
  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. # This is where ssh will try to copy the files associated with the document
  62. REMARKABLE_HOST=${REMARKABLE_HOST:-remarkable}
  63. REMARKABLE_XOCHITL_DIR=${REMARKABLE_XOCHITL_DIR:-.local/share/remarkable/xochitl/}
  64. TARGET_DIR="${REMARKABLE_HOST}:${REMARKABLE_XOCHITL_DIR}"
  65. # Check if we have something to do
  66. if [ $# -lt 1 ]; then
  67. echo "Transfer PDF document to a reMarkable tablet"
  68. echo "usage: $(basename $0) [ -r ] path-to-pdf-file [path-to-pdf-file]..."
  69. exit 1
  70. fi
  71. RESTART_XOCHITL_DEFAULT=${RESTART_XOCHITL_DEFAULT:-0}
  72. RESTART_XOCHITL=${RESTART_XOCHITL_DEFAULT}
  73. if [ $1 == "-r" ] ; then
  74. shift
  75. if [ $RESTART_XOCHITL_DEFAULT == 0 ] ; then
  76. echo Switching
  77. RESTART_XOCHITL=1
  78. else
  79. RESTART_XOCHITL=0
  80. fi
  81. fi
  82. # Create directory where we prepare the files as the reMarkable expects them
  83. tmpdir=$(mktemp -d)
  84. # Loop over the command line arguments,
  85. # which we expect are paths to the PDF files to be transfered
  86. for pdfname in $@ ; do
  87. # reMarkable documents appear to be identified by universally unique IDs (UUID),
  88. # so we generate one for the document at hand
  89. uuid=$(uuidgen)
  90. # Copy the PDF file itself
  91. cp $pdfname ${tmpdir}/${uuid}.pdf
  92. # Add metadata
  93. # The lastModified item appears to contain the date in milliseconds since Epoch
  94. cat <<EOF >>${tmpdir}/${uuid}.metadata
  95. {
  96. "deleted": false,
  97. "lastModified": "$(date +%s)000",
  98. "metadatamodified": false,
  99. "modified": false,
  100. "parent": "",
  101. "pinned": false,
  102. "synced": false,
  103. "type": "DocumentType",
  104. "version": 1,
  105. "visibleName": "$(basename $pdfname .pdf)"
  106. }
  107. EOF
  108. # Add content information
  109. cat <<EOF >${tmpdir}/${uuid}.content
  110. {
  111. "extraMetadata": {
  112. },
  113. "fileType": "pdf",
  114. "fontName": "",
  115. "lastOpenedPage": 0,
  116. "lineHeight": -1,
  117. "margins": 100,
  118. "pageCount": 1,
  119. "textScale": 1,
  120. "transform": {
  121. "m11": 1,
  122. "m12": 1,
  123. "m13": 1,
  124. "m21": 1,
  125. "m22": 1,
  126. "m23": 1,
  127. "m31": 1,
  128. "m32": 1,
  129. "m33": 1
  130. }
  131. }
  132. EOF
  133. # Add cache directory
  134. mkdir ${tmpdir}/${uuid}.cache
  135. # Add highlights directory
  136. mkdir ${tmpdir}/${uuid}.highlights
  137. # Add thumbnails directory
  138. mkdir ${tmpdir}/${uuid}.thumbnails
  139. # Generate preview thumbnail for the first page
  140. # Different sizes were found (possibly depending on whether created by
  141. # the reMarkable itself or some synchronization app?): 280x374 or
  142. # 362x512 pixels. In any case the thumbnails appear to be baseline
  143. # jpeg images - JFIF standard 1.01, resolution (DPI), density 228x228
  144. # or 72x72, segment length 16, precision 8, frames 3
  145. #
  146. # The following will look nice only for PDFs that are higher than about 32mm.
  147. convert -density 300 $pdfname'[0]' \
  148. -colorspace Gray \
  149. -separate -average \
  150. -shave 5%x5% \
  151. -resize 280x374 \
  152. ${tmpdir}/${uuid}.thumbnails/0.jpg
  153. # Transfer files
  154. echo "Transferring $pdfname as $uuid"
  155. scp -r ${tmpdir}/* "${TARGET_DIR}"
  156. rm -rf ${tmpdir}/*
  157. done
  158. rm -rf ${tmpdir}
  159. if [ $RESTART_XOCHITL -eq 1 ] ; then
  160. echo "Restarting Xochitl..."
  161. ssh ${REMARKABLE_HOST} "systemctl restart xochitl"
  162. echo "Done."
  163. fi