MocPList - Enfileirador de áudio e locutor em voz sintetizada
Publicado por Khayla Elias dos Santos (última atualização em 21/02/2019)
[ Hits: 3.143 ]
Homepage: https://linktr.ee/khayla.elias
Download 1549117671.mocplist-1.19.83 (versão 2)
MocPlist é um cliente enfileirador randômico de mídias de áudio para o serviço MOC Player que permite gerar "playlists" baseando-se nas Info Tags dos arquivos de mídias. Além disso, é um locutor em voz sintetizada com diversos recursos como anúncio do título da mídia em reprodução, das horas local e do estado da caixa de email. Mais informações, nas primeiras linhas comentadas do script.
Versão 2 - Enviado por Khayla Elias dos Santos em 02/02/2019
Changelog: Versão 1.19.83 do MocpList Enfileirador automático para o Moc Player.
Novidades:
- Inclusão de arquivo de cache para agilizar novas pesquisas.
- Alteração no algoritmo e na estrutura de dados para acelerar a pesquisa. Esta mudança visa a reduzir principalmente o custo da geração dos índices randômicos na medida em que estes se tornam mais raros de serem gerados.
- Maior confiabilidade no processo de enfileiramento e inclusão de um indicador de número de falhas de arquivos não enfileirados.
- Melhoria dos recursos já implementados.
Download 1549117671.mocplist-1.19.83
#!/bin/bash
# === M O C P L I S T - M o c P l a y l i s t V e r s ã o 1 . 1 9 =================================================
#
# DESCRIÇÃO:
#
# Cliente enfileirador de mídias de áudio para o serviço MOC Player e locutor em voz sintetizada com as seguintes
# características:
#
# - Indentifica informações (tags) da mídia em reprodução no Moc Player.
# - Permite o uso de palavras chaves (padrões de busca) para pesquisa e seleção de mídias que casem com
# as expressões fornecidas pelo usuário.
# - Seleciona as mídias aleatoriamente e as enfileira criando um novo playlist ou ao já existente.
# - Utilizá-se das tags contidas nas mídias e/ou do nome do arquivo destas no processo de enfileiramento.
# - Auto-enfileiramento de mídias quando o tocador está ocioso.
# - Locutor(a) em voz sintetizada para anunciar:
#
# + Título da mídia
# + As horas da máquina local
# + Alguma mensagem de difusão fornecida pelo usuário (broadcast)
# + O número de mensagens não lidas da caixa de email (via fetchmail)
# + Sobre o programa e do tocador
#
#
# NOTAS:
#
# 1) A pesquisa deve ser feita preenchendo-se alguns dos seguintes campos na janela de diálogo:
#
# + Artista/Banda
# + Título
# + Álbum
# + Ano
# + Gênero
# + Outros
#
# 2) No campo 'Outros' pode-se fornecer uma expressão livre que, por sua vez, pode casar com uma tag específica
# (fornecendo-se o padrão adequado da mesma) ou com quaisquer outras pré-filtradas ou, ainda, com o nome do
# arquivo.
#
# 3) A INTERSEÇÃO de casamentos de padrões ocorrerá se houver sucesso no casamento de cada um dos campos
# acima. Note que, com essa regra, cada mídia selecionada CASA COM TODOS OS CAMPOS, inclusive os vazios (veja
# exemplos 1 à 4 abaixo).
#
# 4) A UNIÃO de casamentos de padrões pode ser obtida utilizando-se "Expressões Regulares" (REGEX) separando
# os padrões com o operador OU (o caractere "|"). Note que, com essa regra, cada mídia selecionada CASA COM
# ALGUM DOS PADRÔES fornecidos num determinado campo (exemplos 3 e 4 abaixo).
#
# 5) O pŕe-filtro de busca contém as seguintes tags:
#
# Id3v1: Artist, Year, Genre, Title, Album, Comment.
# Id3v2: TP1, TALB, TYE, TCON, TCOM, TIT, TPE, TOLY, TOPE, TEXT, COMM.
#
# 6) A cada mídia selecionada durante o processo de enfileiramento, um segmento de mídias vizinhas também é
# pesquisado para enfileirar um conjunto de mídias que também casam com as palavras chaves fornecidas pelo
# usuário. A relação de vizinhança se dá na proximidade da árvore do subdiretório que elas pertencem.
#
#
#
# PRÉ-REQUISITOS:
#
# Os pacotes dos seguintes programas devem estar instalados para o funcionamento adequado deste script:
#
# - MOC: Tocador de áudio em console (Music On Console Player).
# - ID3V2: Editor de tags id3v2 em linha de comando.
# - DIALOG: Exibe caixas de diálogo amigáveis ao usuário em scripts shell.
# - ESPEAK: Locutor multilíngue em voz sintetizada.
# - FETCHMAIL: Fetch mail from a POP, IMAP, ETRN, or ODMR-capable server (opcional).
# - FORTUNE: Print a random, hopefully interesting, adage (opcional).
#
#
#
# OPÇÕES:
#
# --update, -u: Atualiza a lista de mídias. Sempre que houver alteração no diretório padrão de músicas é
# necessário iniciar a execução da seguinte forma:
#
# mocplist --update
#
#
# --help, -h: Ajuda básica para executar este script.
#
#
# --about: Exibe estas informações sobre e de ajuda.
#
#
# --reset-theme: restaura o arquivo de configurações do tema do dialog na home do usuário.
#
#
#
# TECLAS DE CONTROLE DA TELA PRINCIPAL:
#
# a: Ativa/desativa o enfileiramento AUTOMÁTICO quando o tocador estiver ocioso.
# b: Toca a mídia ANTERIOR no Moc Player.
# i: Exibe INFO TAGS da mídia em reprodução e que podem ser usadas para pesquisa.
# h: Ajuda.
# l: ADICIONA novas mídias ao playlist atual sem limpá-lo.
# m: Exibe informações da caixa de EMAIL (INBOX).
# n: Toca a PRÓXIMA mídia no Moc Player.
# p: PAUSA/DESPAUSA a mídia em reprodução.
# q: ENCERRA o programa.
# r: Exibe RELATÓRIO da lista de mídias contidas no diretório padrão de músicas.
# s: Permite alterar as CONFIGURAÇÕES básicas.
# L: LIMPA o playlist atual e ADICIONA novas mídias.
# ,: REDUZ o volume 5%.
# .: AUMENTA o volume 5%.
#
#
#
# EXEMPLOS DE USO DE PADRÕES DE BUSCA:
#
#
# 1) Para pesquisar e enfileirar músicas do álbum Falso Brilhante da cantora Elis Regina, basta preencher
# os campos abaixo e deixar os demais vazios:
#
# Artista/banda: Elis Regina
# Álbum: Falso Brilhante
#
# 2) Para obter uma busca mais refinada, pode-se utilizar das "Expressões Regulares". Por exemplo, se quiser buscar
# mídias do gênero Progressive Rock entre os anos de 2010 à 2018, pode-se fornecer as expressões abaixo:
#
# Ano: 201[0-8]
# Gênero: progressive rock
#
# 3) Buscando e enfileirando músicas da banda Sepultura OU Slayer OU Iron Maiden dos anos de 1983 à 1985:
#
# Artista/banda: sepultura|slayer|iron maiden
# Ano: 1983|1984|1985
#
# 4) Para um casamento independente das tags, pode-se usar exclusivamente o campo 'Outros' da seguinte forma:
#
# Outros: techno|Kraftwerk|19[7-9][0-9]
#
# Neste caso, serão enfileirados áudios que contém alguma tag com a expressão "techno" OU "Krafwerk" OU números
# entre 1970 à 1999. Além das tags, vale ressaltar que o nome do arquivo também será usado para o casamento
# de padrões no uso do campo 'Outros'.
#
#
#
# COMENTÁRIOS:
#
# - A busca será mais precisa quanto melhor se utilizar das "Expressões Regulares" para casamento de
# padrões de busca.
#
#
#
# POR: Khayla Elias dos Santos (Alexandre)
# Email: avezdopinguim@gmail.com
# DATA: Julho 2009
# ATUALIZADO EM: Fevereiro 2018
# PLATAFORMA DE TESTE: Linux, Ubuntu 14.04
#
# "Ela virá, a revolução conquistará a todos o direito não somente ao pão, mas, também, a poesia." (Leon Trotsky)
#
# ============================================================================================================================
# ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#
# ESQUEMA DE PESQUISA E PARTICIONAMENTO DA LISTA DE MÍDIAS:
#
# VETOR COM ÍNDICES DA LISTA DE MÍDIAS:
#
# 1 2 3 n
# [...+......<...+.+..+....++.>..+.....+...+..]
# ^ ^
# |....segmento....|
# ponteiro ponteiro
# inicial final
# (randômico)
#
#
#
# PARTICIONAMENTO RANDOMICO DO VETOR A CADA ITERAÇÃO:
#
#
# NÃO PARTICIONADO PÓS PARTICIONADO
# (com índices sujeito a pesquisa) (com índices pesquisados)
#
# 0 [..............<???>....] []
# 1 [...<???>..........] [(...)]
# 2 [.....<???>....] [(...)(...)]
# 3 [...<???>..] [(...)(...)(...)]
# . . .
# . . .
# . . .
# 20 [] [(...)(...)(...) ... (...)]
# P0 P1 P2 P20
#
#
#
# LEGENDA:
#
# (.) Índice de uma mídia qualquer da lista
# (+) Índice de mídia que casam com os padrões de busca
# (1 - n) Índices de mídias vizinhas que serão enfileirados
# (?) Indices de mídias sujeitas a serem pesquisadas
# (< >) Índices limitadores do segmento (vizinhança) a ser pesquisado
# (P0 - P20) Partições pesquisadas
#
# ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
# === P A R Á M E T R O S D E E N T R A D A =============================================================================
UPDATE="$1" # 1) --update ou --report ou --reset-theme ou --help ou --about
shopt -s -o nounset # disallow undefined variables
# === D E C L A R A Ç Ã O D E C O N S T A N T ES =========================================================================
# NOME DO PROCESSO:
declare -r SCRIPT=`basename $0`
declare -r PROG=`echo $SCRIPT | sed 's/\.sh$//'`
declare -r LOCATE="`ps aux|grep ".*bash.*${SCRIPT}"|grep -v "grep"|head -1 |sed "s;^.*/bin/bash ;;"|sed "s; -.*$;;"`" # local
# ARQUIVOS E DIRETÓRIOS:
declare -r BASE=$HOME/.mocplist # diretório de arquivos do script
declare -r MUSICA=$HOME/Música # diretório raiz de áudios
declare -r TEMP=/var/tmp/$SCRIPT # diretório de arquivos temporários
declare -r LOG=$BASE/$SCRIPT.log # arquivo de log do script
declare -r FICHEIROS=$BASE/media-list # lista de todas mídias para pesquisas
declare -r INDEX=$TEMP/indices # índices de mídias a serem pesquisadas
declare -r CHECKEDS=$TEMP/checkeds # índices de mídias pesquisadas (partições)
declare -r WORDS_EN=$BASE/words-en # lista de expressões para eleger idioma inglês
declare -r WORDS_ES=$BASE/words-es # lista de expressões para eleger idioma espanhol
declare -r CONF=$BASE/mocplist.conf # arquivo de configuração
declare -r GENRE_LIST=$BASE/genre.txt # lista de gêneros musicais
declare -r REPORT=$BASE/report-medias.txt # Relatório de mídias contidas em MUSICA
declare -r DATA_MEDIA=$TEMP/data-media # dados da mídia em reprodução
declare -r DATA_ID3=$TEMP/dataID3 # tags id3 da mídia em reprodução
declare -r TOT_FILA=$TEMP/tt-fila # número de enfileirados
declare -r PERC_OUT=$TEMP/perc-out # percentual geral de arquivos varridos
declare -r TT_VARRIDOS=$TEMP/tt-varridos # total acumulado de ficheiros varridos
declare -r SINAL=$TEMP/sinal # flag de interrupção de enfileiramento
declare -r CHMAIL=$BASE/mail.$USER # arquivo de saída do fetchmail
# === A R Q U I V O S E C O N S T A N T E S R E L A T I V O S A O P R O C E S S O ==================================
declare -r VERSAO="Version 1.19"
declare -r TMP_PID=$TEMP/$SCRIPT.pid # pid deste script
declare -r SUB_PID=$TEMP/${SCRIPT}.sub.pid # pid da rotina de enfileiramento em segundo plano
declare -r TMP_LOG=$TEMP/${SCRIPT}_$$.log # log temporário do script em execução
declare -r TMP_TRUNC=$TEMP/${SCRIPT}_$$.trunc # log temporário auxilar
declare -ir MAX_RETIDO=5000 # tamanho máximo do arquivo de log
# === C O N S T A N T E S G E R A I S ======================================================================================
declare -ri PROB=50 # (%) # probabilidade de difusão das horas do host
declare -ri INTERVAL=12 # intervalo de checagem de email (minutos modular)
declare -r UPDATE=${UPDATE:=null} # ativa atualização da lista de 'media-list'
declare -r FRASE_EN="Music On Console Player: " # pronúncia em inglês
declare -r FRASE_PT="Míusic On Console Player: " # pronúncia em português
declare -r FRASE_OP="M.O.C Playlist, enfileiramento de áudio configurável." # frase default
declare -a DICA=("<artist>" "<title>" "<album>" "<year>" "<genre>" "<others>")
# === V A R I Á V E I S I N T E I R A S ====================================================================================
declare -i PID_SPK=99999 # pid do locutor em segundo plano
declare -i MAX_FILA=0 # número de mídias a enfileirar
declare -i VIZINHOS=0 # número de mídias vizinhas a enfileirar
declare -i SECAO=0 # tamanho a ser varrido do seguimento da lista
declare -i REFRESH=0 # set de retorno de atualização da tela principal
declare -i TT_FICHEIROS=0 # Total de mídias na lista de mídias
declare -i BEFORE_MINUTE=0 # minuto obtido na checagem de email
declare -i AFTER_MINUTE=-1 # minuto passado pos checagem de email
declare -i TOT_MAIL=0 # total de mensagens na caixa de entrada
declare -i NEW_MAIL=0 # ńumero de mensagens não lidas
# === V A R I Á V E I S L I T E R A I S ====================================================================================
# FILTRO para pesquisa baseado na saída do programa id3v2:
declare -r FILTRO="id3v|ID3|^Title|^Album|^Comment|\
^TP1|^TALB|^TYE|^TCON|^TCOM|^TIT|^TPE|^TOLY|^TOPE|^TEXT|^COMM"
declare -a PADRAO=("" "" "" "" "" "") # expressões regulares utilizadas nas buscas id3v2
TALK= # ativa/desativa locutor em voz sintetizada
DIFUSAO= # ativa/desativa anúncio de mensagens
VOZ="off" # idioma default do locutor
CHK_MAIL= # ativa checagem de email
MENSAGEM= # mensagem de difusão (broadcast)
COMANDO= # comando gerador de texto
TECLA= # entrada de comandos (teclas de controle da tela principal)
ARTIST= # artista da mídia em reprodução
SONG_TITLE= # titulo da mídia em reprodução
TITLE= # título unificado da mídia
GENRE= # género da mídia em reprodução
YEAR= # ano da mídia em reprodução
ALBUM= # álbum da mídia em reprodução
TRACK= # track da mídia em reprodução
TRACK0= # track passado
TRACK1= # track checked
MODO= # estado do tocador (barra de título)
GMAIL= # endereço de email obtido pelo fetchmail
FRAME_ART= # dicas do dialog
FRAME_TIT= # //
FRAME_ALB= # //
FRAME_YER= # //
FRAME_CON= # //
FRAME_ALL= # //
AUTO="no-auto" # ativa/desativa enfileramento automático
TEXTO=" MocpList - $VERSAO\n\nBy: Khayla Elias dos Santos \
\nEmail: avezdopinguim@gmail.com\n\n \
<3\"(: Uma dedicação do Pinguim à amada Sabiá" # créditos do desenvolverdor
SELECAO= # auxiliar para formatar padrões de busca
# === F U N Ç Õ E S ==========================================================================================================
function help_fn(){
if [ "$#" != 0 ]; then
if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
printf "MocpList - $VERSAO\n\n"
printf "This is searcher in data id3v2 tag and enqueuer list to moc player server.\n\n"
printf "Use:\t$SCRIPT [ --about | <--update> | <-u> | <--help> | <-h> ]\n\n"
exit
else if [ "$1" != "--update" ] && [ "$1" != "-u" ] && [ $1 != "--about" ] && [ "$1" != "--reset-theme" ]; then
printf "Erro: opção inválida.\nUse '$SCRIPT --help' para ajuda.\n"
exit 1
else if [ "$1" = "--about" ]; then
head -200 $LOCATE|sed -e "s;^#;;" -e "/^\!/d"|less
exit
fi # about
fi # opções
fi # help and check parameters
fi # Help and check parameters
} # help_fn - help and check parameters
function fn_fim_script(){
tail -$MAX_RETIDO $LOG > $TMP_TRUNC
echo "$PROG: pid $$", início de linhas ===== >> $TMP_TRUNC
cat $TMP_LOG >> $TMP_TRUNC
mv $TMP_TRUNC $LOG
# extermina processo em segundo plano
[ "`cat $SUB_PID`" -gt 0 ] && kill -9 `cat $SUB_PID`
# Remoção de arquivos temporários:
cd $TEMP; rm -f ./*
tput cnorm; reset
} # fn_fim_script - tratamento de encerramento
function fn_trap(){
#fn_erro N "$PROG: Interrupção forçada"
fn_fim_script &>/dev/null
exit 2
} # fn_trap - tratamento de interrupções
function check_sanity(){
if ! ( type -a mocp 2>/dev/null|grep -q "/mocp" ); then
printf "\r`basename $0`:$LINENO: the command 'mocp' is not available\naborting\n" >&2
exit 1
fi # check mocp
if ! ( type -a dialog 2>/dev/null|grep -q "/dialog" ); then
printf "\r`basename $0`:$LINENO: the command 'dialog' is not available\naborting\n" >&2
exit 1
fi # check dialog
if ! ( type -a id3v2 2>/dev/null|grep -q "/id3v2" ); then
printf "\r`basename $0`:$LINENO: the command 'id3v2' is not available\naborting\n" >&2
exit 1
fi # check id3v2
if ! ( type -a espeak 2>/dev/null|grep -q "/espeak" ); then
printf "\r`basename $0`:$LINENO: the command 'espeak' is not available\naborting\n" >&2
exit 1
fi # check espeak
[ -d "$TEMP" ] || mkdir $TEMP
if [ -s "$TMP_PID" ]; then
PID=`cat $TMP_PID`
if ps -p $PID 2> /dev/null >&2; then
echo "$PROG: Uma instância deste programa já está em execução. PID=$PID." >&2
exit 3
fi
else echo $$ > $TMP_PID
rm -f $TMP_LOG &>/dev/null
fi # garante a execucão de uma única instância
} # check_sanity - verificações pré-eliminares
function reset_theme(){
[ "$UPDATE" = "--reset-theme" ] && dialog --create-rc $HOME/.dialogrc
} # reset_theme - recria arquivo do tema
function check_files(){
# cria diretório do aplicativo na home do usuário
[ -d "$BASE" ] || mkdir $BASE
# padrões básicos para eleger idioma inglês (inclui o subdiretório Internacionais)
[ ! -f "$WORDS_EN" ] && \
printf ".*/M[úu]sica/Internacionais/\nabout[,.!?]*\n^all,* | all,* | all[.!?]*$\n^are,* | are,* | are[.!?]*$\neyes,* | eyes,* | eyes[.!?]*\n^in,* | in,* | in[.!?]*$\n^it,* | it,* | it[.!?]*$\n^how,* | how,* | how[.!?]*$\nlike[,.!?]*\n^m[ae]n,* | m[ae]n,* | m[ae]n[.!?]*$\n^of,* | of,* | of[.!?]*$\n^off,* | off,* | off[.!?]*$\n^on,* | on,* | on[.!?]*$\n^one,* | one,* | one[.!?]*$\n^she,* | she,* | she[.!?]*$\n^the,* | the,* | the[.!?]*$\nthey[,.!?]*\n^we,* | we,* | we[.!?]*$\nwhen,* | when,* |when[.!?]*\nwom[ae]n[,.!?]*\nwitho*[,.!?]*\nyear,* | year,* |year[.!?]*\nyou,* | you,* | you[.!?]*\n^up,* | up,* | up[.!?]*$\n" > $WORDS_EN
# padrões básicos para eleger idioma espanhol (inclui o subdiretório Latinas)
[ ! -f "$WORDS_ES" ] && \
printf ".*/M[úu]sica/Latinas/\n.*ción[,.!?]*\ncoraz[óo]n[,.!?]*\n^cuanto,* | cuanto,* | cuanto[.!?]*$\n^el,* | el,* | el[.!?]*$\nestoy[,.!?]*\n^gustas*,* | gustas*,* | gustas*[.!?]*$\nhasta,* | hasta[.!?]*\nhola,* | hola,* | hola[.!?]*$\nhombres*[,.!?]*\n^hoy,* | hoy,* | hoy[.!?]*$\ninmortal[,.!?]*\nlibertad[,.!?]*\nllorar[,.!?]*\nmío,* | mío[.!?]*\nmujer[,.!?]*\nnecesito[,.!?]*\nquier.,* | quier.[.!?]*\nsoledad[,.!?]*\ntengo,* | tengo[.!?]*\ntiempo[,.!?]*\n^un,* | un,* | un[.!?]*$\n^un[ao],* | un[ao],* | un[ao][.!?]*$\nusted[,.!?]*\nvivir[,.!?]*\n" > $WORDS_ES
[ ! -f "$CONF" ] &&(
printf "# MocpList - Configurações gerais\n\n" > $CONF
printf "# Ativa/desativa locutor em voz sintetizada\n" >>$CONF
printf "TALKER = on\n\n" >>$CONF
printf "# Ativa/desativa difusão de mensagens\n" >>$CONF
printf "BROADCAST = on\n\n" >>$CONF
printf "# Tamanho máximo da lista de enfileiramento\n" >>$CONF
printf "TAM_FILA = 12\n\n" >>$CONF
printf "# Número de mídias vizinhas relação ao subdiretório\n" >>$CONF
printf "NEIGHBOR = 4\n\n" >>$CONF
printf "# Tamanho de cada segmento (vizinhança) pesquisado\n" >>$CONF
printf "NEIGHBORHOOD = 60\n\n" >>$CONF
printf "# Ativa/desativa checagem da caixa de email.\n" >>$CONF
printf "# É necessário que o Fetchmail esteja configurado.\n" >>$CONF
printf "MAIL = off\n\n" >>$CONF
printf "# Comando gerador de texto para difusão.\n" >>$CONF
printf "COMMAND = fortune\n\n" >>$CONF
printf "# Mensagem principal de difusão\n" >>$CONF
printf "MESSAGE = \"Ubuntu, Linux para seres humanos.\"\n" >>$CONF
) # cria arquivo de configuração
# lista de gêneros musicais
[ -f $GENRE_LIST ] || id3v2 -L >$GENRE_LIST
# variáveis arquivadas
echo 0 > $TOT_FILA
echo 0 > $PERC_OUT
echo -1 > $SUB_PID
} # check_files - verifica e (re)cria arquivo de configuração
function set_variables(){
local VALOR=
VALOR="`grep "^[ ]*TALKER[ ]*=" $CONF| sed -r 's/^[ ]*TALKER[ ]*=[ ]*([ONFonf]{2,3})[ ]*$/\1/'`"
case "$VALOR" in
on|ON)
TALK="on"
VOZ="on";;
off|OFF)
TALK="off"
VOZ="off";;
*)
TALK="on";;
esac # ativa/desativa LOCUTOR
VALOR="`grep "^[ ]*BROADCAST[ ]*=" $CONF| sed -r 's/^[ ]*BROADCAST[ ]*=[ ]*([ONFonf]{2,3})[ ]*$/\1/'`"
case "$VALOR" in
on|ON)
DIFUSAO="on";;
off|OFF)
DIFUSAO="off";;
*)
DIFUSAO="on";;
esac # ativa/desativa anúncio de MENSAGENS
VALOR="`grep "^[ ]*MAIL[ ]*=" $CONF| sed -r 's/^[ ]*MAIL[ ]*=[ ]*([onf]{2,3})[ ]*$/\1/'`"
case "$VALOR" in
on|ON)
CHK_MAIL="on";;
off|OFF)
CHK_MAIL="off";;
*)
CHK_MAIL="off";;
esac # ativa/desativa checagem de EMAIL
grep -q "^[ ]*TAM_FILA[ ]*=[ ]*[0-9]\{1,4\}[ ]*$" $CONF
if [ "$?" -eq 0 ]; then
MAX_FILA="`grep "^TAM_FILA[ ]*=[ ]*[0-9]\{1,4\}[ ]*$" $CONF| \
sed -r 's/^TAM_FILA.*=[ ]*([0-9]{1,4})[ ]*$/\1/; s/^00*//'`"
[ "${MAX_FILA:=0}" -eq 0 ] && MAX_FILA=12
else MAX_FILA=12
fi # determina Tamanho MÁXIMO do enfileiramento
grep -q "^[ ]*NEIGHBOR[ ]*=[ ]*[0-9]\{1,2\}[ ]*$" $CONF
if [ "$?" -eq 0 ]; then
VIZINHOS="`grep "^[ ]*NEIGHBOR[ ]*=[ ]*[0-9]\{1,2\}[ ]*$" $CONF| \
sed -r 's/^[ ]*NEIGHBOR[ ]*=[ ]*([0-9]{1,2})[ ]*$/\1/; s/^00*//'`"
[ "${VIZINHOS:=0}" -eq 0 ] && VIZINHOS=3
else VIZINHOS=3
fi # determina o número de VIZINHOS a enfileirar ao varrer o segmento
grep -q "^[ ]*NEIGHBORHOOD[ ]*=[ ]*[0-9]\{1,3\}[ ]*$" $CONF
if [ "$?" -eq 0 ]; then
SECAO="`grep "^[ ]*NEIGHBORHOOD[ ]*=[ ]*[0-9]\{1,3\}[ ]*$" $CONF| \
sed -r 's/^[ ]*NEIGHBORHOOD[ ]*=[ ]*([0-9]{1,3})[ ]*$/\1/; s/^00*//'`"
[ "${SECAO:=0}" -lt "$VIZINHOS" ] && SECAO=$VIZINHOS
else SECAO=50
fi # determinha tamanho de cada SEGMENTO a ser varrido
grep -q "^[ ]*MESSAGE[ ]*=" $CONF
if [ "$?" -eq 0 ]; then
MENSAGEM="`grep "^[ ]*MESSAGE[ ]*=" $CONF|sed "s/^[ ]*MESSAGE[ ]*=[ ]*//"|sed -r 's;"(.*)";\1;'`"
MENSAGEM=${MENSAGEM:=${FRASE_OP}}
fi # mensagem de DIFUSÃO
grep -q "^[ ]*COMMAND[ ]*=" $CONF
if [ "$?" -eq 0 ]; then
COMANDO="`grep "^[ ]*COMMAND[ ]*=" $CONF|sed "s/^[ ]*COMMAND[ ]*=[ ]*//"|sed -r 's;"(.*)";\1;'`"
else COMANDO=
fi # COMANDO para gerador de texto de DIFUSÃO
} # set_variables - configuração dos principais parâmetros
function report(){
local -i SUB_TOTAL=0
local -i TOTAL=0
printf "RELATÓRIO DE MÍDIAS - $HOSTNAME - `date`\n\n" > $REPORT
printf "Local:\t$MUSICA\n\n" >> $REPORT
TOTAL="`find -L $MUSICA/ -iname "*.mp3"| wc -l`"
printf "Mídias *.mp3:\t$TOTAL\n" >> $REPORT
let SUB_TOTAL=SUB_TOTAL+TOTAL
TOTAL="`find -L $MUSICA/ -iname "*.ogg"| wc -l`"
printf "Mídias *.ogg:\t$TOTAL\n" >> $REPORT
let SUB_TOTAL=SUB_TOTAL+TOTAL
TOTAL="`find -L $MUSICA/ -iname "*.wmv"| wc -l`"
printf "Mídias *.wmv:\t$TOTAL\n" >> $REPORT
let SUB_TOTAL=SUB_TOTAL+TOTAL
TOTAL="`find -L $MUSICA/ -iname "*.wav"| wc -l`"
printf "Mídias *.wav:\t$TOTAL\n" >> $REPORT
let SUB_TOTAL=SUB_TOTAL+TOTAL
TOTAL="`find -L $MUSICA/ -iname "*.wma"| wc -l`"
printf "Mídias *.wma:\t$TOTAL\n" >> $REPORT
let SUB_TOTAL=SUB_TOTAL+TOTAL
TOTAL="`find -L $MUSICA/ -iname "*.aac"| wc -l`"
printf "Mídias *.aac:\t$TOTAL\n" >> $REPORT
let SUB_TOTAL=SUB_TOTAL+TOTAL
TOTAL="`find -L $MUSICA/ -iname "*.flac"| wc -l`"
printf "Mídias *.flac:\t$TOTAL\n" >> $REPORT
let SUB_TOTAL=SUB_TOTAL+TOTAL
TOTAL="`find -L $MUSICA/ -iname "*.avi"| wc -l`"
printf "Mídias *.avi:\t$TOTAL\n" >> $REPORT
let SUB_TOTAL=SUB_TOTAL+TOTAL
TOTAL="`find -L $MUSICA/ -iname "*.mp4"| wc -l`"
printf "Mídias *.mp4:\t$TOTAL\n" >> $REPORT
let SUB_TOTAL=SUB_TOTAL+TOTAL
TOTAL="`find -L $MUSICA/ -iname "*.flv"| wc -l`"
printf "Mídias *.flv:\t$TOTAL\n" >> $REPORT
let SUB_TOTAL=SUB_TOTAL+TOTAL
TOTAL="`find -L $MUSICA/ -iname "*.ac3"| wc -l`"
printf "Mídias *.ac3:\t$TOTAL\n" >> $REPORT
let SUB_TOTAL=SUB_TOTAL+TOTAL
TOTAL="`find -L $MUSICA/ -iname "*.3gp"| wc -l`"
printf "Mídias *.3gp:\t$TOTAL\n" >> $REPORT
let SUB_TOTAL=SUB_TOTAL+TOTAL
printf "Total:\t\t$SUB_TOTAL\n" >> $REPORT
} # report - produz relatório de mídias contidas no diretório $MUSICA
function atualiza(){
if [ ! -f "$FICHEIROS" ] || [ "$UPDATE" = "--update" ] || [ "$UPDATE" = "-u" ]; then
local -r FRASE_CRED="`mocp -V |grep -E "This|Version|Run|Author|Home|Copy|License"`"
#=== C R E D I T O S =============================================
if [ "$TALK" = "on" ]; then
espeak -p0 -ven+f4 "About Player:" &>/dev/null
echo "$FRASE_CRED"|espeak -p0 -ven+us+m7 &>/dev/null&
local -i PID_SPK=$!
fi # =============================================================
dialog --stdout --no-collapse --cr-wrap \
--backtitle "Extração de ficheiros de áudios" \
--title "MocpList - Aguarde! Extraindo arquivos de mídias..." \
--infobox "About Player:\n\n`echo "$FRASE_CRED"| sed 's/ //'`\n" 0 0
# Extração de ficheiros ==========================================
find -L $MUSICA/ -iname "*.mp3"| sed "s;.*${MUSICA}/;;" > $FICHEIROS
find -L $MUSICA/ -iname "*.ogg"| sed "s;.*${MUSICA}/;;" >> $FICHEIROS
find -L $MUSICA/ -iname "*.wav"| sed "s;.*${MUSICA}/;;" >> $FICHEIROS
find -L $MUSICA/ -iname "*.wma"| sed "s;.*${MUSICA}/;;" >> $FICHEIROS
find -L $MUSICA/ -iname "*.wmv"| sed "s;.*${MUSICA}/;;" >> $FICHEIROS
find -L $MUSICA/ -iname "*.aac"| sed "s;.*${MUSICA}/;;" >> $FICHEIROS
find -L $MUSICA/ -iname "*.ac3"| sed "s;.*${MUSICA}/;;" >> $FICHEIROS
find -L $MUSICA/ -iname "*.mp4"| sed "s;.*${MUSICA}/;;" >> $FICHEIROS
find -L $MUSICA/ -iname "*.avi"| sed "s;.*${MUSICA}/;;" >> $FICHEIROS
find -L $MUSICA/ -iname "*.flv"| sed "s;.*${MUSICA}/;;" >> $FICHEIROS
find -L $MUSICA/ -iname "*.3gp"| sed "s;.*${MUSICA}/;;" >> $FICHEIROS
find -L $MUSICA/ -iname "*.flac"| sed "s;.*${MUSICA}/;;" >> $FICHEIROS
# ================================================================
report& 2>>$TMP_LOG
sort $FICHEIROS > $FICHEIROS.tmp
mv $FICHEIROS.tmp $FICHEIROS
fi # cria ou atualiza a lista de mídias
# aguarda finalização do locutor:
while [ "`ps au| grep $PID_SPK|wc -l`" -gt 1 ]; do sleep 1 ;done
} # atualiza - Atualiza a lista de arquivos de mídias
function check_mail(){
dialog --stdout --title "MocpList - Fetchmail" \
--infobox "Checando ${GMAIL:=email}..." \
3 60
fetchmail -c > $CHMAIL.1 2>/dev/null
local -i RETORNO=$?
grep -q "INBOX" $CHMAIL.1 2>/dev/null
if [ "$?" = 0 ]; then
cp $CHMAIL.1 $CHMAIL
rm $CHMAIL.1
fi # atualiza arquivo
# obtém estado da inbox
GMAIL="`cut -d' ' -f6 $CHMAIL`"
TOT_MAIL="`cut -d' ' -f1 $CHMAIL`"
local -i VISTO="`cut -d' ' -f3 $CHMAIL|sed 's/[()]//g'`"
NEW_MAIL=$((${TOT_MAIL:=0} - ${VISTO:=-1}))
if [ "$RETORNO" -eq 11 ]; then
let NEW_MAIL=-1*$NEW_MAIL
fi
if [ "$NEW_MAIL" -gt 0 ] && [ "` mocp -Q "%state"`" != "PLAY" ] && [ "$TALK" = "on" ]; then
local S= # plural
[ "$NEW_MAIL" -gt 1 ] && S="s"
espeak -vpt+f4 "Você tem $NEW_MAIL email$S não lido$S." &>/dev/null
fi # anuncia número de emails não lidos
return $RETORNO
} # check_mail - faz checagem de email pelo fetchmail, retorna retorno do fetchmail.
function info_mail(){
local TEXT=$(printf "Checked at `ls -l $CHMAIL|sed 's/ */ /g'|cut -d' ' -f 6-8|sed -r 's/ [0-9][0-9]:/,&/'`" &2>/dev/null)
dialog --stdout --title "MocpList - Fetchmail" \
--backtitle "Informações da caixa de email ($GMAIL)" \
--msgbox "INBOX ($GMAIL): ${NEW_MAIL/-/!}/$TOT_MAIL\n$TEXT" \
6 60
} # info_mail - exibe informações da caixa de entrada.
function restart_player(){
dialog --stdout --sleep 5 \
--backtitle "Reiniciando serviço..." \
--title "Reiniciando o serviço Moc Player..." \
--infobox "$(printf "`mocp -S`")" 0 0
} # restart_player - reinicia serviço moc player
function setup(){
local -i RETORNO=3 # retorno do dialog
local -i LINHAS=0 # número de entradas
local VALUES= # entradas do dialog
# === Alteração do Arquivo de Configuração - Entradas ==================================================
while [ "$RETORNO" -eq 3 ]; do
VALUES=$(dialog --stdout --ok-label "Ok" \
--extra-button --extra-label "File Setup" \
--backtitle "Configurações - Alteração de parâmetros" \
--title "MocpList - Configurações" \
--form "Modifique os campos abaixos conforme a sua escolha:" \
0 0 0 \
"Quantidade de mídias (1-9999):" 1 1 "$MAX_FILA" 1 37 45 4 \
"Mídias com proximidades (1-99):" 2 1 "$VIZINHOS" 2 37 45 2 \
"Tamanho de cada seção (1-99):" 3 1 "$SECAO" 3 37 45 2 \
"Locutor (on/off):" 4 1 "$TALK" 4 37 45 3 \
"Difusão (on/off):" 5 1 "$DIFUSAO" 5 37 45 3 \
"Checagem de email (on/off):" 6 1 "$CHK_MAIL" 6 37 45 3 \
"Comando gerador de texto (difusão):" 7 1 "$COMANDO" 7 37 45 60 \
"Mensagem principal de difusão:" 8 1 "$MENSAGEM" 8 37 45 60)
RETORNO="$?"
if [ "$RETORNO" = 3 ]; then
dialog --stdout \
--title "Configurações ($CONF)" \
--backtitle "Arquivo de configurações" \
--textbox $CONF \
0 0
VALUES=
fi # exibe arquivo de configuração
LINHAS="`printf "$VALUES\n"|wc -l`"
[ -z "$VALUES" ] && LINHAS=0
done # alteração do arquivo de configuração - entradas =================================================
# === Filtragem e Armazenamento Dos Valores ============================================================
if [ "$LINHAS" -gt 0 ]; then
local -a LABELS=("TAM_FILA" "NEIGHBOR" "NEIGHBORHOOD" "TALKER" "BROADCAST" "MAIL" "COMMAND" "MESSAGE")
local -a VALORES=("$MAX_FILA" "$VIZINHOS" "$SECAO" "$TALK" "$DIFUSAO" "$CHK_MAIL" "$COMANDO" "$MENSAGEM")
local -i TAM=$(cat $CONF|wc -l) # número de linhas do arquivo de configuração
local -i NUMBER_LINE=0 # posição da linha no arquivo
local SELECT="`printf "$VALUES\n"|head -1|grep "^[0-9]*$"|sed 's/^00*//'`" # entrada selecionada
if [ "${SELECT:=0}" -gt 0 ]; then
MAX_FILA=$SELECT
VALORES[0]=$SELECT
fi # set MAX_FILA
if [ "$LINHAS" -ge 2 ]; then
SELECT="`printf "$VALUES\n"|head -2|tail -1|grep "^[0-9]*$"|sed 's/^00*//'`"
if [ "${SELECT:=0}" -gt 0 ]; then
VIZINHOS=$SELECT
VALORES[1]=$SELECT
fi
fi # set VIZINHOS
if [ "$LINHAS" -ge 3 ]; then
SELECT="`printf "$VALUES\n"|head -3|tail -1|grep "^[0-9]*$"|sed 's/^00*//'`"
if [ "${SELECT:=0}" -gt 0 ]; then
[ "$SELECT" -lt "$VIZINHOS" ] && SELECT=$VIZINHOS
SECAO=$SELECT
VALORES[2]=$SELECT
fi
fi # set SECAO
if [ "$LINHAS" -ge 4 ]; then
SELECT="`printf "$VALUES\n"|head -4|tail -1`"
case "$SELECT" in
on|ON)
TALK="on"; VOZ="on"
VALORES[3]="on";;
off|OFF)
TALK="off"; VOZ="off"
VALORES[3]="off";;
esac
fi # set TALK on/off
if [ "$LINHAS" -ge 5 ]; then
SELECT="`printf "$VALUES\n"|head -5|tail -1`"
case "$SELECT" in
on|ON)
DIFUSAO="on"
VALORES[4]="on";;
off|OFF)
DIFUSAO="off"
VALORES[4]="off";;
esac
fi # set DIFUSAO on/off
if [ "$LINHAS" -ge 6 ]; then
SELECT="`printf "$VALUES\n"|head -6|tail -1`"
case "$SELECT" in
on|OFF)
CHK_MAIL="on"
VALORES[5]="on";;
off|OFF)
CHK_MAIL="off"
VALORES[5]="off";;
esac
fi # set CHK_MAIL on/off
if [ "$LINHAS" -ge 7 ]; then
SELECT="`printf "$VALUES\n"|head -7|tail -1`"
type "`echo $SELECT|sed "s; .*$;;"`" &>/dev/null
if [ "$?" = 0 ]; then
COMANDO=$SELECT
VALORES[6]=$SELECT
else VALORES[6]=
fi
fi # set COMANDO
if [ "$LINHAS" -eq 8 ]; then
MENSAGEM="`printf "$VALUES\n"|tail -1`"
VALORES[7]=""$MENSAGEM""
else VALORES[7]=
MENSAGEM=
fi # set MENSAGEM
cp $CONF $CONF.1
for i in $(seq 0 $((${#LABELS[@]}-1))); do
NUMBER_LINE=$(cat $CONF.1| grep -n "^${LABELS[$i]}[ ]*=.*"|tail -1|cut -f1 -d: 2>>$TMP_LOG)
if [ -z "$NUMBER_LINE" ] || [ "$NUMBER_LINE" -eq 0 ]; then
let TAM++
NUMBER_LINE=$TAM
fi # add line
head -$(($NUMBER_LINE - 1)) $CONF.1 >$CONF.2
if [ "$i" -eq "$((${#LABELS[@]}-1))" ]; then
printf "${LABELS[$i]} = \"${VALORES[$i]}\"\n" >>$CONF.2
else printf "${LABELS[$i]} = ${VALORES[$i]}\n" >>$CONF.2
fi # insere aspas (") como separador de texto em BROADCAST
tail -$(($TAM - $NUMBER_LINE)) $CONF.1 >>$CONF.2
mv $CONF.2 $CONF.1
done # edita o arquivo de configuração
mv $CONF.1 $CONF
fi # filtragem e armazenamento dos valores =============================================================
return $RETORNO
} # setup - permite a reconfiguração de parâmetros de busca, retorna retorno do dialog.
function split_std(){
local TEXT="`echo "$3"|sed "s;|;\n;g"`\n"
local STRING=
local -i TAM=`printf "$TEXT"|wc -l`
local -i i
SELECAO=
for i in `seq 1 $TAM`; do
STRING="`printf "$TEXT"|head -${i}|tail -1`"
SELECAO="$SELECAO|$1.*$STRING.*|$2.*$STRING.*"
done
SELECAO="`echo "$SELECAO"|sed "s;^|;;"`"
} # split_std - formata padrões de busca de acordo com os campos a serem usados
function change_profile(){
local -i RETORNO=3 # retorno do dialog
local -i LINHAS=0 # número de entradas
local ENTRADA= # entradas do dialog
local FRAME_ART_CP="$FRAME_ART" # cópias de restauração de valores
local FRAME_TIT_CP="$FRAME_TIT" # //
local FRAME_ALB_CP="$FRAME_ALB" # //
local FRAME_YER_CP="$FRAME_YER" # //
local FRAME_CON_CP="$FRAME_CON" # //
local FRAME_ALL_CP="$FRAME_ALL" # //
while [ "$RETORNO" -eq 3 ]; do # ==========================================================
ENTRADA=$(dialog --stdout --ok-label "Ok" \
--extra-button --extra-label "Genre List" \
--title "$1" \
--backtitle "MocpList - Busca e Enfileiramento" \
--form "Forneça expressões que combinem com a busca desejada:" \
0 0 0 \
"Artista, Banda:" 1 1 "${FRAME_ART:-${DICA[0]}}" 1 18 50 99 \
"Título:" 2 1 "${FRAME_TIT:-${DICA[1]}}" 2 18 50 99 \
"Álbum:" 3 1 "${FRAME_ALB:-${DICA[2]}}" 3 18 50 99 \
"Ano:" 4 1 "${FRAME_YER:-${DICA[3]}}" 4 18 50 99 \
"Gênero:" 5 1 "${FRAME_CON:-${DICA[4]}}" 5 18 50 99 \
"Outros:" 6 1 "${FRAME_ALL:-${DICA[5]}}" 6 18 50 99 \
)
RETORNO="$?"
if [ "$RETORNO" = 3 ]; then
dialog --stdout \
--title "Genres List" \
--backtitle "MocpList - Lista de códigos dos gêneros músicais" \
--textbox $GENRE_LIST \
0 0
ENTRADA=
fi
LINHAS="`printf "$ENTRADA\n"|wc -l`"
[ -z "$ENTRADA" ] && LINHAS=0
done # alteração das variáveis de casamento de padrão ======================================
# === Filtragem de entradas ================================================================
if [ "$LINHAS" -gt 0 ]; then
# seleção de entrada:
local SELECT="`printf "$ENTRADA\n"|head -1|sed 's/[ ][ ]*/ /g; s/[ ][ ]*$//'`"
[ "$SELECT" = "${DICA[0]}" ] && SELECT=""
FRAME_ART="$SELECT"
if [ -z "$SELECT" ]; then
PADRAO[0]=
else #PADRAO[0]="Artist: .*$SELECT.* |^TPE.*: .*$SELECT.*$"
split_std "Artist: " "^TPE.*: " "$SELECT"
PADRAO[0]="$SELECAO"
fi # formatação 'artista/banda'
if [ "$LINHAS" -ge 2 ]; then
SELECT="`printf "$ENTRADA\n"|head -2|tail -1|sed 's/[ ][ ]*/ /g; s/[ ][ ]*$//'`"
[ "$SELECT" = "${DICA[1]}" ] && SELECT=""
if [ -z "$SELECT" ]; then
PARDAO[1]=
else split_std "Title: " "^TIT.*: " "$SELECT"
PADRAO[1]="$SELECAO"
fi
FRAME_TIT="$SELECT"
else FRAME_TIT=
fi # formatação 'título'
if [ "$LINHAS" -ge 3 ]; then
SELECT="`printf "$ENTRADA\n"|head -3|tail -1|sed 's/[ ][ ]*/ /g; s/[ ][ ]*$//'`"
[ "$SELECT" = "${DICA[2]}" ] && SELECT="" && FRAME_ALB=""
if [ -z "$SELECT" ]; then
PADRAO[2]=
else split_std "Album: " "^TALB.*: " "$SELECT"
PADRAO[2]="$SELECAO"
fi
FRAME_ALB="$SELECT"
else FRAME_ALB=
fi # Formatação 'álbum'
if [ "$LINHAS" -ge 4 ]; then
SELECT="`printf "$ENTRADA\n"|head -4|tail -1|sed 's/[ ][ ]*/ /g; s/[ ][ ]*$//'`"
[ "$SELECT" = "${DICA[3]}" ] && SELECT=""
if [ -z "$SELECT" ]; then
PADRAO[3]=
else split_std "Year: " "^TYER.*: " "$SELECT"
PADRAO[3]="$SELECAO"
fi
FRAME_YER="$SELECT"
else FRAME_YER=
fi # Formatação 'ano'
if [ "$LINHAS" -ge 5 ]; then
SELECT="`printf "$ENTRADA\n"|head -5|tail -1|sed 's/[ ][ ]*/ /g; s/[ ][ ]*$//'`"
[ "$SELECT" = "${DICA[4]}" ] && SELECT=""
if [ -z "$SELECT" ]; then
PADRAO[4]=
else split_std "Genre: " "^TCON.*: " "$SELECT"
PADRAO[4]="$SELECAO"
fi
FRAME_CON="$SELECT"
else FRAME_CON=
fi # Formatação 'gênero'
if [ "$LINHAS" -eq 6 ]; then
SELECT="`printf "$ENTRADA\n"|tail -1|sed 's/[ ][ ]*/ /g; s/[ ][ ]*$//'`"
[ "$SELECT" = "${DICA[5]}" ] && SELECT=""
if [ -z "$SELECT" ]; then
PADRAO[5]=
else PADRAO[5]="`echo $SELECT|sed 's/^|//g; s/|$//g'`"
fi
FRAME_ALL="$SELECT"
else FRAME_ALL=
fi # Formatação 'outros'
else FRAME_ART="$FRAME_ART_CP"
FRAME_TIT="$FRAME_TIT_CP"
FRAME_ALB="$FRAME_ALB_CP"
FRAME_YER="$FRAME_YER_CP"
FRAME_CON="$FRAME_CON_CP"
FRAME_ALL="$FRAME_ALL_CP"
fi # filtragem de entradas =================================================================
return $RETORNO
} # change_profile - permite alterar o perfil do padrão de busca, retorna retorno do dialog.
function set_voice(){
local TEXT="$1" # texto a ser analisado
local -i TAM=`cat $WORDS_ES|wc -l` # tamanho do arquivo com expressões em alguma língua
local -i SUM_ES=0 # quantidade de expressões em espanhol encontrada
local -i SUM_EN=0 # quantidade de expressões em inglês encontrada
local -i x=0 # aux. de iteração
local WORD= # expressão regular de um idioma
[ -z "$TEXT" ] && return 0
for x in $(seq 1 $TAM); do
WORD="`head -$x $WORDS_ES|tail -1`"
echo "$TEXT"|grep -qiE "$WORD" && let SUM_ES++
done # conta ocorrência de expressões em espanhol
TAM=`cat $WORDS_EN|wc -l`; SUM_EN=0
for x in $(seq 1 $TAM); do
WORD="`head -$x $WORDS_EN|tail -1`"
echo "$TEXT"|grep -qiE "^$WORD" && let SUM_EN++
done # conta ocorrência de expressões em inglês
# ingles=$SUM_EN; espanhol=$SUM_ES ### depurando...
if [ "$(($SUM_ES + $SUM_EN))" -gt 0 ]; then
if [ "$SUM_EN" -gt "$SUM_ES" ]; then
return 2
else return 3
fi
else return 1
fi # elege um dos idiomas ou mantém o default
} # set_voice - elege idioma do locutor
function get_data_and_spk(){
mocp -i > $DATA_MEDIA 2>/dev/null
if [ "$?" -eq 0 ]; then
TRACK="`grep "^File:" $DATA_MEDIA|sed 's/File: *//'`" # TRACK on play
else restart_player
return 0
fi # set data or restart moc
# === Atualiza Tags e Anúncia e Elege Idioma ===============================================================
if [ "$TRACK1" != "$TRACK" ]; then
# === Elege Idioma para o Locutor ==================================================================
if [ "$TALK" = "on" ]; then
set_voice "$TRACK"
case "$?" in
1) VOZ="pt";;
2) VOZ="en-us";;
3) VOZ="es-la";;
*) VOZ="on";;
esac
fi # elege idioma ==================================================================================
id3v2 -l "${TRACK:=}" 2>>$TMP_LOG|sed '/^PRIV.*:/d'|grep -v "^COMM.*:.*[0-9A-F]\{8,\}" >$DATA_ID3
ARTIST="`grep "^TPE1.*: " $DATA_ID3|sed "s/^TPE1.*: *//"`"
SONG_TITLE="`grep "^TIT2.*: " $DATA_ID3|sed "s/^TIT2.*: *//"`"
YEAR="`grep "^TYER.*: " $DATA_ID3|sed "s/^TYER.*: *//"`"
ALBUM="`grep "^TALB.*: " $DATA_ID3|sed "s/^TALB.*: *//"`"
GENRE="`grep "^TCON.*: " $DATA_ID3|sed "s/^TCON.*: *//"`"
ARTIST="${ARTIST:=$(grep "^Artist:" $DATA_MEDIA|sed 's/^Artist: *//')}"
SONG_TITLE="${SONG_TITLE:=$(grep "^SongTitle:" $DATA_MEDIA|sed 's/^SongTitle: *//')}"
ALBUM="${ALBUM:=$(grep "^Album:" $DATA_MEDIA|sed 's/^Album: *//')}"
YEAR="${YEAR:=$(grep "^.*Year: *" $DATA_ID3|sed "s/^.*Year: *//"|sed "s/,.*$//")}"
GENRE="${GENRE:=$(grep "^.*Genre: *" $DATA_ID3|sed "s/^.*Genre: *//"|sed "s/[ ]*$//g")}"
TITLE="$ARTIST - $SONG_TITLE"
echo $TITLE|grep -qE "[[:alnum:]]" || TITLE="`echo $TRACK|sed 's;^/.*/[ 0-9]*;;'| \
sed 's/[MmOoFfAa][PpGgLlVv][34GgVvIi]$//'`" # título alternativo
TRACK1="$TRACK"
fi # atualiza tags e elege idioma =========================================================================
local -i TIME_LEFT="$(grep TimeLeft: $DATA_MEDIA| sed 's/^.* //; s/00*:00/0:01/; s/://; s/^.0//; s/^00*//')"
# Configura Locutor ========================================================================================
if [ "$TIME_LEFT" -gt 3 ] && [ "$TIME_LEFT" -lt 7 ]; then
# Executa o Locutor ================================================================================
if [ "$TALK" = "on" ]; then
local CITE= # citação do player (mudo por default)
local -i RND=$RANDOM
killall -9 espeak &>/dev/null
if [ $(($RND % 100)) -le 50 ];then
if [ "$VOZ" = "en-us" ]; then
CITE="$FRASE_EN"
else CITE="$FRASE_PT"
fi # seleção de pronúncia
fi # escolhe se anúncia créditos moc
espeak -p0 -v$VOZ+m1 "$CITE$TITLE..." &>/dev/null
if [ "$(($RANDOM % 100))" -gt "$PROB" ]; then
if [ "$DIFUSAO" = "on" ]; then
local -i PAUSADO=0
mocp -i|grep -q "State: PLAY" && mocp -P && PAUSADO=1
if [ "$(($RANDOM % 100))" -gt 80 ]; then
local VOICE=
TEXTO="`command $COMANDO`"
set_voice "$TEXTO"
case "$?" in
1) VOICE="pt";;
2) VOICE="en-us";;
3) VOICE="es-la";;
*) VOICE="pt";;
esac
echo "$TEXTO"|espeak -v${VOICE}+m4 &>/dev/null
else espeak -vpt+f4 "$MENSAGEM" &>/dev/null
fi # escolhe aleatóriamente a frase de difusão
[ "$PAUSADO" -eq 1 ] && mocp -U
fi # difusão de mensagens
else CITE="`date "+%H horas, %M minutos"|sed 's/^0//'|sed -r 's/(.*, )0(.*)/\1\2/'`"
espeak -vpt+f4 "$HOSTNAME: $CITE" &>/dev/null
if [ "$NEW_MAIL" -gt 0 ]; then
local S= # plural
[ "$NEW_MAIL" -gt 1 ] && S="s"
espeak -vpt+m4 "Você tem $NEW_MAIL email$S não lido$S." &>/dev/null
fi # anuncia número de emails não lidos
fi # elege anúncio de horas, ou difusão/citação
fi # TALK TRACK in playing =========================================================================
fi # configura saída de voz sintetizada ====================================================================
if [ "$TRACK0" != "$TRACK" ]; then
TRACK0=$TRACK
return 0
else return 1
fi # verifica troca da mídia em execução
} # get_data_and_spk - obtém dados da mídia em reprodução e anuncia titulo em voz sintetizada
function enfileirar(){
local -i PERCENTUAL=$2 # limitador da partição (com uma casa decimal)
local -i TT_VAR=`cat $TT_VARRIDOS` # total acumulado de ficheiros pesquisados
local -i TT_INDEX="`cat $INDEX 2>>$TMP_LOG|wc -l`" # total de índices a serem pesquisados
local -i PONTEIRO=0 # ponteiro inicial do segmento
local -i LINE_SELECT=0 # índice contido no segmento
local -i PROXIMO=0 # contador de vizinhos enfileirados
local -i CONTADOR=0 # ponteiro do segmento em varrimento
local -i VARRIDOS=0 # contador de índices pesquisados da partição
local -i PERC_BUSCA=0 # estado da busca e limitador de partição
local MEDIA_SELECTED= # mídia selecionada
local ID3= # armazena dados id3v2
if [ "$1" != "no" ]; then
local -i TT_FILA=0 # reinicia ńumero de enfileirados
else
local -i TT_FILA=$(cat $TOT_FILA) # restaura número de enfileirados
fi # número de enfileirados
printf "" > $CHECKEDS # limpa lista auxiliar
# === V A R R E D U R A D A P A R T I Ç A O ============================================================================
while [ "$PERC_BUSCA" -le "$PERCENTUAL" ] && [ "$VARRIDOS" -lt "$TT_INDEX" ]; do
PONTEIRO=$((1 + (($RANDOM + `date +%N|sed -e 's/^00*//g'`) % $TT_INDEX))) # ponteiro randomizado
PROXIMO=0; CONTADOR=0
# === V A R R E D U R A D O S E G M E N T O ====================================================================
while [ "$CONTADOR" -lt "$SECAO" ] && [ "$PONTEIRO" -le "$TT_INDEX" ]; do
[ "`cat $SINAL`" -eq 0 ] && return 2 # interrupção por sinal
LINE_SELECT="`head -$PONTEIRO $INDEX|tail -1`" # seleciona índice a pesquisar
# === C H E C A G E M D E I N D I C E S ================================================================
grep -q "^$LINE_SELECT$" $CHECKEDS # checa se índice já foi pesquisado
if [ "$?" -ne 0 ]; then
MEDIA_SELECTED="`head -$LINE_SELECT $FICHEIROS|tail -1`" # seleciona mídia apontada pelo índice
ID3="`id3v2 -l "$MUSICA/$MEDIA_SELECTED"|grep -E "$FILTRO"`" # obtém tags id3 da mídia
# === V E R I F I C A C A S A M E N T O D E P A D R O E S ====================================
echo "$ID3"|grep -qiE "${PADRAO[0]}"
if [ "$?" -eq 0 ] || [ "${PADRAO[0]}" = "" ]; then
echo "$ID3"|grep -qiE "${PADRAO[1]}"
if [ "$?" -eq 0 ] || [ "${PADRAO[1]}" = "" ]; then
echo "$ID3"|grep -qiE "${PADRAO[2]}"
if [ "$?" -eq 0 ] || [ "${PADRAO[2]}" = "" ]; then
echo "$ID3"|grep -qiE "${PADRAO[3]}"
if [ "$?" -eq 0 ] || [ "${PADRAO[3]}" = "" ]; then
echo "$ID3"|grep -qiE "${PADRAO[4]}"
if [ "$?" -eq 0 ] || [ "${PADRAO[4]}" = "" ]; then
echo "$ID3"|grep -qiE "${PADRAO[5]}"
if [ "$?" -eq 0 ] || [ "${PADRAO[5]}" = "" ]; then
# === E N F I L E I R A D E M I D I A ==========
if [ "$TT_FILA" -lt "$MAX_FILA" ]; then
mocp -a "$MUSICA/$MEDIA_SELECTED" || restart_player &>/dev/null
if [ "`mocp -Q %state 2>/dev/null`" = "STOP" ]; then
[ "$TALK" = "on" ] && espeak -p0 -vpt+f4 "Reproduzindo..." &>/dev/null
mocp -p 2>/dev/null
sleep .5
fi # inicia a reprodução
let TT_FILA++; let PROXIMO++
echo $TT_FILA > $TOT_FILA
[ "$PROXIMO" -ge "$VIZINHOS" ] && CONTADOR=$SECAO
else return 1 # conclusão do enfileiramento
fi # enfileiramento de mídia =======================
fi # other
fi # genre
fi # year
fi # album
fi # title
fi # artist/band ===================================================================================
echo "$LINE_SELECT" >> $CHECKEDS
fi # checagem ==============================================================================================
let PONTEIRO++ # move ponteiro do segmento
let CONTADOR++
done # varredura do seguimento =====================================================================================
VARRIDOS="`cat $CHECKEDS|wc -l`" || exit 1
PERC_BUSCA=$((($VARRIDOS + $TT_VAR)*1000/$TT_FICHEIROS))
echo $PERC_BUSCA >$PERC_OUT # (exibido na tela principal)
done # varredura da partição ===============================================================================================
echo "$(($TT_VAR + $VARRIDOS))" > $TT_VARRIDOS # variável restaurável
test "`cat $TT_VARRIDOS`" -lt "$TT_FICHEIROS"
return $? # retorna 1 se concluído, 2 se interrompido e 0 se não concluído
} # enfileira - pesquisa na partição em construção e enfileira mídias
function auto_enqueueur(){
if [ "$AUTO" != "auto" ];then
estado_sub_pid
change_profile "AUTO ENFILEIRAR $MAX_FILA mídias ao 'playlist'..."
if [ "$?" -eq 0 ]; then
AUTO="auto"
else AUTO="no-auto"
fi # ativa o modo auto se confirmado
else AUTO="no-auto"
fi # alterna modo automático
} # auto_enqueueur - toggle auto/no-auto
function hash_list(){
local LIMPAR="$1" # limpar fila (yes/no)
seq 1 $TT_FICHEIROS > $INDEX || exit 1 # lista de índices a serem varridos
local -ai PARTICAO=(`seq 50 50 950` 999 1000) # limitadores de partições (percentuais com uma casa decimal)
local -i LEN=${#PARTICAO[@]} # número de partições (20 + 1 partições)
local -i i=0 # variável de incremento
echo 0 > $TT_VARRIDOS # total geral de índices pesquisados
echo 0 > $PERC_OUT # percentual da varrredura
echo 1 > $SINAL # flag de interrupção de busca e enfileiramento
echo 0 > $TOT_FILA # número de enfileirados
if [ "$TALK" = "on" ]; then
espeak -p0 -vpt+f4 "$HOSTNAME: Enfileirando $MAX_FILA mídias.: " &>/dev/null
test -n "$FRAME_ART" && espeak -p0 -vpt+f4 "Artista: $FRAME_ART" &>/dev/null
test -n "$FRAME_TIT" && espeak -p0 -vpt+f4 "Título: $FRAME_TIT" &>/dev/null
test -n "$FRAME_ALB" && espeak -p0 -vpt+f4 "Álbum: $FRAME_ALB" &>/dev/null
test -n "$FRAME_YER" && espeak -p0 -vpt+f4 "Ano: $FRAME_YER" &>/dev/null
test -n "$FRAME_CON" && espeak -p0 -vpt+f4 "Gênero: $FRAME_CON" &>/dev/null
test -n "$FRAME_ALL" && espeak -p0 -vpt+f4 "Outros: $FRAME_ALL" &>/dev/null
fi # anuncia enfileiramento
for ((i;i<$LEN;i++)); do
# === BEFORE =============================================================
[ "$i" -gt 0 ] && LIMPAR="no" # mantém playlist após primeira iteração
# === ENFILEIRA enfileirar <yes|no|auto> <partição> =====================
enfileirar "$LIMPAR" ${PARTICAO[$i]}
# === AFTER ==============================================================
if [ "$?" -eq 0 ]; then
sed 's/^/\^/' $CHECKEDS|sed 's/$/\$/' > $CHECKEDS.1
grep -vf $CHECKEDS.1 $INDEX > $INDEX.1
mv $INDEX.1 $INDEX
else break # termina se concluído ou interrompido por sinal
fi # elimina partição pesquisada do vetor de índices
done # pesquisa em cada partição construída em tempo de busca e enfileiramento
echo -1 > $SUB_PID
[ "$TALK" = "on" ] && espeak -p0 -vpt+f4 "Busca encerrada." &>/dev/null
} # hash_list - faz o particionamento dos índices e enfileira mídias casadas
function set_list(){
# Parâmetros:
# 1) limpar? <yes|no|auto>
# 2) frase do dialog
local -i RET=1 # retorno
TT_FICHEIROS="`cat $FICHEIROS|wc -l`"
if [ "$1" = "auto" ]; then
[ "`cat $SUB_PID`" -le 0 ] && RET=0
else estado_sub_pid && change_profile "$2" && RET=0
fi # permite interromper e reiniciar o enfileiramento
if [ "$RET" -eq 0 ]; then
if [ "$1" != "no" ]; then
mocp -s &>/dev/null
mocp -c &>/dev/null
fi # interrompe e limpa playlist
hash_list $1& 2>>$TMP_LOG
echo $! > $SUB_PID
fi # enfileira
} # set_list - permite reconfiguração da forma de busca e enfileira arquivos
function estado_sub_pid(){
local -i RET=0
if [ "`cat $SUB_PID`" -gt 0 ]; then
dialog --stdout \
--title "Atenção!" --defaultno \
--yesno "Existi um processo de enfileiramento aberto. A conclusão do mesmo pode demorar alguns minutos. \
\n\nVocê deseja terminá-lo?" \
12 60
if [ "$?" -eq 0 ]; then
dialog --stdout \
--title "MocpList: Encerrando busca..." \
--infobox "\nAguarde! Encerrando procedimento..." \
7 40
echo "0" > $SINAL
local -i DEAD="`cat $SUB_PID`"
while [ "${DEAD:=0}" -gt 0 ]; do sleep 1; DEAD="`cat $SUB_PID`" ;done
else RET=1
fi # modifica sinal e aguarda encerramento
fi # verifica se procedimento está em execução
return $RET
} # estado_sub_pid - verifica e permite encerrar processo de busca em execução
function display_info(){
# parâmetro 1: refresh
get_data_and_spk 2>> $TMP_LOG
if [ "$?" -eq 0 ] || [ "$1" -eq 0 ]; then
local STATUS="ocioso"
local FILE="`echo $TRACK|sed 's;.*/M[úu]sica/;../;'`"
[ "`cat $SUB_PID`" -gt 0 ] && STATUS="`cat $PERC_OUT`% concluído."
if [ -z "$TITLE" ]; then
MODO="Waiting"
TEXTO="Aguardando"
else MODO="Playing -"
TEXTO="Reproduzindo $TITLE"
fi # textos da sobre o estado do tocador
# TEXTO="[$espanhol|$ingles] $TEXTO" ### depurando...
TEXTO="$TEXTO...\n\nArtista: ${ARTIST}\nTítulo: ${SONG_TITLE}\nÁlbum: ${ALBUM}\nAno: ${YEAR}"
TEXTO="$TEXTO\nGênero: ${GENRE}\nArquivo: ${FILE:=}"
TEXTO="$TEXTO\n\nEstado da pesquisa: $(echo $STATUS|sed -r "s/(.*)(.\%).*/\1,\2/"|sed "s/^,/0,/")\nEnfileiramento: `cat $TOT_FILA`/$MAX_FILA"
TEXTO="$TEXTO\nPalavras chaves: {`echo "(${FRAME_ART:-${DICA[0]}}) & (${FRAME_TIT:-${DICA[1]}}) & (${FRAME_ALB:-${DICA[2]}}) & (${FRAME_YER:-${DICA[3]}}) & (${FRAME_CON:-${DICA[4]}}) & (${FRAME_ALL:-${DICA[5]}})"`}"
dialog --stdout --no-collapse --trim --tab-correct \
--backtitle " .::: <s>et :: <l>ist :: <i>nfo :: <b>ack :: <n>ext :: <p>ause :: <h>elp :: <q>uit :::" \
--title "MocpList - Talk
Alterar o papel de parede aleatoriamente
Script Iptables ( Passou em Testes )
Exclusão de arquivos em massa por data
Modo Simples de Baixar e Usar o bash-completion
Monitorando o Preço do Bitcoin ou sua Cripto Favorita em Tempo Real com um Widget Flutuante
Instalando partes faltantes do Plasma 6
Adicionar botão "mostrar área de trabalho" no Zorin OS
Como montar um servidor de backup no linux
Estou tentando ser legalista, mas tá complicado! (9)
espelhar monitores nao funciona (2)
SQLITE não quer funcionar no LINUX LMDE6 64 com Lazaruz 4.2 64bit (n... (1)









