├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── mpdev-c-cpp.yml │ ├── mpdev-obs.yml │ └── shell.yml ├── .gitignore ├── AUTHORS ├── INSTALL ├── LICENSE ├── Makefile.am ├── PKGBUILD.in ├── README.md ├── auto-ccld.sh ├── catChangeLog ├── choose.sh ├── conf-email ├── conf-ip ├── conf-ld ├── conf-version ├── configure.ac ├── create_archpkg ├── create_debian ├── create_rpm ├── create_service.in ├── debian ├── Makefile ├── README ├── changelog.in ├── compat ├── control.in ├── copyright.in ├── docs ├── mpdev.cron.d ├── mpdev.dsc.in ├── mpdev.install.in ├── postinst.in ├── preinst.in ├── prerm.in ├── rules.in └── source │ └── format ├── default.configure ├── doc └── ChangeLog ├── karma.1 ├── karma.in ├── lastfm-scrobbler.1 ├── lcd_display.in ├── librefm-scrobbler.1 ├── mixer.in ├── moc-scrobbler-license ├── moc-scrobbler.in ├── mpd_local.te ├── mpdev-release.in ├── mpdev.1 ├── mpdev.c ├── mpdev.spec.in ├── mpdev_cleanup.1 ├── mpdev_cleanup.c ├── mpdev_rename.1 ├── mpdev_rename.in ├── mpdev_update.1 ├── mpdev_update.c ├── mpdhist.1 ├── mpdhist.in ├── mpdplaylist.1 ├── mpdplaylist.in ├── obs └── mpdev │ └── _service ├── output.in ├── player.in ├── playpause.in ├── prepare_obs ├── replacestr.c ├── replacestr.h ├── songi.1 ├── songi.in ├── tcpopen.h ├── transfer_play.1 ├── transfer_play.in └── warn-auto.sh /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: mbhangui 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/mpdev-c-cpp.yml: -------------------------------------------------------------------------------- 1 | name: mpdev C/C++ CI 2 | 3 | on: 4 | push: 5 | paths: 6 | - '**' 7 | - .github/workflows/mpdev-c-cpp.yml 8 | - '!**/debian/*' 9 | - '!**/mpdev.spec.in' 10 | - '!**/obs/*' 11 | - '!**/doc/*' 12 | - '!**.md' 13 | - '!**/mpdev-obs.yml' 14 | workflow_dispatch: 15 | 16 | jobs: 17 | build: 18 | name: ${{ matrix.host }}-${{ matrix.config.name }} 19 | runs-on: ${{ matrix.host }} 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | host: [ubuntu-latest, macos-latest] 24 | 25 | steps: 26 | - name: extra_packages 27 | run: | 28 | if [ "${OS}" = "ubuntu-latest" ]; then sudo apt-get update;sudo apt-get install libsqlite3-dev; fi 29 | if [ "${OS}" = "macos-latest" ]; then brew install automake autoconf libtool pkgconfig sqlite3 openssl; fi 30 | env: 31 | OS: ${{ matrix.host }} 32 | 33 | - name: checkout_main 34 | uses: actions/checkout@v4 35 | with: 36 | path: main 37 | 38 | - name: checkout_qmail 39 | uses: actions/checkout@v4 40 | with: 41 | repository: mbhangui/libqmail 42 | path: libqmail 43 | 44 | - name: install_qmail 45 | run: cd libqmail;env CPPFLAGS="-I/usr/local/opt/openssl@1.1/include" LDFLAGS="-L/usr/local/opt/openssl@1.1/lib" ./default.configure; env CPPFLAGS="-I/usr/local/opt/openssl@1.1/include" LDFLAGS="-L/usr/local/opt/openssl@1.1/lib" make; sudo make install-strip 46 | - name: build_mpdev 47 | run: | 48 | cd main; ./default.configure; make 49 | make clean; /bin/rm -rf .git ../libqmail autom4te.cache 50 | make -C debian;make mpdev.spec 51 | -------------------------------------------------------------------------------- /.github/workflows/mpdev-obs.yml: -------------------------------------------------------------------------------- 1 | name: mpdev obs trigger 2 | 3 | on: 4 | push: 5 | paths: 6 | - '**' 7 | - .github/workflows/mpdev-obs.yml 8 | - '!**/obs/*' 9 | - '!**/doc/*' 10 | - '!**.md' 11 | - '!**/mpdev-c-cpp.yml' 12 | workflow_dispatch: 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: checkout_mpdev 19 | uses: actions/checkout@v4 20 | - name: checkout_qmail 21 | uses: actions/checkout@v4 22 | with: 23 | repository: mbhangui/libqmail 24 | path: libqmail 25 | 26 | - name: install_qmail 27 | run: | 28 | sudo apt-get update; sudo apt-get install libssl-dev libmysqlclient-dev libsqlite3-dev 29 | cd libqmail; ./default.configure; make; sudo make install-strip 30 | - name: prepare obs 31 | run: /bin/rm -rf libqmail;./prepare_obs mpdev 32 | - uses: actions/upload-artifact@v4 33 | with: 34 | name: mpdev 35 | path: ~/stage 36 | - shell: bash 37 | name: trigger_obs 38 | run: | 39 | # create ssh environment 40 | mkdir ~/.ssh 41 | echo "${{secrets.sf_private_key}}" > ~/.private_key 42 | chmod 600 ~/.private_key 43 | echo "${{secrets.sf_known_hosts}}" > ~/.ssh/known_hosts 44 | # create gpg environment 45 | echo "Importing gpg key" 46 | echo "${{secrets.software_key}}" | gpg --batch --import 47 | echo "Listing gpg key" 48 | gpg --list-secret-keys --keyid-format LONG 49 | # create archive and transfer 50 | cd ~/stage 51 | tar cvfz $GITHUB_WORKSPACE/mpdev-obs.tar.gz * 52 | # sign the archive 53 | echo "${{secrets.software_passphrase}}" | gpg2 --pinentry-mode loopback \ 54 | --passphrase-fd 0 --default-key "${{secrets.software_user}}" \ 55 | -o mpdev-obs.sig --detach-sig $GITHUB_WORKSPACE/mpdev-obs.tar.gz 56 | # copy to /home/frs/project/indimail 57 | scp -q -i ~/.private_key $GITHUB_WORKSPACE/mpdev-obs.tar.gz \ 58 | ~/stage/mpdev-obs.sig "${{secrets.sf_user}}:${{secrets.sf_upload_path}}" 59 | rm -f ~/.private_key ~/.ssh/known_hosts $GITHUB_WORKSPACE/mpdev-obs.tar.gz 60 | rm -rf ~/stage 61 | -------------------------------------------------------------------------------- /.github/workflows/shell.yml: -------------------------------------------------------------------------------- 1 | name: interactive 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | - name: Setup tmate session 12 | uses: mxschmitt/action-tmate@v3 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # http://www.gnu.org/software/automake 2 | 3 | Makefile.in 4 | /ar-lib 5 | /mdate-sh 6 | /py-compile 7 | /test-driver 8 | /ylwrap 9 | 10 | # http://www.gnu.org/software/autoconf 11 | 12 | autom4te.cache 13 | /autoscan.log 14 | /autoscan-*.log 15 | /aclocal.m4 16 | /compile 17 | /config.guess 18 | /config.log 19 | /config.status 20 | /config.sub 21 | /configure 22 | /configure.scan 23 | /depcomp 24 | /install-sh 25 | /missing 26 | /stamp-h1 27 | 28 | # https://www.gnu.org/software/libtool/ 29 | 30 | /ltmain.sh 31 | 32 | # http://www.gnu.org/software/texinfo 33 | 34 | /texinfo.tex 35 | 36 | # http://www.gnu.org/software/m4/ 37 | 38 | m4/libtool.m4 39 | m4/ltoptions.m4 40 | m4/ltsugar.m4 41 | m4/ltversion.m4 42 | m4/lt~obsolete.m4 43 | 44 | # Generated Makefile 45 | # (meta build system like autotools, 46 | # can automatically generate from config.status script 47 | # (which is called by configure script)) 48 | Makefile 49 | .deps 50 | conf-release 51 | config.h.in 52 | config.h.in.BAK 53 | config.h.in~ 54 | haveip6.h 55 | libtool 56 | mpdev.spec 57 | mpdev.changes 58 | choose 59 | create_service 60 | lastfm-scrobbler 61 | librefm-scrobbler 62 | mpdev 63 | mpdev.o 64 | mpdev_maintenance 65 | mpdplaylist 66 | pathexec_env.o 67 | pathexec_run.o 68 | player 69 | tcpopen.o 70 | debian/changelog 71 | debian/debian.tar.gz 72 | debian/mpdev.dsc 73 | debian/mpdev.install 74 | debian/preinst 75 | debian/postinst 76 | debian/prerm 77 | debian/rules 78 | debian/control 79 | debian/copyright 80 | RCS 81 | config.h 82 | create_stats 83 | mpdev_update 84 | mpdev_update.o 85 | replacestr.o 86 | mpdev_cleanup 87 | mpdev_cleanup.o 88 | mpdev_rename 89 | romprhist 90 | misc 91 | transfer_play 92 | playpause 93 | PKGBUILD 94 | mpdev-release 95 | karma 96 | patches 97 | output 98 | mixer 99 | songi 100 | config.h.in 101 | mpdhist 102 | lcd_display 103 | config.guess.BAK 104 | config.sub.BAK 105 | configure.BAK 106 | install-sh.BAK 107 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Manvendra Bhangui 2 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ************************* 3 | 4 | Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software 5 | Foundation, Inc. 6 | 7 | Copying and distribution of this file, with or without modification, 8 | are permitted in any medium without royalty provided the copyright 9 | notice and this notice are preserved. This file is offered as-is, 10 | without warranty of any kind. 11 | 12 | Basic Installation 13 | ================== 14 | 15 | Briefly, the shell command './configure && make && make install' 16 | should configure, build, and install this package. The following 17 | more-detailed instructions are generic; see the 'README' file for 18 | instructions specific to this package. Some packages provide this 19 | 'INSTALL' file but do not implement all of the features documented 20 | below. The lack of an optional feature in a given package is not 21 | necessarily a bug. More recommendations for GNU packages can be found 22 | in *note Makefile Conventions: (standards)Makefile Conventions. 23 | 24 | The 'configure' shell script attempts to guess correct values for 25 | various system-dependent variables used during compilation. It uses 26 | those values to create a 'Makefile' in each directory of the package. 27 | It may also create one or more '.h' files containing system-dependent 28 | definitions. Finally, it creates a shell script 'config.status' that 29 | you can run in the future to recreate the current configuration, and a 30 | file 'config.log' containing compiler output (useful mainly for 31 | debugging 'configure'). 32 | 33 | It can also use an optional file (typically called 'config.cache' and 34 | enabled with '--cache-file=config.cache' or simply '-C') that saves the 35 | results of its tests to speed up reconfiguring. Caching is disabled by 36 | default to prevent problems with accidental use of stale cache files. 37 | 38 | If you need to do unusual things to compile the package, please try 39 | to figure out how 'configure' could check whether to do them, and mail 40 | diffs or instructions to the address given in the 'README' so they can 41 | be considered for the next release. If you are using the cache, and at 42 | some point 'config.cache' contains results you don't want to keep, you 43 | may remove or edit it. 44 | 45 | The file 'configure.ac' (or 'configure.in') is used to create 46 | 'configure' by a program called 'autoconf'. You need 'configure.ac' if 47 | you want to change it or regenerate 'configure' using a newer version of 48 | 'autoconf'. 49 | 50 | The simplest way to compile this package is: 51 | 52 | 1. 'cd' to the directory containing the package's source code and type 53 | './configure' to configure the package for your system. 54 | 55 | Running 'configure' might take a while. While running, it prints 56 | some messages telling which features it is checking for. 57 | 58 | 2. Type 'make' to compile the package. 59 | 60 | 3. Optionally, type 'make check' to run any self-tests that come with 61 | the package, generally using the just-built uninstalled binaries. 62 | 63 | 4. Type 'make install' to install the programs and any data files and 64 | documentation. When installing into a prefix owned by root, it is 65 | recommended that the package be configured and built as a regular 66 | user, and only the 'make install' phase executed with root 67 | privileges. 68 | 69 | 5. Optionally, type 'make installcheck' to repeat any self-tests, but 70 | this time using the binaries in their final installed location. 71 | This target does not install anything. Running this target as a 72 | regular user, particularly if the prior 'make install' required 73 | root privileges, verifies that the installation completed 74 | correctly. 75 | 76 | 6. You can remove the program binaries and object files from the 77 | source code directory by typing 'make clean'. To also remove the 78 | files that 'configure' created (so you can compile the package for 79 | a different kind of computer), type 'make distclean'. There is 80 | also a 'make maintainer-clean' target, but that is intended mainly 81 | for the package's developers. If you use it, you may have to get 82 | all sorts of other programs in order to regenerate files that came 83 | with the distribution. 84 | 85 | 7. Often, you can also type 'make uninstall' to remove the installed 86 | files again. In practice, not all packages have tested that 87 | uninstallation works correctly, even though it is required by the 88 | GNU Coding Standards. 89 | 90 | 8. Some packages, particularly those that use Automake, provide 'make 91 | distcheck', which can by used by developers to test that all other 92 | targets like 'make install' and 'make uninstall' work correctly. 93 | This target is generally not run by end users. 94 | 95 | Compilers and Options 96 | ===================== 97 | 98 | Some systems require unusual options for compilation or linking that 99 | the 'configure' script does not know about. Run './configure --help' 100 | for details on some of the pertinent environment variables. 101 | 102 | You can give 'configure' initial values for configuration parameters 103 | by setting variables in the command line or in the environment. Here is 104 | an example: 105 | 106 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix 107 | 108 | *Note Defining Variables::, for more details. 109 | 110 | Compiling For Multiple Architectures 111 | ==================================== 112 | 113 | You can compile the package for more than one kind of computer at the 114 | same time, by placing the object files for each architecture in their 115 | own directory. To do this, you can use GNU 'make'. 'cd' to the 116 | directory where you want the object files and executables to go and run 117 | the 'configure' script. 'configure' automatically checks for the source 118 | code in the directory that 'configure' is in and in '..'. This is known 119 | as a "VPATH" build. 120 | 121 | With a non-GNU 'make', it is safer to compile the package for one 122 | architecture at a time in the source code directory. After you have 123 | installed the package for one architecture, use 'make distclean' before 124 | reconfiguring for another architecture. 125 | 126 | On MacOS X 10.5 and later systems, you can create libraries and 127 | executables that work on multiple system types--known as "fat" or 128 | "universal" binaries--by specifying multiple '-arch' options to the 129 | compiler but only a single '-arch' option to the preprocessor. Like 130 | this: 131 | 132 | ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 133 | CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 134 | CPP="gcc -E" CXXCPP="g++ -E" 135 | 136 | This is not guaranteed to produce working output in all cases, you 137 | may have to build one architecture at a time and combine the results 138 | using the 'lipo' tool if you have problems. 139 | 140 | Installation Names 141 | ================== 142 | 143 | By default, 'make install' installs the package's commands under 144 | '/usr/local/bin', include files under '/usr/local/include', etc. You 145 | can specify an installation prefix other than '/usr/local' by giving 146 | 'configure' the option '--prefix=PREFIX', where PREFIX must be an 147 | absolute file name. 148 | 149 | You can specify separate installation prefixes for 150 | architecture-specific files and architecture-independent files. If you 151 | pass the option '--exec-prefix=PREFIX' to 'configure', the package uses 152 | PREFIX as the prefix for installing programs and libraries. 153 | Documentation and other data files still use the regular prefix. 154 | 155 | In addition, if you use an unusual directory layout you can give 156 | options like '--bindir=DIR' to specify different values for particular 157 | kinds of files. Run 'configure --help' for a list of the directories 158 | you can set and what kinds of files go in them. In general, the default 159 | for these options is expressed in terms of '${prefix}', so that 160 | specifying just '--prefix' will affect all of the other directory 161 | specifications that were not explicitly provided. 162 | 163 | The most portable way to affect installation locations is to pass the 164 | correct locations to 'configure'; however, many packages provide one or 165 | both of the following shortcuts of passing variable assignments to the 166 | 'make install' command line to change installation locations without 167 | having to reconfigure or recompile. 168 | 169 | The first method involves providing an override variable for each 170 | affected directory. For example, 'make install 171 | prefix=/alternate/directory' will choose an alternate location for all 172 | directory configuration variables that were expressed in terms of 173 | '${prefix}'. Any directories that were specified during 'configure', 174 | but not in terms of '${prefix}', must each be overridden at install time 175 | for the entire installation to be relocated. The approach of makefile 176 | variable overrides for each directory variable is required by the GNU 177 | Coding Standards, and ideally causes no recompilation. However, some 178 | platforms have known limitations with the semantics of shared libraries 179 | that end up requiring recompilation when using this method, particularly 180 | noticeable in packages that use GNU Libtool. 181 | 182 | The second method involves providing the 'DESTDIR' variable. For 183 | example, 'make install DESTDIR=/alternate/directory' will prepend 184 | '/alternate/directory' before all installation names. The approach of 185 | 'DESTDIR' overrides is not required by the GNU Coding Standards, and 186 | does not work on platforms that have drive letters. On the other hand, 187 | it does better at avoiding recompilation issues, and works well even 188 | when some directory options were not specified in terms of '${prefix}' 189 | at 'configure' time. 190 | 191 | Optional Features 192 | ================= 193 | 194 | If the package supports it, you can cause programs to be installed 195 | with an extra prefix or suffix on their names by giving 'configure' the 196 | option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. 197 | 198 | Some packages pay attention to '--enable-FEATURE' options to 199 | 'configure', where FEATURE indicates an optional part of the package. 200 | They may also pay attention to '--with-PACKAGE' options, where PACKAGE 201 | is something like 'gnu-as' or 'x' (for the X Window System). The 202 | 'README' should mention any '--enable-' and '--with-' options that the 203 | package recognizes. 204 | 205 | For packages that use the X Window System, 'configure' can usually 206 | find the X include and library files automatically, but if it doesn't, 207 | you can use the 'configure' options '--x-includes=DIR' and 208 | '--x-libraries=DIR' to specify their locations. 209 | 210 | Some packages offer the ability to configure how verbose the 211 | execution of 'make' will be. For these packages, running './configure 212 | --enable-silent-rules' sets the default to minimal output, which can be 213 | overridden with 'make V=1'; while running './configure 214 | --disable-silent-rules' sets the default to verbose, which can be 215 | overridden with 'make V=0'. 216 | 217 | Particular systems 218 | ================== 219 | 220 | On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC 221 | is not installed, it is recommended to use the following options in 222 | order to use an ANSI C compiler: 223 | 224 | ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" 225 | 226 | and if that doesn't work, install pre-built binaries of GCC for HP-UX. 227 | 228 | HP-UX 'make' updates targets which have the same time stamps as their 229 | prerequisites, which makes it generally unusable when shipped generated 230 | files such as 'configure' are involved. Use GNU 'make' instead. 231 | 232 | On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot 233 | parse its '' header file. The option '-nodtk' can be used as a 234 | workaround. If GNU CC is not installed, it is therefore recommended to 235 | try 236 | 237 | ./configure CC="cc" 238 | 239 | and if that doesn't work, try 240 | 241 | ./configure CC="cc -nodtk" 242 | 243 | On Solaris, don't put '/usr/ucb' early in your 'PATH'. This 244 | directory contains several dysfunctional programs; working variants of 245 | these programs are available in '/usr/bin'. So, if you need '/usr/ucb' 246 | in your 'PATH', put it _after_ '/usr/bin'. 247 | 248 | On Haiku, software installed for all users goes in '/boot/common', 249 | not '/usr/local'. It is recommended to use the following options: 250 | 251 | ./configure --prefix=/boot/common 252 | 253 | Specifying the System Type 254 | ========================== 255 | 256 | There may be some features 'configure' cannot figure out 257 | automatically, but needs to determine by the type of machine the package 258 | will run on. Usually, assuming the package is built to be run on the 259 | _same_ architectures, 'configure' can figure that out, but if it prints 260 | a message saying it cannot guess the machine type, give it the 261 | '--build=TYPE' option. TYPE can either be a short name for the system 262 | type, such as 'sun4', or a canonical name which has the form: 263 | 264 | CPU-COMPANY-SYSTEM 265 | 266 | where SYSTEM can have one of these forms: 267 | 268 | OS 269 | KERNEL-OS 270 | 271 | See the file 'config.sub' for the possible values of each field. If 272 | 'config.sub' isn't included in this package, then this package doesn't 273 | need to know the machine type. 274 | 275 | If you are _building_ compiler tools for cross-compiling, you should 276 | use the option '--target=TYPE' to select the type of system they will 277 | produce code for. 278 | 279 | If you want to _use_ a cross compiler, that generates code for a 280 | platform different from the build platform, you should specify the 281 | "host" platform (i.e., that on which the generated programs will 282 | eventually be run) with '--host=TYPE'. 283 | 284 | Sharing Defaults 285 | ================ 286 | 287 | If you want to set default values for 'configure' scripts to share, 288 | you can create a site shell script called 'config.site' that gives 289 | default values for variables like 'CC', 'cache_file', and 'prefix'. 290 | 'configure' looks for 'PREFIX/share/config.site' if it exists, then 291 | 'PREFIX/etc/config.site' if it exists. Or, you can set the 292 | 'CONFIG_SITE' environment variable to the location of the site script. 293 | A warning: not all 'configure' scripts look for a site script. 294 | 295 | Defining Variables 296 | ================== 297 | 298 | Variables not defined in a site shell script can be set in the 299 | environment passed to 'configure'. However, some packages may run 300 | configure again during the build, and the customized values of these 301 | variables may be lost. In order to avoid this problem, you should set 302 | them in the 'configure' command line, using 'VAR=value'. For example: 303 | 304 | ./configure CC=/usr/local2/bin/gcc 305 | 306 | causes the specified 'gcc' to be used as the C compiler (unless it is 307 | overridden in the site shell script). 308 | 309 | Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an 310 | Autoconf limitation. Until the limitation is lifted, you can use this 311 | workaround: 312 | 313 | CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash 314 | 315 | 'configure' Invocation 316 | ====================== 317 | 318 | 'configure' recognizes the following options to control how it 319 | operates. 320 | 321 | '--help' 322 | '-h' 323 | Print a summary of all of the options to 'configure', and exit. 324 | 325 | '--help=short' 326 | '--help=recursive' 327 | Print a summary of the options unique to this package's 328 | 'configure', and exit. The 'short' variant lists options used only 329 | in the top level, while the 'recursive' variant lists options also 330 | present in any nested packages. 331 | 332 | '--version' 333 | '-V' 334 | Print the version of Autoconf used to generate the 'configure' 335 | script, and exit. 336 | 337 | '--cache-file=FILE' 338 | Enable the cache: use and save the results of the tests in FILE, 339 | traditionally 'config.cache'. FILE defaults to '/dev/null' to 340 | disable caching. 341 | 342 | '--config-cache' 343 | '-C' 344 | Alias for '--cache-file=config.cache'. 345 | 346 | '--quiet' 347 | '--silent' 348 | '-q' 349 | Do not print messages saying which checks are being made. To 350 | suppress all normal output, redirect it to '/dev/null' (any error 351 | messages will still be shown). 352 | 353 | '--srcdir=DIR' 354 | Look for the package's source code in directory DIR. Usually 355 | 'configure' can determine that directory automatically. 356 | 357 | '--prefix=DIR' 358 | Use DIR as the installation prefix. *note Installation Names:: for 359 | more details, including other options available for fine-tuning the 360 | installation locations. 361 | 362 | '--no-create' 363 | '-n' 364 | Run the configure checks, but stop before creating any output 365 | files. 366 | 367 | 'configure' also accepts some other, not widely useful, options. Run 368 | 'configure --help' for more details. 369 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | @SET_MAKE@ 2 | 3 | COFLAGS=-z+05:30 4 | ACLOCAL_AMFLAGS=-I m4 5 | 6 | DEFS=@DEFS@ -Wall -Dlint -fno-strict-aliasing -I/usr/include/qmail -I. 7 | 8 | INSTALL_PROGRAM = ${INSTALL} -c 9 | install_sh_PROGRAM = $(install_sh) -c 10 | INSTALL_SCRIPT = ${INSTALL} -c 11 | install_sh_SCRIPT = $(install_sh) -c 12 | INSTALL_STRIP_PROGRAM = $(install_sh) -c -s 13 | 14 | mpdevbindir=@prefix@/bin 15 | mpdevsbindir=@prefix@/sbin 16 | mpdevlibexecdir=@libexecdir@/mpdev 17 | mpdevsysconfdir=@sysconfdir@/mpdev 18 | 19 | mpdevbin_PROGRAMS = mpdev 20 | mpdevbin_SCRIPTS = librefm-scrobbler lastfm-scrobbler mpdplaylist \ 21 | transfer_play karma songi mpdhist 22 | mpdevlibexec_PROGRAMS = mpdev_cleanup mpdev_update 23 | mpdevlibexec_SCRIPTS = player playpause mpdev_rename output mixer create_service \ 24 | lcd_display 25 | noinst_DATA = mpdev.spec PKGBUILD 26 | man_MANS = mpdplaylist.1 mpdev.1 lastfm-scrobbler.1 librefm-scrobbler.1 \ 27 | mpdev_update.1 mpdev_cleanup.1 transfer_play.1 \ 28 | mpdev_rename.1 karma.1 songi.1 mpdhist.1 29 | mpdevsysconf_DATA=mpdev-release mpd_local.te 30 | doc_DATA=LICENSE moc-scrobbler-license mpdev.changes README.md 31 | 32 | MOSTLYCLEANFILES = mpdev player playpause librefm-scrobbler \ 33 | lastfm-scrobbler mpdplaylist choose \ 34 | create_service karma output mixer \ 35 | songi mpdhist lcd_display 36 | 37 | mpdev_SOURCES = mpdev.c 38 | mpdev_LDADD = $(LIB_QMAIL) 39 | 40 | mpdev_update_SOURCES = mpdev_update.c 41 | mpdev_update_LDADD = $(LIB_QMAIL) $(LIB_SQLITE3) 42 | 43 | mpdev_cleanup_SOURCES = mpdev_cleanup.c replacestr.c 44 | mpdev_cleanup_LDADD = $(LIB_QMAIL) $(LIB_SQLITE3) 45 | 46 | edit = sed \ 47 | -e 's}@PACKAGE\@}$(PACKAGE)}g' \ 48 | -e 's}@PACKAGE_VERSION\@}$(PACKAGE_VERSION)}g' \ 49 | -e 's}@version\@}$(VERSION)}g' \ 50 | -e "s|@release\@|"`cat conf-release`"|g" \ 51 | -e 's|@email\@|'"`cat conf-email`"'|g' \ 52 | -e 's}@pkgconfigdir\@}$(pkgconfigdir)}g' \ 53 | -e 's}@VERSION\@}$(VERSION)}g' \ 54 | -e 's}@sysconfdir\@}$(sysconfdir)}g' \ 55 | -e 's}@libexecdir\@}$(libexecdir)}g' \ 56 | -e 's}@mpdevlibexecdir\@}$(mpdevlibexecdir)}g' \ 57 | -e 's}@prefix\@}$(prefix)}g' 58 | 59 | editlastfm = sed \ 60 | -e 's}@name\@}lastfm}g' \ 61 | -e 's}@url\@}"last.fm"}g' 62 | 63 | editlibrefm = sed \ 64 | -e 's}@name\@}librefm}g' \ 65 | -e 's}@url\@}"libre.fm"}g' 66 | 67 | choose: choose.sh warn-auto.sh 68 | /bin/rm -f choose 69 | cat warn-auto.sh choose.sh > choose 70 | chmod 555 choose 71 | 72 | librefm-scrobbler: moc-scrobbler.in 73 | $(editlibrefm) moc-scrobbler.in > $@ 74 | chmod +x $@ 75 | 76 | lastfm-scrobbler: moc-scrobbler.in 77 | $(editlastfm) moc-scrobbler.in > $@ 78 | chmod +x $@ 79 | 80 | mpdplaylist: mpdplaylist.in 81 | $(edit) $@.in > $@ 82 | chmod +x $@ 83 | 84 | karma: karma.in 85 | $(edit) $@.in > $@ 86 | chmod +x $@ 87 | 88 | songi: songi.in 89 | $(edit) $@.in > $@ 90 | chmod +x $@ 91 | 92 | mpdhist: mpdhist.in 93 | $(edit) $@.in > $@ 94 | chmod +x $@ 95 | 96 | create_service: create_service.in 97 | $(edit) $@.in > $@ 98 | chmod +x $@ 99 | 100 | mpdev_rename: mpdev_rename.in 101 | $(edit) $@.in > $@ 102 | chmod +x $@ 103 | 104 | create_stats: create_stats.in 105 | $(edit) $@.in > $@ 106 | chmod +x $@ 107 | 108 | player: player.in 109 | $(edit) $@.in > $@ 110 | chmod +x $@ 111 | 112 | playpause: playpause.in 113 | $(edit) $@.in > $@ 114 | chmod +x $@ 115 | 116 | transfer_play: transfer_play.in 117 | $(edit) $@.in > $@ 118 | chmod +x $@ 119 | 120 | output: output.in 121 | $(edit) $@.in > $@ 122 | chmod +x $@ 123 | 124 | mixer: mixer.in 125 | $(edit) $@.in > $@ 126 | chmod +x $@ 127 | 128 | lcd_display: lcd_display.in 129 | $(edit) $@.in > $@ 130 | chmod +x $@ 131 | 132 | mpdev.spec: mpdev.spec.in catChangeLog doc/ChangeLog conf-version \ 133 | conf-release conf-email 134 | (cat $@.in;./catChangeLog) | $(edit) > $@ 135 | mpdev.changes: doc/ChangeLog conf-version conf-release conf-email 136 | ./catChangeLog --changes doc/ChangeLog > $@ 137 | PKGBUILD: PKGBUILD.in conf-email \ 138 | conf-version conf-release mpdev.changes 139 | cat $@.in | $(edit) > $@ 140 | -------------------------------------------------------------------------------- /PKGBUILD.in: -------------------------------------------------------------------------------- 1 | # Maintainer: @email@ 2 | pkgname=mpdev 3 | pkgver=@version@ 4 | pkgrel=@release@ 5 | pkgdesc="MPD Event Watcher" 6 | arch=('i686' 'x86_64') 7 | url="https://github.com/mbhangui/${pkgname}" 8 | license=('GPL3') 9 | groups=('base-devel') 10 | depends=('coreutils' 'findutils' 'sed' 'sqlite' 'libqmail') 11 | source=("$pkgname-${pkgver}.tar.gz") 12 | sha256sums=('SKIP') 13 | provides=("pkgname") 14 | options=('strip' '!libtool' 'docs' 'staticlibs' 'zipman' 'debug') 15 | backup=(etc/${pkgname}/${pkgname}-release) 16 | install=archpkg.install 17 | changelog=$pkgname.changes 18 | _prefix=@prefix@ 19 | _shareddir=@prefix@/share 20 | 21 | build() { 22 | cd $srcdir/$pkgname-${pkgver} 23 | ./configure --prefix=${_prefix} --sysconfdir=/etc/${pkgname} \ 24 | --libexecdir=${_prefix}/libexec/${pkgname} 25 | make -s 26 | } 27 | 28 | package() { 29 | depends=('shadow' 'daemontools' 'mpd') 30 | cd $srcdir/$pkgname-${pkgver} 31 | make DESTDIR=${pkgdir} install 32 | install -D -m 0644 ${pkgname}.changes "$pkgdir"${_shareddir}/doc/${pkgname}/${pkgname}.changes 33 | cd $srcdir 34 | } 35 | #### INSTALL SCRIPTS #### 36 | _prefix=@prefix@ 37 | _logdir=/var/log/svc 38 | 39 | post_install() { 40 | /usr/libexec/${pkgname}/create_service --servicedir=/service --user=1000 --add-service 41 | } 42 | 43 | pre_upgrade() { 44 | svc -d /service/${pkgname} 45 | } 46 | 47 | post_upgrade() { 48 | svc -d /service/${pkgname} 49 | } 50 | 51 | pre_remove() { 52 | svc -d /service/${pkgname} 53 | /usr/libexec/${pkgname}/create_service --servicedir=/service --del-service 54 | } 55 | 56 | post_remove() { 57 | log_dir=${_logdir}/${pkgname} 58 | [ "$log_dir" != "/" ] && %{__rm} -fr $log_dir 59 | } 60 | -------------------------------------------------------------------------------- /auto-ccld.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # WARNING: This file was auto-generated. Do not edit! 3 | CC='cc -Wall -O2 -DINET6 -fPIC -fno-strict-aliasing -I/usr/include/qmail' 4 | LD='cc -s -rdynamic' 5 | -------------------------------------------------------------------------------- /catChangeLog: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # $Log: catChangeLog,v $ 3 | # Revision 1.10 2021-03-25 08:33:21+05:30 Cprogrammer 4 | # use default changelog as doc/ChangeLog 5 | # 6 | # Revision 1.9 2021-03-25 08:28:06+05:30 Cprogrammer 7 | # create changelog for rpm, debian and obs 8 | # 9 | # Revision 1.8 2021-02-28 21:58:46+05:30 Cprogrammer 10 | # fixed catChangeLog 11 | # 12 | # Revision 1.7 2020-10-12 17:05:49+05:30 Cprogrammer 13 | # fixed date lines in ChangeLog 14 | # 15 | # Revision 1.6 2020-09-13 20:44:29+05:30 Cprogrammer 16 | # renamed ChangeLog-indimail to ChangeLog 17 | # 18 | # Revision 1.5 2020-06-05 23:36:37+05:30 Cprogrammer 19 | # changed ChangeLog filename 20 | # 21 | # Revision 1.4 2020-05-30 16:43:18+05:30 Cprogrammer 22 | # skip blank lines 23 | # 24 | # Revision 1.3 2020-05-24 12:02:18+05:30 Cprogrammer 25 | # fixed release number 26 | # 27 | # Revision 1.2 2020-05-21 14:38:34+05:30 Cprogrammer 28 | # fixed timestamp 29 | # 30 | # Revision 1.1 2019-05-29 00:47:06+05:30 Cprogrammer 31 | # Initial revision 32 | # 33 | # utility to append changelog to indimail.spec 34 | # 35 | # 36 | # $Id: catChangeLog,v 1.10 2021-03-25 08:33:21+05:30 Cprogrammer Exp mbhangui $ 37 | # 38 | option=1 39 | while test $# -gt 0; do 40 | case "$1" in 41 | -*=*) 42 | optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` 43 | ;; 44 | *) 45 | optarg="" 46 | ;; 47 | esac 48 | 49 | valid=0 50 | case "$1" in 51 | --spec) 52 | option=1 53 | valid=1 54 | ;; 55 | --debian) 56 | option=2 57 | valid=1 58 | ;; 59 | --changes) 60 | option=3 61 | valid=1 62 | ;; 63 | --email=*) 64 | email=$optarg 65 | valid=1 66 | ;; 67 | --version=*) 68 | version=$optarg 69 | valid=1 70 | ;; 71 | --release=*) 72 | release=$optarg 73 | valid=1 74 | ;; 75 | --name=*) 76 | name=$optarg 77 | valid=1; 78 | ;; 79 | --state=*) 80 | state=$optarg 81 | valid=1; 82 | ;; 83 | --urgency=*) 84 | urgency=$optarg 85 | valid=1; 86 | ;; 87 | *) 88 | if [ -n "$optarg" ] ; then 89 | echo "invalid option [$1]" 1>&2 90 | exit 1 91 | fi 92 | ;; 93 | esac 94 | if [ $valid -eq 0 ] ; then 95 | break 96 | fi 97 | shift 98 | done 99 | if [ $# -eq 0 ] ; then 100 | file=doc/ChangeLog 101 | else 102 | file=$1 103 | fi 104 | if [ $option -eq 2 ] ; then 105 | if [ -z "$name" -o -z "$state" -o -z "$urgency" ] ; then 106 | echo "you have to give --name --state --urgency options" 1>&1 107 | fi 108 | fi 109 | if [ -z "$version" ] ; then 110 | if [ -f conf-version ] ; then 111 | version=$(cat conf-version) 112 | elif [ -f ../conf-version ] ; then 113 | version=$(cat ../conf-version) 114 | fi 115 | fi 116 | if [ -z "$release" ] ; then 117 | if [ -f conf-release ] ; then 118 | release=$(cat conf-release) 119 | elif [ -f ../conf-release ] ; then 120 | release=$(cat ../conf-release) 121 | fi 122 | fi 123 | if [ -z "$email" ] ; then 124 | if [ -f conf-email ] ; then 125 | email=$(cat conf-email) 126 | elif [ -f ../conf-email ] ; then 127 | email=$(cat ../conf-email) 128 | fi 129 | fi 130 | 131 | flag=0 132 | nonewline=0 133 | bullet=0 134 | highlights=0 135 | exec 0<$file 136 | while read line 137 | do 138 | echo "$line"|grep "^*" > /dev/null 139 | status=$? 140 | if [ $status -eq 0 -a $flag -ne 0 ] ; then 141 | break 142 | fi 143 | if [ $status -ne 0 -a $flag -eq 0 ] ; then 144 | continue 145 | fi 146 | echo "$line" | grep "^- [0-9]*/.*/.*" > /dev/null # skip dates 147 | if [ $? -eq 0 ] ; then 148 | continue 149 | fi 150 | if [ $flag -eq 0 ] ; then # first line 151 | flag=1 152 | if [ $option -eq 1 ] ; then 153 | echo "* `date -u +"%a %b %d %Y %H:%M:%S %z"` $email" "$version"-"$release"%{?dist} 154 | elif [ $option -eq 2 ] ; then 155 | echo "$name ($version-$release) $state; urgency=$urgency" 156 | echo 157 | elif [ $option -eq 3 ] ; then 158 | printf "%0*d\n" 67 |sed 's}0}-}g' 159 | date "+%a, %b %d %H:%M:%S %Z %Y - $email" 160 | echo 161 | fi 162 | continue 163 | elif [ $flag -eq 1 ] ; then # second line 164 | if [ $option -eq 1 ] ; then 165 | echo "$line" | sed -e "s|@version\@|$version|g" -e "s|@release\@|$release|g" 166 | fi 167 | flag=2 168 | continue 169 | fi 170 | echo $line | grep -E "^o " > /dev/null 171 | if [ $? -eq 0 ] ; then 172 | bullet=1 173 | else 174 | bullet=0 175 | fi 176 | echo "$line" |grep -E "^[0-9]|^[0-9][0-9]|^[0-9][0-9][0-9]" > /dev/null 177 | if [ $? -eq 0 ] ; then 178 | if [ $option -eq 2 -a $nonewline -eq 1 ] ; then 179 | echo 180 | fi 181 | nonewline=0 182 | if [ $option -eq 1 -o $option -eq 3 ] ; then 183 | set $line 184 | shift 185 | echo "- $*" 186 | elif [ $option -eq 2 ] ; then 187 | set $line 188 | shift 189 | nonewline=1 190 | echo -n " * $*" 191 | fi 192 | elif [ -n "$line" ] ; then 193 | if [ $highlights -eq 0 ] ; then 194 | nonewline=0 195 | echo "$line" | grep "Release Highlights" >/dev/null 196 | if [ $? -eq 0 ] ; then 197 | highlights=1 198 | if [ $option -eq 3 ] ; then 199 | echo $line 200 | fi 201 | continue 202 | fi 203 | fi 204 | if [ $highlights -eq 1 ] ; then 205 | echo "$line" | grep "^====" >/dev/null 206 | if [ $? -eq 0 ] ; then 207 | highlights=2 208 | if [ $option -ne 3 ] ; then 209 | continue 210 | fi 211 | if [ $nonewline -eq 1 ] ; then 212 | echo 213 | nonewline=0 214 | fi 215 | echo $line 216 | continue 217 | fi 218 | fi 219 | if [ $highlights -eq 1 ] ; then 220 | if [ $option -ne 3 ] ; then 221 | continue 222 | fi 223 | if [ $bullet -eq 1 ] ; then 224 | if [ $nonewline -eq 1 ] ; then 225 | echo "" 226 | nonewline=0 227 | fi 228 | echo "$line" 229 | bullet=0 230 | else 231 | if [ $nonewline -eq 1 ] ; then 232 | echo "" 233 | nonewline=0 234 | fi 235 | echo -n " $line" 236 | nonewline=1 237 | fi 238 | continue 239 | fi 240 | if [ $option -eq 1 -o $option -eq 3 ] ; then 241 | echo " $line" 242 | elif [ $option -eq 2 ] ; then 243 | echo -n " $line" 244 | nonewline=1 245 | fi 246 | fi 247 | done 248 | if [ $option -eq 2 ] ; then 249 | if [ $nonewline -eq 1 ] ; then 250 | echo 251 | fi 252 | echo 253 | echo " -- $email `date -u +'%a, %d %b %Y %H:%M:%S %z'`" 254 | elif [ $option -eq 3 ] ; then 255 | if [ $nonewline -eq 1 ] ; then 256 | echo 257 | fi 258 | fi 259 | -------------------------------------------------------------------------------- /choose.sh: -------------------------------------------------------------------------------- 1 | 2 | result="$4" 3 | 4 | case "$1" in 5 | *c*) ./compile $2.c >/dev/null 2>&1 || result="$3" ;; 6 | esac 7 | 8 | case "$1" in 9 | *l*) ./load $2 >/dev/null 2>&1 || result="$3" ;; 10 | esac 11 | 12 | case "$1" in 13 | *r*) ./$2 >/dev/null 2>&1 || result="$3" ;; 14 | esac 15 | 16 | case "$1" in 17 | *R*) ./$2 >/dev/null 2>&1 || result="$3" ;; 18 | esac 19 | 20 | case "$1" in 21 | *c* | *l* | *L* | *r*) rm -f $2.o $2 ;; 22 | esac 23 | 24 | exec cat "$result" 25 | -------------------------------------------------------------------------------- /conf-email: -------------------------------------------------------------------------------- 1 | Manvendra Bhangui 2 | -------------------------------------------------------------------------------- /conf-ip: -------------------------------------------------------------------------------- 1 | -DIPV6 2 | -------------------------------------------------------------------------------- /conf-ld: -------------------------------------------------------------------------------- 1 | cc -s -rdynamic 2 | 3 | This will be used to link .o files into an executable. 4 | -------------------------------------------------------------------------------- /conf-version: -------------------------------------------------------------------------------- 1 | 1.0 2 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ([2.69]) 5 | AC_INIT([mpdev],[m4_normalize(m4_include(conf-version))],[m4_normalize(m4_include(conf-email))],[mpdev],[https://github.com/mbhangui/mpdev]) 6 | AC_CONFIG_SRCDIR([mpdev.c]) 7 | AC_CONFIG_HEADERS([config.h]) 8 | AC_CANONICAL_HOST 9 | AC_DEFINE_UNQUOTED(PACKAGE_BUGREPORT, "indimail-support@lists.sourceforge.net") 10 | PACKAGE=$PACKAGE_NAME 11 | VERSION=$PACKAGE_VERSION 12 | AM_INIT_AUTOMAKE([foreign]) 13 | 14 | # Checks for programs. 15 | AC_PROG_CC 16 | LT_INIT 17 | AC_PROG_LN_S 18 | AC_PROG_AWK 19 | AC_PROG_INSTALL 20 | AC_CONFIG_MACRO_DIR([m4]) 21 | AC_PROG_MAKE_SET 22 | 23 | case "$host" in 24 | *-*-sunos4.1.1*) 25 | CPPFLAGS="$CPPFLAGS -DSUNOS4" 26 | CFLAGS="$CFLAGS -O4 -Wall -fPIC" 27 | CXXFLAGS="$CXXFLAGS -O4 -Wall -fPIC" 28 | ;; 29 | *-*-solaris*) 30 | CPPFLAGS="$CPPFLAGS -DSOLARIS" 31 | CFLAGS="$CFLAGS -O4 -Wall -fPIC" 32 | CXXFLAGS="$CXXFLAGS -O4 -Wall -fPIC" 33 | ;; 34 | *-*-linux*) 35 | CPPFLAGS="$CPPFLAGS -DLINUX" 36 | CFLAGS="$CFLAGS -O4 -Wall -fPIC" 37 | CXXFLAGS="$CXXFLAGS -DLINUX -O4 -Wno-delete-non-virtual-dtor -Wno-reorder -Wall -fPIC" 38 | LDFLAGS="$LDFLAGS -pie" 39 | ;; 40 | *-*-freebsd*) 41 | CPPFLAGS="$CPPFLAGS -DFREEBSD -I/usr/local/include" 42 | CFLAGS="$CFLAGS -I/usr/local/include -I/usr/local/include/qmail -Wall" 43 | CXXFLAGS="$CXXFLAGS -DFREEBSD -I/usr/local/include -Wall -fPIC" 44 | CXXFLAGS="$CXXFLAGS -Wno-delete-non-virtual-dtor -Wno-deprecated-register -Wno-reorder" 45 | CXXFLAGS="$CXXFLAGS -Wno-delete-non-abstract-non-virtual-dtor" 46 | LDFLAGS="$LDFLAGS -L/usr/local/lib" 47 | ;; 48 | *-*-darwin*) 49 | CPPFLAGS="$CPPFLAGS -DDARWIN -I/opt/local/include" 50 | CFLAGS="$CFLAGS -I/opt/local/include -I/usr/local/include -I/opt/local/include/qmail -Wall" 51 | CXXFLAGS="$CXXFLAGS -DDARWIN -Wall -fPIC" 52 | CXXFLAGS="$CXXFLAGS -DBIND_8_COMPAT -I/opt/local/include -Wno-c++11-extensions" 53 | CXXFLAGS="$CXXFLAGS -Wno-delete-non-virtual-dtor -Wno-reorder-ctor -Wno-reorder" 54 | LDFLAGS="$LDFLAGS -L/opt/local/lib -L/usr/local/lib" 55 | ;; 56 | *) 57 | CFLAGS="$CFLAGS -O4 -Wall -fPIC" 58 | CXXFLAGS="$CXXFLAGS -O4 -Wall -fPIC" 59 | ;; 60 | esac 61 | 62 | # Checks for libraries. 63 | AC_CHECK_LIB(qmail, substdio_fdbuf, [AC_SUBST([LIB_QMAIL], ["-lqmail"]) AC_DEFINE([HAVE_QMAIL], [1],[qmail Library])],noqmail=t,) 64 | if test " $noqmail" = " t" 65 | then 66 | AC_MSG_ERROR(Could not find qmail library.) 67 | fi 68 | AC_CHECK_LIB(sqlite3, sqlite3_libversion, [AC_SUBST([LIB_SQLITE3], ["-lsqlite3"]) AC_DEFINE([HAVE_SQLITE3], [1],[sqlite3 Library])],nosqlite3=t,) 69 | if test " $nosqlite3" = " t" 70 | then 71 | AC_MSG_ERROR(Could not find sqlite3 library.) 72 | fi 73 | 74 | # Checks for header files. 75 | AC_CHECK_HEADERS([string.h unistd.h errno.h fcntl.h time.h sys/time.h stdlib.h sys/types.h sys/stat.h]) 76 | AC_CHECK_HEADERS([limits.h stdarg.h stdint.h stdbool.h sys/param.h dlfcn.h link.h]) 77 | 78 | # Checks for typedefs, structures, and compiler characteristics. 79 | AC_TYPE_SSIZE_T 80 | 81 | # Checks for library functions. 82 | AC_CHECK_FUNCS([alarm]) 83 | 84 | AC_CONFIG_FILES([Makefile]) 85 | AC_CONFIG_FILES([mpdev-release:mpdev-release.in],[], []) 86 | AC_OUTPUT 87 | -------------------------------------------------------------------------------- /create_archpkg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # $Log: $ 3 | # 4 | # $Id: $ 5 | # 6 | curdir=`pwd` 7 | version=$(cat conf-version) 8 | name=$(basename $curdir|sed -e 's{-x{{g') 9 | if [ ! -f /etc/arch-release ] ; then 10 | echo "you can't make arch package on a non Arch Linux system" 1>&2 11 | exit 1 12 | fi 13 | 14 | verbose=0 15 | release=1 16 | clean=0 17 | while test $# -gt 0; do 18 | case "$1" in 19 | -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` 20 | ;; 21 | *) optarg= 22 | ;; 23 | esac 24 | 25 | case "$1" in 26 | --verbose) 27 | verbose=1 28 | ;; 29 | --release=*) 30 | release=$optarg 31 | ;; 32 | --clean) 33 | clean=1 34 | ;; 35 | *) 36 | echo "invalid option [$1]" 37 | read key 38 | usage 1 39 | ;; 40 | esac 41 | 42 | shift 43 | done 44 | 45 | copy_src=0 46 | meta_pkg=0 47 | echo -n "Copy Source Files - " 48 | read key 49 | if [ " $key" = " y" -o " $key" = " Y" ] ; then 50 | copy_src=1 51 | fi 52 | 53 | pkg_dir=$HOME/stage/arch/$name 54 | mkdir -p $pkg_dir 55 | if [ $copy_src -eq 1 ] ; then 56 | if [ -f $name.packages ] ; then 57 | meta_pkg=1 58 | for dir in `cat $name.packages` 59 | do 60 | real_dir=$(basename $dir) 61 | echo $dir|grep "/" >/dev/null 62 | if [ $? -eq 0 ] ; then 63 | pkg_name=$(basename $dir|sed -e 's{-x{{g') 64 | else 65 | pkg_name=$(echo $dir|sed -e 's{-x{{g') 66 | fi 67 | if [ -d $dir ] ; then 68 | cd $dir 69 | else 70 | echo "$dir: No such file or directory" 1>&2 71 | exit 1 72 | fi 73 | ver=$(cat conf-version) 74 | if [ -z "$ver" ] ; then 75 | echo "no version found for package $pkg_name" 1>&2 76 | exit 1 77 | fi 78 | STAGE=$HOME/stage/arch/$pkg_name-$ver 79 | echo Preparing $pkg_name-$ver 80 | cp -rpf . $STAGE 81 | if [ ! -L $HOME/stage/arch/$real_dir ] ; then 82 | ln -sr $STAGE $HOME/stage/arch/$real_dir 83 | fi 84 | cd $STAGE 85 | echo "Cleaning stage before making a tar archive" 86 | make -s clean >/dev/null 2>&1 87 | make -s distclean >/dev/null 2>&1 88 | /bin/rm -rf autom4te.cache .deps 89 | cd $HOME/stage/arch 90 | echo "Archiving $pkg_name-"$ver".tar.gz in `pwd`" 91 | tar \ 92 | --exclude="$pkg_name-$ver/.git" \ 93 | --exclude="$pkg_name-$ver/debian" \ 94 | --exclude="$pkg_name-$ver/RCS" \ 95 | -cf - $pkg_name-"$ver" \ 96 | | gzip -c > $pkg_dir/$pkg_name-"$ver".tar.gz 97 | cd $curdir 98 | done 99 | fi 100 | 101 | STAGE=$HOME/stage/arch/$name-$version 102 | /bin/rm -rf $STAGE 103 | cp -rpf $curdir $STAGE 104 | /bin/rm -f $STAGE/catChangeLog 105 | /bin/cp catChangeLog $STAGE/catChangeLog 106 | cd $STAGE 107 | make -s PKGBUILD 108 | if [ $? -ne 0 ] ; then 109 | echo "make failed" 1>&2 110 | exit 1 111 | fi 112 | cp PKGBUILD $name.changes $pkg_dir 113 | if [ -f extra_src ] ; then 114 | cp -rpf `grep -h -v "^#" extra_src` $pkg_dir 115 | fi 116 | total=$(grep "#### INSTALL.* ####" PKGBUILD | wc -l) 117 | echo "Total scripts in PKGBUILD=$total" 118 | if [ $total -le 1 ] ; then 119 | echo "Creating archpkg.install" 120 | sed -n '/#### INSTALL SCRIPTS ####/,$p' PKGBUILD \ 121 | | grep -v "^####" > $pkg_dir/archpkg.install 122 | if [ ! -s $pkg_dir/archpkg.install ] ; then 123 | rm -f $pkg_dir/archpkg.install 124 | fi 125 | else 126 | count=1 127 | while true 128 | do 129 | echo "Creating archpkg"$count".install" 130 | sed -n "/#### INSTALL$count SCRIPTS ####/,\$p" PKGBUILD \ 131 | | grep -v "^####" > $pkg_dir/archpkg$count.install 132 | if [ ! -s $pkg_dir/archpkg$count.install ] ; then 133 | rm -f $pkg_dir/archpkg$count.install 134 | fi 135 | if [ $count -eq $total ] ; then 136 | break 137 | fi 138 | count=$(expr $count + 1) 139 | done 140 | fi 141 | if [ $meta_pkg -eq 0 ] ; then 142 | ## tar the main package 143 | echo "Cleaning stage before making a tar archive" 144 | make -s clean >/dev/null 2>&1 145 | make -s distclean >/dev/null 2>&1 146 | /bin/rm -rf autom4te.cache .deps 147 | cd $HOME/stage/arch 148 | echo "Archiving $name-"$version".tar.gz in `pwd`" 149 | tar \ 150 | --exclude="$name-$version/.git" \ 151 | --exclude="$name-$version/debian" \ 152 | --exclude="$name-$version/RCS" \ 153 | -cf - $name-"$version" \ 154 | | gzip -c > $pkg_dir/$name-"$version".tar.gz 155 | fi 156 | /bin/rm -rf $STAGE 157 | fi 158 | echo -n "Build Arch Package for $name-"$version"-1."$release" (Y/N) - " 159 | read key 160 | if [ " $key" = " Y" -o " $key" = " y" ] ; then 161 | cd $curdir 162 | tmprel=`cat conf-release 2>/dev/null` 163 | if [ ! " $tmprel" = " 1.$release" ] ; then 164 | sed -i -e "s|^pkgrel=.*|pkgrel=1.$release|g" $pkg_dir/PKGBUILD 165 | fi 166 | cd $pkg_dir 167 | if [ $clean -eq 1 ] ; then 168 | makepkg -sf --clean 169 | else 170 | makepkg -sf 171 | fi 172 | mv *.zst $HOME/stage/arch 173 | fi 174 | echo -n "Remove Source (Y/N) - " 175 | read key 176 | if [ " $key" = " Y" -o " $key" = " y" ] ; then 177 | /bin/rm -rf $pkg_dir 178 | fi 179 | -------------------------------------------------------------------------------- /create_debian: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # $Log: create_debian,v $ 4 | # Revision 1.1 2020-07-19 18:18:21+05:30 Cprogrammer 5 | # Initial revision 6 | # 7 | # 8 | # $Id: create_debian,v 1.1 2020-07-19 18:18:21+05:30 Cprogrammer Exp mbhangui $ 9 | # 10 | if [ ! -f /etc/debian_version ] ; then 11 | echo "Not a debian or ubuntu distribution" 1>&2 12 | exit 1 13 | fi 14 | make -s -C debian 15 | mpdev_version=$(cat conf-version) 16 | /bin/rm -rf $HOME/stage/mpdev 17 | mkdir -p $HOME/stage/mpdev-$mpdev_version 18 | cp -rp . $HOME/stage/mpdev-$mpdev_version 19 | cd $HOME/stage/mpdev-$mpdev_version 20 | dpkg-buildpackage -tc -b -d 21 | /bin/rm -rf $HOME/stage/mpdev-$mpdev_version 22 | ls -lt $HOME/stage 23 | -------------------------------------------------------------------------------- /create_rpm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # $Log: create_rpm,v $ 4 | # Revision 1.5 2022-05-10 21:30:47+05:30 Cprogrammer 5 | # added --clean option 6 | # 7 | # Revision 1.4 2020-08-10 12:03:41+05:30 Cprogrammer 8 | # fixed cwd 9 | # 10 | # Revision 1.3 2020-08-10 11:54:17+05:30 Cprogrammer 11 | # added comments to indicate cwd 12 | # 13 | # Revision 1.2 2020-07-28 12:40:27+05:30 Cprogrammer 14 | # remove misc from source archive 15 | # 16 | # Revision 1.1 2020-07-19 18:17:22+05:30 Cprogrammer 17 | # Initial revision 18 | # 19 | # 20 | # $Id: create_rpm,v 1.5 2022-05-10 21:30:47+05:30 Cprogrammer Exp mbhangui $ 21 | # 22 | version=$(cat conf-version) 23 | 24 | verbose=0 25 | while test $# -gt 0; do 26 | case "$1" in 27 | -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` 28 | ;; 29 | *) optarg= 30 | ;; 31 | esac 32 | 33 | case "$1" in 34 | --verbose) 35 | verbose=1 36 | ;; 37 | --clean) 38 | clean="--clean" 39 | ;; 40 | --release=*) 41 | release=$optarg 42 | ;; 43 | *) 44 | echo "invalid option [$1]" 45 | read key 46 | usage 1 47 | ;; 48 | esac 49 | 50 | shift 51 | done 52 | 53 | if test -f $HOME/.rpmmacros 54 | then 55 | topdir=`grep ^%_topdir $HOME/.rpmmacros | awk '{print $2}'` 56 | if test -n "$topdir" 57 | then 58 | rpmbuild=$topdir 59 | else 60 | rpmbuild=$HOME/rpmbuild 61 | fi 62 | else 63 | rpmbuild=$HOME/rpmbuild 64 | fi 65 | 66 | copy_src=0 67 | echo -n "Copy Source Files - " 68 | read key 69 | if [ " $key" = " y" -o " $key" = " Y" ] ; then 70 | copy_src=1 71 | fi 72 | 73 | make -s mpdev.spec 74 | if [ $? -ne 0 ] ; then 75 | echo "make failed" 1>&2 76 | exit 0 77 | fi 78 | 79 | if [ $copy_src -eq 1 ] ; then 80 | if [ ! -d ../stage ] ; then 81 | mkdir ../stage 82 | fi 83 | if [ $? -ne 0 ] ; then 84 | exit 1 85 | fi 86 | # /usr/local/src 87 | cd .. 88 | echo "Preparing mpdev-"$version"" 89 | /bin/cp -rp mpdev stage/mpdev-"$version" 90 | # /usr/local/src/stage/mpdev-$version 91 | cd stage/mpdev-$version 92 | echo "Cleaning mpdev-"$version"" 93 | make -s clean >/dev/null 2>&1 94 | make -s distclean >/dev/null 2>&1 95 | /bin/rm -rf autom4te.cache .deps src/config.log 96 | # /usr/local/src/stage/ 97 | cd .. 98 | echo "Archiving mpdev-"$version".tar.gz in `pwd`" 99 | tar \ 100 | --exclude="mpdev-$version/.git" \ 101 | --exclude="mpdev-$version/debian" \ 102 | --exclude="mpdev-$version/misc" \ 103 | --exclude="mpdev-$version/RCS" \ 104 | -cf - mpdev-"$version" \ 105 | | gzip -c > $rpmbuild/SOURCES/mpdev-"$version".tar.gz 106 | /bin/rm -rf mpdev-"$version" 107 | fi 108 | 109 | dist=`uname -r |cut -d . -f4` 110 | if [ -z "$release" ] ; then 111 | if [ -f /usr/bin/mpdev ] ; then 112 | mdist=$(rpm -qf /usr/bin/mpdev|cut -d- -f3|cut -d. -f3) 113 | if [ " $dist" = " $mdist" ] ; then 114 | mversion=$(rpm -qf /usr/bin/mpdev|cut -d- -f2) 115 | if [ "$mversion" = "$version" ] ; then 116 | release=$(rpm -qf /usr/bin/mpdev | cut -d- -f3 | cut -d. -f2) 117 | release=$(expr $release + 1) 118 | else 119 | release=1 120 | fi 121 | else 122 | release=1 123 | fi 124 | else 125 | release=1 126 | fi 127 | fi 128 | 129 | # /usr/local/src/ 130 | cd .. 131 | echo -n "Build RPM for mpdev-"$version"-1."$release" (Y/N) - " 132 | read key 133 | if [ " $key" = " Y" -o " $key" = " y" ] ; then 134 | tmprel=`cat mpdev/conf-release 2>/dev/null` 135 | if [ ! " $tmprel" = " 1.$release" ] ; then 136 | cd mpdev 137 | echo 1.$release > conf-release 138 | make -s mpdev.spec 139 | cp mpdev.spec /tmp 140 | make -C debian -s 141 | cd ../.. 142 | else 143 | cp mpdev/mpdev.spec /tmp 144 | fi 145 | build_arch=`rpmbuild --showrc|grep "^build arch" | awk '{print $4}'` 146 | if [ $verbose -eq 0 ] ; then 147 | echo "rpmbuild -ba $clean --quiet /tmp/mpdev.spec" 148 | rpmbuild -ba $clean --quiet /tmp/mpdev.spec 149 | else 150 | echo "rpmbuild -ba $clean --quiet /tmp/mpdev.spec" 151 | rpmbuild -ba $clean /tmp/mpdev.spec 152 | fi 153 | if [ $? -eq 0 ] ; then 154 | /bin/rm /tmp/mpdev.spec 155 | rpm --addsign $rpmbuild/RPMS/$build_arch/mpdev-"$version"-"1.$release".$dist.$build_arch.rpm 156 | echo -n "RPM lint for mpdev-"$version"-1."$release" (Y/N) - " 157 | read key 158 | if [ " $key" = " Y" -o " $key" = " y" ] ; then 159 | ( 160 | echo mpdev 161 | rpmlint $rpmbuild/RPMS/$build_arch/mpdev-"$version"-"1.$release".$dist.$build_arch.rpm 162 | echo ------------------------ 163 | echo mpdev-"$version"-"1.$release".$dist.src.rpm 164 | rpmlint $rpmbuild/SRPMS/mpdev-"$version"-"1.$release".$dist.src.rpm 165 | echo ------------------------ 166 | ) 2>&1 | less 167 | fi 168 | else 169 | /bin/rm /tmp/mpdev.spec 170 | fi 171 | else 172 | /bin/rm -rf /tmp/mpdev-"$version" 173 | fi 174 | 175 | if [ $copy_src -eq 1 ] ; then 176 | echo -n "Remove Source (Y/N) - " 177 | read key 178 | if [ " $key" = " Y" -o " $key" = " y" ] ; then 179 | /bin/rm -f $rpmbuild/SOURCES/mpdev-"$version".tar.gz 180 | fi 181 | fi 182 | -------------------------------------------------------------------------------- /create_service.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # $Id: create_service.in,v 1.30 2025-01-17 11:55:20+05:30 Cprogrammer Exp mbhangui $ 4 | # 5 | 6 | check_update_if_diff() 7 | { 8 | val=`cat $1 2>/dev/null` 9 | if [ ! " $val" = " $2" ] ; then 10 | echo $2 > $1 11 | fi 12 | } 13 | 14 | add_service() 15 | { 16 | if [ $# -ne 1 ] ; then 17 | echo "USAGE: create_service --servicedir=path --user=username \\" 18 | echo " --lcdhost=host --lcdport=port || --lcdfifo=fifo \\" 19 | echo " --add-service" 1>&2 20 | return 1 21 | fi 22 | userid=$1 23 | case "$SYSTEM" in 24 | Linux) 25 | user=$(getent passwd $userid 2>/dev/null| cut -d: -f1) 26 | if [ $? -ne 0 ] ; then 27 | if [ $? -eq 2 ] ; then 28 | echo "No such userid $userid" 1>&2 29 | return 1 30 | fi 31 | return 1 32 | fi 33 | ;; 34 | Darwin) 35 | user=$(dscl . -list /Users UniqueID|grep -w $userid|awk '{print $1}') 36 | if [ -z "$user" ] ; then 37 | echo "No such userid $userid" 1>&2 38 | return 1 39 | fi 40 | ;; 41 | *) 42 | echo "Configure/setup startup manually" 1>&2 43 | exit 1 44 | ;; 45 | esac 46 | if [ -z "$servicedir" ] ; then 47 | echo "--servicedir not specified" 1>&2 48 | exit 1 49 | fi 50 | if [ ! -d $logdir ] ; then 51 | mkdir -p $logdir 52 | chown qmaill:nofiles $logdir 53 | fi 54 | mkdir -p $servicedir/$service_name/log 55 | mkdir -p $servicedir/$service_name/variables 56 | echo "$prog_args" > $servicedir/$service_name/variables/.options 57 | if [ ! -f $servicedir/$service_name/variables/NO_DB_UPDATE ] ; then 58 | > $servicedir/$service_name/variables/NO_DB_UPDATE 59 | fi 60 | check_update_if_diff $servicedir/$service_name/variables/AUTO_RATING 0 61 | check_update_if_diff $servicedir/$service_name/variables/MPD_HOST 127.0.0.1 62 | check_update_if_diff $servicedir/$service_name/variables/MPD_PORT 6600 63 | if [ -n "$lcdfifo" ] ; then 64 | > $servicedir/$service_name/variables/LCD_HOST 65 | > $servicedir/$service_name/variables/LCD_PORT 66 | check_update_if_diff $servicedir/$service_name/variables/LCD_FIFO $lcdfifo 67 | elif [ -n "$lcdhost" -a -n "$lcdport" ] ; then 68 | > $servicedir/$service_name/variables/LCD_FIFO 69 | check_update_if_diff $servicedir/$service_name/variables/LCD_HOST $lcdhost 70 | check_update_if_diff $servicedir/$service_name/variables/LCD_PORT $lcdport 71 | else 72 | > $servicedir/$service_name/variables/LCD_FIFO 73 | > $servicedir/$service_name/variables/LCD_HOST 74 | > $servicedir/$service_name/variables/LCD_PORT 75 | fi 76 | check_update_if_diff $servicedir/$service_name/variables/MPDEV_TMPDIR "/tmp/mpdev" 77 | sock=$(grep "^bind_to_address" @sysconfdir@/mpd.conf | grep sock|awk '{print $2}'|sed 's{"{{g') 78 | if [ -n "$sock" ] ; then 79 | check_update_if_diff $servicedir/$service_name/variables/MPD_SOCKET $sock 80 | elif [ -S /run/mpd/mpd.sock ] ; then 81 | check_update_if_diff $servicedir/$service_name/variables/MPD_SOCKET "/run/mpd/mpd.sock" 82 | fi 83 | case "$SYSTEM" in 84 | Linux) 85 | home=$(getent passwd $user|cut -d: -f6) 86 | ;; 87 | Darwin) 88 | home=$(dscl . -list /Users NFSHomeDirectory|grep $user|awk '{print $2}') 89 | ;; 90 | esac 91 | if [ -n "$home" ] ; then 92 | check_update_if_diff $servicedir/$service_name/variables/PATH "/bin:/usr/bin:@prefix@/bin:$home/.mpdev:/usr/local/bin:/opt/local/bin" 93 | check_update_if_diff $servicedir/$service_name/variables/HOME "$home" 94 | if [ "$SYSTEM" = "Linux" ] ; then 95 | t_uid=$(getent passwd $user|cut -d: -f3) 96 | check_update_if_diff $servicedir/$service_name/variables/XDG_RUNTIME_DIR "/run/user/$t_uid" 97 | fi 98 | fi 99 | mkdir -p $home/.mpdev 100 | for i in player playpause output mixer lcd_display 101 | do 102 | if [ ! -f $home/.mpdev/$i ] ; then 103 | cp @mpdevlibexecdir@/$i $home/.mpdev 104 | elif [ ! -f $home/.mpdev/."$i".nooverwrite ] ; then 105 | cp @mpdevlibexecdir@/$i $home/.mpdev 106 | fi 107 | done 108 | case "$SYSTEM" in 109 | Linux) 110 | t_uid=$(getent passwd $user|cut -d: -f3) 111 | t_gid=$(getent passwd $user|cut -d: -f4) 112 | ;; 113 | Darwin) 114 | t_uid=$(dscl . -read /Users/$user UniqueID|cut -d: -f2|sed 's{ {{g') 115 | t_gid=$(dscl . -read /Users/$user PrimaryGroupID|cut -d: -f2|sed 's{ {{g') 116 | ;; 117 | esac 118 | chown -R $t_uid:$t_gid $home/.mpdev 119 | 120 | ( 121 | echo "#!/bin/sh" 122 | echo "# generated log script for $host on `date`" 123 | echo "# by the below command" 124 | echo "# $prog_args" 125 | echo "exec @prefix@/bin/setuidgid qmaill \\" 126 | if [ -f @prefix@/sbin/multilog ] ; then 127 | echo "@prefix@/sbin/multilog t $logdir/$service_name" 128 | else 129 | echo "@prefix@/bin/multilog t $logdir/$service_name" 130 | fi 131 | ) > /service/$service_name/log/run 132 | chmod +x /service/$service_name/log/run 133 | ( 134 | echo "#!/bin/sh" 135 | echo "# generated run script for $host on `date`" 136 | echo "# by the below command" 137 | echo "# $prog_args" 138 | echo "exec 2>&1" 139 | echo 140 | echo "user=$user" 141 | echo "home=$home" 142 | echo 143 | echo "for i in lastfm librefm" 144 | echo "do" 145 | echo " echo \"clearing \$i status\"" 146 | echo " @prefix@/bin/setuidgid \$user @prefix@/bin/envdir \\" 147 | echo " variables @prefix@/bin/\$i-scrobbler --stop" 148 | echo " find \$home/.config/\$i-scrobbler -name '*'.log -ctime +7 -exec /bin/rm -f {} \;" 149 | echo "done" 150 | echo "for i in player playpause output mixer" 151 | echo "do" 152 | echo " if [ -f \$home/.mpdev/.\$i.nooverwrite ] ; then" 153 | echo " continue" 154 | echo " fi" 155 | echo " diff @mpdevlibexecdir@/\$i \$home/.mpdev/\$i > /dev/null 2>&1" 156 | echo " if [ \$? -ne 0 ] ; then" 157 | echo " cp @mpdevlibexecdir@/\$i \$home/.mpdev/\$i" 158 | echo " fi" 159 | echo "done" 160 | echo "exec @prefix@/bin/setuidgid -s \$user @prefix@/bin/envdir \\" 161 | echo " variables @prefix@/bin/mpdev -v" 162 | ) > /service/$service_name/run 163 | chmod +x /service/$service_name/run 164 | ( 165 | echo "#!/bin/sh" 166 | echo "# generated run script for $host on `date`" 167 | echo "# by the below command" 168 | echo "# $prog_args" 169 | echo "exec 2>&1" 170 | echo 171 | echo "user=$user" 172 | echo "home=$home" 173 | echo "for i in lastfm librefm" 174 | echo "do" 175 | echo " echo \"clearing \$i status\"" 176 | echo " @prefix@/bin/setuidgid \$user @prefix@/bin/envdir \\" 177 | echo " variables @prefix@/bin/\$i-scrobbler --stop" 178 | echo "done" 179 | ) > /service/$service_name/shutdown 180 | chmod +x /service/$service_name/shutdown 181 | } 182 | 183 | del_service() 184 | { 185 | if [ ! -d $servicedir/$service_name ] ; then 186 | return 0 187 | fi 188 | mv $servicedir/$service_name $servicedir/."$service_name" 189 | svc -dx $servicedir/."$service_name" $servicedir/."$service_name"/log > /dev/null 190 | sleep 5 191 | /bin/rm -rf $servicedir/."$service_name" $servicedir/."$service_name"/log > /dev/null 192 | } 193 | 194 | usage() 195 | { 196 | prog_args="" 197 | if [ -f /usr/bin/less ] ; then 198 | MORE=/usr/bin/less 199 | else 200 | MORE=/usr/bin/more 201 | fi 202 | echo "Press ENTER for options, Cntrl C to quit" 1>&2 203 | read key 204 | $MORE <&2 271 | else 272 | add_service "$user" 273 | selinux_module 274 | fi 275 | ;; 276 | --del-service) 277 | del_service 278 | ;; 279 | --selinux) 280 | selinux_module 281 | ;; 282 | *) 283 | echo "invalid option [$1]" 284 | read key 285 | usage 1 286 | ;; 287 | esac 288 | shift 289 | done 290 | # 291 | # $Log: create_service.in,v $ 292 | # Revision 1.30 2025-01-17 11:55:20+05:30 Cprogrammer 293 | # create XDG_RUNTIME_DIR as /run/user/$uid 294 | # 295 | # Revision 1.29 2023-06-30 10:16:44+05:30 Cprogrammer 296 | # added --lcdfifo argument to create LCD_FIFO env variable 297 | # 298 | # Revision 1.28 2023-06-26 23:17:24+05:30 Cprogrammer 299 | # added --lcdhost, --lcdport to add LCD_HOST, LCD_PORT env variables 300 | # 301 | # Revision 1.27 2023-06-25 11:15:13+05:30 Cprogrammer 302 | # added lcd_display script 303 | # 304 | # Revision 1.26 2023-05-18 08:49:31+05:30 Cprogrammer 305 | # added selinux module 306 | # 307 | # Revision 1.25 2022-11-26 20:40:05+05:30 Cprogrammer 308 | # added supplementary group when running mpdev 309 | # 310 | # Revision 1.24 2022-06-24 09:30:12+05:30 Cprogrammer 311 | # use relative path for variables directory 312 | # 313 | # Revision 1.23 2022-06-23 21:56:43+05:30 Cprogrammer 314 | # added lastfm-scrobbler --stop, librefm-scrobbler --stop for cleanup 315 | # 316 | # Revision 1.22 2022-06-23 09:05:36+05:30 Cprogrammer 317 | # Mac OSX port 318 | # 319 | # Revision 1.21 2022-06-20 01:00:29+05:30 Cprogrammer 320 | # use directories set by ./configure 321 | # 322 | # Revision 1.20 2021-09-26 02:57:43+05:30 Cprogrammer 323 | # change ownership of $HOME/.mpdev to uid 1000 324 | # 325 | # Revision 1.19 2021-09-09 17:10:03+05:30 Cprogrammer 326 | # added mixer script 327 | # 328 | # Revision 1.18 2021-09-09 12:17:03+05:30 Cprogrammer 329 | # added script output 330 | # 331 | # Revision 1.17 2021-04-25 10:22:15+05:30 Cprogrammer 332 | # remove cleanup of /tmp/mpdev as purpose is solved by having it as TMPFS 333 | # 334 | # Revision 1.16 2021-04-19 21:16:09+05:30 Cprogrammer 335 | # added MPDEV_TMPDIR variable 336 | # 337 | # Revision 1.15 2021-04-15 12:26:20+05:30 Cprogrammer 338 | # fixed cleanup of /tmp/mpdev 339 | # 340 | # Revision 1.14 2021-04-14 21:49:57+05:30 Cprogrammer 341 | # do cleanup only once 342 | # 343 | # Revision 1.13 2021-04-14 13:19:21+05:30 Cprogrammer 344 | # fixed .options 345 | # 346 | # Revision 1.12 2021-04-14 09:45:58+05:30 Cprogrammer 347 | # update variables only if changed 348 | # 349 | # Revision 1.11 2021-04-10 19:13:30+05:30 Cprogrammer 350 | # create variables/.options file 351 | # 352 | # Revision 1.10 2021-02-25 15:40:13+05:30 Cprogrammer 353 | # use relative path for variables to allow renaming of service directory 354 | # 355 | # Revision 1.9 2021-02-25 15:13:08+05:30 Cprogrammer 356 | # added cleanup of /tmp/mpdev and logs in scrobbles directory 357 | # 358 | # Revision 1.8 2021-01-07 12:20:08+05:30 Cprogrammer 359 | # fixed copy 360 | # 361 | # Revision 1.7 2020-08-30 10:56:28+05:30 Cprogrammer 362 | # update player, playpause script on startup 363 | # 364 | # Revision 1.6 2020-08-18 08:20:14+05:30 Cprogrammer 365 | # copy playpause script 366 | # 367 | # Revision 1.5 2020-08-17 22:15:20+05:30 Cprogrammer 368 | # set default rating to 0 369 | # 370 | # Revision 1.4 2020-07-23 10:47:04+05:30 Cprogrammer 371 | # fixed path variable 372 | # 373 | # Revision 1.3 2020-07-23 01:48:43+05:30 Cprogrammer 374 | # fix for raspberry pi, dietpi 375 | # 376 | # Revision 1.2 2020-07-22 15:51:03+05:30 Cprogrammer 377 | # added AUTO_RATING env variable 378 | # 379 | # Revision 1.1 2020-07-19 18:17:00+05:30 Cprogrammer 380 | # Initial revision 381 | # 382 | -------------------------------------------------------------------------------- /debian/Makefile: -------------------------------------------------------------------------------- 1 | prefix=/usr 2 | sysconfdir=/etc 3 | shareddir=/usr/share/mpdev 4 | libexecdir=/usr/libexec 5 | mandir=/usr/share/man 6 | logdir=/var/log/svc 7 | servicedir=/service 8 | version=$(shell cat ../conf-version) 9 | release=$(shell cat ../conf-release) 10 | email=$(shell cat ../conf-email) 11 | 12 | edit = sed \ 13 | -e 's,@prefix\@,$(prefix),g' \ 14 | -e 's,@sysconfdir\@,$(sysconfdir),g' \ 15 | -e 's,@shareddir\@,$(shareddir),g' \ 16 | -e 's,@libexecdir\@,$(libexecdir),g' \ 17 | -e 's,@mandir\@,$(mandir),g' \ 18 | -e 's,@logdir\@,$(logdir),g' \ 19 | -e 's,@servicedir\@,$(servicedir),g' \ 20 | -e 's,@version\@,$(version),g' \ 21 | -e 's,@release\@,$(release),g' \ 22 | -e 's,@email\@,$(email),g' \ 23 | -e 's,@DATE\@,$(DATE),g' 24 | 25 | all: rules changelog preinst postinst prerm \ 26 | mpdev.dsc mpdev.install \ 27 | debian.tar.gz 28 | 29 | preinst: preinst.in 30 | $(edit) $@.in > $@ 31 | 32 | postinst: postinst.in 33 | $(edit) $@.in > $@ 34 | 35 | prerm: prerm.in 36 | $(edit) $@.in > $@ 37 | 38 | rules: rules.in Makefile ../conf-version ../conf-release ../conf-email 39 | $(edit) $@.in > $@;chmod +x rules 40 | 41 | mpdev.install: mpdev.install.in 42 | $(edit) $@.in > $@ 43 | 44 | changelog: ../doc/ChangeLog Makefile ../conf-version ../conf-release \ 45 | ../conf-email 46 | ../catChangeLog --debian --name=mpdev --state=unstable \ 47 | --urgency=low ../doc/ChangeLog > $@ 48 | control: control.in ../conf-email 49 | $(edit) $@.in > $@ 50 | copyright: copyright.in ../conf-email 51 | $(edit) $@.in > $@ 52 | 53 | mpdev.dsc: mpdev.dsc.in Makefile ../conf-version ../conf-release ../conf-email 54 | $(edit) $@.in > $@ 55 | 56 | debian.tar.gz: copyright preinst postinst prerm rules changelog compat \ 57 | Makefile control mpdev.install docs source/format 58 | cd .. && tar cf - debian/copyright debian/preinst debian/postinst \ 59 | debian/prerm debian/rules debian/changelog debian/compat \ 60 | debian/control debian/mpdev.install debian/docs debian/source \ 61 | | gzip > debian/$@ 62 | 63 | clean: 64 | /bin/rm -f rules prerm preinst postinst *.dsc changelog \ 65 | mpdev.install debian.tar.gz 66 | -------------------------------------------------------------------------------- /debian/README: -------------------------------------------------------------------------------- 1 | The Debian Package mpdev 2 | ---------------------------- 3 | 4 | Comments regarding the Package 5 | 6 | -- Manvendra Bhangui Thu, 02 Jul 2020 09:27:59 +0530 7 | -------------------------------------------------------------------------------- /debian/changelog.in: -------------------------------------------------------------------------------- 1 | mpdev (@version@-@release@) unstable; urgency=medium 2 | 3 | * Initial Release. 4 | * added update_stats utility to maintain stats database 5 | * mpdev.c: set SONG_DURATION as seconds since epoch 6 | * player can now on its own add entries to stat database 7 | * mpdev - handle empty playlist with no currentsong playing 8 | * added mpdev_update, mpdev_cleanup 9 | * moved mpdev_update, mpdev_cleanup to libexec/mpdev 10 | * added mpdev_rename script 11 | * mpdev_rename: added --query option 12 | * mpdev: use read instead of timeoutread 13 | * mdpev: added START_TIME, END_TIME variables 14 | * player: refactored script to update ratings from rompr/sticker/stats 15 | * player: removed hardcored MySQL connection parameters 16 | * player: fixed variables getting clobbered by functions 17 | * player: display sticker insert/updates after NewSong line 18 | * mpdev_update: added date_added field 19 | * mpdev_update: use st_mtime, instead of st_ctime for date_added field 20 | * mpdplaylist: use date_added field instead of last_modified 21 | * mpdev: send status, currentsong command on player event to set ELAPSED_TIME 22 | * added rompr_hist play history utility for rompr 23 | * renamed rompr_hist to romprhist 24 | * player: added get_rompr_playcount_ts() function to get playcount and timestamp from Playcounttable 25 | * player: option to run without sticker, stats enabled 26 | * player: create temp file for recording original start time 27 | * player: added error condition for getting rating from Ratingtable. 28 | * player: BUG. fixed rating tmp filename 29 | * player: display rating for RompR in logs in RompR scale 30 | * added transfer_play 31 | * player: use AUTO_RATING env variable for automatic rating of unrated songs 32 | * create_service: fix for raspberrypi, dietpi 33 | * mpdev_update: removed requirement of -m option for update mode 34 | * player: exit end-song if END_TIME is not set 35 | * player: fixed display playcount number in verbose output 36 | * mpdev_cleanup.c: made -m optional 37 | * mpdev_update.c: added updation of Disc tag 38 | * player.in: added zztimestamp filed to Ratingtable 39 | * set default values for play_count, rating, date_added fields. 40 | * use %mtime% tag from mpd datatabase for date_added filed instead of using stat(2) call 41 | * mpdplaylist: added --host option to specify mpd host 42 | * mpdplaylist: added --shuffle option to shuffle playlist 43 | * mpdplaylist: renamed --save option to --playlist 44 | * mpdev_rename: use SQL REPLACE instead of sed 45 | * mpdplaylist: renamed --dummy option to --query 46 | * mpdev.c, mpdev_cleanup.c: fixed usage/error strings 47 | * tcpopen.c: added missing return on connect() failure 48 | * player: use unix domain socket if MYSQL_SOCKET is defined 49 | * player: skip http urls 50 | * mpdev: skip submit song when starting from pause state 51 | * create_rpm: added comments to indicated cwd 52 | * player: replaced /tmp/mpdev with MPDEV_TMPDIR 53 | * player: exit now-playing when in pause or stop state 54 | * mpdev.c: set PLAYER_STATE environment variable when starting 55 | * mpdev.c: set ELAPSED_TIME, DURATION only when available 56 | * mpdev.c: fixed setting of initial_state 57 | * mpdev.c: fixed logic of play/pause/stop 58 | * mpdev_update.c: adjust date_added for localtime 59 | * transfer_play: use mpc to play and remove playlist 60 | * added playpause script 61 | * added self-update of scripts in $HOME/.mpdev 62 | * mpdplaylist: auto rate if $HOME/.mpdev/AUTO_RATING file is present 63 | * mpdplaylist: fixed path of stats.db 64 | * mpdplaylist: fixed --clear option 65 | * mpdplaylist: added --limit option 66 | * mpdev_rename: fixed usage string 67 | * create_services: fixed cp 68 | * mpdplaylist.in: added last_played IS NULL to daysnotheard query 69 | * transer_play - display list of valid host on wrong input 70 | * /service/mpdev/run - do cleanup of /tmp/mpdev and scrobble logs in $HOME/.config 71 | * moc-scrobbler - create log file in ddmmyy.log format 72 | * /service/mpd/run - use relative path for variables to allow renaming of service directory 73 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /debian/control.in: -------------------------------------------------------------------------------- 1 | Source: mpdev 2 | Section: sound 3 | Priority: optional 4 | Maintainer: @email@ 5 | Build-Depends: cdbs, debhelper (>= 9), gcc, g++, automake, autoconf, m4, gawk, libqmail-dev, libssl-dev, libsqlite3-dev, pkg-config, lsb-release 6 | Standards-Version: 4.5.0 7 | Homepage: https://github.com/mbhangui/mpdev 8 | 9 | Package: mpdev 10 | Architecture: any 11 | Pre-Depends: daemontools 12 | Depends: mpc, mpd, sqlite3, coreutils, ${shlibs:Depends}, ${misc:Depends} 13 | Description: MPD Event Watcher 14 | mpdev is a daemon, written in C, that watches a Music Player Daemon events, 15 | using mpd's idle command and execs user defined script on event changes. 16 | . 17 | * Uses mpd's idle mode. 18 | * Calls user scripts in $HOME/.mpdev (player, playpause, output, mixer, 19 | lcd_display) 20 | * Sets special environment variables to pass data to the hooks. 21 | * Optional support for scrobbling to last.fm, libre.fm through external scripts 22 | * Included scripts: 23 | - scrobbler 24 | + librefm-scrobbler 25 | + lastfm-scrobbler 26 | - player 27 | + saves song data to a sqlite database 28 | + tracks play count of songs, artist, albums and genres. 29 | + helps choose songs based on listening habits using mpdplaylist 30 | playlist generator 31 | + synchronizes rompr, stats and mpd's sticker db 32 | - mixer 33 | + prints volume control value 34 | - lcd_display 35 | + prints song information to a host running lcdDaemon for 36 | display on a display with Hitachi HD44780 controller 37 | -------------------------------------------------------------------------------- /debian/copyright.in: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: mpdev 3 | Upstream-Contact: @email@ 4 | Source: 5 | 6 | Files: * 7 | Copyright: 2020 8 | License: GPL-2.0 9 | 10 | Files: debian/* 11 | Copyright: 2020 Manvendra Bhangui 12 | License: GPL-2.0 13 | 14 | License: GPL-2.0 15 | This program is free software: you can redistribute it and/or modify 16 | it under the terms of the GNU General Public License as published by 17 | the Free Software Foundation, either version 2 of the License, or 18 | (at your option) any later version. 19 | . 20 | This package is distributed in the hope that it will be useful, 21 | but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | GNU General Public License for more details. 24 | . 25 | You should have received a copy of the GNU General Public License 26 | along with this program. If not, see . 27 | . 28 | On Debian systems, the complete text of the GNU General 29 | Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". 30 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | moc-scrobbler-license 2 | LICENSE 3 | README.md 4 | mpdev.changes 5 | -------------------------------------------------------------------------------- /debian/mpdev.cron.d: -------------------------------------------------------------------------------- 1 | # 2 | # Regular cron jobs for the mpdev package 3 | # 4 | 0 4 * * * root [ -x /usr/bin/mpdev_maintenance ] && /usr/bin/mpdev_maintenance 5 | -------------------------------------------------------------------------------- /debian/mpdev.dsc.in: -------------------------------------------------------------------------------- 1 | Format: 3.0 (quilt) 2 | Source: mpdev 3 | Binary: mpdev 4 | Architecture: any 5 | Version: @version@-@release@ 6 | Maintainer: @email@ 7 | Homepage: http://www.indimail.org 8 | Debtransform-Release: 1 9 | Debtransform-Tar: mpdev-@version@.tar.gz 10 | Debtransform-Files-Tar: debian.tar.gz 11 | Standards-Version: 3.9.1 12 | Build-Depends: cdbs, debhelper (>= 9), gcc, g++, automake, autoconf, m4, gawk, libqmail-dev, libssl-dev, libsqlite3-dev, pkg-config, lsb-release 13 | -------------------------------------------------------------------------------- /debian/mpdev.install.in: -------------------------------------------------------------------------------- 1 | usr/bin @prefix@ 2 | usr/share/man/man1 @prefix@/share/man 3 | usr/libexec/mpdev @prefix@/libexec 4 | /etc/mpdev /etc 5 | -------------------------------------------------------------------------------- /debian/postinst.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # postinst script for mpdev 3 | # 4 | # see: dh_installdeb(1) 5 | 6 | set -e 7 | prefix=@prefix@ 8 | # summary of how this script can be called: 9 | # * `configure' 10 | # * `abort-upgrade' 11 | # * `abort-remove' `in-favour' 12 | # 13 | # * `abort-remove' 14 | # * `abort-deconfigure' `in-favour' 15 | # `removing' 16 | # 17 | # for details, see https://www.debian.org/doc/debian-policy/ or 18 | # the debian-policy package 19 | 20 | 21 | upgrade=0 22 | case "$1" in 23 | configure) 24 | if [ " $2" = " " ] ; then 25 | echo "installing mpdev @version@" 26 | else 27 | upgrade=1 28 | fi 29 | ;; 30 | 31 | abort-upgrade|abort-remove|abort-deconfigure) 32 | ;; 33 | 34 | *) 35 | echo "postinst called with unknown argument \`$1'" >&2 36 | exit 1 37 | ;; 38 | esac 39 | 40 | # dh_installdeb will replace this with shell code automatically 41 | # generated by other debhelper scripts. 42 | 43 | #DEBHELPER# 44 | if [ ! -x ${prefix}/sbin/minisvc ] ; then 45 | echo "${prefix}/sbin/minisvc not found: Proceeding without creating mpdev service" 1>&2 46 | exit 0 47 | fi 48 | if [ $upgrade -eq 1 ] ; then # upgrade 49 | # refresh mpdev services 50 | if [ ! -f /service/mpdev/variables/.options ] ; then 51 | mkdir -p /service/mpdev/variables 52 | echo "/usr/libexec/mpdev/create_service --servicedir=/service --user=1000 --add-service" \ 53 | > /service/mpdev/variables/.options 54 | fi 55 | ${prefix}/sbin/minisvc --servicedir=/service --refreshsvc="/service/mpdev" --silent 56 | # start mpdev services after upgrade 57 | if [ -d /run ] ; then 58 | rundir=/run/svscan 59 | elif [ -d /var/run ] ; then 60 | rundir=/var/run/svscan 61 | else 62 | rundir=/service 63 | fi 64 | set +e 65 | ${prefix}/bin/svok /service/mpdev >/dev/null 2>&1 66 | if [ $? -eq 0 -a -f ${rundir}/mpdev/.down ] ; then 67 | rm -f ${rundir}/mpdev/.down 68 | ${prefix}/bin/svc -u /service/mpdev 69 | fi 70 | set -e 71 | ${prefix}/sbin/minisvc --servicedir=/service --service-name=mpdev \ 72 | --export-variables=/service/mpdev/variables/.variables --force --silent 73 | exit 0 74 | fi 75 | ${prefix}/libexec/mpdev/create_service --servicedir=/service --user=1000 --add-service 76 | ${prefix}/sbin/minisvc --servicedir=/service --service-name=mpdev \ 77 | --export-variables=/service/mpdev/variables/.variables --force --silent 78 | exit 0 79 | -------------------------------------------------------------------------------- /debian/preinst.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # preinst script for mpdev 3 | # 4 | # see: dh_installdeb(1) 5 | 6 | set -e 7 | prefix=@prefix@ 8 | 9 | # summary of how this script can be called: 10 | # * `install' 11 | # * `install' 12 | # * `upgrade' 13 | # * `abort-upgrade' 14 | # for details, see http://www.debian.org/doc/debian-policy/ or 15 | # the debian-policy package 16 | 17 | case "$1" in 18 | install) 19 | ;; 20 | upgrade) 21 | # stop mpdev services before upgrade 22 | if [ -d /run ] ; then 23 | rundir=/run/svscan 24 | elif [ -d /var/run ] ; then 25 | rundir=/var/run/svscan 26 | else 27 | rundir=/service 28 | fi 29 | set +e 30 | ${prefix}/bin/svstat /service/mpdev >/dev/null 2>&1 31 | if [ $? -eq 0 ] ; then 32 | mkdir -p ${rundir}/mpdev 33 | ${prefix}/bin/svc -d /service/mpdev 34 | touch ${rundir}/mpdev/.down 35 | fi 36 | set -e 37 | ;; 38 | *) 39 | echo "preinst called with unknown argument \`$1'" >&2 40 | exit 1 41 | ;; 42 | esac 43 | 44 | # dh_installdeb will replace this with shell code automatically 45 | # generated by other debhelper scripts. 46 | 47 | #DEBHELPER# 48 | 49 | exit 0 50 | -------------------------------------------------------------------------------- /debian/prerm.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # prerm script for mpdev 3 | # 4 | # see: dh_installdeb(1) 5 | 6 | set -e 7 | 8 | # summary of how this script can be called: 9 | # * `remove' 10 | # * `upgrade' 11 | # * `failed-upgrade' 12 | # * `remove' `in-favour' 13 | # * `deconfigure' `in-favour' 14 | # `removing' 15 | # 16 | # for details, see http://www.debian.org/doc/debian-policy/ or 17 | # the debian-policy package 18 | 19 | prefix=@prefix@ 20 | 21 | ID=`id -u` 22 | if [ $ID -ne 0 ] ; then 23 | echo "You are not root" >&2 24 | exit 1 25 | fi 26 | 27 | case "$1" in 28 | remove|upgrade|deconfigure) 29 | ;; 30 | 31 | failed-upgrade) 32 | ;; 33 | 34 | *) 35 | echo "prerm called with unknown argument \`$1'" >&2 36 | exit 1 37 | ;; 38 | esac 39 | 40 | # dh_installdeb will replace this with shell code automatically 41 | # generated by other debhelper scripts. 42 | 43 | #DEBHELPER# 44 | 45 | # we are doing upgrade 46 | if [ " $1" = " upgrade" -o " $1" = " deconfigure" ] ; then 47 | exit 0 48 | fi 49 | echo "stopping and removing mpdev service" 50 | ${prefix}/libexec/mpdev/create_service --servicedir=/service --del-service 51 | echo "removing mpdev logs" 52 | rm -fr /var/log/svc/mpdev 53 | exit 0 54 | -------------------------------------------------------------------------------- /debian/rules.in: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | # -*- makefile -*- 4 | # Sample debian/rules that uses debhelper. 5 | # This file was originally written by Joey Hess and Craig Small. 6 | # As a special exception, when this file is copied by dh-make into a 7 | # dh-make output file, you may use that output file without restriction. 8 | # This special exception was added by Craig Small in version 0.37 of dh-make. 9 | 10 | # Uncomment this to turn on verbose mode. 11 | #export DH_VERBOSE=1 12 | 13 | # This is the debhelper compatibility version to use. 14 | # export DH_COMPAT=4 15 | CFLAGS=-g -DOBS_BUILD 16 | ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) 17 | CFLAGS += -O0 -fno-strict-aliasing -Wno-unused-result -Wno-unused-result 18 | else 19 | CFLAGS += -O2 -fno-strict-aliasing -Wno-unused-result -Wno-unused-result 20 | endif 21 | 22 | prefix=@prefix@ 23 | libexecdir=@libexecdir@ 24 | mandir=@mandir@ 25 | sysconfdir=@sysconfdir@ 26 | version=@version@ 27 | package_name="mpdev" 28 | 29 | cp=/bin/cp 30 | rm=/bin/rm 31 | 32 | DESTDIR=$(CURDIR)/debian/mpdev.tmp 33 | 34 | build: build-stamp 35 | build-stamp: 36 | dh_testdir 37 | # 38 | # Extract source archives 39 | # 40 | # 41 | # run configure script 42 | # 43 | HOME='.';export HOME 44 | ./configure --prefix=${prefix} --sysconfdir=${sysconfdir} \ 45 | --libexecdir=${libexecdir} 46 | $(MAKE) -s DESTDIR=$(DESTDIR) 47 | touch build-stamp 48 | 49 | clean: 50 | rm -f build-stamp configure-stamp 51 | ${rm} -rf $(DESTDIR) .deps 52 | dh_testdir 53 | dh_testroot 54 | dh_clean 55 | $(MAKE) clean >/dev/null 2>&1 || true; $(MAKE) distclean >/dev/null 2>&1 || true 56 | ${rm} -f build-stamp 57 | 58 | install: build 59 | dh_testdir 60 | dh_testroot 61 | dh_prep || dh_clean -k 62 | dh_installdirs 63 | $(MAKE) -s install DESTDIR=$(DESTDIR) 64 | 65 | binary-indep: build install 66 | dh_testdir 67 | dh_testroot 68 | find $(DESTDIR)$(mandir) -name '*'.? -type f -exec gzip -q {} \; 69 | dh_install --sourcedir=$(DESTDIR) -p${package_name} 70 | dh_installchangelogs --exclude ChangeLog 71 | dh_installcron 72 | dh_installdocs 73 | dh_link 74 | dh_strip 75 | dh_compress 76 | dh_fixperms 77 | dh_installdeb 78 | dh_makeshlibs -V 79 | dh_shlibdeps 80 | dh_gencontrol 81 | dh_md5sums 82 | dh_builddeb 83 | 84 | # Build architecture-dependent files here. 85 | binary-arch: build install 86 | 87 | binary: binary-indep binary-arch 88 | .PHONY: build clean binary-indep binary-arch binary install configure 89 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /default.configure: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ ! -f ./configure -o ! -f Makefile -o ! -f Makefile.in ] ; then 3 | autoreconf -fiv 4 | fi 5 | if [ ! -f conf-release ] ; then 6 | echo 1.1 > conf-release 7 | fi 8 | 9 | SYSTEM=$(uname -s) 10 | case "$SYSTEM" in 11 | Linux) 12 | prefix=/usr 13 | sysconfdir=/etc 14 | ;; 15 | FreeBSD) 16 | prefix=/usr/local 17 | sysconfdir=/usr/local/etc 18 | ;; 19 | Darwin) 20 | prefix=/usr/local 21 | sysconfdir=/opt/local/etc 22 | esac 23 | ./configure \ 24 | --prefix=$prefix \ 25 | --sysconfdir=$sysconfdir \ 26 | --libexecdir=$prefix/libexec 27 | -------------------------------------------------------------------------------- /doc/ChangeLog: -------------------------------------------------------------------------------- 1 | * 2 | Release 1.1 Start 30/06/2022 End --/--/---- 3 | - 30/06/2022 4 | 01. First release 5 | - 04/07/2022 6 | 02. preinst: redirect svstat output to /dev/null 7 | - 26/09/2022 8 | 03. karma.in: exit if getopt returns non-zero 9 | 04. mpdhist: new program to display history of last played songs 10 | - 20/10/2022 11 | 05. transfer_play: added --play, --no-rm command line options 12 | - 25/10/2022 13 | 06. transfer_play: added --clearsrc, --cleardst to clear current playlist on 14 | source, destination 15 | - 26/10/2022 16 | 07. create_services: run mpdev with supplementary groups of user 17 | - 29/10/2022 18 | 08. mpdev_rename.in: prevent wrapping of text after 60 characters 19 | - 04/01/2023 20 | 09. transfer_play.in: fixed process_cmdline 21 | - 18/05/2023 22 | 10. added selinux module for mpd 23 | - 10/06/2023 24 | 11. mpdev.c: replaced multiple out() with subprintf() 25 | - 26/06/2023 26 | 12. added lcd_display script to print song information to a remote lcd display 27 | running lcdDaemon 28 | 13. create_service: added --lcdhost, --lcdport to add LCD_HOST, LCD_PORT env 29 | variables 30 | 14. player, lcd_display: display song rating on 4th row 31 | - 29/06/2023 32 | 15. player, playpause: use $HOME/.mpdev/lcd_display or 33 | libexec/mpdev/lcd_display 34 | - 30/06/2023 35 | 16. create_service: added --lcdfifo argument to create LCD_FIFO env variable 36 | 17. player, playpuse: added use of LCD_FIFO to access LCD display 37 | 18. lcd_display: refactored code 38 | 19. player, lcd_display: added display of play counts 39 | 20. playpause: pass RATING, PLAYCOUNT env variable to lcd_display 40 | - 04/07/2023 41 | 21. karma: added --love option to mark scrobble as loved 42 | - 26/03/2024 43 | 22. songi: display last played in days, hours, mins, secs ago 44 | - 04/04/2024 45 | 23. songi: fixed last played when song has never been played 46 | - 08/04/2024 47 | 24. karma, moc-scrobbler: added unlove function 48 | - 09/04/2024 49 | 25. karma: display command if running on tty 50 | 26. moc-scrobbler: added --info option to get track info 51 | - 10/04/2024 52 | 27. mpdplaylist.in: fixed command line arguments having space 53 | - 01/08/2024 54 | 28. karma.in: fixes for MacOS 55 | - 23/12/2024 56 | 29. player.in: do not downgrade karma on pause song 57 | - 17/01/2025 58 | 30. create_services: create XDG_RUNTIME_DIR as /run/user/$uid 59 | 31. songi: fixed last_played when song has never been played 60 | - 11/02/2025 61 | 32. player.in: return db operation 5 times on failure 62 | 63 | * Thu Jun 30 2022 18:32:58 IST Manvendra Bhangui 1.0-1.1%{?dist} 64 | Release 1.0 Start 02/03/2020 End 30/06/2022 65 | - 15/04/2021 66 | 01. Bump Release 67 | 02. player: skip db update if NO_DB_UPDATE is defined and non-zero 68 | 03. mpdplaylist: added --karma option 69 | 04. removed mpdev_maintenaance 70 | - 16/04/2021 71 | 05. added --options-file feature to take command line arguments from an 72 | options file 73 | 06. player: upgrade karma as per last_played logic 74 | 07. added license, README, changelogs to doc directory 75 | - 17/04/2021 76 | 08. mpdplaylist: Fix for space in command line argument values 77 | - 20/04/2021 78 | 09. added --silent parmeter to minisvc invocation 79 | 10. added debian/source/format 80 | 11. added mpdev_rename man page 81 | - 22/04/2021 82 | 12. player: skip update of play_count when song is skipped 83 | 13. player: display correct playcount in rompr table 84 | - 23/04/2021 85 | 14. playpause: fixed end-song, pause-song getting skipped 86 | 15. playpause: use SONG_PLAYED instead of ELAPSED_TIME 87 | 16. renamed SONG_PLAYED to SONG_PLAYED_DURATION 88 | 17. mpdev.c: reset song_played_duration when stopped 89 | 18. playpause: display date in yyyy-mm-dd HH:MM:SS during play/pause 90 | - 24/04/2021 91 | 19. added new script karma for manipulating song's karma value 92 | 20. added more conditions for downgrade karma 93 | 21. player, playpause: skip percentage calculation when SONG_PLAYED_DURATION 94 | is not set 95 | 22. mpdev.c: removed unset of SONG_PLAYED_DURATION 96 | 23. mpdev.c: fixes for SONG_PLAYED_DURATION 97 | 24. mpdev.c: add elapsed time to SONG_PLAYED_DURATION if started when a song 98 | was already playing 99 | 25. player: removed redundant code 100 | - 25/04/2021 101 | 26. mpdev.c: removed get_play_state() as it had the same function as 102 | get_status() function 103 | 27. mdev.c: get elapsed time in a single call to get the intial player state 104 | 28. mpdev.c: use DISABLE_SCROBBLE env variable to disable scrobbling 105 | 29. mpdev.c, player: adde code comments 106 | 30. create_service: remove cleanup of /tmp/mpdev as purpose is solved by 107 | having it as TMPFS 108 | 31. player: added log output for scrobbling 109 | 32. player: sync RompR playcounts with stats.db 110 | 33. player: skip update of last_played when paused to avoid karma getting 111 | increased 112 | 34. player: refactored update of RompR playcounts 113 | 35. player: fixed value of play counts in logs and RompR update 114 | - 26/04/2021 115 | 36. mpdev.c: set song_played_duration when calling script for now-playing 116 | 37. player: display initial song position in NewSong 117 | 38. playpause: display song played duration 118 | 39. mpdev.c: increment song_played_duration when prev state is not in pause 119 | state 120 | 40. player: skip RompR playcount update when song is not fully heard 121 | - 27/04/2021 122 | 41. mpdev.c: initialize elapsed variable 123 | - 08/09/2021 124 | 42. fixed usage string/description in mpdev.c and man page 125 | 43. fixed idle handling 126 | 44. added output even with OUTPUT devices passed as env variables. Feature 127 | request from Markus Gerl 128 | - 09/09/2021 129 | 45. report OUTPUT changes in env variable OUTPUT_CHANGED 130 | 46. added script 'output' 131 | 47. set env variable VOLUME on startup and on mixer level change 132 | 16/09/2021 133 | 48. mpdev.c: BUGFIX: Fixed player not comining out of do idle loop 134 | 49. mpdev.c: decrement count when PLAYLIST_EVENT is followed by PLAYER_EVENT 135 | 50. player.in: disable UPDATE/INSERT echo statements when NO_DB_UPDATE is set 136 | 51. player.in: sanitize shell input 137 | - 17/09/2021 138 | 52. mpdev.c: print debug statements for verbose > 1 139 | - 26/09/2021 140 | 53. create_service: fix ownership of $HOME/.mpdev 141 | - 28/09/2021 142 | 54. player: fix INSERT statement for extra (last_modified) field added to sticker 143 | table 144 | 55. player: skip db update for streams 145 | - 29/09/2021 146 | 56. mpdev_update.c: added last_modified column to sticker table 147 | - 30/09/2021 148 | 57. karma.in: display karma for current playing song when no options are 149 | provided 150 | 58. use -noheader option to prevent .sqlitrc settings messing with results 151 | 59. added songi script to display information from stats.db for any music 152 | file 153 | - 01/10/2021 154 | 60. mpdev_update.c, songi.in: removed name column from song table in stats db 155 | - 06/10/2021 156 | 61. karma: fixed sql statements 157 | - 10/10/2021 158 | 62. player.in: fixed non-skipping of db update for streams 159 | - 15/10/2021 160 | 63. karma: fixed update not working 161 | 64. songi: formated for better display 162 | 65. karma: set song_uri to current playing song if no options are provided 163 | - 18/11/2021 164 | 66. player.in: display mysql error 165 | - 23/12/2021 166 | 67. moc-scrobbler.in: removed use of source command to avoid syntax error 167 | caused by data in track.current, track.last 168 | - 16/01/2022 169 | 68. player.in: scrobble only when PLAYER_STATE is play 170 | - 06/02/2022 171 | 69. mpdplaylist.in: added --incartist, --exlartist option to include/exclude 172 | comma separated list of artists 173 | 70. use tcpopen, pathexec_run, pathexec_env from libqmail 174 | - 10/05/2022 175 | 71. karma.in: merged modifications by https://github.com/Plexvol (use getopt) 176 | - 31/05/2022 177 | 72. skip service creation if daemontools is not installed 178 | - 20/06/2022 179 | 73. create_services.in, Makefile.am, mpdplaylist.in, romprhist.in, 180 | transfer_play.in, songi.in: set/use directories set by ./configure 181 | 74. mpdev_update.c: remove extra arguments passed to print_song 182 | 75. player.in, playpause.in: Fixed date syntax for non-gnu date 183 | 76. player.in, playpause.in: use directories set in ./configure 184 | 77. moc-scrobbler.in: use gnu grep for OSX 185 | - 23/06/2022 186 | 78. Mac OSX port 187 | 79. moc-scrobbler.in: added --love option to love tracks 188 | 80. mpdev service: added lastfm-scrobbler --stop, librefm-scrobbler --stop for 189 | cleanup 190 | - 24/06/2022 191 | 81. mpdev service: use relative path for variables directory 192 | 82. moc-scrobbler.in: removed bashishm 193 | - 25/06/2022 194 | 83. player.in: scrobble direct when track.last is missing 195 | - 27/06/2022 196 | 84. moc-scrobbler.in: replaced echo -n with printf for consistent behaviour 197 | under /bin/sh 198 | - 30/06/2022 199 | 85. Release 1.0 200 | 201 | * Thu Apr 15 11:07:09 UTC 2021 - Manvendra Bhangui 202 | Release 0.1 Start 02/03/2020 203 | - 02/03/2020 204 | 01. Initial Release 205 | 02. added update_stats utility to maintain stats database 206 | 03. mpdev.c: set SONG_DURATION as seconds since epoch 207 | 04. player can now on its own add entries to stat database 208 | - 14/07/2020 209 | 05. mpdev - handle empty playlist with no currentsong playing 210 | 06. added mpdev_update, mpdev_cleanup 211 | - 15/07/2020 212 | 07. moved mpdev_update, mpdev_cleanup to libexec/mpdev 213 | 08. added mpdev_rename script 214 | - 16/07/2020 215 | 09. mpdev_rename: added --query option 216 | 10. mpdev: use read instead of timeoutread 217 | - 17/07/2020 218 | 11. mdpev: added START_TIME, END_TIME variables 219 | 12. player: refactored script to update ratings from rompr/sticker/stats 220 | 13. player: removed hardcored MySQL connection parameters 221 | 14. player: fixed variables getting clobbered by functions 222 | - 19/07/2020 223 | 15. player: display sticker insert/updates after NewSong line 224 | 16. mpdev_update: added date_added field 225 | 17. mpdev_update: use st_mtime, instead of st_ctime for date_added field 226 | 18. mpdplaylist: use date_added field instead of last_modified 227 | - 20/07/2020 228 | 19. mpdev: send status, currentsong command on player event to set 229 | ELAPSED_TIME 230 | 20. added rompr_hist play history utility for rompr 231 | 21. renamed rompr_hist to romprhist 232 | - 21/07/2020 233 | 22. player: added get_rompr_playcount_ts() function to get playcount and 234 | timestamp from Playcounttable 235 | 23. player: option to run without sticker, stats enabled 236 | 24. player: create temp file for recording original start time 237 | 25. player: added error condition for getting rating from Ratingtable. 238 | 26. player: BUG. fixed rating tmp filename 239 | 27. player: display rating for RompR in logs in RompR scale 240 | - 22/07/2020 241 | 28. added transfer_play 242 | 29. player: use AUTO_RATING env variable for automatic rating of unrated songs 243 | 30. create_service: fix for raspberrypi, dietpi 244 | - 24/07/2020 245 | 31. mpdev_update: removed requirement of -m option for update mode 246 | 32. player: exit end-song if END_TIME is not set 247 | 33. player: fixed display playcount number in verbose output 248 | - 28/07/2020 249 | 34. mpdev_cleanup.c: made -m optional 250 | 35. mpdev_update.c: added updation of Disc tag 251 | 35. player.in: added zztimestamp filed to Ratingtable 252 | - 02/08/2020 253 | 36. set default values for play_count, rating, date_added fields. 254 | 37. use %%mtime%% tag from mpd datatabase for date_added filed instead of using stat(2) call 255 | - 03/08/2020 256 | 38. mpdplaylist: added --host option to specify mpd host 257 | 39. mpdplaylist: added --shuffle option to shuffle playlist 258 | - 05/08/2020 259 | 40. mpdplaylist: renamed --save option to --playlist 260 | 41. mpdev_rename: use SQL REPLACE instead of sed 261 | - 06/08/2020 262 | 42. mpdplaylist: renamed --dummy option to --query 263 | - 08/08/2020 264 | 42. mpdev.c, mpdev_cleanup.c: fixed usage/error strings 265 | 43. tcpopen.c: added missing return on connect() failure 266 | - 09/08/2020 267 | 44. player: use unix domain socket if MYSQL_SOCKET is defined 268 | - 10/08/2020 269 | 45. player: skip http urls 270 | 46. mpdev: skip submit song when starting from pause state 271 | 47. create_rpm: added comments to indicated cwd 272 | 48. player: replaced /tmp/mpdev with MPDEV_TMPDIR 273 | 49. player: exit now-playing when in pause or stop state 274 | 50. mpdev.c: set PLAYER_STATE environment variable when starting 275 | 51. mpdev.c: set ELAPSED_TIME, DURATION only when available 276 | 52. mpdev.c: fixed setting of initial_state 277 | 53. mpdev.c: fixed logic of play/pause/stop 278 | - 11/08/2020 279 | 54. mpdev_update.c: adjust date_added for localtime 280 | 55. transfer_play: use mpc to play and remove playlist 281 | - 14/08/2020 282 | 56. added playpause script 283 | - 26/08/2020 284 | 57. player: added self-update of scripts in $HOME/.mpdev 285 | - 27/08/2020 286 | 58. player: auto rate if $HOME/.mpdev/AUTO_RATING file is present 287 | 59. fixed path of stats.db 288 | - 03/08/2020 289 | 60. mpdplaylist: fixed --clear option 290 | - 05/08/2020 291 | 61. mpdplaylist: added --limit option 292 | - 08/08/2020 293 | 62. mpdev_rename: fixed usage string 294 | - 07/01/2021 295 | 63. create_services: fixed cp 296 | 04. mpdplaylist.in: added last_played IS NULL to daysnotheard query 297 | - 14/02/2021 298 | 65. transer_play - display list of valid host on wrong input 299 | - 25/02/2021 300 | 66. /service/mpdev/run - do cleanup of /tmp/mpdev and scrobble logs in 301 | $HOME/.config 302 | 67. moc-scrobbler - create log file in ddmmyy.log format 303 | 68. /service/mpd/run - use relative path for variables to allow renaming 304 | of service directory 305 | - 30/03/2021 306 | 69. obs integration 307 | - 10/04/2021 308 | 70. mpdplaylist - use $HOME/.mpdplaylist.options for default options when no 309 | arguments are provided 310 | 71. package install/upgrade - refresh service 311 | - 11/04/2021 312 | 72. added transfer_play, romprhist man page 313 | 73. refactored romprhist 314 | - 14/04/2021 315 | 74. update variables only if changed 316 | 75. save variables using minisvc --export-variables 317 | 76. mpdplaylist: added --playcount option to get songs that match play counts 318 | 77. mpdplaylist: added --play option 319 | 78. mpdev.c, player: added song played duration in SONG_PLAYED env variable 320 | - 15/04/2021 321 | 79. mpdplaylist: downgrade karma if song is partially played 322 | 80. mpdev.c: fixed initialization of song played duration 323 | 81. create_service: fixed cleanup of /tmp/mpdev 324 | -------------------------------------------------------------------------------- /karma.1: -------------------------------------------------------------------------------- 1 | .\" vim: tw=75 2 | .TH karma 1 3 | .SH NAME 4 | karma \- Set song's karma 5 | 6 | .SH SYNOPSYS 7 | .B karma 8 | [ 9 | .I options 10 | ] 11 | 12 | .SH DESCRIPTION 13 | \fBkarma\fR sets the value of karma for a song or songs. \fIkarma\fR is a 14 | number from 0 to 100 representing a how desirable a song needs to be played. 15 | If no options are provided, \fBkarma\R displays the \fIkarma\fR for the 16 | current playing song. If there is no song playng, \fBkarma\fR will exit if 17 | no option is provided on the command line. 18 | 19 | If a song is skipped, it's karma is downgraded by 1. If a song is played 20 | twice within a day, it's karma is upgraded by 4. If a song is played twice 21 | within a week, it's karma is upgraded by 3. If a song is played twice within 22 | 14 days, its karma is upgraded by 2. If a song is played twice within a 23 | month, it's karma is upgraded by 1. All songs start with a default karma of 24 | 50. The setting of \fIkarma\fR is done by \fBmpdev\fR(1). 25 | 26 | Karma is downgraded by \fBmpdev\fR(1) only for songs rated less than 6 and 27 | played 5 times or less and whose karma is 50 or less. In short a song can 28 | earn a permanent karma under following conditions 29 | 30 | * it's karma becomes 60 or more. 31 | * has been rated 6 or greater. 32 | * has been played from beginning to end more than 5 times. 33 | 34 | \fBkarma\fR utility helps you to play god. You can increase or decrease a 35 | song's karma by any value as per your whims and fancy. 36 | 37 | .SH OPTIONS 38 | 39 | Known values for OPTION are: 40 | 41 | .EX 42 | --love 43 | mark scrobble as loved on lastfm, librefm. If this option is given, all 44 | other options are ignored 45 | 46 | --value=karma_value 47 | Set karma to karma_value. If not set, karma_value is set as 50 48 | 49 | --uri=path 50 | Finds song with uri matching path 51 | 52 | --id=songID 53 | Finds song with id matching songID 54 | 55 | --karma 56 | Find songs with karma as per expression. e.g. 57 | --karma<50 means songs with karma < 50 58 | --karma<=50 means songs with karma < or = 50 59 | --karma=50 means songs with karma = 50 60 | --karma>=50 means songs with karma > or = 50 61 | --karma>50 means songs with karma > 50 62 | 63 | --playcount=exp 64 | Find songs with playcounts as per expression. e.g. 65 | --playcount<5 means songs with play counts < 5 66 | --playcount<=5 means songs with play counts < or = 5 67 | --playcount=5 means songs with play counts = 5 68 | --playcount>=5 means songs with play counts > or = 5 69 | --playcount>5 means songs with play counts > 5 70 | 71 | --rating 72 | Find songs with karma as per expression. e.g. 73 | --rating<6 means gons with ratings < 6 74 | --rating<=6 means gons with ratings < or = 6 75 | --rating=6 means gons with ratings = 6 76 | --rating>=6 means gons with ratings > or = 6 77 | --rating>6 means gons with ratings > 6 78 | 79 | --artist=Artist 80 | Find songs with Artist exactly matching 'Artist' 81 | 82 | --artistany=keyword 83 | Find songs with Artist having 'keyword' anywhere in the Artist field 84 | 85 | --query 86 | Display SQL query, results and exit 87 | 88 | --help 89 | 90 | display this help and exit 91 | 92 | --version 93 | 94 | output version information 95 | .EE 96 | 97 | .SH EXAMPLES 98 | 99 | .EX 100 | 1. Set the karma of the current playing song to 55 101 | 102 | $ karma --value=52 103 | karma id uri 104 | ---------- ---------- ------------------------------------------------------- 105 | 50 12490 Hindi/Milan/09 - Sawan Ka Mahina-Milan-1967-Mukesh.flac 106 | 52 12490 Hindi/Milan/09 - Sawan Ka Mahina-Milan-1967-Mukesh.flac 107 | 108 | 2. Display the karma of the current playing song 109 | 110 | $ karma 111 | karma id uri 112 | ---------- ---------- ------------------------------------------------------- 113 | 50 12500 Hindi/Mirza Ghalib/03 - Aah ko chahiye ek umar-.flac 114 | 115 | 3. Display the karma of a specific song 116 | 117 | $ karma --uri="Deep Purple/1971 - Fireball/01 - Fireball.wv" 118 | karma id uri 119 | ---------- ---------- -------------------------------------------- 120 | 50 52283 Deep Purple/1971 - Fireball/01 - Fireball.wv 121 | .EE 122 | 123 | .SH "SEE ALSO" 124 | mpdplaylist(1), 125 | mpdev(1) 126 | -------------------------------------------------------------------------------- /karma.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # $Id: karma.in,v 1.14 2024-12-23 19:08:21+05:30 Cprogrammer Exp mbhangui $ 4 | # 5 | 6 | get_mpd_conf_value() 7 | { 8 | grep "^$1" @sysconfdir@/mpd.conf|awk '{print $2}' | \ 9 | sed -e 's{"{{g' 10 | } 11 | 12 | usage() 13 | { 14 | if [ -f /usr/bin/less ] ; then 15 | MORE=/usr/bin/less 16 | else 17 | MORE=/usr/bin/more 18 | fi 19 | echo "Press ENTER for options, Cntrl C to quit" 1>&2 20 | read key 21 | $MORE 1>&2 <=50 means songs with karma greater than or equal to 50 44 | --karma >50 means songs with karma greater than 50 45 | 46 | -p 47 | --playcount=exp 48 | Find songs with playcounts as per expression. e.g. 49 | --playcount <5 means songs with play counts less than 5 50 | --playcount <=5 means songs with play counts less than or equal to 5 51 | --playcount =5 means songs with play counts equal to 5 52 | --playcount >=5 means songs with play counts greater than or equal to 5 53 | --playcount >5 means songs with play counts greater than 5 54 | 55 | -r 56 | --rating 57 | Find songs with karma as per expression. e.g. 58 | --rating <6 means gons with ratings less than 6 59 | --rating <=6 means gons with ratings less than or equal to 6 60 | --rating =6 means gons with ratings equal to 6 61 | --rating >=6 means gons with ratings greater than or equal to 6 62 | --rating >6 means gons with ratings greater than 6 63 | 64 | -a Artist 65 | --artist=Artist 66 | Find songs with Artist exactly matching 'Artist' 67 | 68 | --artistany=keyword 69 | Find songs with Artist having 'keyword' anywhere in the Artist field 70 | 71 | --query 72 | Display SQL query, results and exit 73 | 74 | -h 75 | --help 76 | display this help and exit 77 | 78 | EOF 79 | exit $1 80 | } 81 | 82 | process_cmdline() 83 | { 84 | SYSTEM=$(uname -s) 85 | case "$OS" in 86 | Darwin) 87 | if [ -x /opt/local/bin/getopt ] ; then 88 | getopt="/opt/local/bin/getopt" 89 | elif [ -x /usr/local/bin/getopt ] ; then 90 | getopt="/usr/local/bin/getopt" 91 | else 92 | getopt=getopt 93 | fi 94 | ;; 95 | *) 96 | getopt=getopt 97 | ;; 98 | esac 99 | OPTS=`$getopt -o v:u:i:k:a:p:r:h --long value:,uri:,id:,karma:,artist:,artistany,playcount:,rating:,query,love,unlove,help -- "$@"` 100 | if [ $? -ne 0 ] ; then 101 | usage 1 102 | fi 103 | eval set -- "$OPTS" 104 | #echo "$@" 105 | while true; do 106 | case "$1" in 107 | -v|--value) 108 | karma_val=$2 ; shift 2 ;; 109 | -u|--uri) 110 | song_uri=$2 ; shift 2 ;; 111 | -i|--id) 112 | song_id=$2 ; shift 2 ;; 113 | -k|--karma) 114 | if [ "${2:0:1}" = ">" -o "${2:0:1}" = "<" -o "${2:0:1}" = "=" ] ; then 115 | karma="karma$2" ; shift 2 ; 116 | else 117 | karma="karma=$2" ; shift 2 ; 118 | fi ;; 119 | -a|--artist) 120 | exact=1; artist=${2/ /_}; shift 2;; 121 | --artistany) 122 | exact=0; artist=${2/ /_}; shift 2;; 123 | -p|--playcount) 124 | if [ "${2:0:1}" = ">" -o "${2:0:1}" = "<" -o "${2:0:1}" = "=" ] ; then 125 | play_counts="play_count$2" ; shift 2 ; 126 | else 127 | play_counts="play_count=$2" ; shift 2 ; 128 | fi ;; 129 | -r|--rating) 130 | if [ "${2:0:1}" = ">" -o "${2:0:1}" = "<" -o "${2:0:1}" = "=" ] ; then 131 | rating="rating$2" ; shift 2 ; 132 | else 133 | rating="rating=$2" ; shift 2 ; 134 | fi ;; 135 | --query) 136 | do_update=0; shift 1;; 137 | --love) 138 | scrobble_love=1; shift 1;; 139 | --unlove) 140 | scrobble_unlove=1; shift 1;; 141 | -h|--help) 142 | usage 0 ;; 143 | --) shift; break;; 144 | *) 145 | echo "invalid option [$1]" 1>&2; usage 1; break;; 146 | esac 147 | done 148 | } 149 | 150 | song_id="" 151 | karma="" 152 | artist="" 153 | rating="" 154 | play_counts="" 155 | do_update=1 156 | scrobble_love=0 157 | scrobble_unlove=0 158 | process_cmdline "$@" 159 | 160 | if [ $# -eq 0 ] ; then 161 | do_update=0 162 | song_uri=$(mpc current -f %file% | sed -e "s{'{''{g") 163 | if [ -z "$song_uri" ] ; then 164 | echo "No song playing and no options given" 1>&2 165 | usage 1 166 | fi 167 | fi 168 | 169 | music_dir=`get_mpd_conf_value music_directory` 170 | if [ $? -ne 0 ] ; then 171 | echo "could not get music directory from mpd.conf" 1>&2 172 | exit 1 173 | fi 174 | sticker_file=`get_mpd_conf_value sticker_file` 175 | if [ $? -ne 0 ] ; then 176 | echo "could not get sticker database from mpd.conf" 1>&2 177 | exit 1 178 | fi 179 | stats_dir=$(dirname $sticker_file) 180 | stats_file=$stats_dir/stats.db 181 | if [ -z "$stats_file" ] ; then 182 | echo "Unable to find value of stats.db location" 1>&2 183 | exit 1 184 | fi 185 | if [ ! -f "$stats_file" ] ; then 186 | echo "$stats_file: No such file or directory" 1>&2 187 | exit 1 188 | fi 189 | 190 | sql_query_select="SELECT karma, id, uri FROM song " 191 | sql_query_update="UPDATE song set karma=$karma_val " 192 | first_condition="" 193 | 194 | if [ $scrobble_love -eq 1 -o $scrobble_unlove -eq 1 ] ; then 195 | song_uri=$(mpc current -f %file% | sed -e "s{'{''{g") 196 | if [ -z "$song_uri" ] ; then 197 | echo "No song playing and no options given" 1>&2 198 | exit 1 199 | fi 200 | sql_query_s="SELECT title, artist, album FROM song WHERE uri='${song_uri}'" 201 | sqlite3 -noheader -batch $stats_file "$sql_query_s" | while IFS='|' read track artist album 202 | do 203 | tty -s 204 | ret=$? 205 | if [ $scrobble_love -eq 1 ] ; then 206 | echo "marking scrobble as loved on lastfm" 207 | if [ $ret -eq 0 ] ; then 208 | lastfm-scrobbler --love --artist="$artist" --track="$track" --album="$album" 209 | else 210 | lastfm-scrobbler --love --artist="$artist" --track="$track" --album="$album" > /dev/null 211 | fi 212 | echo "marking scrobble as loved on librefm" 213 | if [ $ret -eq 0 ] ; then 214 | librefm-scrobbler --love --artist="$artist" --track="$track" --album="$album" 215 | else 216 | librefm-scrobbler --love --artist="$artist" --track="$track" --album="$album" > /dev/null 217 | fi 218 | else 219 | echo "marking scrobble as unloved on lastfm" 220 | if [ $ret -eq 0 ] ; then 221 | lastfm-scrobbler --unlove --artist="$artist" --track="$track" --album="$album" 222 | else 223 | lastfm-scrobbler --unlove --artist="$artist" --track="$track" --album="$album" > /dev/null 224 | fi 225 | echo "marking scrobble as unloved on librefm" 226 | if [ $ret -eq 0 ] ; then 227 | librefm-scrobbler --unlove --artist="$artist" --track="$track" --album="$album" 228 | else 229 | librefm-scrobbler --unlove --artist="$artist" --track="$track" --album="$album" > /dev/null 230 | fi 231 | fi 232 | done 233 | exit 0 234 | fi 235 | if [ -z "$song_uri" -a -z "$song_id" -a -z "$artist" -a -z "$rating" -a -z "$play_counts" -a -z "$karma" ] ; then 236 | song_uri=$(mpc current -f %file% | sed -e "s{'{''{g") 237 | if [ -z "$song_uri" ] ; then 238 | echo "No song playing and no options given" 1>&2 239 | usage 1 240 | fi 241 | fi 242 | 243 | if [ -n "$song_uri" ] ; then 244 | if [ "$song_uri" = "current" ] ; then 245 | song_uri=$(mpc current -f %file% | sed -e "s{'{''{g") 246 | if [ -z "$song_uri" ] ; then 247 | echo "No song playing" 1>&2 248 | exit 1 249 | fi 250 | fi 251 | if [ -z "$first_condition" ] ; then 252 | sql_query_s="$sql_query_select WHERE" 253 | sql_query_u="$sql_query_update WHERE" 254 | first_condition=1 255 | else 256 | sql_query_s="$sql_query_s AND" 257 | sql_query_u="$sql_query_u AND" 258 | fi 259 | sql_query_s="$sql_query_s uri='${song_uri}'" 260 | sql_query_u="$sql_query_u uri='${song_uri}'" 261 | fi 262 | if [ -n "$song_id" ] ; then 263 | if [ -z "$first_condition" ] ; then 264 | sql_query_s="$sql_query_select WHERE" 265 | sql_query_u="$sql_query_update WHERE" 266 | first_condition=1 267 | else 268 | sql_query_s="$sql_query_s AND" 269 | sql_query_u="$sql_query_u AND" 270 | fi 271 | sql_query_s="$sql_query_s id='$song_id'" 272 | sql_query_u="$sql_query_u id='$song_id'" 273 | fi 274 | if [ -n "$artist" ] ; then 275 | if [ -z "$first_condition" ] ; then 276 | sql_query_s="$sql_query_select WHERE" 277 | sql_query_u="$sql_query_update WHERE" 278 | first_condition=1 279 | elif [ -n "$first_condition" ] ; then 280 | sql_query_s="$sql_query_s AND" 281 | sql_query_u="$sql_query_u AND" 282 | fi 283 | f=`echo $artist|sed "s/_/ /g"` 284 | if [ $exact -eq 1 ] ; then 285 | sql_query_s="$sql_query_s artist='$f'" 286 | sql_query_u="$sql_query_u artist='$f'" 287 | else 288 | sql_query_s="$sql_query_s artist like '%$f%'" 289 | sql_query_u="$sql_query_u artist like '%$f%'" 290 | fi 291 | fi 292 | if [ -n "$rating" ] ; then 293 | if [ -z "$first_condition" ] ; then 294 | sql_query_s="$sql_query_select WHERE" 295 | sql_query_u="$sql_query_update WHERE" 296 | first_condition=1 297 | elif [ -n "$first_condition" ] ; then 298 | sql_query_s="$sql_query_s AND" 299 | sql_query_u="$sql_query_u AND" 300 | fi 301 | sql_query_s="$sql_query_s rating=$rating" 302 | sql_query_u="$sql_query_u rating=$rating" 303 | fi 304 | if [ -n "$play_counts" ] ; then 305 | if [ -z "$first_condition" ] ; then 306 | sql_query_s="$sql_query_select WHERE" 307 | sql_query_u="$sql_query_update WHERE" 308 | first_condition=1 309 | elif [ -n "$first_condition" ] ; then 310 | sql_query_s="$sql_query_s AND" 311 | sql_query_u="$sql_query_u AND" 312 | fi 313 | sql_query_s="$sql_query_s play_count=$play_counts" 314 | sql_query_u="$sql_query_u play_count=$play_counts" 315 | fi 316 | if [ -n "$karma" ] ; then 317 | if [ -z "$first_condition" ] ; then 318 | sql_query_s="$sql_query_select WHERE" 319 | sql_query_u="$sql_query_update WHERE" 320 | first_condition=1 321 | elif [ -n "$first_condition" ] ; then 322 | sql_query_s="$sql_query_s AND" 323 | sql_query_u="$sql_query_u AND" 324 | fi 325 | sql_query_s="$sql_query_s karma=$karma" 326 | sql_query_u="$sql_query_u karma=$karma" 327 | fi 328 | if [ $do_update -eq 1 -a -n "$karma_val" ] ; then 329 | /usr/bin/sqlite3 -column -header "$stats_file" "$sql_query_s"; 330 | /usr/bin/sqlite3 "$stats_file" "$sql_query_u"; 331 | /usr/bin/sqlite3 -column -noheader "$stats_file" "$sql_query_s"; 332 | else 333 | /usr/bin/sqlite3 -column -header "$stats_file" "$sql_query_s"; 334 | fi 335 | exit 0 336 | # 337 | # $Log: karma.in,v $ 338 | # Revision 1.14 2024-12-23 19:08:21+05:30 Cprogrammer 339 | # fix for darwin 340 | # 341 | # Revision 1.13 2024-04-09 23:24:45+05:30 Cprogrammer 342 | # display scrobble command if running with a tty 343 | # 344 | # Revision 1.12 2024-04-08 22:49:51+05:30 Cprogrammer 345 | # added unlove function 346 | # 347 | # Revision 1.11 2023-07-05 22:00:13+05:30 Cprogrammer 348 | # added --love option to mark scrobble as loved 349 | # 350 | # Revision 1.10 2022-09-26 19:07:10+05:30 Cprogrammer 351 | # exit if getopt returns error 352 | # 353 | # Revision 1.9 2022-05-10 21:43:20+05:30 Cprogrammer 354 | # merged modifictions by https://github.com/Plexvol (use getopt) 355 | # 356 | # Revision 1.8 2021-10-15 20:02:56+05:30 Cprogrammer 357 | # set song_uri to current playing song if no options are provided 358 | # 359 | # Revision 1.7 2021-10-15 18:31:39+05:30 Cprogrammer 360 | # fixed update not working 361 | # 362 | # Revision 1.6 2021-10-14 22:39:14+05:30 Cprogrammer 363 | # fixed typo 364 | # 365 | # Revision 1.5 2021-10-11 00:32:37+05:30 Cprogrammer 366 | # fixed sql statement 367 | # 368 | # Revision 1.4 2021-09-30 20:30:25+05:30 Cprogrammer 369 | # use -noheader option to prevent .sqlitrc settings messing with results 370 | # 371 | # Revision 1.3 2021-09-30 11:39:51+05:30 Cprogrammer 372 | # display karma for current playing song when no options are provided 373 | # 374 | # Revision 1.2 2021-09-09 20:41:02+05:30 Cprogrammer 375 | # added missing help display for --value 376 | # 377 | # Revision 1.1 2021-04-24 11:46:17+05:30 Cprogrammer 378 | # Initial revision 379 | -------------------------------------------------------------------------------- /lastfm-scrobbler.1: -------------------------------------------------------------------------------- 1 | .TH lastfm-scrobbler 1 "July 3, 2020" "manual" 2 | .SH NAME 3 | .PP 4 | lastfm-scrobbler - lastfm scrobbler 5 | 6 | .SH SYNOPSIS 7 | .PP 8 | lastfm-scrobbler [\f[I]option\f[]] 9 | 10 | .SH DESCRIPTION 11 | A lastfm.fm (https://last.fm/) scrobbler for \fBmpdev\fR(1) / \fBmpdwatch\fR(1). 12 | 13 | lastfm-scrobbler has been cloned from https://goto.pachanka.org/moc-scrobbler. 14 | 15 | lastfm-scrobbler is a command line scrobbler for last.fm written as a 16 | bourne shell script. 17 | 18 | .EX 19 | USAGE: lastfm-scrobbler [OPTIONS] 20 | 21 | OPTIONS: 22 | 23 | Help: 24 | --help 25 | --help-connect 26 | --help-scrobble 27 | 28 | About: 29 | --version 30 | --about 31 | 32 | Connecting: 33 | --connect --api_key --api_sec 34 | 35 | Scrobbling: 36 | --artist --track --duration 37 | 38 | Trackinfo 39 | --info --artist --track 40 | 41 | Love: 42 | --love --artist --track --duration 43 | 44 | UnLove: 45 | --unlove --artist --track --duration 46 | 47 | Update Current Song: 48 | --update --artist --track --duration 49 | 50 | Stop: 51 | --stop 52 | .EE 53 | 54 | .SH Configuration 55 | 56 | Run the connect command and follow the instructions: 57 | 58 | .EX 59 | $ lastfm-scrobbler --connect 60 | .EE 61 | 62 | You need to have your own [last.fm API keys] (https://www.last.fm/api/account/create). 63 | 64 | .EX 65 | $ lastfm-scrobbler --connect --api_key="abc123" --api_sec="xyz890" 66 | .EE 67 | 68 | After you have added the connection you should have a 69 | `lastfm-scrobbler.conf` file in `~/.config/lastfm-scrobbler/` 70 | 71 | Other examples: 72 | 73 | .EX 74 | Scrobble a track 75 | $ lastfm-scrobbler --artist="test artist" --album="test album" --track="test track" --duration=420 76 | 77 | Love a track which has been scrobbled 78 | $ lastfm-scrobbler --love --artist="test artist" --album="test album" --track="test track" --duration=420 79 | .EE 80 | 81 | .SH SEE ALSO 82 | mpd(1), 83 | mpdev(1), 84 | mpdwatch(1), 85 | librefm-scrobbler(1) 86 | -------------------------------------------------------------------------------- /lcd_display.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # $Id: lcd_display.in,v 1.6 2023-06-30 20:28:25+05:30 Cprogrammer Exp mbhangui $ 4 | # 5 | # You need the nc command for this script to write to a remote LCD. nc 6 | # comes from the netcat package 7 | # If you have installed mpdev this script will get called. 8 | # 9 | # 1. If lcd-daemon is running locally you need to do nothing 10 | # 2. if lcd-daemon is running on a remote host, you need to set 11 | # LCD_HOST, LCD_PORT environment variable in /service/mpdev/variables 12 | # like this 13 | # echo w.x.y.z > /service/mpdev/variables/LCD_HOST 14 | # echo port > /service/mpdev/variables/LCD_PORT 15 | # 16 | 17 | set_command() 18 | { 19 | if [ -n "$LCD_FIFO" ] ; then 20 | cmd="/bin/cat > $LCD_FIFO" 21 | return 0 22 | elif [ -n "$LCD_HOST" ] ; then 23 | if [ -z "$LCD_PORT" ] ; then 24 | LCD_PORT=1806 25 | fi 26 | cmd="nc -w 1 -u $LCD_HOST $LCD_PORT" 27 | return 0 28 | fi 29 | if [ -d /run ] ; then 30 | lcdfifo="/run/lcd-daemon/lcdfifo" 31 | elif [ -d /var/run ] ; then 32 | lcdfifo="/var/run/lcd-daemon/lcdfifo" 33 | else 34 | lcdfifo="/tmp/lcd-daemon/lcdfifo" 35 | fi 36 | if [ -p $lcdfifo ] ; then 37 | cmd="/bin/cat > /run/lcd-daemon/lcdfifo" 38 | return 0 39 | elif [ -x /usr/bin/nc ] ; then 40 | if [ -n "$LCD_HOST" ] ; then 41 | lcdhost=$LCD_HOST 42 | else 43 | lcdhost=$(grep lcdhost /etc/hosts|awk '{print $1}') 44 | fi 45 | if [ -z "$LCD_PORT" ] ; then 46 | LCD_PORT=1806 47 | fi 48 | if [ -n "$lcdhost" ] ; then 49 | cmd="nc -w 1 -u $lcdhost $LCD_PORT" 50 | return 0 51 | fi 52 | fi 53 | exit 1 54 | } 55 | 56 | if [ -z "$MPDEV_TMPDIR" ] ; then 57 | MPDEV_TMPDIR=/tmp/mpdev 58 | fi 59 | 60 | case $1 in 61 | play) 62 | set_command 63 | echo "3 0 0:PL Vo $(mpc vol|cut -d: -f2|cut -d% -f1)" | sh -c "$cmd" 64 | ;; 65 | pause-song|pause) 66 | set_command 67 | echo "3 0 0:PS Vo $(mpc vol|cut -d: -f2|cut -d% -f1)" | sh -c "$cmd" 68 | ;; 69 | end-song) 70 | set_command 71 | echo "3 0 0:ST Vo $(mpc vol|cut -d: -f2|cut -d% -f1)" | sh -c "$cmd" 72 | ;; 73 | now-playing) 74 | set_command 75 | ( 76 | echo "0 0 2:$SONG_TITLE" 77 | echo "1 0 0:$SONG_ARTIST" 78 | echo "2 0 0:$SONG_ALBUM" 79 | printf "3 0 0:PL Vo %+3s R %2d P %d\n" $(mpc vol|cut -d: -f2|cut -d% -f1) $RATING $PLAYCOUNT 80 | ) | tee $MPDEV_TMPDIR/lcd.out | sh -c "$cmd" 81 | ;; 82 | mixer) 83 | set_command 84 | case "$PLAYER_STATE" in 85 | play) 86 | t=PL 87 | ;; 88 | pause) 89 | t=PS 90 | ;; 91 | stop) 92 | t=ST 93 | ;; 94 | *) 95 | t=$PLAYER_STATE 96 | ;; 97 | esac 98 | printf "3 0 0:%s Vo %+3s\n" "$t" $(mpc vol|cut -d: -f2|cut -d% -f1) | sh -c "$cmd" 99 | ;; 100 | esac 101 | -------------------------------------------------------------------------------- /librefm-scrobbler.1: -------------------------------------------------------------------------------- 1 | .TH librefm-scrobbler 1 "July 3, 2020" "manual" 2 | .SH NAME 3 | .PP 4 | librefm-scrobbler - librefm scrobbler 5 | 6 | .SH SYNOPSIS 7 | .PP 8 | librefm-scrobbler [\f[I]option\f[]] 9 | 10 | .SH DESCRIPTION 11 | A librefm.fm (https://libre.fm/) scrobbler for \fBmpdev\fR(1) / \fBmpdwatch\fR(1). 12 | 13 | librefm-scrobbler has been cloned from https://goto.pachanka.org/moc-scrobbler. 14 | 15 | librefm-scrobbler is a command line scrobbler for libre.fm written as a 16 | bourne shell script. 17 | 18 | .EX 19 | USAGE: librefm-scrobbler [OPTIONS] 20 | 21 | OPTIONS: 22 | 23 | Help: 24 | --help 25 | --help-connect 26 | --help-scrobble 27 | 28 | About: 29 | --version 30 | --about 31 | 32 | Connecting: 33 | --connect --api_key --api_sec 34 | 35 | Scrobbling: 36 | --artist --track --duration 37 | 38 | Trackinfo 39 | --info --artist --track 40 | 41 | Love: 42 | --love --artist --track --duration 43 | 44 | UnLove: 45 | --unlove --artist --track --duration 46 | 47 | Update Current Song: 48 | --update --artist --track --duration 49 | 50 | Stop: 51 | --stop 52 | .EE 53 | 54 | .SH Configuration 55 | 56 | Run the connect command and follow the instructions: 57 | 58 | .EX 59 | $ librefm-scrobbler --connect 60 | .EE 61 | 62 | You need to have your own [last.fm API keys](https://www.last.fm/api/account/create). 63 | Note that the last.fm API key works for libre.fm 64 | 65 | .EX 66 | $ librefm-scrobbler --connect --api_key="abc123" --api_sec="xyz890" 67 | .EE 68 | 69 | After you have added the connection you should have a 70 | `librefm-scrobbler.conf` file in `~/.config/librefm-scrobbler/` 71 | 72 | Other examples: 73 | 74 | .EX 75 | Scrobble a track 76 | $ librefm-scrobbler --artist="test artist" --album="test album" \ 77 | --track="test track" --duration=420 78 | 79 | Love a track which has been scrobbled 80 | $ librefm-scrobbler --love --artist="test artist" --album="test album" \ 81 | --track="test track" --duration=420 82 | .EE 83 | 84 | .SH SEE ALSO 85 | mpd(1), 86 | mpdev(1), 87 | mpdwatch(1), 88 | lastfm-scrobbler(1) 89 | -------------------------------------------------------------------------------- /mixer.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # $Log: mixer.in,v $ 4 | # Revision 1.2 2023-06-26 15:56:54+05:30 Cprogrammer 5 | # added lcd_display 6 | # 7 | # Revision 1.1 2021-09-09 17:09:45+05:30 Cprogrammer 8 | # Initial revision 9 | # 10 | # 11 | # $Id: mixer.in,v 1.2 2023-06-26 15:56:54+05:30 Cprogrammer Exp mbhangui $ 12 | # 13 | echo "$0: args=$*" 14 | echo volume=$VOLUME 15 | if [ -n "$LCD_HOST" -a -n "$LCD_PORT" -a -x $HOME/.mpdev/lcd_display ] ; then 16 | $HOME/.mpdev/lcd_display "mixer" 17 | fi 18 | exit 0 19 | -------------------------------------------------------------------------------- /moc-scrobbler-license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 pachanka 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /mpd_local.te: -------------------------------------------------------------------------------- 1 | module mpd_local 1.0; 2 | 3 | require { 4 | type alsa_home_t; 5 | type alsa_var_lib_t; 6 | type config_home_t; 7 | type mpd_home_t; 8 | type mpd_port_t; 9 | type mpd_t; 10 | type nfs_t; 11 | type unconfined_service_t; 12 | type user_home_dir_t; 13 | type var_run_t; 14 | class dir { search }; 15 | class file { getattr open read }; 16 | class sock_file write; 17 | class tcp_socket { listen name_bind name_connect accept create node_bind setopt bind getattr }; 18 | class unix_stream_socket connectto; 19 | } 20 | #============= mpd_t ============== 21 | allow mpd_t alsa_home_t:file { getattr open read }; 22 | allow mpd_t alsa_var_lib_t:dir search; 23 | allow mpd_t config_home_t:dir search; 24 | allow mpd_t mpd_port_t:tcp_socket name_connect; 25 | allow mpd_t nfs_t:dir search; 26 | allow mpd_t var_run_t:sock_file write; 27 | allow mpd_t user_home_dir_t:dir search; 28 | allow mpd_t unconfined_service_t:unix_stream_socket connectto; 29 | -------------------------------------------------------------------------------- /mpdev-release.in: -------------------------------------------------------------------------------- 1 | NAME=@PACKAGE@ 2 | Description="@PACKAGE_NAME@ - MPD Event Watcher" 3 | version="@PACKAGE_VERSION@" 4 | ID=@PACKAGE@ 5 | HOME_URL="@PACKAGE_URL@" 6 | PACKAGE_BUGREPORT='@PACKAGE_BUGREPORT@' 7 | -------------------------------------------------------------------------------- /mpdev.1: -------------------------------------------------------------------------------- 1 | .\" vim: tw=75 2 | .TH mpdev 1 "December 23, 2009" "manual" 3 | .SH NAME 4 | .PP 5 | mpdev - mpd Event Watcher 6 | .SH SYNOPSIS 7 | .PP 8 | mpdev [\f[I]options\f[]] 9 | 10 | .SH DESCRIPTION 11 | 12 | \fBmpdev\fR(1) is a mpd event watcher. It connects to mpd, waits for idle 13 | events. By default it will get the host name and port for mpd from 14 | \f[B]MPD_HOST\f[] and \f[B]MPD_PORT\f[] environment variables. 15 | \f[B]MPD_PASSWORD\f[] environment variable can be set to make 16 | \fBmpdev\fR(1) connect to a password-protected mpd. If these environment 17 | variables aren't set, \fBmpdev\fR(1) connects to localhost on port 6600. 18 | 19 | .SH OPTIONS 20 | .TP 3 21 | .B -v 22 | Set verbose output. You can increase verbosity by specifying it multiple 23 | times 24 | .RS 25 | .RE 26 | 27 | .TP 28 | \fB-h\fR \fIhost\fR / \fIIP\fR 29 | Host or IP address of mpd host if different from localhost 30 | .RS 31 | .RE 32 | 33 | .TP 34 | \fB-p\fR \fIport\fR 35 | port on which mpd(1) is listening if different from 6600 36 | .RS 37 | .RE 38 | 39 | .TP 40 | \fB-s\fR \fIunix_socket\fR 41 | Unix domain socket in case you don't want to use \fIIP\fR and \fIport\fR 42 | .RS 43 | .RE 44 | 45 | .TP 46 | \fB-r\fR \fIretry_interval\fR 47 | Retry interval in seconds in case \fBmpd\fR(1) is down 48 | .RS 49 | .RE 50 | 51 | .SH HOOKS 52 | You can create scripts in $HOME/.mpdev directory. The default installation 53 | installs a script named $HOME/.mpdev/player for the uid 1000. The script 54 | does the following 55 | 56 | .IP \[bu] 4 57 | scrobbles titles to last.fm and libre.fm. You have to create API keys by 58 | running lastfm-scrobbler and librefm-scrobbler one time. You can disable 59 | scrobbling by setting DISABLE_SCROBBLE environment variable 60 | .sp -1 61 | .IP \[bu] 62 | updates play counts in the sqlite stats.db. All db updates get disabled if 63 | you set \fBNO_DB_UPDATE\fR environment variable. 64 | .sp -1 65 | .IP \[bu] 66 | Synchronizes the ratings in the sticker (sqlite). It also initializes the 67 | rating to 3 when you play an unrated song. All db updates get disabled if 68 | you set \fBNO_DB_UPDATE\fR environment variable. 69 | .PP 70 | 71 | You can put your own script named `player` in this directory. In fact 72 | \fBmpdev\fR(1) can run specific hooks for specific types of mpd events. A 73 | hook can be any executable program or script. It will be passed arguments 74 | and have certain environment variables related to the song playing, 75 | available to it. Apart from the \fBplayer\fR script, the default 76 | installation will put the following scripts 77 | 78 | .EX 79 | \fBplaypause\fR - This gets executed when you pause or play a song 80 | \fBmixer\fR - This gets executed when you change the mixer volume 81 | \fBoutput\fR - This gets executed when you enable or disable any output 82 | .EE 83 | 84 | Below is a list of of events and corresponding hooks that will be executed 85 | if available. 86 | 87 | .TS 88 | l l. 89 | MPD EVENT | Hook script 90 | _ 91 | SONG_CHANGE | ~/.mpdev/player 92 | PLAY/PAUSE | ~/.mpdev/playpause 93 | STICKER_EVENT | ~/.mpdev/sticker 94 | MIXER_EVENT | ~/.mpdev/mixer 95 | OUTPUT_EVENT | ~/.mpdev/output 96 | OPTIONS_EVENT | ~/.mpdev/options 97 | UPDATE_EVENT | ~/.mpdev/update 98 | DATABASE_EVENT | ~/.mpdev/database 99 | PLAYLIST_EVENT | ~/.mpdev/playlist 100 | STORED_PLAYLIST_EVENT | ~/.mpdev/stored_playlist 101 | PARTITION_EVENT | ~/.mpdev/partition 102 | SUBSCRIPTION_EVENT | ~/.mpdev/subscription 103 | MESSAGE_EVENT | ~/.mpdev/message 104 | MOUNT_EVENT | ~/.mpdev/mount 105 | NEIGHBOUR_EVENT | ~/.mpdev/neighbour 106 | CUSTOM_EVENT | ~/.mpdev/custom 107 | .TE 108 | 109 | The hooks are passed the following arguments 110 | 111 | .IP \[bu] 4 112 | mpd-event - Passed when the above events listed, apart from 113 | SONG_CHANGE happen. 114 | .sp -1 115 | .IP \[bu] 116 | player-event - Passed to ~/.mpdev/playpause when you play/pause player 117 | .sp -1 118 | .IP \[bu] 119 | playlist-event - Passed to ~/.mpdev/playlist when the playlist changes 120 | .sp -1 121 | .IP \[bu] 122 | now-playing - Passed to ~/.mpdev/player when a song starts playing 123 | .sp -1 124 | .IP \[bu] 125 | end-song - Passed to ~/.mpdev/player when a song finishes playing 126 | .sp -1 127 | .IP \[bu] 128 | output-event - Passed to ~/.mpdev/output script when any device outputs 129 | are enabled or disabled 130 | 131 | .SH Environment Variables 132 | 133 | \fBmpdev\fR(1) sets the following environment variables 134 | 135 | .EX 136 | SONG_ID - Set to the ID from mpd database 137 | SONG_URI - Set to the full path of the music file 138 | SONG_TITLE - Set to the title of the song 139 | SONG_ARTIST - Set to the song artist 140 | SONG_ALBUM - Set to the song album 141 | SONG_DATE - Set to the Date tag of the song 142 | SONG_GENRE - Set to the Genre tag of the song 143 | SONG_TRACK - Set to the track number of the song 144 | SONG_DURATION - Set to the song duration 145 | ELAPSED_TIME - Total time elapsed within the current song in seconds, 146 | but with higher resolution 147 | SONG_PLAYED - Set to the duration for which the song was played 148 | SONG_LAST_MODIFIED - Set to the last modified time of the song 149 | START_TIME - Time at which the song play started 150 | END_TIME - Time at which the song ended 151 | PLAYER_STATE - Set when you pause/resume player 152 | VERBOSE - Set to the verbose field 153 | OUTPUT_CHANGED - Set when you enable or disable any output devices. 154 | This indicates the new state of an output device. 155 | VOLUME - Set during startup and when you change mixer volume. 156 | This indicates the volume level as a percentage. 157 | .EE 158 | 159 | if \fI$HOME/.config/lastfm-scrobbler\fR & 160 | \fI$HOME/.config/librefm-scrobbler\fR are present, \fBmpdev\fR(1) sets 161 | SCROBBLER_LASTFM and SCROBBLER_LIBREFM environment variables respectively. 162 | These get created when you create API keys for lastfm, librefm by running 163 | lastfm-scrobbler and librefm-scrobbler one time with --connect argument. 164 | 165 | \fBmpdev\fR(1) also runs OUTPUT_EVENT on startup ($HOME/.mpdev/output), 166 | with the argument output-initialize. This allows you to store information 167 | for devices configured in your \fBmpd.conf\fR(5). If any output changes, 168 | the environment variable OUTPUT_CHANGED is set in the form 169 | 170 | .TP 2 171 | "\fIDEVNO\fR - \fIstate\fR" 172 | 173 | Where \fIDEVNO\fR is the ID of the device in mpd.conf (0, 1, 2, etc) and 174 | \fIstate\fR is either the word "enabled" or "disabled". 175 | 176 | .PP 177 | So, in the below example, if you disable the headphone, 178 | \fBOUTPUT_CHANGED\fR environment variable will be set as "3 - disabled" 179 | 180 | All devices are maintained in the environment variables 181 | \fBOUTPUT_\fR\fIDEVNO\fR\fB_ID\fR, \fBOUTPUT_\fR\fIDEVNO\fR\fB_NAME\fR, 182 | \fBOUTPUT_\fR\fIDEVNO\fR\fB_STATE\fR, \fBOUTPUT_\fR\fIDEVNO\fR\fB_TYPE\fR, 183 | \fBOUTPUT_\fR\fIDEVNO\fR\fB_EXTRA1\fR, 184 | \fBOUTPUT_\fR\fIDEVNO\fR\fB_EXTRA2\fR, 185 | \fBOUTPUT_\fR\fIDEVNO\fR\fB_EXTRA...\fR 186 | \fBOUTPUT_\fR\fIDEVNO\fR\fB_EXTRAn\fR 187 | 188 | Here \fIDEVNO\fR is the device id of the audio device in mpd.conf. 189 | 190 | Below is an example of the state of environment variables where mpd.conf 191 | have 3 devices configured (Piano DAC Plus 2.1, Xonar EssenceOne, Scarlet 2i2 USB). 192 | 193 | .EX 194 | OUTPUT_0_ID=0 195 | OUTPUT_0_NAME=Piano DAC Plus 2.1 196 | OUTPUT_0_STATE=enabled 197 | OUTPUT_1_ID=1 198 | OUTPUT_1_NAME=Xonar EssenceOne 199 | OUTPUT_1_STATE=disabled 200 | OUTPUT_2_ID=2 201 | OUTPUT_2_NAME=Scarlett 2i2 USB 202 | OUTPUT_2_STATE=disabled 203 | .EE 204 | 205 | .SH SEE ALSO 206 | .IP \[bu] 2 207 | \f[B]mpd\f[](1), 208 | \f[B]mpd.conf\f[](5), 209 | \f[B]sqlite3\f[](1), 210 | \f[B]lastfm-scrobbler\f[](1), 211 | \f[B]librefm-scrobbler\f[](1), 212 | \f[B]karma\f[](1), 213 | \f[B]mpdev_cleanup\f[](1), 214 | \f[B]mpdev_rename\f[](1), 215 | \f[B]mpdev_update\f[](1), 216 | \f[B]mpdplaylist\f[](1), 217 | \f[B]transfer_play\f[](1) 218 | .IP \[bu] 2 219 | https://github.com/mbhangui/mpdev/ 220 | 221 | .SH REPORTING BUGS 222 | .PP 223 | If you find a bug, please report it at https://github.com/mbhangui/mpdev/issues 224 | 225 | .SH COPYRIGHT 226 | .PP 227 | Copyright (c) 2020 Manvendra Bhangui 228 | .PD 0 229 | .P 230 | .PD 231 | Free 232 | use of this software is granted under the terms of the GNU General 233 | Public License (GPLv2). 234 | .SH AUTHOR 235 | Manvendra Bhangui 236 | -------------------------------------------------------------------------------- /mpdev.spec.in: -------------------------------------------------------------------------------- 1 | %undefine _missing_build_ids_terminate_build 2 | %global _unpackaged_files_terminate_build 1 3 | %global debug_package %{nil} 4 | 5 | %if %{defined _project} 6 | # define if building on openSUSE build service 7 | %global build_on_obs 1 8 | %global reconfigure_mode 0 9 | %else 10 | %define _project local 11 | %global build_on_obs 0 12 | %global reconfigure_mode 0 13 | %global _hardened_build 1 14 | %endif 15 | %global _prefix /usr 16 | %global libexecdir @libexecdir@ 17 | %global sysconfdir @sysconfdir@ 18 | %global logdir /var/log/svc/mpdev 19 | 20 | Name: mpdev 21 | Version: @version@ 22 | Release: @release@%{?dist} 23 | Summary: MPD Event Watcher 24 | %if %build_on_obs == 1 25 | License: GPL-3.0+ 26 | %else 27 | License: GPLv3 28 | %endif 29 | URL: https://github.com/mbhangui/mpdev 30 | Source0: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar.gz 31 | 32 | BuildRequires: gcc gcc-c++ make autoconf automake libtool 33 | %if %build_on_obs == 1 34 | %if 0%{?suse_version} 35 | BuildRequires: -post-build-checks 36 | #!BuildIgnore: post-build-checks 37 | %endif 38 | %endif 39 | BuildRequires: libqmail-devel libqmail 40 | %if %{defined suse_version} || %{defined sles_version} 41 | BuildRequires: libsqlite3-0 sqlite3-devel 42 | %else 43 | BuildRequires: sqlite-libs sqlite-devel 44 | %endif 45 | Requires: user(qmaill) 46 | Requires: group(nofiles) 47 | Requires: /usr/bin/mpd /usr/bin/mpc /usr/bin/sqlite3 daemontools coreutils 48 | 49 | %description 50 | mpdev is a daemon, written in C, that watches a Music Player Daemon events, 51 | using mpd's idle command and execs user defined script on event changes. 52 | 53 | * Uses mpd's idle mode. 54 | * Calls user scripts in $HOME/.mpdev (player, playpause, output, mixer, 55 | lcd_display) 56 | * Sets special environment variables to pass data to the hooks. 57 | * Optional support for scrobbling to last.fm, libre.fm through external scripts 58 | * Included scripts: 59 | - scrobbler 60 | + librefm-scrobbler 61 | + lastfm-scrobbler 62 | - player 63 | + saves song data to a sqlite database 64 | + tracks play count of songs, artist, albums and genres. 65 | + helps chose songs based on listening habits using mpdplaylist 66 | playlist generator 67 | + synchronizes stats and mpd's sticker db 68 | - mixer 69 | + prints volume control value 70 | - lcd_display 71 | + prints song information to a host running lcdDaemon for 72 | display on a display with Hitachi HD44780 controller 73 | 74 | %prep 75 | %autosetup 76 | 77 | %build 78 | %configure --prefix=%{_prefix} --sysconfdir=/etc \ 79 | --libexecdir=%{libexecdir} 80 | %{__make} -s %{?_smp_mflags} 81 | ( 82 | echo "---------------- INFORMATION ------------------------" 83 | echo target %_target 84 | echo target_alias %_target_alias 85 | echo target_cpu %_target_cpu 86 | echo target_os %_target_os 87 | echo target_vendor %_target_vendor 88 | echo Project %{_project} 89 | echo Building %{name}-%{version}-%{release} Build %{_build} OS %{_os} 90 | echo "------------------------------------------------------" 91 | ) > %{name}-rpm.info 92 | 93 | %install 94 | %{__make} -s DESTDIR=%{buildroot} install-strip 95 | %{__mkdir_p} %{buildroot}%{sysconfdir}/mpdev 96 | install -m 0644 %{name}-rpm.info %{buildroot}%{sysconfdir}/mpdev/%{name}-rpm.info 97 | 98 | %files 99 | %dir %attr(755,root,root) %{libexecdir}/mpdev 100 | %ghost %dir %attr(0755,qmaill,nofiles) %{logdir} 101 | %ghost %attr(-,qmaill,nofiles) %{logdir}/* 102 | %attr(755,root,root) %{_prefix}/bin/mpdev 103 | %attr(755,root,root) %{_prefix}/bin/mpdplaylist 104 | %attr(755,root,root) %{_prefix}/bin/karma 105 | %attr(755,root,root) %{_prefix}/bin/songi 106 | %attr(755,root,root) %{_prefix}/bin/mpdhist 107 | %attr(755,root,root) %{_prefix}/bin/transfer_play 108 | %attr(755,root,root) %{_prefix}/bin/lastfm-scrobbler 109 | %attr(755,root,root) %{_prefix}/bin/librefm-scrobbler 110 | %attr(755,root,root) %{libexecdir}/mpdev/mpdev_update 111 | %attr(755,root,root) %{libexecdir}/mpdev/mpdev_cleanup 112 | %attr(755,root,root) %{libexecdir}/mpdev/mpdev_rename 113 | %attr(755,root,root) %{libexecdir}/mpdev/create_service 114 | %attr(755,root,root) %{libexecdir}/mpdev/player 115 | %attr(755,root,root) %{libexecdir}/mpdev/playpause 116 | %attr(755,root,root) %{libexecdir}/mpdev/output 117 | %attr(755,root,root) %{libexecdir}/mpdev/mixer 118 | %attr(755,root,root) %{libexecdir}/mpdev/lcd_display 119 | %attr(644,root,root) %{sysconfdir}/mpdev/mpd_local.te 120 | %attr(644,root,root) %{sysconfdir}/mpdev/%{name}-release 121 | %attr(644,root,root) %{sysconfdir}/mpdev/%{name}-rpm.info 122 | 123 | %attr(644,root,root) %{_prefix}/share/man/man1/mpdev.1.gz 124 | %attr(644,root,root) %{_prefix}/share/man/man1/songi.1.gz 125 | %attr(644,root,root) %{_prefix}/share/man/man1/mpdev_update.1.gz 126 | %attr(644,root,root) %{_prefix}/share/man/man1/mpdev_cleanup.1.gz 127 | %attr(644,root,root) %{_prefix}/share/man/man1/mpdev_rename.1.gz 128 | %attr(644,root,root) %{_prefix}/share/man/man1/mpdplaylist.1.gz 129 | %attr(644,root,root) %{_prefix}/share/man/man1/karma.1.gz 130 | %attr(644,root,root) %{_prefix}/share/man/man1/mpdhist.1.gz 131 | %attr(644,root,root) %{_prefix}/share/man/man1/transfer_play.1.gz 132 | %attr(644,root,root) %{_prefix}/share/man/man1/lastfm-scrobbler.1.gz 133 | %attr(644,root,root) %{_prefix}/share/man/man1/librefm-scrobbler.1.gz 134 | 135 | %license LICENSE 136 | 137 | %docdir %{_prefix}/share/doc/%{name} 138 | %if %build_on_obs == 0 139 | %license %attr(644,root,root) %{_prefix}/share/doc/%{name}/LICENSE 140 | %license %attr(644,root,root) %{_prefix}/share/doc/%{name}/moc-scrobbler-license 141 | %else 142 | %attr(644,root,root) %{_prefix}/share/doc/%{name}/LICENSE 143 | %attr(644,root,root) %{_prefix}/share/doc/%{name}/moc-scrobbler-license 144 | %endif 145 | %attr(644,root,root) %{_prefix}/share/doc/%{name}/README.md 146 | %attr(644,root,root) %{_prefix}/share/doc/%{name}/mpdev.changes 147 | 148 | %pretrans 149 | # stop mpdev services before upgrade 150 | if [ -d /run ] ; then 151 | rundir=/run/svscan 152 | elif [ -d /var/run ] ; then 153 | rundir=/var/run/svscan 154 | else 155 | rundir=/service 156 | fi 157 | %{_prefix}/bin/svstat /service/mpdev >/dev/null 2>&1 158 | if [ $? -eq 0 ] ; then 159 | %{__mkdir_p} ${rundir}/mpdev 160 | %{_prefix}/bin/svc -d /service/mpdev 161 | touch ${rundir}/mpdev/.down 162 | fi 163 | 164 | %post 165 | argv1=$1 166 | ID=$(id -u) 167 | if [ $ID -ne 0 ] ; then 168 | echo "You are not root" 1>&2 169 | exit 1 170 | fi 171 | if [ -z "$argv1" ] ; then 172 | argv1=0 173 | fi 174 | if [ ! -x %{_prefix}/sbin/minisvc ] ; then 175 | echo "%{_prefix}/sbin/minisvc not found: Proceeding without creating mpdev service" 1>&2 176 | exit 0 177 | fi 178 | # we are doing upgrade 179 | if [ $argv1 -eq 2 ] ; then # upgrade 180 | if [ -d /run ] ; then 181 | rundir=/run/svscan 182 | elif [ -d /var/run ] ; then 183 | rundir=/var/run/svscan 184 | else 185 | rundir=/service 186 | fi 187 | # refresh mpdev services 188 | if [ ! -f /service/mpdev/variables/.options ] ; then 189 | %{__mkdir_p} /service/mpdev/variables 190 | echo "/usr/libexec/mpdev/create_service --servicedir=/service --user=1000 --add-service" \ 191 | > /service/mpdev/variables/.options 192 | fi 193 | %{_prefix}/sbin/minisvc --servicedir=/service --refreshsvc="/service/mpdev" --silent 194 | %{_prefix}/bin/svok /service/mpdev >/dev/null 2>&1 195 | if [ $? -eq 0 -a -f ${rundir}/mpdev/.down ] ; then 196 | %{__rm} -f ${rundir}/mpdev/.down 197 | %{_prefix}/bin/svc -u /service/mpdev 198 | fi 199 | exit 0 200 | fi 201 | /usr/libexec/mpdev/create_service --servicedir=/service --user=1000 --add-service 202 | %{_prefix}/sbin/minisvc --servicedir=/service --service-name=mpdev \ 203 | --export-variables=/service/mpdev/variables/.variables --force --silent 204 | 205 | %preun 206 | argv1=$1 207 | ID=$(id -u) 208 | if [ $ID -ne 0 ] ; then 209 | echo "You are not root" 1>&2 210 | exit 1 211 | fi 212 | if [ -z "$argv1" ] ; then 213 | argv1=0 214 | fi 215 | # we are doing upgrade 216 | if [ $argv1 -eq 1 ] ; then 217 | exit 0 218 | fi 219 | echo "removing mpdev logs" 220 | log_dir=%{logdir} 221 | [ "$log_dir" != "/" ] && %{__rm} -fr $log_dir 222 | echo "stopping and removing mpdev service" 223 | /usr/libexec/mpdev/create_service --servicedir=/service --del-service 224 | 225 | %changelog 226 | -------------------------------------------------------------------------------- /mpdev_cleanup.1: -------------------------------------------------------------------------------- 1 | .TH mpdev_cleanup 1 "Jul 13, 2020" "manual" 2 | .SH NAME 3 | .PP 4 | mpdev_cleanup - mpdev_cleanup stats / sticker mpd database entries 5 | .SH SYNOPSIS 6 | .PP 7 | mpdev_cleanup [\f[I]option\f[]] 8 | 9 | .SH DESCRIPTION 10 | .PP 11 | \fBmpdev_cleanup\fR(1) cleans the stats.db or sticker.db sqlite database by 12 | removing entries that do not correspond to a valid path to a music file. 13 | 14 | It can operate using either of the two modes below 15 | 16 | .EX 17 | 1. Check the presence of a file on the disk (uses access(2) system call). 18 | 2. Check the presence of a file in mpd database (loads mpd database into memory) 19 | .EE 20 | 21 | Checking against the mpd(1) database is faster than using the access(2) call. 22 | However, if the mpd(1) database has not been updated, there could be entries 23 | in the mpd(1) database which do not correspond to any music file on the disk. 24 | You can use the mpc(1) update command to update the mpd(1) database before 25 | using the mpdev_cleanup(1) command. 26 | 27 | Examples 28 | 29 | .EX 30 | # Use mpd database as reference 31 | 32 | $ mpdev_cleanup -c -d /var/lib/mpd/MDrive/data/stats.db 33 | $ mpdev_cleanup -C -d /var/lib/mpd/MDrive/data/sticker.db 34 | 35 | # Use the filesystem as reference 36 | 37 | $ mpdev_cleanup -c -m /var/lib/mpd/Music -d /var/lib/mpd/MDrive/data/stats.db 38 | $ mpdev_cleanup -C -m /var/lib/mpd/Music -d /var/lib/mpd/MDrive/data/sticker.db 39 | .EE 40 | 41 | .SH OPTIONS 42 | .TP 3 43 | .B -v 44 | Set verbose output. You can increase verbosity by specifying it multiple times 45 | .RS 46 | .RE 47 | 48 | .TP 3 49 | \fB-i\fR \fIIP\fR 50 | IP address of mpd host if different from localhost 51 | .RS 52 | .RE 53 | 54 | .TP 3 55 | \fB-p\fR \fIport\fR 56 | port on which mpd(1) is listening if different from 6600 57 | .RS 58 | .RE 59 | 60 | .TP 3 61 | \fB-s\fR \fIunix_socket\fR 62 | Unix domain socket in case you don't want to use \fIIP\fR and \fIport\fR 63 | .RS 64 | .RE 65 | 66 | .TP 3 67 | \fB-d\fR \fIdb_file_path\fR 68 | full path to the sqlite3(1) stats database 69 | .RS 70 | .RE 71 | 72 | .TP 3 73 | \fB-m\fR \fImusic_directory\fR 74 | Full path to the \fImusic_directory\fR in the mpd.conf(5) configuration file. 75 | .RS 76 | .RE 77 | 78 | .TP 3 79 | .B -c 80 | Clean entries from the stats.db sqlite database 81 | .RS 82 | .RE 83 | 84 | .TP 3 85 | .B -C 86 | Clean entries from the sticker.db sqlite database 87 | .RS 88 | .RE 89 | 90 | .SH REPORTING BUGS 91 | .PP 92 | If you find a bug, please report it at https://github.com/mbhangui/mpdev/issues 93 | 94 | .SH COPYRIGHT 95 | .PP 96 | Copyright (c) 2020 Manvendra Bhangui 97 | .PD 0 98 | .P 99 | .PD 100 | Free 101 | use of this software is granted under the terms of the GNU General 102 | Public License (GPLv2). 103 | .SH AUTHOR 104 | Manvendra Bhangui 105 | 106 | .SH SEE ALSO 107 | mpd(1), 108 | mpc(1), 109 | sqlite3(1), 110 | mpdev(1) 111 | mpdev_update(1), 112 | access(2) 113 | -------------------------------------------------------------------------------- /mpdev_cleanup.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Log: mpdev_cleanup.c,v $ 3 | * Revision 1.5 2025-01-26 16:45:47+05:30 Cprogrammer 4 | * fix gcc14 errors 5 | * 6 | * Revision 1.4 2022-05-10 21:31:23+05:30 Cprogrammer 7 | * use tcpopen from standard include path 8 | * 9 | * Revision 1.3 2020-08-08 11:07:46+05:30 Cprogrammer 10 | * fixed usage, error messages 11 | * 12 | * Revision 1.2 2020-07-28 12:40:52+05:30 Cprogrammer 13 | * made -m optional 14 | * 15 | * Revision 1.1 2020-07-19 18:16:35+05:30 Cprogrammer 16 | * Initial revision 17 | * 18 | * 19 | * mpdev_cleanup - utility to clean entries from stats/sticker sqlite db 20 | * 21 | */ 22 | #ifdef HAVE_CONFIG_H 23 | #include "config.h" 24 | #endif 25 | #ifdef HAVE_SQLITE3 26 | #include 27 | #endif 28 | #ifdef HAVE_UNISTD_H 29 | #include 30 | #endif 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include "replacestr.h" 45 | 46 | #ifndef lint 47 | static char sccsid[] = "$Id: mpdev_cleanup.c,v 1.5 2025-01-26 16:45:47+05:30 Cprogrammer Exp mbhangui $"; 48 | #endif 49 | 50 | ssize_t safewrite(int, char *, size_t); 51 | ssize_t saferead(int, char *, size_t); 52 | 53 | substdio mpdin, mpdout, ssout, sserr; 54 | static stralloc line = {0}, tmp = {0}; 55 | int timeout = 1200, disk_mode = 0, verbose; 56 | char method = 0; 57 | static sqlite3 *db, *memdb; 58 | char *usage = 59 | "usage: mpdev_cleanup [-i IP/Host | -s unix_socket] [-p port]\n" 60 | " -h IP - IP address of MPD host. default 127.0.0.1\n" 61 | " -p port - MPD listening port. default 6600\n" 62 | " -s unix - domain socket path\n" 63 | " -m path - music directory path\n" 64 | " -d path - sqlite3 dbfile path\n" 65 | " -D - Use disk mode\n" 66 | " -c - Clean stats db\n" 67 | " -C - Clean sticker db\n" 68 | " -v - verbose output"; 69 | 70 | void 71 | die_write(char *arg) 72 | { 73 | if (db) 74 | sqlite3_close(db); 75 | substdio_puts(&sserr, "Requested action aborted: write error"); 76 | if (arg) { 77 | substdio_put(&sserr, ": ", 2); 78 | substdio_puts(&sserr, arg); 79 | } 80 | substdio_put(&sserr, "\n", 1); 81 | substdio_flush(&sserr); 82 | _exit(111); 83 | } 84 | 85 | void 86 | out(char *s) 87 | { 88 | if (substdio_puts(&ssout, s) == -1) 89 | die_write(0); 90 | } 91 | 92 | void 93 | flush() 94 | { 95 | if (substdio_flush(&ssout) == -1) 96 | die_write("stdout"); 97 | } 98 | 99 | void 100 | err_out(char *s) 101 | { 102 | if (substdio_puts(&sserr, s) == -1) 103 | die_write(0); 104 | } 105 | 106 | void 107 | err_flush() 108 | { 109 | if (substdio_flush(&sserr) == -1) 110 | die_write("sserr"); 111 | } 112 | 113 | void 114 | die_read(char *arg) 115 | { 116 | if (db) 117 | sqlite3_close(db); 118 | if (arg) { 119 | substdio_put(&sserr, "Requested action aborted: ", 26); 120 | substdio_puts(&sserr, arg); 121 | substdio_put(&sserr, ": read error\n", 13); 122 | } else 123 | substdio_puts(&sserr, "Requested action aborted: read error\n"); 124 | substdio_flush(&sserr); 125 | _exit(111); 126 | } 127 | 128 | void 129 | die_alarm() 130 | { 131 | if (db) 132 | sqlite3_close(db); 133 | substdio_puts(&sserr, "Requested action aborted: timeout\n"); 134 | substdio_flush(&sserr); 135 | _exit(111); 136 | } 137 | 138 | void 139 | die_nomem() 140 | { 141 | if (db) 142 | sqlite3_close(db); 143 | substdio_puts(&sserr, "mpdev: out of memory\n"); 144 | substdio_flush(&sserr); 145 | _exit(111); 146 | } 147 | 148 | ssize_t 149 | saferead(int fd, char *buf, size_t len) 150 | { 151 | int r; 152 | 153 | if ((r = timeoutread(timeout, fd, buf, len)) == -1) { 154 | if (errno == error_timeout) 155 | die_alarm(); 156 | } 157 | if (r < 0) 158 | die_read(0); 159 | return r; 160 | } 161 | 162 | ssize_t 163 | safewrite(int fd, char *buf, size_t len) 164 | { 165 | int r; 166 | 167 | if ((r = timeoutwrite(timeout, fd, buf, len)) <= 0) 168 | die_write(0); 169 | return r; 170 | } 171 | 172 | int 173 | database_init(int transaction_mode, sqlite3_stmt **r_res, sqlite3_stmt **w_res) 174 | { 175 | char *sql, *err_msg; 176 | 177 | *r_res = *w_res = (sqlite3_stmt *) 0; 178 | if (sqlite3_open(":memory:", &memdb) != SQLITE_OK) 179 | strerr_die2x(111, "sqlite3_open: memdb: ", (char *) sqlite3_errmsg(memdb)); 180 | if (transaction_mode) { 181 | if (sqlite3_exec(memdb, "BEGIN TRANSACTION", NULL, NULL, &err_msg) != SQLITE_OK) { 182 | sqlite3_close(memdb); 183 | strerr_die2x(111, "BEGIN TRANSACTION: ", err_msg); 184 | } 185 | if (err_msg) 186 | sqlite3_free(err_msg); 187 | } 188 | sql = "CREATE TABLE IF NOT EXISTS temp(\n" 189 | "id INTEGER PRIMARY KEY,\n" 190 | "uri TEXT UNIQUE NOT NULL\n" 191 | ")"; 192 | if (sqlite3_exec(memdb, sql, 0, 0, &err_msg) != SQLITE_OK) { 193 | sqlite3_close(memdb); 194 | strerr_die4x(111, "sqlite3_exec: ", sql, ": ", err_msg); 195 | } 196 | if (err_msg) 197 | sqlite3_free(err_msg); 198 | sql = "INSERT or IGNORE into temp (uri) values (@uri)"; 199 | if (sqlite3_prepare_v2(memdb, sql, -1, w_res, 0) != SQLITE_OK) { 200 | sqlite3_close(memdb); 201 | strerr_die4x(111, "sqlite3_prepare_v2: ", sql, ": ", (char *) sqlite3_errmsg(db)); 202 | } 203 | sql = "SELECT uri from temp where uri=@uri"; 204 | if (sqlite3_prepare_v2(memdb, sql, -1, r_res, 0) != SQLITE_OK) { 205 | sqlite3_close(memdb); 206 | strerr_die4x(111, "sqlite3_prepare_v2: ", sql, ": ", (char *) sqlite3_errmsg(db)); 207 | } 208 | return (0); 209 | } 210 | 211 | void 212 | insert_data(sqlite3_stmt *res, char *stmt, unsigned long *processed, unsigned long *failure) 213 | { 214 | sqlite3_bind_text(res, 1, stmt, -1, SQLITE_STATIC); 215 | if (sqlite3_step(res) != SQLITE_DONE) 216 | *failure += 1; 217 | else 218 | *processed += 1; 219 | sqlite3_clear_bindings(res); 220 | sqlite3_reset(res); 221 | } 222 | 223 | void 224 | database_end(int transaction_mode) 225 | { 226 | char *sql, *err_msg; 227 | 228 | sql = "CREATE INDEX IF NOT EXISTS uri on temp(uri);"; 229 | if (sqlite3_exec(memdb, sql, 0, 0, &err_msg) != SQLITE_OK) { 230 | sqlite3_close(memdb); 231 | strerr_die4x(111, "sqlite3_exiec: ", sql, ": ", err_msg); 232 | } 233 | if (err_msg) 234 | sqlite3_free(err_msg); 235 | if (transaction_mode) { 236 | if (sqlite3_exec(memdb, "END TRANSACTION", 0, 0, &err_msg) != SQLITE_OK) { 237 | sqlite3_close(memdb); 238 | strerr_die2x(111, "sqlite3_exec: END TRANSACTION: ", err_msg); 239 | } 240 | if (err_msg) 241 | sqlite3_free(err_msg); 242 | } 243 | return; 244 | } 245 | 246 | sqlite3_stmt * 247 | dump_mpd_into_mem(int sock) 248 | { 249 | int match; 250 | char mpdinbuf[1024], mpdoutbuf[512]; 251 | unsigned long processed, failure; 252 | sqlite3_stmt *r_res, *w_res; 253 | 254 | substdio_fdbuf(&mpdin, saferead, sock, mpdinbuf, sizeof mpdinbuf); 255 | substdio_fdbuf(&mpdout, safewrite, sock, mpdoutbuf, sizeof mpdoutbuf); 256 | if (substdio_put(&mpdout, "listallinfo\n", 12) || substdio_flush(&mpdout) == -1) 257 | die_write("unable to write to mpd"); 258 | database_init(1, &r_res, &w_res); 259 | for (processed = failure = 0;;) { 260 | if (getln(&mpdin, &line, &match, '\n') == -1) 261 | die_read("getln"); 262 | if (!match && line.len == 0) 263 | break; 264 | if (!str_diffn(line.s, "OK\n", 3)) 265 | break; 266 | line.s[--line.len] = 0; /*- remove newline */ 267 | if (!str_diffn(line.s, "file: ", 6)) 268 | insert_data(w_res, line.s + 6, &processed, &failure); 269 | } 270 | database_end(1); 271 | return r_res; 272 | } 273 | 274 | static int 275 | callback(void *data, int argc, char **argv, char **column_name) 276 | { 277 | int i, j, notfound = 0; 278 | char *ptr; 279 | 280 | for(i = 0; i < argc; i++) { 281 | #if 0 282 | out(column_name[i]); 283 | out(" "); 284 | out(argv[i] ? argv[i] : "NULL"); 285 | out("\n"); 286 | #endif 287 | if (i || !argv[i]) 288 | continue; 289 | switch (disk_mode) 290 | { 291 | case 1: 292 | notfound = access(argv[i], F_OK); 293 | break; 294 | default: 295 | ptr = sqlite3_expanded_sql((sqlite3_stmt *) data); 296 | tmp.len = 0; 297 | if (ptr && (!stralloc_copys(&tmp, ptr) || !stralloc_0(&tmp))) 298 | die_nomem(); 299 | if (sqlite3_bind_text((sqlite3_stmt *) data, 1, argv[i], -1, SQLITE_STATIC) != SQLITE_OK) { 300 | strerr_warn4("sqlite3_bind_text: ", argv[i], ": ", (char *) sqlite3_errmsg(memdb), 0); 301 | strerr_warn4("sqlite3_bind_text: ", tmp.len ? tmp.s : "unknown statement", ": ", (char *) sqlite3_errmsg(memdb), 0); 302 | return 1; 303 | } 304 | j = sqlite3_step((sqlite3_stmt *) data); 305 | notfound = (j == SQLITE_ROW ? 0 : 1); 306 | sqlite3_clear_bindings((sqlite3_stmt *) data); 307 | sqlite3_reset((sqlite3_stmt *) data); 308 | if (j == SQLITE_ERROR) { 309 | strerr_warn3("sqlite3_step: ", tmp.len ? tmp.s : "unknown statement", ": ", 0); 310 | return 1; 311 | } 312 | break; 313 | } 314 | if (notfound) { 315 | out(method == 1 ? "DELETE from song where uri='" : "DELETE from sticker where uri='"); 316 | if ((j = replacestr(argv[i], "'", "''", &tmp))) 317 | out(tmp.s); 318 | else 319 | out(argv[i]); 320 | out("';\n"); 321 | } 322 | } 323 | return 0; 324 | } 325 | 326 | int 327 | main(int argc, char **argv) 328 | { 329 | int opt, sock, port_num = 6600; 330 | char port[FMT_ULONG], ssoutbuf[512], sserrbuf[512]; 331 | char *sql, *database = 0, *err_msg, *music_directory = 0, 332 | *mpd_socket, *mpd_host, *ptr; 333 | sqlite3_stmt *r_res; 334 | 335 | substdio_fdbuf(&ssout, (ssize_t (*)(int, char *, size_t)) write, 1, ssoutbuf, sizeof(sserrbuf)); 336 | substdio_fdbuf(&sserr, (ssize_t (*)(int, char *, size_t)) write, 2, sserrbuf, sizeof(sserrbuf)); 337 | if (!(mpd_host = env_get("MPD_HOST"))) 338 | mpd_host = "127.0.0.1"; 339 | mpd_socket = env_get("MPD_SOCKET"); 340 | if (!(ptr = env_get("MPD_PORT"))) 341 | port_num = 6600; 342 | else 343 | scan_uint(ptr, (unsigned int *) &port_num); 344 | database = (char *) 0; 345 | while ((opt = getopt(argc, argv, "vcCDd:m:h:s:p:")) != opteof) { 346 | switch (opt) { 347 | case 'h': 348 | mpd_host = optarg; 349 | break; 350 | case 's': 351 | mpd_socket = optarg; 352 | break; 353 | case 'p': 354 | scan_uint(optarg, (unsigned int *) &port_num); 355 | break; 356 | case 'm': 357 | music_directory = optarg; 358 | break; 359 | case 'd': 360 | database = optarg; 361 | break; 362 | case 'c': /*- clean stats */ 363 | if (!method) 364 | method = 1; 365 | else 366 | method = 3; 367 | break; 368 | case 'C': /*- clean sticker */ 369 | if (!method) 370 | method = 2; 371 | else 372 | method = 3; 373 | break; 374 | case 'D': 375 | disk_mode = 1; 376 | break; 377 | case 'v': 378 | verbose++; 379 | break; 380 | default: 381 | strerr_die1x(100, usage); 382 | } 383 | } 384 | 385 | if (!database || !method) { 386 | err_out("You have to specify -d and either -c or -C options\n"); 387 | err_flush(); 388 | strerr_die1x(100, usage); 389 | } 390 | if (method == 3) { 391 | err_out("You cannot specify both -c and -C options\n"); 392 | err_flush(); 393 | strerr_die1x(100, usage); 394 | } 395 | 396 | if (!disk_mode) { 397 | if (mpd_socket && port_num != 6600) 398 | strerr_die1x(100, "you can't specify both socket & port"); 399 | if (mpd_socket && str_diff(mpd_host, "127.0.0.1")) 400 | strerr_die1x(100, "you can't specify both socket & IP"); 401 | port[fmt_ulong(port, port_num)] = 0; 402 | if ((sock = tcpopen(mpd_socket ? mpd_socket : mpd_host, 0, port_num)) == -1) { 403 | if (mpd_socket) 404 | strerr_die4sys(111, "mpdev_cleanup: tcpopen: ", "socket [", mpd_socket, "]: "); 405 | else 406 | strerr_die6sys(111, "mpdev_cleanup: tcpopen: ", "host [", mpd_host, "] port [", port, "]: "); 407 | } 408 | r_res = dump_mpd_into_mem(sock); 409 | } else 410 | r_res = (sqlite3_stmt *) 0; 411 | if (sqlite3_open(database, &db) != SQLITE_OK) 412 | strerr_die3x(111, database, ": ", (char *) sqlite3_errmsg(db)); 413 | if (music_directory && chdir(music_directory)) 414 | strerr_die3sys(111, "unable to chdir to ", music_directory, ": "); 415 | sql = (method == 1 ? "SELECT uri from song" : "SELECT uri from sticker"); 416 | if (sqlite3_exec(db, sql, callback, r_res, &err_msg) != SQLITE_OK) { 417 | sqlite3_close(db); 418 | strerr_die5x(111, database, ": ", sql, ": ", err_msg); 419 | } 420 | if (err_msg) 421 | sqlite3_free(err_msg); 422 | sqlite3_close(db); 423 | out("VACUUM;\n"); 424 | out(".quit\n"); 425 | flush(); 426 | } 427 | -------------------------------------------------------------------------------- /mpdev_rename.1: -------------------------------------------------------------------------------- 1 | .TH mpdev_rename 1 "Apr 20, 2021" "manual" 2 | .SH NAME 3 | .PP 4 | mpdev_rename - rename records in mpdev stats/sicker database 5 | .SH SYNOPSIS 6 | .PP 7 | mpdev_rename --stats-db=path_to_stats.db --query --pattern=\fIpatt\fR 8 | 9 | or 10 | 11 | mpdev_rename --stats-db=path_to_stats.db --pattern=\fIpatt\fR --string=\fIstr\fR --replacement=\fIrepl\fR 12 | 13 | .SH DESCRIPTION 14 | .PP 15 | \fBmpdev_rename\fR(1) helps in rename records in sticker or stats db 16 | when you physically rename a music file. It allows you to retain the 17 | playcounts and ratings for a song, which would otherwise be lost by song rename. 18 | 19 | It can operate in query mode (--query option) or replacement mode 20 | (--string and --replacement options) 21 | 22 | .SH OPTIONS 23 | .TP 3 24 | \fB--query\fR 25 | query the database for the records matching \fIpatt\fR 26 | .RS 27 | .RE 28 | 29 | .TP 3 30 | \fB--pattern\fR=\fIpatt\fR 31 | Use \fIpatt\fR for matching records 32 | .RS 33 | .RE 34 | 35 | .TP 3 36 | \fB--string\fR \fIstr\fR 37 | String to replace 38 | .RS 39 | .RE 40 | 41 | .TP 3 42 | \fB--replacement\fR \fIrepl\fR 43 | Each record found will have \fIstr\fR replaced by \fIrepl\fR 44 | .RS 45 | .RE 46 | 47 | .SH EXAMPLES 48 | .EX 49 | 1 Find all records in the folder \fIMusic\fR/Jethro Tull/Misc/1978* 50 | # mpdev_rename --stats-db=./stats.db --query --pattern='Jethro Tull/1978%' 51 | 52 | 2 Move all the above files to Music/Jethro Tull/Misc 53 | # cd \fIMusic\fR/Jethro Tull/1978* \fIMusic\fR/Jethro Tull/Misc 54 | # mpdev_rename --stats-db=./stats.db --pattern='Jethro Tull/1978%' 55 | --string="Jethro Tull" --replacement="Jethro Tull/Misc" 56 | 57 | Here \fIMusic\fR refers to value of \fImusic_directory\fR in mpd.conf(5) 58 | .EE 59 | 60 | .SH REPORTING BUGS 61 | .PP 62 | If you find a bug, please report it at https://github.com/mbhangui/mpdev/issues 63 | 64 | .SH COPYRIGHT 65 | .PP 66 | Copyright (c) 2020 Manvendra Bhangui 67 | .PD 0 68 | .P 69 | .PD 70 | Free 71 | use of this software is granted under the terms of the GNU General 72 | Public License (GPLv2). 73 | .SH AUTHOR 74 | Manvendra Bhangui 75 | 76 | .SH SEE ALSO 77 | mpd(1), 78 | mpd.conf(5), 79 | sqlite3(1), 80 | mpdev(1) 81 | mpdev_update(1), 82 | mpdev_cleanup(1) 83 | -------------------------------------------------------------------------------- /mpdev_rename.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # $Log: mpdev_rename.in,v $ 4 | # Revision 1.5 2022-11-29 09:48:53+05:30 Cprogrammer 5 | # prevent wrapping of lines after 60 characters 6 | # 7 | # Revision 1.4 2021-09-30 20:31:35+05:30 Cprogrammer 8 | # use -noheader option to prevent .sqlitrc settings messing with results 9 | # 10 | # Revision 1.3 2020-09-08 21:43:05+05:30 Cprogrammer 11 | # fixed usage script 12 | # 13 | # Revision 1.2 2020-08-05 21:15:00+05:30 Cprogrammer 14 | # replaced sed with SQL REPLACE 15 | # 16 | # Revision 1.1 2020-07-19 18:20:04+05:30 Cprogrammer 17 | # Initial revision 18 | # 19 | # 20 | # $Id: mpdev_rename.in,v 1.5 2022-11-29 09:48:53+05:30 Cprogrammer Exp mbhangui $ 21 | # 22 | 23 | usage() 24 | { 25 | prog_args="" 26 | cat <&2 34 | read key 35 | exit $1 36 | } 37 | 38 | ################################# Main ################################## 39 | if test $# -eq 0; then 40 | usage 1 41 | fi 42 | sticker_db="" 43 | stats_db="" 44 | query=0 45 | while test $# -gt 0; do 46 | case "$1" in 47 | -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` 48 | ;; 49 | *) optarg= 50 | ;; 51 | esac 52 | 53 | case "$1" in 54 | --sticker-db=*) 55 | sticker_db=$optarg 56 | dbpath=$optarg 57 | table=sticker 58 | ;; 59 | --stats-db=*) 60 | stats_db=$optarg 61 | dbpath=$optarg 62 | table=song 63 | ;; 64 | 65 | --query) 66 | query=1 67 | ;; 68 | --pattern=*) 69 | patt="$optarg" 70 | ;; 71 | --string=*) 72 | str="$optarg" 73 | ;; 74 | --replacement=*) 75 | repl="$optarg" 76 | ;; 77 | *) 78 | echo "invalid option [$1]" 1>&2 79 | usage 1 80 | ;; 81 | esac 82 | shift 83 | done 84 | 85 | if [ -z "$sticker_db" -a -z "$stats_db" ] ; then 86 | echo "rename_fields: You must specify --sticker-db or --stats-db" 1>&2 87 | usage 1 88 | fi 89 | if [ -n "$sticker_db" -a -n "$stats_db" ] ; then 90 | echo "rename_fields: You cannot specify both --sticker-db and --stats-db" 1>&2 91 | usage 1 92 | fi 93 | if [ $query -eq 0 ] ; then 94 | if [ -z "$str" -o -z "$repl" ] ; then 95 | echo "You have to specify string to replace and replacement string or specify --query" 1>&2 96 | usage 1 97 | fi 98 | fi 99 | if [ $query -eq 1 ] ; then 100 | echo "executing sqlite3 -noheader --list --batch $dbpath \"SELECT uri FROM $table WHERE uri LIKE '$patt'\"" 1>&2 101 | sqlite3 -noheader --list -batch $dbpath "SELECT uri FROM $table WHERE uri LIKE '$patt'" 102 | else 103 | echo "UPDATE $table SET uri=REPLACE(uri, '$str', '$repl') WHERE uri LIKE '$patt'" 1>&2 104 | sqlite3 -batch $dbpath \ 105 | "UPDATE $table SET uri=REPLACE(uri, '$str', '$repl') WHERE uri LIKE '$patt'" 106 | fi 107 | -------------------------------------------------------------------------------- /mpdev_update.1: -------------------------------------------------------------------------------- 1 | .TH mpdev_update 1 "December 23, 2009" "manual" 2 | .SH NAME 3 | .PP 4 | mpdev_update - Update stats, sticker sqlite db from mpd database 5 | .SH SYNOPSIS 6 | .PP 7 | mpdev_update [\f[I]option\f[]] 8 | 9 | .SH DESCRIPTION 10 | .PP 11 | \fBmpdev_update\fR creates/updates stats.db or sticker.db from the 12 | \fBmpd\fR(1) database. It sends the \fIlistinfo\fR command to mpd to 13 | get list of all music files. \fBmpdev_update\fR uses the \fI%mtime%\fR 14 | tag for a file from the mpd(1) database. 15 | 16 | .SH OPTIONS 17 | .TP 3 18 | .B -v 19 | Set verbose output. You can increase verbosity by specifying it multiple times 20 | .RS 21 | .RE 22 | 23 | .TP 3 24 | \fB-i\fR \fIIP\fR 25 | IP address of mpd host if different from localhost 26 | .RS 27 | .RE 28 | 29 | .TP 3 30 | \fB-p\fR \fIport\fR 31 | port on which mpd(1) is listening if different from 6600 32 | .RS 33 | .RE 34 | 35 | .TP 3 36 | \fB-s\fR \fIunix_socket\fR 37 | Unix domain socket in case you don't want to use \fIIP\fR and \fIport\fR 38 | .RS 39 | .RE 40 | 41 | .TP 3 42 | \fB-d\fR \fIdb_file_path\fR 43 | full path to the sqlite3(1) stats database 44 | .RS 45 | .RE 46 | 47 | .TP 3 48 | \fB-D\fR \fI0\fR | \fI1\fR 49 | 0 to insert new records in stats.db, 1 to insert new records in sticker.db 50 | .RS 51 | .RE 52 | 53 | .TP 3 54 | .B -U 55 | Use update mode. The default is to use insert mode. 56 | .RS 57 | .RE 58 | 59 | .TP 3 60 | \fB-j\fR 61 | Puts the journal in volatile memory. This saves disk I/O but at the expense 62 | of database safety and integrity. If the application using SQLite crashes 63 | in the middle of a transaction when the MEMORY journaling mode is set, then 64 | the database file will very likely go corrupt. 65 | .RS 66 | .RE 67 | 68 | .TP 3 69 | \fB-t\fR 70 | Turns on transaction mode at the beginning. This improves performance. But if 71 | the application crashes in the middle, all new changes will be lost 72 | .RS 73 | .RE 74 | 75 | .TP 3 76 | \fB-S\fR 77 | Turns Off synchronous mode. 78 | With synchronous OFF, \fBmpdev_update\fR continues without syncing as soon 79 | as it has handed data off to the operating system. In case \fBmpdev_update\fR 80 | crashes, the data will be safe, but the database might become corrupted if 81 | the operating system crashes or the computer loses power before that data 82 | has been written to the disk. On the other hand, commits can be orders of 83 | magnitude faster with synchronous OFF. 84 | .RS 85 | .RE 86 | 87 | .TP 3 88 | \fB-P\fR 89 | Print SQL statements used during db creation 90 | .RS 91 | .RE 92 | 93 | Examples 94 | 1. create stats.db in the current directory 95 | 96 | .EX 97 | $ mpdev_update -S -j -t -D 0 -d stats.db 98 | Processed 42630 rows, Failures 0 rows, Updated 42636 rows 99 | 100 | real 0m0.830s 101 | user 0m0.405s 102 | sys 0m0.096s 103 | .EE 104 | 105 | 2. Update stats.db in the current directory and add 6 new songs 106 | .EX 107 | $ mpdev_update -S -j -t -D 0 -d stats.db 108 | Processed 42636 rows, Failures 0 rows, Updated 6 rows 109 | 110 | real 0m0.725s 111 | user 0m0.353s 112 | sys 0m0.067s 113 | .EE 114 | 115 | .SH REPORTING BUGS 116 | .PP 117 | If you find a bug, please report it at https://github.com/mbhangui/mpdev/issues 118 | 119 | .SH COPYRIGHT 120 | .PP 121 | Copyright (c) 2020 Manvendra Bhangui 122 | .PD 0 123 | .P 124 | .PD 125 | Free 126 | use of this software is granted under the terms of the GNU General 127 | Public License (GPLv2). 128 | .SH AUTHOR 129 | Manvendra Bhangui 130 | 131 | .SH SEE ALSO 132 | mpd(1), 133 | sqlite3(1), 134 | mpdev_cleanup(1), 135 | mpdev(1) 136 | -------------------------------------------------------------------------------- /mpdhist.1: -------------------------------------------------------------------------------- 1 | .TH mpdhist 1 2 | .SH NAME 3 | mpdhist \- Display History of Last played songs 4 | 5 | .SH SYNOPSYS 6 | .B mpdhist 7 | --limit 8 | [ 9 | .I limit 10 | ] 11 | 12 | .SH DESCRIPTION 13 | \fBmpdhist\fR displays history of songs plays in descending order of time 14 | 15 | .SH OPTIONS 16 | 17 | Known values for OPTION are: 18 | 19 | .EX 20 | -l \fIlimit\fR | --limit=\fIlimit\fR 21 | Display last played \fIlimit\fR songs from history 22 | 23 | -r | --reverse 24 | Show earliest played song first 25 | 26 | -h | --help 27 | 28 | display this help and exit 29 | .EE 30 | 31 | .SH "SEE ALSO" 32 | mpdev(1) 33 | -------------------------------------------------------------------------------- /mpdhist.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # $Id: mpdhist.in,v 1.5 2024-03-11 16:47:12+05:30 Cprogrammer Exp mbhangui $ 4 | # 5 | 6 | usage() 7 | { 8 | cat 1>&2 <&2 63 | usage 1; 64 | break 65 | ;; 66 | esac 67 | done 68 | } 69 | 70 | limit=24 71 | do_rev=0 72 | process_cmdline "$@" 73 | 74 | music_dir=`get_mpd_conf_value music_directory` 75 | if [ $? -ne 0 ] ; then 76 | echo "could not get music directory from mpd.conf" 1>&2 77 | exit 1 78 | fi 79 | sticker_file=`get_mpd_conf_value sticker_file` 80 | if [ $? -ne 0 ] ; then 81 | echo "could not get sticker database from mpd.conf" 1>&2 82 | exit 1 83 | fi 84 | stats_dir=$(dirname $sticker_file) 85 | stats_file=$stats_dir/stats.db 86 | stmt="" 87 | stmt="$stmt select id, title, artist, album, play_count, rating, " 88 | stmt="$stmt strftime('%d-%m-%Y %H:%M:%S', datetime(last_played, 'unixepoch', 'localtime')) " 89 | if [ $do_rev -eq 0 ] ; then 90 | stmt="$stmt from song where last_played is NOT NULL and play_count > 0 order by last_played DESC LIMIT $limit" 91 | else 92 | stmt="$stmt from song where last_played is NOT NULL and play_count > 0 order by last_played ASC LIMIT $limit" 93 | fi 94 | 95 | sqlite3 -header -batch -column $stats_file "$stmt" | \ 96 | sed \ 97 | -e 's/[ \t]\+$//' \ 98 | -e 's{strftime.*${Last Played{' \ 99 | -e 's{ -*${ ==================={' 100 | 101 | # 102 | # $Log: mpdhist.in,v $ 103 | # Revision 1.5 2024-03-11 16:47:12+05:30 Cprogrammer 104 | # removed rompr 105 | # 106 | # Revision 1.4 2022-09-26 21:15:59+05:30 Cprogrammer 107 | # removed debug statement 108 | # 109 | # Revision 1.3 2022-09-26 21:12:59+05:30 Cprogrammer 110 | # added -r option to show earliest played song first 111 | # 112 | # Revision 1.2 2022-09-26 20:18:34+05:30 Cprogrammer 113 | # pass -header option to sqlite3 114 | # 115 | # Revision 1.1 2022-09-26 19:11:08+05:30 Cprogrammer 116 | # Initial revision 117 | # 118 | # 119 | -------------------------------------------------------------------------------- /mpdplaylist.1: -------------------------------------------------------------------------------- 1 | .\" vim: tw=75 2 | .TH mpdplaylist 1 3 | .SH NAME 4 | mpdplaylist \- Generate playlist for Music Player Daemon 5 | 6 | .SH SYNOPSYS 7 | .B mpdplaylist 8 | [ 9 | .I options 10 | ] 11 | 12 | .SH DESCRIPTION 13 | 14 | \fBmpdplaylist\fR(1) is a shell frontend for generating playlists for Music 15 | Player Daemon. It has many options to help you chose a playlist based on 16 | tracks played by you using \fBmpd\fR(1). It uses the stats.db \fBsqlite\fR 17 | database generated by \fBmpdev\fR(1) and the ratings maintained in the 18 | sticker database for mpd. 19 | 20 | \fBmpdplaylist\fR(1) displays the result on stdout. You can redirect the 21 | output to any filename with m3u extension. You can also use --playlist 22 | option tosave the result to a playlist in the mpd(1) 23 | \fIplaylist_directory\fR configured in mpd.conf(5). 24 | 25 | If no options are given, \fBmdplaylist\fR can use the file 26 | $HOME/.mpdplaylist.options to use default options. You can use 27 | --options-file=\fIfile\fR to load options from \fIfile\fR 28 | 29 | .SH OPTIONS 30 | Known values for OPTION are: 31 | 32 | .EX 33 | --options-file=filename 34 | Take extra command line options from filename 35 | 36 | --fromyear=From Year 37 | Year in YYYY format 38 | 39 | --toyear=To Year 40 | Year in YYYY format 41 | 42 | --includegenre=Genre List to be included 43 | comma separated list of genre. 44 | 45 | --excludegenre=Genre List to be excluded 46 | comma separated list of genre 47 | 48 | --includeartist=Artist List to be included 49 | comma separated list of artist. 50 | 51 | --excludeartist=Artist List to be excluded 52 | comma separated list of artist 53 | 54 | --minrating=Minimum Rating (value from 0 to 10, or -1 for unrated songs) 55 | 56 | --artist=Artist 57 | Find songs with Artist exactly matching 'Artist' 58 | 59 | --artistany=keyword 60 | Find songs with Artist having 'keyword' anywhere in the Artist field 61 | 62 | --new=d 63 | Find songs added in the last 'd' days 64 | 65 | --daysheard=d 66 | Find songs heard in the last 'd' days 67 | 68 | --daysnotheard=d 69 | Find songs not heard in the last 'd' days, use d=0 for songs never played 70 | 71 | --oldfirst 72 | Order playlist in ascending order of Last Played field 73 | (Song played earlier come at top) 74 | 75 | --popular 76 | Order playlist in decreasing order of Rating field 77 | (Songs with high rating come at top) 78 | 79 | --karma 80 | Find songs with karma as per expression. e.g. 81 | --karma<50 means songs with karma less than 50 82 | --karma<=50 means songs with karma less than or equal to 50 83 | --karma=50 means songs with karma equal to 50 84 | --karma>=50 means songs with karma greater than or equal to 50 85 | --karma>50 means songs with karma greater than 50 86 | 87 | --playcount=exp 88 | Find songs with playcounts as per expression. e.g. 89 | --playcount<5 means songs with play counts less than 5 90 | --playcount<=5 means songs with play counts less than or equal to5 91 | --playcount=5 means songs with play counts equal to 5 92 | --playcount>=5 means songs with play counts greater than or equal to 5 93 | --playcount>5 means songs with play counts greater than 5 94 | 95 | --playlist=playlist 96 | save the playlist in the filename $playlist_dir/playlist. 97 | If the playlist is named now, new playlist will be added to the 98 | current mpd playlist. If --clear is also specified, the current 99 | playlist will be cleared and loaded. The 'now' playlist is not 100 | saved to the playlist directory. Without --playlist option, 101 | result will be displayed on screen. 102 | 103 | --host=host 104 | mpd host to use 105 | 106 | --shuffle 107 | shuffle playlist 108 | 109 | --limit=n 110 | Limit the playlist to n entries 111 | 112 | --play 113 | Play songs when playlist=now 114 | 115 | --clear 116 | clear playlist before adding. See --playlist option 117 | 118 | --query 119 | Display the SQL query and exit 120 | 121 | --help 122 | 123 | display this help and exit 124 | 125 | --version 126 | 127 | output version information 128 | .EE 129 | 130 | .SH EXAMPLES 131 | .EX 132 | Load a playlist as defined in ~/.mpdplaylist.options 133 | \fBmpdplaylist\fR 134 | 135 | Load a playlist as defined in ~/.mpdplaylist.new 136 | \fBmpdplaylist\fR --options-file=~/.mpdplaylist.new 137 | 138 | List all songs added in the last 3 days 139 | \fBmpdplaylist\fR --new=3 140 | 141 | List all songs belonging to \fIHindi\fR genre, having a rting of 6 & 142 | greater (on a scale of 10), from the year 1970 to the year 2000. Sort the 143 | result on the \fIlast_played\fR field in ascendning order and in descending 144 | order of the \fIrating\fR field. 145 | 146 | \fBmpdplaylist\fR --fromyear=1970 --toyear=2000 --includegenre="Hindi" \ 147 | --minrating=6 --oldfirst --popular 148 | 149 | List all songs in the genre 'Heavy Metal' and 'Hard Rock', added in the 150 | last 30 days 151 | 152 | \fBmpdplaylist\fR --includegenre="Heavy Metal, Hard Rock" --new=30 153 | 154 | List all songs heard in the last 10 days 155 | 156 | \fBmpdplaylist\fR --daysheard=10 157 | 158 | List all songs not heard in the last 20 days 159 | 160 | \fBmpdplaylist\fR --daysnotheard=20 161 | 162 | List all songs which have never been heard 163 | 164 | \fBmpdplaylist\fR --daysnotheard=0 165 | 166 | List all songs added in the last 1 year but have never been heard 167 | 168 | \fBmpdplaylist\fR --new=365 --daysnotheard=0 169 | 170 | List all songs not heard in the last 20 days order by last played with the 171 | last played at top 172 | 173 | \fBmpdplaylist\fR --oldfirst --daysnotheard=20 174 | 175 | Save the output in the mpd playlist new 176 | 177 | \fBmpdplaylist\fR --includegenre="Heavy Metal, Hard Rock" --new=30 --playlist=new 178 | .EE 179 | 180 | .SH RETURN VALUE 181 | \fBmpdplaylist\fR returns non-zero status on error. 182 | 183 | .SH "SEE ALSO" 184 | mpd(1), 185 | mpc(1), 186 | mpd.conf(5), 187 | mpdev_update(1), 188 | mpdev_cleanup(1), 189 | mpdev(1), 190 | sqlite3(1) 191 | -------------------------------------------------------------------------------- /mpdplaylist.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # $Log: mpdplaylist.in,v $ 4 | # Revision 1.22 2024-04-10 21:29:19+05:30 Cprogrammer 5 | # fixed command line arguments with space 6 | # 7 | # Revision 1.21 2022-06-20 01:04:54+05:30 Cprogrammer 8 | # use directories set in ./configure 9 | # 10 | # Revision 1.20 2022-05-10 21:33:16+05:30 Cprogrammer 11 | # added --includeartist, --excludeartist to include, exclude artists in query 12 | # 13 | # Revision 1.19 2021-09-30 20:31:46+05:30 Cprogrammer 14 | # use -noheader option to prevent .sqlitrc settings messing with results 15 | # 16 | # Revision 1.18 2021-04-24 11:56:20+05:30 Cprogrammer 17 | # minor fixes for display and error messages 18 | # 19 | # Revision 1.17 2021-04-18 16:39:41+05:30 Cprogrammer 20 | # fix for space in command line argument values 21 | # 22 | # Revision 1.16 2021-04-16 12:56:50+05:30 Cprogrammer 23 | # added --options-file feature to take command line arguments from an options file 24 | # 25 | # Revision 1.15 2021-04-15 22:06:27+05:30 Cprogrammer 26 | # added --karma option 27 | # 28 | # Revision 1.14 2021-04-14 16:40:22+05:30 Cprogrammer 29 | # added --play option 30 | # 31 | # Revision 1.13 2021-04-14 13:11:29+05:30 Cprogrammer 32 | # added --playcount option to get songs that match play counts 33 | # 34 | # Revision 1.12 2021-04-10 13:05:38+05:30 Cprogrammer 35 | # set default options (command line arguments) from .mpdplaylist.options 36 | # 37 | # Revision 1.11 2021-04-10 11:15:39+05:30 Cprogrammer 38 | # updated usage message for --playlist option 39 | # 40 | # Revision 1.10 2021-01-07 12:20:20+05:30 Cprogrammer 41 | # added last_played is NULL to query daysnotheard 42 | # 43 | # Revision 1.9 2020-09-05 12:32:29+05:30 Cprogrammer 44 | # added --limit option 45 | # 46 | # Revision 1.8 2020-09-03 20:36:39+05:30 Cprogrammer 47 | # fixed --clear option 48 | # 49 | # Revision 1.7 2020-09-03 11:10:32+05:30 Cprogrammer 50 | # fixed stats_db path 51 | # 52 | # Revision 1.6 2020-08-30 11:34:59+05:30 Cprogrammer 53 | # fixed stats.db path 54 | # 55 | # Revision 1.5 2020-08-06 16:15:39+05:30 Cprogrammer 56 | # renamed --dummy option to --query 57 | # 58 | # Revision 1.4 2020-08-05 12:08:02+05:30 Cprogrammer 59 | # renamed --save to --playlist 60 | # 61 | # Revision 1.3 2020-08-02 20:48:38+05:30 Cprogrammer 62 | # added --shuffle option to shuffle playlist 63 | # 64 | # Revision 1.2 2020-08-02 17:52:35+05:30 Cprogrammer 65 | # added --host option to specify mpd host 66 | # 67 | # Revision 1.1 2020-07-19 18:17:52+05:30 Cprogrammer 68 | # Initial revision 69 | # 70 | # 71 | # $Id: mpdplaylist.in,v 1.22 2024-04-10 21:29:19+05:30 Cprogrammer Exp mbhangui $ 72 | # 73 | 74 | get_mpd_conf_value() 75 | { 76 | grep "^$1" @sysconfdir@/mpd.conf|awk '{print $2}' | \ 77 | sed -e 's{"{{g' 78 | } 79 | 80 | usage() 81 | { 82 | if [ -f /usr/bin/less ] ; then 83 | MORE=/usr/bin/less 84 | else 85 | MORE=/usr/bin/more 86 | fi 87 | echo "Press ENTER for options, Cntrl C to quit" 1>&2 88 | read key 89 | $MORE 1>&2 <=50 means songs with karma greater than or equal to 50 146 | --karma>50 means songs with karma greater than 50 147 | 148 | --playcount=exp 149 | Find songs with playcounts as per expression. e.g. 150 | --playcount<5 means songs with play counts less than 5 151 | --playcount<=5 means songs with play counts less than or equal to 5 152 | --playcount=5 means songs with play counts equal to 5 153 | --playcount>=5 means songs with play counts greater than or equal to 5 154 | --playcount>5 means songs with play counts greater than 5 155 | 156 | --playlist=playlist 157 | save the playlist in the filename $playlist_dir/playlist. 158 | If the playlist is named now, new playlist will be added to the 159 | current mpd playlist. If --clear is also specified, the current 160 | playlist will be cleared and loaded. The 'now' playlist is not 161 | saved to the playlist directory. Without --playlist option, 162 | result will be displayed on screen. 163 | 164 | --host=host 165 | mpd host to use 166 | 167 | --shuffle 168 | shuffle playlist 169 | 170 | --limit=n 171 | Limit the playlist to n entries 172 | 173 | --play 174 | Play songs when playlist=now 175 | 176 | --clear 177 | clear playlist before adding. See --playlist option 178 | 179 | --query 180 | Display the SQL query and exit 181 | 182 | --help 183 | 184 | display this help and exit 185 | 186 | --version 187 | 188 | output version information 189 | EOF 190 | exit $1 191 | } 192 | 193 | process_cmdline() 194 | { 195 | while test $# -gt 0; do 196 | case "$1" in 197 | -*=*) 198 | optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` 199 | optval=`echo "$1" | cut -d'=' -f1` 200 | prog_args="$prog_args $optval=\"$optarg\"" 201 | ;; 202 | -*\>*) 203 | optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*>//'` 204 | optarg=">$optarg" 205 | optval=`echo "$1" | cut -d'>' -f1` 206 | prog_args="$prog_args $optval\"$optarg\"" 207 | ;; 208 | -*\<*) 209 | optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*&2 233 | usage 1 234 | fi 235 | includegenre=`echo $optarg| sed "s/ /_/g"` 236 | ;; 237 | --excludegenre=*) 238 | if [ -n "$includegenre" ] ; then 239 | echo "you cannot give both includegenre and excludegenre together" 1>&2 240 | usage 1 241 | fi 242 | excludegenre=`echo $optarg| sed "s/ /_/g"` 243 | ;; 244 | --includeartist=*) 245 | if [ -n "$excludeartist" ] ; then 246 | echo "you cannot give both includeartist and excludeartist together" 1>&2 247 | usage 1 248 | fi 249 | includeartist=`echo $optarg| sed "s/ /_/g"` 250 | ;; 251 | --excludeartist=*) 252 | if [ -n "$includeartist" ] ; then 253 | echo "you cannot give both includeartist and excludeartist together" 1>&2 254 | usage 1 255 | fi 256 | excludeartist=`echo $optarg| sed "s/ /_/g"` 257 | ;; 258 | --minrating=*) 259 | minrate=$optarg 260 | ;; 261 | --artist=*) 262 | exact=1 263 | artist=`echo "$optarg"| sed "s/ /_/g"` 264 | ;; 265 | --artistany=*) 266 | exact=0 267 | artist=`echo $optarg| sed "s/ /_/g"` 268 | ;; 269 | --karma=*|--karma\>*|--karma\<*) 270 | first_char=$(echo $optarg | cut -c1) 271 | if [ ! "$first_char" = ">" -a ! "$first_char" = "<" ] ; then 272 | karma="karma=$optarg" 273 | else 274 | karma="karma$optarg" 275 | fi 276 | ;; 277 | --playcount=*|--playcount\>*|--playcount\<*) 278 | first_char=$(echo $optarg | cut -c1) 279 | if [ ! "$first_char" = ">" -a ! "$first_char" = "<" ] ; then 280 | play_counts="play_count=$optarg" 281 | else 282 | play_counts="play_count$optarg" 283 | fi 284 | ;; 285 | --new=*) 286 | daysadded=$optarg 287 | ;; 288 | --daysheard=*) 289 | daysheard=$optarg 290 | ;; 291 | --daysnotheard=*) 292 | daysnotheard=$optarg 293 | ;; 294 | --playlist=*) 295 | playlist=$optarg 296 | ;; 297 | --oldfirst) 298 | oldfirst=1 299 | ;; 300 | --popular) 301 | sort_popular=1 302 | ;; 303 | --query) 304 | dummy=1 305 | ;; 306 | --shuffle) 307 | shuffle=1 308 | ;; 309 | --clear) 310 | do_clear=1 311 | ;; 312 | --limit=*) 313 | limit=$optarg 314 | ;; 315 | --play) 316 | do_play=1 317 | ;; 318 | --verbose) 319 | verbose="-v" 320 | ;; 321 | --host=*) 322 | mpd_host=$optarg 323 | ;; 324 | --help) 325 | playlist_dir=`get_mpd_conf_value playlist_dir` 326 | usage 0 327 | ;; 328 | *) 329 | echo "invalid option [$1]" 1>&2 330 | usage 1 331 | ;; 332 | esac 333 | shift 334 | done 335 | } 336 | 337 | verbose="" 338 | fromyear="" 339 | toyear="" 340 | includegenre="" 341 | excludegenre="" 342 | includeartist="" 343 | excludeartist="" 344 | artist="" 345 | minrate="" 346 | oldfirst=0 347 | sort_popular=0 348 | dummy=0 349 | shuffle=0 350 | do_clear=0 351 | limit=0 352 | do_play=0 353 | play_counts="" 354 | karma="" 355 | playlist="" 356 | daysadded="" 357 | daysheard="" 358 | daysnotheard="" 359 | mpd_host="" 360 | options_file="" 361 | prog_args="$0" 362 | 363 | if [ $# -eq 0 -a -f $HOME/.mpdplaylist.options ] ; then 364 | options=$(grep -v '^#' -h $HOME/.mpdplaylist.options) 365 | set -- $options 366 | fi 367 | process_cmdline "$@" 368 | if [ -n "$options_file" ] ; then 369 | options="$(grep -v '^#' -h $options_file)" 370 | eval process_cmdline $options 371 | fi 372 | 373 | music_dir=`get_mpd_conf_value music_directory` 374 | if [ $? -ne 0 ] ; then 375 | echo "could not get music directory from mpd.conf" 1>&2 376 | exit 1 377 | fi 378 | sticker_file=`get_mpd_conf_value sticker_file` 379 | if [ $? -ne 0 ] ; then 380 | echo "could not get sticker database from mpd.conf" 1>&2 381 | exit 1 382 | fi 383 | playlist_dir=`get_mpd_conf_value playlist_dir` 384 | if [ $? -ne 0 ] ; then 385 | echo "could not get playlist directory from mpd.conf" 1>&2 386 | exit 1 387 | fi 388 | stats_dir=$(dirname $sticker_file) 389 | stats_file=$stats_dir/stats.db 390 | if [ -z "$stats_file" ] ; then 391 | echo "Unable to get stats.db location" 1>&2 392 | exit 1 393 | fi 394 | if [ ! -f "$stats_file" ] ; then 395 | echo "$stats_file: No such file or directory" 1>&2 396 | exit 1 397 | fi 398 | 399 | sql_query="SELECT uri FROM song " 400 | first_condition="" 401 | if [ -n "$fromyear" ] ; then 402 | if [ -z "$first_condition" ] ; then 403 | sql_query="$sql_query WHERE" 404 | first_condition=1 405 | elif [ -n "$first_condition" ] ; then 406 | sql_query="$sql_query AND" 407 | fi 408 | sql_query="$sql_query date >= $fromyear" 409 | fi 410 | if [ -n "$toyear" ] ; then 411 | if [ -z "$first_condition" ] ; then 412 | sql_query="$sql_query WHERE" 413 | first_condition=1 414 | elif [ -n "$first_condition" ] ; then 415 | sql_query="$sql_query AND" 416 | fi 417 | sql_query="$sql_query date <= $toyear" 418 | fi 419 | count=0 420 | if [ -n "$excludegenre" ] ; then 421 | if [ -z "$first_condition" ] ; then 422 | sql_query="$sql_query WHERE" 423 | first_condition=1 424 | elif [ -n "$first_condition" ] ; then 425 | sql_query="$sql_query AND" 426 | fi 427 | for i in $(echo $excludegenre | sed "s/,/ /g") 428 | do 429 | f=`echo $i|sed "s/_/ /g"` 430 | if [ $count -eq 0 ] ; then 431 | sql_query="$sql_query genre NOT IN ('$f'" 432 | else 433 | sql_query="$sql_query, '$f'" 434 | fi 435 | count=`expr $count + 1` 436 | done 437 | sql_query="$sql_query)" 438 | fi 439 | count=0 440 | if [ -n "$includegenre" ] ; then 441 | if [ -z "$first_condition" ] ; then 442 | sql_query="$sql_query WHERE" 443 | first_condition=1 444 | elif [ -n "$first_condition" ] ; then 445 | sql_query="$sql_query AND" 446 | fi 447 | for i in $(echo $includegenre | sed "s/,/ /g") 448 | do 449 | f=`echo $i|sed "s/_/ /g"` 450 | if [ $count -eq 0 ] ; then 451 | sql_query="$sql_query genre IN ('$f'" 452 | else 453 | sql_query="$sql_query, '$f'" 454 | fi 455 | count=`expr $count + 1` 456 | done 457 | sql_query="$sql_query)" 458 | fi 459 | count=0 460 | if [ -n "$excludeartist" ] ; then 461 | if [ -z "$first_condition" ] ; then 462 | sql_query="$sql_query WHERE" 463 | first_condition=1 464 | elif [ -n "$first_condition" ] ; then 465 | sql_query="$sql_query AND" 466 | fi 467 | for i in $(echo $excludeartist | sed "s/,/ /g") 468 | do 469 | f=`echo $i|sed "s/_/ /g"` 470 | if [ $count -eq 0 ] ; then 471 | sql_query="$sql_query artist NOT IN ('$f'" 472 | else 473 | sql_query="$sql_query, '$f'" 474 | fi 475 | count=`expr $count + 1` 476 | done 477 | sql_query="$sql_query)" 478 | fi 479 | count=0 480 | if [ -n "$includeartist" ] ; then 481 | if [ -z "$first_condition" ] ; then 482 | sql_query="$sql_query WHERE" 483 | first_condition=1 484 | elif [ -n "$first_condition" ] ; then 485 | sql_query="$sql_query AND" 486 | fi 487 | for i in $(echo $includeartist | sed "s/,/ /g") 488 | do 489 | f=`echo $i|sed "s/_/ /g"` 490 | if [ $count -eq 0 ] ; then 491 | sql_query="$sql_query artist IN ('$f'" 492 | else 493 | sql_query="$sql_query, '$f'" 494 | fi 495 | count=`expr $count + 1` 496 | done 497 | sql_query="$sql_query)" 498 | fi 499 | if [ -n "$minrate" ] ; then 500 | if [ -z "$first_condition" ] ; then 501 | sql_query="$sql_query WHERE" 502 | first_condition=1 503 | elif [ -n "$first_condition" ] ; then 504 | sql_query="$sql_query AND" 505 | fi 506 | if [ "$minrate" -lt 0 ] ; then 507 | sql_query="$sql_query rating = 0" 508 | else 509 | sql_query="$sql_query rating >= $minrate" 510 | fi 511 | fi 512 | if [ -n "$artist" ] ; then 513 | if [ -z "$first_condition" ] ; then 514 | sql_query="$sql_query WHERE" 515 | first_condition=1 516 | elif [ -n "$first_condition" ] ; then 517 | sql_query="$sql_query AND" 518 | fi 519 | f=`echo $artist|sed "s/_/ /g"` 520 | if [ $exact -eq 1 ] ; then 521 | sql_query="$sql_query artist = '$f'" 522 | else 523 | sql_query="$sql_query artist like '%$f%'" 524 | fi 525 | fi 526 | if [ -n "$daysadded" ] ; then 527 | if [ -z "$first_condition" ] ; then 528 | sql_query="$sql_query WHERE" 529 | first_condition=1 530 | elif [ -n "$first_condition" ] ; then 531 | sql_query="$sql_query AND" 532 | fi 533 | tmval=`date +'%s'` 534 | tmval=`expr $tmval - $daysadded \* 86400` 535 | sql_query="$sql_query date_added >= $tmval" 536 | fi 537 | if [ -n "$karma" ] ; then 538 | if [ -z "$first_condition" ] ; then 539 | sql_query="$sql_query WHERE" 540 | first_condition=1 541 | elif [ -n "$first_condition" ] ; then 542 | sql_query="$sql_query AND" 543 | fi 544 | sql_query="$sql_query $karma" 545 | fi 546 | if [ -n "$play_counts" ] ; then 547 | if [ -z "$first_condition" ] ; then 548 | sql_query="$sql_query WHERE" 549 | first_condition=1 550 | elif [ -n "$first_condition" ] ; then 551 | sql_query="$sql_query AND" 552 | fi 553 | sql_query="$sql_query $play_counts" 554 | fi 555 | if [ -n "$daysheard" ] ; then 556 | if [ -z "$first_condition" ] ; then 557 | sql_query="$sql_query WHERE" 558 | first_condition=1 559 | elif [ -n "$first_condition" ] ; then 560 | sql_query="$sql_query AND" 561 | fi 562 | tmval=`date +'%s'` 563 | tmval=`expr $tmval - $daysheard \* 86400` 564 | sql_query="$sql_query last_played >= $tmval" 565 | fi 566 | if [ -n "$daysnotheard" ] ; then 567 | if [ -z "$first_condition" ] ; then 568 | sql_query="$sql_query WHERE" 569 | first_condition=1 570 | elif [ -n "$first_condition" ] ; then 571 | sql_query="$sql_query AND" 572 | fi 573 | if [ ! "$daysnotheard" = "0" ] ; then 574 | tmval=`date +'%s'` 575 | tmval=`expr $tmval - $daysnotheard \* 86400` 576 | sql_query="$sql_query (last_played < $tmval OR last_played IS NULL)" 577 | else 578 | sql_query="$sql_query last_played IS NULL" 579 | fi 580 | fi 581 | order_by=0 582 | if [ $oldfirst -eq 1 ] ; then 583 | if [ $order_by -eq 0 ] ; then 584 | sql_query="$sql_query ORDER BY last_played ASC" 585 | order_by=1 586 | else 587 | sql_query="$sql_query, last_played ASC" 588 | fi 589 | fi 590 | if [ $sort_popular -eq 1 ] ; then 591 | if [ $order_by -eq 0 ] ; then 592 | sql_query="$sql_query ORDER BY rating DESC" 593 | order_by=1 594 | else 595 | sql_query="$sql_query, rating DESC" 596 | fi 597 | fi 598 | if [ -n "$daysadded" ] ; then 599 | if [ $order_by -eq 0 ] ; then 600 | sql_query="$sql_query ORDER BY date_added ASC" 601 | order_by=1 602 | else 603 | sql_query="$sql_query, date_added ASC" 604 | fi 605 | fi 606 | if [ $limit -gt 0 ] ; then 607 | sql_query="$sql_query limit $limit" 608 | fi 609 | if [ -z "$fromyear" -a -z "$toyear" -a -z "$includegenre" -a -z "$excludegenre" \ 610 | -a -z "$includeartist" -a -z "$excludeartist" -a -z "$minrate" \ 611 | -a -z "$artist" -a -z "$daysadded" -a -z "$daysheard" -a -z "$daysnotheard" \ 612 | -a -z "$play_counts" -a -z "$karma" ] ; then 613 | echo "No options given and no default usage configuration found" 1>&2 614 | usage 1 615 | exit 1 616 | fi 617 | if [ $dummy -eq 0 ] ; then 618 | if [ -n "$playlist" ] ; then 619 | if [ "$playlist" = "now" ] ; then 620 | if [ $shuffle -eq 1 ] ; then 621 | /usr/bin/sqlite3 -noheader $stats_file "$sql_query;" | shuf > $playlist_dir/now.m3u 622 | else 623 | /usr/bin/sqlite3 -noheader $stats_file "$sql_query;" > $playlist_dir/now.m3u 624 | fi 625 | if [ -z "$mpd_host" ] ; then 626 | mpd_host=localhost 627 | fi 628 | if [ $do_clear -eq 1 ] ; then 629 | mpc --host="$mpd_host" clear 630 | fi 631 | mpc --host="$mpd_host" load now 632 | mpc --host="$mpd_host" rm now 633 | if [ $do_play -eq 1 ] ; then 634 | mpc --host="$mpd_host" play 635 | fi 636 | else 637 | if [ $shuffle -eq 1 ] ; then 638 | ( 639 | echo "# $prog_args" 640 | /usr/bin/sqlite3 -noheader $stats_file "$sql_query;" | shuf 641 | ) | tee $playlist_dir/"$playlist".m3u 642 | else 643 | ( 644 | echo "# $prog_args" 645 | /usr/bin/sqlite3 -noheader $stats_file "$sql_query;" 646 | ) | tee $playlist_dir/"$playlist".m3u 647 | fi 648 | fi 649 | else 650 | echo "# $prog_args" 651 | /usr/bin/sqlite3 -noheader $stats_file "$sql_query;" 652 | fi 653 | else 654 | echo "$sql_query;" 655 | fi 656 | exit 0 657 | -------------------------------------------------------------------------------- /obs/mpdev/_service: -------------------------------------------------------------------------------- 1 | 2 | 3 | https 4 | sourceforge.net 5 | /projects/indimail/files/github/mpdev-obs.tar.gz 6 | 7 | 8 | *.tar.gz 9 | *.tar.gz *.dsc *.spec PKGBUILD *.install *.changes 10 | 11 | 12 | -------------------------------------------------------------------------------- /output.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # $Log: output.in,v $ 4 | # Revision 1.2 2021-09-09 22:58:01+05:30 Cprogrammer 5 | # print output device env variables only during startup 6 | # 7 | # Revision 1.1 2021-09-09 12:19:13+05:30 Cprogrammer 8 | # Initial revision 9 | # 10 | # 11 | # $Id: output.in,v 1.2 2021-09-09 22:58:01+05:30 Cprogrammer Exp mbhangui $ 12 | # 13 | echo "$0: args=$*" 14 | if [ -n "$OUTPUT_CHANGED" ] ; then 15 | echo "Output Changed: $OUTPUT_CHANGED" 16 | fi 17 | if [ " $1" = " output-initialize" ] ; then 18 | env|grep OUTPUT_|grep -v "OUTPUT_C"| sort 19 | fi 20 | exit $? 21 | -------------------------------------------------------------------------------- /playpause.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # $Log: playpause.in,v $ 4 | # Revision 1.16 2023-06-30 21:00:37+05:30 Cprogrammer 5 | # pass RATING, PLAYCOUNT env variable to lcd_display 6 | # 7 | # Revision 1.15 2023-06-30 10:18:10+05:30 Cprogrammer 8 | # added use of fifo for accessing LCD display 9 | # 10 | # Revision 1.14 2023-06-29 10:36:33+05:30 Cprogrammer 11 | # use $HOME/.mpdev/lcd_display or libexec/mpdev/lcd_display 12 | # 13 | # Revision 1.13 2023-06-25 11:20:17+05:30 Cprogrammer 14 | # run lcd_display program 15 | # 16 | # Revision 1.12 2022-06-20 01:06:51+05:30 Cprogrammer 17 | # fixed date syntax for non-gnu date 18 | # 19 | # Revision 1.11 2021-04-26 10:01:33+05:30 Cprogrammer 20 | # display song played duration in playpause 21 | # 22 | # Revision 1.10 2021-04-24 20:48:53+05:30 Cprogrammer 23 | # prevent end-song getting executed twice when playlist ends 24 | # 25 | # Revision 1.9 2021-04-24 14:52:15+05:30 Cprogrammer 26 | # skip percentage calculation when SONG_PLAYED_DURATION is not set 27 | # 28 | # Revision 1.8 2021-04-23 18:43:42+05:30 Cprogrammer 29 | # display date in %Y-%m-%d %H:%M%S during play/pause 30 | # 31 | # Revision 1.7 2021-04-23 16:46:18+05:30 Cprogrammer 32 | # renamed SONG_PLAYED to SONG_PLAYED_DURATION 33 | # 34 | # Revision 1.6 2021-04-23 16:44:22+05:30 Cprogrammer 35 | # use SONG_PLAYED instead of ELAPSED_TIME 36 | # 37 | # Revision 1.5 2021-04-23 10:16:17+05:30 Cprogrammer 38 | # fixed end-song, pause-song getting skipped 39 | # 40 | # Revision 1.4 2021-04-19 22:07:08+05:30 Cprogrammer 41 | # create /tmp/mpdev directory 42 | # 43 | # Revision 1.3 2021-04-15 11:55:39+05:30 Cprogrammer 44 | # fix awk script for checking percent 45 | # 46 | # Revision 1.2 2020-08-18 08:16:37+05:30 Cprogrammer 47 | # use export command instead of declare 48 | # 49 | # Revision 1.1 2020-08-14 13:44:57+05:30 Cprogrammer 50 | # Initial revision 51 | # 52 | # 53 | # $Id: playpause.in,v 1.16 2023-06-30 21:00:37+05:30 Cprogrammer Exp mbhangui $ 54 | # 55 | 56 | if [ -z "$VERBOSE" ] ; then 57 | VERBOSE=0 58 | fi 59 | # we don't handle stream uri currently 60 | echo $SONG_URI|grep "^http://" >/dev/null 61 | if [ $? -eq 0 ] ; then 62 | exit 0 63 | fi 64 | SYSTEM=$(uname -s) 65 | case "$SYSTEM" in 66 | Linux) 67 | gnu_date=1 68 | ;; 69 | *) 70 | gnu_date=0 71 | ;; 72 | esac 73 | if [ -z "$MPDEV_TMPDIR" ] ; then 74 | MPDEV_TMPDIR=/tmp/mpdev 75 | fi 76 | mkdir -p $MPDEV_TMPDIR 77 | csum=`echo "$SONG_URI"| cksum | awk '{print $1}'` 78 | if [ $VERBOSE -gt 0 ] ; then 79 | t=$(date +'%s') 80 | if [ $gnu_date -eq 1 ] ; then 81 | echo "$0: PLAYER_STATE=$PLAYER_STATE [$t] [`date +"%Y-%m-%d %H:%M:%S" --date=@"$t"`] pos=$SONG_PLAYED_DURATION" 82 | else 83 | echo "$0: PLAYER_STATE=$PLAYER_STATE [$t] [`date -r "$t" +"%Y-%m-%d %H:%M:%S"`] pos=$SONG_PLAYED_DURATION" 84 | fi 85 | fi 86 | if [ " $PLAYER_STATE" = " play" ] ; then 87 | if [ ! -f $MPDEV_TMPDIR/start_time.$csum ] ; then 88 | echo $START_TIME > $MPDEV_TMPDIR/start_time.$csum 89 | if [ -f $MPDEV_TMPDIR/stats.$csum ] ; then 90 | touch -r $MPDEV_TMPDIR/stats.$csum $MPDEV_TMPDIR/start_time.$csum 91 | fi 92 | fi 93 | exit 0 94 | fi 95 | if [ -z "$MIN_PLAY_PERCENT" ] ; then 96 | MIN_PLAY_PERCENT=75 97 | fi 98 | if [ -f $MPDEV_TMPDIR/start_time.$csum ] ; then 99 | START_TIME=`cat $MPDEV_TMPDIR/start_time.$csum` 100 | else 101 | if [ -f $MPDEV_TMPDIR/sticker.$csum ] ; then 102 | START_TIME=$(stat --terse $MPDEV_TMPDIR/stats.$csum | awk '{print $13}') 103 | fi 104 | echo $START_TIME > $MPDEV_TMPDIR/start_time.$csum 105 | touch -r $MPDEV_TMPDIR/stats.$csum $MPDEV_TMPDIR/start_time.$csum 106 | fi 107 | 108 | if [ " $PLAYER_STATE" = " pause" ] ; then 109 | END_TIME=$(date +'%s') 110 | export END_TIME=$END_TIME 111 | exec $HOME/.mpdev/player pause-song 112 | fi 113 | if [ " $PLAYER_STATE" = " stop" ] ; then 114 | END_TIME=$(date +'%s') 115 | export END_TIME=$END_TIME 116 | if [ ! -f $MPDEV_TMPDIR/end.$csum ] ; then 117 | exec $HOME/.mpdev/player end-song 118 | fi 119 | fi 120 | if ( test -n "$LCD_HOST" && test -n "$LCD_PORT" ) || ( test -n "$LCD_FIFO" ) ; then 121 | if [ "$PLAYER_STATE" = "pause" -o "$PLAYER_STATE" = "resume" ] ; then 122 | RATING=$(cat $MPDEV_TMPDIR/rating.$csum) 123 | PLAYCOUNT=$(cat $MPDEV_TMPDIR/pcount.$csum) 124 | if [ -x $HOME/.mpdev/lcd_dislay ] ; then 125 | env RATING="$RATING" PLAYCOUNT="$PLAYCOUNT" $HOME/.mpdev/lcd_display "$PLAYER_STATE" 126 | elif [ -x @libexecdir@/mpdev/lcd_dislay ] ; then 127 | env RATING="$RATING" PLAYCOUNT="$PLAYCOUNT" @libexecdir@/mpdev/lcd_dislay "$PLAYER_STATE" 128 | fi 129 | fi 130 | fi 131 | -------------------------------------------------------------------------------- /prepare_obs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # This script prepares artifacts that can be downloaded for openSUSE build service 4 | # It creates name.tar.gz, debian.tar.gz, name.spec name.changes and PKGBUILD 5 | # 6 | set -e 7 | if [ $# -ne 1 ] ; then 8 | echo "USAGE: prepare_obs name" 1>&2 9 | exit 1 10 | fi 11 | name=$1 12 | curdir=$PWD 13 | version=$(cat conf-version) 14 | stage=$HOME/stage 15 | mkdir -p $stage 16 | meta_pkg=0 17 | if [ ! -f conf-release ] ; then 18 | echo 1.1 > conf-release 19 | fi 20 | if [ -f $name.packages ] ; then 21 | meta_pkg=1 22 | for dir in `cat $name.packages` 23 | do 24 | real_dir=$(basename $dir) 25 | echo $dir|grep "/" >/dev/null 26 | if [ $? -eq 0 ] ; then 27 | pkg_name=$(basename $dir|sed -e 's{-x{{g') 28 | else 29 | pkg_name=$(echo $dir|sed -e 's{-x{{g') 30 | fi 31 | if [ -d $dir ] ; then 32 | cd $dir 33 | else 34 | echo "$dir: No such file or directory" 1>&2 35 | exit 1 36 | fi 37 | ver=$(cat conf-version) 38 | if [ -z "$ver" ] ; then 39 | echo "no version found for package $pkg_name" 1>&2 40 | exit 1 41 | fi 42 | echo Preparing $pkg_name-$ver 43 | cp -rpf . $stage/$pkg_name-$ver 44 | cd $stage/$pkg_name-$ver 45 | if [ -f default.configure -a ! -f ./configure -o ! -f ./Makefile ] ; then 46 | echo reconfiguring $pkg_name-$ver 47 | ./default.configure >/dev/null 2>&1 48 | fi 49 | if [ -f Makefile ] ; then 50 | echo cleaning $pkg_name-$ver 51 | set +e 52 | make clean && make distclean >/dev/null 2>&1 53 | find . -type d -name autom4te.cache -exec /bin/rm -rf '{}' '+' 54 | set -e 55 | fi 56 | # remove debian directory from archive 57 | #/bin/rm -rf debian .git RCS 58 | cd .. 59 | echo "creating archive $pkg_name-$ver.tar.gz" 60 | tar cfz $pkg_name-$ver.tar.gz $pkg_name-$ver 61 | if [ ! "$real_dir" = "$pkg_name" -a ! -L $real_dir ] ; then 62 | ln -sr $pkg_name-$ver $real_dir 63 | fi 64 | cd $curdir 65 | done 66 | fi 67 | echo "Preparing $name-$version" 68 | cp -rp . $stage/$name-$version 69 | if [ -L $stage/$name-$version/catChangeLog ] ; then 70 | /bin/rm -f $stage/$name-$version/catChangeLog 71 | cp catChangeLog $stage/$name-$version # for spec file, changes, debian/changelog to get built 72 | fi 73 | cd $stage/$name-$version 74 | if [ -f default.configure -a ! -f ./configure -o ! -f ./Makefile ] ; then 75 | echo reconfiguring $name-$version 76 | ./default.configure >/dev/null 2>&1 77 | fi 78 | 79 | if [ ! -f $name.changes ] ; then 80 | make $name.changes 81 | fi 82 | if [ ! -f $name.changes ] ; then 83 | # This will build the $name.changes file 84 | ./catChangeLog --changes > $name.changes 85 | fi 86 | 87 | # now build the spec, PKGBUILD and dsc files 88 | 89 | # rpm distributions 90 | if [ -f $name.spec.in -a -f Makefile -a ! -f $name.$spec ] ; then 91 | make $name.spec 92 | fi 93 | 94 | for i in permissions.easy permissions.secure permissions.paranoid rpmlintrc 95 | do 96 | if [ -f $name-$i.in -a -f Makefile -a ! -f $name-$i ] ; then 97 | make $name-$i 98 | fi 99 | if [ -f $name-$i ] ; then 100 | cp $name-$i $stage 101 | fi 102 | done 103 | 104 | # debian 105 | if [ -f debian/Makefile.in ] ; then 106 | make debian/Makefile 107 | fi 108 | 109 | if [ -f debian/Makefile ] ; then 110 | make -C debian 111 | cp debian/debian.tar.gz $stage 112 | cp debian/*.dsc $stage 113 | make -C debian clean >/dev/null 114 | fi 115 | 116 | # arch linux 117 | if [ -f PKGBUILD.in -a -f Makefile -a ! -f PKGBUILD ] ; then 118 | make PKGBUILD 119 | fi 120 | 121 | if [ -f PKGBUILD ] ; then 122 | sed -i 's/_build_on_obs=.*/_build_on_obs=1/g' PKGBUILD 123 | total=$(grep "#### INSTALL.* ####" PKGBUILD | wc -l) 124 | if [ $total -le 1 ] ; then 125 | sed -n '/#### INSTALL SCRIPTS ####/,$p' PKGBUILD \ 126 | | grep -v "^####" > archpkg.install || true 127 | if [ ! -s archpkg.install ] ; then 128 | /bin/rm -f archpkg.install 129 | fi 130 | else 131 | count=1 132 | while true 133 | do 134 | sed -n "/#### INSTALL$count SCRIPTS ####/,/#### END ####/p" PKGBUILD \ 135 | | grep -v "^####" > archpkg"$count".install || true 136 | if [ ! -s archpkg"$count".install ] ; then 137 | /bin/rm -f archpkg"$count".install 138 | fi 139 | if [ $count -eq $total ] ; then 140 | break 141 | fi 142 | count=$(expr $count + 1) 143 | done 144 | fi 145 | fi 146 | 147 | for i in $name.spec $name.changes PKGBUILD archpkg*.install 148 | do 149 | if [ -f $i ] ; then 150 | cp $i $stage 151 | fi 152 | done 153 | if [ -f extra_src ] ; then 154 | make `grep -h -v "^#" extra_src` 155 | cp -rpf `grep -h -v "^#" extra_src` $stage 156 | fi 157 | if [ -f Makefile ] ; then 158 | echo cleaning $name-$version 159 | set +e 160 | make clean && make distclean >/dev/null 2>&1 161 | find . -type d -name autom4te.cache -exec /bin/rm -rf '{}' '+' 162 | set -e 163 | fi 164 | 165 | # clean meta packages 166 | if [ $meta_pkg -eq 1 ] ; then 167 | for dir in `cat $name.packages` 168 | do 169 | real_dir=$(basename $dir) 170 | echo $dir | grep "/" >/dev/null 171 | if [ $? -eq 0 ] ; then 172 | pkg_name=$(echo $real_dir | sed -e 's{-x{{g') 173 | else 174 | pkg_name=$(echo $dir | sed -e 's{-x{{g') 175 | fi 176 | ver=$(cat $dir/conf-version) 177 | /bin/rm -rf $stage/$pkg_name-$ver 178 | if [ ! "$real_dir" = "$pkg_name" -a -L $stage/$real_dir ] ; then 179 | /bin/rm -f $stage/$real_dir 180 | fi 181 | done 182 | /bin/rm -rf $stage/$name-$version 183 | else 184 | /bin/rm -rf debian .git RCS 185 | cd .. 186 | echo "creating archive $name-$version.tar.gz" 187 | tar cfz $name-$version.tar.gz $name-$version 188 | /bin/rm -rf $name-$version 189 | fi 190 | -------------------------------------------------------------------------------- /replacestr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Log: replacestr.c,v $ 3 | * Revision 1.1 2020-07-19 18:26:54+05:30 Cprogrammer 4 | * Initial revision 5 | * 6 | */ 7 | #ifdef HAVE_CONFIG_H 8 | #include "config.h" 9 | #endif 10 | #ifdef HAVE_QMAIL 11 | #include 12 | #include 13 | #include 14 | #endif 15 | 16 | #ifndef lint 17 | static char sccsid[] = "$Id: replacestr.c,v 1.1 2020-07-19 18:26:54+05:30 Cprogrammer Exp mbhangui $"; 18 | #endif 19 | 20 | /* 21 | * returns 0 if search string ch not found 22 | * and leaves buf untouched 23 | */ 24 | int 25 | replacestr(char *str, char *ch, char *rch, stralloc *buf) 26 | { 27 | int chlen, rchlen, prev; 28 | register int i, cnt; 29 | register char *ptr, *s; 30 | 31 | chlen = str_len(ch); 32 | rchlen = str_len(rch); 33 | for (ptr = str, prev = cnt = 0; *ptr;) { 34 | if (!(s = str_str(ptr, ch))) 35 | break; 36 | if (!cnt) 37 | buf->len = 0; 38 | i = s - str; 39 | if (!stralloc_catb(buf, ptr, i - prev)) 40 | return (-1); 41 | if (!stralloc_catb(buf, rch, rchlen)) 42 | return (-1); 43 | ptr = str + i + chlen; /*- move past the found character */ 44 | prev = i + chlen; 45 | cnt++; 46 | } 47 | if (cnt) { 48 | /*- copy remaining data */ 49 | if (!stralloc_cats(buf, ptr)) 50 | return (-1); 51 | if (!stralloc_0(buf)) 52 | return (-1); 53 | buf->len--; 54 | } 55 | return (cnt); 56 | } 57 | -------------------------------------------------------------------------------- /replacestr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Log: replacestr.h,v $ 3 | * Revision 1.1 2019-04-13 23:39:27+05:30 Cprogrammer 4 | * replacestr.h 5 | * 6 | */ 7 | #ifndef REPLACESTR_H 8 | #define REPLACESTR_H 9 | #ifdef HAVE_CONFIG_H 10 | #include "config.h" 11 | #endif 12 | #ifdef HAVE_QMAIL 13 | #include 14 | #endif 15 | 16 | int replacestr(char *, char *, char *, stralloc *); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /songi.1: -------------------------------------------------------------------------------- 1 | .TH songi 1 2 | .SH NAME 3 | songi \- Display song's information in stats.db 4 | 5 | .SH SYNOPSYS 6 | .B songi \fIfilename\fR(s) 7 | 8 | .SH DESCRIPTION 9 | \fBsongi\fR displays information about song, namely 10 | .EX 11 | play_count 12 | last_played 13 | rating 14 | karma 15 | duration 16 | artist 17 | album 18 | title 19 | track 20 | genre, 21 | date 22 | composer 23 | performer 24 | disc 25 | date_added 26 | last_modified 27 | .EE 28 | songi expects audio files to be provided on the commandline. You can use wildcards in filenames. 29 | 30 | .SH "SEE ALSO" 31 | karma(1) 32 | -------------------------------------------------------------------------------- /songi.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # $Id: songi.in,v 1.8 2025-01-17 12:13:54+05:30 Cprogrammer Exp mbhangui $ 4 | # 5 | 6 | get_mpd_conf_value() 7 | { 8 | grep "^$1" @sysconfdir@/mpd.conf|awk '{print $2}' | \ 9 | sed -e 's{"{{g' 10 | } 11 | 12 | locate_file() 13 | { 14 | dir="$2" 15 | file=$(basename "$dir") 16 | while true 17 | do 18 | t=$(dirname "$dir") 19 | if [ -f $1/"$file" ] ; then 20 | echo "$1/$file" | sed s{"$1"/{{ 21 | break 22 | fi 23 | dir="$t" 24 | file="$(basename "$dir")/$file" 25 | done 26 | } 27 | 28 | display_info() 29 | { 30 | turi=`echo $1|sed -e "s{'{''{g"` 31 | out=$(mktemp -t mpdevXXXXXXXXXX) 32 | Q="SELECT title,play_count,last_played," 33 | Q="$Q rating, karma, duration," 34 | Q="$Q artist, album, track, genre," 35 | Q="$Q date, composer, performer, disc," 36 | Q="$Q datetime(date_added, 'unixepoch', 'localtime')," 37 | Q="$Q datetime(last_modified, 'unixepoch', 'localtime')" 38 | Q="$Q FROM song WHERE uri='$turi';" 39 | sqlite3 -noheader -line -batch $stats_file "$Q" | sed \ 40 | -e 's{.*datetime(date_added.*){ Date Added{g' \ 41 | -e 's{.*datetime(last_modified.*){Last Updated{g' \ 42 | -e 's{ {{g' > $out 43 | t1=$(sed -n 3p < $out | awk '{print $3}') 44 | if [ -z "$t1" ] ; then 45 | t1=0 46 | fi 47 | # play_count 48 | t2=$(sed -n 2p < $out | awk '{print $3}') 49 | if [ -z "$t2" ] ; then 50 | t2=0 51 | fi 52 | if [ $t1 -eq 0 -o $t2 -eq 0 ] ; then 53 | last_played="never" 54 | else 55 | t2=$(date +%s) 56 | extra_days=0 57 | extra_days_func $t1 58 | diff=$(echo $t1 $t2 | awk '{printf("%d\n", $2-$1)}') 59 | days=$(echo $diff | awk '{printf("%d\n", $1/86400)}') 60 | years=$(expr $days / 365) 61 | days=$(expr $days % 365) 62 | if [ $extra_days -gt 0 ] ; then 63 | days=$(expr $days - 1) 64 | fi 65 | hours=$(echo $diff | awk '{printf("%d\n", ($1%86400)/3600)}') 66 | mins=$(echo $diff | awk '{printf("%d\n", ($1%3600)/60)}') 67 | secs=$(echo $diff | awk '{printf("%d\n", $1%60)}') 68 | if [ $years -eq 0 ] ; then 69 | last_played="$(date --date=@"$t1")\n Last Played = $days days $hours hr $mins min $secs sec" 70 | else 71 | last_played="$(date --date=@"$t1")\n Last Played = $years years $days days $hours hr $mins min $secs sec" 72 | fi 73 | fi 74 | # duration 75 | t1=$(sed -n 6p < $out | awk '{print $3}') 76 | hours=$(echo $t1 | awk '{printf("%d\n", ($1%86400)/3600)}') 77 | mins=$(echo $t1 | awk '{printf("%d\n", ($1%3600)/60)}') 78 | secs=$(echo $t1 | awk '{printf("%d\n", $1%60)}') 79 | if [ "$hours" = "0" ] ; then 80 | duration="$mins min $secs sec ($t1)" 81 | else 82 | duration="$hours hr $mins min $secs sec ($t1)" 83 | fi 84 | sed \ 85 | -e "s{last_played.*{Last Played = $last_played{g" \ 86 | -e "s{duration.*{Duration = $duration{g" < $out 87 | /bin/rm -f $out 88 | } 89 | 90 | extra_days_func() 91 | { 92 | t1=$1 93 | t2=$(date +%s) 94 | y1=$(date --date="@$t1" +%Y) 95 | m1=$(date --date="@$t1" +%m) 96 | y2=$(date --date="@$t2" +%Y) 97 | m2=$(date --date="@$t2" +%m) 98 | year=$y1 99 | first_flag=1 100 | extra_days=0 101 | while true 102 | do 103 | leap_year=0 104 | is_century=$(expr $year % 100) 105 | if [ $is_century -eq 0 ] ; then 106 | is_400=$(expr $year % 400) 107 | if [ $is_400 -eq 0 ] ; then 108 | leap_year=1 109 | fi 110 | else 111 | is_4=$(expr $year % 4) 112 | if [ $is_4 -eq 0 ] ; then 113 | leap_year=1 114 | fi 115 | fi 116 | if [ $leap_year -eq 1 ] ; then 117 | if [ $first_flag -eq 1 ] ; then 118 | d1=$(date --date="@$t1" +%d) 119 | if [ $m1 -eq 2 -a $d1 -lt 29 ] ; then 120 | extra_days=$(expr $extra_days + 1) 121 | elif [ $m1 -eq 1 ] ; then 122 | extra_days=$(expr $extra_days + 1) 123 | fi 124 | first_flag=0 125 | else 126 | extra_days=$(expr $extra_days + 1) 127 | fi 128 | fi 129 | if [ $year -eq $y2 ] ; then 130 | if [ $leap_year -eq 1 ] ; then 131 | d2=$(date --date="@$t2" +%d) 132 | if [ $m2 -eq 2 -a $d2 -gt 28 ] ; then 133 | extra_days=$(expr $extra_days + 1) 134 | elif [ $m2 -gt 2 ] ; then 135 | extra_days=$(expr $extra_days + 1) 136 | fi 137 | fi 138 | break 139 | fi 140 | year=$(expr $year + 1) 141 | if [ $year -gt $y2 ] ; then 142 | break 143 | fi 144 | done 145 | } 146 | 147 | if [ $# -eq 0 ] ; then 148 | uri=$(mpc current -f %file%) 149 | if [ -z "$uri" ] ; then 150 | echo "No song playing and no options given" 1>&2 151 | exit 1 152 | fi 153 | fi 154 | music_dir=`get_mpd_conf_value music_directory` 155 | if [ $? -ne 0 ] ; then 156 | echo "could not get music directory from mpd.conf" 1>&2 157 | exit 1 158 | fi 159 | sticker_file=$(get_mpd_conf_value sticker_file) 160 | if [ $? -ne 0 ] ; then 161 | echo "sticker database not enabled in @sysconfdir@/mpd.conf" 1>&2 162 | return 1 163 | else 164 | if [ ! -f $sticker_file ] ; then 165 | echo "$sticker_file: No such file or directory" 1>&2 166 | return 1 167 | fi 168 | fi 169 | stats_dir=$(dirname $sticker_file) 170 | stats_file=$stats_dir/stats.db 171 | if [ ! -f $stats_file ] ; then 172 | echo "$stats_file: No such file or directory" 1>&2 173 | return 1 174 | fi 175 | if [ $# -eq 0 ] ; then 176 | t=$(basename "$uri") 177 | echo "---- $t ------------------------" 178 | display_info "$uri" 179 | echo "----------------------------" 180 | exit $? 181 | fi 182 | for i in "$@" 183 | do 184 | uri=$(locate_file "$music_dir" "$i") 185 | if [ -n "$uri" ] ; then 186 | t=$(basename "$uri") 187 | ext=$(echo $t|rev|cut -d. -f1|rev) 188 | case $ext in 189 | dsf|flac|m4a|mp3|MP3|ogg|wma|wv) 190 | echo "---- $t ------------------------" 191 | display_info "$uri" 192 | echo "----------------------------" 193 | ;; 194 | *) 195 | echo "Unsupported extension $ext in $t" 1>&2 196 | ;; 197 | esac 198 | fi 199 | done 200 | # 201 | # $Log: songi.in,v $ 202 | # Revision 1.8 2025-01-17 12:13:54+05:30 Cprogrammer 203 | # display last played in years, days, hours, minutes, seconds 204 | # 205 | # Revision 1.7 2024-04-04 20:51:29+05:30 Cprogrammer 206 | # fixed last_played when song has never been played 207 | # 208 | # Revision 1.6 2024-03-26 19:24:12+05:30 Cprogrammer 209 | # display last played in days, hours, mins, secs ago 210 | # 211 | # Revision 1.5 2022-06-20 01:07:30+05:30 Cprogrammer 212 | # use directories set in ./configure 213 | # 214 | # Revision 1.4 2021-10-15 18:41:52+05:30 Cprogrammer 215 | # formatted for better display 216 | # 217 | # Revision 1.3 2021-10-14 22:39:24+05:30 Cprogrammer 218 | # bugfix for period in filenames 219 | # 220 | # Revision 1.2 2021-10-01 12:05:56+05:30 Cprogrammer 221 | # removed name column from song table in stats db 222 | # 223 | # Revision 1.1 2021-09-30 20:31:57+05:30 Cprogrammer 224 | # Initial revision 225 | # 226 | -------------------------------------------------------------------------------- /tcpopen.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Log: tcpopen.h,v $ 3 | * Revision 1.1 2015-08-20 18:30:40+05:30 Cprogrammer 4 | * Initial revision 5 | * 6 | * 7 | */ 8 | #ifndef _TCPOPEN_H 9 | #define _TCPOPEN_H 10 | 11 | #ifndef __P 12 | #ifdef __STDC__ 13 | #define __P(args) args 14 | #else 15 | #define __P(args) () 16 | #endif 17 | #endif 18 | 19 | int tcpopen __P((char *, char *, int)); 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /transfer_play.1: -------------------------------------------------------------------------------- 1 | .TH transfer_play 1 2 | .SH NAME 3 | transfer_play \- Transfer mpd playlist from one host to another 4 | 5 | .SH SYNOPSYS 6 | .B transfer_play [--play] [--no-rm] \fIsrc\fR \fIdest\fR 7 | 8 | .SH DESCRIPTION 9 | \fBtransfer_play\fR transfers your mpd(1) playlist from one \fIsrc\fR to 10 | \fIdest\fR. It uses the value of \fIstate_file\fR parameter in mpd.conf(5) 11 | to get the current playlist on \fIsrc\fR. It the uses mpc(1) to load the 12 | playlist on \fIdest\fR. 13 | 14 | .SH OPTIONS 15 | Known values for OPTION are: 16 | 17 | --play 18 | start playing on destination after transferring current playlist 19 | 20 | --no-rm 21 | Do not remove current playlist from source after transfer 22 | 23 | .SH SEE ALSO 24 | mpd(1), 25 | mpdev(1), 26 | mpdplaylist(1), 27 | mpd.conf(5) 28 | -------------------------------------------------------------------------------- /transfer_play.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # $Log: transfer_play.in,v $ 3 | # Revision 1.10 2023-01-04 23:41:33+05:30 Cprogrammer 4 | # fixed process_cmdline 5 | # 6 | # Revision 1.9 2022-11-25 21:17:02+05:30 Cprogrammer 7 | # added --clearsrc, --cleardst to clear current playlist on source, destination 8 | # 9 | # Revision 1.8 2022-10-21 13:45:26+05:30 Cprogrammer 10 | # added command line options --play, --no-rm 11 | # 12 | # Revision 1.7 2022-06-20 01:07:37+05:30 Cprogrammer 13 | # use directories set in ./configure 14 | # 15 | # Revision 1.6 2021-02-14 18:43:07+05:30 Cprogrammer 16 | # display list of valid hosts on wrong input 17 | # 18 | # Revision 1.5 2020-09-05 12:32:42+05:30 Cprogrammer 19 | # clear playlist before adding 20 | # 21 | # Revision 1.4 2020-08-30 10:57:30+05:30 Cprogrammer 22 | # use state_file definition in mpd.conf to figure out state_file directory 23 | # 24 | # Revision 1.3 2020-08-11 22:23:23+05:30 Cprogrammer 25 | # use mpc to play and remove playlist 26 | # 27 | # Revision 1.2 2020-07-23 01:47:58+05:30 Cprogrammer 28 | # removed incorrect check for tohost 29 | # 30 | # Revision 1.1 2020-07-22 15:50:47+05:30 Cprogrammer 31 | # Initial revision 32 | # 33 | # 34 | # $Id: transfer_play.in,v 1.10 2023-01-04 23:41:33+05:30 Cprogrammer Exp mbhangui $ 35 | # 36 | 37 | get_mpd_conf_value() 38 | { 39 | grep "^$1" @sysconfdir@/mpd.conf|awk '{print $2}' | \ 40 | sed -e 's{"{{g' 41 | } 42 | 43 | get_mpd_state() 44 | { 45 | ( 46 | do_print=0 47 | cat $state_dir/mpd_state.$1 | while read line 48 | do 49 | if [ " $line" = " playlist_begin" ] ; then 50 | do_print=1 51 | continue 52 | fi 53 | if [ " $line" = " playlist_end" ] ; then 54 | break 55 | fi 56 | if [ $do_print -eq 1 ] ; then 57 | echo $line 58 | fi 59 | done 60 | ) | sed -e 's{^.*:{{' 61 | } 62 | 63 | usage() 64 | { 65 | if [ -f /usr/bin/less ] ; then 66 | MORE=/usr/bin/less 67 | else 68 | MORE=/usr/bin/more 69 | fi 70 | $MORE 1>&2 <//'` 98 | optarg=">$optarg" 99 | optval=`echo "$1" | cut -d'>' -f1` 100 | prog_args="$prog_args $optval\"$optarg\"" 101 | ;; 102 | -*\<*) 103 | optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*&2 152 | usage 1 153 | fi 154 | playlist_dir=$(get_mpd_conf_value playlist_directory) 155 | if [ $? -ne 0 ] ; then 156 | echo "could not get playlist directory from mpd.conf" 1>&2 157 | exit 1 158 | fi 159 | music_dir=$(get_mpd_conf_value music_dir) 160 | if [ $? -ne 0 ] ; then 161 | echo "could not get music directory from mpd.conf" 1>&2 162 | exit 1 163 | fi 164 | 165 | state_file=$(get_mpd_conf_value state_file) 166 | state_dir=$(dirname $state_file) 167 | if [ ! -f $state_dir/mpd_state.$srchost ] ; then 168 | echo "No such host $srchost" 1>&2 169 | echo "List of valid hosts" 170 | ls $state_dir/mpd_state.*|cut -d. -f2 171 | exit 1 172 | fi 173 | 174 | out=$(mktemp -t mpdevXXXXXXXXXX) 175 | # get current playlist from $srchost 176 | get_mpd_state $srchost > $out.m3u 177 | 178 | if [ -s $out.m3u ] ; then 179 | mv $out.m3u $playlist_dir 180 | 181 | # clear current playlist on $dsthost 182 | if [ $cleardst -eq 1 ] ; then 183 | mpc --host="$dsthost" clear 184 | fi 185 | # create current playlist from $outb 186 | outb=$(basename $out) 187 | mpc --host=$dsthost load $outb 188 | # delete playlist $outb.m3u from playlist directory 189 | mpc --host=$dsthost rm $outb 190 | 191 | if [ $do_play -eq 1 ] ; then 192 | # start playing current playlist on $dsthost 193 | mpc --host=$dsthost play 194 | fi 195 | 196 | # clear current playlist on $srchost 197 | if [ $clearsrc -eq 1 ] ; then 198 | mpc --host="$srchost" clear 199 | fi 200 | /bin/rm -f $out 201 | else 202 | /bin/rm -f $out $out.m3u 203 | echo "empty current playlist on source" 1>&2 204 | exit 1 205 | fi 206 | -------------------------------------------------------------------------------- /warn-auto.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # WARNING: This file was auto-generated. Do not edit! 3 | --------------------------------------------------------------------------------