class Sgfa::Web::Binder

Binder web interface

Constants

BinderTable
DocketEach

each entry

EditAttach
EditAttachButton
EditForm
EditTag
EditTagButton
EditTagOpt
EditTagSel
EntryDisp
HistoryDisp
HistoryItem
HistoryTable
InfoTable
JacketPost
JacketsForm
JacketsRow
JacketsTable
ListPrefix
ListTable
ListTag
LogRow
LogTable
PageDiv

Page division

PageSize
PageSizeMax
TagRow
TagTable
UsersForm
UsersRow
UsersTable
ValuesForm
ValuesRow
ValuesTable

Public Instance Methods

_call(env) click to toggle source

Process the request

This is a seperate method to simplify the flow control by using return.

# File lib/sgfa/web/binder.rb, line 74
def _call(env)

  # defaults
  env['sgfa.status'] = :badreq
  env['sgfa.title'] = 'SFGA Error'
  env['sfga.navbar'] = ''
  env['sgfa.html'] = 'Invalid request'

  path = env['PATH_INFO'].split('/')
  if path.empty?
    jacket = nil
  else
    path.shift if path[0].empty?
    jacket = path.shift
  end

  # just the binder
  if !jacket
    case env['REQUEST_METHOD']
      when 'GET'; return _get_jackets(env, path)
      when 'POST'; return _post_binder(env)
      else; return
    end
  end

  # special binder pages
  if jacket[0] == '_'
    return if env['REQUEST_METHOD'] != 'GET'
    case jacket
    when '_jackets'
      return _get_jackets(env, path)
    when '_users'
      return _get_users(env, path)
    when '_values'
      return _get_values(env, path)
    when '_info'
      return _get_binder(env, path)
    else
      return
    end
  end

  # jacket info stored
  env['sgfa.jacket.url'] = jacket
  env['sgfa.jacket.name'] = _escape_un(jacket)
  cmd = path.shift

  # just the jacket
  if !cmd
    case env['REQUEST_METHOD']
      when 'GET'; return _get_tag(env, path)
      when 'POST'; return _post_jacket(env)
      else; return
    end
  end

  # jacket stuff
  return if env['REQUEST_METHOD'] != 'GET'
  case cmd
    when '_edit'; return _get_edit(env, path)
    when '_entry';  return _get_entry(env, path)
    when '_history'; return _get_history(env, path)
    when '_attach'; return _get_attach(env, path)
    when '_tag'; return _get_tag(env, path)
    when '_log'; return _get_log(env, path)
    when '_list'; return _get_list(env, path)
    when '_info'; return _get_info(env, path)
    when '_docket'; return _get_docket(env, path)
    else; return
  end

end
_disp_entry(env, ent, opts={}) click to toggle source

Display an entry

# File lib/sgfa/web/binder.rb, line 722
def _disp_entry(env, ent, opts={})

  enum = ent.entry
  rnum = ent.revision
  hnum = ent.history

  tl = ent.tags
  tags = "Tags:<br>\n"
  if tl.empty?
    tags << "none\n"
  else
    tl.sort.each do |tag|
      tags << _link_tag(env, tag, _escape_html(tag)) + "<br>\n"
    end
  end

  al = ent.attachments
  att = "Attachments:<br>\n"
  if al.empty?
    att << "none\n"
  else
    al.each do |anum, hnum, name|
      att << _link_attach(env, enum, anum, hnum, name, _escape_html(name)) +
        "<br>\n"
    end
  end
  if rnum == 1
    prev = 'previous'
  else
    prev = _link_revision(env, enum, rnum-1, 'previous')
  end
  curr = opts[:current] ? '' : _link_entry(env, enum, 'current')
  edit = _link_edit(env, enum, 'edit')
  hist = _link_history(env, hnum, hnum.to_s)
  hash = ent.hash
  hash << ('<br>Jacket: %s' % ent.jacket) if opts[:jacket]

  body = EntryDisp % [
    _escape_html(ent.title),
    _escape_html(ent.body),
    ent.time.localtime.strftime('%F %T %z'),
    rnum, prev, curr, hist, edit,
    tags,
    att,
    hash
  ]

  return body
end
_disp_jackets(env, jackets, tr) click to toggle source

Display jacket list

# File lib/sgfa/web/binder.rb, line 351
def _disp_jackets(env, jackets, tr)

  rows = ''
  jackets.each do |jnam, jinfo|
    perms = jinfo[:perms]
    ps = perms.empty? ? '-' : _escape_html(perms.join(', '))
    rows << JacketsRow % [_link_jacket(env, jnam, _escape_html(jnam)),
      _escape_html(jinfo[:title]), ps]  
  end
  html = JacketsTable % rows
  html << JacketsForm % env['SCRIPT_NAME'] if tr[:perms].include?('manage')

  return html
end
_disp_users(env, users, tr) click to toggle source

Display users

# File lib/sgfa/web/binder.rb, line 436
def _disp_users(env, users, tr)
  rows = ''
  users.each do |unam, pl|
    perms = pl.empty? ? '-' : pl.join(', ')
    rows << UsersRow % [
      _escape_html(unam), _escape_html(perms)
    ]
  end
  html = UsersTable % rows 
  html << (UsersForm % env['SCRIPT_NAME']) if tr[:perms].include?('manage')
  return html
end
_disp_values(env, values, tr) click to toggle source

Display values

# File lib/sgfa/web/binder.rb, line 491
def _disp_values(env, values, tr)
  rows = ''
  values.each do |vnam, vset|
    rows << ValuesRow % [
      _escape_html(vnam), _escape_html(vset)
    ]
  end
  html = ValuesTable % rows
  html << (ValuesForm % env['SCRIPT_NAME']) if tr[:perms].include?('manage')
  
  return html
end
_get_attach(env, path) click to toggle source

Get an attachment

# File lib/sgfa/web/binder.rb, line 946
def _get_attach(env, path)
  _navbar_jacket(env, 'Attachment')

  spec = path.shift
  return if !spec
  ma = /^(\d+)-(\d+)-(\d+)$/.match(spec)
  return if !ma
  name = path.shift
  return if !name
  return if !path.empty?
  enum, anum, hnum = ma[1,3].map{|st| st.to_i}
  name = _escape_un(name)
  
  ext = name.rpartition('.')[2]
  if ext.empty?
    mime = 'application/octet-stream'
  else
    mime = Rack::Mime.mime_type('.' + ext)
  end

  tr = _trans(env)
  file = env['sgfa.binder'].read_attach(tr, enum, anum, hnum)
 
  env['sgfa.status'] = :ok
  env['sgfa.headers'] = {
    'Content-Length' => file.size.to_s,
    'Content-Type' => mime,
    'Content-Disposition' => 'attachment',
  }
  env['sgfa.file'] = FileBody.new(file)

end
_get_binder(env, path) click to toggle source

Get binder info

# File lib/sgfa/web/binder.rb, line 379
def _get_binder(env, path)
  _navbar_binder(env, 'Binder')
  return if !path.empty?

  tr = _trans(env)
  info = env['sgfa.binder'].binder_info(tr)
  
  env['sgfa.status'] = :ok
  env['sgfa.html'] = BinderTable % [
    info[:id_hash], _escape_html(info[:id_text]),
    info[:jackets].size, info[:users].size, info[:values].size,
    _escape_html(tr[:perms].join(', '))
  ]
end
_get_docket(env, path) click to toggle source

Get a docket view

# File lib/sgfa/web/binder.rb, line 587
def _get_docket(env, path)
  _navbar_jacket(env, 'Docket')

  # tag, page, perpage
  tag = path.empty? ? Jacket::TagAll : _escape_un(path.shift)
  page = path.empty? ? 1 : path.shift.to_i
  page = 1 if page == 0
  rck = Rack::Request.new(env)
  params = rck.GET
  per = params['perpage'] ? params['perpage'].to_i : 0
  per = PageSize if( per == 0 || per > PageSizeMax )

  # get
  tr = _trans(env)
  size, ents = env['sgfa.binder'].read_tag(tr, tag, (page-1)*per, per,
    raw: true)
  html = "<div class='tagname'>Docket: %s</div>\n" % _escape_html(tag)
  if ents.size == 0
    html << 'No entries'
  else
    rows = ''
    ents.reverse_each do |item|
      if item.is_a?(Entry)
        rows << _disp_entry(env, item, jacket: false, current: true)
      else
        enum, rnum, hnum, time, title, tcnt, acnt = item
        if rnum == 1
          prev = 'previous'
        else
          prev = _link_revision(env, enum, rnum-1, 'previous')
        end
        hist = _link_history(env, hnum, hnum.to_s)
        rows << DocketEach % [
          _escape_html(title),
          time.localtime.strftime("%F %T %z"),
          rnum, prev, hist, tcnt, acnt,
        ]
      end
    end
    html << rows
  end

  link = '%s/%s/_docket/%s' % [
    env['SCRIPT_NAME'],
    env['sgfa.jacket.url'],
    _escape(tag)
  ]
  query = (per != PageSize) ? { 'perpage' => per.to_s } : nil
  pages = PageDiv % _link_pages(page, per, size, link, query)

  env['sgfa.status'] = :ok
  env['sgfa.html'] = html + pages
end
_get_edit(env, path) click to toggle source

Get edit form

# File lib/sgfa/web/binder.rb, line 1127
def _get_edit(env, path)
  _navbar_jacket(env, 'Edit')

  tr = _trans(env)

  # get entry
  if path.empty?
    enum = 0
    rnum = 0
    ent = Entry.new
    ent.title = 'Title'
    ent.body = 'Body'
    ent.time = Time.now
  else
    enum = path.shift.to_i
    return if enum == 0 || !path.empty?
    ent = env['sgfa.binder'].read_entry(tr, enum)
    rnum = ent.revision
  end

  # get tag list and prefixes
  lst = env['sgfa.binder'].read_list(tr)
  prefix = {}
  lst.each do |tag|
    idx = tag.index(':')
    next unless idx
    pre = tag[0,idx].strip
    post = tag[idx+1..-1].strip
    if prefix[pre]
      prefix[pre].push post
    else
      prefix[pre] = [post]
    end
  end

  # attachments
  atts = ''
  acnt = 0
  ent.attachments.each do |anum, hnum, name|
    atts << EditAttach % [acnt, _escape_html(name), acnt, anum, acnt, '']
    acnt += 1
  end
  atts << EditAttach % [acnt, '', acnt, 0, acnt, EditAttachButton]

  # tags
  tags = ''
  cnt = 0
  prefix.keys.sort.each do |pre|
    lst = prefix[pre]
    px = _escape_html(pre)
    opts = ''
    lst.sort.each do |post|
      ex = _escape_html(post)
      opts << EditTagOpt % [px, ex, ex]
    end
    tags << EditTagSel % [px, cnt, px, opts]
    cnt += 1
  end
  tcnt = 0
  ent.tags.sort.each do |tag|
    tags << EditTag % [tcnt, _escape_html(tag), '']
    tcnt += 1
  end
  tags << EditTag % [tcnt, '', EditTagButton]

  # the page
  html = EditForm % [
    env['SCRIPT_NAME'], env['sgfa.jacket.url'],
    _escape_html(ent.title), ent.time.localtime.strftime('%F %T %z'),
    _escape_html(ent.body), atts, tags, enum, rnum, acnt+1, tcnt+1,
    acnt, tcnt
  ]
  
  env['sgfa.status'] = :ok
  env['sgfa.html'] = html
end
_get_entry(env, path) click to toggle source

Get an entry

# File lib/sgfa/web/binder.rb, line 693
def _get_entry(env, path)
  _navbar_jacket(env, 'Entry')

  return if path.empty?
  enum = path.shift.to_i
  rnum = path.empty? ? 0 : path.shift.to_i
  return if enum == 0

  tr = _trans(env)
  ent = env['sgfa.binder'].read_entry(tr, enum, rnum)

  env['sgfa.status'] = :ok
  env['sgfa.html'] = _disp_entry(env, ent)
end
_get_history(env, path) click to toggle source

Display a history item

# File lib/sgfa/web/binder.rb, line 791
def _get_history(env, path)
  _navbar_jacket(env, 'History')

  return if path.empty?
  hnum = path.shift.to_i
  return if hnum == 0

  tr = _trans(env)
  hst = env['sgfa.binder'].read_history(tr, hnum)
  hnum = hst.history
  plnk = (hnum == 1) ? 'Previous' : _link_history(env, hnum-1, 'Previous')
  nlnk = _link_history(env, hnum+1, 'Next')

  rows = ""
  hst.entries.each do |enum, rnum, hash|
    disp = "Entry %d-%d" % [enum, rnum]
    rows << (HistoryItem % [_link_revision(env, enum, rnum, disp), hash])
  end
  hst.attachments.each do |enum, anum, hash|
    disp = "Attach %d-%d-%d" % [enum, anum, hnum]
    rows << HistoryItem %
      [_link_attach(env, enum, anum, hnum, hash + '.bin', disp), hash]
  end
  tab = HistoryTable % rows

  body = HistoryDisp % [
    hnum, tab, hst.time.localtime.strftime('%F %T %z'),
    _escape_html(hst.user), plnk, nlnk, hst.hash, hst.jacket
  ]

  env['sgfa.status'] = :ok
  env['sgfa.html'] = body
end
_get_info(env, path) click to toggle source

Get jacket info

# File lib/sgfa/web/binder.rb, line 918
def _get_info(env, path)
  _navbar_jacket(env, 'Jacket')
  return if !path.empty?
  tr = _trans(env)

  info = env['sgfa.binder'].binder_info(tr)
  hst = env['sgfa.binder'].read_history(tr, 0)
  if hst
    hmax = hst.history
    emax = hst.entry_max
    time = hst.time.localtime.strftime('%F %T %z')
  else
    hmax = 0
    emax = 0
    time = 'none'
  end

  jinf = info[:jackets][env['sgfa.jacket.name']]
  env['sgfa.status'] = :ok
  env['sgfa.html'] = InfoTable % [
    jinf[:id_text], jinf[:id_hash],
    time, hmax, emax
  ]
end
_get_jackets(env, path) click to toggle source

Get jacket list

# File lib/sgfa/web/binder.rb, line 332
def _get_jackets(env, path)
  _navbar_binder(env, 'Jackets')

  if !path.empty?
    env['sgfa.status'] = :badreq
    env['sgfa.html'] = 'Invalid URL requested'
    return
  end

  tr = _trans(env)
  info = env['sgfa.binder'].binder_info(tr)

  env['sgfa.status'] = :ok
  env['sgfa.html'] = _disp_jackets(env, info[:jackets], tr)
end
_get_list(env, path) click to toggle source

Get list of tags

# File lib/sgfa/web/binder.rb, line 839
def _get_list(env, path)
  _navbar_jacket(env, 'List')

  bnd = env['sgfa.binder']
  tr = _trans(env)
  lst = bnd.read_list(tr)

  # sort into prefixed & regular
  prefix = {}
  regular = []
  lst.each do |tag|
    idx = tag.index(':')
    if !idx
      regular.push tag
      next
    end
    pre = tag[0,idx].strip
    if prefix[pre]
      prefix[pre].push tag
    else
      prefix[pre] = [tag]
    end
  end

  # regular & prefix list
  rows = ''
  if path.empty?
    prefix.keys.sort.each do |pre|
      size = prefix[pre].size
      rows << ListPrefix % 
        [_link_prefix(env, pre, _escape_html(pre)), size]
    end
    regular.sort.each do |tag|
      size, ents = bnd.read_tag(tr, tag, 0, 0)
      rows << ListTag % [
        _link_tag(env, tag, _escape_html(tag)),
        size,
        _link_tag(env, tag, 'Tag'),
        _link_dock(env, tag, 'Docket')
      ]
    end

  # list entire prefix
  else
    pre = _escape_un(path.shift)
    return if !path.empty?
    if !prefix[pre]
      env['sgfa.status'] = :notfound
      env['sgfa.html'] = 'Tag prefix not found'
      return
    end

    prefix[pre].sort.each do |tag|
      size, ents = bnd.read_tag(tr, tag, 0, 0)
      rows << ListTag % [
        _link_tag(env, tag, _escape_html(tag)),
        size,
        _link_tag(env, tag, 'Tag'),
        _link_dock(env, tag, 'Docket')
      ]
    end
  end

  env['sgfa.status'] = :ok
  env['sgfa.html'] = ListTable % rows
end
_get_log(env, path) click to toggle source

Get the log

# File lib/sgfa/web/binder.rb, line 653
def _get_log(env, path)
  _navbar_jacket(env, 'Log')

  page = path.empty? ? 1 : path.shift.to_i
  page = 1 if page == 0
  return if !path.empty?
  rck = Rack::Request.new(env)
  params = rck.GET
  per = params['perpage'] ? params['perpage'].to_i : 0
  if per == 0 || per > PageSizeMax
    per = PageSize
  end

  tr = _trans(env)
  size, hsts = env['sgfa.binder'].read_log(tr, (page-1)*per, per)
  if hsts.size == 0
    env['sgfa.html'] = 'No history'
    env['sgfa.status'] = :notfound
  else
    rows = ''
    hsts.each do |hnum, time, user, ecnt, acnt|
      rows << LogRow % [
        hnum,
        _link_history(env, hnum, time.localtime.strftime('%F %T %z')),
        _escape_html(user),
        ecnt, acnt
      ]
    end
    link = '%s/%s/_log' % [env['SCRIPT_NAME'], env['sgfa.jacket.url']]
    query = (per != PageSize) ? { 'perpage' => per.to_s } : nil
    env['sgfa.status'] = :ok
    env['sgfa.html'] = (LogTable % rows) +
      _link_pages(page, per, size, link, query)
  end

end
_get_tag(env, path) click to toggle source

Get a tag

# File lib/sgfa/web/binder.rb, line 521
def _get_tag(env, path)
  _navbar_jacket(env, 'Tag')

  if path.empty?
    tag = '_all'
  else
    tag = _escape_un(path.shift)
  end
  page = path.empty? ? 1 : path.shift.to_i
  page = 1 if page == 0
  rck = Rack::Request.new(env)
  params = rck.GET
  per = params['perpage'] ? params['perpage'].to_i : 0
  if per == 0 || per > PageSizeMax
    per = PageSize
  end

  tr = _trans(env)
  size, ents = env['sgfa.binder'].read_tag(tr, tag, (page-1)*per, per)
  if ents.size == 0
    html = 'No entries'
  else
    rows = ''
    ents.reverse_each do |enum, rnum, hnum, time, title, tcnt, acnt|
      rows << TagRow % [
        time.localtime.strftime("%F %T %z"),
        _link_entry(env, enum, _escape_html(title)),
        acnt, tcnt,
        _link_edit(env, enum, 'edit')
      ]
    end
    html = TagTable % [_escape_html(tag), rows]
  end

  link = '%s/%s/_tag/%s' % [
    env['SCRIPT_NAME'],
    env['sgfa.jacket.url'],
    _escape(tag)
  ]
  query = (per != PageSize) ? { 'perpage' => per.to_s } : nil
  pages = PageDiv % _link_pages(page, per, size, link, query)

  env['sgfa.status'] = :ok
  env['sgfa.html'] = html + pages
end
_get_users(env, path) click to toggle source

Get users

# File lib/sgfa/web/binder.rb, line 417
def _get_users(env, path)
  _navbar_binder(env, 'Users')

  if !path.empty?
    env['sgfa.status'] = :badreq
    env['sgfa.html'] = 'Invalid URL requested'
    return
  end

  tr = _trans(env)
  info = env['sgfa.binder'].binder_info(tr)

  env['sgfa.status'] = :ok
  env['sgfa.html'] = _disp_users(env, info[:users], tr)
end
_get_values(env, path) click to toggle source

Get values

# File lib/sgfa/web/binder.rb, line 472
def _get_values(env, path)
  _navbar_binder(env, 'Values')
  
  if !path.empty?
    env['sgfa.status'] = :badreq
    env['sgfa.html'] = 'Invalid URL requested'
    return
  end

  tr = _trans(env)
  info = env['sgfa.binder'].binder_info(tr)
  
  env['sgfa.status'] = :ok
  env['sgfa.html'] = _disp_values(env, info[:values], tr)
end
_link_entry(env, enum, disp) click to toggle source

Link to display an entry

# File lib/sgfa/web/binder.rb, line 220
def _link_entry(env, enum, disp)
  "<a href='%s/%s/_entry/%d'>%s</a>" % [
    env['SCRIPT_NAME'],
    env['sgfa.jacket.url'],
    enum,
    disp
  ]
end
_navbar_binder(env, act) click to toggle source

Generate navigation bar for a binder

# File lib/sgfa/web/binder.rb, line 158
def _navbar_binder(env, act)
  env['sgfa.title'] = 'SGFA Binder %s &mdash; %s' % 
    [act, _escape_html(env['sgfa.binder.name'])]
  base = env['SCRIPT_NAME']
  txt = _navbar(env, act, NavBarBinder, base)
  if env['sgfa.cabinet.url']
    txt << "<div class='link'><a href='%s'>Cabinet</a></div>\n" %
      env['sgfa.cabinet.url']
  end
  env['sgfa.navbar'] = txt
end
_navbar_jacket(env, act) click to toggle source

Generate navbar for a jacket

# File lib/sgfa/web/binder.rb, line 185
def _navbar_jacket(env, act)
  env['sgfa.title'] = 'SGFA Jacket %s &mdash; %s : %s' % [
    act,
    _escape_html(env['sgfa.binder.name']),
    _escape_html(env['sgfa.jacket.name'])
  ]
  base = env['SCRIPT_NAME'] + '/' + env['sgfa.jacket.url']
  txt = _navbar(env, act, NavBarJacket, base)
  txt << "<div class='link'><a href='%s'>Binder</a></div>\n" %
    env['SCRIPT_NAME']
  env['sgfa.navbar'] = txt
end
_post_binder(env) click to toggle source

Handle binder post

# File lib/sgfa/web/binder.rb, line 1320
def _post_binder(env)
  _navbar_binder(env, 'Edit')

  rck = Rack::Request.new(env)
  params = rck.POST

  # stupid kludge to fix bad standards inplementation.
  # apparently browsers don't set the charset correctly so rack defaults
  # to ASCII-8BIT, and then everything dies when there's actually UTF-8
  # present.  Since modern browsers actually send UTF-8 when we ask for
  # it, just force it to UTF-8 and hope for the best.
  params.each{ |key, val| val.force_encoding('utf-8') if val.is_a?(String) }

  tr = _trans(env)
  tr[:title] = 'Test title'
  tr[:body] = 'Test description of action'

  bnd = env['sgfa.binder']

  # jacket
  if params['create']
    _navbar_binder(env, 'Jackets')
    ['jacket', 'newname', 'title', 'perms'].each do |fn|
      next if params[fn]
      raise Error::Limits, 'Bad form submission'
    end
    perms = params['perms'].split(',').map{|it| it.strip }
    title = params['title']
    newname = params['newname']
    jacket = params['jacket']
    tr[:jacket] = jacket

    info = bnd.binder_info(tr)
    oj = info[:jackets][jacket]
    if oj
      newname ||= jacket
      title = oj['title'] if title.empty?
      jck = bnd.jacket_edit(tr, newname, title, perms)
      env['sgfa.message'] = 'Jacket edited.'
    else
      jck = bnd.jacket_create(tr, title, perms)
      env['sgfa.message'] = 'Jacket created.'
    end
    env['sgfa.status'] = :ok
    env['sgfa.html'] = _disp_jackets(env, jck, tr)

  # user
  elsif params['set']
    _navbar_binder(env, 'Users')
    ['user', 'perms'].each do |fn|
      next if params[fn]
      raise Error::Limits, 'Bad form submission'
    end
    perms = params['perms'].split(',').map{|it| it.strip }
    users = bnd.binder_user(tr, params['user'], perms)
    env['sgfa.status']  = :ok
    env['sgfa.message'] = 'User edited.'
    env['sgfa.html'] = _disp_users(env, users, tr)

  # binder
  elsif params['assign']
    _navbar_binder(env, 'Values')
    ['value', 'state'].each do |fn|
      next if params[fn]
      raise Error::Limits, 'Bad form submission'
    end
    vals = { params['value'] => params['state'] }
    values = bnd.binder_values(tr, vals)
    env['sgfa.status'] = :ok
    env['sgfa.message'] = 'Values assigned.'
    env['sgfa.html'] = _disp_values(env, values, tr)

  end

end
_post_jacket(env) click to toggle source

Handle jacket post

# File lib/sgfa/web/binder.rb, line 1215
def _post_jacket(env)
  _navbar_jacket(env, 'Edit')

  rck = Rack::Request.new(env)
  params = rck.POST

  # stupid kludge to fix bad standards inplementation.
  # apparently browsers don't set the charset correctly so rack defaults
  # to ASCII-8BIT, and then everything dies when there's actually UTF-8
  # present.  Since modern browsers actually send UTF-8 when we ask for
  # it, just force it to UTF-8 and hope for the best.
  params.each{ |key, val| val.force_encoding('utf-8') if val.is_a?(String) }

  # validate fields present
  JacketPost.each do |fn|
    next if params[fn]
    raise Error::Limits, 'Bad form submission'
  end
  tagcnt = params['tagcnt'].to_i
  attcnt = params['attcnt'].to_i
  tagcnt.times do |ix|
    next if params['tag%d' % ix]
    raise Error::Limits, 'Bad form submission'
  end
  attcnt.times do |ix|
    next if params['attnumb%d' % ix]
    raise Error::Limits, 'Bad form submission'
  end
  
  # get the entry being edited
  enum = params['entry'].to_i
  rnum = params['revision'].to_i
  tr = _trans(env)
  if enum != 0
    ent = env['sgfa.binder'].read_entry(tr, enum, rnum)
  else
    ent = Entry.new
  end

  # tags
  oldt = ent.tags
  newt = []
  tagcnt.times do |ix|
    tx = 'tag%d' % ix
    if !params[tx].empty?
      newt.push params[tx]
    end
  end

  # attachments
  attcnt.times do |ix|
    anum = params['attnumb%d' % ix].to_i
    name = params['attname%d' % ix]
    file = params['attfile%d' % ix]

    # copy uploaded file
    if file && file != ''
      ftmp = env['sgfa.binder'].temp
      IO::copy_stream(file[:tempfile], ftmp)
      file[:tempfile].close!
    else
      ftmp = nil
    end

    # new file
    if anum == 0
      next if !ftmp
      name = file[:filename] if name == ''
      ent.attach(name, ftmp)
      
    # old file
    else
      ent.replace(anum, ftmp) if ftmp
      if name != ''
        ent.rename(anum, name)
      elsif ftmp
        ent.rename(anum, file[:filename])
      else
        ent.delete(anum)
      end
    end

  end

  # general
  ent.title = params['title']
  ent.body = params['body']
  begin
    time = Time.parse(params['time'])
    ent.time = time
  rescue ArgumentError
  end
  oldt.each{|tag| ent.untag(tag) if !newt.include?(tag) }
  newt.each{|tag| ent.tag(tag) if !oldt.include?(tag) }
  env['sgfa.binder'].write(tr, [ent])

  env['sgfa.status'] = :ok
  env['sgfa.message'] = 'Entry edited.'
  env['sgfa.html'] = _disp_entry(env, ent)

end
call(env) click to toggle source

Request

@param env [Hash] The Rack environment for this request, with app

specific options

@option env [String] ‘sgfa.binder.url’ URL encoded binder name @option env [String] ‘sgfa.binder.name’ The name of the binder @option env [Binder] ‘sgfa.binder’ The binder @option env [String] ‘sgfa.user’ The user name @option env [Array] ‘sgfa.groups’ Array of groups the user belongs to

# File lib/sgfa/web/binder.rb, line 38
def call(env)
  _call(env)
  return response(env)

rescue Error::Permission => exp
  env['sgfa.status'] = :deny
  env['sgfa.html'] = _escape_html(exp.message)
  return response(env)

rescue Error::Conflict => exp
  env['sgfa.status'] = :conflict
  env['sgfa.html'] = _escape_html(exp.message)
  return response(env)

rescue Error::NonExistent => exp
  env['sgfa.status'] = :notfound
  env['sgfa.html'] = _escape_html(exp.message)
  return response(env)

rescue Error::Limits => exp
  env['sgfa.status'] = :badreq
  env['sgfa.html'] = _escape_html(exp.message)
  return response(env)

rescue Error::Corrupt => exp
  env['sgfa.status'] = :servererror
  env['sgfa.html'] = _escape_html(exp.message)
  return response(env)

end