jota 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/INSTALL +64 -97
- data/LICENSE +1 -1
- data/bin/jota +0 -1
- data/lib/app_error.rb +0 -2
- data/lib/clip.rb +18 -19
- data/lib/clip_array.rb +41 -36
- data/lib/gui.rb +72 -69
- data/lib/helper.rb +43 -5
- data/lib/immediate.rb +0 -3
- data/lib/jota.rb +3 -6
- data/lib/jota_curses.rb +27 -29
- data/lib/mbox_storage-tmail.rb +258 -0
- data/lib/preferences.rb +7 -9
- data/lib/test.rb +37 -0
- data/lib/version.rb +4 -8
- data/tests/test_all.rb +1 -1
- data/tests/test_clip.rb +1 -1
- data/tests/test_clip_array.rb +1 -1
- metadata +36 -56
- data/bin/jota.bat +0 -7
data/lib/helper.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
require 'objspace'
|
3
|
+
require 'time'
|
3
4
|
|
4
5
|
def escape_from(str)
|
5
6
|
str.gsub!(/\n(>*)From /,"\n\\1>From ")
|
@@ -30,7 +31,16 @@ def expand_filename(str, dirname, filename)
|
|
30
31
|
end
|
31
32
|
|
32
33
|
def expand_tabs(str)
|
33
|
-
|
34
|
+
# see http://www.rootr.net/rubyfaq-9.html, Sec. 9.17
|
35
|
+
|
36
|
+
# The pack-A version does not work, because A expects a binary/ASCII
|
37
|
+
# string, not a Unicode string
|
38
|
+
|
39
|
+
#return str.gsub(/([^\t]{8})|([^\t]*)\t/n){[$+].pack("A8")}
|
40
|
+
|
41
|
+
s = str.clone
|
42
|
+
while s.sub!(/(^[^\t]*)\t(\t*)/){$1+' '*(8-$1.size%8+8*$2.size)};end
|
43
|
+
return s
|
34
44
|
end
|
35
45
|
|
36
46
|
def debug_file
|
@@ -48,7 +58,7 @@ def debug_file
|
|
48
58
|
print_verbose "logging to '#{$debug_filename}' "+
|
49
59
|
"not possible: #{msg}, using stdout"
|
50
60
|
end
|
51
|
-
|
61
|
+
|
52
62
|
end
|
53
63
|
return $debug_file
|
54
64
|
end
|
@@ -58,7 +68,7 @@ def print_verbose(msg)
|
|
58
68
|
# do not write to $debug_file, this can be nil
|
59
69
|
debug_file.puts "#{Process.pid}-1# #{msg}"
|
60
70
|
debug_file.flush
|
61
|
-
end
|
71
|
+
end
|
62
72
|
end
|
63
73
|
|
64
74
|
def print_debug(msg)
|
@@ -66,7 +76,7 @@ def print_debug(msg)
|
|
66
76
|
# do not write to $debug_file, this can be nil
|
67
77
|
debug_file.puts "#{Process.pid}-2# #{msg}"
|
68
78
|
debug_file.flush
|
69
|
-
end
|
79
|
+
end
|
70
80
|
end
|
71
81
|
|
72
82
|
def editor(str)
|
@@ -98,3 +108,31 @@ def editor(str)
|
|
98
108
|
|
99
109
|
return lines
|
100
110
|
end
|
111
|
+
|
112
|
+
# for debugging only, normally not referenced
|
113
|
+
|
114
|
+
class Class
|
115
|
+
def <=>(x)
|
116
|
+
self.to_s <=> x.to_s
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def dump_objectspace
|
121
|
+
GC.start
|
122
|
+
sleep 60
|
123
|
+
|
124
|
+
count = Hash.new 0
|
125
|
+
ObjectSpace.each_object do |o|
|
126
|
+
count[o.class] += 1
|
127
|
+
end
|
128
|
+
|
129
|
+
File.open "objectspace-#{Time.now.iso8601}","w" do |f|
|
130
|
+
f.puts "ObjectSpace.memsize_of_all = #{ObjectSpace.memsize_of_all.to_s}"
|
131
|
+
f.puts "ps -o rss = #{`ps -o rss= -p #{Process.pid}`.to_i} kB"
|
132
|
+
f.puts
|
133
|
+
|
134
|
+
count.keys.sort.each do |k|
|
135
|
+
f.puts "#{k} #{count[k]}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
data/lib/immediate.rb
CHANGED
data/lib/jota.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
# $Id: jota.rb 296 2011-01-31 10:39:18Z dz $
|
4
|
-
|
5
|
-
|
6
3
|
require 'getoptlong'
|
7
4
|
require 'helper'
|
8
5
|
|
@@ -184,7 +181,7 @@ def start_curses
|
|
184
181
|
curses = JotaCurses.new
|
185
182
|
|
186
183
|
if @filename then
|
187
|
-
open_or_fail(curses,@filename)
|
184
|
+
open_or_fail(curses,@filename)
|
188
185
|
if @regexp then
|
189
186
|
goto_or_fail(curses,@regexp)
|
190
187
|
end
|
@@ -235,7 +232,7 @@ def start_gui
|
|
235
232
|
msgbox.secondary_text = "I'm terribly sorry."+
|
236
233
|
"\n\nDetails:\n#{e.class}: #{e.message}"
|
237
234
|
msgbox.add_button("Crash",Gtk::Dialog::RESPONSE_OK)
|
238
|
-
|
235
|
+
|
239
236
|
msgbox.run do | response |
|
240
237
|
case response
|
241
238
|
when Gtk::Dialog::RESPONSE_OK
|
@@ -285,7 +282,7 @@ def run
|
|
285
282
|
start_immediate
|
286
283
|
else
|
287
284
|
begin
|
288
|
-
# this 'require' must be after the command line is parsed,
|
285
|
+
# this 'require' must be after the command line is parsed,
|
289
286
|
# because 'require libglade2' parses the commandline too.
|
290
287
|
require 'gui'
|
291
288
|
gui_ok = true
|
data/lib/jota_curses.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
|
2
|
-
# $Id: jota_curses.rb 296 2011-01-31 10:39:18Z dz $
|
3
|
-
|
4
2
|
require "curses"
|
5
3
|
require 'tempfile'
|
6
4
|
|
@@ -40,7 +38,7 @@ def set_terminal
|
|
40
38
|
@columns = Curses.stdscr.maxx
|
41
39
|
@lines = Curses.stdscr.maxy
|
42
40
|
print_debug "setting terminal: lines=#{@lines}, columns=#{@columns}"
|
43
|
-
end
|
41
|
+
end
|
44
42
|
|
45
43
|
def initialize
|
46
44
|
@data = nil
|
@@ -58,7 +56,7 @@ def initialize
|
|
58
56
|
@editor_running = false
|
59
57
|
|
60
58
|
default_focus
|
61
|
-
end
|
59
|
+
end
|
62
60
|
|
63
61
|
def finish
|
64
62
|
Curses.close_screen
|
@@ -80,7 +78,7 @@ def open(filename)
|
|
80
78
|
@data.current_index = 0
|
81
79
|
@top_win_first = 0
|
82
80
|
return @data
|
83
|
-
end
|
81
|
+
end
|
84
82
|
|
85
83
|
def clip_array
|
86
84
|
return @data
|
@@ -101,7 +99,7 @@ def create(filename)
|
|
101
99
|
@data.current_index = 0
|
102
100
|
@top_win_first = 0
|
103
101
|
draw_bars
|
104
|
-
end
|
102
|
+
end
|
105
103
|
|
106
104
|
|
107
105
|
def delete
|
@@ -121,7 +119,7 @@ def delete
|
|
121
119
|
end
|
122
120
|
|
123
121
|
@data.delete
|
124
|
-
end
|
122
|
+
end
|
125
123
|
|
126
124
|
def run
|
127
125
|
Curses.init_screen
|
@@ -158,7 +156,7 @@ def run
|
|
158
156
|
@bot_win_lines = draw_bottom_window
|
159
157
|
handle_key
|
160
158
|
end
|
161
|
-
end
|
159
|
+
end
|
162
160
|
|
163
161
|
|
164
162
|
|
@@ -168,7 +166,7 @@ end
|
|
168
166
|
|
169
167
|
def get_bot_win_height
|
170
168
|
rows = @lines - @top_win_height - 3
|
171
|
-
|
169
|
+
|
172
170
|
# some error checking if the terminal window is made too small
|
173
171
|
if rows < 3 then
|
174
172
|
# first try to adjust the windows
|
@@ -189,7 +187,7 @@ def get_bot_win_height
|
|
189
187
|
else
|
190
188
|
return rows
|
191
189
|
end
|
192
|
-
end
|
190
|
+
end
|
193
191
|
|
194
192
|
private
|
195
193
|
|
@@ -232,7 +230,7 @@ def draw_bars
|
|
232
230
|
@bot_bar.addstr("h=help, q=quit")
|
233
231
|
end
|
234
232
|
@bot_bar.refresh
|
235
|
-
end
|
233
|
+
end
|
236
234
|
|
237
235
|
def draw_top_window
|
238
236
|
@top_win.clear
|
@@ -244,13 +242,13 @@ def draw_top_window
|
|
244
242
|
marker = " "
|
245
243
|
end
|
246
244
|
if i < @data.length then
|
247
|
-
@top_win.addstr("%s %s\n" %
|
245
|
+
@top_win.addstr("%s %s\n" %
|
248
246
|
[marker, @data[i].title![@left_margin_top..@left_margin_top+@columns-4]])
|
249
247
|
end
|
250
248
|
end
|
251
249
|
end
|
252
250
|
@top_win.refresh
|
253
|
-
end
|
251
|
+
end
|
254
252
|
|
255
253
|
def draw_bottom_window
|
256
254
|
print_debug "drawing text in #{@mode} mode"
|
@@ -285,7 +283,7 @@ def draw_bottom_window
|
|
285
283
|
@bot_win.refresh
|
286
284
|
|
287
285
|
return result
|
288
|
-
end
|
286
|
+
end
|
289
287
|
|
290
288
|
def help_text
|
291
289
|
return <<-EOT
|
@@ -313,14 +311,14 @@ Jota #{Version::STRING}, (C) #{Version::YEARS} #{Version::AUTHOR} <#{Version::AU
|
|
313
311
|
EDITOR #{ENV["EDITOR"]}
|
314
312
|
SHELL #{ENV["SHELL"]}
|
315
313
|
EOT
|
316
|
-
end
|
314
|
+
end
|
317
315
|
|
318
316
|
def redraw_all
|
319
317
|
print_debug "redrawing"
|
320
318
|
draw_bars
|
321
319
|
draw_top_window
|
322
320
|
@bot_win_lines = draw_bottom_window
|
323
|
-
end
|
321
|
+
end
|
324
322
|
|
325
323
|
def set_windows
|
326
324
|
bot_win_height = get_bot_win_height
|
@@ -352,7 +350,7 @@ def set_windows
|
|
352
350
|
@bot_bar.keypad = true
|
353
351
|
|
354
352
|
redraw_all
|
355
|
-
end
|
353
|
+
end
|
356
354
|
|
357
355
|
def app_quit
|
358
356
|
if @data then
|
@@ -365,7 +363,7 @@ def app_quit
|
|
365
363
|
finish
|
366
364
|
exit
|
367
365
|
end
|
368
|
-
end
|
366
|
+
end
|
369
367
|
|
370
368
|
def call_editor(text)
|
371
369
|
Curses.close_screen
|
@@ -387,7 +385,7 @@ def handle_key
|
|
387
385
|
@bot_bar.move(0,79)
|
388
386
|
@bot_bar.refresh
|
389
387
|
# Ruby 1.8: getch return alway a Fixnum
|
390
|
-
# Ruby 1.9: getch return a String if char is printable (between " "
|
388
|
+
# Ruby 1.9: getch return a String if char is printable (between " "
|
391
389
|
# and "~"), Fixnum otherwise
|
392
390
|
begin
|
393
391
|
ch = @bot_bar.getch
|
@@ -492,7 +490,7 @@ def handle_key
|
|
492
490
|
if command == "" then
|
493
491
|
command = ENV["SHELL"]
|
494
492
|
end
|
495
|
-
|
493
|
+
|
496
494
|
Curses.stdscr.clear
|
497
495
|
Curses.close_screen
|
498
496
|
puts "\nJota executing '#{command}'"
|
@@ -561,7 +559,7 @@ def handle_key
|
|
561
559
|
|
562
560
|
adjust_top_win_first
|
563
561
|
adjust_bot_win_first
|
564
|
-
end
|
562
|
+
end
|
565
563
|
|
566
564
|
def adjust_top_win_first
|
567
565
|
return if not @data
|
@@ -570,7 +568,7 @@ def adjust_top_win_first
|
|
570
568
|
elsif @data.current_index > @top_win_first+@top_win_height-1 then
|
571
569
|
@top_win_first = @data.current_index-@top_win_height+1
|
572
570
|
end
|
573
|
-
end
|
571
|
+
end
|
574
572
|
|
575
573
|
def adjust_bot_win_first
|
576
574
|
return if not @data
|
@@ -579,13 +577,13 @@ def adjust_bot_win_first
|
|
579
577
|
elsif @bot_win_lines and @bot_win_first > @bot_win_lines-1 then
|
580
578
|
@bot_win_first = @bot_win_lines-1
|
581
579
|
end
|
582
|
-
end
|
580
|
+
end
|
583
581
|
|
584
582
|
def message(str)
|
585
583
|
@bot_bar.clear
|
586
584
|
@bot_bar.addstr(str)
|
587
585
|
@bot_bar.refresh
|
588
|
-
end
|
586
|
+
end
|
589
587
|
|
590
588
|
def prompt(str,type=:string)
|
591
589
|
@bot_bar.clear
|
@@ -608,7 +606,7 @@ def prompt(str,type=:string)
|
|
608
606
|
Curses.noecho
|
609
607
|
draw_bars
|
610
608
|
return result
|
611
|
-
end
|
609
|
+
end
|
612
610
|
|
613
611
|
def prompt_filename(str)
|
614
612
|
loop do
|
@@ -618,7 +616,7 @@ def prompt_filename(str)
|
|
618
616
|
@bot_win.addstr File.expand_path(".")
|
619
617
|
@bot_win.addstr(":\n")
|
620
618
|
ent = (Dir.entries ".").sort
|
621
|
-
ent.each do | f |
|
619
|
+
ent.each do | f |
|
622
620
|
next if f =~ /^\./
|
623
621
|
@bot_win.addstr(f)
|
624
622
|
if File.directory? f then
|
@@ -631,14 +629,14 @@ def prompt_filename(str)
|
|
631
629
|
return filename
|
632
630
|
end
|
633
631
|
end
|
634
|
-
end
|
632
|
+
end
|
635
633
|
|
636
634
|
def error(msg)
|
637
635
|
@bot_bar.clear
|
638
636
|
@bot_bar.addstr("ERROR: ")
|
639
637
|
@bot_bar.addstr(msg.to_s)
|
640
638
|
@bot_bar.refresh
|
641
|
-
end
|
639
|
+
end
|
642
640
|
|
643
641
|
def really?(prefstr,promptstr)
|
644
642
|
if @data.nil? then
|
@@ -656,6 +654,6 @@ def really?(prefstr,promptstr)
|
|
656
654
|
else
|
657
655
|
return false
|
658
656
|
end
|
659
|
-
end
|
657
|
+
end
|
660
658
|
|
661
659
|
end # class
|
@@ -0,0 +1,258 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
# from page.rb
|
4
|
+
|
5
|
+
# def Page.from_mbox(str)
|
6
|
+
# # "From_" line already removed
|
7
|
+
# cl = Page.new
|
8
|
+
# in_header = true
|
9
|
+
# charset = "UTF-8"
|
10
|
+
# str.each_line do | line |
|
11
|
+
# line.encode!(charset)
|
12
|
+
# if in_header then
|
13
|
+
# if line == "\n" then
|
14
|
+
# in_header = false
|
15
|
+
# next
|
16
|
+
# end
|
17
|
+
# #(key, value) = line.split(/\s*:\s*/,2)
|
18
|
+
# # stricter pattern to preserve leading spaces
|
19
|
+
# (key, value) = line.split(/\s*: /,2)
|
20
|
+
# value.chomp!
|
21
|
+
# case key.downcase
|
22
|
+
# when "flags", "x-flags"
|
23
|
+
# cl.wrap = value.downcase.include?("w")
|
24
|
+
# when "subject"
|
25
|
+
# cl.title = value
|
26
|
+
# when "created-at", "date"
|
27
|
+
# cl.created = Time.parse(value)
|
28
|
+
# when "content-type"
|
29
|
+
# case value
|
30
|
+
# when "text/plain"
|
31
|
+
# cl.type = :text
|
32
|
+
# when "application/x-jota-pref"
|
33
|
+
# cl.type = :pref
|
34
|
+
# else
|
35
|
+
# cl.type = :text # safe fallback type
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
# else
|
39
|
+
# cl.data << line
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
# return cl
|
43
|
+
# end
|
44
|
+
|
45
|
+
# def to_mbox
|
46
|
+
# str = ""
|
47
|
+
# charset = "UTF-8"
|
48
|
+
|
49
|
+
# str << "Created-At: %s\n" % @created.ctime
|
50
|
+
|
51
|
+
# str << "Subject: %s\n" % @title
|
52
|
+
|
53
|
+
# case @type
|
54
|
+
# when :text
|
55
|
+
# str << "Content-Type: text/plain; charset=#{charset}\n"
|
56
|
+
# when :pref
|
57
|
+
# str << "Content-Type: application/x-jota-pref\n"
|
58
|
+
# end
|
59
|
+
|
60
|
+
# str << "Flags: "
|
61
|
+
# str << "w" if @wrap
|
62
|
+
# str << "\n"
|
63
|
+
|
64
|
+
# if type == :pref then
|
65
|
+
# str << "Originating-Client: %s %s\n" %
|
66
|
+
# [Jota::Version::PROGRAM_NAME, Jota::Version::STRING]
|
67
|
+
# end
|
68
|
+
|
69
|
+
# str << "\n"
|
70
|
+
|
71
|
+
# str << @data
|
72
|
+
|
73
|
+
# return str
|
74
|
+
# end
|
75
|
+
|
76
|
+
|
77
|
+
# from book.rb
|
78
|
+
|
79
|
+
# def Book.read_mbox(file)
|
80
|
+
# ca = self.new
|
81
|
+
# first_line = true
|
82
|
+
# str = ""
|
83
|
+
# i = 1
|
84
|
+
|
85
|
+
# Log.debug "reading pages, mbox format"
|
86
|
+
|
87
|
+
# if file.eof? or file.readline =~ /^From / then
|
88
|
+
# # valid
|
89
|
+
# else
|
90
|
+
# raise Jota::AppError, "Not an Mbox file"
|
91
|
+
# end
|
92
|
+
|
93
|
+
# file.each_line do | line |
|
94
|
+
# line.chomp!
|
95
|
+
# if line =~ /^From / then
|
96
|
+
# if not first_line then
|
97
|
+
# page = Jota::Page.from_mbox(unescape_from(str))
|
98
|
+
# if page.type == :pref then
|
99
|
+
# ca.pref = Jota::Preferences.read(page.data)
|
100
|
+
# Log.debug " #{i}: Preferences"
|
101
|
+
# else
|
102
|
+
# ca << page
|
103
|
+
# Log.debug " #{i}: '#{page.title}'"
|
104
|
+
# end
|
105
|
+
# i += 1
|
106
|
+
# end
|
107
|
+
# str = ""
|
108
|
+
# else
|
109
|
+
# str << line << "\n"
|
110
|
+
# end
|
111
|
+
# first_line = false
|
112
|
+
# end
|
113
|
+
|
114
|
+
# if str != "" then
|
115
|
+
# page = Jota::Page.from_mbox(unescape_from(str))
|
116
|
+
# if page.type == :pref then
|
117
|
+
# ca.pref = Jota::Preferences.read(page.data)
|
118
|
+
# Log.debug " #{i}: Preferences"
|
119
|
+
# else
|
120
|
+
# ca << page
|
121
|
+
# Log.debug " #{i}: '#{page.title}'"
|
122
|
+
# end
|
123
|
+
# end
|
124
|
+
|
125
|
+
# ca.current_index = ca.length - 1
|
126
|
+
# return ca
|
127
|
+
# end
|
128
|
+
|
129
|
+
# def write_mbox(file)
|
130
|
+
# Log.debug "writing pages, mbox format"
|
131
|
+
# i = 1
|
132
|
+
|
133
|
+
# # Pref page first
|
134
|
+
# pc = Jota::Page.new
|
135
|
+
# pc.type = :pref
|
136
|
+
# pc.title = "Preferences"
|
137
|
+
# pc.data = @pref.write
|
138
|
+
|
139
|
+
# ([pc]+self).each do | page |
|
140
|
+
# file.print "From %s@localhost %s\n" %
|
141
|
+
# [Jota::Version::PROGRAM_NAMELC, Time.now.ctime]
|
142
|
+
# file.print(escape_from(page.to_mbox.chomp))
|
143
|
+
# file.print("\n")
|
144
|
+
# Log.debug " #{i}: '#{page.title}'"
|
145
|
+
# i += 1
|
146
|
+
# end
|
147
|
+
# end
|
148
|
+
|
149
|
+
require 'log'
|
150
|
+
require 'tmail' # gem install tmail, needs ruby > 1.9.1; does not work with
|
151
|
+
# ruby-2.1.1 "has a non escaped non ASCII character in non
|
152
|
+
# ASCII-8BIT script (RegexpError)"
|
153
|
+
|
154
|
+
# ... since everybody should now use the new gem "mail".
|
155
|
+
# https://rubygems.org/gems/mail
|
156
|
+
|
157
|
+
#http://www.rubydoc.info/gems/mbox
|
158
|
+
|
159
|
+
mb =Mbox.open "mbox.jota"
|
160
|
+
mb.each do |x|
|
161
|
+
x.to_s
|
162
|
+
end
|
163
|
+
|
164
|
+
require 'yaml'
|
165
|
+
|
166
|
+
|
167
|
+
module Jota
|
168
|
+
|
169
|
+
class Storage; end
|
170
|
+
|
171
|
+
class MboxStorage < Storage
|
172
|
+
|
173
|
+
attr_reader :book, :filename, :is_rw
|
174
|
+
|
175
|
+
def initialize book, filename=nil
|
176
|
+
@book = book
|
177
|
+
@filename = File.expand_path filename
|
178
|
+
@is_rw = true
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.load filename, mode = :rw
|
182
|
+
Log.info "loading Mbox file '#{filename}' with mode '#{mode}'"
|
183
|
+
array = []
|
184
|
+
pref = nil
|
185
|
+
TMail::UNIXMbox.new(filename,nil,true).each_port do |port|
|
186
|
+
mail = TMail::Mail.new(port)
|
187
|
+
Log.debug "MboxStorage.load: '#{mail.inspect}'"
|
188
|
+
type = parse_type(mail.content_type)
|
189
|
+
data = mail.body
|
190
|
+
hash = {
|
191
|
+
"created" => Date.parse(mail["created-at"]),
|
192
|
+
"data" => data,
|
193
|
+
"title" => mail.subject,
|
194
|
+
"type" => type,
|
195
|
+
"wrap" => mail["flags"].downcase.include?("w"),
|
196
|
+
}
|
197
|
+
if type == :pref then
|
198
|
+
pref = YAML.load data
|
199
|
+
else
|
200
|
+
page = Page.from_hash hash
|
201
|
+
array << page
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
storage = self.new (Book.from_array(array, pref)), filename
|
206
|
+
return storage
|
207
|
+
end
|
208
|
+
|
209
|
+
def save_as filename
|
210
|
+
return if ! @book
|
211
|
+
Log.info "saving Mbox file '#{filename}'"
|
212
|
+
# mailbox = UNIXMbox.new(filename,nil,true)
|
213
|
+
array = @book.map{|page|page.to_hash}
|
214
|
+
|
215
|
+
File.open(@filename, "w") do |file|
|
216
|
+
# preferences
|
217
|
+
mail = TMail::Mail.new
|
218
|
+
mail["created-at"] = Time.now.to_s
|
219
|
+
mail["flags"] = ""
|
220
|
+
mail.subject = "Preferences"
|
221
|
+
mail.body = YAML.dump @book.pref
|
222
|
+
mail.set_content_type "application", "x-jota-pref"
|
223
|
+
Log.debug "MboxStorage.save_as: pref '#{mail.inspect}'"
|
224
|
+
file.print mail.encoded
|
225
|
+
|
226
|
+
# pages
|
227
|
+
array.each do |hash|
|
228
|
+
mail = TMail::Mail.new
|
229
|
+
mail["created-at"] = hash["created"].to_s
|
230
|
+
mail["flags"] = hash["wrap"]? "w" : "" # the only flag for now
|
231
|
+
mail.subject = hash["title"]
|
232
|
+
mail.body = hash["data"]
|
233
|
+
mail.set_content_type "text", "plain" # all non-:pref pages are :text for now
|
234
|
+
Log.debug "MboxStorage.save_as: page '#{mail.inspect}'"
|
235
|
+
file.print mail.encoded
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def save
|
241
|
+
save_as @filename if @filename
|
242
|
+
end
|
243
|
+
|
244
|
+
private
|
245
|
+
|
246
|
+
def parse_type content_type
|
247
|
+
case content_type
|
248
|
+
when "text/plain"
|
249
|
+
return :text
|
250
|
+
when "application/x-jota-pref"
|
251
|
+
return :pref
|
252
|
+
else
|
253
|
+
return :text
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
end # class
|
258
|
+
end # module
|