mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-15 22:26:04 +00:00
SONOS: Added new module Sonos and Sonosplayer with all dependencies
git-svn-id: https://svn.fhem.de/fhem/trunk@7244 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
95051ad7d2
commit
35ed38e313
2989
fhem/CHANGED
2989
fhem/CHANGED
File diff suppressed because it is too large
Load Diff
6668
fhem/FHEM/00_SONOS.pm
Executable file
6668
fhem/FHEM/00_SONOS.pm
Executable file
File diff suppressed because it is too large
Load Diff
1286
fhem/FHEM/21_SONOSPLAYER.pm
Executable file
1286
fhem/FHEM/21_SONOSPLAYER.pm
Executable file
File diff suppressed because it is too large
Load Diff
55
fhem/FHEM/lib/Encode/transliterate_win1251.pm
Normal file
55
fhem/FHEM/lib/Encode/transliterate_win1251.pm
Normal file
@ -0,0 +1,55 @@
|
||||
#!/usr/bin/perl -w
|
||||
$VERSION = '1.00';
|
||||
use strict;
|
||||
package Encode::transliterate_win1251;
|
||||
|
||||
my $debug;
|
||||
|
||||
# Assume that FROM are 1-char, and have no REx charclass special characters
|
||||
my $uc = "ß ÂÅÐÒÛÓÈÎÏØ Ù ÀÑÄÔÃÕÉÊËÇÜ ÖÆ ÁÍÌÝÞ × ¨Ú";
|
||||
my $ul = "YAVERTYUIOPSHSCHASDFGHJKLZ''CZHBNMEYUCHE'";
|
||||
|
||||
# titlecase and random alternative translations
|
||||
my $tc = "ß Ø Ù Æ Þ Þ Þ þ × × × ÷ ß ß ÿ ß ß ÿ Ù Ù ù ¨ ¨ ¸ ";
|
||||
my $tl = "YaShSchZhYuIUIuiuChTchTCHtchIAIaiaJAJajaTCHTchtchJOJojo";
|
||||
|
||||
# Assume that 1-char parts of TO have no REx charclass special characters
|
||||
|
||||
my $lc = "ÿ âåðòûóèîïø ù àñäôãõéêëçüöæ áíìýþ ÷ ¸ú¹";
|
||||
my $ll = "yavertyuiopshschasdfghjklz'czhbnmeyuche'N";
|
||||
|
||||
sub prepare_translation {
|
||||
my ($from, $to) = @_;
|
||||
die "Mismatch of length:\nfrom: '$from'\nto: '$to'\n" unless length($from) == length $to;
|
||||
my @from = ($from =~ /(\S\s*)/g);
|
||||
my (%hash_from, %hash_to);
|
||||
for my $chunk (@from) {
|
||||
my $chunk_to = substr($to, 0, length $chunk);
|
||||
substr($to, 0, length $chunk) = "";
|
||||
$chunk =~ s/\s+$//;
|
||||
$hash_from{$chunk} = $chunk_to;
|
||||
# Prefer earlier definition for reverse translation
|
||||
$hash_to{$chunk_to} = $chunk unless exists $hash_to{$chunk_to};
|
||||
}
|
||||
(\%hash_from, \%hash_to)
|
||||
}
|
||||
|
||||
sub make_translator {
|
||||
my ($hash) = @_;
|
||||
die unless keys %$hash;
|
||||
my @keys2 = grep length > 1, keys %$hash;
|
||||
my $keys1 = join '', grep length == 1, keys %$hash;
|
||||
my $rex = '';
|
||||
$rex .= (join('|', sort {length $b <=> length $a} @keys2) . '|')
|
||||
if @keys2;
|
||||
$rex .= "[\Q$keys1\E]" if length $keys1;
|
||||
warn "rex = '$rex'\n" if $debug;
|
||||
eval "sub {s/($rex)/\$hash->{\$1}/g}" or die;
|
||||
}
|
||||
|
||||
sub cyr_table {"$uc$lc$tc"}
|
||||
sub lat_table {"$ul$ll$tl"}
|
||||
|
||||
#my $to = make_translator( (prepare_translation("$uc$lc$tc", "$ul$ll$tl"))[0] );
|
||||
|
||||
1;
|
2939
fhem/FHEM/lib/MP3/Info.pm
Normal file
2939
fhem/FHEM/lib/MP3/Info.pm
Normal file
File diff suppressed because it is too large
Load Diff
3558
fhem/FHEM/lib/MP3/Tag.pm
Normal file
3558
fhem/FHEM/lib/MP3/Tag.pm
Normal file
File diff suppressed because it is too large
Load Diff
345
fhem/FHEM/lib/MP3/Tag/CDDB_File.pm
Normal file
345
fhem/FHEM/lib/MP3/Tag/CDDB_File.pm
Normal file
@ -0,0 +1,345 @@
|
||||
package MP3::Tag::CDDB_File;
|
||||
|
||||
use strict;
|
||||
use File::Basename;
|
||||
use File::Spec;
|
||||
use vars qw /$VERSION @ISA/;
|
||||
|
||||
$VERSION="1.00";
|
||||
@ISA = 'MP3::Tag::__hasparent';
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
MP3::Tag::CDDB_File - Module for parsing CDDB files.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $db = MP3::Tag::CDDB_File->new($filename, $track); # Name of audio file
|
||||
my $db = MP3::Tag::CDDB_File->new_from($record, $track); # Contents of CDDB
|
||||
|
||||
($title, $artist, $album, $year, $comment, $track) = $db->parse();
|
||||
|
||||
see L<MP3::Tag>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
MP3::Tag::CDDB_File is designed to be called from the MP3::Tag module.
|
||||
|
||||
It parses the content of CDDB file.
|
||||
|
||||
The file is found in the same directory as audio file; the list of possible
|
||||
file names is taken from the field C<cddb_files> if set by MP3::Tag config()
|
||||
method.
|
||||
|
||||
=over 4
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
# Constructor
|
||||
|
||||
sub new_from {
|
||||
my ($class, $data, $track) = @_;
|
||||
bless {data => [split /\n/, $data], track => $track}, $class;
|
||||
}
|
||||
|
||||
sub new_setdir {
|
||||
my $class = shift;
|
||||
my $filename = shift;
|
||||
$filename = $filename->filename if ref $filename;
|
||||
$filename = dirname($filename);
|
||||
return bless {dir => $filename}, $class; # bless to enable get_config()
|
||||
}
|
||||
|
||||
sub new_fromdir {
|
||||
my $class = shift;
|
||||
my $h = shift;
|
||||
my $dir = $h->{dir};
|
||||
my ($found, $e);
|
||||
my $l = $h->get_config('cddb_files');
|
||||
for my $file (@$l) {
|
||||
my $f = File::Spec->catdir($dir, $file);
|
||||
$found = $f, last if -r $f;
|
||||
}
|
||||
return unless $found;
|
||||
local *F;
|
||||
open F, "< $found" or die "Can't open `$found': $!";
|
||||
if ($e = $h->get_config('decode_encoding_cddb_file') and $e->[0]) {
|
||||
eval "binmode F, ':encoding($e->[0])'"; # old binmode won't compile...
|
||||
}
|
||||
my @data = <F>;
|
||||
close F or die "Error closing `$found': $!";
|
||||
bless {filename => $found, data => \@data, track => shift,
|
||||
parent => $h->{parent}}, $class;
|
||||
}
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $h = $class->new_setdir(@_);
|
||||
$class->new_fromdir($h);
|
||||
}
|
||||
|
||||
sub new_with_parent {
|
||||
my ($class, $filename, $parent) = @_;
|
||||
my $h = $class->new_setdir($filename);
|
||||
$h->{parent} = $parent;
|
||||
$class->new_fromdir($h);
|
||||
}
|
||||
|
||||
# Destructor
|
||||
|
||||
sub DESTROY {}
|
||||
|
||||
=item parse()
|
||||
|
||||
($title, $artist, $album, $year, $comment, $track) =
|
||||
$db->parse($what);
|
||||
|
||||
parse_filename() extracts information about artist, title, track number,
|
||||
album and year from the CDDB record. $what is optional; it maybe title,
|
||||
track, artist, album, year, genre or comment. If $what is defined parse() will return
|
||||
only this element.
|
||||
|
||||
Additionally, $what can take values C<artist_collection> (returns the value of
|
||||
artist in the disk-info field DTITLE, but only if author is specified in the
|
||||
track-info field TTITLE), C<title_track> (returns the title specifically from
|
||||
track-info field - the C<track> may fall back to the info from disk-info
|
||||
field), C<comment_collection> (processed EXTD comment), C<comment_track>
|
||||
(processed EXTT comment).
|
||||
|
||||
The returned year and genre is taken from DYEAR, DGENRE, EXTT, EXTD fields;
|
||||
recognized prefixes in the two last fields are YEAR, ID3Y, ID3G.
|
||||
The declarations of this form are stripped from the returned comment.
|
||||
|
||||
An alternative
|
||||
syntax "Recorded"/"Recorded on"/"Recorded in"/ is also supported; the format
|
||||
of the date recognized by ID3v2::year(), or just a date field without a prefix.
|
||||
|
||||
=cut
|
||||
|
||||
sub return_parsed {
|
||||
my ($self,$what) = @_;
|
||||
if (defined $what) {
|
||||
return $self->{parsed}{a_in_title} if $what =~/^artist_collection/i;
|
||||
return $self->{parsed}{t_in_track} if $what =~/^title_track/i;
|
||||
return $self->{parsed}{extt} if $what =~/^comment_track/i;
|
||||
return $self->{parsed}{extd} if $what =~/^comment_collection/i;
|
||||
return $self->{parsed}{DISCID} if $what =~/^cddb_id/i;
|
||||
return $self->{parsed}{album} if $what =~/^al/i;
|
||||
return $self->{parsed}{artist} if $what =~/^a/i;
|
||||
return $self->{parsed}{track} if $what =~/^tr/i;
|
||||
return $self->{parsed}{year} if $what =~/^y/i;
|
||||
return $self->{parsed}{comment}if $what =~/^c/i;
|
||||
return $self->{parsed}{genre} if $what =~/^g/i;
|
||||
return $self->{parsed}{title};
|
||||
}
|
||||
|
||||
return $self->{parsed} unless wantarray;
|
||||
return map $self->{parsed}{$_} , qw(title artist album year comment track);
|
||||
}
|
||||
|
||||
my %r = ( 'n' => "\n", 't' => "\t", '\\' => "\\" );
|
||||
|
||||
sub parse_lines {
|
||||
my ($self) = @_;
|
||||
return if $self->{fields};
|
||||
for my $l (@{$self->{data}}) {
|
||||
next unless $l =~ /^\s*(\w+)\s*=(\s*(.*))/;
|
||||
my $app = $2;
|
||||
$self->{fields}{$1} = "", $app = $3 unless exists $self->{fields}{$1};
|
||||
$self->{fields}{$1} .= $app;
|
||||
$self->{last} = $1 if $1 =~ /\d+$/;
|
||||
}
|
||||
s/\\([nt\\])/$r{$1}/g for values %{$self->{fields}};
|
||||
}
|
||||
|
||||
sub parse {
|
||||
my ($self,$what) = @_;
|
||||
return $self->return_parsed($what) if exists $self->{parsed};
|
||||
$self->parse_lines;
|
||||
my %parsed;
|
||||
my ($t1, $c1, $t2, $c2) = map $self->{fields}{$_}, qw(DTITLE EXTD);
|
||||
my $track = $self->track;
|
||||
if ($track) {
|
||||
my $t = $track - 1;
|
||||
($t2, $c2) = map $self->{fields}{$_}, "TTITLE$t", "EXTT$t";
|
||||
}
|
||||
my ($a, $t, $aa, $tt, $a_in_title, $t_in_track);
|
||||
($a, $t) = split /\s+\/\s+/, $t1, 2 if defined $t1;
|
||||
($a, $t) = ($t, $a) unless defined $t;
|
||||
($aa, $tt) = split /\s+\/\s+/, $t2, 2 if defined $t2;
|
||||
($aa, $tt) = ($tt, $aa) unless defined $tt;
|
||||
undef $a if defined $a and $a =~
|
||||
/^\s*(<<\s*)?(Various Artists|compilation disc)\s*(>>\s*)?$/i;
|
||||
undef $aa if defined $aa and $aa =~
|
||||
/^\s*(<<\s*)?(Various Artists|compilation disc)\s*(>>\s*)?$/i;
|
||||
$a_in_title = $a if defined $a and length $a and defined $aa and length $aa;
|
||||
$aa = $a unless defined $aa and length $aa;
|
||||
$t_in_track = $tt;
|
||||
$tt = $t unless defined $tt and length $tt;
|
||||
|
||||
my ($y, $cat) = ($self->{fields}{DYEAR}, $self->{fields}{DGENRE});
|
||||
for my $f ($c2, $c1) {
|
||||
if (defined $f and length $f) { # Process old style declarations
|
||||
while ($f =~ s/^\s*((YEAR|ID3Y)|ID3G)\b:?\s*(\d+)\b\s*(([;.,]|\s-\s)\s*)?//i
|
||||
|| $f =~ s/(?:\s*(?:[;.,]|\s-\s))?\s*\b((YEAR|ID3Y)|ID3G)\b:?\s*(\d+)\s*([;.,]\s*)?$//i) {
|
||||
$y = $3 if $2 and not $y;
|
||||
$cat = $3 if not $2 and not $cat;
|
||||
}
|
||||
if ($f =~ s{
|
||||
((^|[;,.]|\s+-\s) # 1,2
|
||||
\s*
|
||||
(Recorded (\s+[io]n)? \s* (:\s*)? )? # 3, 4, 5
|
||||
(\d{4}([-,][-\d\/,]+)?) # 6, 7
|
||||
\b \s* (?: [.;] \s* )?
|
||||
((?:[;.,]|\s-\s|$)\s*)) # 8
|
||||
}
|
||||
{
|
||||
((($self->{parent}->get_config('comment_remove_date'))->[0]
|
||||
and not ($2 and $8))
|
||||
? '' : $1) . ($2 && $8 ? $8 : '')
|
||||
}xeim and not ($2 and $8)) {
|
||||
# Overwrite the disk year for longer forms
|
||||
$y = $6 if $3 or $7 or not $y or $c2 and $f eq $c2;
|
||||
}
|
||||
$f =~ s/^\s+//;
|
||||
$f =~ s/\s+$//;
|
||||
undef $f unless length $f;
|
||||
}
|
||||
}
|
||||
my ($cc1, $cc2) = ($c1, $c2);
|
||||
if (defined $c2 and length $c2) { # Merge unless one is truncation of another
|
||||
if ( defined $c1 and length $c1
|
||||
and $c1 ne substr $c2, 0, length $c1
|
||||
and $c1 ne substr $c2, -length $c1 ) {
|
||||
$c2 =~ s/\s*[.,:;]$//;
|
||||
my $sep = (("$c1$c2" =~ /\n/) ? "\n" : '; ');
|
||||
$c1 = "$c2$sep$c1";
|
||||
} else {
|
||||
$c1 = $c2;
|
||||
}
|
||||
}
|
||||
if (defined $cat and $cat =~ /^\d+$/) {
|
||||
require MP3::Tag::ID3v1;
|
||||
$cat = $MP3::Tag::ID3v1::winamp_genres[$cat] if $cat < scalar @MP3::Tag::ID3v1::winamp_genres;
|
||||
}
|
||||
|
||||
@parsed{ qw( title artist album year comment track genre
|
||||
a_in_title t_in_track extt extd) } =
|
||||
($tt, $aa, $t, $y, $c1, $track, $cat, $a_in_title, $t_in_track, $cc2, $cc1);
|
||||
$parsed{DISCID} = $self->{fields}{DISCID};
|
||||
$self->{parsed} = \%parsed;
|
||||
$self->return_parsed($what);
|
||||
}
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=item title()
|
||||
|
||||
$title = $db->title();
|
||||
|
||||
Returns the title, obtained from the C<'Tracktitle'> entry of the file.
|
||||
|
||||
=cut
|
||||
|
||||
*song = \&title;
|
||||
|
||||
sub title {
|
||||
return shift->parse("title");
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item artist()
|
||||
|
||||
$artist = $db->artist();
|
||||
|
||||
Returns the artist name, obtained from the C<'Performer'> or
|
||||
C<'Albumperformer'> entries (the first which is present) of the file.
|
||||
|
||||
=cut
|
||||
|
||||
sub artist {
|
||||
return shift->parse("artist");
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item track()
|
||||
|
||||
$track = $db->track();
|
||||
|
||||
Returns the track number, stored during object creation, or queried from
|
||||
the parent.
|
||||
|
||||
|
||||
=cut
|
||||
|
||||
sub track {
|
||||
my $self = shift;
|
||||
return $self->{track} if defined $self->{track};
|
||||
return if $self->{recursive} or not $self->parent_ok;
|
||||
local $self->{recursive} = 1;
|
||||
return $self->{parent}->track1;
|
||||
}
|
||||
|
||||
=item year()
|
||||
|
||||
$year = $db->year();
|
||||
|
||||
Returns the year, obtained from the C<'Year'> entry of the file. (Often
|
||||
not present.)
|
||||
|
||||
=cut
|
||||
|
||||
sub year {
|
||||
return shift->parse("year");
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item album()
|
||||
|
||||
$album = $db->album();
|
||||
|
||||
Returns the album name, obtained from the C<'Albumtitle'> entry of the file.
|
||||
|
||||
=cut
|
||||
|
||||
sub album {
|
||||
return shift->parse("album");
|
||||
}
|
||||
|
||||
=item comment()
|
||||
|
||||
$comment = $db->comment();
|
||||
|
||||
Returns the C<'Trackcomment'> entry of the file. (Often not present.)
|
||||
|
||||
=cut
|
||||
|
||||
sub comment {
|
||||
return shift->parse("comment");
|
||||
}
|
||||
|
||||
=item genre()
|
||||
|
||||
$genre = $db->genre($filename);
|
||||
|
||||
=cut
|
||||
|
||||
sub genre {
|
||||
return shift->parse("genre");
|
||||
}
|
||||
|
||||
for my $elt ( qw( cddb_id ) ) {
|
||||
no strict 'refs';
|
||||
*$elt = sub (;$) {
|
||||
return shift->parse($elt);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
310
fhem/FHEM/lib/MP3/Tag/Cue.pm
Normal file
310
fhem/FHEM/lib/MP3/Tag/Cue.pm
Normal file
@ -0,0 +1,310 @@
|
||||
package MP3::Tag::Cue;
|
||||
|
||||
use strict;
|
||||
use File::Basename;
|
||||
#use File::Spec;
|
||||
use vars qw /$VERSION @ISA/;
|
||||
|
||||
$VERSION="1.00";
|
||||
@ISA = 'MP3::Tag::__hasparent';
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
MP3::Tag::Cue - Module for parsing F<.cue> files.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $db = MP3::Tag::Cue->new($filename, $track); # Name of audio file
|
||||
my $db = MP3::Tag::Cue->new_from($record, $track); # Contents of .cue file
|
||||
|
||||
($title, $artist, $album, $year, $comment, $track) = $db->parse();
|
||||
|
||||
see L<MP3::Tag>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
MP3::Tag::Cue is designed to be called from the MP3::Tag module.
|
||||
|
||||
It parses the content of a F<.cue> file.
|
||||
|
||||
The F<.cue> file is looked for in the same directory as audio file; one of the
|
||||
following conditions must be satisfied:
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
The "audio" file is specified is actually a F<.cue> file;
|
||||
|
||||
=item *
|
||||
|
||||
There is exactly one F<.cue> file in the directory of audio file;
|
||||
|
||||
=item *
|
||||
|
||||
There is exactly one F<.cue> file in the directory of audio file
|
||||
with basename which is a beginning of the name of audio file.
|
||||
|
||||
=item *
|
||||
|
||||
There is exactly one F<.cue> file in the directory of audio file
|
||||
with basename which matches (case-insensitive) a beginning of the
|
||||
name of audio file.
|
||||
|
||||
=back
|
||||
|
||||
If no F<.cue> file is found in the directory of audio file, the same process
|
||||
is repeated once one directory uplevel, with the name of the file's directory
|
||||
used instead of the file name. E.g., with the files like this
|
||||
|
||||
Foo/bar.cue
|
||||
Foo/bar/04.wav
|
||||
|
||||
audio file F<Foo/bar/04.wav> will be associated with F<Foo/bar.cue>.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
# Constructor
|
||||
|
||||
sub new_from {
|
||||
my ($class, $data, $track) = @_;
|
||||
bless {data => [split /\n/, $data], track => $track}, $class;
|
||||
}
|
||||
|
||||
sub matches($$$) {
|
||||
my ($f1, $f, $case) = (shift, shift, shift);
|
||||
substr($f1, -4, 4) = '';
|
||||
return $f1 eq substr $f, 0, length $f1 if $case;
|
||||
return lc $f1 eq lc substr $f, 0, length $f1;
|
||||
}
|
||||
|
||||
sub find_cue ($$) {
|
||||
my ($f, $d, %seen) = (shift, shift);
|
||||
require File::Glob; # "usual" glob() fails on spaces...
|
||||
my @cue = (File::Glob::bsd_glob("$d/*.cue"), File::Glob::bsd_glob('$d/*.CUE'));
|
||||
@seen{@cue} = (1) x @cue; # remove duplicates:
|
||||
@cue = keys %seen;
|
||||
my $c = @cue;
|
||||
@cue = grep matches($_, $f, 0), @cue if @cue > 1;
|
||||
@cue = grep matches($_, $f, 1), @cue if @cue > 1;
|
||||
($c, @cue)
|
||||
}
|
||||
|
||||
sub new_with_parent {
|
||||
my ($class, $f, $p, $e, %seen, @cue) = (shift, shift, shift);
|
||||
$f = $f->filename if ref $f;
|
||||
$f = MP3::Tag->rel2abs($f);
|
||||
if ($f =~ /\.cue$/i and -f $f) {
|
||||
@cue = $f;
|
||||
} else {
|
||||
my $d = dirname($f);
|
||||
(my $c, @cue) = find_cue($f, $d);
|
||||
unless ($c) {
|
||||
my $d1 = dirname($d);
|
||||
(my $c, @cue) = find_cue($d, $d1);
|
||||
}
|
||||
}
|
||||
return unless @cue == 1;
|
||||
local *F;
|
||||
open F, "< $cue[0]" or die "Can't open `$cue[0]': $!";
|
||||
if ($e = ($p or 'MP3::Tag')->get_config1('decode_encoding_cue_file')) {
|
||||
eval "binmode F, ':encoding($e->[0])'"; # old binmode won't compile...
|
||||
}
|
||||
my @data = <F>;
|
||||
close F or die "Error closing `$cue[0]': $!";
|
||||
bless {filename => $cue[0], data => \@data, track => shift,
|
||||
parent => $p}, $class;
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, $f) = (shift, shift);
|
||||
$class->new_with_parent($f, undef, @_);
|
||||
}
|
||||
|
||||
# Destructor
|
||||
|
||||
sub DESTROY {}
|
||||
|
||||
=over 4
|
||||
|
||||
=item parse()
|
||||
|
||||
($title, $artist, $album, $year, $comment, $track) =
|
||||
$db->parse($what);
|
||||
|
||||
parse_filename() extracts information about artist, title, track number,
|
||||
album and year from the F<.cue> file. $what is optional; it maybe title,
|
||||
track, artist, album, year, genre or comment. If $what is defined parse() will return
|
||||
only this element.
|
||||
|
||||
Additionally, $what can take values C<artist_collection> (returns the value of
|
||||
artist in the whole-disk-info field C<PERFORMER>, C<songwriter>.
|
||||
|
||||
=cut
|
||||
|
||||
sub return_parsed {
|
||||
my ($self,$what) = @_;
|
||||
if (defined $what) {
|
||||
return $self->{parsed}{collection_performer} if $what =~/^artist_collection/i;
|
||||
return $self->{parsed}{album} if $what =~/^al/i;
|
||||
return $self->{parsed}{performer} if $what =~/^a/i;
|
||||
return $self->{parsed}{songwriter} if $what =~/^songwriter/i;
|
||||
return $self->{parsed}{track} if $what =~/^tr/i;
|
||||
return $self->{parsed}{date} if $what =~/^y/i;
|
||||
return $self->{parsed}{comment}if $what =~/^c/i;
|
||||
return $self->{parsed}{genre} if $what =~/^g/i;
|
||||
return $self->{parsed}{title};
|
||||
}
|
||||
|
||||
return $self->{parsed} unless wantarray;
|
||||
return map $self->{parsed}{$_} , qw(title artist album year comment track);
|
||||
}
|
||||
|
||||
my %r = ( 'n' => "\n", 't' => "\t", '\\' => "\\" );
|
||||
|
||||
sub parse_lines {
|
||||
my ($self) = @_;
|
||||
# return if $self->{fields};
|
||||
my $track_seen = '';
|
||||
my $track = $self->track;
|
||||
$track = -1e100 unless $track or length $track;
|
||||
for my $l (@{$self->{data}}) {
|
||||
# http://digitalx.org/cuesheetsyntax.php
|
||||
# http://wiki.hydrogenaudio.org/index.php?title=Cuesheet
|
||||
# What about http://cue2toc.sourceforge.net/ ? Can it deal with .toc of cdrecord?
|
||||
# http://www.willwap.co.uk/Programs/vbrfix.php - may inspect gap info???
|
||||
next unless $l =~ /^\s*(REM\s+)?
|
||||
(GENRE|DATE|DISCID|COMMENT|PERFORMER|TITLE
|
||||
|ISRC|POSTGAP|PREGAP|SONGWRITER
|
||||
|FILE|INDEX|TRACK|CATALOG|CDTEXTFILE|FLAGS)\s+(.*)/x;
|
||||
my $field = lc $2;
|
||||
my $val = $3;
|
||||
$val =~ s/^\"(.*)\"/$1/; # Ignore trailing fields after TRACK, FILE
|
||||
$track_seen = $1 if $field eq 'track' and $val =~ /^0?(\d+)/;
|
||||
next if length $track_seen and $track_seen != $track;
|
||||
|
||||
$self->{fields}{$field} = $val; # unless exists $self->{fields}{$field};
|
||||
next if length $track_seen;
|
||||
$self->{fields}{album} = $val if $field eq 'title';
|
||||
$self->{fields}{collection_performer} = $val if $field eq 'performer';
|
||||
}
|
||||
}
|
||||
|
||||
sub parse {
|
||||
my ($self,$what) = @_;
|
||||
return $self->return_parsed($what) if exists $self->{parsed};
|
||||
$self->parse_lines;
|
||||
$self->{parsed} = { %{$self->{fields}} }; # Make a copy
|
||||
$self->return_parsed($what);
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item title()
|
||||
|
||||
$title = $db->title();
|
||||
|
||||
Returns the title, obtained from the C<'Tracktitle'> entry of the file.
|
||||
|
||||
=cut
|
||||
|
||||
# *song = \&title;
|
||||
|
||||
sub title {
|
||||
return shift->parse("title");
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item artist()
|
||||
|
||||
$artist = $db->artist();
|
||||
|
||||
Returns the artist name, obtained from the C<'Performer'> or
|
||||
C<'Albumperformer'> entries (the first which is present) of the file.
|
||||
|
||||
=cut
|
||||
|
||||
sub artist {
|
||||
return shift->parse("artist");
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item track()
|
||||
|
||||
$track = $db->track();
|
||||
|
||||
Returns the track number, stored during object creation, or queried from
|
||||
the parent.
|
||||
|
||||
=cut
|
||||
|
||||
sub track {
|
||||
my $self = shift;
|
||||
return $self->{track} if defined $self->{track};
|
||||
return if $self->{recursive} or not $self->parent_ok;
|
||||
local $self->{recursive} = 1;
|
||||
return $self->{parent}->track1;
|
||||
}
|
||||
|
||||
=item year()
|
||||
|
||||
$year = $db->year();
|
||||
|
||||
Returns the year, obtained from the C<'Year'> entry of the file. (Often
|
||||
not present.)
|
||||
|
||||
=cut
|
||||
|
||||
sub year {
|
||||
return shift->parse("year");
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item album()
|
||||
|
||||
$album = $db->album();
|
||||
|
||||
Returns the album name, obtained from the C<'Albumtitle'> entry of the file.
|
||||
|
||||
=cut
|
||||
|
||||
sub album {
|
||||
return shift->parse("album");
|
||||
}
|
||||
|
||||
=item comment()
|
||||
|
||||
$comment = $db->comment();
|
||||
|
||||
Returns the C<'REM COMMENT'> entry of the file. (Often not present.)
|
||||
|
||||
=cut
|
||||
|
||||
sub comment {
|
||||
return shift->parse("comment");
|
||||
}
|
||||
|
||||
=item genre()
|
||||
|
||||
$genre = $db->genre($filename);
|
||||
|
||||
=cut
|
||||
|
||||
sub genre {
|
||||
return shift->parse("genre");
|
||||
}
|
||||
|
||||
for my $elt ( qw( artist_collection songwriter ) ) {
|
||||
no strict 'refs';
|
||||
*$elt = sub (;$) {
|
||||
return shift->parse($elt);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
481
fhem/FHEM/lib/MP3/Tag/File.pm
Normal file
481
fhem/FHEM/lib/MP3/Tag/File.pm
Normal file
@ -0,0 +1,481 @@
|
||||
package MP3::Tag::File;
|
||||
|
||||
use strict;
|
||||
use Fcntl;
|
||||
use File::Basename;
|
||||
use vars qw /$VERSION @ISA/;
|
||||
|
||||
$VERSION="1.00";
|
||||
@ISA = 'MP3::Tag::__hasparent';
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
MP3::Tag::File - Module for reading / writing files
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $mp3 = MP3::Tag->new($filename);
|
||||
|
||||
($title, $artist, $no, $album, $year) = $mp3->parse_filename();
|
||||
|
||||
see L<MP3::Tag>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
MP3::Tag::File is designed to be called from the MP3::Tag module.
|
||||
|
||||
It offers possibilities to read/write data from files via read(), write(),
|
||||
truncate(), seek(), tell(), open(), close(); one can find the filename via
|
||||
the filename() method.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
# Constructor
|
||||
|
||||
sub new_with_parent {
|
||||
my ($class, $filename, $parent) = @_;
|
||||
return undef unless -f $filename or -c $filename;
|
||||
return bless {filename => $filename, parent => $parent}, $class;
|
||||
}
|
||||
*new = \&new_with_parent; # Obsolete handler
|
||||
|
||||
# Destructor
|
||||
|
||||
sub DESTROY {
|
||||
my $self=shift;
|
||||
if (exists $self->{FH} and defined $self->{FH}) {
|
||||
$self->close;
|
||||
}
|
||||
}
|
||||
|
||||
# File subs
|
||||
|
||||
sub filename { shift->{filename} }
|
||||
|
||||
sub open {
|
||||
my $self=shift;
|
||||
my $mode= shift;
|
||||
if (defined $mode and $mode =~ /w/i) {
|
||||
$mode=O_RDWR; # read/write mode
|
||||
} else {
|
||||
$mode=O_RDONLY; # read only mode
|
||||
}
|
||||
unless (exists $self->{FH}) {
|
||||
local *FH;
|
||||
if (sysopen (FH, $self->filename, $mode)) {
|
||||
$self->{FH} = *FH;
|
||||
binmode $self->{FH};
|
||||
} else {
|
||||
warn "Open `" . $self->filename() . "' failed: $!\n";
|
||||
}
|
||||
}
|
||||
return exists $self->{FH};
|
||||
}
|
||||
|
||||
|
||||
sub close {
|
||||
my $self=shift;
|
||||
if (exists $self->{FH}) {
|
||||
close $self->{FH};
|
||||
delete $self->{FH};
|
||||
}
|
||||
}
|
||||
|
||||
sub write {
|
||||
my ($self, $data) = @_;
|
||||
if (exists $self->{FH}) {
|
||||
local $\ = '';
|
||||
print {$self->{FH}} $data;
|
||||
}
|
||||
}
|
||||
|
||||
sub truncate {
|
||||
my ($self, $length) = @_;
|
||||
if ($length<0) {
|
||||
my @stat = stat $self->{FH};
|
||||
$length = $stat[7] + $length;
|
||||
}
|
||||
if (exists $self->{FH}) {
|
||||
truncate $self->{FH}, $length;
|
||||
}
|
||||
}
|
||||
|
||||
sub size {
|
||||
my ($self) = @_;
|
||||
return -s $self->{FH} if exists $self->{FH};
|
||||
return -s ($self->filename);
|
||||
}
|
||||
|
||||
sub seek {
|
||||
my ($self, $pos, $whence)=@_;
|
||||
$self->open unless exists $self->{FH};
|
||||
seek $self->{FH}, $pos, $whence;
|
||||
}
|
||||
|
||||
sub tell {
|
||||
my ($self, $pos, $whence)=@_;
|
||||
return undef unless exists $self->{FH};
|
||||
return tell $self->{FH};
|
||||
}
|
||||
|
||||
sub read {
|
||||
my ($self, $buf_, $length) = @_;
|
||||
$self->open unless exists $self->{FH};
|
||||
return read $self->{FH}, $$buf_, $length;
|
||||
}
|
||||
|
||||
sub is_open {
|
||||
return exists shift->{FH};
|
||||
}
|
||||
|
||||
# keep the old name
|
||||
*isOpen = \&is_open;
|
||||
|
||||
# read and decode the header of the mp3 part of the file
|
||||
# the raw content of the header fields is stored, the values
|
||||
# are not interpreted in any way (e.g. layer==3 means 'Layer I'
|
||||
# as specified in the mp3 format)
|
||||
sub get_mp3_frame_header {
|
||||
my ($self, $start) = @_;
|
||||
|
||||
$start = 0 unless $start;
|
||||
|
||||
if (exists $self->{mp3header}) {
|
||||
return $self->{mp3header};
|
||||
}
|
||||
|
||||
$self->seek($start, 0);
|
||||
my ($data, $bits)="";
|
||||
while (1) {
|
||||
my $nextdata;
|
||||
$self->read(\$nextdata, 512);
|
||||
return unless $nextdata; # no header found
|
||||
$data .= $nextdata;
|
||||
if ($data =~ /(\xFF[\xE0-\xFF]..)/) {
|
||||
$bits = unpack("B32", $1);
|
||||
last;
|
||||
}
|
||||
$data = substr $data, -3
|
||||
}
|
||||
|
||||
my @fields;
|
||||
for (qw/11 2 2 1 4 2 1 1 1 2 2 1 1 2/) {
|
||||
push @fields, oct "0b" . substr $bits, 0, $_;
|
||||
$bits = substr $bits, $_ if length $bits > $_;
|
||||
}
|
||||
|
||||
$self->{mp3header}={};
|
||||
for (qw/sync version layer proctection bitrate_id sampling_rate_id padding private
|
||||
channel_mode mode_ext copyright original emphasis/) {
|
||||
$self->{mp3header}->{$_}=shift @fields;
|
||||
}
|
||||
|
||||
return $self->{mp3header}
|
||||
}
|
||||
|
||||
|
||||
# use filename to determine information about song/artist/album
|
||||
|
||||
=pod
|
||||
|
||||
=over 4
|
||||
|
||||
=item parse_filename()
|
||||
|
||||
($title, $artist, $no, $album, $year) = $mp3->parse_filename($what, $filename);
|
||||
|
||||
parse_filename() tries to extract information about artist, title,
|
||||
track number, album and year from the filename. (For backward
|
||||
compatibility it may be also called by deprecated name
|
||||
read_filename().)
|
||||
|
||||
This is likely to fail for a lot of filenames, especially the album will
|
||||
be often wrongly guessed, as the name of the parent directory is taken as
|
||||
album name.
|
||||
|
||||
$what and $filename are optional. $what maybe title, track, artist, album
|
||||
or year. If $what is defined parse_filename() will return only this element.
|
||||
|
||||
If $filename is defined this filename will be used and not the real
|
||||
filename which was set by L<MP3::Tag> with
|
||||
C<MP3::Tag-E<gt>new($filename)>. Otherwise the actual filename is used
|
||||
(subject to configuration variable C<decode_encoding_filename>).
|
||||
|
||||
Following formats will be hopefully recognized:
|
||||
|
||||
- album name/artist name - song name.mp3
|
||||
|
||||
- album_name/artist_name-song_name.mp3
|
||||
|
||||
- album.name/artist.name_song.name.mp3
|
||||
|
||||
- album name/(artist name) song name.mp3
|
||||
|
||||
- album name/01. artist name - song name.mp3
|
||||
|
||||
- album name/artist name - 01 - song.name.mp3
|
||||
|
||||
If artist or title end in C<(NUMBER)> with 4-digit NUMBER, it is considered
|
||||
the year.
|
||||
|
||||
=cut
|
||||
|
||||
*read_filename = \&parse_filename;
|
||||
|
||||
sub return_parsed {
|
||||
my ($self,$what) = @_;
|
||||
if (defined $what) {
|
||||
return $self->{parsed}{album} if $what =~/^al/i;
|
||||
return $self->{parsed}{artist} if $what =~/^a/i;
|
||||
return $self->{parsed}{no} if $what =~/^tr/i;
|
||||
return $self->{parsed}{year} if $what =~/^y/i;
|
||||
return $self->{parsed}{title};
|
||||
}
|
||||
|
||||
return $self->{parsed} unless wantarray;
|
||||
return map $self->{parsed}{$_} , qw(title artist no album year);
|
||||
}
|
||||
|
||||
sub parse_filename {
|
||||
my ($self,$what,$filename) = @_;
|
||||
unless (defined $filename) {
|
||||
$filename = $self->filename;
|
||||
my $e;
|
||||
if ($e = $self->get_config('decode_encoding_filename') and $e->[0]) {
|
||||
require Encode;
|
||||
$filename = Encode::decode($e->[0], $filename);
|
||||
}
|
||||
}
|
||||
my $pathandfile = $filename;
|
||||
|
||||
$self->return_parsed($what) if exists $self->{parsed_filename}
|
||||
and $self->{parsed_filename} eq $filename;
|
||||
|
||||
# prepare pathandfile for easier use
|
||||
my $ext_rex = $self->get_config('extension')->[0];
|
||||
$pathandfile =~ s/$ext_rex//; # remove extension
|
||||
$pathandfile =~ s/ +/ /g; # replace several spaces by one space
|
||||
|
||||
# Keep two last components of the file name
|
||||
my ($file, $path) = fileparse($pathandfile, "");
|
||||
($path) = fileparse($path, "");
|
||||
my $orig_file = $file;
|
||||
|
||||
# check which chars are used for seperating words
|
||||
# assumption: spaces between words
|
||||
|
||||
unless ($file =~/ /) {
|
||||
# no spaces used, find word seperator
|
||||
my $Ndot = $file =~ tr/././;
|
||||
my $Nunderscore = $file =~ tr/_/_/;
|
||||
my $Ndash = $file =~ tr/-/-/;
|
||||
if (($Ndot>$Nunderscore) && ($Ndot>1)) {
|
||||
$file =~ s/\./ /g;
|
||||
}
|
||||
elsif ($Nunderscore > 1) {
|
||||
$file =~ s/_/ /g;
|
||||
}
|
||||
elsif ($Ndash>2) {
|
||||
$file =~ s/-/ /g;
|
||||
}
|
||||
}
|
||||
|
||||
# check wich chars are used for seperating parts
|
||||
# assumption: " - " is used
|
||||
|
||||
my $partsep = " - ";
|
||||
|
||||
unless ($file =~ / - /) {
|
||||
if ($file =~ /-/) {
|
||||
$partsep = "-";
|
||||
} elsif ($file =~ /^\(.*\)/) {
|
||||
# replace brackets by -
|
||||
$file =~ s/^\((.*?)\)/$1 - /;
|
||||
$file =~ s/ +/ /;
|
||||
$partsep = " - ";
|
||||
} elsif ($file =~ /_/) {
|
||||
$partsep = "_";
|
||||
} else {
|
||||
$partsep = "DoesNotExist";
|
||||
}
|
||||
}
|
||||
|
||||
# get parts of name
|
||||
my ($title, $artist, $no, $album, $year)=("","","","","");
|
||||
|
||||
# try to find a track-number in front of filename
|
||||
if ($file =~ /^ *(\d+)[\W_]/) {
|
||||
$no=$1; # store number
|
||||
$file =~ s/^ *\d+//; # and delete it
|
||||
$file =~ s/^$partsep// || $file =~ s/^.//;
|
||||
$file =~ s/^ +//;
|
||||
}
|
||||
|
||||
$file =~ s/_+/ /g unless $partsep =~ /_/; #remove underscore unless they are needed for part seperation
|
||||
my @parts = split /$partsep/, $file;
|
||||
if (@parts == 1) {
|
||||
$title=$parts[0];
|
||||
$no = $file if $title and $title =~ /^\d{1,2}$/;
|
||||
} elsif (@parts == 2) {
|
||||
if ($parts[0] =~ /^\d{1,2}$/) {
|
||||
$no = $parts[0];
|
||||
$title = $file;
|
||||
} elsif ($parts[1] =~ /^\d{1,2}$/) {
|
||||
$no = $parts[1];
|
||||
$title = $file;
|
||||
} else {
|
||||
$artist=$parts[0];
|
||||
$title=$parts[1];
|
||||
}
|
||||
} elsif (@parts > 2) {
|
||||
my $temp = "";
|
||||
$artist = shift @parts;
|
||||
foreach (@parts) {
|
||||
if (/^ *(\d+)\.? *$/) {
|
||||
$artist.= $partsep . $temp if $temp;
|
||||
$temp="";
|
||||
$no=$1;
|
||||
} else {
|
||||
$temp .= $partsep if $temp;
|
||||
$temp .= $_;
|
||||
}
|
||||
}
|
||||
$title=$temp;
|
||||
}
|
||||
|
||||
$title =~ s/ +$//;
|
||||
$artist =~ s/ +$//;
|
||||
$no =~ s/ +$//;
|
||||
|
||||
# Special-case names like audio12 etc created by some software
|
||||
# (cdda2wav, gramofile, etc)
|
||||
$no = $+ if not $no and $title =~ /^(\d+)?(?:audio|track|processed)\s*(\d+)?$/i and $+;
|
||||
|
||||
$no =~ s/^0+//;
|
||||
|
||||
if ($path) {
|
||||
unless ($artist) {
|
||||
$artist = $path;
|
||||
} else {
|
||||
$album = $path;
|
||||
}
|
||||
}
|
||||
# Keep the year in the title/artist (XXXX Should we?)
|
||||
$year = $1 if $title =~ /\((\d{4})\)/ or $artist =~ /\((\d{4})\)/;
|
||||
|
||||
$self->{parsed_filename} = $filename;
|
||||
$self->{parsed} = { artist=>$artist, song=>$title, no=>$no,
|
||||
album=>$album, title=>$title, year => $year};
|
||||
$self->return_parsed($what);
|
||||
}
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=item title()
|
||||
|
||||
$title = $mp3->title($filename);
|
||||
|
||||
Returns the title, guessed from the filename. See also parse_filename(). (For
|
||||
backward compatibility, can be called by deprecated name song().)
|
||||
|
||||
$filename is optional and will be used instead of the real filename if defined.
|
||||
|
||||
=cut
|
||||
|
||||
*song = \&title;
|
||||
|
||||
sub title {
|
||||
my $self = shift;
|
||||
return $self->parse_filename("title", @_);
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item artist()
|
||||
|
||||
$artist = $mp3->artist($filename);
|
||||
|
||||
Returns the artist name, guessed from the filename. See also parse_filename()
|
||||
|
||||
$filename is optional and will be used instead of the real filename if defined.
|
||||
|
||||
=cut
|
||||
|
||||
sub artist {
|
||||
my $self = shift;
|
||||
return $self->parse_filename("artist", @_);
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item track()
|
||||
|
||||
$track = $mp3->track($filename);
|
||||
|
||||
Returns the track number, guessed from the filename. See also parse_filename()
|
||||
|
||||
$filename is optional and will be used instead of the real filename if defined.
|
||||
|
||||
=cut
|
||||
|
||||
sub track {
|
||||
my $self = shift;
|
||||
return $self->parse_filename("track", @_);
|
||||
}
|
||||
|
||||
=item year()
|
||||
|
||||
$year = $mp3->year($filename);
|
||||
|
||||
Returns the year, guessed from the filename. See also parse_filename()
|
||||
|
||||
$filename is optional and will be used instead of the real filename if defined.
|
||||
|
||||
=cut
|
||||
|
||||
sub year {
|
||||
my $self = shift;
|
||||
my $y = $self->parse_filename("year", @_);
|
||||
return $y if length $y;
|
||||
return;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item album()
|
||||
|
||||
$album = $mp3->album($filename);
|
||||
|
||||
Returns the album name, guessed from the filename. See also parse_filename()
|
||||
The album name is guessed from the parent directory, so it is very likely to fail.
|
||||
|
||||
$filename is optional and will be used instead of the real filename if defined.
|
||||
|
||||
=cut
|
||||
|
||||
sub album {
|
||||
my $self = shift;
|
||||
return $self->parse_filename("album", @_);
|
||||
}
|
||||
|
||||
=item comment()
|
||||
|
||||
$comment = $mp3->comment($filename); # Always undef
|
||||
|
||||
=cut
|
||||
|
||||
sub comment {}
|
||||
|
||||
=item genre()
|
||||
|
||||
$genre = $mp3->genre($filename); # Always undef
|
||||
|
||||
=cut
|
||||
|
||||
sub genre {}
|
||||
|
||||
1;
|
544
fhem/FHEM/lib/MP3/Tag/ID3v1.pm
Normal file
544
fhem/FHEM/lib/MP3/Tag/ID3v1.pm
Normal file
@ -0,0 +1,544 @@
|
||||
package MP3::Tag::ID3v1;
|
||||
|
||||
# Copyright (c) 2000-2004 Thomas Geffert. All rights reserved.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the Artistic License, distributed
|
||||
# with Perl.
|
||||
|
||||
use strict;
|
||||
use vars qw /@mp3_genres @winamp_genres $AUTOLOAD %ok_length $VERSION @ISA/;
|
||||
|
||||
$VERSION="1.00";
|
||||
@ISA = 'MP3::Tag::__hasparent';
|
||||
|
||||
# allowed fields in ID3v1.1 and max length of this fields (except for track and genre which are coded later)
|
||||
%ok_length = (title => 30, artist => 30, album => 30, comment => 28, track => 3, genre => 3000, year=>4, genreID=>1);
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
MP3::Tag::ID3v1 - Module for reading / writing ID3v1 tags of MP3 audio files
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
MP3::Tag::ID3v1 is designed to be called from the MP3::Tag module.
|
||||
|
||||
use MP3::Tag;
|
||||
$mp3 = MP3::Tag->new($filename);
|
||||
|
||||
# read an existing tag
|
||||
$mp3->get_tags();
|
||||
$id3v1 = $mp3->{ID3v1} if exists $mp3->{ID3v1};
|
||||
|
||||
# or create a new tag
|
||||
$id3v1 = $mp3->new_tag("ID3v1");
|
||||
|
||||
See L<MP3::Tag|according documentation> for information on the above used functions.
|
||||
|
||||
* Reading the tag
|
||||
|
||||
print " Title: " .$id3v1->title . "\n";
|
||||
print " Artist: " .$id3v1->artist . "\n";
|
||||
print " Album: " .$id3v1->album . "\n";
|
||||
print "Comment: " .$id3v1->comment . "\n";
|
||||
print " Year: " .$id3v1->year . "\n";
|
||||
print " Genre: " .$id3v1->genre . "\n";
|
||||
print " Track: " .$id3v1->track . "\n";
|
||||
|
||||
# or at once
|
||||
@tagdata = $mp3->all();
|
||||
foreach $tag (@tagdata) {
|
||||
print $tag;
|
||||
}
|
||||
|
||||
* Changing / Writing the tag
|
||||
|
||||
$id3v1->comment("This is only a Test Tag");
|
||||
$id3v1->title("testing");
|
||||
$id3v1->artist("Artest");
|
||||
$id3v1->album("Test it");
|
||||
$id3v1->year("1965");
|
||||
$id3v1->track("5");
|
||||
$id3v1->genre("Blues");
|
||||
# or at once
|
||||
$id3v1->all("song title","artist","album","1900","comment",10,"Ska");
|
||||
$id3v1->write_tag();
|
||||
|
||||
* Removing the tag from the file
|
||||
|
||||
$id3v1->remove_tag();
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Thomas Geffert, thg@users.sourceforge.net
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
=pod
|
||||
|
||||
=over
|
||||
|
||||
=item title(), artist(), album(), year(), comment(), track(), genre()
|
||||
|
||||
$artist = $id3v1->artist;
|
||||
$artist = $id3v1->artist($artist);
|
||||
$album = $id3v1->album;
|
||||
$album = $id3v1->album($album);
|
||||
$year = $id3v1->year;
|
||||
$year = $id3v1->year($year);
|
||||
$comment = $id3v1->comment;
|
||||
$comment = $id3v1->comment($comment);
|
||||
$track = $id3v1->track;
|
||||
$track = $id3v1->track($track);
|
||||
$genre = $id3v1->genre;
|
||||
$genre = $id3v1->genre($genre);
|
||||
|
||||
Use these functions to retrieve the date of these fields,
|
||||
or to set the data.
|
||||
|
||||
$genre can be a string with the name of the genre, or a number
|
||||
describing the genre.
|
||||
|
||||
=cut
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
my $attr = $AUTOLOAD;
|
||||
|
||||
# is it an allowed field
|
||||
$attr =~ s/.*:://;
|
||||
return unless $attr =~ /[^A-Z]/;
|
||||
$attr = 'title' if $attr eq 'song';
|
||||
warn "invalid field: ->$attr()" unless $ok_length{$attr};
|
||||
|
||||
if (@_) {
|
||||
my $new = shift;
|
||||
$new =~ s/ *$//;
|
||||
if ($attr eq "genre") {
|
||||
if ($new =~ /^\d+$/) {
|
||||
$self->{genreID} = $new;
|
||||
} else {
|
||||
$self->{genreID} = genre2id($new);
|
||||
}
|
||||
$new = id2genre($self->{genreID})
|
||||
if defined $self->{genreID} and $self->{genreID} < @winamp_genres;
|
||||
}
|
||||
$new = substr $new, 0, $ok_length{$attr};
|
||||
$self->{$attr}=$new;
|
||||
$self->{changed} = 1;
|
||||
}
|
||||
$self->{$attr} =~ s/ +$//;
|
||||
return $self->{$attr};
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item all()
|
||||
|
||||
@tagdata = $id3v1->all;
|
||||
@tagdata = $id3v1->all($title, $artist, $album, $year, $comment, $track, $genre);
|
||||
|
||||
Returns all information of the tag in a list.
|
||||
You can use this sub also to set the data of the complete tag.
|
||||
|
||||
The order of the data is always title, artist, album, year, comment, track, and genre.
|
||||
genre has to be a string with the name of the genre, or a number identifying the genre.
|
||||
|
||||
=cut
|
||||
|
||||
sub all {
|
||||
my $self=shift;
|
||||
if ($#_ == 6) {
|
||||
my $new;
|
||||
for (qw/title artist album year comment track genre/) {
|
||||
$new = shift;
|
||||
$new =~ s/ +$//;
|
||||
$new = substr $new, 0, $ok_length{$_};
|
||||
$self->{$_}=$new;
|
||||
}
|
||||
if ($self->{genre} =~ /^\d+$/) {
|
||||
$self->{genreID} = $self->{genre};
|
||||
} else {
|
||||
$self->{genreID} = genre2id($self->{genre});
|
||||
}
|
||||
$self->{genre} = id2genre($self->{genreID})
|
||||
if defined $self->{genreID} and $self->{genreID} < @winamp_genres;
|
||||
$self->{changed} = 1;
|
||||
}
|
||||
for (qw/title artist album year comment track genre/) {
|
||||
$self->{$_} =~ s/ +$//;
|
||||
}
|
||||
if (wantarray) {
|
||||
return ($self->{title},$self->{artist},$self->{album},
|
||||
$self->{year},$self->{comment}, $self->{track}, $self->{genre});
|
||||
}
|
||||
return $self->{title};
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item fits_tag()
|
||||
|
||||
warn "data truncated" unless $id3v1->fits_tag($hash);
|
||||
|
||||
Check whether the info in ID3v1 tag fits into the format of the file.
|
||||
|
||||
=cut
|
||||
|
||||
sub fits_tag {
|
||||
my ($self, $hash) = (shift, shift);
|
||||
my $elt;
|
||||
if (defined (my $track = $hash->{track})) {
|
||||
$track = $track->[0] if ref $track;
|
||||
return unless $track =~ /^\d{0,3}$/ and ($track eq '' or $track < 256);
|
||||
}
|
||||
my $s = '';
|
||||
for $elt (qw(title artist album comment year)) {
|
||||
next unless defined (my $data = $hash->{$elt});
|
||||
$data = $data->[0] if ref $data;
|
||||
return if $data =~ /[^\x00-\xFF]/;
|
||||
$s .= $data;
|
||||
next if $ok_length{$elt} >= length $data;
|
||||
next
|
||||
if $elt eq 'comment' and not $hash->{track} and length $data <= 30;
|
||||
return;
|
||||
}
|
||||
if (defined (my $genre = $hash->{genre})) {
|
||||
$genre = $genre->[0] if ref $genre;
|
||||
my @g = MP3::Tag::Implemenation::_massage_genres($genre);
|
||||
return if @g > 1;
|
||||
my $id = MP3::Tag::Implemenation::_massage_genres($genre, 'num');
|
||||
return if not defined $id or $id eq '' or $id == 255;
|
||||
}
|
||||
if ($s =~ /[^\x00-\x7E]/) {
|
||||
my $w = ($self->get_config('encode_encoding_v1') || [0])->[0];
|
||||
my $r = ($self->get_config('decode_encoding_v1') || [0])->[0];
|
||||
$_ = (lc or 'iso-8859-1') for $r, $w;
|
||||
# Safe: per-standard and read+write is idempotent:
|
||||
return 1 if $r eq $w and $w eq 'iso-8859-1';
|
||||
return !(($self->get_config('encoded_v1_fits')||[0])->[0])
|
||||
if $w eq 'iso-8859-1'; # read+write not idempotent
|
||||
return if $w ne $r
|
||||
and not (($self->get_config('encoded_v1_fits')||[0])->[0]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
=item as_bin()
|
||||
|
||||
$str = $id3v1->as_bin();
|
||||
|
||||
Returns the ID3v1 tag as a string.
|
||||
|
||||
=item write_tag()
|
||||
|
||||
$id3v1->write_tag();
|
||||
|
||||
[old name: writeTag() . The old name is still available, but you should use the new name]
|
||||
|
||||
Writes the ID3v1 tag to the file.
|
||||
|
||||
=cut
|
||||
|
||||
sub as_bin {
|
||||
my $self = shift;
|
||||
my($t) = ( $self->{track} =~ m[^(\d+)(?:/|$)], 0 );
|
||||
my (%f, $f, $e);
|
||||
for $f (qw(title artist album comment) ) {
|
||||
$f{$f} = $self->{$f};
|
||||
}
|
||||
|
||||
if ($e = $self->get_config('encode_encoding_v1') and $e->[0]) {
|
||||
my $field;
|
||||
require Encode;
|
||||
|
||||
for $field (qw(title artist album comment)) {
|
||||
$f{$field} = Encode::encode($e->[0], $f{$field});
|
||||
}
|
||||
}
|
||||
|
||||
$f{comment} = pack "a28 x C", $f{comment}, $t if $t;
|
||||
$self->{genreID}=255 unless $self->{genreID} =~ /^\d+$/;
|
||||
|
||||
return pack("a3a30a30a30a4a30C","TAG",$f{title}, $f{artist},
|
||||
$f{album}, $self->{year}, $f{comment}, $self->{genreID});
|
||||
}
|
||||
|
||||
sub write_tag {
|
||||
my $self = shift;
|
||||
return undef unless exists $self->{title} && exists $self->{changed};
|
||||
my $data = $self->as_bin();
|
||||
my $mp3obj = $self->{mp3};
|
||||
my $mp3tag;
|
||||
$mp3obj->close;
|
||||
if ($mp3obj->open("write")) {
|
||||
$mp3obj->seek(-128,2);
|
||||
$mp3obj->read(\$mp3tag, 3);
|
||||
if ($mp3tag eq "TAG") {
|
||||
$mp3obj->seek(-125,2); # neccessary for windows
|
||||
$mp3obj->write(substr $data, 3);
|
||||
} else {
|
||||
$mp3obj->seek(0,2);
|
||||
$mp3obj->write($data);
|
||||
}
|
||||
} else {
|
||||
warn "Couldn't open file `" . $mp3obj->filename() . "' to write tag";
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
*writeTag = \&write_tag;
|
||||
|
||||
=pod
|
||||
|
||||
=item remove_tag()
|
||||
|
||||
$id3v1->remove_tag();
|
||||
|
||||
Removes the ID3v1 tag from the file. Returns negative on failure,
|
||||
FALSE if no tag was found.
|
||||
|
||||
(Caveat: only I<one tag> is removed; some - broken - files may have
|
||||
many chain-loaded one after another; you may need to call remove_tag()
|
||||
in a loop to handle such beasts.)
|
||||
|
||||
[old name: removeTag() . The old name is still available, but you
|
||||
should use the new name]
|
||||
|
||||
=cut
|
||||
|
||||
sub remove_tag {
|
||||
my $self = shift;
|
||||
my $mp3obj = $self->{mp3};
|
||||
my $mp3tag;
|
||||
$mp3obj->seek(-128,2);
|
||||
$mp3obj->read(\$mp3tag, 3);
|
||||
if ($mp3tag eq "TAG") {
|
||||
$mp3obj->close;
|
||||
if ($mp3obj->open("write")) {
|
||||
$mp3obj->truncate(-128);
|
||||
$self->all("","","","","",0,255);
|
||||
$mp3obj->close;
|
||||
$self->{changed} = 1;
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
*removeTag = \&remove_tag;
|
||||
|
||||
=pod
|
||||
|
||||
=item genres()
|
||||
|
||||
@allgenres = $id3v1->genres;
|
||||
$genreName = $id3v1->genres($genreID);
|
||||
$genreID = $id3v1->genres($genreName);
|
||||
|
||||
Returns a list of all genres, or the according name or id to
|
||||
a given id or name.
|
||||
|
||||
=cut
|
||||
|
||||
sub genres {
|
||||
# return an array with all genres, of if a parameter is given, the according genre
|
||||
my ($self, $genre) = @_;
|
||||
if ( (defined $self) and (not defined $genre) and ($self !~ /MP3::Tag/)) {
|
||||
## genres may be called directly via MP3::Tag::ID3v1::genres()
|
||||
## and $self is then not used for an id3v1 object
|
||||
$genre = $self;
|
||||
}
|
||||
|
||||
return \@winamp_genres unless defined $genre;
|
||||
|
||||
if ($genre =~ /^\d+$/) {
|
||||
return $winamp_genres[$genre] if $genre<scalar @winamp_genres;
|
||||
return undef;
|
||||
}
|
||||
|
||||
my ($id, $found)=0;
|
||||
foreach (@winamp_genres) {
|
||||
if (uc $_ eq uc $genre) {
|
||||
$found = 1;
|
||||
last;
|
||||
}
|
||||
$id++;
|
||||
}
|
||||
$id=255 unless $found;
|
||||
return $id;
|
||||
}
|
||||
|
||||
=item new()
|
||||
|
||||
$id3v1 = MP3::Tag::ID3v1->new($mp3fileobj[, $create]);
|
||||
|
||||
Generally called from MP3::Tag, because a $mp3fileobj is needed.
|
||||
If $create is true, a new tag is created. Otherwise undef is
|
||||
returned, if now ID3v1 tag is found in the $mp3obj.
|
||||
|
||||
Please use
|
||||
|
||||
$mp3 = MP3::Tag->new($filename);
|
||||
$id3v1 = $mp3->new_tag("ID3v1"); # Empty new tag
|
||||
|
||||
or
|
||||
|
||||
$mp3 = MP3::Tag->new($filename);
|
||||
$mp3->get_tags();
|
||||
$id3v1 = $mp3->{ID3v1}; # Existing tag (if present)
|
||||
|
||||
instead of using this function directly
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
# create a ID3v1 object
|
||||
sub new {
|
||||
my ($class, $fileobj, $create) = @_;
|
||||
my $self={mp3=>$fileobj};
|
||||
my $buffer;
|
||||
|
||||
if ($create) {
|
||||
$self->{new} = 1;
|
||||
} else {
|
||||
$fileobj->open or return unless $fileobj->is_open;
|
||||
$fileobj->seek(-128,2);
|
||||
$fileobj->read(\$buffer, 128);
|
||||
return undef unless substr ($buffer,0,3) eq "TAG";
|
||||
}
|
||||
|
||||
bless $self, $class;
|
||||
$self->read_tag($buffer); # $buffer unused if ->{new}
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub new_with_parent {
|
||||
my ($class, $filename, $parent) = @_;
|
||||
return unless my $new = $class->new($filename, undef);
|
||||
$new->{parent} = $parent;
|
||||
$new;
|
||||
}
|
||||
|
||||
#################
|
||||
##
|
||||
## internal subs
|
||||
|
||||
# actually read the tag data
|
||||
sub read_tag {
|
||||
my ($self, $buffer) = @_;
|
||||
my ($id3v1, $e);
|
||||
|
||||
if ($self->{new}) {
|
||||
($self->{title}, $self->{artist}, $self->{album}, $self->{year},
|
||||
$self->{comment}, $self->{track}, $self->{genre}, $self->{genreID}) = ("","","","","",'',"",255);
|
||||
$self->{changed} = 1;
|
||||
} else {
|
||||
(undef, $self->{title}, $self->{artist}, $self->{album}, $self->{year},
|
||||
$self->{comment}, $id3v1, $self->{track}, $self->{genreID}) =
|
||||
unpack (($] < 5.6
|
||||
? "a3 A30 A30 A30 A4 A28 C C C" # Trailing spaces stripped too
|
||||
: "a3 Z30 Z30 Z30 Z4 Z28 C C C"),
|
||||
$buffer);
|
||||
|
||||
if ($id3v1!=0) { # ID3v1 tag found: track is not valid, comment two chars longer
|
||||
$self->{comment} .= chr($id3v1);
|
||||
$self->{comment} .= chr($self->{track})
|
||||
if $self->{track} and $self->{track}!=32;
|
||||
$self->{track} = '';
|
||||
};
|
||||
$self->{track} = '' unless $self->{track};
|
||||
$self->{genre} = id2genre($self->{genreID});
|
||||
if ($e = $self->get_config('decode_encoding_v1') and $e->[0]) {
|
||||
my $field;
|
||||
require Encode;
|
||||
|
||||
for $field (qw(title artist album comment)) {
|
||||
$self->{$field} = Encode::decode($e->[0], $self->{$field});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# convert small integer id to genre name
|
||||
sub id2genre {
|
||||
my $id=shift;
|
||||
return "" unless defined $id and $id < @winamp_genres;
|
||||
return $winamp_genres[$id];
|
||||
}
|
||||
|
||||
# convert genre name to small integer id
|
||||
sub genre2id {
|
||||
my $genre = MP3::Tag::Implemenation::_massage_genres(shift, 'num');
|
||||
return $genre if defined $genre;
|
||||
return 255;
|
||||
}
|
||||
|
||||
# nothing to do for destroy
|
||||
sub DESTROY {
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
######## define all the genres
|
||||
|
||||
BEGIN { @mp3_genres = ( 'Blues', 'Classic Rock', 'Country', 'Dance',
|
||||
'Disco', 'Funk', 'Grunge', 'Hip-Hop', 'Jazz', 'Metal', 'New Age',
|
||||
'Oldies', 'Other', 'Pop', 'R&B', 'Rap', 'Reggae', 'Rock', 'Techno',
|
||||
'Industrial', 'Alternative', 'Ska', 'Death Metal', 'Pranks',
|
||||
'Soundtrack', 'Euro-Techno', 'Ambient', 'Trip-Hop', 'Vocal',
|
||||
'Jazz+Funk', 'Fusion', 'Trance', 'Classical', 'Instrumental', 'Acid',
|
||||
'House', 'Game', 'Sound Clip', 'Gospel', 'Noise', 'AlternRock',
|
||||
'Bass', 'Soul', 'Punk', 'Space', 'Meditative', 'Instrumental Pop',
|
||||
'Instrumental Rock', 'Ethnic', 'Gothic', 'Darkwave',
|
||||
'Techno-Industrial', 'Electronic', 'Pop-Folk', 'Eurodance', 'Dream',
|
||||
'Southern Rock', 'Comedy', 'Cult', 'Gangsta', 'Top 40',
|
||||
'Christian Rap', 'Pop/Funk', 'Jungle', 'Native American', 'Cabaret', 'New Wave',
|
||||
'Psychadelic', 'Rave', 'Showtunes', 'Trailer', 'Lo-Fi', 'Tribal',
|
||||
'Acid Punk', 'Acid Jazz', 'Polka', 'Retro', 'Musical', 'Rock & Roll',
|
||||
'Hard Rock', );
|
||||
|
||||
@winamp_genres = ( @mp3_genres, 'Folk', 'Folk-Rock',
|
||||
'National Folk', 'Swing', 'Fast Fusion', 'Bebob', 'Latin', 'Revival',
|
||||
'Celtic', 'Bluegrass', 'Avantgarde', 'Gothic Rock',
|
||||
'Progressive Rock', 'Psychedelic Rock', 'Symphonic Rock',
|
||||
'Slow Rock', 'Big Band', 'Chorus', 'Easy Listening',
|
||||
'Acoustic', 'Humour', 'Speech', 'Chanson', 'Opera',
|
||||
'Chamber Music', 'Sonata', 'Symphony', 'Booty Bass', 'Primus',
|
||||
'Porn Groove', 'Satire', 'Slow Jam', 'Club', 'Tango', 'Samba',
|
||||
'Folklore', 'Ballad', 'Power Ballad', 'Rhythmic Soul',
|
||||
'Freestyle', 'Duet', 'Punk Rock', 'Drum Solo', 'Acapella',
|
||||
'Euro-House', 'Dance Hall',
|
||||
# More from MP3::Info
|
||||
'Goa', 'Drum & Bass', 'Club-House', 'Hardcore',
|
||||
'Terror', 'Indie', 'BritPop', 'Negerpunk',
|
||||
'Polsk Punk', 'Beat', 'Christian Gangsta Rap',
|
||||
'Heavy Metal', 'Black Metal', 'Crossover',
|
||||
'Contemporary Christian Music', 'Christian Rock',
|
||||
'Merengue', 'Salsa', 'Thrash Metal', 'Anime',
|
||||
'JPop', 'SynthPop', # 149
|
||||
);
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<MP3::Tag>, L<MP3::Tag::ID3v2>
|
||||
|
||||
ID3v1 standard - http://www.id3.org
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (c) 2000-2004 Thomas Geffert. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the Artistic License, distributed
|
||||
with Perl.
|
||||
|
||||
=cut
|
2989
fhem/FHEM/lib/MP3/Tag/ID3v2.pm
Normal file
2989
fhem/FHEM/lib/MP3/Tag/ID3v2.pm
Normal file
File diff suppressed because it is too large
Load Diff
332
fhem/FHEM/lib/MP3/Tag/ID3v2_Data.pod
Normal file
332
fhem/FHEM/lib/MP3/Tag/ID3v2_Data.pod
Normal file
@ -0,0 +1,332 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
MP3::Tag::ID3v2_Data - get_frame() data format and supported frames
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
$mp3 = MP3::Tag->new($filename);
|
||||
$mp3->get_tags();
|
||||
$id3v2 = $mp3->{ID3v2} if exists $mp3->{id3v2};
|
||||
|
||||
($info, $long) = $id3v2->get_frame($id); # or
|
||||
|
||||
($info, $long) = $id3v2->get_frame($id, 'raw');
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This document describes how to use the results of the get_frame function of
|
||||
MP3::Tag::ID3v2, thus the data format of frames retrieved with
|
||||
MP3::Tag::ID3v2::get_frame().
|
||||
|
||||
It contains also a list of all supported ID3v2-Frames.
|
||||
|
||||
=head2 get_frame()
|
||||
|
||||
($info, $long) = $id3v2->get_frame($id); # or
|
||||
|
||||
($info, $long) = $id3v2->get_frame($id, 'raw');
|
||||
|
||||
$id has to be a name of a frame like "APIC". For more variants of calling
|
||||
see L<get_frame()|MP3::Tag::ID3v2>.
|
||||
|
||||
The names of all frames found in a tag can be retrieved with the L<get_frame_ids()|MP3::Tag::ID3v2> function.
|
||||
|
||||
=head2 Using the returned data
|
||||
|
||||
In the ID3v2.3 specifications 73 frames are defined, which can contain very
|
||||
different information. That means that get_frame returns the information
|
||||
of different frames also in different ways.
|
||||
|
||||
=over 4
|
||||
|
||||
=item Simple Frames
|
||||
|
||||
A lot of the tags contain only a text string and encoding information. If
|
||||
you call ($info, $long) = $id3v2->get_frame($id) for such a frame, $info will contain
|
||||
the text string and $long will contain the english name of the frame.
|
||||
|
||||
Example:
|
||||
get_frame("TIT2"); # returns
|
||||
|
||||
("Birdhouse In Your Soul", "Title/songname/content description")
|
||||
|
||||
=item Complex Frames
|
||||
|
||||
For more complex frames the returned $info is a reference to a hash, where
|
||||
each entry of the hash decribes a part of the information found in the
|
||||
frame. The key of a hash entry contains the name of this part, the according
|
||||
value contains the information itself.
|
||||
|
||||
Example:
|
||||
get_frame("APIC"); # returns
|
||||
|
||||
( { "Description" => "Flood",
|
||||
"MIME Type" => "/image/jpeg",
|
||||
"Picture Type" => "Cover (front)",
|
||||
"_Data" => "..data of jpeg picture (binary).."
|
||||
},
|
||||
"Attached Picture");
|
||||
|
||||
=item Other Frames
|
||||
|
||||
Some frames are not supported at the moment, ie the data found in the frame
|
||||
is not returned in a descriptive way. But you can read the data of this
|
||||
frames (and also of all other frames too) in raw mode. Then the complete
|
||||
data field of the frame is returned, without any modifications. This means
|
||||
that the returned data will be almost binary data.
|
||||
|
||||
Example:
|
||||
get_frame("TIT2", 'raw'); # returns
|
||||
|
||||
("\x00Birdhouse In Your Soul", "Title/songname/content description")
|
||||
|
||||
=back
|
||||
|
||||
The frames which (in addition to C<Text>/C<URL>) contain only
|
||||
C<Description> and C<Language> fields are in some intermediate position
|
||||
between "simple" and "complex" frames. They can be handled very similarly
|
||||
to "simple" frames by using "long names", such as C<COMM[description]>
|
||||
or C<COMM(LANG)[description]>, and the corresponding "quick" API such
|
||||
as frame_select().
|
||||
|
||||
|
||||
|
||||
=head2 List of Simple Frames
|
||||
|
||||
Following Frames are supported
|
||||
and return a single string (text). In the List you can find the frame IDs
|
||||
and the long names of the frames as returned by $id3v2->get_frame():
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
=item IPLS : Involved people list
|
||||
|
||||
=item MCDI : Music CD identifier
|
||||
|
||||
=item PCNT : Play counter
|
||||
|
||||
=item TALB : Album/Movie/Show title
|
||||
|
||||
=item TBPM : BPM (beats per minute)
|
||||
|
||||
=item TCOM : Composer
|
||||
|
||||
=item TCON : Content type
|
||||
|
||||
=item TCOP : Copyright message
|
||||
|
||||
=item TDAT : Date
|
||||
|
||||
=item TDLY : Playlist delay
|
||||
|
||||
=item TDRC : Recording time
|
||||
|
||||
=item TENC : Encoded by
|
||||
|
||||
=item TEXT : Lyricist/Text writer
|
||||
|
||||
=item TFLT : File type
|
||||
|
||||
=item TIME : Time
|
||||
|
||||
=item TIPL : Involved people list
|
||||
|
||||
=item TIT1 : Content group description
|
||||
|
||||
=item TIT2 : Title/songname/content description
|
||||
|
||||
=item TIT3 : Subtitle/Description refinement
|
||||
|
||||
=item TKEY : Initial key
|
||||
|
||||
=item TLAN : Language(s)
|
||||
|
||||
=item TLEN : Length
|
||||
|
||||
=item TMCL : Musician credits list
|
||||
|
||||
=item TMED : Media type
|
||||
|
||||
=item TOAL : Original album/movie/show title
|
||||
|
||||
=item TOFN : Original filename
|
||||
|
||||
=item TOLY : Original lyricist(s)/text writer(s)
|
||||
|
||||
=item TOPE : Original artist(s)/performer(s)
|
||||
|
||||
=item TORY : Original release year
|
||||
|
||||
=item TOWN : File owner/licensee
|
||||
|
||||
=item TPE1 : Lead performer(s)/Soloist(s)
|
||||
|
||||
=item TPE2 : Band/orchestra/accompaniment
|
||||
|
||||
=item TPE3 : Conductor/performer refinement
|
||||
|
||||
=item TPE4 : Interpreted, remixed, or otherwise modified by
|
||||
|
||||
=item TPOS : Part of a set
|
||||
|
||||
=item TPUB : Publisher
|
||||
|
||||
=item TRCK : Track number/Position in set
|
||||
|
||||
=item TRDA : Recording dates
|
||||
|
||||
=item TRSN : Internet radio station name
|
||||
|
||||
=item TRSO : Internet radio station owner
|
||||
|
||||
=item TSIZ : Size
|
||||
|
||||
=item TSRC : ISRC (international standard recording code)
|
||||
|
||||
=item TSSE : Software/Hardware and settings used for encoding
|
||||
|
||||
=item TYER : Year
|
||||
|
||||
=item WCOM : Commercial information
|
||||
|
||||
=item WCOP : Copyright/Legal information
|
||||
|
||||
=item WOAF : Official audio file webpage
|
||||
|
||||
=item WOAR : Official artist/performer webpage
|
||||
|
||||
=item WOAS : Official audio source webpage
|
||||
|
||||
=item WORS : Official internet radio station homepage
|
||||
|
||||
=item WPAY : Payment
|
||||
|
||||
=item WPUB : Publishers official webpage
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
=head2 List of Complex Frames
|
||||
|
||||
Following frames are supported and return a reference to a hash. The
|
||||
list shows which keys can be found in the returned hash:
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
=item AENC : Audio encryption
|
||||
|
||||
Keys: URL, Preview start, Preview length, _Data
|
||||
|
||||
=item APIC : Attached picture
|
||||
|
||||
Keys: MIME type, Picture Type, Description, _Data
|
||||
|
||||
=item COMM : Comments
|
||||
|
||||
Keys: Language, Description, Text
|
||||
|
||||
=item COMR : Commercial frame
|
||||
|
||||
Keys: Price, Valid until, URL, Received as, Name of Seller, Description, MIME type, _Logo
|
||||
|
||||
=item ENCR : Encryption method registration
|
||||
|
||||
Keys: Owner ID, Method symbol, _Data
|
||||
|
||||
=item GEOB : General encapsulated object
|
||||
|
||||
Keys: MIME type, Filename, Description, _Data
|
||||
|
||||
=item GRID : Group identification registration
|
||||
|
||||
Keys: Owner, Symbol, _Data
|
||||
|
||||
=item LINK : Linked information
|
||||
|
||||
Keys: ID, URL, Text
|
||||
|
||||
=item OWNE : Ownership frame
|
||||
|
||||
Keys: Price payed, Date of purchase, Text
|
||||
|
||||
=item POPM : Popularimeter
|
||||
|
||||
Keys: URL, Rating, Counter
|
||||
|
||||
=item PRIV : Private frame
|
||||
|
||||
Keys: Text, _Data
|
||||
|
||||
=item RBUF : Recommended buffer size
|
||||
|
||||
Keys: Buffer size, Embedded info flag, Offset to next tag
|
||||
|
||||
=item RVRB : Reverb
|
||||
|
||||
Keys: Reverb left (ms), Reverb right (ms), Reverb bounces (left), Reverb bounces (right), Reverb feedback (left to left), Reverb feedback (left to right), Reverb feedback (right to right), Reverb feedback (right to left), Premix left to right, Premix right to left
|
||||
|
||||
=item SYTC : Synchronized tempo codes
|
||||
|
||||
Keys: Time Stamp Format, _Data
|
||||
|
||||
=item TXXX : User defined text information frame
|
||||
|
||||
Keys: Description, Text
|
||||
|
||||
=item UFID : Unique file identifier
|
||||
|
||||
Keys: Text, _Data
|
||||
|
||||
=item USER : Terms of use
|
||||
|
||||
Keys: Language, Text
|
||||
|
||||
=item USLT : Unsychronized lyric/text transcription
|
||||
|
||||
Keys: Language, Description, Text
|
||||
|
||||
=item WXXX : User defined URL link frame
|
||||
|
||||
Keys: Description, URL
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
=head2 List of Other Frames
|
||||
|
||||
Following frames are only supported in raw mode:
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
=item CRM : Encrypted meta frame
|
||||
|
||||
=item EQUA : Equalization
|
||||
|
||||
=item ETCO : Event timing codes
|
||||
|
||||
=item LNK : Linked information
|
||||
|
||||
=item MLLT : MPEG location lookup table
|
||||
|
||||
=item PIC : Attached picture
|
||||
|
||||
=item POSS : Position synchronisation frame
|
||||
|
||||
=item RVAD : Relative volume adjustment
|
||||
|
||||
=item SYLT : Synchronized lyric/text
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<MP3::Tag>, L<MP3::Tag::ID3v2>
|
||||
|
119
fhem/FHEM/lib/MP3/Tag/ImageExifTool.pm
Normal file
119
fhem/FHEM/lib/MP3/Tag/ImageExifTool.pm
Normal file
@ -0,0 +1,119 @@
|
||||
package MP3::Tag::ImageExifTool;
|
||||
|
||||
use strict;
|
||||
use File::Basename;
|
||||
#use File::Spec;
|
||||
use vars qw /$VERSION @ISA/;
|
||||
|
||||
$VERSION="0.01";
|
||||
@ISA = 'MP3::Tag::__hasparent';
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
MP3::Tag::ImageExifTool - extract size info from image files via L<Image::Size|Image::Size>.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $db = MP3::Tag::ImageExifTool->new($filename); # Name of multimedia file
|
||||
|
||||
see L<MP3::Tag>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
MP3::Tag::ImageExifTool is designed to be called from the MP3::Tag module.
|
||||
|
||||
It implements width(), height() and mime_type() methods (sizes in pixels).
|
||||
|
||||
They return C<undef> if C<Image::Size> is not available, or does not return valid data.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
# Constructor
|
||||
|
||||
sub new_with_parent {
|
||||
my ($class, $f, $p, $e, %seen, @cue) = (shift, shift, shift);
|
||||
$f = $f->filename if ref $f;
|
||||
bless [$f], $class;
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, $f) = (shift, shift);
|
||||
$class->new_with_parent($f, undef, @_);
|
||||
}
|
||||
|
||||
# Destructor
|
||||
|
||||
sub DESTROY {}
|
||||
|
||||
sub __info ($) {
|
||||
my $self = shift;
|
||||
unless (defined $self->[1]) {
|
||||
my $v = eval { require Image::ExifTool;
|
||||
Image::ExifTool->new()->ImageInfo($self->[0], '-id3:*') };
|
||||
# How to detect errors?
|
||||
$self->[1] = $v->{Error} ? '' : $v;
|
||||
}
|
||||
return $self->[1];
|
||||
}
|
||||
|
||||
my %tr = qw( mime_type MIMEType year Date width ImageWidth height ImageHeight
|
||||
bit_depth BitDepth );
|
||||
|
||||
for my $elt ( qw( title track artist album year genre comment mime_type
|
||||
width height ) ) {
|
||||
my $n = ($tr{$elt} or ucfirst $elt);
|
||||
my $is_genre = ($elt eq 'genre');
|
||||
my $r = sub ($) {
|
||||
my $info = shift()->__info;
|
||||
return unless $info;
|
||||
my $v = $info->{$n};
|
||||
$v =~ s/^None$// if $is_genre and $v;
|
||||
return $v;
|
||||
};
|
||||
no strict 'refs';
|
||||
*$elt = $r;
|
||||
}
|
||||
|
||||
sub bit_depth ($) {
|
||||
my $info = shift()->__info;
|
||||
return unless $info;
|
||||
$info->{BitsPerSample} || $info->{Depth} || $info->{BitDepth}
|
||||
}
|
||||
|
||||
sub field ($$) {
|
||||
my $info = shift()->__info;
|
||||
return unless $info;
|
||||
$info->{shift()}
|
||||
}
|
||||
|
||||
sub _duration ($) {
|
||||
my $info = shift()->__info;
|
||||
return unless $info;
|
||||
my($d, $dd) = $info->{Duration};
|
||||
if (defined $d and $d =~ /\d/) {
|
||||
$dd = 1;
|
||||
return $d if $d =~ /^\d*(\.\d*)?$/;
|
||||
}
|
||||
# Probably this is already covered by Duration? No, it is usually rounded...
|
||||
my($c, $r, $r1) = map $info->{$_}, qw(FrameCount VideoFrameRate FrameRate);
|
||||
unless (defined $c and $r ||= $r1) { # $d usually contains rounded value
|
||||
return $1*3600 + $2*60 + $3 if $dd and $d =~ /^(\d+):(\d+):(\d+(\.\d*)?)$/;
|
||||
return $1*60 + $2 if $dd and $d =~ /^(\d+):(\d+(\.\d*)?)$/;
|
||||
return;
|
||||
}
|
||||
$r = 30/1.001 if $r =~ /^29.97\d*^/;
|
||||
$r = 24/1.001 if $r =~ /^23.9(7\d*|8)$/;
|
||||
$c/$r
|
||||
}
|
||||
|
||||
sub img_type ($) {
|
||||
my $self = shift;
|
||||
my $t = $self->mime_type;
|
||||
return uc $1 if $t =~ m(^image/(.*));
|
||||
return;
|
||||
}
|
||||
|
||||
1;
|
77
fhem/FHEM/lib/MP3/Tag/ImageSize.pm
Normal file
77
fhem/FHEM/lib/MP3/Tag/ImageSize.pm
Normal file
@ -0,0 +1,77 @@
|
||||
package MP3::Tag::ImageSize;
|
||||
|
||||
use strict;
|
||||
use File::Basename;
|
||||
#use File::Spec;
|
||||
use vars qw /$VERSION @ISA/;
|
||||
|
||||
$VERSION="0.01";
|
||||
@ISA = 'MP3::Tag::__hasparent';
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
MP3::Tag::ImageSize - extract size info from image files via L<Image::Size|Image::Size>.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $db = MP3::Tag::ImageSize->new($filename); # Name of multimedia file
|
||||
|
||||
see L<MP3::Tag>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
MP3::Tag::ImageSize is designed to be called from the MP3::Tag module.
|
||||
|
||||
It implements width(), height() and mime_type() methods (sizes in pixels).
|
||||
|
||||
They return C<undef> if C<Image::Size> is not available, or does not return valid data.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Image::Size>, L<MP3::Tag>
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
# Constructor
|
||||
|
||||
sub new_with_parent {
|
||||
my ($class, $f, $p, $e, %seen, @cue) = (shift, shift, shift);
|
||||
$f = $f->filename if ref $f;
|
||||
bless [$f], $class;
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, $f) = (shift, shift);
|
||||
$class->new_with_parent($f, undef, @_);
|
||||
}
|
||||
|
||||
# Destructor
|
||||
|
||||
sub DESTROY {}
|
||||
|
||||
my @fields = qw( 0 0 width height img_type mime_type );
|
||||
for my $elt ( 2, 3, 4, 5 ) { # i_bitdepth
|
||||
my $r = sub (;$) {
|
||||
my $self = shift;
|
||||
unless ($self->[1]) {
|
||||
my ($w, $h, $t) = eval { require Image::Size;
|
||||
Image::Size::imgsize($self->[0]) };
|
||||
defined $w or @$self[1..4] = (1,undef,undef,undef), return;
|
||||
my $tt = "image/\L$t";
|
||||
@$self[1..5] = (1, $w, $h, $t, $tt);
|
||||
}
|
||||
return $self->[$elt];
|
||||
};
|
||||
no strict 'refs';
|
||||
*{$fields[$elt]} = $r;
|
||||
}
|
||||
|
||||
for my $elt ( qw( title track artist album year genre comment ) ) {
|
||||
no strict 'refs';
|
||||
*$elt = sub (;$) { return };
|
||||
}
|
||||
|
||||
1;
|
148
fhem/FHEM/lib/MP3/Tag/Inf.pm
Normal file
148
fhem/FHEM/lib/MP3/Tag/Inf.pm
Normal file
@ -0,0 +1,148 @@
|
||||
package MP3::Tag::Inf;
|
||||
|
||||
use strict;
|
||||
use vars qw /$VERSION @ISA/;
|
||||
|
||||
$VERSION="1.00";
|
||||
@ISA = 'MP3::Tag::__hasparent';
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
MP3::Tag::Inf - Module for parsing F<.inf> files associated with music tracks.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $mp3inf = MP3::Tag::Inf->new($filename); # Name of MP3 or .INF file
|
||||
# or an MP3::Tag::File object
|
||||
|
||||
($title, $artist, $album, $year, $comment, $track) = $mp3inf->parse();
|
||||
|
||||
see L<MP3::Tag>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
MP3::Tag::Inf is designed to be called from the MP3::Tag module.
|
||||
|
||||
It parses the content of F<.inf> file (created, e.g., by cdda2wav).
|
||||
|
||||
=over 4
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
# Constructor
|
||||
|
||||
sub new_with_parent {
|
||||
my ($class, $filename, $parent) = @_;
|
||||
my $self = bless {parent => $parent}, $class;
|
||||
|
||||
$filename = $filename->filename if ref $filename;
|
||||
my $ext_rex = $self->get_config('extension')->[0];
|
||||
$filename =~ s/($ext_rex)|$/.inf/; # replace extension
|
||||
return unless -f $filename;
|
||||
$self->{filename} = $filename;
|
||||
$self;
|
||||
}
|
||||
|
||||
# Destructor
|
||||
|
||||
sub DESTROY {}
|
||||
|
||||
=item parse()
|
||||
|
||||
($title, $artist, $album, $year, $comment, $track) =
|
||||
$mp3inf->parse($what);
|
||||
|
||||
parse_filename() extracts information about artist, title, track number,
|
||||
album and year from the F<.inf> file. $what is optional; it maybe title,
|
||||
track, artist, album, year or comment. If $what is defined parse() will return
|
||||
only this element.
|
||||
|
||||
As a side effect of this call, $mp3inf->{info} is set to the hash reference
|
||||
with the content of particular elements of the F<.inf> file. Typically present
|
||||
are the following fields:
|
||||
|
||||
CDINDEX_DISCID
|
||||
CDDB_DISCID
|
||||
MCN
|
||||
ISRC
|
||||
Albumperformer
|
||||
Performer
|
||||
Albumtitle
|
||||
Tracktitle
|
||||
Tracknumber
|
||||
Trackstart
|
||||
Tracklength
|
||||
Pre-emphasis
|
||||
Channels
|
||||
Copy_permitted
|
||||
Endianess
|
||||
Index
|
||||
|
||||
The following fields are also recognized:
|
||||
|
||||
Year
|
||||
Trackcomment
|
||||
|
||||
=cut
|
||||
|
||||
sub return_parsed {
|
||||
my ($self,$what) = @_;
|
||||
if (defined $what) {
|
||||
return $self->{parsed}{album} if $what =~/^al/i;
|
||||
return $self->{parsed}{artist} if $what =~/^a/i;
|
||||
return $self->{parsed}{track} if $what =~/^tr/i;
|
||||
return $self->{parsed}{year} if $what =~/^y/i;
|
||||
return $self->{parsed}{genre} if $what =~/^g/i;
|
||||
if ($what =~/^cddb_id/i) {
|
||||
my $o = $self->{parsed}{Cddb_discid};
|
||||
$o =~ s/^0x//i if $o;
|
||||
return $o;
|
||||
}
|
||||
return $self->{parsed}{Cdindex_discid} if $what =~/^cdindex_id/i;
|
||||
return $self->{parsed}{comment}if $what =~/^c/i;
|
||||
return $self->{parsed}{title};
|
||||
}
|
||||
|
||||
return $self->{parsed} unless wantarray;
|
||||
return map $self->{parsed}{$_} , qw(title artist album year comment track);
|
||||
}
|
||||
|
||||
sub parse {
|
||||
my ($self,$what) = @_;
|
||||
|
||||
$self->return_parsed($what) if exists $self->{parsed};
|
||||
local *IN;
|
||||
open IN, "< $self->{filename}" or die "Error opening `$self->{filename}': $!";
|
||||
my $e;
|
||||
if ($e = $self->get_config('decode_encoding_inf') and $e->[0]) {
|
||||
eval "binmode IN, ':encoding($e->[0])'"; # old binmode won't compile...
|
||||
}
|
||||
my ($line, %info);
|
||||
for $line (<IN>) {
|
||||
$self->{info}{ucfirst lc $1} = $2
|
||||
if $line =~ /^(\S+)\s*=\s*['"]?(.*?)['"]?\s*$/;
|
||||
}
|
||||
close IN or die "Error closing `$self->{filename}': $!";
|
||||
my %parsed;
|
||||
@parsed{ qw( title artist album year comment track Cddb_discid Cdindex_discid ) } =
|
||||
@{ $self->{info} }{ qw( Tracktitle Performer Albumtitle
|
||||
Year Trackcomment Tracknumber
|
||||
Cddb_discid Cdindex_discid) };
|
||||
$parsed{artist} = $self->{info}{Albumperformer}
|
||||
unless defined $parsed{artist};
|
||||
$self->{parsed} = \%parsed;
|
||||
$self->return_parsed($what);
|
||||
}
|
||||
|
||||
for my $elt ( qw( title track artist album comment year genre cddb_id cdindex_id ) ) {
|
||||
no strict 'refs';
|
||||
*$elt = sub (;$) {
|
||||
my $self = shift;
|
||||
$self->parse($elt, @_);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
52
fhem/FHEM/lib/MP3/Tag/LastResort.pm
Normal file
52
fhem/FHEM/lib/MP3/Tag/LastResort.pm
Normal file
@ -0,0 +1,52 @@
|
||||
package MP3::Tag::LastResort;
|
||||
|
||||
use strict;
|
||||
use vars qw /$VERSION @ISA/;
|
||||
|
||||
$VERSION="1.00";
|
||||
@ISA = 'MP3::Tag::__hasparent';
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
MP3::Tag::LastResort - Module for using other fields to fill autoinfo fields.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $mp3extra = MP3::Tag::LastResort::new_with_parent($filename, $parent);
|
||||
$comment = $mp3inf->comment();
|
||||
|
||||
see L<MP3::Tag>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
MP3::Tag::LastResort is designed to be called from the MP3::Tag module.
|
||||
|
||||
It uses the artist_collection() as comment() if comment() is not otherwise
|
||||
defined.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
# Constructor
|
||||
|
||||
sub new_with_parent {
|
||||
my ($class, $filename, $parent) = @_;
|
||||
bless {parent => $parent}, $class;
|
||||
}
|
||||
|
||||
# Destructor
|
||||
|
||||
sub DESTROY {}
|
||||
|
||||
for my $elt ( qw( title track artist album year genre ) ) {
|
||||
no strict 'refs';
|
||||
*$elt = sub (;$) { return };
|
||||
}
|
||||
|
||||
sub comment {
|
||||
shift->{parent}->artist_collection()
|
||||
}
|
||||
|
||||
1;
|
274
fhem/FHEM/lib/MP3/Tag/ParseData.pm
Normal file
274
fhem/FHEM/lib/MP3/Tag/ParseData.pm
Normal file
@ -0,0 +1,274 @@
|
||||
package MP3::Tag::ParseData;
|
||||
|
||||
use strict;
|
||||
use vars qw /$VERSION @ISA/;
|
||||
|
||||
$VERSION="1.00";
|
||||
@ISA = 'MP3::Tag::__hasparent';
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
MP3::Tag::ParseData - Module for parsing arbitrary data associated with music files.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
# parses the file name according to one of the patterns:
|
||||
$mp3->config('parse_data', ['i', '%f', '%t - %n - %a.%e', '%t - %y.%e']);
|
||||
$title = $mp3->title;
|
||||
|
||||
see L<MP3::Tag>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
MP3::Tag::ParseData is designed to be called from the MP3::Tag module.
|
||||
|
||||
Each option of configuration item C<parse_data> should be of the form
|
||||
C<[$flag, $string, $pattern1, ...]>. For each of the option, patterns of
|
||||
the option are matched agains the $string of the option, until one of them
|
||||
succeeds. The information obtained from later options takes precedence over
|
||||
the information obtained from earlier ones.
|
||||
|
||||
The meaning of the patterns is the same as for parse() or parse_rex() methods
|
||||
of C<MP3::Tag>. Since the default for C<parse_data> is empty, by default this
|
||||
handler has no effect.
|
||||
|
||||
$flag is split into 1-character-long flags (unknown flags are ignored):
|
||||
|
||||
=over
|
||||
|
||||
=item C<i>
|
||||
|
||||
the string-to-parse is interpolated first;
|
||||
|
||||
=item C<f>
|
||||
|
||||
the string-to-parse is interpreted as the name of the file to read;
|
||||
|
||||
=item C<F>
|
||||
|
||||
added to C<f>, makes it non-fatal if the file does not exist;
|
||||
|
||||
=item C<B>
|
||||
|
||||
the file should be read in C<binary> mode;
|
||||
|
||||
=item C<n>
|
||||
|
||||
the string-to-parse is interpreted as collection of lines, one per track;
|
||||
|
||||
=item C<l>
|
||||
|
||||
the string-to-parse is interpreted as collection of lines, and the first
|
||||
matched is chosen;
|
||||
|
||||
=item C<I>
|
||||
|
||||
the resulting string is interpolated before parsing.
|
||||
|
||||
=item C<b>
|
||||
|
||||
Do not strip the leading and trailing blanks. (With output to file,
|
||||
the output is performed in binary mode too.)
|
||||
|
||||
=item C<R>
|
||||
|
||||
the patterns are considered as regular expressions.
|
||||
|
||||
=item C<m>
|
||||
|
||||
one of the patterns must match.
|
||||
|
||||
=item C<o>, C<O>, C<D>
|
||||
|
||||
With C<o> or C<O> interpret the pattern as a name of file to output
|
||||
parse-data to. With C<O> the name of output file is interpolated.
|
||||
When C<D> is present, intermediate directories are created.
|
||||
|
||||
=item C<z>
|
||||
|
||||
Do not ignore a field even if the result is a 0-length string.
|
||||
|
||||
=back
|
||||
|
||||
Unless C<b> option is given, the resulting values have starting and
|
||||
trailing whitespace trimmed. (Actually, split()ing into lines is done
|
||||
using the configuration item C<parse_split>; it defaults to C<"\n">.)
|
||||
|
||||
If the configuration item C<parse_data> has multiple options, the $strings
|
||||
which are interpolated will use information set by preceding options;
|
||||
similarly, any interolated option may use information obtained by other
|
||||
handlers - even if these handers are later in the pecking order than
|
||||
C<MP3::Tag::ParseData> (which by default is the first handler). For
|
||||
example, with
|
||||
|
||||
['i', '%t' => '%t (%y)'], ['i', '%t' => '%t - %c']
|
||||
|
||||
and a local CDDB file which identifies title to C<'Merry old - another
|
||||
interpretation (1905)'>, the first field will interpolate C<'%t'> into this
|
||||
title, then will split it into the year and the rest. The second field will
|
||||
split the rest into a title-proper and comment.
|
||||
|
||||
Note that one can use fields of the form
|
||||
|
||||
['mz', 'This is a forced title' => '%t']
|
||||
|
||||
to force particular values for parts of the MP3 tag.
|
||||
|
||||
The usual methods C<artist>, C<title>, C<album>, C<comment>, C<year>, C<track>,
|
||||
C<year> can be used to access the results of the parse.
|
||||
|
||||
It is possible to set individual id3v2 frames; use %{TIT1} or
|
||||
some such. Setting to an empty string deletes the frame if config
|
||||
parameter C<id3v2_frame_empty_ok> is false (the default value).
|
||||
Setting ID3v2 frames uses the same translation rules as
|
||||
select_id3v2_frame_by_descr().
|
||||
|
||||
=head2 SEE ALSO
|
||||
|
||||
The flags C<i f F B l m I b> are identical to flags of the method
|
||||
interpolate_with_flags() of MP3::Tag (see L<MP3::Tag/"interpolate_with_flags">).
|
||||
Essentially, the other flags (C<R m o O D z>) are applied to the result of
|
||||
calling the latter method.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
# Constructor
|
||||
|
||||
sub new_with_parent {
|
||||
my ($class, $filename, $parent) = @_;
|
||||
$filename = $filename->filename if ref $filename;
|
||||
bless {filename => $filename, parent => $parent}, $class;
|
||||
}
|
||||
|
||||
# Destructor
|
||||
|
||||
sub DESTROY {}
|
||||
|
||||
sub parse_one {
|
||||
my ($self, $in) = @_;
|
||||
|
||||
my @patterns = @$in; # Apply shift to a copy, not original...
|
||||
my $flags = shift @patterns;
|
||||
my $data = shift @patterns;
|
||||
|
||||
my @data = $self->{parent}->interpolate_with_flags($data, $flags);
|
||||
my $res;
|
||||
my @opatterns = @patterns;
|
||||
|
||||
if ($flags =~ /[oO]/) {
|
||||
@patterns = map $self->{parent}->interpolate($_), @patterns
|
||||
if $flags =~ /O/;
|
||||
return unless length $data[0] or $flags =~ /z/;
|
||||
for my $file (@patterns) {
|
||||
if ($flags =~ /D/ and $file =~ m,(.*)[/\\],s) {
|
||||
require File::Path;
|
||||
File::Path::mkpath($1);
|
||||
}
|
||||
open OUT, "> $file" or die "open(`$file') for write: $!";
|
||||
if ($flags =~ /b/) {
|
||||
binmode OUT;
|
||||
} else {
|
||||
my $e;
|
||||
if ($e = $self->get_config('encode_encoding_files') and $e->[0]) {
|
||||
eval "binmode OUT, ':encoding($e->[0])'"; # old binmode won't compile...
|
||||
}
|
||||
}
|
||||
local ($/, $,) = ('', '');
|
||||
print OUT $data[0];
|
||||
close OUT or die "close(`$file') for write: $!";
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ($flags =~ /R/) {
|
||||
@patterns = map $self->{parent}->parse_rex_prepare($_), @patterns;
|
||||
} else {
|
||||
@patterns = map $self->{parent}->parse_prepare($_), @patterns;
|
||||
}
|
||||
for $data (@data) {
|
||||
my $pattern;
|
||||
for $pattern (@patterns) {
|
||||
last if $res = $self->{parent}->parse_rex_match($pattern, $data);
|
||||
}
|
||||
last if $res;
|
||||
}
|
||||
{ local $" = "' `";
|
||||
die "Pattern(s) `@opatterns' did not succeed vs `@data'"
|
||||
if $flags =~ /m/ and not $res;
|
||||
}
|
||||
my $k;
|
||||
for $k (keys %$res) {
|
||||
unless ($flags =~ /b/) {
|
||||
$res->{$k} =~ s/^\s+//;
|
||||
$res->{$k} =~ s/\s+$//;
|
||||
}
|
||||
delete $res->{$k} unless length $res->{$k} or $flags =~ /z/;
|
||||
}
|
||||
return unless $res and keys %$res;
|
||||
return $res;
|
||||
}
|
||||
|
||||
# XXX Two decisions: which entries can access results of which ones,
|
||||
# and which entries overwrite which ones; the user can reverse one of them
|
||||
# by sorting config('parse_data') in the opposite order; but not both.
|
||||
# Only practice can show whether our choice is correct... How to customize?
|
||||
|
||||
sub parse { # Later recipies can access results of earlier ones.
|
||||
my ($self,$what) = @_;
|
||||
|
||||
return $self->{parsed}->{$what} # Recalculate during recursive calls
|
||||
if not $self->{parsing} and exists $self->{parsed}; # Do not recalc after finish
|
||||
|
||||
my $data = $self->get_config('parse_data');
|
||||
return unless $data and @$data;
|
||||
my $parsing = $self->{parsing};
|
||||
local $self->{parsing};
|
||||
|
||||
my (%res, $d, $c);
|
||||
for $d (@$data) {
|
||||
$c++;
|
||||
$self->{parsing} = $c;
|
||||
# Protect against recursion: later $d can access results of earlier ones
|
||||
last if $parsing and $parsing <= $c;
|
||||
my $res = $self->parse_one($d);
|
||||
# warn "Failure: [@$d]\n" unless $res;
|
||||
# Set user-scratch space data immediately
|
||||
for my $k (keys %$res) {
|
||||
if ($k eq 'year') { # Do nothing
|
||||
} elsif ($k =~ /^U(\d{1,2})$/) {
|
||||
$self->{parent}->set_user($1, delete $res->{$k})
|
||||
} elsif (0 and $k =~ /^\w{4}(\d{2,})?$/) {
|
||||
if (length $res->{$k}
|
||||
or $self->get_config('id3v2_frame_empty_ok')->[0]) {
|
||||
$self->{parent}->set_id3v2_frame($k, delete $res->{$k})
|
||||
} else {
|
||||
delete $res->{$k};
|
||||
$self->{parent}->set_id3v2_frame($k); # delete
|
||||
}
|
||||
} elsif ($k =~ /^\w{4}(\d{2,}|(?:\(([^()]*(?:\([^()]+\)[^()]*)*)\))?(?:\[(\\.|[^]\\]*)\])?)$/) {
|
||||
my $r = delete $res->{$k};
|
||||
$r = undef unless length $r or $self->get_config('id3v2_frame_empty_ok')->[0];
|
||||
if (defined $r or $self->{parent}->_get_tag('ID3v2')) {
|
||||
$self->{parent}->select_id3v2_frame_by_descr($k, $r);
|
||||
}
|
||||
}
|
||||
}
|
||||
# later ones overwrite earlier
|
||||
%res = (%res, %$res) if $res;
|
||||
}
|
||||
$self->{parsed} = \%res;
|
||||
# return unless keys %res;
|
||||
return $self->{parsed}->{$what};
|
||||
}
|
||||
|
||||
for my $elt ( qw( title track artist album comment year genre ) ) {
|
||||
no strict 'refs';
|
||||
*$elt = sub (;$) {
|
||||
my $self = shift;
|
||||
$self->parse($elt, @_);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
1217
fhem/FHEM/lib/Normalize/Text/Music_Fields.pm
Normal file
1217
fhem/FHEM/lib/Normalize/Text/Music_Fields.pm
Normal file
File diff suppressed because it is too large
Load Diff
1861
fhem/FHEM/lib/Normalize/Text/Music_Fields/A_Dvor_k.comp
Normal file
1861
fhem/FHEM/lib/Normalize/Text/Music_Fields/A_Dvor_k.comp
Normal file
File diff suppressed because it is too large
Load Diff
2496
fhem/FHEM/lib/Normalize/Text/Music_Fields/A_Schnittke.comp
Normal file
2496
fhem/FHEM/lib/Normalize/Text/Music_Fields/A_Schnittke.comp
Normal file
File diff suppressed because it is too large
Load Diff
2569
fhem/FHEM/lib/Normalize/Text/Music_Fields/D_Shostakovich.comp
Normal file
2569
fhem/FHEM/lib/Normalize/Text/Music_Fields/D_Shostakovich.comp
Normal file
File diff suppressed because it is too large
Load Diff
906
fhem/FHEM/lib/Normalize/Text/Music_Fields/G_Gershwin.comp
Normal file
906
fhem/FHEM/lib/Normalize/Text/Music_Fields/G_Gershwin.comp
Normal file
@ -0,0 +1,906 @@
|
||||
# format = mail-header
|
||||
|
||||
|
||||
# no_opus_no
|
||||
|
||||
|
||||
|
||||
## Note: All orchestral/operatic pieces are orchestrated by Gershwin unless otherwise specified.
|
||||
## * Lullaby (1919), a meditative piece for string quartet. Originally, a class assignment from his music theory teacher.
|
||||
## * Blue Monday, a one-act opera featured in George White's Scandals of 1922, orchestrated by Will Vodery.
|
||||
## + A Suite from Blue Monday for two pianos was later arranged and has been recorded.
|
||||
## + Reorchestrated by Ferde Grofe and retitled 135th Street in 1925.
|
||||
## * Rhapsody in Blue, (1924), his most famous work, a symphonic jazz composition for Paul Whiteman's jazz band & piano , better known in the form orchestrated for full
|
||||
## symphonic orchestra by Ferde Grofe. Featured in numerous films and commercials.
|
||||
|
||||
Title-RAW: Short Story,
|
||||
Title-For: violin and piano
|
||||
Title-Dates: 1925
|
||||
|
||||
##, an arrangement of two other short pieces originally intended to be included with the Three Preludes.
|
||||
## * Concerto in F, (1925), three movements, for piano and orchestra
|
||||
## * Three Preludes, (1926), for piano
|
||||
## * An American In Paris (1928), a symphonic poem with elements of jazz and realistic Parisian sound effects
|
||||
## * Second Rhapsody for Piano and Orchestra (1931), for Piano and Orchestra, based on the score for a musical sequence from Delicious. Working title for the work was Rhapsody
|
||||
## in Rivets.
|
||||
## + The form most commonly heard today is a re-orchestrated version by Robert McBride; most of Gershwin's orchestrations have been simplified. Also, eight measures not by the composer
|
||||
## were added to the recapitulation. Michael Tilson Thomas has been a promulgator of Gershwin's original version.
|
||||
## * Cuban Overture (1932), originally titled Rumba, a tone poem featuring elements of native Cuban dance and folk music; score specifies usage of native Cuban instruments
|
||||
|
||||
Title-RAW: Piano Transcriptions of Eight Songs
|
||||
Title-Dates: 1932
|
||||
|
||||
## * I Got Rhythm Variations (1934), a set of interesting variations on his famous song, for piano and orchestra
|
||||
## + Includes a waltz, an atonal fugue, and experimentation with Asian and jazz influences
|
||||
## * Porgy And Bess, a folk opera (1935) (from the book by DuBose Heyward) about African-American life, now considered a definitive work of the American theater.
|
||||
## + Contains the famous aria "Summertime", in addition to hits like "I Got Plenty of Nothin'" and "It Ain't Necessarily So".
|
||||
## + Porgy and Bess has also been heard in the concert hall, mostly in two orchestral suites, one by Gershwin himself entitled Catfish Row; another suite by Robert Russell
|
||||
## Bennett, Porgy and Bess: A Symphonic Picture is also relatively popular.
|
||||
|
||||
Title-RAW: Walking the Dog
|
||||
Title-Dates: 1937
|
||||
|
||||
##, a humorous piece for orchestra featuring the clarinet. Originally a musical sequence entitled Promenade from the movie Shall We Dance for piano
|
||||
## and chamber orchestra.
|
||||
## + Many other incidental sequences from Shall We Dance were written and (for the most part) orchestrated by Gershwin, among them: Waltz of the Red Balloons and a final
|
||||
## extended 8-minute orchestral passage based on the title song with an intruiging coda hinting at Gershwin forging a new musical path. It is unknown why any of these
|
||||
## compositions have not seen the light of day in the concert hall.
|
||||
## + Most of the musicals Gershwin wrote are also known for their instrumental music, among them the March from Strike Up The Band and overtures to many of his later
|
||||
## shows.
|
||||
|
||||
Title-RAW: Impromptu in Two Keys
|
||||
Title-Dates: publ. posth. in 1973
|
||||
|
||||
##, for piano
|
||||
|
||||
Title-Count: Two
|
||||
Title-Type: Waltzes
|
||||
Title-Key: C major
|
||||
Title-Dates: publ. posth. in 1975
|
||||
|
||||
##, for piano
|
||||
## + Originally a two-piano interlude in Pardon My English on Broadway.
|
||||
|
||||
|
||||
|
||||
## Musical theater credits
|
||||
|
||||
|
||||
|
||||
## Note: All works are musicals produced on Broadway unless specified otherwise.
|
||||
|
||||
|
||||
|
||||
Title-RAW: Half Past Eight (lyrics by Ira Gershwin and Edward B. Perkins). Premiered in Syracuse.
|
||||
Title-Dates: 1919
|
||||
|
||||
Title-RAW: La La Lucille
|
||||
Title-Lyrics-By: Arthur Jackson, B. G. DeSylva and Irving Caesar
|
||||
Title-Dates: 1919
|
||||
|
||||
Title-RAW: Morris Gest
|
||||
Title-Name: Midnight Whirl
|
||||
Title-Lyrics-By: B. G. DeSylva and John Henry Mears
|
||||
Title-Dates: 1919
|
||||
|
||||
Title-RAW: Limehouse Nights
|
||||
Title-Lyrics-By: B. G. DeSylva and John Henry Mears
|
||||
Title-Dates: 1919
|
||||
|
||||
Title-RAW: Poppyland
|
||||
Title-Lyrics-By: B. G. DeSylva and John Henry Mears
|
||||
Title-Dates: 1920
|
||||
|
||||
Title-RAW: George White's Scandals of 1920
|
||||
Title-Lyrics-By: Arthur Jackson
|
||||
Title-Dates: 1920
|
||||
|
||||
Title-RAW: A Dangerous Maid (lyrics by Ira Gershwin). Premiered in Atlantic City.
|
||||
Title-Dates: 1921
|
||||
|
||||
Title-RAW: The Broadway Whirl (co-composed with Harry Tierney, lyrics by Buddy DeSylva, Joseph McCarthy, Richard Carle and John Henry Mears
|
||||
Title-Dates: 1921
|
||||
|
||||
Title-RAW: George White's Scandals of 1921
|
||||
Title-Lyrics-By: Arthur Jackson
|
||||
Title-Dates: 1921
|
||||
|
||||
Title-RAW: George White's Scandals of 1922
|
||||
Title-Lyrics-By: E. Ray Goetz, Ira Gershwin and B. G. DeSylva
|
||||
Title-Dates: 1922
|
||||
|
||||
## + The premiere performance featured the one-act opera Blue Monday with libretto and lyrics by B. G. DeSylva, set in Harlem in a jazz idiom. However, after only one
|
||||
## performance, the opera was withdrawn from the show. Gershwin also wrote seven other songs for the show.
|
||||
|
||||
Title-RAW: Our Nell (co-composed with William Daly, lyrics co-written by Gershwin and Daly)
|
||||
Title-Dates: 1922
|
||||
|
||||
Title-RAW: By and By
|
||||
Title-Lyrics-By: Brian Hooker
|
||||
Title-Dates: 1922
|
||||
|
||||
Title-RAW: Innocent Ingenue Baby (co-composed with William Daly, lyrics by Brian Hooker)
|
||||
Title-Dates: 1923
|
||||
|
||||
Title-RAW: Walking Home with Angeline
|
||||
Title-Lyrics-By: Brian Hooker
|
||||
Title-Dates: 1923
|
||||
|
||||
Title-RAW: The Rainbow (lyrics by Clifford Grey and Brian Hooker). Premiered in London.
|
||||
Title-Dates: 1923
|
||||
|
||||
Title-RAW: George White's Scandals of 1923
|
||||
Title-Lyrics-By: E. Ray Goetz, B. G. DeSylva and Ballard MacDonald
|
||||
Title-Dates: 1923
|
||||
|
||||
Title-RAW: Sweet Little Devil
|
||||
Title-Lyrics-By: B. G. DeSylva
|
||||
Title-Dates: 1924
|
||||
|
||||
Title-RAW: George White's Scandals of 1924
|
||||
Title-Lyrics-By: B. G. DeSylva and Ballard MacDonald
|
||||
Title-Dates: 1924
|
||||
|
||||
Title-RAW: Primrose (lyrics by Desmond Carter and Ira Gershwin). Premiered in London.
|
||||
Title-Dates: 1924
|
||||
|
||||
Title-RAW: Lady, Be Good!
|
||||
Title-Lyrics-By: Ira Gershwin
|
||||
Title-Dates: 1924
|
||||
|
||||
Title-RAW: Tell Me More!
|
||||
Title-Lyrics-By: Ira Gershwin and B. G. DeSylva
|
||||
Title-Dates: 1925
|
||||
|
||||
Title-RAW: Tip-Toes
|
||||
Title-Lyrics-By: Ira Gershwin
|
||||
Title-Dates: 1925
|
||||
|
||||
Title-RAW: Song of the Flame (operetta, lyrics by Otto Harbach and Oscar Hammerstein II, and musical collaboration by Herbert Stothart)
|
||||
Title-Dates: 1925
|
||||
|
||||
Title-RAW: Oh, Kay!
|
||||
Title-Lyrics-By: Ira Gershwin and Howard Dietz
|
||||
Title-Dates: 1926
|
||||
|
||||
## + Includes the famous song, "Someone to Watch Over Me"
|
||||
## + Revived in 1928 and 1990 (the latter with an all-Black cast)
|
||||
|
||||
|
||||
|
||||
Title-RAW: Strike Up The Band
|
||||
Title-Lyrics-By: Ira Gershwin
|
||||
Title-Dates: premiered in Philadelphia 1927, revised Broadway in 1930, revised 1936 for U.C.L.A
|
||||
|
||||
# prev_aka Strike Up The Band
|
||||
|
||||
|
||||
|
||||
## + Revised and produced on Broadway in 1930
|
||||
|
||||
Title-RAW: Funny Face
|
||||
Title-Lyrics-By: Ira Gershwin
|
||||
Title-Dates: 1927
|
||||
|
||||
Title-RAW: Rosalie
|
||||
Title-Lyrics-By: Ira Gershwin and P. G. Wodehouse, co-composed with Sigmund Romberg
|
||||
Title-Dates: 1928
|
||||
|
||||
Title-RAW: Treasure Girl
|
||||
Title-Lyrics-By: Ira Gershwin
|
||||
Title-Dates: 1928
|
||||
|
||||
Title-RAW: Show Girl
|
||||
Title-Lyrics-By: Ira Gershwin and Gus Kahn
|
||||
Title-Dates: 1929
|
||||
|
||||
Title-RAW: Girl Crazy
|
||||
Title-Lyrics-By: Ira Gershwin
|
||||
Title-Dates: 1930
|
||||
|
||||
Title-RAW: Of Thee I Sing
|
||||
Title-Lyrics-By: Ira Gershwin
|
||||
Title-Dates: 1931
|
||||
|
||||
## + Awarded the Pulitzer Prize for Drama for 1932 and was the first musical to win that award, although only Ira Gershwin and the bookwriters were awarded the Prize and
|
||||
## not George Gershwin
|
||||
## + Revived in 1933 and 1952
|
||||
|
||||
Title-RAW: Pardon My English
|
||||
Title-Lyrics-By: Ira Gershwin
|
||||
Title-Dates: 1933
|
||||
|
||||
Title-RAW: Let 'Em Eat Cake
|
||||
Title-Lyrics-By: Ira Gershwin
|
||||
Title-Dates: 1933
|
||||
|
||||
## Let 'Em Eat Cake (lyrics by Ira Gershwin), sequel to Of Thee I Sing (1933)
|
||||
|
||||
Title-RAW: Porgy and Bess
|
||||
Title-Lyrics-By: Ira Gershwin and DuBose Heyward
|
||||
Title-Dates: 1935
|
||||
|
||||
## + Revived on Broadway in 1942, 1943, 1953, 1976 (Houston Grand Opera winner of the Tony Award for Most Innovative Revival of a Musical), and 1983
|
||||
|
||||
|
||||
|
||||
## Works featuring original Gershwin songs for shows by other composers
|
||||
|
||||
|
||||
|
||||
Title-RAW: The Passing Show of 1916 - "Making of a Girl" co-composed with Sigmund Romberg, lyrics by Harold Atteridge
|
||||
Title-Dates: 1916
|
||||
|
||||
Title-RAW: Hitchy-Koo of 1918 - "You-Oo just You", lyrics by Irving Caesar
|
||||
Title-Dates: 1918
|
||||
|
||||
Title-RAW: Ladies First - "(The Real) American Folk Song (is a Rag)", lyrics by Ira Gershwin and "Some Wonderful Sort of Someone", lyrics by Schuyler Greene
|
||||
Title-Dates: 1918
|
||||
|
||||
## * 1919 - Good Morning, Judge - "I was so young (you were so beautiful)", lyrics by Irvine Caesar and Alfred Bryan and "here's more to the kiss than the x-x-x", lyrics by
|
||||
## Irving Caesar
|
||||
|
||||
Title-RAW: The Lady in Red - "Some Wonderful Sort of Someone", lyrics by Schyler Greene and "Something about Love", lyrics by L. Paley
|
||||
Title-Dates: 1919
|
||||
|
||||
Title-RAW: The Capitol Revue - "Come to the Moon", lyrics by L. Paley and Ned Wayburn, "Swanee", lyrics by Irvine Caesar
|
||||
Title-Dates: 1919
|
||||
|
||||
Title-RAW: Dear Mabel - "We're pals", lyrics by Irving Caesar, first performed in Baltimore
|
||||
Title-Dates: 1920
|
||||
|
||||
Title-RAW: Ed Wynn's Carnival - "Oo, how I love you to be loved by you", lyrics by L. Paley
|
||||
Title-Dates: 1920
|
||||
|
||||
Title-RAW: The Sweetheart Shop - "Waiting for the Sun to Come Out", lyrics by Ira Gershwin
|
||||
Title-Dates: 1920
|
||||
|
||||
Title-RAW: Sinbad - "Swanee" (as performed by Al Jolson)
|
||||
Title-Dates: 1920
|
||||
|
||||
Title-RAW: Broadway Brevities of 1920 - "Lu Lu" and "Snowflakes", lyrics by Arthur Jackson and "Spanish love", lyrics by Irving Caesar
|
||||
Title-Dates: 1920
|
||||
|
||||
Title-RAW: Piccadilly to Broadway, songs unpublished
|
||||
Title-Dates: 1920
|
||||
|
||||
Title-RAW: Blue Eyes, songs unpublished
|
||||
Title-Dates: 1921
|
||||
|
||||
Title-RAW: Selwyn's Snapshots of 1921, songs unpublished
|
||||
Title-Dates: 1921
|
||||
|
||||
Title-RAW: The Perfect Fool - "My Log-Cabin Home", lyrics by Irving Caesar and Buddy De Sylva, "No One Else but that Girl of Mine", lyrics by Irving Caesar
|
||||
Title-Dates: 1921
|
||||
|
||||
Title-RAW: The French Doll - "Do it again!", lyrics by Buddy De Sylva
|
||||
Title-Dates: 1922
|
||||
|
||||
Title-RAW: For Goodness Sake - "Someone" and "Tra-la-la", lyrics by Ira Gershwin
|
||||
Title-Dates: 1922
|
||||
|
||||
Title-RAW: The Dancing Girl - "That American Boy of Mine", lyrics by Irving Caesar
|
||||
Title-Dates: 1922
|
||||
|
||||
Title-RAW: Spice of 1922 - "The Yankee Doodle Blues", lyrics by Irving Caesar and Buddy De Sylva
|
||||
Title-Dates: 1922
|
||||
|
||||
Title-RAW: Little Miss Bluebeard (play) - "I won't say I will but I won't say I won't", lyrics by Ira Gershwin and Buddy De Sylva
|
||||
Title-Dates: 1923
|
||||
|
||||
Title-RAW: Nifties of 1923 - "At Half Past Seven", lyrics by Buddy De Sylva, and "Nashville Nightingale", lyrics by Irving Caesar
|
||||
Title-Dates: 1923
|
||||
|
||||
Title-RAW: Americana of 1926 -
|
||||
Title-Name: That Lost Barber Shop Chord
|
||||
Title-Dates: 1926
|
||||
|
||||
Title-RAW: 9:15 Revue
|
||||
Title-Dates: 1930
|
||||
|
||||
Title-RAW: The Show is On -
|
||||
Title-Name: By Strauss
|
||||
Title-Dates: 1936
|
||||
|
||||
## + Revived in 1937
|
||||
|
||||
|
||||
|
||||
## Works interpolating Gershwin songs posthumously:
|
||||
|
||||
|
||||
|
||||
Title-RAW: At Home With Ethel Waters -
|
||||
Title-Name: Lady Be Good
|
||||
Title-Dates: 1953
|
||||
|
||||
Title-RAW: Mr. Wonderful
|
||||
Title-Dates: 1956
|
||||
|
||||
### "I Got Rhythm" a hit single for pop vocal group The Happenings (1967)
|
||||
### My One And Only - an adaptation of the music from Funny Face (1983)
|
||||
### Uptown...It's Hot! - "Lady Be Good" (1986)
|
||||
### Crazy For You - musical adapting George and Ira Gershwin Tin Pan Alley and Broadway songs (1992)
|
||||
## + Awarded the Tony Award for Best Musical
|
||||
### The Gershwins' Fascinating Rhythm - revue with songs by George and Ira Gershwin (1999)
|
||||
## * 2001 - George Gershwin Alone - one-man play by Hershey Felder, who portrayed Gershwin, incorporating "Swanee" from Sinbad (lyrics by Irving Caesar), "Embraceable You" from
|
||||
## Girl Crazy (lyrics by Ira Gershwin), "Someone to Watch Over Me" from Oh, Kay! (lyrics by Ira Gershwin), "Bess, You is My Woman Now" from Porgy and Bess
|
||||
## (lyrics by DuBose Heyward and Ira Gershwin), An American in Paris and Rhapody in Blue.
|
||||
### Elaine Stritch at Liberty - But Not For Me (2002)
|
||||
### Back From Broadway - one-time concert featuring songs by George Gershwin (2002)
|
||||
|
||||
|
||||
|
||||
## Musical films
|
||||
|
||||
|
||||
|
||||
Title-RAW: The Sunshine Trail - theme song of same title (lyrics by Ira Gershwin), as well as accompaniment music for silent film
|
||||
Title-Dates: 1923
|
||||
|
||||
Title-RAW: Delicious
|
||||
Title-Lyrics-By: Ira Gershwin
|
||||
Title-Dates: 1931
|
||||
|
||||
Title-RAW: Shall We Dance?
|
||||
Title-Lyrics-By: Ira Gershwin
|
||||
Title-Dates: 1937
|
||||
|
||||
Title-RAW: A Damsel in Distress
|
||||
Title-Lyrics-By: Ira Gershwin
|
||||
Title-Dates: 1937
|
||||
|
||||
Title-RAW: Goldwyn Follies
|
||||
Title-Lyrics-By: Ira Gershwin
|
||||
Title-Dates: 1938
|
||||
|
||||
## + Gershwin died during the filming. Vernon Duke completed and adapted Gerhwin's songs, and composed some additional ones.
|
||||
|
||||
Title-RAW: The Shocking Miss Pilgrim (Kay Swift adapted a number of unpublished Gershwin melodies and Ira Gershwin wrote the lyrics.)
|
||||
Title-Dates: 1947
|
||||
|
||||
Title-RAW: Kiss Me, Stupid (adaptations of unpublished Gershwin songs with lyrics by Ira Gershwin.)
|
||||
Title-Dates: 1964
|
||||
|
||||
|
||||
|
||||
## Miscellaneous Songs
|
||||
|
||||
|
||||
|
||||
Title-RAW: When you want 'em, you can't get 'em, when you've got 'em, you don't want 'em
|
||||
Title-Lyrics-By: M. Roth
|
||||
Title-Dates: 1916
|
||||
|
||||
Title-RAW: The Love of a Wife
|
||||
Title-Lyrics-By: Arthur Jackson and B. G. De Sylva
|
||||
Title-Dates: 1919
|
||||
|
||||
Title-RAW: Yan-Kee
|
||||
Title-Lyrics-By: Irving Caesar
|
||||
Title-Dates: 1920
|
||||
|
||||
Title-RAW: Dixie Rose
|
||||
Title-Lyrics-By: Irving Caesar and B. G. De Sylva
|
||||
Title-Dates: 1921
|
||||
|
||||
Title-RAW: In the Heart of a Geisha
|
||||
Title-Lyrics-By: Fred Fisher
|
||||
Title-Dates: 1921
|
||||
|
||||
Title-RAW: Swanee Rose
|
||||
Title-Lyrics-By: Irving Caesar and B. G. De Sylva
|
||||
Title-Dates: 1921
|
||||
|
||||
Title-RAW: Tomale (I'm hot for you)
|
||||
Title-Lyrics-By: B. G. De Sylva
|
||||
Title-Dates: 1921
|
||||
|
||||
Title-RAW: Harlem River Chanty and It's a great little world!
|
||||
Title-Lyrics-By: Ira Gershwin, originally composed for Tip-Toes on Broadway but not used
|
||||
Title-Dates: 1925
|
||||
|
||||
Title-RAW: Murderous Monty (and Light-Fingered Jane)
|
||||
Title-Lyrics-By: Desmond Carter, composed for London production of Tell Me More.
|
||||
Title-Dates: 1925
|
||||
|
||||
Title-RAW: I'd rather charleston
|
||||
Title-Lyrics-By: Desmond Carter, composed for London production of Lady Be Good.
|
||||
Title-Dates: 1926
|
||||
|
||||
Title-RAW: Beautiful gypsy and Rosalie (originally composed for Rosalie on Broadway, but not used)
|
||||
Title-Dates: 1928
|
||||
|
||||
Title-RAW: Feeling Sentimental (originally composed for Show Girl on Broadway, but not used)
|
||||
Title-Dates: 1929
|
||||
|
||||
Title-RAW: In the Mandarin's Orchid Garden
|
||||
Title-Dates: 1929
|
||||
|
||||
Title-RAW: Mischa, Yascha, Toscha, Sascha (originally composed for the musical film Delicious, but not used.
|
||||
Title-Dates: 1931
|
||||
|
||||
## + This is Gershwin's only finished work based on a Jewish theme, and the title is a reference to the first names of four Jewish-Russian violinists, Mischa Elman,
|
||||
## Jascha Heifetz, Toscha Seidel and Sascha Jacobsen.
|
||||
|
||||
Title-RAW: You've got what gets me (for 1st film version of Girl Crazy)
|
||||
Title-Dates: 1932
|
||||
|
||||
Title-RAW: Till Then
|
||||
Title-Dates: 1933
|
||||
|
||||
Title-RAW: King of Swing
|
||||
Title-Lyrics-By: Al Stillman
|
||||
Title-Dates: 1936
|
||||
|
||||
Title-RAW: Strike up the band for U.C.L.A (to the same music as the song Strike Up The Band)
|
||||
Title-Dates: 1936
|
||||
|
||||
|
||||
|
||||
Title-RAW: Hi-Ho!
|
||||
Title-Lyrics-By: Ira Gershwin
|
||||
Title-Dates: 1937
|
||||
|
||||
## originally composed for Shall We Dance, but not used
|
||||
|
||||
|
||||
|
||||
Title-RAW: Just Another Rhumba
|
||||
Title-Lyrics-By: Ira Gershwin, originally composed for The Goldwyn Follies, but not used
|
||||
Title-Dates: 1938
|
||||
|
||||
Title-RAW: Dawn of a New Day
|
||||
Title-Dates: 1938
|
||||
|
||||
|
||||
|
||||
## Commercial Works for Piano
|
||||
|
||||
|
||||
|
||||
Title-RAW: Rialto Ripples - rag
|
||||
Title-Dates: 1918
|
||||
|
||||
## * early 1920s - Three-Quarter Blues (Irish Waltz)
|
||||
|
||||
Title-RAW: Swiss Miss (arrangement of a song from Lady Be Good)
|
||||
Title-Dates: 1926
|
||||
|
||||
Title-RAW: Merry Andrew (arrangement of a dance piece from Rosalie)
|
||||
Title-Dates: 1928
|
||||
|
||||
Title-RAW: George Gershwin's Song-Book (arrangements of refrains from Gershwin songs)
|
||||
Title-Dates: 1932
|
||||
|
||||
|
||||
|
||||
### ==### PIANO //
|
||||
|
||||
Title: 3 Preludes for Piano (1926) (transcr. for vn. and pf. by Heifetz)
|
||||
|
||||
Title: Three Preludes for Piano (1926) (transcr. for vn. and pf. by Heifetz)
|
||||
|
||||
Title-Count: 3
|
||||
Title-Type: Preludes
|
||||
Title-For: Piano
|
||||
Title-Dates: 1926
|
||||
|
||||
Title-Count: Three
|
||||
Title-Type: Preludes
|
||||
Title-For: Piano
|
||||
Title-Dates: 1926
|
||||
|
||||
Title: Prelude No. 1 for Piano (1926) - Allegro ben ritmato e deciso
|
||||
|
||||
Title: Prelude No. 2 for Piano (1926) - Andante con moto e poco rubato
|
||||
|
||||
Title: Prelude No. 3 for Piano (1926) - Allegro ben ritmato e deciso
|
||||
|
||||
### ==### MUSICALS //
|
||||
### The Passing Show of 1916
|
||||
### ###MUSICALS //
|
||||
### La La Lucille (1919)
|
||||
### ###MUSICALS //
|
||||
### George White's Scandals (1920--1924)
|
||||
### ###MUSICALS //
|
||||
### A Dangerous Maid (1921)
|
||||
### ###MUSICALS //
|
||||
### Sweet Little Devil (1924)
|
||||
### ###MUSICALS //
|
||||
### Primrose (1924)
|
||||
### ###MUSICALS //
|
||||
### Lady, Be Good! (1924)
|
||||
### ###MUSICALS //
|
||||
### Song of the Flame (1925)
|
||||
### ###MUSICALS //
|
||||
### Tell Me More (1925)
|
||||
### ###MUSICALS //
|
||||
### Tip Toes (1925)
|
||||
### ###MUSICALS //
|
||||
### Oh, Kay! (1926, lyrics by P. G. Wodehouse)
|
||||
### ###MUSICALS //
|
||||
### Strike up the Band (1927, 2nd vers. 1930)
|
||||
### ###MUSICALS //
|
||||
### Funny Face (1927)
|
||||
### ###MUSICALS //
|
||||
### Rosalie (1928)
|
||||
### ###MUSICALS //
|
||||
### Treasure Girl (1928)
|
||||
### ###MUSICALS //
|
||||
### Show Girl (1929)
|
||||
### ###MUSICALS //
|
||||
### Girl Crazy (1930)
|
||||
### ###MUSICALS //
|
||||
### Of Thee I Sing (1931, lyrics by George F. Kaufman)
|
||||
### ###MUSICALS //
|
||||
### Pardon my English (1933)
|
||||
### ###MUSICALS //
|
||||
### Let 'em eat Cake (1933)
|
||||
### ==### SONGS //
|
||||
### ## Among the best of hundreds of songs are Swanee; The Man I Love; Embraceable You; I Got Rhythm; Fascinating Rhythm; 'S Wonderful; Lady Be Good; and Love Walked In. The popular Summertime is from Porgy and Bess
|
||||
### ###FILMS //
|
||||
### Delicious (1931)
|
||||
### ###FILMS //
|
||||
### Shall We Dance?; A Damsel in Distress (1937)
|
||||
### ###FILMS //
|
||||
### The Goldwyn Follies (1938)
|
||||
### ###FILMS //
|
||||
### The Shocking Miss Pilgrim (1946)
|
||||
### ###FILMS //
|
||||
### Kiss Me, Stupid (1964)
|
||||
### ###OPERAS //
|
||||
|
||||
Title-RAW: Blue Monday
|
||||
Title-Dates: 1-act; item in George White's Scandals 1922 but withdrawn after 1 perf.; retitled 135th Street and revived Miami 1970
|
||||
|
||||
### ###OPERAS //
|
||||
### Porgy and Bess (1934--1935)
|
||||
### ###ORCH. //
|
||||
|
||||
Title-RAW: Rhapsody in Blue (pf. and orch.)
|
||||
Title-Dates: 1924
|
||||
|
||||
### ###ORCH. //
|
||||
|
||||
Title-Type: Piano concerto
|
||||
Title-Key: F major
|
||||
Title-Dates: 1925
|
||||
|
||||
### ###ORCH. //
|
||||
|
||||
Title-RAW: An American in Paris
|
||||
Title-Dates: 1928
|
||||
|
||||
### ###ORCH. //
|
||||
|
||||
Title-RAW: Second Rhapsody for Piano and orch. (working title "Rhapsody in Rivets")
|
||||
Title-Dates: 1931
|
||||
|
||||
### ###ORCH. //
|
||||
|
||||
Title-RAW: Cuban Overture
|
||||
Title-Dates: 1932
|
||||
|
||||
### ###ORCH. //
|
||||
|
||||
|
||||
|
||||
Title-RAW: "I Got Rhythm" Variations for Piano and orch.
|
||||
Title-Dates: 1934
|
||||
|
||||
# prev_aka Variations on "I Got Rhythm"
|
||||
|
||||
|
||||
|
||||
###
|
||||
###
|
||||
### ## http://www.gershwinfan.com/works.html
|
||||
###
|
||||
### Since I Found You (1913)
|
||||
### When You Want 'Em, You Can't Get 'Em; When You've Got 'Em, You Don't Want 'Em (1916)
|
||||
### ## The Passing Show of 1916 (1916)
|
||||
### Rialto Ripples (1917)
|
||||
### Beautiful Bird (1917)
|
||||
### You Are Not the Girl (1917)
|
||||
### Hitchy Koo of 1918 (1918)
|
||||
### The Real American Folk Song (Is a Rag) (1918)
|
||||
### Kitchenette (1918)
|
||||
### If You Only Knew (1918)
|
||||
### There's Magic in the Air (1918)
|
||||
### When There's a Chance to Dance (1918)
|
||||
### ## La, La, Lucille (1919)
|
||||
### Morris Gest Midnight Whirl (1919)
|
||||
### Lullaby (1919)
|
||||
### Good Morning, Judge (1919)
|
||||
### The Lady in Red (1919)
|
||||
### Capitol Revue (1919)
|
||||
### George White's Scandals of 1920 (1920)
|
||||
### Piccadilly to Broadway (1920)
|
||||
### For No Reason at All (1920)
|
||||
### Mischa, Jascha, Toscha, Sascha (1920)
|
||||
### Waiting for the Sun to Come Out (1920)
|
||||
### Back Home (1920)
|
||||
### I Want to Be Wanted by You (1920)
|
||||
### Ed Wynn's Carnival (1920)
|
||||
### Sinbad (1920)
|
||||
### Broadway Brevities of 1920 (1920)
|
||||
### George White's Scandals of 1921 (1921)
|
||||
### The Perfect Fool (1921)
|
||||
### Blue Eyes (1921)
|
||||
### Selwyn's Snapshots of 1921 (1921)
|
||||
### George White's Scandals of 1922 (1922)
|
||||
### ## Blue Monday (one-act opera) (1922)
|
||||
### Molly on the Shore (1922)
|
||||
### For Goodness Sake (1922)
|
||||
### A New Step Ev'ry Day a/k/a Stairway to Paradise (1922)
|
||||
### Our Nell (1922)
|
||||
### The French Doll (1922)
|
||||
### ## A Dangerous Maid (1921)
|
||||
### Phoebe (1921)
|
||||
### Spice of 1922 (1922)
|
||||
### The Rainbow (1923)
|
||||
### George White's Scandals of 1923 (1923)
|
||||
### The Dancing Girl (1923)
|
||||
### Nifties of 1923 (1923)
|
||||
### I Won't Say I Will but I Won't Say I Won't (1923)
|
||||
### The Sunshine Trail (1923)
|
||||
### ## Rhapsody in Blue (1924)
|
||||
### George White's Scandals of 1924 (1924)
|
||||
### ## Lady, Be Good! (1924)
|
||||
### ## Sweet Little Devil (1924)
|
||||
### ## Primrose (1924)
|
||||
### ## Concerto in F (1925)
|
||||
### ## Song of the Flame (1925)
|
||||
### Short Story (1925)
|
||||
### ## Tell Me More (1925)
|
||||
### ## Tip-Toes (1925)
|
||||
### Preludes for Piano (1926)
|
||||
### Americana (1926)
|
||||
### ## Oh, Kay! (1926)
|
||||
### ## Strike Up the Band (1927)
|
||||
### ## Funny Face (1927)
|
||||
### ## Treasure Girl (1928)
|
||||
### ## An American in Paris (1928)
|
||||
### ## Rosalie (1928)
|
||||
### ## Show Girl (1929)
|
||||
### Impromptu in Two Keys (1929)
|
||||
### Three-Quarter Blues (1929)
|
||||
### East is West (1929)
|
||||
### 9:15 Review (1930)
|
||||
### ## Girl Crazy (1930)
|
||||
### Strike Up the Band (revision) (1930)
|
||||
### ## Of Thee I Sing (1931)
|
||||
### ## Delicious (1931)
|
||||
### George Gershwin's Song-Book (1932)
|
||||
### ## Second Rhapsody (1932)
|
||||
### ## Cuban Overture (1932)
|
||||
### Girl Crazy (1932)
|
||||
### ## Pardon My English (1933)
|
||||
### ## Let 'Em Eat Cake (1933)
|
||||
### ## Variations on I Got Rhythm (1934)
|
||||
### ## Porgy and Bess (1935)
|
||||
### The Show is On (1936)
|
||||
### Suite from Porgy and Bess (1936)
|
||||
### ## Shall We Dance? (1937)
|
||||
### A Damsel in Distress (1937)
|
||||
### ## The Goldwyn Follies (1937)
|
||||
|
||||
|
||||
|
||||
Title: Summertime (Act I Scene 1)
|
||||
|
||||
Title: A Woman is a Sometime Thing (Act I Scene 1)
|
||||
|
||||
|
||||
|
||||
Title: My Man's Gone Now (Act I Scene 2)
|
||||
|
||||
# prev_aka MY MANS GONE NOW
|
||||
|
||||
|
||||
|
||||
Title: It Take a Long Pull to Get There (Act II Scene 1)
|
||||
|
||||
Title: I Got Plenty o' Nuttin' (Act II Scene 1)
|
||||
|
||||
|
||||
|
||||
Title: Buzzard Keep on Flyin' (Act II Scene 1)
|
||||
|
||||
# prev_aka THE BUZZARD SONG
|
||||
|
||||
|
||||
|
||||
Title: Bess, You Is My Woman Now (Act II Scene 1)
|
||||
|
||||
Title: Oh, I Can't Sit Down (Act II Scene 1)
|
||||
|
||||
|
||||
|
||||
Title: It Ain't Necessarily So (Act II Scene 2)
|
||||
|
||||
## Misprints:
|
||||
|
||||
# prev_aka It Aint Necessarily So (Act II Scene 2)
|
||||
|
||||
# prev_aka It Aint Necessarily So
|
||||
|
||||
|
||||
|
||||
Title: What you want wid Bess (Act II Scene 2)
|
||||
|
||||
Title: Oh, Doctor Jesus (Act II Scene 3)
|
||||
|
||||
Title: A Red-Haired Woman (Act II Scene 4)
|
||||
|
||||
Title: There's a Boat Dat's Leavin' Soon for New York (Act III Scene 2)
|
||||
|
||||
|
||||
|
||||
Title: Bess, O Where's My Bess? (Act III Scene 3)
|
||||
|
||||
# prev_aka Where is my Bess
|
||||
|
||||
|
||||
|
||||
Title: I'm on my way (Act III Scene 3)
|
||||
|
||||
|
||||
|
||||
### From Ella's record
|
||||
|
||||
|
||||
|
||||
Title: The Half Of It Dearie Blues
|
||||
|
||||
Title: 'S Wonderful
|
||||
|
||||
Title: Aren't You Kind Of Glad We Did?
|
||||
|
||||
Title: (I've Got) Beginner's Luck
|
||||
|
||||
Title: Bidin' My Time
|
||||
|
||||
Title: Boy Wanted
|
||||
|
||||
Title: Boy! What Love Has Done To Me!
|
||||
|
||||
Title: But Not For Me
|
||||
|
||||
Title: By Strauss
|
||||
|
||||
Title: Cheerful Little Earful
|
||||
|
||||
Title: Clap Yo' Hands
|
||||
|
||||
Title: Embraceable You
|
||||
|
||||
Title: Fascinating Rhythm
|
||||
|
||||
Title: Fascinatin' Rhythm
|
||||
|
||||
Title: Fidgety Feet
|
||||
|
||||
Title: A Foggy Day
|
||||
|
||||
Title: For You, For Me, For Evermore
|
||||
|
||||
## Funny Face
|
||||
|
||||
Title: He Loves And She Loves
|
||||
|
||||
Title: How Long Has This Been Going On?
|
||||
|
||||
Title: I Can't Be Bothered Now
|
||||
|
||||
Title: I Got Rhythm
|
||||
|
||||
Title: I Was Doing All Right
|
||||
|
||||
Title: I've Got A Crush On You
|
||||
|
||||
Title: Isn't It A Pity?
|
||||
|
||||
Title: Just Another Rhumba
|
||||
|
||||
Title: Let's Call The Whole Thing Off
|
||||
|
||||
Title: Let's Kiss And Make Up
|
||||
|
||||
Title: Looking For A Boy
|
||||
|
||||
Title: Lorelei
|
||||
|
||||
### Lorelei - (alternate take)
|
||||
|
||||
Title: Love Is Here To Stay
|
||||
|
||||
### Love Is Here To Stay - (alternate take)
|
||||
|
||||
Title: Love Is Sweeping The Country
|
||||
|
||||
Title: Love Walked In
|
||||
|
||||
Title: The Man I Love
|
||||
|
||||
Title: March Of The Swiss Soldiers
|
||||
|
||||
Title: My Cousin In Milwaukee
|
||||
|
||||
Title: My One And Only
|
||||
|
||||
Title: Nice Work If You Can Get It
|
||||
|
||||
### Of Thee I Sing
|
||||
|
||||
Title: Oh, Lady, Be Good!
|
||||
|
||||
### Oh, Lady, Be Good! - (alternate take)
|
||||
|
||||
Title: Oh, So Nice!
|
||||
|
||||
Title: Prelude I
|
||||
|
||||
Title: Prelude II
|
||||
|
||||
Title: Prelude III
|
||||
|
||||
Title: Promenade (Walking The Dog)
|
||||
|
||||
Title: The Real American Folk Song (Is A Rag)
|
||||
|
||||
Title: Sam And Delilah
|
||||
|
||||
### Shall We Dance?
|
||||
|
||||
Title: Slap That Bass
|
||||
|
||||
Title: Somebody From Somewhere
|
||||
|
||||
Title: Somebody Loves Me
|
||||
|
||||
Title: Someone To Watch Over Me
|
||||
|
||||
Title: Soon
|
||||
|
||||
Title: Stiff Upper Lip
|
||||
|
||||
### Strike Up The Band
|
||||
|
||||
Title: That Certain Feeling
|
||||
|
||||
Title: They All Laughed
|
||||
|
||||
Title: They Can't Take That Away From Me
|
||||
|
||||
Title: Things Are Looking Up
|
||||
|
||||
Title: Treat Me Rough
|
||||
|
||||
Title: Who Cares?
|
||||
|
||||
### You've Got What Gets Me
|
||||
|
||||
|
||||
|
||||
### From Gershwin plays Gershwin
|
||||
|
||||
Title: Hang on to Me
|
||||
|
||||
Title: Sweet and low down
|
||||
|
||||
Title: Then do we dance?
|
||||
|
||||
Title: Maybe
|
||||
|
||||
Title: Do-do-do
|
||||
|
||||
|
||||
|
||||
## From Porgy and Bess
|
||||
|
||||
Title: I wants to stay here
|
||||
|
||||
Title: Medley: Here come de honey man crab man oh
|
||||
|
868
fhem/FHEM/lib/Normalize/Text/Music_Fields/J_Brahms.comp
Normal file
868
fhem/FHEM/lib/Normalize/Text/Music_Fields/J_Brahms.comp
Normal file
@ -0,0 +1,868 @@
|
||||
# format = mail-header
|
||||
|
||||
|
||||
|
||||
## This is a very primitive list, not taking into account sub-opuses
|
||||
|
||||
|
||||
Title-Type: Piano Sonata
|
||||
Title-No: 1
|
||||
Title-Key: C major
|
||||
Title-Opus: 1
|
||||
Title-Dates: 1852
|
||||
|
||||
|
||||
|
||||
Title-Type: Piano Sonata
|
||||
Title-No: 2
|
||||
Title-Key: F sharp minor
|
||||
Title-Opus: 2
|
||||
Title-Dates: 1852
|
||||
|
||||
|
||||
|
||||
Title-Count: Six
|
||||
Title-Type: Songs
|
||||
Title-Opus: 3
|
||||
Title-Dates: 1853
|
||||
|
||||
|
||||
|
||||
Title-Type: Scherzo
|
||||
Title-Key: E flat minor
|
||||
Title-For: piano
|
||||
Title-Opus: 4
|
||||
Title-Dates: 1851
|
||||
|
||||
|
||||
|
||||
Title-Type: Piano Sonata
|
||||
Title-No: 3
|
||||
Title-Key: F minor
|
||||
Title-Opus: 5
|
||||
Title-Dates: 1853
|
||||
|
||||
|
||||
|
||||
Title-Count: Six
|
||||
Title-Type: Songs
|
||||
Title-Opus: 6
|
||||
|
||||
|
||||
|
||||
Title-Count: Six
|
||||
Title-Type: Songs
|
||||
Title-Opus: 7
|
||||
|
||||
|
||||
|
||||
Title-Type: Piano Trio
|
||||
Title-No: 1
|
||||
Title-Key: B major
|
||||
Title-Opus: 8
|
||||
Title-Dates: 1854
|
||||
|
||||
|
||||
|
||||
Title-RAW: Variations on a theme by Robert Schumann
|
||||
Title-Key: F sharp minor
|
||||
Title-For: piano
|
||||
Title-Opus: 9
|
||||
Title-Dates: 1854
|
||||
|
||||
|
||||
|
||||
Title-Count: Four
|
||||
Title-Type: Ballades
|
||||
Title-For: piano
|
||||
Title-Opus: 10
|
||||
Title-Dates: 1854
|
||||
|
||||
|
||||
|
||||
Title-Type: Serenade
|
||||
Title-No: 1
|
||||
Title-Key: D major
|
||||
Title-For: orchestra
|
||||
Title-Opus: 11
|
||||
Title-Dates: 1857
|
||||
|
||||
|
||||
|
||||
Title-Name: Ave Maria
|
||||
Title-Opus: 12
|
||||
|
||||
|
||||
|
||||
Title-Name: Begräbnisgesang
|
||||
Title-Opus: 13
|
||||
|
||||
|
||||
|
||||
Title-Count: Eight
|
||||
Title-Type: Songs and Romances
|
||||
Title-Opus: 14
|
||||
|
||||
|
||||
|
||||
Title-Type: Piano Concerto
|
||||
Title-No: 1
|
||||
Title-Key: D minor
|
||||
Title-Opus: 15
|
||||
Title-Dates: 1859
|
||||
|
||||
|
||||
|
||||
Title-Type: Serenade
|
||||
Title-No: 2
|
||||
Title-Key: A major
|
||||
Title-For: orchestra
|
||||
Title-Opus: 16
|
||||
Title-Dates: 1859
|
||||
|
||||
|
||||
|
||||
Title-Count: Four
|
||||
Title-Type: Songs
|
||||
Title-For: female voices, two horns and harp
|
||||
Title-Opus: 17
|
||||
|
||||
|
||||
|
||||
Title-Type: String Sextet
|
||||
Title-No: 1
|
||||
Title-Key: B flat major
|
||||
Title-Opus: 18
|
||||
Title-Dates: 1860
|
||||
|
||||
|
||||
|
||||
Title-Count: Five
|
||||
Title-Type: Poems
|
||||
Title-Opus: 19
|
||||
|
||||
|
||||
|
||||
Title-Count: Three
|
||||
Title-Type: Duets
|
||||
Title-Opus: 20
|
||||
|
||||
|
||||
|
||||
Title-RAW: Two Sets of Variations
|
||||
Title-For: piano
|
||||
Title-Opus: 21
|
||||
|
||||
|
||||
|
||||
Title-Name: Marienlieder
|
||||
Title-Opus: 22
|
||||
|
||||
|
||||
|
||||
Title-RAW: Variations on a Theme by Robert Schumann
|
||||
Title-For: piano, four hands
|
||||
Title-Opus: 23
|
||||
Title-Dates: 1861
|
||||
|
||||
|
||||
|
||||
Title-RAW: Variations and Fugue on a Theme by Handel
|
||||
Title-For: piano
|
||||
Title-Opus: 24
|
||||
Title-Dates: 1861
|
||||
|
||||
|
||||
|
||||
Title-Type: Piano Quartet
|
||||
Title-No: 1
|
||||
Title-Key: G minor
|
||||
Title-Opus: 25
|
||||
Title-Dates: 1861
|
||||
|
||||
|
||||
|
||||
Title-Type: Piano Quartet
|
||||
Title-No: 2
|
||||
Title-Key: A major
|
||||
Title-Opus: 26
|
||||
Title-Dates: 1861
|
||||
|
||||
|
||||
|
||||
Title-RAW: Psalm 13
|
||||
Title-Opus: 27
|
||||
|
||||
|
||||
|
||||
Title-Count: Four
|
||||
Title-Type: Duets
|
||||
Title-Opus: 28
|
||||
|
||||
|
||||
|
||||
Title-Count: Two
|
||||
Title-Type: Motets
|
||||
Title-Opus: 29
|
||||
Title-Dates: 1860, published 1864
|
||||
|
||||
|
||||
|
||||
Title-RAW: Geistliches Lied
|
||||
Title-Opus: 30
|
||||
|
||||
|
||||
|
||||
Title-Count: Three
|
||||
Title-Type: Vocal Quartets
|
||||
Title-Opus: 31
|
||||
|
||||
|
||||
|
||||
Title-Count: Nine
|
||||
Title-Type: Songs
|
||||
Title-Opus: 32
|
||||
|
||||
|
||||
|
||||
Title-Count: Fifteen
|
||||
Title-Type: Romances
|
||||
Title-Related-How: from Tieck's
|
||||
Title-Related-Name: Liebesgeschichte der schönen Magelone
|
||||
Title-Opus: 33
|
||||
|
||||
|
||||
|
||||
Title-Type: Piano Quintet
|
||||
Title-Key: F minor
|
||||
Title-Opus: 34
|
||||
Title-Dates: 1864
|
||||
|
||||
|
||||
|
||||
Title-Type: Sonata
|
||||
Title-For: 2 Pianos
|
||||
Title-Key: F minor
|
||||
Title-Opus: 34b
|
||||
|
||||
|
||||
|
||||
Title-RAW: Variations on a Theme by Paganini
|
||||
Title-For: Piano
|
||||
Title-Opus: 35
|
||||
Title-Dates: 1862-1863
|
||||
|
||||
|
||||
|
||||
Title-Type: String Sextet
|
||||
Title-No: 2
|
||||
Title-Opus: 36
|
||||
|
||||
|
||||
|
||||
Title-Count: Three
|
||||
Title-Type: Sacred Choruses
|
||||
Title-Opus: 37
|
||||
|
||||
|
||||
|
||||
Title-Type: Cello Sonata
|
||||
Title-No: 1
|
||||
Title-Key: E minor
|
||||
Title-Opus: 38
|
||||
Title-Dates: 1862-65
|
||||
|
||||
|
||||
|
||||
Title-Count: Sixteen
|
||||
Title-Type: Waltzes
|
||||
Title-For: piano, four hands
|
||||
Title-Opus: 39
|
||||
Title-Dates: 1865
|
||||
|
||||
|
||||
|
||||
Title-Type: Trio
|
||||
Title-For: Horn, Violin and Piano
|
||||
Title-Key: E flat major
|
||||
Title-Opus: 40
|
||||
Title-Dates: 1865
|
||||
|
||||
|
||||
|
||||
Title-Count: Five
|
||||
Title-Type: Songs
|
||||
Title-For: male voices
|
||||
Title-Opus: 41
|
||||
|
||||
|
||||
|
||||
Title-Count: Three
|
||||
Title-Type: secular songs
|
||||
Title-For: choir
|
||||
Title-Opus: 42
|
||||
|
||||
|
||||
|
||||
Title-Count: Four
|
||||
Title-Type: Songs
|
||||
Title-Opus: 43
|
||||
|
||||
|
||||
|
||||
Title-Count: Twelve
|
||||
Title-Type: Songs and Romances
|
||||
Title-Opus: 44
|
||||
|
||||
|
||||
|
||||
Title-Name: Ein deutsches Requiem
|
||||
Title-Opus: 45
|
||||
Title-Dates: 1868
|
||||
|
||||
|
||||
|
||||
Title-Count: Four
|
||||
Title-Type: Songs
|
||||
Title-Opus: 46
|
||||
|
||||
|
||||
|
||||
Title-Count: Five
|
||||
Title-Type: Songs
|
||||
Title-Opus: 47
|
||||
|
||||
|
||||
|
||||
Title-Count: Seven
|
||||
Title-Type: Songs
|
||||
Title-Opus: 48
|
||||
|
||||
|
||||
|
||||
Title-RAW: Five Songs -- (#4, "Wiegenlied", is also known as "Brahms' Lullaby")
|
||||
Title-Opus: 49
|
||||
|
||||
|
||||
|
||||
Title-Name: Rinaldo
|
||||
Title-Opus: 50
|
||||
|
||||
|
||||
|
||||
Title-Count: Two
|
||||
Title-Type: String Quartets
|
||||
Title-Opus: 51
|
||||
|
||||
|
||||
|
||||
Title-Count: Eighteen
|
||||
Title-Name: Liebeslieder-Waltzer
|
||||
Title-For: piano, four hands and vocal quartet
|
||||
Title-Name: ad libitum
|
||||
Title-Opus: 52
|
||||
Title-Dates: 1874
|
||||
|
||||
|
||||
|
||||
Title-RAW: Alto Rhapsody
|
||||
Title-Opus: 53
|
||||
|
||||
|
||||
|
||||
Title-Name: Schicksalslied
|
||||
Title-Opus: 54
|
||||
|
||||
|
||||
|
||||
Title-Name: Triumphlied
|
||||
Title-Opus: 55
|
||||
|
||||
|
||||
|
||||
Title-RAW: Variations on a Theme by Joseph Haydn
|
||||
Title-Opus: 56
|
||||
Title-Dates: 1873
|
||||
|
||||
|
||||
|
||||
Title-Count: Eight
|
||||
Title-Type: Songs
|
||||
Title-Opus: 57
|
||||
|
||||
|
||||
|
||||
Title-Count: Eight
|
||||
Title-Type: Songs
|
||||
Title-Opus: 58
|
||||
|
||||
|
||||
|
||||
Title-Count: Eight
|
||||
Title-Type: Songs
|
||||
Title-Opus: 59
|
||||
|
||||
|
||||
|
||||
Title-Type: Piano Quartet
|
||||
Title-No: 3
|
||||
Title-Key: C minor
|
||||
Title-Opus: 60
|
||||
|
||||
|
||||
|
||||
Title-Count: Four
|
||||
Title-Type: Duets
|
||||
Title-Opus: 61
|
||||
|
||||
|
||||
|
||||
Title-Count: Seven
|
||||
Title-Type: secular songs
|
||||
Title-For: choir
|
||||
Title-Opus: 62
|
||||
|
||||
|
||||
|
||||
Title-Count: Nine
|
||||
Title-Type: Songs
|
||||
Title-Opus: 63
|
||||
|
||||
|
||||
|
||||
Title-Count: Three
|
||||
Title-Type: Vocal Quartets
|
||||
Title-Opus: 64
|
||||
|
||||
|
||||
|
||||
Title-RAW: Neue Liebeslieder - 15 Waltzes
|
||||
Title-Opus: 65
|
||||
|
||||
|
||||
|
||||
Title-Count: Five
|
||||
Title-Type: Duets
|
||||
Title-Opus: 66
|
||||
|
||||
|
||||
|
||||
Title-Type: String Quartet
|
||||
Title-No: 3
|
||||
Title-Key: B flat major
|
||||
Title-Opus: 67
|
||||
Title-Dates: 1876
|
||||
|
||||
|
||||
|
||||
Title-Type: Symphony
|
||||
Title-No: 1
|
||||
Title-Key: C minor
|
||||
Title-Opus: 68
|
||||
Title-Dates: 1876 première
|
||||
|
||||
|
||||
|
||||
Title-Count: Nine
|
||||
Title-Type: Songs
|
||||
Title-Opus: 69
|
||||
|
||||
|
||||
|
||||
Title-Count: Four
|
||||
Title-Type: Songs
|
||||
Title-Opus: 70
|
||||
|
||||
|
||||
|
||||
Title-Count: Five
|
||||
Title-Type: Songs
|
||||
Title-Opus: 71
|
||||
|
||||
|
||||
|
||||
Title-Count: Five
|
||||
Title-Type: Songs
|
||||
Title-Opus: 72
|
||||
|
||||
|
||||
|
||||
Title-Type: Symphony
|
||||
Title-No: 2
|
||||
Title-Key: D major
|
||||
Title-Opus: 73
|
||||
Title-Dates: 1877
|
||||
|
||||
|
||||
|
||||
Title-Count: Two
|
||||
Title-Type: Motets
|
||||
Title-Opus: 74
|
||||
|
||||
|
||||
|
||||
Title-Count: Four
|
||||
Title-Type: Ballads and Romances
|
||||
Title-Opus: 75
|
||||
|
||||
|
||||
|
||||
Title-Count: Eight
|
||||
Title-Type: Pieces
|
||||
Title-For: piano
|
||||
Title-Opus: 76
|
||||
Title-Dates: 1878
|
||||
|
||||
|
||||
|
||||
Title-Type: Violin Concerto
|
||||
Title-Key: D major
|
||||
Title-Opus: 77
|
||||
Title-Dates: 1878
|
||||
|
||||
|
||||
|
||||
Title-Type: Violin Sonata
|
||||
Title-No: 1
|
||||
Title-Key: G major
|
||||
Title-Opus: 78
|
||||
|
||||
|
||||
|
||||
Title-Count: Two
|
||||
Title-Type: Rhapsodies
|
||||
Title-For: piano
|
||||
Title-Opus: 79
|
||||
Title-Dates: 1879
|
||||
|
||||
|
||||
|
||||
Title-Name: Academic Festival Overture
|
||||
Title-For: orchestra
|
||||
Title-Opus: 80
|
||||
Title-Dates: 1880
|
||||
|
||||
|
||||
|
||||
Title-Name: Tragic Overture
|
||||
Title-For: orchestra
|
||||
Title-Opus: 81
|
||||
Title-Dates: 1880
|
||||
|
||||
|
||||
|
||||
Title-Name: Nänie
|
||||
Title-Opus: 82
|
||||
Title-Dates: 1881
|
||||
|
||||
|
||||
|
||||
Title-Type: Piano Concerto
|
||||
Title-No: 2
|
||||
Title-Key: B flat major
|
||||
Title-Opus: 83
|
||||
Title-Dates: 1881
|
||||
|
||||
|
||||
|
||||
Title-Type: Romances and Songs
|
||||
Title-Opus: 84
|
||||
|
||||
|
||||
|
||||
Title-Count: Six
|
||||
Title-Type: Songs
|
||||
Title-Opus: 85
|
||||
|
||||
|
||||
|
||||
Title-Count: Six
|
||||
Title-Type: Songs
|
||||
Title-Opus: 86
|
||||
|
||||
|
||||
|
||||
Title-Type: Piano Trio
|
||||
Title-No: 2
|
||||
Title-Key: C major
|
||||
Title-Opus: 87
|
||||
|
||||
|
||||
|
||||
Title-Type: String Quintet
|
||||
Title-No: 1
|
||||
Title-Key: F major
|
||||
Title-Opus: 88
|
||||
Title-Dates: 1882
|
||||
|
||||
|
||||
|
||||
Title-Name: Gesang der Parzen
|
||||
Title-Opus: 89
|
||||
|
||||
|
||||
|
||||
Title-Type: Symphony
|
||||
Title-No: 3
|
||||
Title-Key: F major
|
||||
Title-Opus: 90
|
||||
Title-Dates: 1883
|
||||
|
||||
|
||||
|
||||
Title-Count: Two
|
||||
Title-Type: Songs
|
||||
Title-For: Voice, Viola & Piano
|
||||
Title-Opus: 91
|
||||
|
||||
|
||||
|
||||
Title-Count: Four
|
||||
Title-Type: Vocal Quartets
|
||||
Title-Opus: 92
|
||||
|
||||
|
||||
|
||||
Title-Count: Six
|
||||
Title-Type: Songs and Romances
|
||||
Title-For: choir
|
||||
Title-Opus: 93
|
||||
|
||||
|
||||
|
||||
Title-Count: Five
|
||||
Title-Type: Songs
|
||||
Title-Opus: 94
|
||||
|
||||
|
||||
|
||||
Title-Count: Seven
|
||||
Title-Type: Songs
|
||||
Title-Opus: 95
|
||||
|
||||
|
||||
|
||||
Title-Count: Four
|
||||
Title-Type: Songs
|
||||
Title-Opus: 96
|
||||
|
||||
|
||||
|
||||
Title-Count: Six
|
||||
Title-Type: Songs
|
||||
Title-Opus: 97
|
||||
|
||||
|
||||
|
||||
Title-Type: Symphony
|
||||
Title-No: 4
|
||||
Title-Key: E minor
|
||||
Title-Opus: 98
|
||||
Title-Dates: 1885
|
||||
|
||||
|
||||
|
||||
Title-Type: Cello Sonata
|
||||
Title-No: 2
|
||||
Title-Key: F major
|
||||
Title-Opus: 99
|
||||
Title-Dates: 1886
|
||||
|
||||
|
||||
|
||||
Title-Type: Violin Sonata
|
||||
Title-No: 2
|
||||
Title-Key: A major
|
||||
Title-Opus: 100
|
||||
Title-Dates: 1886
|
||||
|
||||
|
||||
|
||||
Title-Type: Piano Trio
|
||||
Title-No: 3
|
||||
Title-Key: C minor
|
||||
Title-Opus: 101
|
||||
Title-Dates: 1886
|
||||
|
||||
|
||||
|
||||
Title-Type: Double Concerto
|
||||
Title-For: Violin and Cello
|
||||
Title-Key: A minor
|
||||
Title-Opus: 102
|
||||
Title-Dates: 1887
|
||||
|
||||
|
||||
|
||||
Title-Name: Zigeunerlieder
|
||||
Title-Opus: 103
|
||||
|
||||
|
||||
|
||||
Title-Count: Five
|
||||
Title-Type: songs
|
||||
Title-For: choir
|
||||
Title-Opus: 104
|
||||
|
||||
|
||||
|
||||
Title-Count: Five
|
||||
Title-Type: Songs
|
||||
Title-Opus: 105
|
||||
|
||||
|
||||
|
||||
Title-Count: Five
|
||||
Title-Type: Songs
|
||||
Title-Opus: 106
|
||||
|
||||
|
||||
|
||||
Title-Count: Five
|
||||
Title-Type: Songs
|
||||
Title-Opus: 107
|
||||
|
||||
|
||||
|
||||
Title-Type: Violin Sonata
|
||||
Title-No: 3
|
||||
Title-Key: D minor
|
||||
Title-Opus: 108
|
||||
|
||||
|
||||
|
||||
Title-Name: Fest- und Gedenksprüche
|
||||
Title-For: choir
|
||||
Title-Opus: 109
|
||||
|
||||
|
||||
|
||||
Title-Count: Three
|
||||
Title-Type: Motets
|
||||
Title-Opus: 110
|
||||
|
||||
|
||||
|
||||
Title-Type: String Quintet
|
||||
Title-No: 2
|
||||
Title-Key: G major
|
||||
Title-Name: Prater
|
||||
Title-Opus: 111
|
||||
Title-Dates: 1890
|
||||
|
||||
|
||||
|
||||
Title-Count: Six
|
||||
Title-Type: Vocal Quartets
|
||||
Title-Opus: 112
|
||||
|
||||
|
||||
|
||||
Title-Count: Thirteen
|
||||
Title-Type: Canons
|
||||
Title-For: female choir
|
||||
Title-Opus: 113
|
||||
|
||||
|
||||
|
||||
Title-Type: Trio
|
||||
Title-For: Piano, Clarinet, and Cello
|
||||
Title-Key: A minor
|
||||
Title-Opus: 114
|
||||
Title-Dates: 1891
|
||||
|
||||
|
||||
|
||||
Title-Type: Quintet
|
||||
Title-For: Clarinet and Strings
|
||||
Title-Key: B minor
|
||||
Title-Opus: 115
|
||||
Title-Dates: 1891
|
||||
|
||||
|
||||
|
||||
Title-Count: Seven
|
||||
Title-Type: Fantasias
|
||||
Title-For: piano
|
||||
Title-Opus: 116
|
||||
Title-Dates: 1892
|
||||
|
||||
|
||||
|
||||
Title-Count: Three
|
||||
Title-Type: Intermezzi
|
||||
Title-For: piano
|
||||
Title-Opus: 117
|
||||
Title-Dates: 1892
|
||||
|
||||
|
||||
|
||||
Title-Count: Six
|
||||
Title-Type: Pieces
|
||||
Title-For: Piano
|
||||
Title-Opus: 118
|
||||
Title-Dates: 1893
|
||||
|
||||
|
||||
|
||||
Title-Count: Four
|
||||
Title-Type: Pieces
|
||||
Title-For: piano
|
||||
Title-Opus: 119
|
||||
Title-Dates: 1893
|
||||
|
||||
|
||||
|
||||
Title-Count: Two
|
||||
Title-Type: Clarinet Sonatas
|
||||
Title-Opus: 120
|
||||
|
||||
|
||||
|
||||
Title-Name: Vier ernste Gesänge
|
||||
Title-RAW: ("Four Serious Songs")
|
||||
Title-Opus: 121
|
||||
Title-Dates: 1896
|
||||
|
||||
|
||||
|
||||
Title-Count: Eleven
|
||||
Title-Type: Chorale Preludes
|
||||
Title-For: organ
|
||||
Title-Opus: 122
|
||||
Title-Dates: 1896
|
||||
|
||||
|
||||
|
||||
Title-RAW: Hungarian Dances (1869) (Brahms considered these adaptations, not original works, and so he did not assign an Opus #) [1]
|
||||
Title-Opus: WoO 1
|
||||
|
||||
|
||||
|
||||
Title-RAW: Chorale Prelude and Fugue on „O Traurigkeit, o Herzeleid“
|
||||
Title-For: organ
|
||||
Title-Opus: WoO 7
|
||||
|
||||
|
||||
|
||||
Title-Type: Fugue
|
||||
Title-Key: A flat minor
|
||||
Title-For: organ
|
||||
Title-Opus: WoO 8
|
||||
|
||||
|
||||
|
||||
Title-Type: Prelude and Fugue
|
||||
Title-Key: A minor
|
||||
Title-For: organ
|
||||
Title-Opus: WoO 9
|
||||
|
||||
|
||||
|
||||
Title-Type: Prelude and Fugue
|
||||
Title-Key: G minor
|
||||
Title-For: organ
|
||||
Title-Opus: WoO 10
|
||||
|
||||
|
||||
|
4227
fhem/FHEM/lib/Normalize/Text/Music_Fields/L_van_Beethoven.comp
Normal file
4227
fhem/FHEM/lib/Normalize/Text/Music_Fields/L_van_Beethoven.comp
Normal file
File diff suppressed because it is too large
Load Diff
218
fhem/FHEM/lib/Normalize/Text/Music_Fields/Music_Fields-rus.lst
Normal file
218
fhem/FHEM/lib/Normalize/Text/Music_Fields/Music_Fields-rus.lst
Normal file
@ -0,0 +1,218 @@
|
||||
# charset = cp1251
|
||||
|
||||
### Aliases should be at the front; correct => misspell1, misspell2...
|
||||
# alias Чёрный => Черный
|
||||
# alias Кушелёв-Безбородко => Кушелев-Безбородко
|
||||
# alias Кушелёв-Безбородко => Кушелев-Безбородко
|
||||
# alias Гумилёв => Гумилев
|
||||
|
||||
Александр Дольский
|
||||
Александр Мирзаян
|
||||
Александр Суханов
|
||||
Александр Вертинский (1889-03-21--1957-05-21)
|
||||
Александр Городницкий
|
||||
Булат Окуджава (1924-5-9--1997-6-12)
|
||||
Елена Камбурова
|
||||
Михаил Щербаков
|
||||
Новелла Матвеева
|
||||
Вера Матвеева (1945-10-23--1976-8-11)
|
||||
Ада (Ариадна Адамовна) Якушева
|
||||
Владимир Сергеевич Дашкевич
|
||||
|
||||
## First prefered:
|
||||
Сергей и Татьяна Никитины
|
||||
##Татьяна и Сергей Никитины
|
||||
|
||||
Сергей Никитин
|
||||
Валерий Агафонов (1941-10-3-1984-9-5)
|
||||
Виктор Берковский (1932-07-13--2005-07-22)
|
||||
Владимир Высоцкий (1938-1-25--1980-7-25)
|
||||
Юлий Ким
|
||||
фольклор МГУ
|
||||
Дмитрий Сухарев
|
||||
Арсений Тарковский (1907-6-24--1989-5-27)
|
||||
Агния Барто (1906-2-17--1981-4-1)
|
||||
Вадим Владимирович Егоров
|
||||
Иван Семенович Киуру
|
||||
Григорий Поженян
|
||||
Лариса Критская
|
||||
|
||||
Андрей Вознесенский
|
||||
Александр Кушнер
|
||||
Борис Леонидович Пастернак (1890-2-10--1960-5-30)
|
||||
Осип Эмильевич Мандельштам (1891-1-15--1938-12-27)
|
||||
Владимир Владимирович Маяковский (1893-07-19--1930-4-14)
|
||||
Андрей Миронов (1941-3-8--1987-8-16)
|
||||
Андрей Петров
|
||||
Александр Блок (1880-11-28--1921-8-7)
|
||||
Борис Владимирович Заходер (1918-9-9-2000-11-7)
|
||||
Борис Натанович Стругацкий
|
||||
Борис Слуцкий (1919-5-7--1986-2-22)
|
||||
Юрий Визбор (1934-6-20--1984-9-17)
|
||||
Юрий Давыдович Левитанский (1922-1-21--1996-1-24)
|
||||
Ада Якушева
|
||||
Александр Галич (1918-10-19--1977-12-15)
|
||||
Александр Дулов
|
||||
Вероника Тушнова (1915-1965)
|
||||
Андрей Макаревич
|
||||
Борис Гребенщиков
|
||||
Александр Карпов
|
||||
Андрей Корф
|
||||
Домино
|
||||
Игорь Белый
|
||||
Кирилл Волошин
|
||||
Леонид Сергеев
|
||||
Наталья Приезжева
|
||||
Олег Митяев
|
||||
Скай
|
||||
Светлана Ветрова
|
||||
Таня Королева
|
||||
Тимур Шаов
|
||||
Три Сучка
|
||||
Вадим и Валерий Мищуки
|
||||
Вероника Долина
|
||||
Владимир Ланцберг
|
||||
|
||||
## This causes infinite loop of expansion Иващенко => Васильев и Иващенко => Иващенко
|
||||
## Васильев и Иващенко
|
||||
|
||||
Михаил Светлов (1903-6-17--1964-7-28)
|
||||
Эдуард Багрицкий (1895-11-4--1939-2-16)
|
||||
Виктор Соснора
|
||||
Николай Заболоцкий (1903-5-7--1958-10-14)
|
||||
Георгий Иванов (1894-11-10--1958-8-26)
|
||||
Даниил Хармс (1905-12-30--1942-2-2)
|
||||
Дон Аминадо (1888-5-7--1957-11-14)
|
||||
Евгений Евтушенко
|
||||
Евгений Клячкин (1934-3-23--1994-7-30)
|
||||
Иосиф Александрович Бродский (1940-5-24--1996-1-28)
|
||||
Олег Чухонцев
|
||||
Павел Коган (1918-7-7--1942)
|
||||
Поль Верлен (1844-3-30--1896-1-8)
|
||||
Юрий Аделунг (1945-4-3--1993-1-6)
|
||||
Давид Самуилович Самойлов (1920-6-1--1990-2-23)
|
||||
Генрих Вениаминович Сапгир (1928-11-20--1999-10-7)
|
||||
Овсей Дриз (1908-5-16--1971-2-14)
|
||||
Иван Крылов (1769-2-13--1844-11-21)
|
||||
Самуил Яковлевич Маршак (1887-11-3--1964-7-4)
|
||||
Константин Библ (1898-2-26--1951-11-12)
|
||||
Марина Ивановна Цветаева (1992-10-8--1941-8-31)
|
||||
Саша Чёрный (1880-10-13--1932-7-5)
|
||||
Вениамин Борисович Смехов
|
||||
Максимилиан Александрович Волошин (1877-5-28--1932-8-11)
|
||||
Николай Степанович Гумилёв (1886-4-15--1921-8)
|
||||
Григорий Александрович Кушелёв-Безбородко (1832-2-1--1870-5-13),
|
||||
Пётр Андреевич Вяземский (1792-7-23--1878-11-22)
|
||||
Михаил Львович Матусовский (1915-7-23--1990-7-16)
|
||||
Александр Александрович Алябьев (1787-8-15--1851-3-6)
|
||||
Борис Алексеевич Прозоровский (1891-6-30--1937)
|
||||
|
||||
## Maurice Car^eme
|
||||
Морис Карем (1899-5-12--1978-1-13)
|
||||
|
||||
## dates not checked
|
||||
Михаил Кудимов
|
||||
Борис Носик
|
||||
Вадим Егоров
|
||||
Тим Собакин
|
||||
Юрий Кузнецов
|
||||
Агнешка Осеецкая
|
||||
|
||||
А. Н. Островский
|
||||
Антон Павлович Чехов (1860-1-29--1904-7-15)
|
||||
Александр Сергеевич Грибоедов (1790(5?)-1-15-1829-2-11)
|
||||
Александр Сергеевич Пушкин (1799-6-6-1837-2-10)
|
||||
Андре Моруа (1885-1967)
|
||||
Аркадий Аверченко (1881-3-18--1925-3-18)
|
||||
Василь Быков (1924-6-19--2003-6-22)
|
||||
Владимир Алексеевич Гиляровский (1853-12-8---1935-10-1)
|
||||
Денис Иванович Фонвизин (1744(5?)-4-3--1792)
|
||||
Джек Лондон (1876-1-12--1916-11-22)
|
||||
Иван Алексеевич Бунин (1870-10-22--1953-11-8)
|
||||
Илья Ильф (1897-10-15--1937-4-12)
|
||||
Евгений Петров (1903-12-13--1942-7)
|
||||
Иван Сергеевич Тургенев (1818-10-28--1883-11-22)
|
||||
Исаак Бабель (1894-7-13-1940-1-27)
|
||||
Лев Николаевич Толстой (1828-9-9--1910-11-20)
|
||||
Михаил Афанасьевич Булгаков (1891-5-15--1940-3-10)
|
||||
Михаил Юрьевич Лермонтов (1814-10-15--1841-7-27)
|
||||
Николай Васильевич Гоголь (1809-4-1--1852-3-4)
|
||||
Николай Семёнович Лесков (1831-2-16--1895-3-5)
|
||||
О. Генри (1862-7-11--1910-6-5)
|
||||
Оскар Уайльд (1984-10-16--1900-11-13)
|
||||
Фёдор Михайлович Достоевский (1821-11-11--1881-2-9)
|
||||
Ганс Христиан Андерсен (1805-4-2--1875-8-4)
|
||||
Ярослав Гашек (1883-4-30--1923-3-3)
|
||||
Джозеф Редьярд Киплинг (1865-12-30--1936-1-18)
|
||||
|
||||
Юрий Аделунг (1945-4-3--1993-1-6)
|
||||
Алексей Николаевич Апухтин (1840(1?)-11-27--1893-8-29)
|
||||
Афанасий Афанасьевич Фет (1820-12-5--1892-12-3)
|
||||
Алексей Константинович Толстой (1817-9-5--1875-10-10)
|
||||
Владимир Владимирович Набоков (1899-4-24--1977-7-2)
|
||||
Роберт Иванович Рождественский (1932-6-20--1994-3-20)
|
||||
Владимир Туриянский
|
||||
Вадим Сергеевич Шефнер (1915-2002)
|
||||
Иннокентий Фёдорович Анненский (1855-9-1--1909-12-11)
|
||||
Илья Львович Сельвинский (1899-10-24--1968-3-22)
|
||||
Исаак Иосифович Шварц
|
||||
Илья Григорьевич Эренбург (1891-1-27--1967-8-31)
|
||||
Михаил Сергеевич Боярский
|
||||
Максимилиан Александрович Волошин (1877-5-28-1932-8-11)
|
||||
Микаэл Таривердиев (1931-8-15--1996-6-24)
|
||||
Николай Михайлович Рубцов (1936-1-3--1971-1-19)
|
||||
Федор Иванович Тютчев (1803-12-5--1873-7-27)
|
||||
Николоз Мелитонович Бараташвили (1817-12-27--1845-10-21)
|
||||
Вера Ильинична Матвеева (1945-10-23--1976-8-11)
|
||||
Геннадий Фёдорович Шпаликов (1937-09-06--1974-11-01)
|
||||
Александр Моисеевич Володин (1919-2-10--2001-12-17)
|
||||
Юрий Абрамович Левитин (1912-12-18--1993-8-2)
|
||||
Сергей Александрович Есенин (1895-10-3--1925-12-28)
|
||||
|
||||
## В. Берестов
|
||||
## В. Золотухин
|
||||
## В. Смехов
|
||||
|
||||
Олег Анофриев
|
||||
Олег Иванович Даль (1941-5-25--1981-5-3)
|
||||
Перси Биши Шелли (1792-8-4--1822-7-8)
|
||||
Римма Фёдоровна Казакова
|
||||
Эльдар Рязанов
|
||||
Эдуард Николаевич Успенский
|
||||
Юрий Алексеевич Кукин
|
||||
Юнна Петровна Мориц
|
||||
|
||||
## Я. Пригожий
|
||||
|
||||
### These should be at the end
|
||||
|
||||
### Possible misspellings of the first name
|
||||
# fix_firstname фолклор МГУ
|
||||
|
||||
### Misspelling of older versions fixed: misspelled => correct_shortcut
|
||||
# fix Ivan Krylov (1769-1844) => Крылов
|
||||
# fix Samuil Marshak (1887-1964) => Маршак
|
||||
# fix А. С. Грибоедов (1790(5?)-1829) => Александр Сергеевич Грибоедов (1790(5?)-1-15-1829-2-11)
|
||||
# fix Д. И. Фонвизин (1744(5?)-1792) => Денис Иванович Фонвизин (1744(5?)-4-3--1792)
|
||||
# fix Х. К. Андерсен => Андерсен
|
||||
# fix П.-Б. Шелли => Шелли
|
||||
# fix Эдуард Багрицкий (1922-1942) => Багрицкий
|
||||
# fix Иосиф Александрович Бродский (19405-24--1996-1-28) => Бродский
|
||||
# fix Татьяна и Сергей Никитины => Сергей и Татьяна Никитины
|
||||
# fix Р. Киплинг => Киплинг
|
||||
|
||||
## Non-automatic shortnames
|
||||
# shortname Дм. Сухарев
|
||||
# shortname Никитины
|
||||
# shortname Арс. Тарковский
|
||||
# shortname И. Киуру
|
||||
# shortname А. Апухтин
|
||||
# shortname Дж. Киплинг
|
||||
# shortname Дж. Лондон
|
||||
|
||||
## This might be wrongly expanded when combinations like
|
||||
## Сергей и Татьяна Никитины, Виктор Берковский
|
||||
## are broken over "," and "и"
|
||||
|
||||
# keep Татьяна Никитины
|
||||
# keep Сергей Никитины
|
828
fhem/FHEM/lib/UPnP/Common.pm
Normal file
828
fhem/FHEM/lib/UPnP/Common.pm
Normal file
@ -0,0 +1,828 @@
|
||||
package UPnP::Common;
|
||||
|
||||
use 5.006;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use HTTP::Headers;
|
||||
use IO::Socket;
|
||||
|
||||
use vars qw(@EXPORT $VERSION @ISA $AUTOLOAD);
|
||||
|
||||
require Exporter;
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
our $VERSION = '0.03';
|
||||
|
||||
my %XP_CONSTANTS = (
|
||||
SSDP_IP => "239.255.255.250",
|
||||
SSDP_PORT => 1900,
|
||||
CRLF => "\015\012",
|
||||
IP_LEVEL => getprotobyname('ip') || 0,
|
||||
);
|
||||
|
||||
#ALW - Changed from 'MSWin32' => [3,5],
|
||||
my @MD_CONSTANTS = qw(IP_MULTICAST_TTL IP_ADD_MEMBERSHIP);
|
||||
my %MD_CONSTANT_VALUES = (
|
||||
'MSWin32' => [10,12],
|
||||
'cygwin' => [3,5],
|
||||
'darwin' => [10,12],
|
||||
'linux' => [33,35],
|
||||
'default' => [33,35],
|
||||
);
|
||||
|
||||
@EXPORT = qw();
|
||||
|
||||
use constant PROBE_IP => "239.255.255.251";
|
||||
use constant PROBE_PORT => 8950;
|
||||
|
||||
my $ref = $MD_CONSTANT_VALUES{$^O};
|
||||
if (!defined($ref)) {
|
||||
$ref = $MD_CONSTANT_VALUES{default};
|
||||
}
|
||||
my $consts;
|
||||
for my $name (keys %XP_CONSTANTS) {
|
||||
$consts .= "use constant $name => \'" . $XP_CONSTANTS{$name} . "\';\n";
|
||||
}
|
||||
for my $index (0..$#MD_CONSTANTS) {
|
||||
my $name = $MD_CONSTANTS[$index];
|
||||
$consts .= "use constant $name => \'" . $ref->[$index] . "\';\n";
|
||||
}
|
||||
|
||||
#warn $consts; # for development
|
||||
eval $consts;
|
||||
push @EXPORT, (keys %XP_CONSTANTS, @MD_CONSTANTS);
|
||||
|
||||
#findLocalIP();
|
||||
|
||||
my %typeMap = (
|
||||
'ui1' => 'int',
|
||||
'ui2' => 'int',
|
||||
'ui4' => 'int',
|
||||
'i1' => 'int',
|
||||
'i2' => 'int',
|
||||
'i4' => 'int',
|
||||
'int' => 'int',
|
||||
'r4' => 'float',
|
||||
'r8' => 'float',
|
||||
'number' => 'float',
|
||||
'fixed' => 'float',
|
||||
'float' => 'float',
|
||||
'char' => 'string',
|
||||
'string' => 'string',
|
||||
'date' => 'timeInstant',
|
||||
'dateTime.tz' => 'timeInstant',
|
||||
'time' => 'timeInstant',
|
||||
'time.tz' => 'timeInstant',
|
||||
'boolean' => 'boolean',
|
||||
'bin.base64' => 'base64Binary',
|
||||
'bin.hex' => 'hexBinary',
|
||||
'uri' => 'uriReference',
|
||||
'uuid' => 'string',
|
||||
);
|
||||
|
||||
BEGIN {
|
||||
use SOAP::Lite;
|
||||
$SOAP::Constants::DO_NOT_USE_XML_PARSER = 1;
|
||||
}
|
||||
|
||||
sub getLocalIP {
|
||||
if (defined $UPnP::Common::LocalIP) {
|
||||
return $UPnP::Common::LocalIP;
|
||||
}
|
||||
|
||||
my $probeSocket = IO::Socket::INET->new(Proto => 'udp',
|
||||
Reuse => 1);
|
||||
|
||||
my $listenSocket = IO::Socket::INET->new(Proto => 'udp',
|
||||
Reuse => 1,
|
||||
LocalPort => PROBE_PORT);
|
||||
my $ip_mreq = inet_aton(PROBE_IP) . INADDR_ANY;
|
||||
setsockopt($listenSocket,
|
||||
getprotobyname('ip'),
|
||||
$ref->[1],
|
||||
$ip_mreq);
|
||||
|
||||
my $destaddr = sockaddr_in(PROBE_PORT, inet_aton(PROBE_IP));
|
||||
send($probeSocket, "Test", 0, $destaddr);
|
||||
|
||||
my $buf = '';
|
||||
my $peer = recv($listenSocket, $buf, 2048, 0);
|
||||
my ($port, $addr) = sockaddr_in($peer);
|
||||
|
||||
$probeSocket->close;
|
||||
$listenSocket->close;
|
||||
|
||||
setLocalIP($addr);
|
||||
return $UPnP::Common::LocalIP;
|
||||
}
|
||||
|
||||
sub setLocalIP {
|
||||
my ($addr) = @_;
|
||||
$UPnP::Common::LocalIP = inet_ntoa($addr);
|
||||
}
|
||||
|
||||
sub parseHTTPHeaders {
|
||||
my $buf = shift;
|
||||
my $headers = HTTP::Headers->new;
|
||||
|
||||
# Header parsing code borrowed from HTTP::Daemon
|
||||
my($key, $val);
|
||||
HEADER:
|
||||
while ($buf =~ s/^([^\012]*)\012//) {
|
||||
$_ = $1;
|
||||
s/\015$//;
|
||||
if (/^([^:\s]+)\s*:\s*(.*)/) {
|
||||
$headers->push_header($key => $val) if $key;
|
||||
($key, $val) = ($1, $2);
|
||||
}
|
||||
elsif (/^\s+(.*)/) {
|
||||
$val .= " $1";
|
||||
}
|
||||
else {
|
||||
last HEADER;
|
||||
}
|
||||
}
|
||||
$headers->push_header($key => $val) if $key;
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
sub UPnPToSOAPType {
|
||||
my $upnpType = shift;
|
||||
return $typeMap{$upnpType};
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
package UPnP::Common::DeviceLoader;
|
||||
|
||||
use strict;
|
||||
|
||||
sub new {
|
||||
my $self = shift;
|
||||
my $class = ref($self) || $self;
|
||||
|
||||
return bless {
|
||||
_parser => UPnP::Common::Parser->new,
|
||||
}, $class;
|
||||
}
|
||||
|
||||
sub parser {
|
||||
my $self = shift;
|
||||
return $self->{_parser};
|
||||
}
|
||||
|
||||
sub parseServiceElement {
|
||||
my $self = shift;
|
||||
my $element = shift;
|
||||
my($name, $attrs, $children) = @$element;
|
||||
|
||||
my $service = $self->newService(%{$_[1]});
|
||||
for my $childElement (@$children) {
|
||||
my $childName = $childElement->[0];
|
||||
|
||||
if (UPnP::Common::Service::isProperty($childName)) {
|
||||
my $value = $childElement->[2];
|
||||
$service->$childName($value);
|
||||
}
|
||||
}
|
||||
|
||||
return $service;
|
||||
}
|
||||
|
||||
sub parseDeviceElement {
|
||||
my $self = shift;
|
||||
my $element = shift;
|
||||
my $parent = shift;
|
||||
my($name, $attrs, $children) = @$element;
|
||||
|
||||
my $device = $self->newDevice(%{$_[0]});
|
||||
$device->parent($parent);
|
||||
for my $childElement (@$children) {
|
||||
my $childName = $childElement->[0];
|
||||
|
||||
if ($childName eq 'deviceList') {
|
||||
my $childDevices = $childElement->[2];
|
||||
next if (ref $childDevices ne "ARRAY");
|
||||
for my $deviceElement (@$childDevices) {
|
||||
my $childDevice = $self->parseDeviceElement($deviceElement,
|
||||
$device,
|
||||
@_);
|
||||
if ($childDevice) {
|
||||
$device->addChild($childDevice);
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif ($childName eq 'serviceList') {
|
||||
my $services = $childElement->[2];
|
||||
for my $serviceElement (@$services) {
|
||||
my $service = $self->parseServiceElement($serviceElement,
|
||||
@_);
|
||||
if ($service) {
|
||||
$device->addService($service);
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif (UPnP::Common::Device::isProperty($childName)) {
|
||||
my $value = $childElement->[2];
|
||||
$device->$childName($value);
|
||||
}
|
||||
}
|
||||
|
||||
return $device;
|
||||
}
|
||||
|
||||
sub parseDeviceDescription {
|
||||
my $self = shift;
|
||||
my $description = shift;
|
||||
my ($base, $device);
|
||||
|
||||
my $parser = $self->parser;
|
||||
my $element = $parser->parse($description);
|
||||
if (defined($element) && ref $element eq 'ARRAY') {
|
||||
my($name, $attrs, $children) = @$element;
|
||||
for my $child (@$children) {
|
||||
my ($childName) = @$child;
|
||||
if ($childName eq 'URLBase') {
|
||||
$base = $child->[2];
|
||||
}
|
||||
elsif ($childName eq 'device') {
|
||||
$device = $self->parseDeviceElement($child,
|
||||
undef,
|
||||
@_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ($device, $base);
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
package UPnP::Common::Device;
|
||||
|
||||
use strict;
|
||||
|
||||
use Carp;
|
||||
use Scalar::Util qw(weaken);
|
||||
|
||||
use vars qw($AUTOLOAD %deviceProperties);
|
||||
for my $prop (qw(deviceType friendlyName manufacturer
|
||||
manufacturerURL modelDescription modelName
|
||||
modelNumber modelURL serialNumber UDN
|
||||
presentationURL UPC location)) {
|
||||
$deviceProperties{$prop}++;
|
||||
}
|
||||
|
||||
sub new {
|
||||
my $self = shift;
|
||||
my $class = ref($self) || $self;
|
||||
my %args = @_;
|
||||
|
||||
$self = bless {}, $class;
|
||||
if ($args{Location}) {
|
||||
$self->location($args{Location});
|
||||
}
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub addChild {
|
||||
my $self = shift;
|
||||
my $child = shift;
|
||||
|
||||
push @{$self->{_children}}, $child;
|
||||
}
|
||||
|
||||
sub addService {
|
||||
my $self = shift;
|
||||
my $service = shift;
|
||||
|
||||
push @{$self->{_services}}, $service;
|
||||
}
|
||||
|
||||
sub parent {
|
||||
my $self = shift;
|
||||
|
||||
if (@_) {
|
||||
$self->{_parent} = shift;
|
||||
weaken($self->{_parent});
|
||||
}
|
||||
|
||||
return $self->{_parent};
|
||||
}
|
||||
|
||||
sub children {
|
||||
my $self = shift;
|
||||
|
||||
if (ref $self->{_children}) {
|
||||
return @{$self->{_children}};
|
||||
}
|
||||
|
||||
return ();
|
||||
}
|
||||
|
||||
sub services {
|
||||
my $self = shift;
|
||||
|
||||
if (ref $self->{_services}) {
|
||||
return @{$self->{_services}};
|
||||
}
|
||||
|
||||
return ();
|
||||
}
|
||||
|
||||
sub getService {
|
||||
my $self = shift;
|
||||
my $id = shift;
|
||||
|
||||
for my $service ($self->services) {
|
||||
if ($id &&
|
||||
($id eq $service->serviceId) ||
|
||||
($id eq $service->serviceType)) {
|
||||
return $service;
|
||||
}
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub isProperty {
|
||||
my $prop = shift;
|
||||
return $deviceProperties{$prop};
|
||||
}
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
my $attr = $AUTOLOAD;
|
||||
$attr =~ s/.*:://;
|
||||
return if $attr eq 'DESTROY';
|
||||
|
||||
croak "invalid attribute method: ->$attr()" unless $deviceProperties{$attr};
|
||||
|
||||
$self->{uc $attr} = shift if @_;
|
||||
return $self->{uc $attr};
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
package UPnP::Common::Service;
|
||||
|
||||
use strict;
|
||||
|
||||
use SOAP::Lite;
|
||||
use Carp;
|
||||
|
||||
use vars qw($AUTOLOAD %serviceProperties);
|
||||
for my $prop (qw(serviceType serviceId SCPDURL controlURL
|
||||
eventSubURL base)) {
|
||||
$serviceProperties{$prop}++;
|
||||
}
|
||||
|
||||
sub new {
|
||||
my $self = shift;
|
||||
my $class = ref($self) || $self;
|
||||
|
||||
return bless {}, $class;
|
||||
}
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
my $attr = $AUTOLOAD;
|
||||
$attr =~ s/.*:://;
|
||||
return if $attr eq 'DESTROY';
|
||||
|
||||
croak "invalid attribute method: ->$attr()" unless $serviceProperties{$attr};
|
||||
|
||||
$self->{uc $attr} = shift if @_;
|
||||
return $self->{uc $attr};
|
||||
}
|
||||
|
||||
sub isProperty {
|
||||
my $prop = shift;
|
||||
return $serviceProperties{$prop};
|
||||
}
|
||||
|
||||
sub addAction {
|
||||
my $self = shift;
|
||||
my $action = shift;
|
||||
|
||||
$self->{_actions}->{$action->name} = $action;
|
||||
}
|
||||
|
||||
sub addStateVariable {
|
||||
my $self = shift;
|
||||
my $var = shift;
|
||||
|
||||
$self->{_stateVariables}->{$var->name} = $var;
|
||||
}
|
||||
|
||||
sub actions {
|
||||
my $self = shift;
|
||||
|
||||
$self->_loadDescription;
|
||||
|
||||
if (defined($self->{_actions})) {
|
||||
return values %{$self->{_actions}};
|
||||
}
|
||||
|
||||
return ();
|
||||
}
|
||||
|
||||
sub getAction {
|
||||
my $self = shift;
|
||||
my $name = shift;
|
||||
|
||||
$self->_loadDescription;
|
||||
|
||||
if (defined($self->{_actions})) {
|
||||
return $self->{_actions}->{$name};
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub stateVariables {
|
||||
my $self = shift;
|
||||
|
||||
$self->_loadDescription;
|
||||
|
||||
if (defined($self->{_stateVariables})) {
|
||||
return values %{$self->{_stateVariables}};
|
||||
}
|
||||
|
||||
return ();
|
||||
}
|
||||
|
||||
sub getStateVariable {
|
||||
my $self = shift;
|
||||
my $name = shift;
|
||||
|
||||
$self->_loadDescription;
|
||||
|
||||
if (defined($self->{_stateVariables})) {
|
||||
return $self->{_stateVariables}->{$name};
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub getArgumentType {
|
||||
my $self = shift;
|
||||
my $arg = shift;
|
||||
|
||||
$self->_loadDescription;
|
||||
|
||||
my $var = $self->getStateVariable($arg->relatedStateVariable);
|
||||
if ($var) {
|
||||
return $var->SOAPType;
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub _parseArgumentList {
|
||||
my $self = shift;
|
||||
my $list = shift;
|
||||
my $action = shift;
|
||||
|
||||
return if (! ref $list);
|
||||
|
||||
for my $argumentElement (@$list) {
|
||||
my($name, $attrs, $children) = @$argumentElement;
|
||||
if ($name eq 'argument') {
|
||||
my $argument = UPnP::Common::Argument->new;
|
||||
for my $argumentChild (@$children) {
|
||||
my ($childName) = @$argumentChild;
|
||||
if ($childName eq 'name') {
|
||||
$argument->name($argumentChild->[2]);
|
||||
}
|
||||
elsif ($childName eq 'direction') {
|
||||
my $direction = $argumentChild->[2];
|
||||
if ($direction eq 'in') {
|
||||
$action->addInArgument($argument);
|
||||
}
|
||||
elsif ($direction eq 'out') {
|
||||
$action->addOutArgument($argument);
|
||||
}
|
||||
}
|
||||
elsif ($childName eq 'relatedStateVariable') {
|
||||
$argument->relatedStateVariable($argumentChild->[2]);
|
||||
}
|
||||
elsif ($childName eq 'retval') {
|
||||
$action->retval($argument);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub _parseActionList {
|
||||
my $self = shift;
|
||||
my $list = shift;
|
||||
|
||||
for my $actionElement (@$list) {
|
||||
my($name, $attrs, $children) = @$actionElement;
|
||||
if ($name eq 'action') {
|
||||
my $action = UPnP::Common::Action->new;
|
||||
for my $actionChild (@$children) {
|
||||
my ($childName) = @$actionChild;
|
||||
if ($childName eq 'name') {
|
||||
$action->name($actionChild->[2]);
|
||||
}
|
||||
elsif ($childName eq 'argumentList') {
|
||||
$self->_parseArgumentList($actionChild->[2],
|
||||
$action);
|
||||
}
|
||||
}
|
||||
$self->addAction($action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub _parseStateTable {
|
||||
my $self = shift;
|
||||
my $list = shift;
|
||||
|
||||
for my $varElement (@$list) {
|
||||
my($name, $attrs, $children) = @$varElement;
|
||||
if ($name eq 'stateVariable') {
|
||||
my $var = UPnP::Common::StateVariable->new(exists $attrs->{sendEvents} && ($attrs->{sendEvents} eq 'yes'));
|
||||
for my $varChild (@$children) {
|
||||
my ($childName) = @$varChild;
|
||||
if ($childName eq 'name') {
|
||||
$var->name($varChild->[2]);
|
||||
}
|
||||
elsif ($childName eq 'dataType') {
|
||||
$var->type($varChild->[2]);
|
||||
}
|
||||
}
|
||||
$self->addStateVariable($var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub parseServiceDescription {
|
||||
my $self = shift;
|
||||
my $parser = shift;
|
||||
my $description = shift;
|
||||
|
||||
my $element = $parser->parse($description);
|
||||
if (defined($element) && ref $element eq 'ARRAY') {
|
||||
my($name, $attrs, $children) = @$element;
|
||||
for my $child (@$children) {
|
||||
my ($childName) = @$child;
|
||||
if ($childName eq 'actionList') {
|
||||
$self->_parseActionList($child->[2]);
|
||||
}
|
||||
elsif ($childName eq 'serviceStateTable') {
|
||||
$self->_parseStateTable($child->[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
carp("Malformed SCPD document");
|
||||
}
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
package UPnP::Common::Action;
|
||||
|
||||
use strict;
|
||||
|
||||
use Carp;
|
||||
|
||||
use vars qw($AUTOLOAD %actionProperties);
|
||||
for my $prop (qw(name retval)) {
|
||||
$actionProperties{$prop}++;
|
||||
}
|
||||
|
||||
sub new {
|
||||
return bless {}, shift;
|
||||
}
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
my $attr = $AUTOLOAD;
|
||||
$attr =~ s/.*:://;
|
||||
return if $attr eq 'DESTROY';
|
||||
|
||||
croak "invalid attribute method: ->$attr()" unless $actionProperties{$attr};
|
||||
|
||||
$self->{uc $attr} = shift if @_;
|
||||
return $self->{uc $attr};
|
||||
}
|
||||
|
||||
sub addInArgument {
|
||||
my $self = shift;
|
||||
my $argument = shift;
|
||||
|
||||
push @{$self->{_inArguments}}, $argument;
|
||||
}
|
||||
|
||||
sub addOutArgument {
|
||||
my $self = shift;
|
||||
my $argument = shift;
|
||||
|
||||
push @{$self->{_outArguments}}, $argument;
|
||||
}
|
||||
|
||||
sub inArguments {
|
||||
my $self = shift;
|
||||
|
||||
if (defined $self->{_inArguments}) {
|
||||
return @{$self->{_inArguments}};
|
||||
}
|
||||
|
||||
return ();
|
||||
}
|
||||
|
||||
sub outArguments {
|
||||
my $self = shift;
|
||||
|
||||
if (defined $self->{_outArguments}) {
|
||||
return @{$self->{_outArguments}};
|
||||
}
|
||||
|
||||
return ();
|
||||
}
|
||||
|
||||
sub arguments {
|
||||
my $self = shift;
|
||||
|
||||
return ($self->inArguments, $self->outArguments);
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
package UPnP::Common::Argument;
|
||||
|
||||
use strict;
|
||||
|
||||
use Carp;
|
||||
|
||||
use vars qw($AUTOLOAD %argumentProperties);
|
||||
for my $prop (qw(name relatedStateVariable)) {
|
||||
$argumentProperties{$prop}++;
|
||||
}
|
||||
|
||||
sub new {
|
||||
return bless {}, shift;
|
||||
}
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
my $attr = $AUTOLOAD;
|
||||
$attr =~ s/.*:://;
|
||||
return if $attr eq 'DESTROY';
|
||||
|
||||
croak "invalid attribute method: ->$attr()" unless $argumentProperties{$attr};
|
||||
|
||||
$self->{uc $attr} = shift if @_;
|
||||
return $self->{uc $attr};
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
package UPnP::Common::StateVariable;
|
||||
|
||||
use strict;
|
||||
|
||||
use Carp;
|
||||
|
||||
use vars qw($AUTOLOAD %varProperties);
|
||||
for my $prop (qw(name type evented)) {
|
||||
$varProperties{$prop}++;
|
||||
}
|
||||
|
||||
sub new {
|
||||
my $self = bless {}, shift;
|
||||
$self->evented(shift);
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub SOAPType {
|
||||
my $self = shift;
|
||||
return UPnP::Common::UPnPToSOAPType($self->type);
|
||||
}
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
my $attr = $AUTOLOAD;
|
||||
$attr =~ s/.*:://;
|
||||
return if $attr eq 'DESTROY';
|
||||
|
||||
croak "invalid attribute method: ->$attr()" unless $varProperties{$attr};
|
||||
|
||||
$self->{uc $attr} = shift if @_;
|
||||
return $self->{uc $attr};
|
||||
}
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
package UPnP::Common::Parser;
|
||||
|
||||
use XML::Parser::Lite;
|
||||
|
||||
# Parser code borrowed from SOAP::Lite. This package uses the
|
||||
# event-driven XML::Parser::Lite parser to construct a nested data
|
||||
# structure - a poor man's DOM. Each XML element in the data structure
|
||||
# is represented by an array ref, with the values (listed by subscript
|
||||
# below) corresponding with:
|
||||
# 0 - The element name.
|
||||
# 1 - A hash ref representing the element attributes.
|
||||
# 2 - An array ref holding either child elements or concatenated
|
||||
# character data.
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
|
||||
return bless { _parser => XML::Parser::Lite->new }, $class;
|
||||
}
|
||||
|
||||
sub parse {
|
||||
my $self = shift;
|
||||
my $parser = $self->{_parser};
|
||||
|
||||
$parser->setHandlers(Final => sub { shift; $self->final(@_) },
|
||||
Start => sub { shift; $self->start(@_) },
|
||||
End => sub { shift; $self->end(@_) },
|
||||
Char => sub { shift; $self->char(@_) },);
|
||||
$parser->parse(shift);
|
||||
}
|
||||
|
||||
sub final {
|
||||
my $self = shift;
|
||||
my $parser = $self->{_parser};
|
||||
|
||||
# clean handlers, otherwise ControlPoint::Parser won't be deleted:
|
||||
# it refers to XML::Parser which refers to subs from ControlPoint::Parser
|
||||
undef $self->{_values};
|
||||
$parser->setHandlers(Final => undef,
|
||||
Start => undef,
|
||||
End => undef,
|
||||
Char => undef,);
|
||||
$self->{_done};
|
||||
}
|
||||
|
||||
sub start { push @{shift->{_values}}, [shift, {@_}] }
|
||||
|
||||
sub char { push @{shift->{_values}->[-1]->[3]}, shift }
|
||||
|
||||
sub end {
|
||||
my $self = shift;
|
||||
my $done = pop @{$self->{_values}};
|
||||
$done->[2] = defined $done->[3] ? join('',@{$done->[3]}) : '' unless ref $done->[2];
|
||||
undef $done->[3];
|
||||
@{$self->{_values}} ? (push @{$self->{_values}->[-1]->[2]}, $done)
|
||||
: ($self->{_done} = $done);
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
UPnP::Common - Internal modules and methods for the UPnP
|
||||
implementation. The C<UPnP::ControlPoint> and C<UPnP::DeviceManager>
|
||||
modules should be used.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Part of the Perl UPnP implementation suite.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
UPnP documentation and resources can be found at L<http://www.upnp.org>.
|
||||
|
||||
The C<SOAP::Lite> module can be found at L<http://www.soaplite.com>.
|
||||
|
||||
UPnP implementations in other languages include the UPnP SDK for Linux
|
||||
(L<http://upnp.sourceforge.net/>), Cyberlink for Java
|
||||
(L<http://www.cybergarage.org/net/upnp/java/index.html>) and C++
|
||||
(L<http://sourceforge.net/projects/clinkcc/>), and the Microsoft UPnP
|
||||
SDK
|
||||
(L<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/upnp/upnp/universal_plug_and_play_start_page.asp>).
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Vidur Apparao (vidurapparao@users.sourceforge.net)
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (C) 2004 by Vidur Apparao
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself, either Perl version 5.8 or,
|
||||
at your option, any later version of Perl 5 you may have available.
|
||||
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:t
|
||||
# End:
|
1595
fhem/FHEM/lib/UPnP/ControlPoint.pm
Normal file
1595
fhem/FHEM/lib/UPnP/ControlPoint.pm
Normal file
File diff suppressed because it is too large
Load Diff
BIN
fhem/FHEM/lib/UPnP/sonos_empty.jpg
Normal file
BIN
fhem/FHEM/lib/UPnP/sonos_empty.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.7 KiB |
BIN
fhem/FHEM/lib/UPnP/sonos_input_default.jpg
Normal file
BIN
fhem/FHEM/lib/UPnP/sonos_input_default.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
BIN
fhem/FHEM/lib/UPnP/sonos_input_tv.jpg
Normal file
BIN
fhem/FHEM/lib/UPnP/sonos_input_tv.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
fhem/FHEM/lib/UPnP/sonos_playlist.jpg
Normal file
BIN
fhem/FHEM/lib/UPnP/sonos_playlist.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
1205
fhem/HISTORY
1205
fhem/HISTORY
File diff suppressed because it is too large
Load Diff
@ -1,324 +1,329 @@
|
||||
Files with a maintainer. If you wish to change a file, please contact the
|
||||
maintainer of the file to do the change.
|
||||
|
||||
The third column specifies, where/how the maintainer should be contacted. If
|
||||
there is no reaction from the mainainer within 3 weeks, then rudolfkoenig
|
||||
(forum.fhem.de/FHEM Forum) should be contacted, in order to assign a new
|
||||
maintainer.
|
||||
|
||||
When adding a new file, add yourself as the maintainer.
|
||||
|
||||
File Maintainer Contact
|
||||
=========================================================================
|
||||
fhem.pl rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
fhem.cfg rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
Makefile rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
configDB.pm betateilchen http://forum.fhem.de Sonstiges
|
||||
|
||||
FHEM/00_CM11.pm borisneubert http://forum.fhem.de SlowRF
|
||||
FHEM/00_CUL.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/00_FBAHA.pm rudolfkoenig http://forum.fhem.de FRITZ!Box
|
||||
FHEM/00_FHZ.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/00_HMLAN.pm martinp876 http://forum.fhem.de HomeMatic
|
||||
FHEM/00_KM271.pm physikus http://forum.fhem.de Sonstiges
|
||||
FHEM/00_LIRC.pm rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
FHEM/00_MAXLAN.pm mgehre http://forum.fhem.de MAX
|
||||
FHEM/00_MQTT.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/00_MYSENSORS.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/00_NetzerI2C.pm klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/00_OWX.pm pahenning/ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/00_OWX_ASYNC ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/00_RPII2C klausw http://forum.fhem.de Einplatinencomputer
|
||||
FHEM/00_TCM.pm klaus-schauer http://forum.fhem.de EnOcean
|
||||
FHEM/00_THZ.pm immiimmi http://forum.fhem.de Sonstiges
|
||||
FHEM/00_TUL.pm hotmaz http://forum.fhem.de KNX/EIB
|
||||
FHEM/00_ZWDongle.pm rudolfkoenig http://forum.fhem.de ZWave
|
||||
FHEM/01_FHEMWEB.pm rudolfkoenig http://forum.fhem.de Frontends
|
||||
FHEM/02_FRAMEBUFFER.pm kaihs http://forum.fhem.de Frontends
|
||||
FHEM/02_HTTPSRV.pm borisneubert http://forum.fhem.de Frontends
|
||||
FHEM/02_RSS.pm borisneubert http://forum.fhem.de Frontends
|
||||
FHEM/09_BS.pm borisneubert http://forum.fhem.de SlowRF
|
||||
FHEM/09_CUL_FHTTK.pm matscher http://forum.fhem.de SlowRF
|
||||
FHEM/09_USF1000.pm borisneubert http://forum.fhem.de SlowRF
|
||||
FHEM/10_CUL_HM.pm martinp876 http://forum.fhem.de HomeMatic
|
||||
FHEM/10_CUL_IR.pm odroegehorn http://forum.fhem.de SlowRF
|
||||
FHEM/10_EIB.pm hotmaz http://forum.fhem.de KNX/EIB
|
||||
FHEM/10_EnOcean.pm klaus-schauer http://forum.fhem.de EnOcean
|
||||
FHEM/10_FBDECT.pm rudolfkoenig http://forum.fhem.de FRITZ!Box
|
||||
FHEM/10_FRM.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/10_FS20.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/10_IT.pm justme1968 http://forum.fhem.de InterTechno
|
||||
FHEM/10_Itach_IR ulimaass http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/10_MAX.pm mgehre http://forum.fhem.de MAX
|
||||
FHEM/10_MQTT_BRIDGE ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/10_MQTT_DEVICE ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/10_MYSENSORS_DEVICE ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/10_OWServer.pm borisneubert/mfr69bs http://forum.fhem.de 1Wire
|
||||
FHEM/10_SOMFY.pm thdankert http://forum.fhem.de Sonstiges
|
||||
FHEM/10_UNIRoll.pm c-herrmann http://forum.fhem.de SlowRF
|
||||
FHEM/10_ZWave.pm rudolfkoenig http://forum.fhem.de ZWave
|
||||
FHEM/10_RESIDENTS.pm loredo http://forum.fhem.de Automatisierung
|
||||
FHEM/11_FHT.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/11_FHT8V.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/11_OWDevice.pm borisneubert/mfr69bs http://forum.fhem.de 1Wire
|
||||
FHEM/12_HMS.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/13_KS300.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/14_CUL_MAX.pm mgehre http://forum.fhem.de MAX
|
||||
FHEM/14_CUL_TX.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/14_CUL_WS.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/15_CUL_EM.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/16_CUL_RFR.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/16_STACKABLE_CC.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/17_EGPM2LAN.pm alexus http://forum.fhem.de Sonstiges
|
||||
FHEM/17_SIS_PMS.pm painseeker http://forum.fhem.de Sonstiges
|
||||
FHEM/18_CUL_HOERMANN.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/19_Revolt.pm martinppp/mehf http://forum.fhem.de SlowRF
|
||||
FHEM/20_FRM_AD.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_FRM_ROTENC.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_FRM_I2C.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_FRM_IN.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_FRM_LCD.pm ntruchsess http://forum.fhem.de Sonstige Systeme (deprecated)
|
||||
FHEM/20_FRM_OUT.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_FRM_PWM.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_FRM_RBG.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_FRM_SERVO.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_FRM_STEPPER.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_OWFS.pm mfr69bs http://forum.fhem.de 1Wire (deprecated)
|
||||
FHEM/20_X10.pm borisneubert http://forum.fhem.de SlowRF
|
||||
FHEM/20_ROOMMATE.pm loredo http://forum.fhem.de Automatisierung
|
||||
FHEM/20_GUEST.pm loredo http://forum.fhem.de Automatisierung
|
||||
FHEM/21_OWAD.pm pahenning/ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/21_OWCOUNT.pm pahenning/ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/21_OWID.pm pahenning/ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/21_OWLCD.pm pahenning/ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/21_OWMULTI.pm pahenning/ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/21_OWSWITCH.pm pahenning/ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/21_OWTEMP.pm mfr69bs http://forum.fhem.de 1Wire (deprecated)
|
||||
FHEM/21_OWTHERM.pm pahenning/ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/22_ALL3076.pm sachag http://forum.fhem.de Snstiges
|
||||
FHEM/23_ALL4027.pm sachag http://forum.fhem.de Sonstiges
|
||||
FHEM/23_KOSTALPIKO.pm john http://forum.fhem.de CodeSchnipsel
|
||||
FHEM/23_LUXTRONIK2.pm tupol http://forum.fhem.de Sonstiges (PM: http://forum.fhem.de/index.php?action=pm;sa=send;u=5432)
|
||||
FHEM/23_WEBIO.pm sachag http://forum.fhem.de Sonstiges
|
||||
FHEM/23_WEBIO_12DIGITAL.pm sachag http://forum.fhem.de Sonstiges
|
||||
FHEM/24_NetIO230B.pm rudolfkoenig/orphan http://forum.fhem.de Sonstiges
|
||||
FHEM/30_HUEBridge.pm justme1968 http://forum.fhem.de Beleuchtung
|
||||
FHEM/30_ENECSYSGW.pm akw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/31_HUEDevice.pm justme1968 http://forum.fhem.de Beleuchtung
|
||||
FHEM/31_ENECSYSINV.pm akw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/31_LightScene.pm justme1968 http://forum.fhem.de Automatisierung
|
||||
FHEM/32_SYSSTAT.pm justme1968 http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/32_mailcheck.pm justme1968 http://forum.fhem.de Automatisierung
|
||||
FHEM/32_withings.pm justme1968 http://forum.fhem.de Sonstiges
|
||||
FHEM/33_readingsGroup.pm justme1968 http://forum.fhem.de Frontends
|
||||
FHEM/33_readingsHistory.pm justme1968 http://forum.fhem.de Frontends
|
||||
FHEM/33_readingsProxy.pm justme1968 http://forum.fhem.de Automatisierung
|
||||
FHEM/32_speedtest.pm justme1968 http://forum.fhem.de Sonstiges
|
||||
FHEM/34_NUT.pm creideiki http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/34_panStamp.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/34_SWAP.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/35_SWAP_0000002200000003.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/35_SWAP_0000002200000008.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/36_EC3000.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/36_JeeLink.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/36_PCA301.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/36_LaCrosse.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/36_EMT7110.pm HCS http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/36_Level.pm HCS http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/36_WMBUS.pm kaihs http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/37_SHC.pm rr2000 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/37_SHCdev.pm rr2000 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/38_harmony.pm justme1968 http://forum.fhem.de Multimedia
|
||||
FHEM/38_CO20.pm justme1968 http://forum.fhem.de Sonstiges
|
||||
FHEM/40_RFXCOM.pm wherzig http://forum.fhem.de RFXTRX
|
||||
FHEM/41_OREGON.pm wherzig http://forum.fhem.de Sonstiges
|
||||
FHEM/42_RFXMETER.pm wherzig http://forum.fhem.de RFXTRX
|
||||
maintainer of the file to do the change.
|
||||
|
||||
The third column specifies, where/how the maintainer should be contacted. If
|
||||
there is no reaction from the mainainer within 3 weeks, then rudolfkoenig
|
||||
(forum.fhem.de/FHEM Forum) should be contacted, in order to assign a new
|
||||
maintainer.
|
||||
|
||||
When adding a new file, add yourself as the maintainer.
|
||||
|
||||
File Maintainer Contact
|
||||
=========================================================================
|
||||
fhem.pl rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
fhem.cfg rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
Makefile rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
configDB.pm betateilchen http://forum.fhem.de Sonstiges
|
||||
|
||||
FHEM/00_CM11.pm borisneubert http://forum.fhem.de SlowRF
|
||||
FHEM/00_CUL.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/00_FBAHA.pm rudolfkoenig http://forum.fhem.de FRITZ!Box
|
||||
FHEM/00_FHZ.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/00_HMLAN.pm martinp876 http://forum.fhem.de HomeMatic
|
||||
FHEM/00_KM271.pm physikus http://forum.fhem.de Sonstiges
|
||||
FHEM/00_LIRC.pm rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
FHEM/00_MAXLAN.pm mgehre http://forum.fhem.de MAX
|
||||
FHEM/00_MQTT.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/00_MYSENSORS.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/00_NetzerI2C.pm klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/00_OWX.pm pahenning/ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/00_OWX_ASYNC ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/00_RPII2C klausw http://forum.fhem.de Einplatinencomputer
|
||||
FHEM/00_SONOS.pm Reinerlein http://forum.fhem.de Multimedia
|
||||
FHEM/00_TCM.pm klaus-schauer http://forum.fhem.de EnOcean
|
||||
FHEM/00_THZ.pm immiimmi http://forum.fhem.de Sonstiges
|
||||
FHEM/00_TUL.pm hotmaz http://forum.fhem.de KNX/EIB
|
||||
FHEM/00_ZWDongle.pm rudolfkoenig http://forum.fhem.de ZWave
|
||||
FHEM/01_FHEMWEB.pm rudolfkoenig http://forum.fhem.de Frontends
|
||||
FHEM/02_FRAMEBUFFER.pm kaihs http://forum.fhem.de Frontends
|
||||
FHEM/02_HTTPSRV.pm borisneubert http://forum.fhem.de Frontends
|
||||
FHEM/02_RSS.pm borisneubert http://forum.fhem.de Frontends
|
||||
FHEM/09_BS.pm borisneubert http://forum.fhem.de SlowRF
|
||||
FHEM/09_CUL_FHTTK.pm matscher http://forum.fhem.de SlowRF
|
||||
FHEM/09_USF1000.pm borisneubert http://forum.fhem.de SlowRF
|
||||
FHEM/10_CUL_HM.pm martinp876 http://forum.fhem.de HomeMatic
|
||||
FHEM/10_CUL_IR.pm odroegehorn http://forum.fhem.de SlowRF
|
||||
FHEM/10_EIB.pm hotmaz http://forum.fhem.de KNX/EIB
|
||||
FHEM/10_EnOcean.pm klaus-schauer http://forum.fhem.de EnOcean
|
||||
FHEM/10_FBDECT.pm rudolfkoenig http://forum.fhem.de FRITZ!Box
|
||||
FHEM/10_FRM.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/10_FS20.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/10_IT.pm justme1968 http://forum.fhem.de InterTechno
|
||||
FHEM/10_Itach_IR ulimaass http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/10_MAX.pm mgehre http://forum.fhem.de MAX
|
||||
FHEM/10_MQTT_BRIDGE ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/10_MQTT_DEVICE ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/10_MYSENSORS_DEVICE ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/10_OWServer.pm borisneubert/mfr69bs http://forum.fhem.de 1Wire
|
||||
FHEM/10_SOMFY.pm thdankert http://forum.fhem.de Sonstiges
|
||||
FHEM/10_UNIRoll.pm c-herrmann http://forum.fhem.de SlowRF
|
||||
FHEM/10_ZWave.pm rudolfkoenig http://forum.fhem.de ZWave
|
||||
FHEM/10_RESIDENTS.pm loredo http://forum.fhem.de Automatisierung
|
||||
FHEM/11_FHT.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/11_FHT8V.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/11_OWDevice.pm borisneubert/mfr69bs http://forum.fhem.de 1Wire
|
||||
FHEM/12_HMS.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/13_KS300.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/14_CUL_MAX.pm mgehre http://forum.fhem.de MAX
|
||||
FHEM/14_CUL_TX.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/14_CUL_WS.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/15_CUL_EM.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/16_CUL_RFR.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/16_STACKABLE_CC.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/17_EGPM2LAN.pm alexus http://forum.fhem.de Sonstiges
|
||||
FHEM/17_SIS_PMS.pm painseeker http://forum.fhem.de Sonstiges
|
||||
FHEM/18_CUL_HOERMANN.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/19_Revolt.pm martinppp/mehf http://forum.fhem.de SlowRF
|
||||
FHEM/20_FRM_AD.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_FRM_ROTENC.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_FRM_I2C.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_FRM_IN.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_FRM_LCD.pm ntruchsess http://forum.fhem.de Sonstige Systeme (deprecated)
|
||||
FHEM/20_FRM_OUT.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_FRM_PWM.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_FRM_RBG.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_FRM_SERVO.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_FRM_STEPPER.pm ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/20_OWFS.pm mfr69bs http://forum.fhem.de 1Wire (deprecated)
|
||||
FHEM/20_X10.pm borisneubert http://forum.fhem.de SlowRF
|
||||
FHEM/20_ROOMMATE.pm loredo http://forum.fhem.de Automatisierung
|
||||
FHEM/20_GUEST.pm loredo http://forum.fhem.de Automatisierung
|
||||
FHEM/21_OWAD.pm pahenning/ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/21_OWCOUNT.pm pahenning/ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/21_OWID.pm pahenning/ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/21_OWLCD.pm pahenning/ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/21_OWMULTI.pm pahenning/ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/21_OWSWITCH.pm pahenning/ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/21_OWTEMP.pm mfr69bs http://forum.fhem.de 1Wire (deprecated)
|
||||
FHEM/21_OWTHERM.pm pahenning/ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/21_SONOSPLAYER Reinerlein http://forum.fhem.de Multimedia
|
||||
FHEM/22_ALL3076.pm sachag http://forum.fhem.de Snstiges
|
||||
FHEM/23_ALL4027.pm sachag http://forum.fhem.de Sonstiges
|
||||
FHEM/23_KOSTALPIKO.pm john http://forum.fhem.de CodeSchnipsel
|
||||
FHEM/23_LUXTRONIK2.pm tupol http://forum.fhem.de Sonstiges (PM: http://forum.fhem.de/index.php?action=pm;sa=send;u=5432)
|
||||
FHEM/23_WEBIO.pm sachag http://forum.fhem.de Sonstiges
|
||||
FHEM/23_WEBIO_12DIGITAL.pm sachag http://forum.fhem.de Sonstiges
|
||||
FHEM/24_NetIO230B.pm rudolfkoenig/orphan http://forum.fhem.de Sonstiges
|
||||
FHEM/30_HUEBridge.pm justme1968 http://forum.fhem.de Beleuchtung
|
||||
FHEM/30_ENECSYSGW.pm akw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/31_HUEDevice.pm justme1968 http://forum.fhem.de Beleuchtung
|
||||
FHEM/31_ENECSYSINV.pm akw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/31_LightScene.pm justme1968 http://forum.fhem.de Automatisierung
|
||||
FHEM/32_SYSSTAT.pm justme1968 http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/32_mailcheck.pm justme1968 http://forum.fhem.de Automatisierung
|
||||
FHEM/32_withings.pm justme1968 http://forum.fhem.de Sonstiges
|
||||
FHEM/33_readingsGroup.pm justme1968 http://forum.fhem.de Frontends
|
||||
FHEM/33_readingsHistory.pm justme1968 http://forum.fhem.de Frontends
|
||||
FHEM/33_readingsProxy.pm justme1968 http://forum.fhem.de Automatisierung
|
||||
FHEM/32_speedtest.pm justme1968 http://forum.fhem.de Sonstiges
|
||||
FHEM/34_NUT.pm creideiki http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/34_panStamp.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/34_SWAP.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/35_SWAP_0000002200000003.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/35_SWAP_0000002200000008.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/36_EC3000.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/36_JeeLink.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/36_PCA301.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/36_LaCrosse.pm justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/36_EMT7110.pm HCS http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/36_Level.pm HCS http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/36_WMBUS.pm kaihs http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/37_SHC.pm rr2000 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/37_SHCdev.pm rr2000 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/38_harmony.pm justme1968 http://forum.fhem.de Multimedia
|
||||
FHEM/38_CO20.pm justme1968 http://forum.fhem.de Sonstiges
|
||||
FHEM/40_RFXCOM.pm wherzig http://forum.fhem.de RFXTRX
|
||||
FHEM/41_OREGON.pm wherzig http://forum.fhem.de Sonstiges
|
||||
FHEM/42_RFXMETER.pm wherzig http://forum.fhem.de RFXTRX
|
||||
FHEM/42_SMARTMON.pm hexenmeister http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/42_SYSMON.pm hexenmeister http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/43_RFXX10REC.pm wherzig http://forum.fhem.de RFXTRX
|
||||
FHEM/44_TEK603.pm eisler http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/45_TRX.pm wherzig http://forum.fhem.de RFXTRX
|
||||
FHEM/46_TRX_ELSE.pm wherzig http://forum.fhem.de RFXTRX
|
||||
FHEM/46_TRX_LIGHT.pm wherzig http://forum.fhem.de RFXTRX
|
||||
FHEM/46_TRX_SECURITY.pm wherzig http://forum.fhem.de RFXTRX
|
||||
FHEM/46_TRX_WEATHER.pm wherzig http://forum.fhem.de RFXTRX
|
||||
FHEM/49_IPCAM.pm mfr69bs http://forum.fhem.de Sonstiges
|
||||
FHEM/50_WS300.pm Dirk http://forum.fhem.de SlowRF
|
||||
FHEM/51_I2C_BMP180.pm Dirk http://forum.fhem.de Einplatinencomputer
|
||||
FHEM/51_Netzer.pm klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/51_RPI_GPIO.pm klausw http://forum.fhem.de Einplatinencomputer
|
||||
FHEM/52_I2C_DS1307 ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_EEPROM.pm klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_LCD ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_MCP23008 klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_MCP23017 klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_MCP342x klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_PCA9532 klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_PCF8574 klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_SHT21 klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_TSL2561 kaihs http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/55_GDS.pm betateilchen http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/55_PIFACE.pm klaus.schauer http://forum.fhem.de Einplatinencomputer
|
||||
FHEM/55_weco.pm betateilchen http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/56_POKEYS.pm axelberner http://forum.fhem.de Sonstiges
|
||||
FHEM/57_Calendar.pm borisneubert http://forum.fhem.de Unterstützende Dienste
|
||||
FHEM/59_HCS.pm mfr69bs http://forum.fhem.de Automatisierung
|
||||
FHEM/59_OPENWEATHER.pm tupol http://forum.fhem.de Unterstuetzende Dienste (PM: http://forum.fhem.de/index.php?action=pm;sa=send;u=5432)
|
||||
FHEM/59_Twilight.pm dietmar63 http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/59_PROPLANTA.pm tupol http://forum.fhem.de Unterstuetzende Dienste (PM: http://forum.fhem.de/index.php?action=pm;sa=send;u=5432)
|
||||
FHEM/59_WWO.pm baumrasen http://forum.fhem.de Sonstiges
|
||||
FHEM/59_Weather.pm borisneubert http://forum.fhem.de Unterstützende Dienste
|
||||
FHEM/60_EM.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/61_EMWZ.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/62_EMEM.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/63_EMGZ.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/64_ESA2000.pm stromer-12 http://forum.fhem.de SlowRF
|
||||
FHEM/66_ECMD.pm borisneubert http://forum.fhem.de Sonstiges
|
||||
FHEM/67_ECMDDevice.pm borisneubert http://forum.fhem.de Sonstiges
|
||||
FHEM/70_EGPM.pm alexus http://forum.fhem.de Sonstiges
|
||||
FHEM/70_ENIGMA2.pm loredo http://forum.fhem.de Multimedia
|
||||
FHEM/70_Jabber.pm BioS http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/70_JSONMETER.pm tupol http://forum.fhem.de Sonstiges
|
||||
FHEM/70_PHTV.pm loredo http://forum.fhem.de Multimedia
|
||||
FHEM/70_ONKYO_AVR.pm loredo http://forum.fhem.de Multimedia
|
||||
FHEM/70_PIONEERAVR.pm hofrichter http://forum.fhem.de Multimedia
|
||||
FHEM/70_SCIVT.pm rudolfkoenig/orphan http://forum.fhem.de Sonstiges
|
||||
FHEM/70_SISPM.pm real-wusel http://forum.fhem.de Sonstiges
|
||||
FHEM/70_SML.pm bentele http://forum.fhem.de Sonstiges
|
||||
FHEM/70_STV.pm bentele http://forum.fhem.de Sonstiges
|
||||
FHEM/70_TellStick.pm real-wusel http://forum.fhem.de Sonstiges
|
||||
FHEM/70_USBWX.pm wherzig http://forum.fhem.de Sonstiges
|
||||
FHEM/70_VIERA.pm teevau http://forum.fhem.de Sonstiges
|
||||
FHEM/70_WS3600.pm Josch http://forum.fhem.de Sonstiges
|
||||
FHEM/70_XBMC.pm dennisb http://forum.fhem.de Multimedia
|
||||
FHEM/70_Pushover.pm Johannes_B http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/70_PushNotifier.pm xusader http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/71_YAMAHA_AVR.pm markusbloch http://forum.fhem.de Multimedia
|
||||
FHEM/71_YAMAHA_BD.pm markusbloch http://forum.fhem.de Multimedia
|
||||
FHEM/72_FB_CALLMONITOR.pm markusbloch http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/72_FRITZBOX.pm tupol http://forum.fhem.de Unterstuetzende Dienste (PM: http://forum.fhem.de/index.php?action=pm;sa=send;u=5432)
|
||||
FHEM/73_PRESENCE.pm markusbloch http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/73_MPD.pm wzut http://forum.fhem.de Multimedia
|
||||
FHEM/75_MSG.pm ruebedo http://forum.fhem.de Automatisierung
|
||||
FHEM/76_MSGFile.pm ruebedo http://forum.fhem.de Automatisierung
|
||||
FHEM/76_MSGMail.pm ruebedo http://forum.fhem.de Automatisierung
|
||||
FHEM/80_M232.pm borisneubert http://forum.fhem.de Sonstiges
|
||||
FHEM/80_xxLG7000.pm painseeker http://forum.fhem.de Sonstiges
|
||||
FHEM/81_M232Counter.pm borisneubert http://forum.fhem.de Sonstiges
|
||||
FHEM/82_LGTV.pm painseeker http://forum.fhem.de Sonstiges
|
||||
FHEM/82_M232Voltage.pm borisneubert http://forum.fhem.de Sonstiges
|
||||
FHEM/87_WS2000.pm tdressler http://forum.fhem.de Sonstiges
|
||||
FHEM/88_ALL4000T.pm sachag http://forum.fhem.de Sonstiges
|
||||
FHEM/88_LINDY_HDMI_SWITCH.pm sachag http://forum.fhem.de Multimedia
|
||||
FHEM/88_IPWE.pm tdressler http://forum.fhem.de Sonstiges
|
||||
FHEM/88_Itach_Relay.pm sachag http://forum.fhem.de Automatisierung
|
||||
FHEM/88_Itach_IRDevice ulimaass http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/88_VantagePro2.pm sachag http://forum.fhem.de Sonstiges
|
||||
FHEM/88_WEBCOUNT.pm sachag http://forum.fhem.de Sonstiges
|
||||
FHEM/89_HEATRONIC.pm heikoranft http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/89_VCONTROL.pm adamwit http://forum.fhem.de Heizungssteuerung/Raumklima
|
||||
FHEM/90_at.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/91_eventTypes.pm rudolfkoenig http://forum.fhem.de Frontends
|
||||
FHEM/91_notify.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/91_sequence.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/91_watchdog.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/92_FileLog.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/93_DbLog.pm tobiasfaust http://forum.fhem.de Automatisierung
|
||||
FHEM/93_FHEM2FHEM.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/95_FLOORPLAN.pm ulimaass http://forum.fhem.de Frontends
|
||||
FHEM/95_Dashboard.pm svenson08 http://forum.fhem.de Frontends
|
||||
FHEM/95_PachLog.pm rudolfkoenig/orphan http://forum.fhem.de Sonstiges
|
||||
FHEM/95_holiday.pm rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
FHEM/95_remotecontrol.pm ulimaass http://forum.fhem.de Frontends
|
||||
FHEM/98_Text2Speech.pm tobiasfaust http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_apptime.pm martinp876 http://forum.fhem.de Sonstiges
|
||||
FHEM/98_ComfoAir.pm StefanStrobel http://forum.fhem.de Sonstiges
|
||||
FHEM/98_CULflash.pm rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
FHEM/98_DOIF.pm damian-s http://forum.fhem.de Automatisierung
|
||||
FHEM/98_FReplacer.pm stefanstrobel http://forum.fhem.de Sonstiges
|
||||
FHEM/98_GEOFANCY.pm loredo http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_HMinfo.pm martinp876 http://forum.fhem.de HomeMatic
|
||||
FHEM/98_Heating_Control.pm dietmar63 http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_HTTPMOD.pm stefanstrobel http://forum.fhem.de Sonstiges
|
||||
FHEM/98_IF.pm damian-s http://forum.fhem.de Automatisierung
|
||||
FHEM/98_JsonList.pm mfr69bs http://forum.fhem.de Automatisierung
|
||||
FHEM/98_JsonList2.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_PID20.pm John http://forum.fhem.de Automatisierung
|
||||
FHEM/98_RandomTimer.pm dietmar63 http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_SVG.pm rudolfkoenig http://forum.fhem.de Frontends
|
||||
FHEM/98_THRESHOLD.pm damian-s http://forum.fhem.de Automatisierung
|
||||
FHEM/98_WeekdayTimer.pm dietmar63 http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_WOL.pm dietmar63 http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_XmlList.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_autocreate.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_average.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_backup.pm rudlfkoenig http://forum.fhem.de Sonstiges
|
||||
FHEM/98_cloneDummy.pm Joachim http://forum.fhem.de Automatisierung
|
||||
FHEM/98_cmdalias.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_configdb.pm betateilchen http://forum.fhem.de Sonstiges
|
||||
FHEM/98_copy.pm justme1968 http://forum.fhem.de Sonstiges
|
||||
FHEM/98_CustomReadings.pm HCS http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_dewpoint.pm Joachim http://forum.fhem.de Automatisierung
|
||||
FHEM/98_dummy.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_fheminfo.pm mfr69bs http://forum.fhem.de Sonstiges
|
||||
FHEM/98_HourCounter.pm john http://forum.fhem.de MAX
|
||||
FHEM/98_logProxy.pm justme1968 http://forum.fhem.de Frontends
|
||||
FHEM/98_notice.pm mfr69bs http://forum.fhem.de Sonstiges
|
||||
FHEM/98_pilight.pm andreas-fey http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_rain.pm baumrasen http://forum.fhem.de Sonstiges
|
||||
FHEM/98_restore.pm rudolgkoenig http://forum.fhem.de Sonstiges
|
||||
FHEM/98_statistics.pm tupol http://forum.fhem.de Sonstiges (PM: http://forum.fhem.de/index.php?action=pm;sa=send;u=5432)
|
||||
FHEM/98_structure.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_telnet.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_update.pm rudolgkoenig http://forum.fhem.de Sonstiges
|
||||
FHEM/98_weblink.pm rudolfkoenig http://forum.fhem.de Frontends
|
||||
FHEM/99_SUNRISE_EL.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/99_Utils.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/Blocking.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/DevIo.pm rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
FHEM/Color.pm justme1968 http://forum.fhem.de Sonstiges
|
||||
FHEM/FritzBoxUtils.pm rudolfkoenig http://forum.fhem.de FRITZ!Box
|
||||
FHEM/HMConfig.pm martinp876 http://forum.fhem.de HomeMatic
|
||||
FHEM/HttpUtils.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/MaxCommon.pm mgehre http://forum.fhem.de MAX
|
||||
FHEM/ONKYOdb.pm loredo http://forum.fhem.de Multimedia
|
||||
FHEM/OWX_DS2480.pm ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/OWX_DS9097.pm ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/OWX_FRM.pm ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/OWX_SER.pm ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/SetExtensions.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/SHC_datafields.pm rr2000 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/SHC_parser.pm rr2000 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/TcpServerUtils.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/lib/Device/Firmata/* ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/lib/Device/MySensors/* ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/lib/ProtoThreads.pm ntruchsess http://forum.fhem.de FHEM Development
|
||||
FHEM/lib/SHC_packet_layout.xml rr2000 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/lib/SWAP/* justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/FhemUtils/* mfr69bs http://forum.fhem.de Sonstiges
|
||||
FHEM/GPUtils.pm ntruchsess http://forum.fhem.de FHEM Development
|
||||
|
||||
contrib/YAF/* danielweisensee http://forum.fhem.de Frontends
|
||||
contrib/23_WEBTHERM.pm betateilchen/sachag http://forum.fhem.de Sonstiges
|
||||
contrib/55_BBB_BMP180.pm betateilchen http://forum.fhem.de Einplatinencomputer
|
||||
contrib/71_LISTENLIVE.pm betateilchen http://forum.fhem.de Multimedia
|
||||
contrib/98_geodata.pm betateilchen http://forum.fhem.de Sonstiges
|
||||
contrib/98_openweathermap.pm betateilchen http://forum.fhem.de Unterstuetzende Dienste
|
||||
contrib/98_PID.pm betateilchen http://forum.fhem.de Automatisierung
|
||||
|
||||
www/codemirror/* betateilchen http://forum.fhem.de Frontends
|
||||
www/gplot/* rudolfkoenig http://forum.fhem.de Frontends
|
||||
www/images/* ulimaass http://forum.fhem.de Frontends
|
||||
www/pgm2/dashboard/* svenson08 http://forum.fhem.de Frontends
|
||||
www/pgm2/fhemweb_readingsHistory.js justme1968 http://forum.fhem.de Frontends
|
||||
www/pgm2/* rudolfkoenig http://forum.fhem.de Frontends
|
||||
www/jscolor/* justme1968 http://forum.fhem.de Frontends
|
||||
www/frontend/* johannnes http://forum.fhem.de Frontends
|
||||
|
||||
docs/fhem-floorplan-* ulimaass http://forum.fhem.de Sonstiges
|
||||
docs/* rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
|
||||
Files that every developer should modify/extend
|
||||
MAINTAINER.txt
|
||||
CHANGES
|
||||
HISTORY
|
||||
FHEM/42_SYSMON.pm hexenmeister http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/43_RFXX10REC.pm wherzig http://forum.fhem.de RFXTRX
|
||||
FHEM/44_TEK603.pm eisler http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/45_TRX.pm wherzig http://forum.fhem.de RFXTRX
|
||||
FHEM/46_TRX_ELSE.pm wherzig http://forum.fhem.de RFXTRX
|
||||
FHEM/46_TRX_LIGHT.pm wherzig http://forum.fhem.de RFXTRX
|
||||
FHEM/46_TRX_SECURITY.pm wherzig http://forum.fhem.de RFXTRX
|
||||
FHEM/46_TRX_WEATHER.pm wherzig http://forum.fhem.de RFXTRX
|
||||
FHEM/49_IPCAM.pm mfr69bs http://forum.fhem.de Sonstiges
|
||||
FHEM/50_WS300.pm Dirk http://forum.fhem.de SlowRF
|
||||
FHEM/51_I2C_BMP180.pm Dirk http://forum.fhem.de Einplatinencomputer
|
||||
FHEM/51_Netzer.pm klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/51_RPI_GPIO.pm klausw http://forum.fhem.de Einplatinencomputer
|
||||
FHEM/52_I2C_DS1307 ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_EEPROM.pm klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_LCD ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_MCP23008 klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_MCP23017 klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_MCP342x klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_PCA9532 klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_PCF8574 klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_SHT21 klausw http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/52_I2C_TSL2561 kaihs http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/55_GDS.pm betateilchen http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/55_PIFACE.pm klaus.schauer http://forum.fhem.de Einplatinencomputer
|
||||
FHEM/55_weco.pm betateilchen http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/56_POKEYS.pm axelberner http://forum.fhem.de Sonstiges
|
||||
FHEM/57_Calendar.pm borisneubert http://forum.fhem.de Unterstützende Dienste
|
||||
FHEM/59_HCS.pm mfr69bs http://forum.fhem.de Automatisierung
|
||||
FHEM/59_OPENWEATHER.pm tupol http://forum.fhem.de Unterstuetzende Dienste (PM: http://forum.fhem.de/index.php?action=pm;sa=send;u=5432)
|
||||
FHEM/59_Twilight.pm dietmar63 http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/59_PROPLANTA.pm tupol http://forum.fhem.de Unterstuetzende Dienste (PM: http://forum.fhem.de/index.php?action=pm;sa=send;u=5432)
|
||||
FHEM/59_WWO.pm baumrasen http://forum.fhem.de Sonstiges
|
||||
FHEM/59_Weather.pm borisneubert http://forum.fhem.de Unterstützende Dienste
|
||||
FHEM/60_EM.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/61_EMWZ.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/62_EMEM.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/63_EMGZ.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||
FHEM/64_ESA2000.pm stromer-12 http://forum.fhem.de SlowRF
|
||||
FHEM/66_ECMD.pm borisneubert http://forum.fhem.de Sonstiges
|
||||
FHEM/67_ECMDDevice.pm borisneubert http://forum.fhem.de Sonstiges
|
||||
FHEM/70_EGPM.pm alexus http://forum.fhem.de Sonstiges
|
||||
FHEM/70_ENIGMA2.pm loredo http://forum.fhem.de Multimedia
|
||||
FHEM/70_Jabber.pm BioS http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/70_JSONMETER.pm tupol http://forum.fhem.de Sonstiges
|
||||
FHEM/70_PHTV.pm loredo http://forum.fhem.de Multimedia
|
||||
FHEM/70_ONKYO_AVR.pm loredo http://forum.fhem.de Multimedia
|
||||
FHEM/70_PIONEERAVR.pm hofrichter http://forum.fhem.de Multimedia
|
||||
FHEM/70_SCIVT.pm rudolfkoenig/orphan http://forum.fhem.de Sonstiges
|
||||
FHEM/70_SISPM.pm real-wusel http://forum.fhem.de Sonstiges
|
||||
FHEM/70_SML.pm bentele http://forum.fhem.de Sonstiges
|
||||
FHEM/70_STV.pm bentele http://forum.fhem.de Sonstiges
|
||||
FHEM/70_TellStick.pm real-wusel http://forum.fhem.de Sonstiges
|
||||
FHEM/70_USBWX.pm wherzig http://forum.fhem.de Sonstiges
|
||||
FHEM/70_VIERA.pm teevau http://forum.fhem.de Sonstiges
|
||||
FHEM/70_WS3600.pm Josch http://forum.fhem.de Sonstiges
|
||||
FHEM/70_XBMC.pm dennisb http://forum.fhem.de Multimedia
|
||||
FHEM/70_Pushover.pm Johannes_B http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/70_PushNotifier.pm xusader http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/71_YAMAHA_AVR.pm markusbloch http://forum.fhem.de Multimedia
|
||||
FHEM/71_YAMAHA_BD.pm markusbloch http://forum.fhem.de Multimedia
|
||||
FHEM/72_FB_CALLMONITOR.pm markusbloch http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/72_FRITZBOX.pm tupol http://forum.fhem.de Unterstuetzende Dienste (PM: http://forum.fhem.de/index.php?action=pm;sa=send;u=5432)
|
||||
FHEM/73_PRESENCE.pm markusbloch http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/73_MPD.pm wzut http://forum.fhem.de Multimedia
|
||||
FHEM/75_MSG.pm ruebedo http://forum.fhem.de Automatisierung
|
||||
FHEM/76_MSGFile.pm ruebedo http://forum.fhem.de Automatisierung
|
||||
FHEM/76_MSGMail.pm ruebedo http://forum.fhem.de Automatisierung
|
||||
FHEM/80_M232.pm borisneubert http://forum.fhem.de Sonstiges
|
||||
FHEM/80_xxLG7000.pm painseeker http://forum.fhem.de Sonstiges
|
||||
FHEM/81_M232Counter.pm borisneubert http://forum.fhem.de Sonstiges
|
||||
FHEM/82_LGTV.pm painseeker http://forum.fhem.de Sonstiges
|
||||
FHEM/82_M232Voltage.pm borisneubert http://forum.fhem.de Sonstiges
|
||||
FHEM/87_WS2000.pm tdressler http://forum.fhem.de Sonstiges
|
||||
FHEM/88_ALL4000T.pm sachag http://forum.fhem.de Sonstiges
|
||||
FHEM/88_LINDY_HDMI_SWITCH.pm sachag http://forum.fhem.de Multimedia
|
||||
FHEM/88_IPWE.pm tdressler http://forum.fhem.de Sonstiges
|
||||
FHEM/88_Itach_Relay.pm sachag http://forum.fhem.de Automatisierung
|
||||
FHEM/88_Itach_IRDevice ulimaass http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/88_VantagePro2.pm sachag http://forum.fhem.de Sonstiges
|
||||
FHEM/88_WEBCOUNT.pm sachag http://forum.fhem.de Sonstiges
|
||||
FHEM/89_HEATRONIC.pm heikoranft http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/89_VCONTROL.pm adamwit http://forum.fhem.de Heizungssteuerung/Raumklima
|
||||
FHEM/90_at.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/91_eventTypes.pm rudolfkoenig http://forum.fhem.de Frontends
|
||||
FHEM/91_notify.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/91_sequence.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/91_watchdog.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/92_FileLog.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/93_DbLog.pm tobiasfaust http://forum.fhem.de Automatisierung
|
||||
FHEM/93_FHEM2FHEM.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/95_FLOORPLAN.pm ulimaass http://forum.fhem.de Frontends
|
||||
FHEM/95_Dashboard.pm svenson08 http://forum.fhem.de Frontends
|
||||
FHEM/95_PachLog.pm rudolfkoenig/orphan http://forum.fhem.de Sonstiges
|
||||
FHEM/95_holiday.pm rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
FHEM/95_remotecontrol.pm ulimaass http://forum.fhem.de Frontends
|
||||
FHEM/98_Text2Speech.pm tobiasfaust http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_apptime.pm martinp876 http://forum.fhem.de Sonstiges
|
||||
FHEM/98_ComfoAir.pm StefanStrobel http://forum.fhem.de Sonstiges
|
||||
FHEM/98_CULflash.pm rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
FHEM/98_DOIF.pm damian-s http://forum.fhem.de Automatisierung
|
||||
FHEM/98_FReplacer.pm stefanstrobel http://forum.fhem.de Sonstiges
|
||||
FHEM/98_GEOFANCY.pm loredo http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_HMinfo.pm martinp876 http://forum.fhem.de HomeMatic
|
||||
FHEM/98_Heating_Control.pm dietmar63 http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_HTTPMOD.pm stefanstrobel http://forum.fhem.de Sonstiges
|
||||
FHEM/98_IF.pm damian-s http://forum.fhem.de Automatisierung
|
||||
FHEM/98_JsonList.pm mfr69bs http://forum.fhem.de Automatisierung
|
||||
FHEM/98_JsonList2.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_PID20.pm John http://forum.fhem.de Automatisierung
|
||||
FHEM/98_RandomTimer.pm dietmar63 http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_SVG.pm rudolfkoenig http://forum.fhem.de Frontends
|
||||
FHEM/98_THRESHOLD.pm damian-s http://forum.fhem.de Automatisierung
|
||||
FHEM/98_WeekdayTimer.pm dietmar63 http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_WOL.pm dietmar63 http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_XmlList.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_autocreate.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_average.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_backup.pm rudlfkoenig http://forum.fhem.de Sonstiges
|
||||
FHEM/98_cloneDummy.pm Joachim http://forum.fhem.de Automatisierung
|
||||
FHEM/98_cmdalias.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_configdb.pm betateilchen http://forum.fhem.de Sonstiges
|
||||
FHEM/98_copy.pm justme1968 http://forum.fhem.de Sonstiges
|
||||
FHEM/98_CustomReadings.pm HCS http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_dewpoint.pm Joachim http://forum.fhem.de Automatisierung
|
||||
FHEM/98_dummy.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_fheminfo.pm mfr69bs http://forum.fhem.de Sonstiges
|
||||
FHEM/98_HourCounter.pm john http://forum.fhem.de MAX
|
||||
FHEM/98_logProxy.pm justme1968 http://forum.fhem.de Frontends
|
||||
FHEM/98_notice.pm mfr69bs http://forum.fhem.de Sonstiges
|
||||
FHEM/98_pilight.pm andreas-fey http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/98_rain.pm baumrasen http://forum.fhem.de Sonstiges
|
||||
FHEM/98_restore.pm rudolgkoenig http://forum.fhem.de Sonstiges
|
||||
FHEM/98_statistics.pm tupol http://forum.fhem.de Sonstiges (PM: http://forum.fhem.de/index.php?action=pm;sa=send;u=5432)
|
||||
FHEM/98_structure.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_telnet.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/98_update.pm rudolgkoenig http://forum.fhem.de Sonstiges
|
||||
FHEM/98_weblink.pm rudolfkoenig http://forum.fhem.de Frontends
|
||||
FHEM/99_SUNRISE_EL.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/99_Utils.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/Blocking.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/DevIo.pm rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
FHEM/Color.pm justme1968 http://forum.fhem.de Sonstiges
|
||||
FHEM/FritzBoxUtils.pm rudolfkoenig http://forum.fhem.de FRITZ!Box
|
||||
FHEM/HMConfig.pm martinp876 http://forum.fhem.de HomeMatic
|
||||
FHEM/HttpUtils.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/MaxCommon.pm mgehre http://forum.fhem.de MAX
|
||||
FHEM/ONKYOdb.pm loredo http://forum.fhem.de Multimedia
|
||||
FHEM/OWX_DS2480.pm ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/OWX_DS9097.pm ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/OWX_FRM.pm ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/OWX_SER.pm ntruchsess http://forum.fhem.de 1Wire
|
||||
FHEM/SetExtensions.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/SHC_datafields.pm rr2000 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/SHC_parser.pm rr2000 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/TcpServerUtils.pm rudolfkoenig http://forum.fhem.de Automatisierung
|
||||
FHEM/lib/Device/Firmata/* ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/lib/Device/MySensors/* ntruchsess http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/lib/Encode/* Reinerlein http://forum.fhem.de Multimedia
|
||||
FHEM/lib/MP3/* Reinerlein http://forum.fhem.de Multimedia
|
||||
FHRM/lib/Normalize Reinerlein http://forum.fhem.de Multimedia
|
||||
FHEM/lib/ProtoThreads.pm ntruchsess http://forum.fhem.de FHEM Development
|
||||
FHEM/lib/SHC_packet_layout.xml rr2000 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/lib/SWAP/* justme1968 http://forum.fhem.de Sonstige Systeme
|
||||
FHEM/lib/UPnP/* Reinerlein http://forum.fhem.de Multimedia
|
||||
FHEM/FhemUtils/* mfr69bs http://forum.fhem.de Sonstiges
|
||||
FHEM/GPUtils.pm ntruchsess http://forum.fhem.de FHEM Development
|
||||
|
||||
contrib/YAF/* danielweisensee http://forum.fhem.de Frontends
|
||||
contrib/23_WEBTHERM.pm betateilchen/sachag http://forum.fhem.de Sonstiges
|
||||
contrib/55_BBB_BMP180.pm betateilchen http://forum.fhem.de Einplatinencomputer
|
||||
contrib/71_LISTENLIVE.pm betateilchen http://forum.fhem.de Multimedia
|
||||
contrib/98_geodata.pm betateilchen http://forum.fhem.de Sonstiges
|
||||
contrib/98_openweathermap.pm betateilchen http://forum.fhem.de Unterstuetzende Dienste
|
||||
contrib/98_PID.pm betateilchen http://forum.fhem.de Automatisierung
|
||||
|
||||
www/codemirror/* betateilchen http://forum.fhem.de Frontends
|
||||
www/gplot/* rudolfkoenig http://forum.fhem.de Frontends
|
||||
www/images/* ulimaass http://forum.fhem.de Frontends
|
||||
www/pgm2/dashboard/* svenson08 http://forum.fhem.de Frontends
|
||||
www/pgm2/fhemweb_readingsHistory.js justme1968 http://forum.fhem.de Frontends
|
||||
www/pgm2/* rudolfkoenig http://forum.fhem.de Frontends
|
||||
www/jscolor/* justme1968 http://forum.fhem.de Frontends
|
||||
www/frontend/* johannnes http://forum.fhem.de Frontends
|
||||
|
||||
docs/fhem-floorplan-* ulimaass http://forum.fhem.de Sonstiges
|
||||
docs/* rudolfkoenig http://forum.fhem.de Sonstiges
|
||||
|
||||
Files that every developer should modify/extend
|
||||
MAINTAINER.txt
|
||||
CHANGES
|
||||
HISTORY
|
||||
|
Loading…
x
Reference in New Issue
Block a user