summaryrefslogtreecommitdiffstats
path: root/clerk_rating_client
blob: 96627454b368f1f33943c4191c012d2478841cc5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/perl

binmode(STDOUT, ":utf8");
use v5.10;
use warnings;
use Array::Utils qw(:all);
#use DDP;
use File::Spec;
use strict;
use utf8;
use Encode qw(decode encode);
use File::Find;
use Getopt::Std;
use Net::MPD;

my $mpd_host = "tauron";
my $mpd = Net::MPD->connect($ENV{MPD_HOST} // $mpd_host // 'localhost');
my $music_root = "/mnt/raid/Audio/Rips";

sub main {
    my %options=();
    getopts("rst", \%options);

    if ($options{r} // $options{s} // $options{t}) {
        if    (defined $options{r}) { subscribe_ratings_channel(); track_rating(); }
        elsif (defined $options{s}) { subscribe_ratings_channel(); sync_ratings(); }
        elsif (defined $options{t}) { tag_from_sticker(); }
    }   else { subscribe_ratings_channel(); track_rating(); };
}

sub subscribe_ratings_channel {
    $mpd->subscribe('rating');
}

sub track_rating {
    while(1) {
    	$mpd->idle('message');
    	my @blub = $mpd->read_messages;
        foreach (@blub) {
        	my $string = $_->{message};
        	my @array = split("\t", $string);
        	my $uri = $array[0];
        	my $mode = $array[1];
        	my $rating = $array[2];
            $uri = decode('UTF-8', $uri );
            my @files = $mpd->search('filename', $uri);
            my @song_tags = $files[0];
            my $albumartist = $song_tags[0]->{AlbumArtist};
            my $artist = $song_tags[0]->{Artist};
            my $title = $song_tags[0]->{Title};
            my $album = $song_tags[0]->{Album};
            if ($uri =~ /.*.flac$/) {
                if ($mode eq "RATING") {
                    print ":: tagging track \"${title}\" by \"${artist}\" with rating of \"${rating}\"\n";
                } elsif ($mode eq "ALBUMRATING") {
                    print ":: tagging track \"${title}\" by \"${albumartist}\" with albumrating of \"${rating}\"\n";
                }
                system('metaflac', '--remove-tag=RATING', "${music_root}/${uri}");
                system('metaflac', "--set-tag=${mode}=${rating}", "${music_root}/${uri}");
            }
            elsif ($uri =~ /.*.mp3$/) {
                if ($mode eq "RATING") {
                    print ":: tagging track \"${title}\" by \"${artist}\" with rating of \"${rating}\"\n";
                } elsif ($mode eq "ALBUMRATING") {
                    print ":: tagging track \"${title}\" by \"${albumartist}\" with albumrating of \"${rating}\"\n";
                }
                system('mid3v2', "--TXXX:${mode}:${rating}", "${music_root}/${uri}");
            }
            elsif ($uri =~ /.*.ogg$/) {
                print "!! OGG files not supported, yet\n";
            }
        }
    }
}

sub sync_ratings {
	my @sticker_uris;
	my @actual_uris;
    my @available_stickers = $mpd->sticker_find('song', 'rating', '');
    foreach my $rated_song (@available_stickers) {
    	push @sticker_uris, "$rated_song->{file}";
	}

	my @absolute;
	find({
    wanted   => sub { push @absolute, $_ if -f and -r },
    no_chdir => 1,
	}, $music_root);
	my @relative = map { File::Spec->abs2rel($_, $music_root) } @absolute;
	push @actual_uris, $_ for @relative;
	
	my @diff = array_diff(@sticker_uris, @actual_uris);
	foreach my $unrated_song (@diff) {
		if ( $unrated_song =~ /.*.flac$/) {
			my $rating = system('metaflac', '--show-tag=RATING', "${music_root}/${unrated_song}");
			print "$rating\n";
			if ($rating ne "0") {
				print "rating ${music_root}/${unrated_song} with $rating\n";
				$mpd->sticker_value("song", "$unrated_song", "rating", "$rating");
			}
		}
	}
}

sub tag_from_sticker {
    my @available_stickers = $mpd->sticker_find('song', 'rating', '');
    foreach my $rated_song (@available_stickers) {
		my $uri = $rated_song->{file};
		my $rating = $rated_song->{sticker};
        if ($uri =~ /.*.flac$/) {
            system('metaflac', '--remove-tag=RATING', "${music_root}/${uri}");
            system('metaflac', "--set-tag=RATING=$rating", "${music_root}/${uri}");
        }
        elsif ($uri =~ /.*.mp3$/) {
            system('mid3v2', "--TXXX:RATING:${rating}", "${music_root}/${uri}");
        }
        elsif ($uri =~ /.*.ogg$/) {
            print "!! OGG files not supported, yet\n";
        }
	}
}

main();