@jiDul.
Ce que j'ai raconté plus haut est *ma* solution pour un problème spécifique mais qui ressemble beaucoup à ce que vous avez décris au début. Et le but n'était même pas de produire une solution pour vous. J'ai réagi (et je continue à réagir) seulement au croyance aveugle dans la technologie autant qu'elle est neuve (ou recyclée avec un nouveau nom).
Alors, je peux maintenant proposer ma solution et essayer de la rendre « plus accessible ». Comme je ne suis pas français et me trompe à peu près continuellement dans le choix de mes mots, ceci vas soit vous rendre suicidaire ... ou tout à fait résoudre vos problèmes. Je suis incapable de le prévoir. Mais notez obligatoirement, que ma remarque en haut ne sert qu'à critiquer la recommandation d'un CMS où une
page web est demandé
e et suffit entièrement !
Longue explication.Contexte : Il y a une maison en indivision. La maison est louée fréquemment par des membres de la famille et d'autres personnes. Nous avons besoin d'un calendrier pour communiquer les vacances pour que les intéressés peuvent faire leurs réservations. Je ne peux pas exiger des autres la moindre maitrise de la technologie et n'ai pas envie de passer mon temps avec la gestion.
Idée : Les locations ou les réservations sont formulées de n'importe quel manière. Soit je les reçois par mail soit je les note moi-même, rapidement et sans besoin de respecter un format quelconque autre que celui les
dates. Cette notice, en texte brute (notepad, vim, DOS-edit.., UltraEdit, TextPad ... ) doit suffire pour remplir le calendrier.
Réalisation : Je me suis écris une page web pour l'affichage du « calendrier ». Là, où les réservations seront affichées, j'ai définis un « garde-place ». C'est actuellement le symbol «
%= » mais ceci est configurable. Pour remplir le calendrier, j'ai un script, c'est à dire une petite routine, qui lis les notices en texte brute, extrait les dates et remplis la page web, en créant une copie où le garde-place est remplacé par la liste des réservations.
C'est beaucoup plus frugal que cette explication.., j'avoue.
Alors ici le script en Ruby et un modul «
completable » qui est utilisé. Qui veut peut facilement reproduire la même chose dans d'autres languages :
- Code: Tout sélectionner
#!/usr/bin/env ruby
require 'date'
require 'logger'
require_relative 'completable'
LOG = Logger.new(STDOUT)
LOG.level = Logger::DEBUG
SOURCE = "caltemplate.html"
TARGET = "calendrier.html"
SPLT = "\t"
if ARGV && ARGV.length > 0
entries = ""
ARGV.each do |arg|
if(File.exist?(arg) && File.readable?(arg))
File.open(arg) do |fl|
lines = fl.readlines;
fields = nil
lines.each do |ln|
ln.chomp!
ln.strip!
contents = ''
if (!ln.empty?)
ln.gsub!("\n", "<br/>")
ln.gsub!('&', '&')
ln.gsub!('<', '<')
ln.gsub!('>', '>')
fields = ln.split()
LOG.debug('fields is ' << fields.to_s)
if(fields && !fields.empty? )
contents << fields.collect do |fn|
begin
rg = Regexp.new(/\d\d?\.\d\d?\.\d\d\d\d/)
dt = nil
if(rg.match(fn) )
fn.delete!(',')
dt = Date.parse(fn)
end
rescue ArgumentError,TypeError => er
LOG.warn("Field is not a date-value: " << fn)
LOG.warn er.message
end
if dt
fn = '<span class="date">' << fn << '</span>'
LOG.debug('date: ' << dt.to_s)
end
fn
end.join(' ')
end
end
if(!contents.chomp.strip.empty?)
entries << "<div class=\"cal\">%s</div>" %contents
end
end
end
# entries << "<div class=\"cal\">%s</div>" %contents
# File.open(arg, 'w') {|of| of << "<div class=\"cal\">%s</div>" %contents}
else
LOG.error('not a readable file: ' << arg)
end
end
File.open(SOURCE, 'r') do |s|
File.open(TARGET, 'w') do |t|
LOG.debug(entries)
s.extend(Completable)
s.field_delimiter = '%='
fc, msg = s.complete(:entries => entries, :cur_date => Date.today.strftime('%d %b %Y')) do |chunk|
t << chunk
end
end
end
else
LOG.error('ERROR: no arguments!')
end
- Code: Tout sélectionner
#encoding: UTF-8
=begin
/***************************************************************************
* Copyright © 2008-2014, Michael Uplawski <michael.uplawski@uplawski.eu> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
=end
# Completable file-objects can treat their
# contents like a fillable form. Predefined
# fields are searched and replaced by values.
module Completable
attr_reader :backup, :summary
# The main function of this module. Expects as parameters a Hash of
# field/substitution- pairs and an optional block. If a block is
# given, the original file will be processed and a backup is created.
def complete(subst_def, &b)
@summary = Summary.new(subst_def)
@field_count = 0
if(self.respond_to?(:gets) )
if(self.respond_to?(:closed?) && !self.closed?)
self.rewind
if(subst_def && subst_def.respond_to?(:has_key?))
LOG.debug('subst_def is ' << subst_def.to_s) if LOG
cpos = 0
if(!b)
@backup="#{self.path}_backup"
outfile = File.open(@backup, 'w'){|bf| bf.write(self.readlines() )}
self.rewind
end
while(chunk = self.gets())
chunk, msg = process(chunk, subst_def)
if(!chunk && msg)
return nil, msg
end
if(b)
b.call(chunk)
else
self.seek(cpos, IO::SEEK_SET)
self.write(chunk)
end
cpos = self.pos
end
else
return nil, 'first parameter must be a Hash'
end
else
return nil, 'completable object must at least be open for reading'
end
else
return nil, 'completable object must also respond to :gets'
end
@field_count
end
# sets the character sequence, which marks
# substitutable text
def field_delimiter=(d)
@field_delimiter = d
@field_regex = Regexp.new("#{d}[^#{d}]*#{d.reverse}")
end
# returns the character sequence, which marks
# substitutable text
def field_delimiter()
if(!@field_delimiter)
field_delimiter=(' ')
end
@field_delimiter
end
private
# processes one chunk of text with the given
# map of field/substitution pairs
def process(chunk, subst_def)
if(@field_regex)
# rpl = chunk.match(@field_regex)
fields = chunk.scan(@field_regex)
fields.each do |rpl|
if rpl
# offset = rpl.offset(0) if rpl
offset = chunk.index(rpl)
test_key = rpl.to_s.delete(@field_delimiter)
test_key = test_key.to_sym if test_key
if(subst_def.has_key?(test_key))
@summary.add_found(test_key)
value = subst_def[test_key]
chunk.gsub!(rpl.to_s, value) if value
@field_count += 1
end
end
end
chunk
else
return nil, 'field-delimiter must be set.'
end
end
# a class to summarize processing results
class Summary
attr_accessor :fields_found
def fields_missing
if(@fields_found)
@fields - @fields_found.keys
else
@fields
end
end
def initialize(fields)
if fields.respond_to?(:keys)
@fields = Array.new(fields.keys)
elsif fields.respond_to?(:to_ary)
@fields = Array.new(fields)
else
@fields = Array.new()
end
@fields_found = Hash.new
end
def add_found(field)
count = @fields_found[field]
count = 0 if !count
@fields_found[field] = count + 1
end
end
end
Modifs : Conversions Outre Rhin/Français