mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-01 01:09:47 +00:00
added opt-in message
git-svn-id: https://svn.fhem.de/fhem/trunk@2600 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
9321e27953
commit
59048aa80d
749
fhem/FHEM/98_notice.pm
Normal file
749
fhem/FHEM/98_notice.pm
Normal file
@ -0,0 +1,749 @@
|
||||
# $Id$
|
||||
# vim: ts=2:et
|
||||
################################################################
|
||||
#
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2013 Copyright: Martin Fischer (m_fischer at gmx dot de)
|
||||
# All rights reserved
|
||||
#
|
||||
# This file is part of fhem.
|
||||
#
|
||||
# Fhem 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 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Fhem 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 fhem. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################
|
||||
|
||||
package main;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Time::Local;
|
||||
|
||||
sub CommandNotice($$);
|
||||
sub notice_Confirmation($$$);
|
||||
sub notice_Get($$$);
|
||||
sub notice_List($$);
|
||||
sub notice_Read($$$);
|
||||
|
||||
use vars qw(@locale);
|
||||
@locale = qw(de en);
|
||||
|
||||
my $confirmationFile = ".notice-confirmation";
|
||||
|
||||
########################################
|
||||
sub
|
||||
notice_Initialize($$)
|
||||
{
|
||||
my %hash = (
|
||||
Fn => "CommandNotice",
|
||||
Hlp => "[confirm|list|reset|view] <id>,view and confirmation of system messages",
|
||||
);
|
||||
$cmds{notice} = \%hash;
|
||||
}
|
||||
|
||||
########################################
|
||||
sub
|
||||
CommandNotice($$)
|
||||
{
|
||||
my ($cl,$param) = @_;
|
||||
my $modPath = (-d "updatefhem.dir" ? "updatefhem.dir":$attr{global}{modpath});
|
||||
my $modDir = "$modPath/FHEM";
|
||||
my $noticeDir = "$modDir/FhemUtils";
|
||||
my $name = "notice";
|
||||
my @commands = qw(confirm condition get list position reset view);
|
||||
my $ret;
|
||||
|
||||
# split arguments
|
||||
my @args = split(/ +/,$param);
|
||||
|
||||
$args[0] = "list" if(!defined($args[0]));
|
||||
|
||||
if(!@args || $args[0] ~~ @commands) {
|
||||
my $cmd = $args[0];
|
||||
|
||||
if($cmd eq "list") {
|
||||
# view all a list of notes
|
||||
my $type = "all";
|
||||
if(defined($args[1])) {
|
||||
$type = $args[1];
|
||||
}
|
||||
$ret = notice_List($noticeDir,$type);
|
||||
|
||||
} elsif($cmd eq "view") {
|
||||
# view a single note
|
||||
return "notice view needs an argument"
|
||||
if(!defined($args[1]));
|
||||
|
||||
my $id = $args[1];
|
||||
my $notice_ref = {};
|
||||
$notice_ref = notice_Read($notice_ref,$noticeDir,$args[1]);
|
||||
return "Nothing to view. Maybe wrong ID?"
|
||||
if(!keys %$notice_ref);
|
||||
|
||||
my $locale = "en";
|
||||
my $header = 1;
|
||||
if(@args == 3) {
|
||||
$locale = ($args[2] ~~ @locale) ? $args[2] : "en";
|
||||
$header = ($args[2] eq "noheader") ? 0 : 1;
|
||||
} elsif(@args == 4) {
|
||||
if($args[2] ~~ @locale) {
|
||||
$locale = ($args[2] ~~ @locale) ? $args[2] : "en";
|
||||
$header = ($args[3] eq "noheader") ? 0 : 1;
|
||||
} elsif($args[2] eq "noheader") {
|
||||
$header = ($args[2] eq "noheader") ? 0 : 1;
|
||||
$locale = ($args[3] ~~ @locale) ? $args[3] : "en";
|
||||
}
|
||||
}
|
||||
|
||||
if($header) {
|
||||
$ret = sprintf("%-10s: %s\n","ID",$id);
|
||||
$ret .= sprintf("%-10s: %s\n","From",$notice_ref->{$id}{from})
|
||||
if(exists $notice_ref->{$id}{from});
|
||||
$ret .= sprintf("%-10s: %s\n","Date",$notice_ref->{$id}{date})
|
||||
if(exists $notice_ref->{$id}{from});
|
||||
$ret .= sprintf("%-10s: %s\n","Expire",$notice_ref->{$id}{expire})
|
||||
if(exists $notice_ref->{$id}{expire});
|
||||
$ret .= sprintf("%-10s: %s\n","Title",$notice_ref->{$id}{locale}{$locale}{title})
|
||||
if(exists $notice_ref->{$id}{locale}{$locale}{title});
|
||||
$ret .= "### Start of Text\n";
|
||||
}
|
||||
|
||||
foreach my $line (@{$notice_ref->{$id}{locale}{$locale}{text}}) {
|
||||
$ret .= $line."\n";
|
||||
}
|
||||
|
||||
$ret .= "### End of Text\n" if($header);
|
||||
|
||||
} elsif($cmd eq "confirm") {
|
||||
# confirm a note
|
||||
return "notice view needs an argument"
|
||||
if(!defined($args[1]));
|
||||
|
||||
my $id = $args[1];
|
||||
my $notice_ref = {};
|
||||
$notice_ref = notice_Read($notice_ref,$noticeDir,$id);
|
||||
return "Nothing to view. Maybe wrong ID?"
|
||||
if(!keys %$notice_ref);
|
||||
|
||||
if(!defined($notice_ref->{$id}{confirm}) ||
|
||||
(defined($notice_ref->{$id}{confirm}) && $notice_ref->{$id}{confirm} == 0) ) {
|
||||
return "$id needs no confirmation.";
|
||||
} else {
|
||||
my $confirmation = 1;
|
||||
if(@args > 2) {
|
||||
shift @args;
|
||||
shift @args;
|
||||
$confirmation = "@args";
|
||||
}
|
||||
$ret = notice_Confirmation($noticeDir,$id,$confirmation);
|
||||
}
|
||||
|
||||
} elsif($cmd eq "get") {
|
||||
# get list of notes
|
||||
my $type = (defined($args[1])) ? $args[1] : "all";
|
||||
my $value = (defined($args[2]) && $args[2] =~ /[0-8]/) ? $args[2] : 0;
|
||||
return notice_Get($noticeDir,$type,$value);
|
||||
|
||||
} elsif($cmd eq "position") {
|
||||
# returns position of notice
|
||||
return "notice position needs an argument"
|
||||
if(!defined($args[1]));
|
||||
|
||||
my $id = $args[1];
|
||||
my $notice_ref = {};
|
||||
$notice_ref = notice_Read($notice_ref,$noticeDir,$id);
|
||||
return (defined($notice_ref->{$id}{position})) ? $notice_ref->{$id}{position} : undef;
|
||||
} elsif($cmd eq "reset") {
|
||||
# reset all confirmations
|
||||
if(-e "$noticeDir/$confirmationFile") {
|
||||
if(defined($args[1] && lc($args[1]) eq "yes")) {
|
||||
my $cmdret = unlink "$noticeDir/$confirmationFile";
|
||||
if(!$cmdret) {
|
||||
$ret = "an error occured while deleting file '$noticeDir/$confirmationFile': $!";
|
||||
} else {
|
||||
$ret = "all confirmations deleted successfully.";
|
||||
}
|
||||
} else {
|
||||
$ret = "This command delete all confirmations.\n";
|
||||
$ret .= "If you really want to do this, call 'notice reset yes'";
|
||||
return $ret;
|
||||
}
|
||||
} else {
|
||||
$ret = "nothing to do. no confirmation exists.";
|
||||
}
|
||||
} elsif($cmd eq "condition") {
|
||||
# supplies a value of an embedded test
|
||||
return "condition view needs an argument"
|
||||
if(!defined($args[1]));
|
||||
|
||||
my $id = $args[1];
|
||||
my $notice_ref = {};
|
||||
$notice_ref = notice_Read($notice_ref,$noticeDir,$id);
|
||||
return "Nothing to view. Maybe wrong ID?"
|
||||
if(!keys %$notice_ref);
|
||||
|
||||
my %conditions;
|
||||
foreach my $key (sort %{$notice_ref->{$id}}) {
|
||||
my $order;
|
||||
if(lc($key) =~ /^key_/) {
|
||||
(undef,$order) = split("_",$key);
|
||||
if(defined($notice_ref->{$id}{"val_$order"})) {
|
||||
$conditions{$notice_ref->{$id}{$key}}{value} = ($notice_ref->{$id}{"val_$order"}) ?
|
||||
eval $notice_ref->{$id}{"val_$order"} : undef;
|
||||
$conditions{$notice_ref->{$id}{$key}}{condition} = (defined($notice_ref->{$id}{"con_$order"})) ?
|
||||
$notice_ref->{$id}{"con_$order"} : "";
|
||||
Log 5, "notice id:$id condition key:".$notice_ref->{$id}{$key} . " " .
|
||||
"value:" .$conditions{$notice_ref->{$id}{$key}}{value} . " " .
|
||||
"condition:".$notice_ref->{$id}{"val_$order"};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(keys %conditions) {
|
||||
foreach my $key (sort keys %conditions) {
|
||||
Log 5, "notice id:$id condition key:$key value:$conditions{$key}{value} condition:$conditions{$key}{condition}";
|
||||
$ret .= "$key:$conditions{$key}{value}:$conditions{$key}{condition}";
|
||||
$ret .= "|";
|
||||
}
|
||||
chop $ret;
|
||||
return $ret;
|
||||
} else {
|
||||
return undef;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
return "Unknown argument $args[0]; choose one of " . join(" ", sort @commands);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
########################################
|
||||
sub
|
||||
notice_List($$)
|
||||
{
|
||||
my ($noticeDir,$type) = @_;
|
||||
$type = ($type eq "all") ? ".*" : $type;
|
||||
my @dir;
|
||||
my $ret;
|
||||
|
||||
if(opendir(my $DH, "$noticeDir")) {
|
||||
@dir = grep { /^$type-.*\d+$/ && -f "$noticeDir/$_" } readdir($DH);
|
||||
closedir $DH;
|
||||
|
||||
my $notice_ref = {};
|
||||
foreach my $file (@dir) {
|
||||
$notice_ref = notice_Read($notice_ref,$noticeDir,$file);
|
||||
}
|
||||
|
||||
my @col1 = sort keys %{$notice_ref};
|
||||
my $col1 = (reverse sort { $a <=> $b } map { length($_) } @col1)[0];
|
||||
if(!keys %$notice_ref) {
|
||||
$ret = "==> nothing found";
|
||||
} else {
|
||||
|
||||
my @confirmationFile;
|
||||
if(open(my $FH, "<$noticeDir/$confirmationFile")) {
|
||||
Log 5, "notice read file: $noticeDir/$confirmationFile";
|
||||
while(my $line = <$FH>) {
|
||||
chomp $line;
|
||||
push(@confirmationFile,$line);
|
||||
}
|
||||
close $FH;
|
||||
}
|
||||
|
||||
foreach my $lang (sort @locale) {
|
||||
$ret .= "==> Language: $lang\n";
|
||||
$ret .= sprintf(" %-*s %-10s %-10s %-10s %s\n",$col1,"ID","Published","Expired","Confirmed","Description");
|
||||
foreach my $notice (sort keys %{$notice_ref}) {
|
||||
my ($dateTime,$oldConfirmation);
|
||||
next if(!exists $notice_ref->{$notice}{locale}{$lang});
|
||||
foreach my $line (@confirmationFile) {
|
||||
if($line =~ /^$notice\s*/) {
|
||||
($dateTime,$oldConfirmation) = $line =~ /^.*\s*(\d{4}-\d{2}-\d{2})\s\d{2}:\d{2}:\d{2}\s*(.*)$/;
|
||||
$dateTime = substr($dateTime,8,2).".".substr($dateTime,5,2).".".substr($dateTime,0,4);
|
||||
}
|
||||
}
|
||||
$ret .= sprintf(" %-*s %-10s %-10s %-10s %s\n",
|
||||
$col1,
|
||||
$notice,
|
||||
(defined($notice_ref->{$notice}{publish}) && $notice_ref->{$notice}{publish} ne "0") ?
|
||||
$notice_ref->{$notice}{publish} : "actually",
|
||||
(defined($notice_ref->{$notice}{expire}) && $notice_ref->{$notice}{expire} ne "0") ?
|
||||
$notice_ref->{$notice}{expire} : "never",
|
||||
($dateTime) ? $dateTime :
|
||||
(defined($notice_ref->{$notice}{confirm}) && $notice_ref->{$notice}{confirm} ne "0") ?
|
||||
"no" : "not needed",
|
||||
$notice_ref->{$notice}{locale}{$lang}{title});
|
||||
}
|
||||
$ret .= "\n";
|
||||
}
|
||||
chomp $ret;
|
||||
}
|
||||
|
||||
} else {
|
||||
$ret = "update could not open directory '$noticeDir': $!";
|
||||
Log 1, $ret;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
########################################
|
||||
# value: 0 = all
|
||||
# 1 = not confirmed
|
||||
# 2 = not expired
|
||||
# 3 = not confirmed, not expired
|
||||
# 4 = published
|
||||
# 5 = not confirmed, published
|
||||
# 6 = not expired, published
|
||||
# 7 = not confirmed, not expired, published
|
||||
# 8 = confirmed
|
||||
sub
|
||||
notice_Get($$$)
|
||||
{
|
||||
my ($noticeDir,$type,$value) = @_;
|
||||
$value = ($value) ? $value : 0;
|
||||
my @now = localtime();
|
||||
|
||||
my @dir;
|
||||
|
||||
if(opendir(my $DH, "$noticeDir")) {
|
||||
my $search = ($type eq "all") ? ".*" : $type;
|
||||
@dir = grep { /^$search-.*\d+$/ && -f "$noticeDir/$_" } readdir($DH);
|
||||
closedir $DH;
|
||||
} else {
|
||||
Log 1, "notice could not open directory '$noticeDir': $!";
|
||||
}
|
||||
|
||||
my @confirmed;
|
||||
if($value == 1 || $value == 3 || $value == 5 || $value == 7 || $value == 8) {
|
||||
if(open(my $FH, "<$noticeDir/$confirmationFile")) {
|
||||
Log 5, "notice read file: $noticeDir/$confirmationFile";
|
||||
while(my $line = <$FH>) {
|
||||
my ($id,undef) = split(" ",$line);
|
||||
if($type eq "all") {
|
||||
push(@confirmed,$id);
|
||||
} elsif($id =~ /^$type/) {
|
||||
push(@confirmed,$id);
|
||||
}
|
||||
}
|
||||
close $FH;
|
||||
}
|
||||
}
|
||||
|
||||
if(@dir) {
|
||||
my $notice_ref = {};
|
||||
foreach my $file (sort @dir) {
|
||||
$notice_ref = notice_Read($notice_ref,$noticeDir,$file);
|
||||
}
|
||||
|
||||
if(!keys %$notice_ref) {
|
||||
return undef;
|
||||
} else {
|
||||
|
||||
my $ret;
|
||||
if($value == 0) {
|
||||
# all
|
||||
$ret = join(",",sort @dir);
|
||||
} elsif($value == 1) {
|
||||
# not confirmed
|
||||
$ret = _notConfirmed($notice_ref,@confirmed);
|
||||
Log 5, "notice notConfirmed:$ret";
|
||||
} elsif($value == 2) {
|
||||
# not expired
|
||||
$ret = _notExpired($notice_ref,@now);
|
||||
Log 5, "notice notExpired:$ret";
|
||||
} elsif($value == 3) {
|
||||
# not confirmed, not expired
|
||||
my $notConfirmed = _notConfirmed($notice_ref,@confirmed);
|
||||
my $notExpired = _notExpired($notice_ref,@now);
|
||||
Log 5, "notice notConfirmed:$notConfirmed notExpired:$notExpired";
|
||||
my @merged;
|
||||
foreach my $id (@dir) {
|
||||
push (@merged, $id) if($notConfirmed =~ /$id/ && $notExpired =~ /$id/);
|
||||
}
|
||||
$ret = join(",",sort @merged);
|
||||
} elsif($value == 4) {
|
||||
# published
|
||||
$ret = _published($notice_ref,@now);
|
||||
Log 5, "notice published:$ret";
|
||||
} elsif($value == 5) {
|
||||
# not confirmed, published
|
||||
my $notConfirmed = _notConfirmed($notice_ref,@confirmed);
|
||||
my $published = _published($notice_ref,@now);
|
||||
Log 5, "notice notConfirmed:$notConfirmed published:$published";
|
||||
my @merged;
|
||||
foreach my $id (sort @dir) {
|
||||
push (@merged, $id) if($notConfirmed =~ /$id/ && $published =~ /$id/);
|
||||
}
|
||||
$ret = join(",",sort @merged);
|
||||
} elsif($value == 6) {
|
||||
# not expired, published
|
||||
my $notExpired = _notExpired($notice_ref,@now);
|
||||
my $published = _published($notice_ref,@now);
|
||||
Log 5, "notice notExpired:$notExpired published:$published";
|
||||
my @merged;
|
||||
foreach my $id (sort @dir) {
|
||||
push (@merged, $id) if($notExpired =~ /$id/ && $published =~ /$id/);
|
||||
}
|
||||
$ret = join(",",sort @merged);
|
||||
} elsif($value == 7) {
|
||||
# not confirmed, not expired, published
|
||||
my $notConfirmed = _notConfirmed($notice_ref,@confirmed);
|
||||
my $notExpired = _notExpired($notice_ref,@now);
|
||||
my $published = _published($notice_ref,@now);
|
||||
Log 5, "notice notConfirmed:$notConfirmed notExpired:$notExpired published:$published";
|
||||
my @merged;
|
||||
foreach my $id (sort @dir) {
|
||||
push (@merged, $id) if($notConfirmed =~ /$id/ && $notExpired =~ /$id/ && $published =~ /$id/);
|
||||
}
|
||||
$ret = join(",",sort @merged);
|
||||
} elsif($value == 8) {
|
||||
# confirmed
|
||||
$ret = join(",",sort @confirmed);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
return undef;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
########################################
|
||||
sub
|
||||
_notConfirmed($@)
|
||||
{
|
||||
my ($notice_ref,@confirmed) = @_;
|
||||
my @ret;
|
||||
foreach my $id (sort keys %{$notice_ref}) {
|
||||
push(@ret,$id)
|
||||
if(defined($notice_ref->{$id}{confirm}) &&
|
||||
$notice_ref->{$id}{confirm} != 0 && !grep (m/^$id$/,@confirmed));
|
||||
}
|
||||
return join(",",@ret);
|
||||
}
|
||||
|
||||
########################################
|
||||
sub
|
||||
_notExpired($@)
|
||||
{
|
||||
my ($notice_ref,@now) = @_;
|
||||
my @ret;
|
||||
foreach my $id (sort keys %{$notice_ref}) {
|
||||
my ($d,$m,$y);
|
||||
if(defined($notice_ref->{$id}{expire}) && $notice_ref->{$id}{expire} =~ /\d{2}.\d{2}.\d{4}/) {
|
||||
$d = substr($notice_ref->{$id}{expire},0,2);
|
||||
$m = substr($notice_ref->{$id}{expire},3,2)-1;
|
||||
$y = substr($notice_ref->{$id}{expire},6,4)-1900;
|
||||
}
|
||||
push(@ret,$id)
|
||||
if(!defined($notice_ref->{$id}{expire}) ||
|
||||
(defined($notice_ref->{$id}{expire}) && $notice_ref->{$id}{expire} !~ /\d{2}.\d{2}.\d{4}/) ||
|
||||
(defined($notice_ref->{$id}{expire}) && $notice_ref->{$id}{expire} =~ /\d{2}.\d{2}.\d{4}/ &&
|
||||
notice_epochDate($now[3],$now[4],$now[5]) <= notice_epochDate($d,$m,$y)));
|
||||
}
|
||||
return join(",",@ret);
|
||||
}
|
||||
|
||||
########################################
|
||||
sub
|
||||
_published($@)
|
||||
{
|
||||
my ($notice_ref,@now) = @_;
|
||||
my @ret;
|
||||
foreach my $id (sort keys %{$notice_ref}) {
|
||||
my ($d,$m,$y);
|
||||
if(defined($notice_ref->{$id}{publish}) && $notice_ref->{$id}{publish} =~ /\d{2}.\d{2}.\d{4}/) {
|
||||
$d = substr($notice_ref->{$id}{publish},0,2);
|
||||
$m = substr($notice_ref->{$id}{publish},3,2)-1;
|
||||
$y = substr($notice_ref->{$id}{publish},6,4)-1900;
|
||||
}
|
||||
push(@ret,$id)
|
||||
if(!defined($notice_ref->{$id}{publish}) ||
|
||||
(defined($notice_ref->{$id}{publish}) && $notice_ref->{$id}{publish} !~ /\d{2}.\d{2}.\d{4}/) ||
|
||||
(defined($notice_ref->{$id}{publish}) && $notice_ref->{$id}{publish} =~ /\d{2}.\d{2}.\d{4}/ &&
|
||||
notice_epochDate($now[3],$now[4],$now[5]) >= notice_epochDate($d,$m,$y)));
|
||||
}
|
||||
return join(",",@ret);
|
||||
}
|
||||
|
||||
########################################
|
||||
sub
|
||||
notice_epochDate($$$)
|
||||
{
|
||||
my ($day,$month,$year) = @_;
|
||||
return timelocal("0","0","0",$day,$month,$year);
|
||||
}
|
||||
|
||||
########################################
|
||||
sub
|
||||
notice_Confirmation($$$)
|
||||
{
|
||||
my ($noticeDir,$id,$confirmation) = @_;
|
||||
my @file;
|
||||
my $confirmed = 0;
|
||||
my $oldConfirmation;
|
||||
my $dateTime;
|
||||
my $now = TimeNow();
|
||||
my $ret;
|
||||
|
||||
if(open(my $FH, "<$noticeDir/$confirmationFile")) {
|
||||
Log 5, "notice read file: $noticeDir/$confirmationFile";
|
||||
while(my $line = <$FH>) {
|
||||
chomp $line;
|
||||
if($line =~ /^$id\s*/) {
|
||||
($dateTime,$oldConfirmation) = $line =~ /^.*\s*(\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})\s*(.*)$/;
|
||||
$confirmed = 1;
|
||||
}
|
||||
push(@file,$line);
|
||||
}
|
||||
close $FH;
|
||||
}
|
||||
|
||||
if($confirmed == 0) {
|
||||
push(@file,"$id $now $confirmation\n");
|
||||
}
|
||||
|
||||
if($oldConfirmation eq $confirmation) {
|
||||
$ret = "$id already confirmed on $dateTime: $oldConfirmation";
|
||||
} else {
|
||||
if(open(my $FH, ">$noticeDir/$confirmationFile")) {
|
||||
Log 5, "notice write file: $noticeDir/$confirmationFile";
|
||||
foreach my $line (sort @file) {
|
||||
if($line =~ /^$id\s*/) {
|
||||
print $FH "$id $now $confirmation\n";
|
||||
if(!$oldConfirmation) {
|
||||
$ret = "$id confirmed on $now: $confirmation";
|
||||
} else {
|
||||
$ret = "$id changed on $now: $confirmation";
|
||||
}
|
||||
Log 1, "notice $ret";
|
||||
} else {
|
||||
print $FH "$line\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ret = "error while writing file: $noticeDir/$confirmationFile: $!";
|
||||
Log 1, "notice $ret";
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
########################################
|
||||
sub
|
||||
notice_Read($$$)
|
||||
{
|
||||
my ($notice_ref,$noticeDir,$noticeFile) = @_;
|
||||
my %notice = %$notice_ref if($notice_ref && ref($notice_ref) eq "HASH");
|
||||
|
||||
if(open(my $FH, "<$noticeDir/$noticeFile")) {
|
||||
Log 5, "notice read file: $noticeDir/$noticeFile";
|
||||
my $key;
|
||||
my $value;
|
||||
my $locale;
|
||||
while(my $line = <$FH>) {
|
||||
chomp $line;
|
||||
if(uc($line) =~ /^#\s.*:.*$/ && uc($line) !~ /^#\s*NOTICE_\S{2}$/ && uc($line) !~ /^#\s*TITLE_\S{2}\s*:.*$/) {
|
||||
($key,$value) = $line =~ /^#\s*(.*)\s*:\s*(.*)$/;
|
||||
$notice{$noticeFile}{lc($key)} = $value;
|
||||
} elsif (uc($line) =~ /^#\s*TITLE_\S{2}\s*:.*$/) {
|
||||
($locale,$value) = $line =~ /^#\s*TITLE_(\S{2})\s*:\s*(.*)$/;
|
||||
$notice{$noticeFile}{locale}{lc($locale)}{title} = $value;
|
||||
} elsif (uc($line) =~ /^#\s*NOTICE_\S{2}$/) {
|
||||
($locale) = $line =~ /^#\s*NOTICE_(\S{2})$/;
|
||||
} else {
|
||||
$locale = "EN" if(!$locale);
|
||||
push @{ $notice{$noticeFile}{locale}{lc($locale)}{text} }, $line;
|
||||
}
|
||||
}
|
||||
close $FH;
|
||||
} else {
|
||||
Log 1, "update could not open notice '$noticeDir/$noticeFile': $!";
|
||||
return undef;
|
||||
}
|
||||
return \%notice;
|
||||
}
|
||||
|
||||
=pod
|
||||
=begin html
|
||||
|
||||
<a name="notice"></a>
|
||||
<h3>notice</h3>
|
||||
<ul>
|
||||
<code>notice [confirm [value]|list [<keyword>]|reset [yes]|view <id> [noheader|[de|en]]]</code><br>
|
||||
<br>
|
||||
View and confirmation of system messages.
|
||||
<br>
|
||||
<br>
|
||||
During an update or a system start from FHEM sometimes it is necessary to
|
||||
inform the user about important changes or additions. It may be necessary
|
||||
to confirm a system message by the user.
|
||||
<br>
|
||||
<br>
|
||||
By entering the command '<code>notice</code>' a list of all messages is displayed.
|
||||
Are messages available in different languages, they are ordered by language.
|
||||
<br>
|
||||
Example:
|
||||
<blockquote><code><pre>
|
||||
fhem> notice
|
||||
==> Language: de
|
||||
ID Published Expired Confirmed Description
|
||||
advice-20130128-002 actually never not needed kurze beschreibung
|
||||
update-20130128-002 31.01.2013 01.02.2013 no kurze beschreibung
|
||||
|
||||
==> Language: en
|
||||
ID Published Expired Confirmed Description
|
||||
advice-20130128-001 actually never no short description
|
||||
advice-20130128-002 actually never not needed short description
|
||||
update-20130128-001 actually never no short description
|
||||
update-20130128-002 31.01.2013 01.02.2013 no short description
|
||||
</pre></code></blockquote>
|
||||
By entering '<code>notice list <keyword></code>' the output of the list contains only
|
||||
available messages that starts with '<code><keyword></code>'.
|
||||
<br>
|
||||
Example:
|
||||
<blockquote><code><pre>
|
||||
fhem> notice list update
|
||||
==> Language: de
|
||||
ID Published Expired Confirmed Description
|
||||
update-20130128-002 31.01.2013 01.02.2013 no kurze beschreibung
|
||||
|
||||
==> Language: en
|
||||
ID Published Expired Confirmed Description
|
||||
update-20130128-001 actually never no short description
|
||||
update-20130128-002 31.01.2013 01.02.2013 no short description
|
||||
</pre></code></blockquote>
|
||||
To display a single message, enter the command '<code>notice view <id></code>' where <code>id</code>
|
||||
is the Identifier of the message. You can use the optional parameter <code>noheader</code>
|
||||
or the language codes <code>de</code> or <code>en</code> to display the message
|
||||
without the header informations or in your prefered language if available.
|
||||
<br>
|
||||
Example:
|
||||
<blockquote><code><pre>
|
||||
fhem> notice view advice-20130128-002 de
|
||||
ID : advice-20130128-002
|
||||
From : M. Fischer
|
||||
Date : 28.01.2013
|
||||
Expire : 0
|
||||
Title : kurze beschreibung
|
||||
### Start of Text
|
||||
test-advice
|
||||
|
||||
dies ist ein test
|
||||
|
||||
001
|
||||
### End of Text
|
||||
</pre></code></blockquote>
|
||||
If it is necessary to confirm a message, this is be done by entering '<code>notice confirm <id> [value]</code>'.
|
||||
The optional argument <code>value</code> will also be stored with the confirmation.
|
||||
<br>
|
||||
Example:
|
||||
<blockquote><code><pre>
|
||||
fhem> notice confirm update-20130128-001 foo:bar
|
||||
update-20130128-001 confirmed on 2013-01-29 20:58:57: foo:bar
|
||||
</pre></code></blockquote>
|
||||
Sometimes it is necessary to reset all confirmations. This is be done by entering
|
||||
'<code>notice reset</code>'.
|
||||
<br>
|
||||
Example:
|
||||
<blockquote><code><pre>
|
||||
fhem> notice reset
|
||||
This command delete all confirmations.
|
||||
If you really want to do this, call 'notice reset yes'
|
||||
</pre></code></blockquote>
|
||||
<br>
|
||||
<strong>For developers only:</strong>
|
||||
<br>
|
||||
<br>
|
||||
<code>notice [condition <id>|get <keyword> <value>|position <id>]</code><br>
|
||||
<br>
|
||||
<br>
|
||||
These arguments are normally not needed by any user.
|
||||
<br>
|
||||
<br>
|
||||
A message may optionally contains one or more code snippets. The argument <code>condition</code> supplies the determined
|
||||
value(s) of the embedded test(s) as a key:value pair. If more than one pair returned, they they are seperated by <code>|</code>.
|
||||
It is possible to define your own rules for a condition, like <code>!empty</code> or <code>>>5</code> and so on. An example
|
||||
of a condition is shown in the below example message file.
|
||||
Example:
|
||||
<blockquote><code><pre>
|
||||
fhem> notice condition update-20130127-001
|
||||
configfile:./fhem.cfg|sendStatistics:never:!empty
|
||||
</pre></code></blockquote>
|
||||
The argument <code>get</code>, followed by a <code>keyword</code> and a number from 0 to 8, returns a
|
||||
comma seperated list of message ids.
|
||||
The possible outputs are:
|
||||
<ul>
|
||||
<li><code>0 returns a list of all messages.</code></li>
|
||||
<li><code>1 returns a list of unconfirmed messages.</code></li>
|
||||
<li><code>2 returns a list of messages that are not expired.</code></li>
|
||||
<li><code>3 returns a list of messages that are not expired and unconfirmed.</code></li>
|
||||
<li><code>4 returns a list of published messages.</code></li>
|
||||
<li><code>5 returns a list of unconfirmed and published messages.</code></li>
|
||||
<li><code>6 returns a list of published messages that are not expired.</code></li>
|
||||
<li><code>7 returns a list of published, unconfirmed and not expired messages.</code></li>
|
||||
<li><code>8 returns a list of confirmed messages.</code></li>
|
||||
</ul>
|
||||
Example:
|
||||
<blockquote><code><pre>
|
||||
fhem> notice get all 2
|
||||
advice-20130128-001,advice-20130128-002,update-20130128-001,update-20130128-002
|
||||
</pre></code></blockquote>
|
||||
The argument <code>position</code> followed by an <code><id></code> returns the view position of a message if defined.
|
||||
<br>
|
||||
Example:
|
||||
<blockquote><code><pre>
|
||||
fhem> notice position update-20130128-001
|
||||
before
|
||||
</pre></code></blockquote>
|
||||
Example of a message file:
|
||||
<blockquote><code><pre>
|
||||
# FROM: M. Fischer
|
||||
# DATE: 28.01.2013
|
||||
# CONFIRM: 1
|
||||
# PUBLISH: 31.01.2013
|
||||
# EXPIRE: 01.02.2013
|
||||
# KEY_1: sendStatistics
|
||||
# VAL_1: AttrVal("global","sendStatistics",undef);
|
||||
# CON_1: !empty
|
||||
# KEY_2: configfile
|
||||
# VAL_2: AttrVal("global","configfile",undef);
|
||||
# POSITION: top
|
||||
# TITLE_DE: kurze beschreibung
|
||||
# NOTICE_DE
|
||||
Hinweis:
|
||||
|
||||
dies ist ein test
|
||||
# TITLE_EN: short description
|
||||
# NOTICE_EN
|
||||
Advice:
|
||||
|
||||
this is a test
|
||||
</pre></code></blockquote>
|
||||
The keywords '<code>FROM, DATE, CONFIRM, PUBLISH, EXPIRE, TITLE_DE, TITLE_EN, NOTICE_DE, NOTICE_EN</code>' are fixed.
|
||||
It is possible to add any key:value string to these files. Also it is possible to set only one or both keywords of
|
||||
'<code>TITLE_DE, TITLE_EN</code>' and '<code>NOTICE_DE, NOTICE_EN</code>'.
|
||||
</ul>
|
||||
|
||||
=end html
|
||||
1;
|
138
fhem/FHEM/FhemUtils/update-20130127-001
Normal file
138
fhem/FHEM/FhemUtils/update-20130127-001
Normal file
@ -0,0 +1,138 @@
|
||||
# FROM: M. Fischer
|
||||
# DATE: 27.01.2013
|
||||
# CONFIRM: 1
|
||||
# PUBLISH: 0
|
||||
# EXPIRE: 0
|
||||
# POSITION: before
|
||||
# KEY_1: sendStatistics
|
||||
# VAL_1: AttrVal("global","sendStatistics",undef);
|
||||
# CON_1: !empty
|
||||
# TITLE_DE: Das FHEM-Projekt moechte Dich um Deine Unterstuetzung bitten!
|
||||
# NOTICE_DE
|
||||
HINWEIS:
|
||||
|
||||
Das FHEM-Projekt moechte Dich um Deine Unterstuetzung bitten!
|
||||
|
||||
Im Rahmen der Aktualisierung kann FHEM Informationen ueber diese Installation
|
||||
an einen zentralen Server uebertragen. Diese Daten beinhalten Angaben ueber
|
||||
die installierte FHEM-Version, das Betriebssystem und Rechner-Architektur,
|
||||
die aktuelle Perl-Version, sowie eine Liste der zur Laufzeit definierten
|
||||
Module (inkl. der Anzahl der Definitionen je Modultyp). Weiterhin werden die
|
||||
definierten Modelltypen ermittelt.
|
||||
|
||||
Die am FHEM-Projekt beteiligten Entwickler erhalten wertvolle Informationen zu
|
||||
der Umgebung, in der FHEM installiert ist, und eine Einschaetzung, wie haeufig
|
||||
die jeweiligen Module eingesetzt werden. Dies kann Auswirkungen auf die
|
||||
Weiterentwicklung aber auch auf die zeitnahe Bereitstellung von Erweiterungen
|
||||
und Korrekturen haben.
|
||||
|
||||
Es werden keine personenbezogenen Daten uebertragen und / oder gespeichert.
|
||||
Die Daten werden nicht an Dritte weitergegeben und nicht fuer kommerzielle
|
||||
Zwecke verwendet. Sie dienen einzig als Hilfestellung zur Entwicklung und
|
||||
zur Einschaetzung der Verbreitung von FHEM.
|
||||
|
||||
Eine weiterfuehrende Beschreibung ist der Dokumentation zu dem FHEM-Befehl
|
||||
'fheminfo' sowie dem globalen Paramater 'sendStatsistics' zu entnehmen. Eine
|
||||
Uebersicht der erhobenen Informationen kann jederzeit ueber den Aufruf von
|
||||
'fheminfo' abgerufen werden.
|
||||
|
||||
Wenn Du das FHEM-Projekt unterstuetzen moechtest, solltest Du jetzt ueber das
|
||||
globale Attribut 'sendStatsistics' die automatische Uebermittlung aktivieren:
|
||||
|
||||
attr global sendStatistics onUpdate
|
||||
|
||||
Im Anschluss solltest Du die aktuelle Konfiguration speichern, um diesen
|
||||
Hinweis nicht erneut angezeigt zu bekommen. Der Updatevorgang kann dann wie
|
||||
gewohnt fortgesetzt werden.
|
||||
|
||||
Moechtest Du keine automatische Uebermittlung der Daten waehrend der
|
||||
Aktualisierung, solltest Du nun das globale Attribut 'sendStatistics' auf
|
||||
'manually' setzen:
|
||||
|
||||
attr global sendStatistics manually
|
||||
|
||||
Die Uebermittlung der Daten muss manuell ueber den Befehl 'fheminfo send'
|
||||
erfolgen.
|
||||
|
||||
Moechtest Du niemals Daten ueber die vorhandene FHEM-Installation uebermitteln,
|
||||
so muss das globale Attribut auf 'never' gesetzt werden:
|
||||
|
||||
attr global sendStatistics never
|
||||
|
||||
Ein Aufruf von 'fheminfo send' ist damit wirkungslos.
|
||||
|
||||
Die obigen Einstellungen koennen jederzeit geaendert werden. Eine Uebersicht
|
||||
der bereits von anderen Installationen uebermittelten Informationen kann ueber
|
||||
|
||||
http://fhem.de/stats/statistics.cgi
|
||||
|
||||
eingesehen werden.
|
||||
|
||||
Das FHEM-Team freut sich, wenn auch Du durch die automatische Uebermittlung
|
||||
Deiner technischen Daten zum FHEM-Projekt beitraegst.
|
||||
|
||||
Dieser Hinweistext kann erneut durch den Aufruf von 'update viewAdvice'
|
||||
angezeigt werden.
|
||||
|
||||
Vielen Dank fuer Deine Unterstuetzung!
|
||||
# TITLE_EN: The FHEM Project asks for your support!
|
||||
# NOTICE_EN
|
||||
The FHEM Project asks for your support!
|
||||
|
||||
During the update process FHEM is able to send statistical information
|
||||
regarding your installation to a central server. This may include data like
|
||||
your installed FHEM version, the operating system, Perl version, computer
|
||||
achitecture and the list of modules used during the update. Also the list of
|
||||
model types and number of definitions for each module may be collected.
|
||||
|
||||
The developers behind the FHEM project receive valuable information about the
|
||||
environment in which FHEM is installed and get an overview how often those
|
||||
modules are used. This may affect the further development of FHEM as well as
|
||||
the timely provision of extensions and corrections.
|
||||
|
||||
No personal information will be transferred or stored during this process. The
|
||||
data collected will neither be made available to a third party nor used for
|
||||
commercial purposes. The only purpose is to support further development of
|
||||
FHEM and to asses its distribution.
|
||||
|
||||
A more detailed explanation can be found in the documentation related to the
|
||||
command 'fheminfo' and the global parameter 'sendStatistics'. An overview
|
||||
about all information collected can be displayed at any time by using the
|
||||
command 'fheminfo'.
|
||||
|
||||
If you would like to support the FHEM project, you may set the global attribut
|
||||
'sendStatistics' to enable the automatic info transfer process.
|
||||
|
||||
attr global sendStatistics onUpdate
|
||||
|
||||
Thereafter you should save the current configuration to avoid this note beeing
|
||||
displayed again. The update process can be continued like before.
|
||||
|
||||
In case you do not whish an automatic transmission of the data collected
|
||||
during update, you should set the global attribute 'sendStatistics' to
|
||||
'manually':
|
||||
|
||||
attr global sendStatistics manually
|
||||
|
||||
Manual transfer of the data can then be performed by using the command
|
||||
'fheminfo send'.
|
||||
|
||||
If you never want to send information about your FHEM installation by all
|
||||
means, you need to set the global attribut 'sendStatistics' to 'never':
|
||||
|
||||
attr global sendStatistics never
|
||||
|
||||
Even the use of 'fheminfo send' will then not transfer any data.
|
||||
|
||||
All the settings mentioned above can be amended at any time. An overview of
|
||||
data sent from other installations can be obtained at
|
||||
|
||||
http://fhem.de/stats/statistics.cgi
|
||||
|
||||
The FHEM Project Team would be happy if you considered supporting the
|
||||
development of FHEM by transferring your technical data to the project.
|
||||
|
||||
This info text can be displayed again by using the command
|
||||
'update viewAdvice'.
|
||||
|
||||
Thanks a lot for your support!
|
Loading…
Reference in New Issue
Block a user