jota 0.8.0

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.
data/INSTALL ADDED
@@ -0,0 +1,145 @@
1
+
2
+ $Id: INSTALL 37 2009-02-09 10:06:02Z dz $
3
+
4
+ Jota is a written in the Ruby programming language and uses GTK+ Widgets.
5
+
6
+ To set up a working run time environment to have to install the
7
+ following packages:
8
+
9
+ - Ruby interpreter often already installed
10
+ - GTK+ libraries comes with Gnome, you probably have it already
11
+ - libglade a library for loadable user interfaces
12
+ part of the GTK+ project
13
+ - Ruby bindings for GTK+ and libglade
14
+ - Ruby Gems the Ruby packet manager
15
+
16
+ If you want to use the command line version of Jota, you will need the
17
+ 'Cmd' gem: gem install cmd
18
+
19
+
20
+ PREREQUISITES
21
+ -------------
22
+
23
+ For the common operating systems you can use the following command:
24
+
25
+ * Ubuntu/Debian
26
+
27
+ % apt-get install libglade2-ruby1.8 rubygems
28
+
29
+
30
+ * FreeBSD
31
+
32
+ % portinstall ruby18-libglade2 ruby18-gems
33
+
34
+ or
35
+
36
+ % cd /usr/ports/devel/ruby-libglade2
37
+ % make
38
+ % make install
39
+
40
+
41
+ * Fedora (unfinished)
42
+
43
+ % yum install ...
44
+
45
+
46
+ * OpenSUSE
47
+
48
+ Does not work for 11.0, probably 10.0 and maybe 11.1. Sorry!
49
+
50
+ At first, install the packages ruby and rubygems from the standard SUSE
51
+ repositories. Because the other GTK+ related packages that you will
52
+ need are not in these repositories, you have to fetch and install the
53
+ RPMs manually. Read
54
+ http://ruby-gnome2.sourceforge.jp/hiki.cgi?Install+Guide+for+SUSE
55
+ and fetch the tgz, e.g.
56
+
57
+ % wget http://franz.hob-bruneck.info/downloads/suse100/ruby-gnome2/0.14.1/\
58
+ ruby-gnome2-0.14.1.suse100.tar.gz
59
+
60
+ Create a temporary directory somewhere
61
+
62
+ % mkdir opensuse.tmp
63
+ % cd opensuse.tmp
64
+
65
+ Unpack and install the necessary RPMs
66
+
67
+ % tar xvfz ../ruby-gnome2*.tar.gz
68
+ % rpm -i ruby-glib2*
69
+ % rpm -i ruby-atk*
70
+ % rpm -i ruby-pango*
71
+ % rpm -i --nodeps ruby-gdkpixbuf2*
72
+ % rpm -i ruby-gtk2*
73
+ % rpm -i ruby-libglade2*
74
+
75
+
76
+
77
+ * Windows
78
+
79
+ Windows of course has no sophisticated package management. You have to
80
+ download and install the following by hand.
81
+
82
+ Go to http://ruby-gnome2.sourceforge.jp/#Ruby-GNOME2+Win32+GUI+Installer
83
+ and follow the three steps. In short:
84
+
85
+ 1. install http://rubyforge.org/frs/download.php/17357/ruby185-22.exe
86
+ (enable RubyGems)
87
+ 2. install http://prdownloads.sourceforge.net/ruby-gnome2/ruby-gnome2-0.16.0-1-i386-mswin32.exe?download
88
+
89
+
90
+ INSTALLING
91
+ ----------
92
+
93
+ Now install Jota as a ruby gem:
94
+
95
+ gem install jota
96
+
97
+ alternatively, download jota-$VERSION.gem and install it with
98
+
99
+ gem install jota-$VERSION.gem
100
+
101
+ If you get the error "ERROR: While executing gem ... (RuntimeError)" and
102
+ "jota requires cmd >= 0.7.2", you have an older version of gems that does not
103
+ resolve dependencies on its own.
104
+
105
+ So you have to
106
+
107
+ gem install cmd
108
+
109
+ before
110
+
111
+ gem install jota
112
+
113
+ (Only if you want to use joacli)
114
+
115
+
116
+
117
+ RUNNING
118
+ -------
119
+
120
+ Unix:
121
+
122
+ Normally, binaries installed through gems should be in the path, so you
123
+ can simply invoke Jota with the command jota
124
+
125
+ If the binary is not in the path, you have to find out the full pathname.
126
+ This is gems dependant. For Ubuntu Linux, the full name is
127
+ /var/lib/gems/1.8/bin/jota
128
+
129
+ Windows:
130
+
131
+ You can run Jota through: Start->Execute: "Jota" or create a shortcut and
132
+ point it to C:\Ruby\bin\jota.cmd
133
+
134
+
135
+ UPDATING
136
+ --------
137
+
138
+ gem update jota
139
+
140
+ or
141
+
142
+ gem uninstall jota
143
+ gem install jota
144
+ gem cleanup jota
145
+
data/bin/jota ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # $Id: jota 28 2009-01-22 09:20:48Z dz $
4
+
5
+ begin
6
+ require 'jota'
7
+ rescue LoadError
8
+ require 'rubygems'
9
+ require 'jota'
10
+ end
11
+
12
+ Jota.new.run_gui
data/bin/jotacli ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # $Id: jotacli 28 2009-01-22 09:20:48Z dz $
4
+
5
+ begin
6
+ require 'jota'
7
+ rescue LoadError
8
+ require 'rubygems'
9
+ require 'jota'
10
+ end
11
+
12
+ Jota.new.run_cli
data/lib/app_error.rb ADDED
@@ -0,0 +1,5 @@
1
+
2
+ # $Id: app_error.rb 28 2009-01-22 09:20:48Z dz $
3
+
4
+ class AppError < StandardError
5
+ end
data/lib/cli.rb ADDED
@@ -0,0 +1,277 @@
1
+
2
+ # $Id: cli.rb 37 2009-02-09 10:06:02Z dz $
3
+
4
+ # if you use vim and don't like folds type zR
5
+
6
+ require 'clip'
7
+ require 'clip_array'
8
+ require 'preferences'
9
+
10
+ begin
11
+ require 'cmd'
12
+ rescue LoadError
13
+ require 'rubygems'
14
+ require 'cmd'
15
+ end
16
+
17
+ class JotaCli < Cmd
18
+
19
+ require 'tempfile'
20
+ prompt_with :prompt_command
21
+
22
+ doc :open, "Open clip file"
23
+ doc :close, "Close clip file"
24
+ doc :create, "Create a new empty clip file"
25
+ doc :list, "List clips with type, index number and title"
26
+ doc :edit, "Edit clip with $EDITOR (or /usr/bin/vi if not set)"
27
+ doc :show, "Show contents of clip"
28
+ doc :new, "Create a new clip"
29
+ doc :delete, "Delete a clip"
30
+ doc :default, "Set default command"
31
+ doc :page, "Show content of clip through $PAGER"
32
+
33
+
34
+ def do_open(args)
35
+ #{{{1
36
+ filename = args.to_s
37
+ @data.close if @data
38
+ begin
39
+ @data = ClipArray.open(filename)
40
+ rescue SystemCallError, AppError => msg
41
+ puts msg
42
+ @data = nil
43
+ end
44
+ end #}}}1
45
+
46
+ def do_close
47
+ #{{{1
48
+ return if @data.nil?
49
+
50
+ @data.close
51
+ @data = nil
52
+ end #}}}1
53
+
54
+ def do_create(args)
55
+ #{{{1
56
+ filename = args.to_s
57
+ @data.close if @data
58
+ begin
59
+ @data = ClipArray.create(filename)
60
+ rescue AppError => msg
61
+ puts msg
62
+ @data = nil
63
+ end
64
+ end #}}}1
65
+
66
+ def do_list
67
+ #{{{1
68
+ return if @data.nil?
69
+
70
+ @data.each_index do | i |
71
+ print "%2d %s %s\n" % [
72
+ i+1,
73
+ type_to_char(@data[i].type),
74
+ @data[i].title]
75
+ end
76
+ end #}}}1
77
+
78
+ def do_edit(args)
79
+ #{{{1
80
+ index = get_index(args)
81
+ return if index.nil?
82
+
83
+ file = Tempfile.new("jotacli")
84
+ filename = file.path
85
+ print_verbose "creating temporary file '#{filename}'"
86
+
87
+ file.puts @data[index].title
88
+ file.puts @data[index].data
89
+ file.close
90
+
91
+ if ENV["EDITOR"] then
92
+ cmdline = ENV["EDITOR"]
93
+ else
94
+ cmdline = "/usr/bin/vi"
95
+ end
96
+ cmdline = "%s %s" % [cmdline, filename]
97
+ print_verbose "executing '#{cmdline}'"
98
+
99
+ if system(cmdline) then
100
+ file = File.open(filename,"r")
101
+ lines = file.readlines
102
+ @data[index].title = lines[0].chomp
103
+ @data[index].data = lines[1..lines.length-1].join("")
104
+ file.close
105
+ else
106
+ puts "Error executing '#{cmdline}' with exit code #{$?}"
107
+ end
108
+
109
+ File.unlink(filename)
110
+
111
+ # because of this save we do not not need autosave for the cli version
112
+ @data.save
113
+ end #}}}1
114
+
115
+ def do_show(args)
116
+ #{{{1
117
+ index = get_index(args)
118
+ return if index.nil?
119
+
120
+ puts @data[index].title
121
+ puts @data[index].data
122
+ end #}}}1
123
+
124
+ def do_delete(args)
125
+ #{{{1
126
+ index = get_index(args)
127
+ return if index.nil?
128
+
129
+ @data.current_index = index
130
+
131
+ if pref("deletesave_enable") and not @data.current.empty? then
132
+ deletefile = expand_filename(pref("deletesave_file"),
133
+ @data.dirname, @data.filename)
134
+ end
135
+
136
+ begin
137
+ @data.current.append_as_mbox(deletefile)
138
+ rescue SystemCallError => msg
139
+ puts msg
140
+ end
141
+
142
+ @data.delete
143
+ end #}}}1
144
+
145
+ def do_new
146
+ #{{{1
147
+ return if @data.nil?
148
+
149
+ @data.new
150
+ end #}}}1
151
+
152
+ def do_page(args)
153
+ #{{{1
154
+ index = get_index(args)
155
+ return if index.nil?
156
+
157
+ file = Tempfile.new("jotacli")
158
+ filename = file.path
159
+ print_verbose "creating temporary file '#{filename}'"
160
+
161
+ file.puts @data[index].title
162
+ file.puts @data[index].data
163
+ file.close
164
+
165
+ if ENV["PAGER"] then
166
+ cmdline = ENV["PAGER"]
167
+ else
168
+ cmdline = "/bin/more"
169
+ end
170
+ cmdline = "%s %s" % [cmdline, filename]
171
+ print_verbose "executing '#{cmdline}'"
172
+
173
+ if not system(cmdline) then
174
+ puts "Error executing '#{cmdline}' with exit code #{$?}"
175
+ end
176
+
177
+ File.unlink(filename)
178
+ end #}}}1
179
+
180
+ def do_default(args)
181
+ #{{{1
182
+ if args.nil? or args == "" then
183
+ puts "Default command is '#{@default_command}'"
184
+ elsif args =~ /^(show|edit|page)$/ then
185
+ @default_command = args
186
+ else
187
+ puts "Illegal default command. Valid are show, edit, and page"
188
+ end
189
+ end #}}}1
190
+
191
+ private
192
+
193
+ def setup
194
+ #{{{1
195
+ puts "#{Version::PROGRAM_NAME} #{Version::STRING} ready"
196
+ puts "Type 'help' for commands"
197
+
198
+ @data = nil
199
+ @default_command = "page"
200
+ end #}}}1
201
+
202
+ def command_missing(command, args)
203
+ #{{{1
204
+ case @default_command
205
+ when "show"
206
+ do_show(command)
207
+ when "edit"
208
+ do_edit(command)
209
+ when "page"
210
+ do_page(command)
211
+ end
212
+ end #}}}1
213
+
214
+ def prompt_command
215
+ #{{{1
216
+ if @data.nil? then
217
+ "> "
218
+ else
219
+ @data.filename+"> "
220
+ end
221
+ end #}}}1
222
+
223
+ def postloop
224
+ #{{{1
225
+ @data.save if @data
226
+ end #}}}1
227
+
228
+ def type_to_char(t)
229
+ #{{{1
230
+ case t
231
+ when :text
232
+ return "t"
233
+ when :pref
234
+ return "p"
235
+ else
236
+ return "?"
237
+ end
238
+ end #}}}1
239
+
240
+ def get_index(str)
241
+ #{{{1
242
+ return nil if @data.nil? or str.nil?
243
+
244
+ if str =~ /^\d+$/ then
245
+ result = str.to_i - 1
246
+ else
247
+ result = nil
248
+ re = Regexp.new(str,Regexp::IGNORECASE)
249
+ @data.each_index do | i |
250
+ if @data[i].title.match(re) then
251
+ result = i
252
+ break
253
+ end
254
+ end
255
+ if result.nil? then
256
+ return nil
257
+ end
258
+ end
259
+ if result < 0 or result >= @data.length then
260
+ return nil
261
+ else
262
+ return result
263
+ end
264
+ end #}}}1
265
+
266
+ def pref(key)
267
+ #{{{1
268
+ if @data.nil? then
269
+ return Preferences.defaults[key]
270
+ else
271
+ @data.pref[key]
272
+ end
273
+ end #}}}1
274
+
275
+ end # class
276
+
277
+ # vim600: set foldmethod=marker:
data/lib/clip.rb ADDED
@@ -0,0 +1,137 @@
1
+
2
+ # $Id: clip.rb 37 2009-02-09 10:06:02Z dz $
3
+
4
+ # if you use vim and don't like folds type zR
5
+
6
+ require 'time'
7
+ require 'version'
8
+
9
+ class Clip
10
+
11
+
12
+ # Instance Variables
13
+ # data String "" text (*every* line ends with an LF)
14
+ # wrap Boolean false line wrap?
15
+ # type Symbol :text :text, :pref
16
+ # title String "" first line of clip (without LF)
17
+ # created Time now creation time
18
+ # pos Int 0 saved cursor position
19
+
20
+
21
+ attr_accessor :wrap, :title, :created, :pos, :type, :data
22
+
23
+ def initialize
24
+ #{{{1
25
+ @data = "" # no lines at all, "\n" would be 1 empty line
26
+ @wrap = false
27
+ @type = :text
28
+ @title = ""
29
+ @created = Time.now
30
+ @pos = 0
31
+ end #}}}1
32
+
33
+ def Clip.from_mbox(str)
34
+ #{{{1
35
+ # "From_" line already removed
36
+ cl = Clip.new
37
+ in_header = true
38
+ str.each_line do | line |
39
+ if in_header then
40
+ if line == "\n" then
41
+ in_header = false
42
+ next
43
+ end
44
+ #(key, value) = line.split(/\s*:\s*/,2)
45
+ # stricter pattern to preserve leading spaces
46
+ (key, value) = line.split(/\s*: /,2)
47
+ value.chomp!
48
+ case key.downcase
49
+ when "x-wrap"
50
+ cl.wrap = (value.downcase == "true")
51
+ when "subject"
52
+ cl.title = value
53
+ when "date"
54
+ cl.created = Time.parse(value)
55
+ when "content-type"
56
+ case value
57
+ when "text/plain"
58
+ cl.type = :text
59
+ when "application/x-jota-pref"
60
+ cl.type = :pref
61
+ else
62
+ cl.type = :text # safe fallback type
63
+ end
64
+ end
65
+ else
66
+ cl.data << line
67
+ end
68
+ end
69
+ return cl
70
+ end #}}}1
71
+
72
+ def to_mbox
73
+ #{{{1
74
+ str = ""
75
+ str << "Date: %s\n" % @created.ctime
76
+ str << "Subject: %s\n" % @title
77
+ case @type
78
+ when :text
79
+ str << "Content-Type: text/plain\n"
80
+ when :pref
81
+ str << "Content-Type: application/x-jota-pref\n"
82
+ end
83
+ str << "X-Wrap: %s\n" % @wrap.to_s
84
+ str << "X-Saved-By: %s %s\n" % [
85
+ Version::PROGRAM_NAME, Version::STRING]
86
+ str << "\n"
87
+ str << @data
88
+ return str
89
+ end #}}}1
90
+
91
+ def Clip.from_hash(hash)
92
+ #{{{1
93
+ cl = Clip.new
94
+ case hash["type"]
95
+ when :text
96
+ cl.wrap = hash["wrap"]
97
+ cl.data = hash["data"]
98
+ cl.title = hash["title"]
99
+ cl.created = hash["created"]
100
+ end
101
+ return cl
102
+ end #}}}1
103
+
104
+ def to_hash
105
+ #{{{1
106
+ hash = Hash.new
107
+ hash["type"] = @type
108
+ hash["wrap"] = @wrap
109
+ hash["data"] = @data
110
+ hash["title"] = @title
111
+ hash["created"] = @created
112
+ return hash
113
+ end #}}}1
114
+
115
+ def append_as_mbox(file_and_path)
116
+ #{{{1
117
+ File.open(file_and_path,"a") do | f |
118
+ f.print "From %s@localhost %s\n" %
119
+ [Version::PROGRAM_NAME, Time.now.ctime]
120
+ f.print(to_mbox)
121
+ end
122
+ end #}}}1
123
+
124
+ def empty?
125
+ #{{{1
126
+ # strip also removes LFs
127
+ return @data.strip == "" && @title.strip == ""
128
+ end #}}}1
129
+
130
+ def ==(clip)
131
+ #{{{1
132
+ return self.to_hash == clip.to_hash
133
+ end #}}}1
134
+
135
+ end #class
136
+
137
+ # vim600: set foldmethod=marker: