forked from metaperl/scpaste
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscpaste.el
245 lines (205 loc) · 8.7 KB
/
scpaste.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
;;; scpaste.el --- Paste to the web via scp.
;; Copyright © 2008-2012 Phil Hagelberg and contributors
;; Author: Phil Hagelberg
;; URL: https://github.com/technomancy/scpaste
;; Version: 0.6.5
;; Created: 2008-04-02
;; Keywords: convenience hypermedia
;; EmacsWiki: SCPaste
;; Package-Requires: ((htmlize "1.39"))
;; This file is NOT part of GNU Emacs.
;;; Commentary:
;; This will place an HTML copy of a buffer on the web on a server
;; that the user has shell access on.
;; It's similar in purpose to services such as http://paste.lisp.org
;; or http://rafb.net, but it's much simpler since it assumes the user
;; has an account on a publicly-accessible HTTP server. It uses `scp'
;; as its transport and uses Emacs' font-lock as its syntax
;; highlighter instead of relying on a third-party syntax highlighter
;; for which individual language support must be added one-by-one.
;;; Install
;; Add Marmalade as a package source, and then run M-x package-install
;; scpaste.
;; Set `scpaste-http-destination' and `scpaste-scp-destination' to
;; appropriate values, and add this to your Emacs config:
;; (setq scpaste-http-destination "http://p.hagelb.org"
;; scpaste-scp-destination "p.hagelb.org:p.hagelb.org")
;; If you have a different keyfile, you can set that, too:
;; (setq scpaste-scp-pubkey "~/.ssh/my_keyfile.pub")
;; If you use a non-standard ssh port, you can specify it by setting
;; `scpaste-scp-port'.
;; If you need to use alternative scp and ssh programs, you can set
;; `scpaste-scp' and `scpaste-ssh'. For example, scpaste works with the Putty
;; suite on Windows if you set these to pscp and plink, respectively.
;; Optionally you can set the displayed name for the footer and where
;; it should link to:
;; (setq scpaste-user-name "Technomancy"
;; scpaste-user-address "http://technomancy.us/")
;;; Usage
;; M-x scpaste, enter a name, and press return. The name will be
;; incorporated into the URL by escaping it and adding it to the end
;; of `scpaste-http-destination'. The URL for the pasted file will be
;; pushed onto the kill ring.
;; You can autogenerate a splash page that gets uploaded as index.html
;; in `scpaste-http-destination' by invoking M-x scpaste-index. This
;; will upload an explanation as well as a listing of existing
;; pastes. If a paste's filename includes "private" it will be skipped.
;; You probably want to set up SSH keys for your destination to avoid
;; having to enter your password once for each paste. Also be sure the
;; key of the host referenced in `scpaste-scp-destination' is in your
;; known hosts file--scpaste will not prompt you to add it but will
;; simply hang.
;;; License:
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
;;; Code:
(require 'url)
(require 'htmlize)
(defvar scpaste-scp-port
nil)
(defvar scpaste-scp
"scp"
"The scp program to use.")
(defvar scpaste-ssh
"ssh"
"The ssh program to use when running remote shell commands.")
(defvar scpaste-http-destination
"http://p.hagelb.org"
"Publicly-accessible (via HTTP) location for pasted files.")
(defvar scpaste-scp-destination
"p.hagelb.org:p.hagelb.org"
"SSH-accessible directory corresponding to `scpaste-http-destination'.
You must have write-access to this directory via `scp'.")
(defvar scpaste-scp-pubkey
nil
"Identity file for the server.
Corresponds to ssh’s `-i` option Example: \"~/.ssh/id.pub\"")
(defvar scpaste-user-name
nil
"Name displayed under the paste.")
(defvar scpaste-user-address
nil
"Link to the user’s homebase (can be a mailto:).")
;; To set defvar while developing: (load-file (buffer-file-name))
(defvar scpaste-el-location (replace-regexp-in-string "\.elc$" ".el"
load-file-name))
(defun scpaste-footer ()
"HTML message to place at the bottom of each file."
(concat "<p style='font-size: 8pt; font-family: monospace;'>Generated by "
(let ((user (or scpaste-user-name user-full-name)))
;;(concat "DEBUG" user scpaste-user-name scpaste-user-address)
(if scpaste-user-address
(concat "<a href='" scpaste-user-address "'>" user "</a>")
user))
" using <a href='http://p.hagelb.org'>scpaste</a> at %s. "
(cadr (current-time-zone)) ". (<a href='%s'>original</a>)</p>"))
;;;###autoload
(defun scpaste (original-name)
"Paste the current buffer via `scp' to `scpaste-http-destination'.
If ORIGINAL-NAME is an empty string, then the buffer name is used
for the file name."
(interactive "MName (defaults to buffer name): ")
(let* ((b (generate-new-buffer (generate-new-buffer-name "b")))
(hb (htmlize-buffer))
(name (replace-regexp-in-string "[/\\%*:|\"<> ]+" "_"
(if (equal "" original-name)
(buffer-name)
original-name)))
(full-url (concat scpaste-http-destination
"/" (url-hexify-string name) ".html"))
(scp-destination (concat scpaste-scp-destination
"/" name ".html"))
(scp-original-destination (concat scpaste-scp-destination
"/" name))
(tmp-file (concat temporary-file-directory name))
(tmp-hfile (concat temporary-file-directory name ".html")))
;; Save the files (while adding a footer to html file)
(save-excursion
(copy-to-buffer b (point-min) (point-max))
(switch-to-buffer b)
(write-file tmp-file)
(kill-buffer b)
(switch-to-buffer hb)
(goto-char (point-min))
(search-forward "</body>\n</html>")
(insert (format (scpaste-footer)
(current-time-string)
(substring full-url 0 -5)))
(write-file tmp-hfile)
(kill-buffer hb))
(let* ((identity (if scpaste-scp-pubkey
(concat "-i " scpaste-scp-pubkey) ""))
(port (if scpaste-scp-port (concat "-P " scpaste-scp-port)))
(invocation (concat scpaste-scp " -q " identity " " port))
(command-1 (concat invocation " " tmp-file " "
scp-original-destination))
(command-2 (concat invocation " " tmp-hfile " "
scp-destination)))
(let* ((error-buffer "*scp-error*")
(retval (+
(with-temp-message
(format "Executing %s" command-1)
(shell-command command-1 nil error-buffer))
(with-temp-message
(format "Executing %s" command-2)
(shell-command command-2 nil error-buffer))))
;; (select-enable-primary t))
(x-select-enable-primary t))
(delete-file tmp-file)
(delete-file tmp-hfile)
;; Notify user and put the URL on the kill ring
(if (= retval 0)
(progn (kill-new full-url)
(message "Pasted to %s (on kill ring)" full-url))
(progn
(pop-to-buffer error-buffer)
(help-mode-setup)))))))
;;;###autoload
(defun scpaste-region (name)
"Paste the current region via `scpaste'.
NAME is used for the file name."
(interactive "MName: ")
(let ((region-contents (buffer-substring (mark) (point))))
(with-temp-buffer
(insert region-contents)
(scpaste name))))
;;;###autoload
(defun scpaste-index ()
"Generate an index of all existing pastes on server on the splash page."
(interactive)
(let* ((dest-parts (split-string scpaste-scp-destination ":"))
(files (shell-command-to-string (concat scpaste-ssh " " (car dest-parts)
" ls " (cadr dest-parts))))
(file-list (split-string files "\n")))
(save-excursion
(with-temp-buffer
(insert-file-contents scpaste-el-location)
(goto-char (point-min))
(search-forward ";;; Commentary")
(forward-line -1)
(insert "\n;;; Pasted Files\n\n")
(dolist (file file-list)
(when (and (string-match "\\.html$" file)
(not (string-match "private" file)))
(insert (concat ";; * <" scpaste-http-destination "/" file ">\n"))))
(emacs-lisp-mode)
(if (fboundp 'font-lock-ensure)
(font-lock-ensure)
(font-lock-fontify-buffer))
(rename-buffer "SCPaste")
(write-file (concat temporary-file-directory "scpaste-index"))
(scpaste "index")))))
(provide 'scpaste)
;;; scpaste.el ends here