+ (setq iplayer-current-channel channel)
+ (display-iplayer-tree (get-iplayer-tree "--channel" (format "^%s$" channel))))
+
+(define-iplayer-command iplayer-refresh (&optional keys)
+ "Refresh the current iPlayer channel display."
+ (interactive)
+ (if iplayer-current-channel
+ (iplayer-channel iplayer-current-channel)
+ (iplayer-show-all)))
+
+(defun iplayer-download-display-state (process)
+ (let ((id (process-get process 'iplayer-id))
+ (state (process-get process 'iplayer-state))
+ (progress (process-get process 'iplayer-progress)))
+ (with-current-buffer (get-buffer-create "*iplayer-progress*")
+ (goto-char (point-min))
+ (let ((found (re-search-forward (format "^%s:" id) nil 'end)))
+ (unless found
+ (unless (= (point) (progn (forward-line 0) (point)))
+ (goto-char (point-max))
+ (newline)))
+ (forward-line 0)
+ (let ((beg (point)))
+ (end-of-line)
+ (delete-region beg (point)))
+ (insert (format "%s: %s %s%%" id state progress))))))
+
+(defun iplayer-download-process-filter (process string)
+ (catch 'no-progress
+ (cond
+ ((string-match "^Starting download" string)
+ (process-put process 'iplayer-state 'downloading)
+ (process-put process 'iplayer-progress 0.0))
+ ((and (eql (process-get process 'iplayer-state) 'downloading)
+ (string-match "(\\([0-9]\\{1,3\\}.[0-9]\\)%)$" string))
+ (process-put process 'iplayer-progress (string-to-number (match-string 1 string))))
+ ((string-match "Started writing to temp file" string)
+ (process-put process 'iplayer-state 'transcoding)
+ (process-put process 'iplayer-progress 0.0))
+ ((string-match " Progress: =*>?\\([0-9]\\{1,3\\}\\)%-*|" string)
+ (let ((idx (match-beginning 0)) (data (match-data)))
+ (while (string-match " Progress: =*>?\\([0-9]\\{1,3\\}\\)%-*|" string (match-end 0))
+ (setq idx (match-beginning 0))
+ (setq data (match-data)))
+ (set-match-data data)
+ (process-put process 'iplayer-progress (string-to-number (match-string 1 string)))))
+ (t (with-current-buffer (process-buffer process)
+ (insert string))
+ (throw 'no-progress nil)))
+ (iplayer-download-display-state process)))
+
+(defun iplayer-download-process-sentinel (process string)
+ (cond
+ ((string-match "^finished" string)
+ ;; KLUDGE: get-iplayer installs signal handlers and exit with a 0
+ ;; exit code from them. That means we can't use the sentinel to
+ ;; distinguish between being killed and exiting with success, so
+ ;; we hack around the problem.
+ (if (= (process-get process 'iplayer-progress) 100)
+ (process-put process 'iplayer-state 'finished)
+ (process-put process 'iplayer-state 'failed)))
+ ((string-match "^exited abnormally" string)
+ (process-put process 'iplayer-state 'failed)))
+ (iplayer-download-display-state process))