MocPList - Enfileirador de áudio e locutor em voz sintetizada
Publicado por Khayla Elias dos Santos (última atualização em 21/02/2019)
[ Hits: 2.673 ]
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
Script que busca IP Livres em uma rede
Proteja sua rede com um simples script de firewall
Estatística dos MB's consumidos pela internet
Enviar mensagem ao usuário trabalhando com as opções do php.ini
Meu Fork do Plugin de Integração do CVS para o KDevelop
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Compartilhamento de Rede com samba em modo Público/Anônimo de forma simples, rápido e fácil
Cups: Mapear/listar todas as impressoras de outro Servidor CUPS de forma rápida e fácil
Criando uma VPC na AWS via CLI
Tem como instalar o gerenciador AMD Adrenalin no Ubuntu 24.04? (7)