Piggy 0.4.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. data/CHANGES.txt +91 -0
  2. data/INSTALL.txt +77 -0
  3. data/LICENCE.txt +339 -0
  4. data/README.txt +27 -0
  5. data/UNINSTALL.txt +24 -0
  6. data/bin/directory_diff +6 -0
  7. data/bin/ftp_browser +6 -0
  8. data/bin/piggy +6 -0
  9. data/lib/directory_diff.rb +35 -0
  10. data/lib/ftp_browser.rb +33 -0
  11. data/lib/icons/auto-select-for-del.ico +0 -0
  12. data/lib/icons/auto-select-right.ico +0 -0
  13. data/lib/icons/auto-upload-right.ico +0 -0
  14. data/lib/icons/back.ico +0 -0
  15. data/lib/icons/checked.ico +0 -0
  16. data/lib/icons/copy.png +0 -0
  17. data/lib/icons/cut.png +0 -0
  18. data/lib/icons/dir.ico +0 -0
  19. data/lib/icons/dirup.ico +0 -0
  20. data/lib/icons/file.ico +0 -0
  21. data/lib/icons/fileopen.png +0 -0
  22. data/lib/icons/filesave.ico +0 -0
  23. data/lib/icons/gallery.ico +0 -0
  24. data/lib/icons/generate.ico +0 -0
  25. data/lib/icons/minus.png +0 -0
  26. data/lib/icons/move-right-dir.ico +0 -0
  27. data/lib/icons/move-right-file.ico +0 -0
  28. data/lib/icons/newer-file.ico +0 -0
  29. data/lib/icons/next-image.ico +0 -0
  30. data/lib/icons/paste.png +0 -0
  31. data/lib/icons/plus.png +0 -0
  32. data/lib/icons/preview.png +0 -0
  33. data/lib/icons/previous-image.ico +0 -0
  34. data/lib/icons/reload.ico +0 -0
  35. data/lib/icons/remove-selected.ico +0 -0
  36. data/lib/icons/rotate.ico +0 -0
  37. data/lib/icons/slides.ico +0 -0
  38. data/lib/icons/stop-slides.ico +0 -0
  39. data/lib/icons/unchecked-dir.ico +0 -0
  40. data/lib/icons/unchecked.ico +0 -0
  41. data/lib/icons/upload-selected.ico +0 -0
  42. data/lib/icons/upload.ico +0 -0
  43. data/lib/piggy-core/alive_check.rb +44 -0
  44. data/lib/piggy-core/debug.rb +21 -0
  45. data/lib/piggy-core/encoding.rb +11 -0
  46. data/lib/piggy-core/environment.rb +66 -0
  47. data/lib/piggy-core/exifr_adapter.rb +85 -0
  48. data/lib/piggy-core/file_info.rb +218 -0
  49. data/lib/piggy-core/ftp_adapter.rb +106 -0
  50. data/lib/piggy-core/htmlgen.rb +242 -0
  51. data/lib/piggy-core/nconvert_thumbsgen.rb +73 -0
  52. data/lib/piggy-core/options.rb +116 -0
  53. data/lib/piggy-core/options_persistence.rb +54 -0
  54. data/lib/piggy-core/progress.rb +48 -0
  55. data/lib/piggy-core/rmagick_thumbnail_page_generator.rb +30 -0
  56. data/lib/piggy-core/thumbnail_generator.rb +79 -0
  57. data/lib/piggy-core/thumbnail_page_generator.rb +542 -0
  58. data/lib/piggy-core/upload_info.rb +41 -0
  59. data/lib/piggy-core/version.rb +18 -0
  60. data/lib/piggy-core/winshell.rb +240 -0
  61. data/lib/piggy-gui/directory_diff_widget.rb +398 -0
  62. data/lib/piggy-gui/filtered_file_list.rb +243 -0
  63. data/lib/piggy-gui/fox_thumbsgen.rb +18 -0
  64. data/lib/piggy-gui/ftp_browser_widget.rb +395 -0
  65. data/lib/piggy-gui/html_generation_dialog.rb +157 -0
  66. data/lib/piggy-gui/image_processor.rb +140 -0
  67. data/lib/piggy-gui/multiimagecanvas.rb +163 -0
  68. data/lib/piggy-gui/options_dialog.rb +85 -0
  69. data/lib/piggy-gui/piggy_image_browser.rb +776 -0
  70. data/lib/piggy-gui/pipe_log.rb +67 -0
  71. data/lib/piggy-gui/progress_with_dialog.rb +51 -0
  72. data/lib/piggy-gui/require-fox.rb +87 -0
  73. data/lib/piggy.rb +35 -0
  74. data/lib/templates/fuss.htm +10 -0
  75. data/lib/templates/kopf.htm +13 -0
  76. data/lib/templates/navigation.htm +11 -0
  77. data/lib/templates/slideshow.htm +129 -0
  78. data/lib/templates/slideshow.js +691 -0
  79. data/lib/templates/styles/basic/style.css +27 -0
  80. data/lib/templates/styles/black/style.css +64 -0
  81. data/lib/templates/styles/roundedbox/roundedbox_lo.gif +0 -0
  82. data/lib/templates/styles/roundedbox/roundedbox_lu.gif +0 -0
  83. data/lib/templates/styles/roundedbox/roundedbox_ro.gif +0 -0
  84. data/lib/templates/styles/roundedbox/roundedbox_ru.gif +0 -0
  85. data/lib/templates/styles/roundedbox/style.css +70 -0
  86. data/lib/templates/styles/shadow/lo.gif +0 -0
  87. data/lib/templates/styles/shadow/lu.gif +0 -0
  88. data/lib/templates/styles/shadow/ro.gif +0 -0
  89. data/lib/templates/styles/shadow/ru.gif +0 -0
  90. data/lib/templates/styles/shadow/style.css +63 -0
  91. data/test/file_info_test.rb +117 -0
  92. data/test.rb +8 -0
  93. data/web/IMAGE_PROCESSING.txt +53 -0
  94. data/web/INSTALL.txt +74 -0
  95. data/web/extern.gif +0 -0
  96. data/web/ftp-browser.png +0 -0
  97. data/web/index-de.html +60 -0
  98. data/web/index.html +57 -0
  99. data/web/piggy.png +0 -0
  100. data/web/style.css +14 -0
  101. metadata +177 -0
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'timeout'
4
+
5
+ # This class works similar to a timeout.
6
+ # Run it like this:
7
+ #
8
+ # x = AliveCheck(10)
9
+ # begin
10
+ # x.check { ... x.alive! ... }
11
+ # rescue Timeout::Error => msg
12
+ # ...
13
+ # end
14
+ #
15
+ # If x doesn't get an alive! notification for
16
+ # 10 to 20 seconds, it will raise a Timeout::Error
17
+ class AliveCheck
18
+ def initialize(check_interval_sec, ex_msg = 'execution expired')
19
+ @sec = check_interval_sec
20
+ @alive = false
21
+ @ex_msg = ex_msg
22
+ end
23
+
24
+ def check
25
+ checked_thread = Thread.current
26
+ @alive = true
27
+ aliveChecker = Thread.new {
28
+ while(@alive) do
29
+ @alive = false
30
+ sleep(@sec)
31
+ end
32
+ checked_thread.raise(Timeout::Error, @ex_msg) if checked_thread.alive?
33
+ }
34
+ begin
35
+ yield
36
+ ensure
37
+ aliveChecker.kill if aliveChecker and aliveChecker.alive?
38
+ end
39
+ end
40
+
41
+ def alive!
42
+ @alive = true
43
+ end
44
+ end
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Global methods temporaryly used for debugging.
4
+ # Inspired by the book
5
+ # "Programmieren mit Ruby" by R�hrl/Schmiedl/Weyss"
6
+
7
+ def beginTrace
8
+ $stderr.puts "Begin Trace in: #{caller.first}"
9
+ set_trace_func proc {
10
+ |event, file, line, id, binding, classname|
11
+ unless File.basename(file) == 'debug.rb'
12
+ $stderr.printf("%8s %s-, %-2d %10s %8s\n",
13
+ event, file, line, id, classname)
14
+ end
15
+ }
16
+ end
17
+
18
+ def endTrace
19
+ $stderr.set_trace_func(nil)
20
+ puts "End Trace in: #{caller.first}"
21
+ end
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/ruby
2
+ # $Id: require-fox.rb 188 2007-12-16 14:10:39Z Sascha $
3
+
4
+ def utf8_as_string(aString)
5
+ return aString.unpack("U*").pack("C*")
6
+ end
7
+
8
+ def string_as_utf8(aString)
9
+ aString.unpack("C*").pack("U*")
10
+ end
11
+
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Require this file will set global constants to appropriate values:
4
+ #
5
+ # - PIGGY_PATH points to piggy's lib directory.
6
+ # - RMAGICK_AVAILIABLE will be true if RMagick is installed
7
+ #
8
+ # The standard method is to find the installed gem and let
9
+ # PIGGY_PATH point to the subdirectory lib.
10
+ #
11
+ # If the gem isn't found, we assume that piggy has been started
12
+ # from within the lib directory itself and therefore set
13
+ # PIGGY_PATH = '.'. (This is often the case during development.)
14
+ #
15
+ # Note that PIGGY_PATH uses the Ruby notation of the path.
16
+ #
17
+ # So, what ist this good for? We'll find all resource files,
18
+ # icons or other user-independent configuration files using
19
+ # paths relative to PIGGY_PATH.
20
+
21
+ begin
22
+ require 'rubygems'
23
+ require 'piggy-core/version.rb'
24
+
25
+ # Try to find lib directory of this specific Piggy gem version
26
+ def findPiggyDirectory
27
+ puts "Checking $LOAD_PATH"
28
+ $LOAD_PATH.each do
29
+ |d|
30
+ if /piggy.lib$/ =~ d
31
+ return d.gsub(/\\/, '/')
32
+ end
33
+ end
34
+ puts "Checking Gems"
35
+ piggyGemDir = "Piggy-#{PiggyVersion.versionString.gsub(/-/, '.')}"
36
+ all = Gem::path.collect { |gempath|
37
+ File.join(gempath, 'gems', piggyGemDir)
38
+ }.select { |f|
39
+ File.directory?(f)
40
+ }
41
+ return all.empty? ? '.' : File.join(all.first, 'lib')
42
+ end
43
+ PIGGY_PATH = findPiggyDirectory
44
+ puts "Successfully detecting piggy gem lib in #{PIGGY_PATH}"
45
+ rescue LoadError
46
+ PIGGY_PATH = '.'
47
+ end
48
+
49
+ # Temporary change working dir while executing a given block
50
+ # (depriciated)
51
+ def inPath(path, &block)
52
+ workingDirSik = Dir.getwd
53
+ begin
54
+ Dir.chdir(path)
55
+ block.call
56
+ ensure
57
+ Dir.chdir(workingDirSik)
58
+ end
59
+ end
60
+
61
+ begin
62
+ require 'RMagick'
63
+ RMAGICK_AVAILIABLE = true
64
+ rescue LoadError
65
+ RMAGICK_AVAILIABLE = false
66
+ end
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env ruby
2
+ #$Id: options.rb 177 2007-11-21 21:59:52Z Sascha $
3
+
4
+ require 'exifr'
5
+
6
+ # This adapter is used as an additional
7
+ # layer between Piggy and EXIFR.
8
+ class ExifrAdapter
9
+ def initialize(file)
10
+ @exif = loadExif(file)
11
+ end
12
+
13
+ def exif?
14
+ @exif && @exif.exif?
15
+ end
16
+
17
+ def to_s
18
+ return 'no exif' unless exif?
19
+ desc = "Exif:\n\t"
20
+ h = @exif.exif.to_hash
21
+ desc += h.keys.collect { |k| "#{k.to_s}: #{h[k].to_s}" }.join("\n\t")
22
+ return desc
23
+ end
24
+
25
+ def viewDegrees
26
+ return 0 unless exif?
27
+ orientation = @exif.exif[:orientation]
28
+ return 0 if orientation.nil?
29
+ imageMock = ExifrDegreeComuter.new
30
+ orientation.transform_rmagick(imageMock)
31
+ return imageMock.degree
32
+ end
33
+
34
+ def width
35
+ exif? ? @exif.width : 0
36
+ end
37
+
38
+ def height
39
+ exif? ? @exif.height : 0
40
+ end
41
+
42
+ private
43
+
44
+ def loadExif(file)
45
+ if(hasExtension?(file, 'jpg'))
46
+ EXIFR::JPEG.new(file)
47
+ elsif(hasExtension?(file, 'tif'))
48
+ EXIFR::TIFF.new(file)
49
+ else
50
+ nil
51
+ end
52
+ end
53
+
54
+ def hasExtension?(filename, ext)
55
+ File.basename(filename.upcase, ext.upcase) !=
56
+ File.basename(filename.upcase)
57
+ end
58
+ end
59
+
60
+ # Simulate rmagick image to compte degree instead
61
+ # of rotate.
62
+ class ExifrDegreeComuter
63
+ attr_reader(:degree)
64
+
65
+ def initialize
66
+ @degree = 0
67
+ end
68
+
69
+ def flop
70
+ end
71
+
72
+ def flip
73
+ end
74
+
75
+ def rotate(degree)
76
+ @degree = degree
77
+ self
78
+ end
79
+ end
80
+
81
+ class EXIFR::TIFF::Orientation
82
+ def to_s
83
+ @value.to_s + ' (' + @type.to_s + ')'
84
+ end
85
+ end
@@ -0,0 +1,218 @@
1
+ #!/usr/bin/ruby
2
+ #$Id: file_info.rb 195 2008-05-29 21:32:40Z Sascha $
3
+
4
+ # Provides classes to hold some information for single files,
5
+ # directory contents and multiple files at different locations.
6
+
7
+ # Some utility methods for path handling.
8
+ module FilePath
9
+
10
+ # Ruby path notation for a given operation system/file system
11
+ # specific path
12
+ def FilePath.internPath(pathString)
13
+ return '' unless pathString
14
+ newPath = pathString.gsub(/\\/, File::SEPARATOR)
15
+ return newPath =~ /:$/ ? newPath + File::SEPARATOR : newPath
16
+ end
17
+
18
+ # Just as File.join but handles at least one possible error.
19
+ #
20
+ # ===Example
21
+ #
22
+ # FilePath.join('bla/', '/blubb') # => 'bla/blubb'
23
+ def FilePath.join(string1, string2)
24
+ return string2 unless string1 && !string1.empty?
25
+ return string1 unless string2 && !string2.empty?
26
+ noLeadingSeps2 = string2.sub(Regexp.compile("#{File::SEPARATOR}*"), '')
27
+ return File.join(string1, noLeadingSeps2)
28
+ end
29
+
30
+ # Sections of a given pathString
31
+ def FilePath.split(pathString)
32
+ pathString.split(File::SEPARATOR)
33
+ end
34
+
35
+ # Removes the last section of a given pathString.
36
+ # Won't remove a section of a file system root.
37
+ # Possible roots are '/', 'C:', 'X:/', ...
38
+ def FilePath.oneDirUp(pathString)
39
+ return '' unless pathString
40
+ sections = FilePath.split(pathString)
41
+ return '' unless sections || !sections.empty?
42
+ if sections.size == 1
43
+ return pathString if pathString =~ /:/
44
+ return pathString if pathString == '/'
45
+ return ''
46
+ end
47
+ return '' unless sections[-1]
48
+ numOfCharsToStrip = sections[-1].size + 2
49
+ return FilePath.internPath(pathString[0..-numOfCharsToStrip])
50
+ end
51
+ end
52
+
53
+ # Every String could be a Filename but we want
54
+ # a class containing name and path to make some things
55
+ # more explicit.
56
+ class FileName
57
+ attr_accessor(:name)
58
+ attr_reader(:path)
59
+
60
+ def initialize(theName, thePath = '')
61
+ @name = theName
62
+ setPath(thePath)
63
+ end
64
+
65
+ def path=(newPath)
66
+ setPath(newPath)
67
+ end
68
+
69
+ def setPath(newPath)
70
+ @path = FilePath.internPath(newPath)
71
+ end
72
+
73
+ def nameWithPath
74
+ return FilePath.join(path, name)
75
+ end
76
+
77
+ def nameWithoutExtension
78
+ return File.basename(name, '.' + extension)
79
+ end
80
+
81
+ def extension
82
+ return name.split('.')[-1]
83
+ end
84
+
85
+ def pathSections
86
+ return FilePath.split(path)
87
+ end
88
+ end
89
+
90
+ # An entity object where you can set all attributes no matter
91
+ # if (or where) the file exists. Next to a name and path it
92
+ # has further attributes such as a creation and a modification
93
+ # time and a size in bytes. New instances aren't directories by
94
+ # default but you can set this flag, too.
95
+ class FileInfo < FileName
96
+ attr_accessor(:size, :mtime, :ctime)
97
+
98
+ def initialize(theName, thePath = '')
99
+ super(theName, thePath)
100
+ @size = 0
101
+ @isDirectory = false
102
+ end
103
+
104
+ def directory?
105
+ return @isDirectory
106
+ end
107
+
108
+ def directory!
109
+ @isDirectory = true
110
+ end
111
+
112
+ def mtimeString
113
+ timeStringFor(mtime)
114
+ end
115
+
116
+ def ctimeString
117
+ timeStringFor(ctime)
118
+ end
119
+
120
+ protected
121
+
122
+ def timeStringFor(time)
123
+ return 'unknown' unless time
124
+ time.strftime("%m/%d/%Y at %I:%M%p")
125
+ end
126
+ end
127
+
128
+ class CommentedFile < FileInfo
129
+ attr_accessor(:comment, :rotation, :width, :height)
130
+
131
+ def initialize(theName, thePath = '', theComment = '')EXIFR
132
+ super(theName, thePath)
133
+ @comment = theComment
134
+ @rotation = 0
135
+ @width = 0
136
+ @height = 0
137
+ end
138
+
139
+ def rotate?
140
+ @rotation && @rotation != 0
141
+ end
142
+ end
143
+
144
+ # An unordered list of FileInfos, accessible by name.
145
+ # The directory location is stored as a path-String.
146
+ class DirectoryContents
147
+ attr_accessor(:path)
148
+
149
+ def initialize(thePath = '')
150
+ @path = thePath
151
+ @contents = Hash.new
152
+ end
153
+
154
+ def add(aFileName)
155
+ @contents[aFileName.name] = aFileName
156
+ end
157
+
158
+ def []=(aName, info)
159
+ @contents[aName] = info
160
+ end
161
+
162
+ def get(aFileName)
163
+ return @contents[aFileName.name]
164
+ end
165
+
166
+ def at(aName)
167
+ return @contents[aName]
168
+ end
169
+
170
+ def [](aName)
171
+ return @contents[aName]
172
+ end
173
+
174
+ alias has_key? []
175
+
176
+ def keys
177
+ return @contents.keys
178
+ end
179
+
180
+ def directories
181
+ return @contents.keys.select { |k| @contents[k].directory? }.sort
182
+ end
183
+
184
+ def files
185
+ return @contents.keys.reject { |k| @contents[k].directory? }.sort
186
+ end
187
+ end
188
+
189
+ # A unordered list of FileInfos accessible by FileName.
190
+ # (Which means that you need both, path and name, to store
191
+ # the info in the repository. Unless DirectoryContents these
192
+ # files do not need to have a common location.)
193
+ class FileRepository
194
+ def initialize
195
+ @repository = Hash.new
196
+ end
197
+
198
+ def add(aFileName)
199
+ self[aFileName] = aFileName
200
+ end
201
+
202
+ def []=(aFileName, info)
203
+ hashOrNil = @repository[aFileName.path]
204
+ if hashOrNil == nil
205
+ hashOrNil = Hash.new
206
+ @repository[aFileName.path] = hashOrNil
207
+ end
208
+ hashOrNil[aFileName.name] = info
209
+ end
210
+
211
+ def get(aFileName)
212
+ subHash = @repository[aFileName.path]
213
+ return subHash == nil ? nil : subHash[aFileName.name]
214
+ end
215
+ alias [] get
216
+ alias has_key? get
217
+ end
218
+
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'timeout'
4
+ require 'net/ftp'
5
+ require 'piggy-core/alive_check'
6
+ require 'piggy-core/options'
7
+
8
+ # This is a wrapper around Net::FTP. It has a different interface
9
+ # and introduces two additional timeouts. Configure the timeouts
10
+ # and other parameters through PiggyOptions.
11
+ class FtpAdapter
12
+
13
+ attr_accessor(:host, :user, :password)
14
+
15
+ def initialize(options)
16
+ @connection = nil
17
+ @options = options # some options may change any time
18
+ end
19
+
20
+ def connect(host, user, password)
21
+ cTimeout { @connection = Net::FTP.open(host, user, password) }
22
+ @connection.debug_mode = @options.debug
23
+ end
24
+
25
+ def chdir(path)
26
+ if path && !path.empty?
27
+ cTimeout { @connection.chdir(path) }
28
+ end
29
+ end
30
+
31
+ def nlst
32
+ cTimeout { @connection.nlst }
33
+ end
34
+
35
+ def info(file, path)
36
+ info = FileInfo.new(file, path)
37
+ begin
38
+ mtime = cTimeout {
39
+ @connection.mtime(file, @options.ftpHasLocaltime?)
40
+ }
41
+ mtime = mtime.localtime unless @options.ftpHasLocaltime?
42
+ info.mtime = mtime
43
+ rescue Net::FTPError
44
+ info.directory!
45
+ end
46
+ info
47
+ end
48
+
49
+ def mkdir(dir)
50
+ cTimeout { @connection.mkdir(dir) }
51
+ end
52
+
53
+ def delete(file)
54
+ cTimeout { @connection.delete(file) }
55
+ end
56
+
57
+ # Upload with progress events.
58
+ #
59
+ # Example:
60
+ # upload('C:\tmp\bla\big.zip', 'C:\tmp') {
61
+ # |data|
62
+ # ...
63
+ # data.size
64
+ # ...
65
+ # }
66
+ # This will create a remote file bla/big.zip
67
+ # and every chunk of transferred data will
68
+ # be given to the block.
69
+ def upload(localPath, file, &block)
70
+ depthOffset = FilePath.split(localPath).size
71
+ pathSections = FilePath.split(file)
72
+ dirs = pathSections[depthOffset..-2]
73
+ unless dirs == nil
74
+ dirs.each do
75
+ |dir|
76
+ begin
77
+ chdir(dir)
78
+ rescue Net::FTPError
79
+ mkdir(dir)
80
+ chdir(dir)
81
+ end
82
+ end
83
+ end
84
+ aliveChecker = AliveCheck.new(@options.ftpTransferTimeout,
85
+ "ftp transfer timeout")
86
+ aliveChecker.check do
87
+ @connection.putbinaryfile(file) { |data|
88
+ aliveChecker.alive!
89
+ block.call(data)
90
+ }
91
+ end
92
+ unless dirs == nil
93
+ dirs.each { |dir| chdir('..') }
94
+ end
95
+ end
96
+
97
+ def close
98
+ @connection.close unless @connection.nil?
99
+ end
100
+
101
+ private
102
+
103
+ def cTimeout(&block)
104
+ timeout(@options.ftpConnectionTimeout, &block)
105
+ end
106
+ end