Class: Juli::Macro::Photo

Inherits:
Base
  • Object
show all
Includes:
Visitor::Html::TagHelper
Defined in:
lib/juli/macro/photo.rb

Overview

embed photo(image) in juli wiki text with minimum maintenance cost

See ‘doc/photo(macro).txt’ for the detail.

Defined Under Namespace

Classes: ConfigNoMount, DirNameConflict

Constant Summary collapse

PUBLIC_PHOTO_DIR_DEFAULT =
'public_photo'
SEED_DEFAULT =
'-- Juli seed default!! --'
CONF_DEFAULT =
{
  'storages'  => [
    {
      'kind'    => 'local',
      'dir'     => '/home/YOUR_NAME/Photos',
    },
  ],
  'small'     => {
    'width'   => 512,           # default small width in pixel
    'style'   => 'float: right'
  },
  'large'     => {
    'width'   => 1024           # default large width in pixel
  }
}

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Visitor::Html::TagHelper

#content_tag, #tag

Methods inherited from Base

#after_root, #on_root

Methods included from Util

#camelize, conf, find_template, in_filename, juli_repo, mkdir, out_filename, str_limit, str_trim, to_wikiname, underscore, usage, visitor, visitor_list

Constructor Details

#initializePhoto

Returns a new instance of Photo.



60
61
62
63
64
65
66
67
68
69
# File 'lib/juli/macro/photo.rb', line 60

def initialize
  super
  for storage in conf_photo && conf_photo['storages'] || {}
    if storage['kind'] == 'aws'
      _h = {}
      storage['params'].each{|k,v| _h[k.to_sym] = v}  # to sym
      @aws = ::Aws::S3::Client.new(_h)
    end
  end
end

Class Method Details

.conf_templateObject



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/juli/macro/photo.rb', line 37

def self.conf_template
  <<EOM
# Photo macro setup sample is as follows.
#
#photo:
# mount:        '#{CONF_DEFAULT['mount']}'    # DEPERECATED, use storages[].kind = 'local'
# storages:
# - kind:       local
#   dir:        '#{CONF_DEFAULT['mount']}'
# - kind:       aws
#   params:
#     region:   ap-northeast-1
#     profile:  juli
#   bucket:     juli
#   prefix:     photo
# small:
#   width:      #{CONF_DEFAULT['small']['width']}
#   style:      '#{CONF_DEFAULT['small']['style']}'
# large:
#   width:      #{CONF_DEFAULT['large']['width']}
EOM
end

Instance Method Details

#conf_photoObject



169
170
171
# File 'lib/juli/macro/photo.rb', line 169

def conf_photo
  @conf_photo ||= conf['photo']
end

#intern(path, size = :small, url = true) ⇒ Object

create resized, rotated, and ‘exif’ eliminated cache when:

  1. not already created, or

  2. cache is obsolete

and return the path.

source photo is looked up under the following order:

  1. local directory designated by ‘mount’ config, if defined

  2. remote storage designated by ‘storage’ config, if defined

INPUTS

path

photo-macro path argument

size

:small, or :large

url

when true, return url, else, return physical file-system path



144
145
146
147
148
149
150
151
152
153
# File 'lib/juli/macro/photo.rb', line 144

def intern(path, size = :small, url = true)
  if conf_photo['mount']
    STDERR.printf "DEPERECATED WARNING: 'mount' is deprecated; use 'storages'\n"
    result = intern_local_mount(conf_photo['mount'], path, size, url)
    return result if result != ''
  end

  result = intern_storages(path, size, url)
  return result if result != ''
end

#photo_name(path, size) ⇒ Object

simplify path to the non-directory name with size.

Example

path

a/b/c.jpg

photo_name

a_b_c_#size.jpg



114
115
116
117
118
# File 'lib/juli/macro/photo.rb', line 114

def photo_name(path, size)
  flat = path.gsub(/\//, '_')
  sprintf("%s_%s%s",
      File.basename(flat, '.*'), size, File.extname(flat))
end

#photo_path(path, size, url = true) ⇒ Object

cached photo path

INPUTS

path

photo-macro path argument

size

:small, or :large

url

when true, return url, else, return physical file-system path



126
127
128
# File 'lib/juli/macro/photo.rb', line 126

def photo_path(path, size, url = true)
  File.join(public_photo_dir(url), photo_name(path, size))
end

#public_photo_dir(url = true) ⇒ Object

public photo directory is used to:

  • store converted photo from original one

  • protect private photo in ‘mount’ directory and storage from public web access by copying (with conversion) to it on demand.

INPUTS

url

when true, return url, else, return physical file-system path

Raises:



99
100
101
102
103
104
105
106
107
# File 'lib/juli/macro/photo.rb', line 99

def public_photo_dir(url = true)
  dir = File.join(conf['output_top'], PUBLIC_PHOTO_DIR_DEFAULT)
  raise DirNameConflict if File.file?(dir)

  if !File.directory?(dir)
    FileUtils.mkdir(dir)
  end
  url ? PUBLIC_PHOTO_DIR_DEFAULT : dir
end

#rotate(img) ⇒ Object

rotate image to fit orientation



76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/juli/macro/photo.rb', line 76

def rotate(img)
  exif = img.get_exif_by_entry(:Orientation)
  return img if !(exif && exif[0] && exif[0][0] == :Orientation)
  case exif[0][1]
  when '1'  # Normal
    img
  when '6'  #  90 degree
    img.rotate(90)    # 90[deg] to clock direction
  when '8'  # 270 degree
    img.rotate(-90)   # 90[deg] to reversed-clock direction
  else
    img
  end
end

#run(*args) ⇒ Object

return <img…> HTML tag for the photo with this macro features.



156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/juli/macro/photo.rb', line 156

def run(*args)
  path      = args[0].gsub(/\.\./, '')     # sanitize '..'
  style     = conf_photo['small']['style']
  small_url = intern(path)
  large_url = intern(path, :large)
  (:a, :href=>large_url) do
    tag(:img,
        :src    => intern(path),
        :class  => 'juli_photo_small',
        :style  => style)
  end
end

#set_conf_default(conf) ⇒ Object



71
72
73
# File 'lib/juli/macro/photo.rb', line 71

def set_conf_default(conf)
  set_conf_default_sub(conf, 'photo', CONF_DEFAULT)
end