samizdat-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

calendar-0.1 (patch): very basic calendar


From: boud
Subject: calendar-0.1 (patch): very basic calendar
Date: Wed, 14 Feb 2007 01:44:48 +0100 (CET)

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/terms/dcq.rdf
<rdf:Property rdf:about="http://purl.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 <address@hidden>
+#   Copyright (c) 2002-2007  Dmitry Borodaenko <address@hidden>
 #
 #   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;focus=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}">
 #{title}<div class="info">#{info}</div>
 <div class="content">#{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#{html}</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#{width}#{line[:class] if line[:content].size > 0}><div 
class="content">#{MessageContent.render_cacheable(line[:content], line[:format])}#{'&nbsp;' unless 
line[:content].size > 0}</div></td>\n}
+#        %{<td#{width}#{line[:class] if line[:content].size > 0}><div 
class="content">#{MessageContent.render_cacheable(line[:content], line[:format])}#{'&nbsp;' unless 
line[:content].size > 0}</div></td>\n}
+ %{<td#{width}#{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 <address@hidden>
+#   Copyright (c) 2002-2007  Dmitry Borodaenko <address@hidden>
 #
 #   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 #{msg} ?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 + %{\n}, + 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 <address@hidden>
+#   Copyright (c) 2002-2007  Dmitry Borodaenko <address@hidden>
 #
 #   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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]