List Info

Thread: calendar-0.1 (patch): very basic calendar




calendar-0.1 (patch): very basic calendar
user name
2007-02-13 18:44:48
hi samizdat-devel,

Here is version 0.1 of a calendar patch.

DESCRIPTION:
The admin publishes a message which is intended to become
the calendar
superfocus and puts its ID in the site config file. Any
logged in member
looking at a message X sees an additional prompt _('Put this
in the
calendar') below the Add another focus prompt. S/he clicks,
chooses a
date, and submits.

If the date is valid, then a new message Y is created with a
title
corresponding to that date in %Y-%m-%d format if no such
message
already exists, message X is joined (relation created) to
that date
message (converting it into a focus), and the date message Y
is
joined (relation created) to the calendar message, which
becomes
a superfocus (if this didn't happen before).

The title + link of message X is written into date message Y
(in text/textile
format).

Displaying of the calendar superfocus is made an exception
from that
of normal focuses. The list of related resources (i.e. date
messages
like Y) are sorted by their titles (not their last modified
dates), in
increasing numerical (chronological) order starting from
"today", so
that the soonest days with events are the most obvious.
Older dates
are not displayed under the calendar superfocus, but remain
related
to it, and the messages which had been related to them
retain these
relations.

The dates are created wikified, i.e. as "open for
editing", so users
have the liberty of e.g. modifying the content of events
that
have already past.


FILES:
config.yaml - one line:  calendar:
<ID-of-calendar-message-superfocus>
template.rb - html stuff
cgi-bin/resource.rb - create foci, relations, display
calendar superfocus
message.rb  - one line - update call to   focus_fields  
method



DISCUSSION:

DEEP:
My guess is that a more elegant and in the long term more
powerful
technical solution would be to dig more deeply into the rdf
core
of samizdat , e.g. at
least link message to dates via a dublin core 
property, so that they can be more easily/systematically
communicated
around the web:
http://purl.org/dc/t
erms/dcq.rdf
<rdf:Property rdf:about="http://pu
rl.org/dc/terms/temporal">

However, what i've done seems to work and i've learn a bit
more ruby.
i'm sure some bits can be written much more compactly while
providing
equivalent functionality. Anyone feel free to propose a
better version. 

BELLS & WHISTLES:
i didn't do the "5 row 7 column" typical month -
change to day - 
change to year visual type calendar stuff, but i'm also not
totally
convinced that people are likely to use them that much. The
examples
i remember seem to be too separate from their associated cms
or wiki - 
my feeling is that by having a calendar which has
essentially the same
look and feel as the news items, people might be more likely
to use
them and integrate planning and publishing...  Of course,
i'm not against
the visual stuff, but i've spent enough time on this anyway
and IMHO
it should be enough to be useful.


Any feedback would be welcome.

cheers
boud


--- lib/samizdat/engine/template.rb	2007-01-20
12:59:03.000000000 +0100
+++ /usr/lib/ruby/1.8/samizdat/engine/template.rb	2007-02-14
00:18:11.128912464 +0100
 -1,6
+1,6 
  # Samizdat HTML templates
  #
-#   Copyright (c) 2002-2006  Dmitry Borodaenko
<angdraugdebian.org>
+#   Copyright (c) 2002-2007  Dmitry Borodaenko
<angdraugdebian.org>
  #
  #   This program is free software.
  #   You can distribute/modify this program under the terms
of
 -32,6
+32,31 
    # document navigation links (made, start, next, ...)
    attr_accessor :link

+
+  # some calendar constants
+  days_s = [ [0, _("SELECT DAY")] ]
+  for i in 1..31
+    days_s += [ [i, i.to_s] ]
+  end
+  Days_s = days_s
+
+  months_s = []
+  Months_inv = Date::MONTHS.invert
+  for i in 1..12
+#    months_s += [ [i, Months_inv[i] ] ]  # needs l10n
+    months_s += [ [i, i.to_s ] ]
+  end
+  Months_s = months_s
+
+  years_s = []
+  thisyear= Time.now.year 
+
+  for i in 0..3  # default 4 years' calendar
+    years_s += [ [thisyear+i, (thisyear+i).to_s] ]
+  end
+  Years_s = years_s
+
+
    # HTML header, title, and style settings
    #
    def head(title='', options={})
 -276,6
+301,14 
        fbox += box(nil,
          '<p><a title="'+_('Click to relate
this resource to another focus')+%{"
href="resource.rb?id=#{related.id}&amp;focus=select
">}+_('Add another focus')+'</a></p>'
        )
+      if config['calendar']
+        fbox += box(nil,
+                    '<p><a title="'+ 
+                      _('Click to put this resource in the
calendar')+
+                     
%{"href="resource.rb?id=#{related.id}&amp;focu
s=select&amp;calendar=start">}+
+                      _('Put this in the calendar')+
'</a></p>'
+                    )
+      end # if config['calendar']
      end
      fbox
    end
 -291,7
+324,18 

    # form fields for vote on focus rating
    #
-  def focus_fields(id, focus, advanced=('advanced' == session.cookie('ui')))
+  def focus_fields(id, focus, calendar,
advanced=('advanced' == session.cookie('ui')))
+    if 'start' == calendar
+    fields =
+      [ [:hidden, 'id', id],
+        [:label, 'calendar_date', _('Select the date at
which this event is planned for')],
+        [:select, 'cal_year', Years_s, Time.now.year], 
+        [:select, 'cal_month', Months_s, Time.now.month], 
+        [:select, 'cal_day', Days_s, 0],  # default day is
invalid day
+        [:hidden, 'rating', 1], 
+        [:hidden, 'calendar', 'send'],
+      ]
+    else
      focuses = Focus.collect_focuses {|f,|
        [f, Resource.new(session,
f).render(:title)]
      }
 -318,6
+362,7 
      else
        fields.push([:hidden, 'rating', 1])
      end
+    end  #end if calendar
    end

    # transform date to a standard string representation
 -498,10
+543,18 
        else
          message_content(translation, mode)
        end
+    html =
  %{<div class="message"
id="id#{message.id}">
  #<div
class="info">#</div>
  <div
class="content">#</div>
  </div>n}
+    if message.current
+      current_message_hidden =
rdf.get_property(message.current, 's::hidden')
+    end
+    if message.hidden  or  current_message_hidden
+      html = %{<div
class="message-hidden">n#</div>n}

+    end
+    html
    end

    # language selection
 -597,12
+650,21 
        left = left.join if left.kind_of? Array
        right = right.join if right.kind_of? Array
        width = right ? ' style="width: 50%"' : '
colspan="2"'
+
+      if old[:hidden] or new[:hidden]
+        div_hide = %{<div
class="message-hidden">} 
+      else
+        div_hide = "<div>" 
+      end
+
        left and left = {:format => old[:format],
:content => left,
          :class => (right ? ' class="delete"'
: '')}
        right and right = {:format => new[:format],
:content => right,
          :class => ' class="add"'}
        %{<tr>n} + [left, right].compact.collect
{|line|
-%{<td##{line[:class] if line[:content].size >
0}><div
class="content">#{MessageContent.render_cacheab
le(line[:content], line[:format])}#{'&nbsp;' unless
line[:content].size > 0}</div></td>n}
+#        %{<td##{line[:class] if
line[:content].size > 0}><div
class="content">#{MessageContent.render_cacheab
le(line[:content], line[:format])}#{'&nbsp;' unless
line[:content].size > 0}</div></td>n}
+        %{<td##{line[:class] if
line[:content].size > 0}><div
class="content">} + 
+          div_hide +
%{#{MessageContent.render_cacheable(line[:content],
line[:format])}#{'&nbsp;' unless line[:content].size
> 0}</div></div></td>n}
        }.join + "</tr>n"
      }.join + %{</tbody></table>n}
    end


--- cgi-bin/resource.rb	2007-01-08 03:10:18.000000000 +0100
+++ /usr/share/samizdat/cgi-bin/resource.rb	2007-02-14
00:28:49.116923544 +0100
 -2,7
+2,7 
  #
  # Samizdat resource display
  #
-#   Copyright (c) 2002-2006  Dmitry Borodaenko
<angdraugdebian.org>
+#   Copyright (c) 2002-2007  Dmitry Borodaenko
<angdraugdebian.org>
  #
  #   This program is free software.
  #   You can distribute/modify this program under the terms
of
 -11,6
+11,7 
  # vim: et sw=2 sts=2 ts=8 tw=0

  require 'samizdat/engine'
+#require 'date'

  # messages that are related to this focus
  #
 -31,6
+32,25 
  ORDER BY ?date DESC}, limit_page, limit_page * skip
      ).collect {|m,| m }   # unwrap DBI::Row
    end
+
+  if config['calendar'] and id.to_i == config['calendar']
+    # TODO rewrite this using .collect instead of .each
+    list_titles = []
+    today=Time.now.strftime("%Y-%m-%d") 
+    list.each do |msg|
+      m_title, = rdf.select_one %{
+SELECT ?title
+WHERE (dc::title # ?title)}
+      if m_title >= today  # ignore old events
+        list_titles += [[m_title, msg]]  # add a pair
+      end
+    end
+    list_titles.sort! { |a,b| a[0] <=> b[0] }
+
+
+    list = list_titles.collect { |pair| pair[1] }
+
+  end
    list.collect {|msg| yield msg }
  end

 -59,7
+79,7 
    end
  end

-request do |session|
+each_request do |session|

    # RewriteRule ^(/samizdat-base)/([0-9]+)$
$1/resource.rb?id=$2 [PT]
    #
 -81,26
+101,122 
    body = session.has_key?('skip')? r[:messages] : r.to_s

    # vote on focus rating
-  if session.has_key?('focus') or
session.has_key?('focus_id')
+  if session.has_key?('focus') or
session.has_key?('focus_id') or
+      (session.has_key?('calendar') and
config['calendar'])
      session.access('vote') or raise AuthError,
        sprintf(_('Your current access level (%s) does not
allow to vote'),
          _(session.role))

-    focus, focus_id, rating = session.params %w[focus
focus_id rating]
+    #    focus, focus_id, rating = session.params %w[focus
focus_id rating]
+    focus, focus_id, rating, calendar, cal_year, cal_month,
cal_day, creator, format, description = 
+      session.params %w[focus focus_id rating calendar
cal_year cal_month cal_day creator format description]
+
      focus = nil if 'select' == focus
+
+    # julian date if date is valid, otherwise set to nil
+    jd= Date::valid_civil?(cal_year.to_i, cal_month.to_i,
cal_day.to_i) 
+
+    if 'send' == calendar and config['calendar'] 
+      if jd
+        dd = cal_day.to_s
+        dd = "0" + dd  if cal_day.to_i < 10
+        mm = cal_month.to_s 
+        mm = "0" + mm if cal_month.to_i < 10 
+
+        focus_title= cal_year.to_s + "-" + mm +
"-" + dd
+
+        # find out if a message for this date already
exists
+        db.transaction do |db|
+          focus_id, = db.select_one 'SELECT id FROM
Message
+        WHERE title = ? ', focus_title
+        end
+        if focus_id
+          # do nothing
+        else
+          # calendar focus is created as open for editing
by members
+          if config['locale']['languages'][0]
+            lang= config['locale']['languages'][0]
+          else
+            lang= NULL
+          end
+ 
+          message = PublishMessage.new(session)
+
+          db.transaction do |db|
+            focus_id, = rdf.assert( %{
+INSERT ?msg
+WHERE (dc::creator ?msg :creator)
+      (dc::title ?msg :title)
+      (dc::language ?msg :language)
+      (dc::format ?msg :format)
+      (dc::description ?msg :desc)
+      (s::content ?msg :content)
+      (s::openForAll ?msg :open)
+      (s::inReplyTo ?msg :parent)
+},
+                                    { 
+                                      :creator =>
creator, 
+                                      :title =>
focus_title, 
+                                      :language =>
lang,
+                                      :format =>
'text/textile',
+                                      :desc =>
description, 
+                                      :content => ' ',
+                                      :open => true, 
+                                      :parent => nil
+                                    } )
+          end # db.transaction
+        end #     if focus_id
+
+        # add link (editing is open, so this is not
hardwiring) 
+        db.transaction do |db|
+          f_content, = db.select_one 'SELECT content FROM
Message
+          WHERE id = ? ', focus_id
+          m_title, = db.select_one 'SELECT title FROM
Message
+          WHERE id = ? ', id
+          db.do 'UPDATE Message SET content = ? 
+          WHERE id = ? ', 
+          f_content + %{n"} + m_title + %{":/} +
id.to_s + %, 
+          focus_id 
+          db.do 'UPDATE Message SET format = ? WHERE id = ?
', 
+          "text/textile", focus_id 
+        end #  db.transaction do |db|
+
+        calendar_superfocus = config['calendar']
+      else # invalid date - try again
+        calendar = 'start'
+      end
+    end  # if 'send' == calendar
+
+
      if focus_id = Resource.validate_id(focus_id)
        # manual entry overrides selection
        focus = focus_id
      end
+    focus_id = focus  # needed for Resource.new 
+#    old_id = id # needed for session.redirect
      focus = Focus.new(session, focus, resource) if focus

      if focus.kind_of?(Focus) and rating   # commit vote
        # rating is validated by Focus#rating=
        db.transaction {|db| focus.rating = rating }
-      session.redirect(id.to_s)
+
+      if Resource.validate_id(calendar_superfocus)
+        focus_r = Resource.new(session, focus_id) # focus
as Resource object
+        calendar_superfocus = Focus.new(session,
calendar_superfocus, focus_r) 
+        if calendar_superfocus.kind_of?(Focus)
+          db.transaction {|db| calendar_superfocus.rating =
rating }
+        end
+        session.redirect(focus_id.to_s) # otherwise session
may be confused
+      else
+        session.redirect(id.to_s)
+      end
+
+
+#      session.redirect(old_id.to_s)
      else   # display vote form
        vote_form = t.form( 'resource.rb',
-        *t.focus_fields(id, focus) +
+#        *t.focus_fields(id, focus) +
+        *t.focus_fields(id, focus, calendar) +
          [ [:br], [:submit, nil, _('Submit')] ]
        )
        next t.page(_('Vote') + ': ' + r[:head],


--- lib/samizdat/engine/message.rb	2007-01-20
13:02:29.000000000 +0100
+++ /usr/lib/ruby/1.8/samizdat/engine/message.rb	2007-02-11
01:40:22.000000000 +0100
 -1,6
+1,6 
  # Samizdat message handling
  #
-#   Copyright (c) 2002-2006  Dmitry Borodaenko
<angdraugdebian.org>
+#   Copyright (c) 2002-2007  Dmitry Borodaenko
<angdraugdebian.org>
  #
  #   This program is free software.
  #   You can distribute/modify this program under the terms
of
 -542,7
+544,8 
        ]

        # select focus for new message
-      form.push(*t.focus_fields(nil, nil, false)) if
+#      form.push(*t.focus_fields(nil, nil, false)) if
+      form.push(*t.focus_fields(nil, nil, false, false))
if
          session.access('vote') and parent.nil?

        # advanced parameters


--- data/samizdat/config.yaml	2006-11-28 17:57:47.000000000
+0100
+++ /etc/samizdat/sites/config.yaml	2007-02-14
00:08:16.498310056 +0100

+
+# Basic Calendar 
+#
+# First publish a message by hand which you wish to become
the
+# calendar focus. Put its ID here and then stop/start
samizdat.
+# Members should then be able to add messages to the
calendar.
+#
+# e.g. if message with ID 9999 is the calendar message
(focus), then
+# put:
+#
+# calendar: 9999



_______________________________________________
samizdat-devel mailing list
samizdat-develnongnu.org
http://lists.nongnu.org/mailman/listinfo/samizdat-devel

[1]

about | contact  Other archives ( Real Estate discussion Medical topics )