~ubuntu-branches/ubuntu/saucy/wl/saucy-proposed

« back to all changes in this revision

Viewing changes to elmo/elmo-file.el

  • Committer: Bazaar Package Importer
  • Author(s): Tatsuya Kinoshita
  • Date: 2007-01-02 21:08:54 UTC
  • mfrom: (3.1.3 edgy)
  • Revision ID: james.westby@ubuntu.com-20070102210854-nw929130dlxgi6q3
Tags: 2.14.0-4
elmo/elmo-imap4.el: Fix "IMAP error: No `OK' response from server",
patch from upstream CVS version. (closes: #405284)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
;;; elmo-file.el --- File interface for ELMO.
 
2
 
 
3
;; Copyright (C) 2000 Yuuichi Teranishi <teranisi@gohome.org>
 
4
 
 
5
;; Author: Yuuichi Teranishi <teranisi@gohome.org>
 
6
;; Keywords: mail, net news
 
7
 
 
8
;; This file is part of ELMO (Elisp Library for Message Orchestration).
 
9
 
 
10
;; This program is free software; you can redistribute it and/or modify
 
11
;; it under the terms of the GNU General Public License as published by
 
12
;; the Free Software Foundation; either version 2, or (at your option)
 
13
;; any later version.
 
14
;;
 
15
;; This program is distributed in the hope that it will be useful,
 
16
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
;; GNU General Public License for more details.
 
19
;;
 
20
;; You should have received a copy of the GNU General Public License
 
21
;; along with GNU Emacs; see the file COPYING.  If not, write to the
 
22
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
23
;; Boston, MA 02111-1307, USA.
 
24
;;
 
25
 
 
26
;;; Commentary:
 
27
;;
 
28
 
 
29
;;; Code:
 
30
;;
 
31
(eval-when-compile (require 'cl))
 
32
 
 
33
(require 'elmo)
 
34
(require 'elmo-map)
 
35
(require 'mime-edit)
 
36
 
 
37
(defun elmo-file-find (files)
 
38
  "Return the first existing filename in the FILES."
 
39
  (let (file)
 
40
    (while files
 
41
      (when (file-exists-p (car files))
 
42
        (setq file (car files)
 
43
              files nil))
 
44
      (setq files (cdr files)))
 
45
    (and file (expand-file-name file))))
 
46
 
 
47
(defcustom elmo-file-command (exec-installed-p "file")
 
48
  "*Program name of the file type detection command `file'."
 
49
  :type '(string :tag "Program name of the file")
 
50
  :group 'elmo)
 
51
 
 
52
(defcustom elmo-file-command-argument
 
53
  (let ((magic-file (elmo-file-find
 
54
                     '("/usr/share/magic.mime"
 
55
                       "/usr/share/file/magic.mime"
 
56
                       "/cygwin/usr/share/file/magic.mime"))))
 
57
    (if magic-file (list "-m" magic-file)))
 
58
  "*Argument list for the `file' command.
 
59
\(It should return the MIME content type\)"
 
60
  :type '(repeat string)
 
61
  :group 'elmo)
 
62
 
 
63
(defcustom elmo-file-fetch-max-size (* 1024 1024)
 
64
  "*Max size of the message fetching."
 
65
  :type 'integer
 
66
  :group 'elmo)
 
67
 
 
68
(eval-and-compile
 
69
  (luna-define-class elmo-file-folder (elmo-map-folder) (file-path))
 
70
  (luna-define-internal-accessors 'elmo-file-folder))
 
71
 
 
72
(luna-define-method elmo-folder-initialize ((folder
 
73
                                             elmo-file-folder)
 
74
                                            name)
 
75
  (elmo-file-folder-set-file-path-internal folder name)
 
76
  folder)
 
77
 
 
78
(luna-define-method elmo-folder-expand-msgdb-path ((folder
 
79
                                                    elmo-file-folder))
 
80
  (expand-file-name
 
81
   (elmo-replace-string-as-filename (elmo-folder-name-internal folder))
 
82
   (expand-file-name "file" elmo-msgdb-directory)))
 
83
 
 
84
(defun elmo-file-make-date-string (attrs)
 
85
  (let ((s (current-time-string (nth 5 attrs))))
 
86
    (string-match "\\`\\([A-Z][a-z][a-z]\\) +[A-Z][a-z][a-z] +[0-9][0-9]? *[0-9][0-9]?:[0-9][0-9]:[0-9][0-9] *[0-9]?[0-9]?[0-9][0-9]"
 
87
                  s)
 
88
    (concat (elmo-match-string 1 s) ", "
 
89
            (timezone-make-date-arpa-standard s (current-time-zone)))))
 
90
 
 
91
(defun elmo-file-detect-content-type (file)
 
92
  "Return content-type of the FILE."
 
93
  (if (or (not (file-exists-p file))
 
94
          (file-directory-p file))
 
95
      "application/octet-stream"
 
96
    (let (type)
 
97
      (setq type (mime-find-file-type file))
 
98
      (if (and (string= (nth 0 type) "application")
 
99
               (string= (nth 1 type) "octet-stream"))
 
100
          (if (and elmo-file-command
 
101
                   elmo-file-command-argument)
 
102
              (with-temp-buffer
 
103
                (if (zerop (apply 'call-process elmo-file-command
 
104
                                  nil `(,(current-buffer) nil)
 
105
                                  nil (append elmo-file-command-argument
 
106
                                              (list (expand-file-name file)))))
 
107
                    (progn
 
108
                      (goto-char (point-min))
 
109
                      (when (re-search-forward ": *" nil t)
 
110
                        (setq type (buffer-substring (match-end 0)
 
111
                                                     (point-at-eol))))
 
112
                      (cond
 
113
                       ((string= "empty" type)
 
114
                        "application/octet-stream")
 
115
                       ((string-match "text" type)
 
116
                        "text/plain")
 
117
                       (t
 
118
                        (car (split-string type)))))
 
119
                  "application/octet-stream"))
 
120
            (concat (nth 0 type) "/" (nth 1 type)))
 
121
        (concat (nth 0 type) "/" (nth 1 type))))))
 
122
 
 
123
(defun elmo-file-msgdb-create-entity (msgdb folder number)
 
124
  "Create msgdb entity for the message in the FOLDER with NUMBER."
 
125
  (let* ((file (elmo-message-file-name folder number))
 
126
         (attrs (file-attributes file)))
 
127
    (and (not (file-directory-p file))
 
128
         attrs
 
129
         (elmo-msgdb-make-message-entity
 
130
          (elmo-msgdb-message-entity-handler msgdb)
 
131
          :message-id (concat "<" (elmo-replace-in-string
 
132
                                   file "/" ":")
 
133
                              "@" (system-name))
 
134
          :number number
 
135
          :size (nth 7 attrs)
 
136
          :date (elmo-file-make-date-string attrs)
 
137
          :subject (file-name-nondirectory file)
 
138
          :from (concat (user-full-name (nth 2 attrs))
 
139
                        " <" (user-login-name (nth 2 attrs)) "@"
 
140
                        (system-name) ">")))))
 
141
 
 
142
(luna-define-method elmo-folder-msgdb-create ((folder elmo-file-folder)
 
143
                                              numlist flag-table)
 
144
  (let ((new-msgdb (elmo-make-msgdb))
 
145
        entity mark i percent num)
 
146
    (setq num (length numlist))
 
147
    (setq i 0)
 
148
    (message "Creating msgdb...")
 
149
    (while numlist
 
150
      (setq entity
 
151
            (elmo-file-msgdb-create-entity new-msgdb folder (car numlist)))
 
152
      (when entity
 
153
        (elmo-msgdb-append-entity new-msgdb entity '(new unread)))
 
154
      (when (> num elmo-display-progress-threshold)
 
155
        (setq i (1+ i))
 
156
        (setq percent (/ (* i 100) num))
 
157
        (elmo-display-progress
 
158
         'elmo-folder-msgdb-create "Creating msgdb..."
 
159
         percent))
 
160
      (setq numlist (cdr numlist)))
 
161
    (message "Creating msgdb...done")
 
162
    new-msgdb))
 
163
 
 
164
(luna-define-method elmo-folder-message-file-p ((folder elmo-file-folder))
 
165
  t)
 
166
 
 
167
(luna-define-method elmo-message-file-name ((folder elmo-file-folder)
 
168
                                            number)
 
169
  (expand-file-name (car (split-string
 
170
                          (elmo-map-message-location folder number)
 
171
                          "/"))
 
172
                    (elmo-file-folder-file-path-internal folder)))
 
173
 
 
174
(luna-define-method elmo-folder-message-make-temp-file-p
 
175
  ((folder elmo-file-folder))
 
176
  t)
 
177
 
 
178
(luna-define-method elmo-folder-diff ((folder elmo-file-folder))
 
179
  (cons nil nil))
 
180
 
 
181
(luna-define-method elmo-folder-message-make-temp-files ((folder
 
182
                                                          elmo-file-folder)
 
183
                                                         numbers
 
184
                                                         &optional
 
185
                                                         start-number)
 
186
  (let ((temp-dir (elmo-folder-make-temporary-directory folder))
 
187
        (cur-number (if start-number 0)))
 
188
    (dolist (number numbers)
 
189
      (elmo-copy-file
 
190
       (elmo-message-file-name folder number)
 
191
       (expand-file-name
 
192
        (int-to-string (if start-number (incf cur-number) number))
 
193
        temp-dir)))
 
194
    temp-dir))
 
195
 
 
196
(luna-define-method elmo-map-message-fetch ((folder elmo-file-folder)
 
197
                                            location strategy
 
198
                                            &optional section unseen)
 
199
  (let ((file (expand-file-name (car (split-string location "/"))
 
200
                                (elmo-file-folder-file-path-internal folder)))
 
201
        charset guess uid is-text)
 
202
    (when (file-exists-p file)
 
203
      (set-buffer-multibyte nil)
 
204
      (prog1
 
205
          (insert-file-contents-as-binary file nil 0 elmo-file-fetch-max-size)
 
206
        (unless (or (std11-field-body "To")
 
207
                    (std11-field-body "Cc")
 
208
                    (std11-field-body "Subject"))
 
209
          (setq guess (elmo-file-detect-content-type file))
 
210
          (setq is-text (string-match "^text/" guess))
 
211
          (when is-text
 
212
            (set-buffer-multibyte t)
 
213
            (decode-coding-region
 
214
             (point-min) (point-max)
 
215
             elmo-mime-display-as-is-coding-system)
 
216
            (setq charset (detect-mime-charset-region (point-min)
 
217
                                                      (point-max))))
 
218
          (goto-char (point-min))
 
219
          (setq uid (nth 2 (file-attributes file)))
 
220
          (insert "From: " (concat (user-full-name uid)
 
221
                                   " <"(user-login-name uid) "@"
 
222
                                   (system-name) ">") "\n")
 
223
          (insert "Subject: " (file-name-nondirectory file) "\n")
 
224
          (insert "Date: "
 
225
                  (elmo-file-make-date-string (file-attributes file))
 
226
                  "\n")
 
227
          (insert "Message-ID: "
 
228
                  (concat "<" (elmo-replace-in-string file "/" ":")
 
229
                          "@" (system-name) ">\n"))
 
230
          (insert "Content-Type: "
 
231
                  guess
 
232
                  (or (and is-text
 
233
                           (concat
 
234
                            "; charset=" (upcase (symbol-name charset))))
 
235
                      "")
 
236
                  "\nMIME-Version: 1.0\n\n")
 
237
          (when is-text
 
238
            (encode-mime-charset-region (point-min) (point-max) charset))
 
239
          (set-buffer-multibyte nil))))))
 
240
 
 
241
(luna-define-method elmo-map-folder-list-message-locations
 
242
  ((folder elmo-file-folder))
 
243
  (delq nil
 
244
        (mapcar
 
245
         (lambda (file)
 
246
           (when (not (file-directory-p file))
 
247
             (concat
 
248
              file "/"
 
249
              (mapconcat
 
250
               'number-to-string
 
251
               (nth 5 (file-attributes (expand-file-name
 
252
                                        file
 
253
                                        (elmo-file-folder-file-path-internal
 
254
                                         folder))))
 
255
               ":"))))
 
256
         (directory-files (elmo-file-folder-file-path-internal folder)))))
 
257
 
 
258
(luna-define-method elmo-folder-exists-p ((folder elmo-file-folder))
 
259
  (file-directory-p (elmo-file-folder-file-path-internal folder)))
 
260
 
 
261
(luna-define-method elmo-folder-list-subfolders ((folder elmo-file-folder)
 
262
                                                 &optional one-level)
 
263
  (when (file-directory-p (elmo-file-folder-file-path-internal folder))
 
264
    (append
 
265
     (list (elmo-folder-name-internal folder))
 
266
     (delq nil
 
267
           (mapcar
 
268
            (lambda (file)
 
269
              (when (and (file-directory-p
 
270
                          (expand-file-name
 
271
                           file
 
272
                           (elmo-file-folder-file-path-internal folder)))
 
273
                         (not (string= file "."))
 
274
                         (not (string= file "..")))
 
275
                (concat (elmo-folder-name-internal folder) "/" file)))
 
276
            (directory-files (elmo-file-folder-file-path-internal
 
277
                              folder)))))))
 
278
 
 
279
(require 'product)
 
280
(product-provide (provide 'elmo-file) (require 'elmo-version))
 
281
 
 
282
;;; elmo-file.el ends here