gf-ralbum 0.0.2 → 0.0.5

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.
Files changed (118) hide show
  1. data/VERSION +1 -0
  2. data/bin/{ralbum.rb → ralbum} +1 -1
  3. data/example/example.sh +2 -1
  4. data/example/test_jalbum_phototree/jalbum-settings.jap +321 -0
  5. data/example/test_jalbum_phototree/src/albumfiles.txt +9 -0
  6. data/example/test_jalbum_phototree/src/comments.properties +0 -0
  7. data/example/test_jalbum_phototree/src/flowers/albumfiles.txt +14 -0
  8. data/example/test_jalbum_phototree/src/meta.properties +2 -0
  9. data/example/{test_phototree → test_rubyphoto_phototree}/album.xml +0 -0
  10. data/example/test_rubyphoto_phototree/flowers/IMG_1469.wt.jpg +0 -0
  11. data/example/test_rubyphoto_phototree/flowers/IMG_2291.jpg +0 -0
  12. data/example/test_rubyphoto_phototree/flowers/IMG_2598.jpg +0 -0
  13. data/example/test_rubyphoto_phototree/flowers/IMG_3068.jpg +0 -0
  14. data/example/test_rubyphoto_phototree/flowers/IMG_3323.jpg +0 -0
  15. data/example/test_rubyphoto_phototree/flowers/IMG_3348.jpg +0 -0
  16. data/example/{test_phototree → test_rubyphoto_phototree}/r_photo01.jpg +0 -0
  17. data/example/{test_phototree → test_rubyphoto_phototree}/r_photo01.jpg.xml +0 -0
  18. data/example/{test_phototree/catalog_data → test_rubyphoto_phototree/ralbum}/md5_to_key.yaml +0 -0
  19. data/example/{test_phototree/catalog_data → test_rubyphoto_phototree/ralbum}/md5_to_key.yaml.test +0 -0
  20. data/example/{test_phototree/catalog_data → test_rubyphoto_phototree/ralbum}/project.xml +206 -3
  21. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum01/album.xml +0 -0
  22. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum01/subalbum01_photo01.jpg +0 -0
  23. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum01/subalbum01_photo01.jpg.xml +0 -0
  24. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum01/subalbum01_photo02.jpg +0 -0
  25. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum01/subalbum01_photo02.jpg.xml +0 -0
  26. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum01/subalbum01_photo03.jpg +0 -0
  27. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum01/subalbum01_photo03.jpg.xml +0 -0
  28. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum01/subalbum01_photo04.jpg +0 -0
  29. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum01/subalbum01_photo04.jpg.xml +0 -0
  30. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum02/album.xml +0 -0
  31. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum02/subalbum02_photo01.jpg +0 -0
  32. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum02/subalbum02_photo01.jpg.xml +0 -0
  33. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum02/subalbum02_photo02.jpg +0 -0
  34. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum02/subalbum02_photo02.jpg.xml +0 -0
  35. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum02/subalbum02_photo03.jpg +0 -0
  36. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum02/subalbum02_photo03.jpg.xml +0 -0
  37. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum02/subalbum02_photo04.jpg +0 -0
  38. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum02/subalbum02_photo04.jpg.xml +0 -0
  39. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum02/subalbum02_photo05.jpg +0 -0
  40. data/example/{test_phototree → test_rubyphoto_phototree}/subalbum02/subalbum02_photo05.jpg.xml +0 -0
  41. data/lib/ralbum.rb +9 -5
  42. data/lib/ralbum/album_tree/album.rb +74 -0
  43. data/lib/ralbum/album_tree/generate_album_tree_node_visitor.rb +73 -0
  44. data/lib/ralbum/album_tree/image_file.rb +88 -0
  45. data/lib/ralbum/{image_pool.rb → album_tree/image_pool.rb} +16 -4
  46. data/lib/ralbum/catalog.rb +7 -7
  47. data/lib/ralbum/cli/cli_ralbum.rb +66 -25
  48. data/lib/ralbum/image_strategies/copy_image_strategy.rb +16 -0
  49. data/lib/ralbum/image_strategies/linked_image_strategy.rb +18 -0
  50. data/lib/ralbum/image_strategies/scaled_image_strategy.rb +52 -0
  51. data/lib/ralbum/image_strategies/sepia_scaled_image_strategy.rb +50 -0
  52. data/lib/{ralbum-common → ralbum}/object_with_properties.rb +0 -0
  53. data/lib/{ralbum-common → ralbum}/object_with_validation.rb +0 -0
  54. data/lib/ralbum/photo_tree/jalbum_photo_tree.rb +83 -0
  55. data/lib/ralbum/photo_tree/photo_file.rb +149 -0
  56. data/lib/ralbum/photo_tree/photo_tree_item.rb +68 -0
  57. data/lib/ralbum/{photo_tree_node.rb → photo_tree/photo_tree_node.rb} +16 -13
  58. data/lib/ralbum/{photo_tree_builder.rb → photo_tree/rubyphoto_photo_tree.rb} +64 -46
  59. data/lib/ralbum/project.rb +48 -12
  60. data/lib/ralbum/skin.rb +34 -27
  61. data/lib/ralbum/skin_engine.rb +32 -17
  62. data/lib/ralbum/skin_engines/erb_skin_engine.rb +2 -5
  63. data/lib/ralbum/skin_engines/kwartz_skin_engine.rb +6 -9
  64. data/lib/ralbum/skin_manager.rb +11 -2
  65. data/lib/ralbum/skins/cgi/cgi_skin.rb +21 -23
  66. data/lib/ralbum/skins/cgi/res/model.rb +30 -32
  67. data/lib/ralbum/skins/gfold/inc/menu_bottom.html +53 -53
  68. data/lib/ralbum/skins/gfold/inc/menu_top.html +71 -71
  69. data/lib/ralbum/skins/gfold/inc/page_footer.html +28 -28
  70. data/lib/ralbum/skins/gfold/out/album_page.rb +316 -316
  71. data/lib/ralbum/skins/gfold/out/image_page.rb +231 -231
  72. data/lib/ralbum/skins/gfold/out/tree_page.rb +96 -96
  73. data/lib/ralbum/skins/gfold/res/prototype.js +3277 -3277
  74. data/lib/ralbum/skins/gfold/template/album_page.html +161 -161
  75. data/lib/ralbum/skins/gfold/template/album_page.plogic +127 -127
  76. data/lib/ralbum/skins/gfold/template/image_page.html +91 -91
  77. data/lib/ralbum/skins/gfold/template/image_page.plogic +70 -70
  78. data/lib/ralbum/skins/gfold/template/tree_page.html +79 -79
  79. data/lib/ralbum/skins/gfold/template/tree_page.plogic +45 -45
  80. data/lib/ralbum/skins/js/out/album_page.rb +2 -2
  81. data/lib/ralbum/skins/js/out/tree_page.rb +18 -17
  82. data/lib/ralbum/skins/js/template/album_page.html +2 -2
  83. data/lib/ralbum/skins/js/template/tree_page.html +1 -1
  84. data/lib/ralbum/skins/test_erb/template/album_page.rhtml +22 -0
  85. data/lib/ralbum/skins/test_erb/template/image_page.rhtml +44 -0
  86. data/lib/ralbum/tasks/compile_skins.rb +8 -0
  87. data/test/ralbum/cli/tc_cli_ralbum.rb +35 -0
  88. data/test/ralbum/image_strategies/tc_scaled_image_strategy.rb +18 -0
  89. data/test/ralbum/image_strategies/tc_sepia_scaled_image_strategy.rb +18 -0
  90. data/test/ralbum/photo_tree/tc_jalbum_photo_tree.rb +39 -0
  91. data/test/ralbum/photo_tree/tc_photo_file.rb +13 -0
  92. data/test/ralbum/{tc_01_photo_tree.rb → photo_tree/tc_photo_tree.rb} +10 -12
  93. data/test/ralbum/photo_tree/tc_rubyalbum_photo_tree.rb +20 -0
  94. data/test/ralbum/tc_album.rb +55 -0
  95. data/test/ralbum/tc_catalog.rb +8 -4
  96. data/test/ralbum/tc_image_pool.rb +37 -0
  97. data/test/ralbum/{tc_05_kwartz_skin_engine.rb → tc_kwartz_skin_engine.rb} +1 -1
  98. data/test/ralbum/{tc_04_skin_manager.rb → tc_skin_manager.rb} +8 -3
  99. data/test/ralbum/test_helper.rb +16 -1
  100. data/test_data/ralbum/test_data/is_test/dummy.txt +0 -0
  101. metadata +78 -81
  102. data/bin/ralbum-JPG2jpg.rb +0 -90
  103. data/bin/ralbum-compile_skins.rb +0 -18
  104. data/bin/ralbum-myconv.rb +0 -81
  105. data/bin/ralbum-readexif.rb +0 -18
  106. data/bin/ralbum-reorder.rb +0 -200
  107. data/lib/ralbum/album.rb +0 -66
  108. data/lib/ralbum/generate_album_tree_node_visitor.rb +0 -60
  109. data/lib/ralbum/image_file.rb +0 -81
  110. data/lib/ralbum/image_strategy.rb +0 -143
  111. data/lib/ralbum/photo_tree_item.rb +0 -89
  112. data/test/ralbum/cli/test_cli_ralbum.rb +0 -13
  113. data/test/ralbum/tc_02_photo_tree_builder.rb +0 -20
  114. data/test/ralbum/tc_03_album.rb +0 -42
  115. data/test/ralbum/tc_06_image_strategy.rb +0 -21
  116. data/test/test_ralbum.rb +0 -14
  117. data/test_data/ralbum/test_data/is_test/r_photo01_scaled.jpg +0 -0
  118. data/test_data/ralbum/test_data/is_test/r_photo01_sepia_scaled.jpg +0 -0
@@ -0,0 +1,16 @@
1
+ #
2
+ # Copy an image from inpath to outpath
3
+ #
4
+ class CopyImageStrategy
5
+ attr_reader :name
6
+
7
+ def initialize( name )
8
+ @name = name
9
+ end
10
+
11
+ def build( inpath, outpath )
12
+ FileUtils.cp( inpath, outpath )
13
+ end
14
+
15
+ end
16
+
@@ -0,0 +1,18 @@
1
+ #
2
+ # Create a link from inpath to outpath
3
+ #
4
+ class LinkedImageStrategy
5
+
6
+ attr_reader :name
7
+
8
+ def initialize( name )
9
+ @name = name
10
+ end
11
+
12
+ def build( inpath, outpath )
13
+ return if File.exist?( outpath )
14
+ ralbum_verbose( 1, "link " )
15
+ File.symlink( inpath, outpath )
16
+ end
17
+
18
+ end
@@ -0,0 +1,52 @@
1
+ #
2
+ # Strategy for build a scaled image
3
+ #
4
+ class ScaledImageStrategy
5
+
6
+ attr_reader :name, :width, :height, :quality
7
+
8
+ def initialize( name, width, height, quality )
9
+ @name = name
10
+ @width = width
11
+ @height = height
12
+ @quality = quality
13
+ end
14
+
15
+
16
+ #
17
+ # build a scaled image and store it in outpath
18
+ #
19
+ # inpath source image file
20
+ # outpath destination image file
21
+ #
22
+ # TODO: sostituire inpath con PhotoFile
23
+ # TODO: sostituire outpath con ImageFile
24
+ def build( inpath, outpath )
25
+ # TODO: ritornare un risultato per es. 1 = skipped 2 = copiato 3 = scalata immagine
26
+ result_msg = ""
27
+ img = Magick::ImageList.new(inpath)
28
+
29
+ if @width > img.columns and @height > img.rows
30
+ result_msg = "(c) "
31
+ # FileUtils.cp( inpath, outpath )
32
+ # rimuovere i metadata
33
+ else
34
+ result_msg = "(#{@quality}%) "
35
+ img.resize_to_fit!(@width, @height)
36
+ end
37
+ img.profile!('*', nil)
38
+
39
+ img.write(outpath) {|i| i.quality = quality }
40
+ result_msg
41
+ end
42
+
43
+ def write_xml( xml_iss )
44
+ xml_is = xml_iss.add_element( "image_strategy")
45
+ xml_is.attributes["name"] = self.class.to_s
46
+ xml_par = xml_is.add_element("par")
47
+ xml_par.attributes["width"] = @width.to_s
48
+ xml_par.attributes["height"] = @height.to_s
49
+ xml_par.attributes["quality"] = @quality.to_s
50
+ end
51
+
52
+ end
@@ -0,0 +1,50 @@
1
+ #
2
+ # Strategy for build a scaled image
3
+ #
4
+ class SepiaScaledImageStrategy
5
+
6
+ attr_reader :name, :width, :height, :quality
7
+
8
+ def initialize( name, width, height, quality )
9
+ @name = name
10
+ @width = width
11
+ @height = height
12
+ @quality = quality
13
+ end
14
+
15
+ #
16
+ # build a scaled image and store it in outpath
17
+ #
18
+ # inpath source image file
19
+ # outpath destination image file
20
+ #
21
+ def build( inpath, outpath )
22
+ # TODO: ritornare un risultato per es. 1 = skipped 2 = copiato 3 = scalata immagine
23
+ result_msg = ""
24
+ img = Magick::ImageList.new(inpath)
25
+
26
+ if @width > img.columns and @height > img.rows
27
+ result_msg = "(c) "
28
+ # FileUtils.cp( inpath, outpath )
29
+ # rimuovere i metadata
30
+ else
31
+ result_msg = "(#{@quality}%) "
32
+ img.resize_to_fit!(@width, @height)
33
+ end
34
+ img = img.sepiatone
35
+ img.profile!('*', nil)
36
+
37
+ img.write(outpath) {|i| i.quality = quality }
38
+ result_msg
39
+ end
40
+
41
+ def write_xml( xml_iss )
42
+ xml_is = xml_iss.add_element( "image_strategy")
43
+ xml_is.attributes["name"] = self.class.to_s
44
+ xml_par = xml_is.add_element("par")
45
+ xml_par.attributes["width"] = @width
46
+ xml_par.attributes["height"] = @height
47
+ xml_par.attributes["quality"] = @quality
48
+ end
49
+
50
+ end
@@ -0,0 +1,83 @@
1
+ # treevisitor
2
+ require 'treevisitor/tree_node_visitor'
3
+ require 'treevisitor/dir_tree_walker'
4
+ require 'treevisitor/visitors/callback_tree_node_visitor2'
5
+
6
+ # ralbum
7
+ require 'ralbum/catalog'
8
+ require 'ralbum/photo_tree/photo_tree_item'
9
+ require 'ralbum/photo_tree/photo_tree_node'
10
+
11
+ class JalbumPhotoTreeBuilder
12
+
13
+ def run( phototree_dirname )
14
+ photoTree = build_photo_tree_from_directory( phototree_dirname )
15
+ # read_meta_info_old_format( photoTree )
16
+ # update_meta_info( photoTree )
17
+ photoTree
18
+ end
19
+
20
+ # ------------------------------------------------------------------------------
21
+ #
22
+ # build photo tree senza metainfo
23
+ #
24
+
25
+ def build_photo_tree_from_directory( jalbum_dirname )
26
+ ralbum_verbose( 1, "phototree - building phototree from #{jalbum_dirname}" )
27
+
28
+ @photo_tree_dirname = jalbum_dirname
29
+ dtw = DirTreeWalker.new( jalbum_dirname )
30
+
31
+ # TODO: ignorare tutti le directory che iniziano per "." questa deve essere un'opzione di DirTreeWalker
32
+ dtw.add_ignore_dir( ".svn" )
33
+ dtw.add_ignore_dir( ".csv" )
34
+ dtw.add_ignore_dir( ".git" )
35
+ dtw.add_ignore_dir( Catalog::DEFAULT_CATALOG_DIRNAME )
36
+
37
+ dtw.add_ignore_pattern(".jalbum")
38
+
39
+ visitor = CallbackTreeNodeVisitor2.new(self)
40
+ dtw.run( visitor ).root # return a photo_tree
41
+ end
42
+
43
+ def on_enter_tree_node(pathname, parent)
44
+ # puts "_on_enter_tree_node #{pathname}"
45
+
46
+ if parent.nil?
47
+ photo_tree_node = PhotoTreeNode.new( File.basename(pathname) , parent )
48
+ photo_tree_node.prefix_path= File.dirname( pathname ) + File::SEPARATOR
49
+ else
50
+ photo_tree_node = PhotoTreeNode.new( File.basename(pathname), parent )
51
+ end
52
+
53
+ albumfiles_path = File.join(pathname, "albumfiles.txt")
54
+ if File.exist?( albumfiles_path )
55
+ create_leaf_node_from_album_file( photo_tree_node, albumfiles_path )
56
+ end
57
+ photo_tree_node
58
+ end
59
+
60
+ def on_visit_leaf_node( src_leaf_node, parent_node )
61
+ end
62
+
63
+ def create_leaf_node_from_album_file(parent, albumfiles_path)
64
+ # puts "-----------------"
65
+ File.open(albumfiles_path).each_line do |line|
66
+ i = line.index('#')
67
+ if i
68
+ next if i == 0
69
+ line = [0..i-1].strip
70
+ end
71
+ next if line.length == 0
72
+
73
+ image_filename = line.split("\t")[1]
74
+ next if image_filename.nil?
75
+ image_filename.chomp!
76
+ # puts image_filename
77
+
78
+ PhotoTreeItem.new(image_filename, parent )
79
+ end
80
+ # puts "----------------"
81
+ end
82
+
83
+ end
@@ -0,0 +1,149 @@
1
+ class PhotoFile
2
+
3
+ attr_reader :path
4
+ attr_reader :size
5
+ attr_reader :width
6
+ attr_reader :height
7
+ attr_reader :geometry
8
+
9
+ def initialize( path )
10
+ if not File.exist?(path)
11
+ raise RAlbumException.new "file '#{path}' not exist"
12
+ end
13
+ if File.directory?(path)
14
+ raise RAlbumException.new "expected '#{path}' as file but it is a directory"
15
+ end
16
+
17
+ read_info(path)
18
+ end
19
+
20
+ def time
21
+ return @time if ! @time.nil?
22
+ @time = File.mtime( @path )
23
+ end
24
+
25
+ def md5
26
+ return @md5 if @md5
27
+ blob = File.open(path, "rb") do |f|
28
+ f.read
29
+ end
30
+ @md5 = MD5.new( blob ).to_s
31
+ # ralbum_verbose( 2, sprintf("%40s: %d %s \n", name, time, @md5 ) )
32
+ end
33
+
34
+ def to_s
35
+ s = @path + "\n"
36
+ s << sprintf("%40s: %s \n", "file size", "#{@size} Kb")
37
+ s << sprintf("%40s: %s \n", "image size", "#{@width} X #{@height}")
38
+ s << sprintf("%40s: %s \n", "timestamp", "#{@timestamp}")
39
+ s << sprintf("%40s: %s \n", "exposuretime", "#{@exposuretime} ")
40
+ s << sprintf("%40s: %s \n", "aperture", "#{@aperture}")
41
+ s << sprintf("%40s: %s \n", "exposure_bias", "#{@exposure_bias}")
42
+ s << sprintf("%40s: %s \n", "flash", "#{@flash}")
43
+ s << sprintf("%40s: %s \n", "focal_length", "#{@focal_length}")
44
+ s << sprintf("%40s: %s \n", "iso_speed","#{@iso_speed}")
45
+
46
+ s << sprintf("%40s: %s \n", "caption","#{@caption}")
47
+ s << sprintf("%40s: %s \n", "keywords","#{@keywords}")
48
+ s << sprintf("%40s: %s \n", "copyright","#{@copyright}")
49
+ s
50
+ end
51
+
52
+ private
53
+
54
+ def read_info(path)
55
+ @path = path
56
+ image = Magick::Image::read(@path).first
57
+ @width = image.columns
58
+ @height = image.rows
59
+ @geometry = "#{@width} X #{@height}"
60
+ @size = image.filesize / 1024
61
+
62
+ # exif:ExposureBiasValue
63
+
64
+ # puts " Format: #{image.format}"
65
+
66
+ # class_type = case image.class_type
67
+ # when Magick::DirectClass
68
+ # "DirectClass"
69
+ # when Magick::PseudoClass
70
+ # "PseudoClass"
71
+ # end
72
+ # puts " Class: " + class_type
73
+
74
+ # puts " Depth: #{image.depth} bits-per-pixel"
75
+ # puts " Colors: #{image.number_colors}"
76
+ # puts " Filesize: #{image.filesize}"
77
+ # puts " Resolution: #{image.x_resolution.to_i}x#{image.y_resolution.to_i} "+
78
+ # "pixels/#{image.units == Magick::PixelsPerInchResolution ?
79
+ # "inch" : "centimeter"}"
80
+
81
+ if image.properties.length > 0
82
+ # puts " Properties:"
83
+ # image.properties { |name,value|
84
+ # puts %Q| #{name} = "#{value}"|
85
+ # }
86
+
87
+
88
+ @timestamp = image.properties['exif:DateTimeOriginal']
89
+ @exposuretime = image.properties['exif:ExposureTime']
90
+ @aperture = image.properties['exif:FNumber']
91
+ @exposure_bias = ""
92
+ @flash = image.properties['exif:Flash']
93
+
94
+ # 85/1 -> 85 mm
95
+
96
+ @focal_length = image.properties['exif:FocalLength']
97
+ unless @focal_length.nil?
98
+ focal_length_split = @focal_length.split("/")
99
+ if focal_length_split.length > 2 and focal_length_split[1] == "1"
100
+ @focal_length = focal_length_split[0] + " mm"
101
+ end
102
+ end
103
+
104
+
105
+ @iso_speed = image.properties['exif:ISOSpeedRatings']
106
+ end
107
+
108
+ # # puts image.iptc_profile
109
+ # puts image.each_iptc_dataset { |dataset, data_field|
110
+ # puts "#{dataset} -> #{data_field}"
111
+ # }
112
+
113
+ @copyright = image.get_iptc_dataset(Magick::IPTC::Application::Copyright_Notice)
114
+ @keywords = image.get_iptc_dataset(Magick::IPTC::Application::Keywords)
115
+ @caption = image.get_iptc_dataset(Magick::IPTC::Application::Caption)
116
+ end
117
+
118
+ # def force_read_metainfo
119
+ # unless File.exist?(path)
120
+ # raise RAlbumException.new "photo '#{path}' not exists"
121
+ # end
122
+ # blob = File.open(path, "rb") do |f|
123
+ # f.read
124
+ # end
125
+ # @md5 = MD5.new( blob ).to_s
126
+ # ralbum_verbose( 2, sprintf("%40s: %d %s \n", name, time, @md5 ) )
127
+ #
128
+ # image = Magick::ImageList.new
129
+ # image.from_blob( blob )
130
+ # set_exif_property(image, "model", "Model")
131
+ # set_exif_property(image, "date_and_time", "DateTimeOriginal")
132
+ # set_exif_property(image, "FocalLength", "FocalLengthIn35mmFilm")
133
+ # set_exif_property(image, "exposure_time", "ExposureTime")
134
+ # set_exif_property(image, "white_balance", "WhiteBalance")
135
+ # set_exif_property(image, "iso_speed", "ISOSpeedRatings")
136
+ #
137
+ # @properties['width'] = image.columns
138
+ # @properties['height'] = image.rows
139
+ # end
140
+
141
+ # def set_exif_property(image, key_xml, key_exif )
142
+ # a = image.get_exif_by_entry(key_exif)
143
+ # if a && ( value = a[0][1] )
144
+ # @properties[key_xml] = value
145
+ # end
146
+ # end
147
+
148
+ end
149
+
@@ -0,0 +1,68 @@
1
+ # treevisitor
2
+ require 'gf_utilities/md5'
3
+ require 'treevisitor/leaf_node'
4
+
5
+ # ralbum
6
+ require 'ralbum'
7
+ require 'ralbum/options'
8
+ require 'ralbum/ralbum_exception'
9
+ require 'ralbum/photo_tree/photo_file'
10
+
11
+ #
12
+ # PhotoTreeItem contains a "photo"
13
+ # (it is different from image; only albums contains images)
14
+ #
15
+ class PhotoTreeItem < LeafNode
16
+
17
+ attr_reader :photo_file
18
+
19
+ attr_accessor :title
20
+ attr_accessor :description
21
+
22
+ def initialize( filename, photo_tree_node )
23
+ @title = nil
24
+ @description = nil
25
+
26
+ if photo_tree_node.nil?
27
+ raise RAlbumException.new("photo_tree_node cannot be nil")
28
+ end
29
+ if File.dirname( filename ) == "."
30
+ filename = File.join( photo_tree_node.path_with_prefix, filename )
31
+ end
32
+ super( filename, photo_tree_node )
33
+ @photo_file = PhotoFile.new(filename)
34
+ end
35
+
36
+ def basename
37
+ File.basename( name )
38
+ end
39
+
40
+ def to_s
41
+ if title and not title.empty?
42
+ "'#{basename}': '#{title}'"
43
+ else
44
+ "'#{basename}'"
45
+ end
46
+ end
47
+
48
+ ############################################################################
49
+ # configurations
50
+
51
+ def write_xml( xml_el )
52
+ xml_photo = xml_el.add_element( "photo" )
53
+ xml_photo.add_element("md5").text = md5
54
+ xml_photo.add_element("title").text = name
55
+ xml_photo.add_element("description").text = self["description"]
56
+ xml_photo.add_element("file_date").text = time
57
+
58
+ xml_exif = xml_photo.add_element("exif")
59
+ xml_exif.add_element("model").text = self["model"]
60
+ xml_exif.add_element("date_and_time").text = self["date_and_time"]
61
+ xml_exif.add_element("FocalLength").text = self["FocalLength"]
62
+ xml_exif.add_element("exposure_time").text = self["exposure_time"]
63
+ xml_exif.add_element("white_balance").text = self["white_balance"]
64
+ xml_exif.add_element("iso_speed").text = self["iso_speed"]
65
+ end
66
+
67
+ end
68
+