debian/0000775000000000000000000000000012705246062007174 5ustar debian/mythtv.cnf0000664000000000000000000000005612703351755011224 0ustar [mysqld] #bind-address=:: max_connections=100 debian/rules0000775000000000000000000001562512703351755010271 0ustar #!/usr/bin/make -f #For our custom rules on all mythtv packages # get-orig-source # info # newest-revision include debian/mythtv.make #build goes here buildroot := debian/tmp # Set this to yes for releases MYTHTV_RELEASE ?= no ifeq (yes,$(MYTHTV_RELEASE)) MYTHTV_COMPILE_TYPE = release else MYTHTV_COMPILE_TYPE = profile endif # Use the 'profile' compile type when nostrip or noopt is used ifneq (,$(filter nostrip noopt,$(DEB_BUILD_OPTIONS))) MYTHTV_COMPILE_TYPE = profile endif ## Export QT version explicitely (fixes issues for non x86/arm builders) export QT_SELECT = 5 # # # Architecture Independent Build flags # # # MYTHTV_CONFIGURE_OPTS += --compile-type=$(MYTHTV_COMPILE_TYPE) \ --prefix=/usr \ --runprefix=/usr \ --disable-mythlogserver \ --enable-crystalhd \ --enable-lirc \ --enable-audio-alsa \ --enable-audio-oss \ --enable-dvb \ --enable-ivtv \ --enable-firewire \ --enable-joystick-menu \ --with-bindings=perl \ --enable-ffmpeg-pthreads \ --enable-pic \ --perl-config-opts="INSTALLDIRS=vendor" \ --enable-libvpx \ --enable-sdl \ --enable-libmp3lame \ --enable-libx264 \ --enable-vdpau ifeq "$(DEB_BUILD_ARCH)" "armhf" MYTHTV_CONFIGURE_OPTS += --disable-opengl-video --disable-opengl --disable-vaapi else MYTHTV_CONFIGURE_OPTS += --enable-opengl-video --enable-vaapi endif # # # Architecture dependent build flags # # # DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH) ifeq "$(DEB_BUILD_ARCH)" "i386" MYTHTV_CONFIGURE_OPTS += --cpu=i686 --enable-mmx endif ifeq "$(DEB_BUILD_ARCH)" "powerpc" MYTHTV_CONFIGURE_OPTS += --enable-altivec --extra-cxxflags="-maltivec" endif ifeq "$(DEB_BUILD_ARCH)" "armhf" MYTHTV_CONFIGURE_OPTS += --extra-cflags="-I/opt/vc/include" --extra-cxxflags="-I/opt/vc/include" --extra-cflags="-I/opt/vc/include/IL" --extra-cxxflags="-I/opt/vc/include/IL" --extra-libs="-L/opt/vc/lib" --extra-cflags="-I/opt/vc/include/interface/vcos/pthreads" --extra-cxxflags="-I/opt/vc/include/interface/vcos/pthreads" --extra-cflags="-I/opt/vc/include/interface/vmcs_host/linux" --extra-cxxflags="-I/opt/vc/include/interface/vmcs_host/linux" --extra-libs="-lEGL" endif #Mythplugins configure opts MYTHPLUGINS_CONFIGURE_OPTS += --prefix=/usr \ --enable-all \ --zm-version=1.22.3 \ --qmake=/usr/bin/qmake \ ifeq "$(DEB_BUILD_ARCH)" "armhf" MYTHPLUGINS_CONFIGURE_OPTS += --disable-opengl endif #Use moar CPUs for jya PROCESSORS ?= $(shell grep -ic ^processor /proc/cpuinfo) ifeq (0,$(PROCESSORS)) PROCESSORS := 1 endif #link problem with binutils 2.21 in precise #and ffmpeg sync from 0.26, libswscale LDFLAGS:=$(shell DEB_LDFLAGS_MAINT_STRIP="-Wl,-Bsymbolic-functions" dpkg-buildflags --get LDFLAGS) # Need a writable home directory for ccache export HOME=$(CURDIR)/debian/home %: dh $@ --parallel --with systemd #Rather than have a configure/build/install phase, combine them all so we can do each part in order override_dh_auto_install: if [ -f mythtv/VERSION ] && [ -f debian/DESCRIBE ]; then \ mv mythtv/VERSION mythtv/VERSION.old ;\ cp debian/DESCRIBE mythtv/VERSION ;\ fi cd mythtv && sh version.sh `pwd` mkdir $(CURDIR)/debian/home #mythtv cd mythtv && ./configure $(MYTHTV_CONFIGURE_OPTS) $(MAKE) -j$(PROCESSORS) -C mythtv $(MAKE) -C mythtv install INSTALL_ROOT=$(CURDIR)/debian/tmp #mythplugins cd mythplugins && ./configure $(MYTHPLUGINS_CONFIGURE_OPTS) --mythroot=$(CURDIR)/debian/tmp $(MAKE) -j$(PROCESSORS) -C mythplugins for plugin in mytharchive \ mythgallery mythgame mythmusic mythmovies mythnews \ mythweather mythzoneminder mythbrowser mythnetvision ; do \ $(MAKE) -C mythplugins/$$plugin install INSTALL_ROOT=$(CURDIR)/debian/$$plugin; \ done #(MythTV) We replace these with shell scripts mv debian/tmp/usr/bin/mythfrontend debian/tmp/usr/bin/mythfrontend.real mv debian/tmp/usr/bin/mythtv-setup debian/tmp/usr/bin/mythtv-setup.real #(All) Make sure python/perl scripts are executable find debian/tmp/usr/share -type f \( -iname "*.p[y|l]" ! -iname "oauth_api.py" \) -size +1b -exec chmod 755 {} \; #Set up python package properly dh_python2 -plibmyth-python override_dh_install: if [ -d /etc/php5 ]; then \ mkdir -p ${buildroot}/etc/php5/apache2/conf.d; \ cp debian/20-mythweb.ini ${buildroot}/etc/php5/apache2/conf.d; \ elif [ -d /etc/php/7.0 ]; then \ mkdir -p ${buildroot}/etc/php/7.0/apache2/conf.d; \ cp debian/20-mythweb.ini ${buildroot}/etc/php/7.0/apache2/conf.d; \ fi dh_install -Xusr/share/mythtv/fonts/Free \ -Xusr/share/mythtv/fonts/Purisa \ -Xusr/share/mythtv/fonts/Droid \ -Xusr/share/mythtv/fonts/texgyrechorus \ -Xusr/lib/libmythzmq.la \ -Xusr/share/mythtv/fonts/tiresias_gpl3.txt \ -XLICENSE \ -X.git \ -Xscriptaculous \ -Xprototype.js \ -Xjquery.min.js \ --fail-missing override_dh_installinit: dh_installinit #(MythTV) Remove license files find debian/tmp -name "COPYING" -delete find debian/tmp -name "README.license" -delete #(MythTV) Set correct permissions for png and html files find debian/tmp -regex '.*\.png$$' -print0 | xargs -0 -r chmod 644 find debian/tmp -regex '.*\.html$$' -print0 | xargs -0 -r chmod 644 override_dh_strip: dh_strip --dbg-package=mythtv-dbg override_dh_makeshlibs: dh_makeshlibs -V -Xusr/lib/mythtv/filters override_dh_compress: dh_compress -X.pl -X.py override_dh_fixperms: dh_fixperms -X.pl -X.py #themes shouldn't be like this for type in png html txt jpg xml ; do \ find debian -name "*.$$type" -type f -exec chmod -x {} \; ;\ done override_dh_auto_clean: [ -f mythtv/config.mak ] && $(MAKE) -C mythtv distclean || true [ -f mythplugins/config.pro ] && $(MAKE) -C mythplugins distclean || true [ -f mythtv/VERSION.old ] && mv mythtv/VERSION.old mythtv/VERSION || true dh_auto_clean debconf-updatepo rm -rf $(CURDIR)/debian/home override_dh_installdocs: dh_installdocs #(MythTV) Remove license files from contrib documentation. find debian/mythtv-backend/usr/share/doc/mythtv-backend/contrib \ -name "COPYING" -delete rm -f debian/mythtv-common/usr/share/mythtv/themes/Terra/watermarks/README.license #(MythWeb) for file in LICENSE README INSTALL; do \ rm -f debian/mythweb/usr/share/mythtv/mythweb/$$file ;\ done find debian/mythweb -name ".gitignore" -type f -delete || true rm -rf debian/mythweb/usr/share/mythtv/mythweb/data/tv_icons rm -rf debian/mythweb/usr/share/mythtv/mythweb/data/cache #(Myththemes) rm -f debian/mythtv-theme-childish/usr/share/mythtv/themes/Childish/COPYING override_dh_installman: debian/generate_manpages.sh dh_installman debian/control0000664000000000000000000005200512705245370010602 0ustar Source: mythtv Section: graphics Priority: optional Maintainer: MythTV Ubuntu Maintainers Uploaders: Mario Limonciello , Andres Mejia , Homepage: http://www.mythtv.org Standards-Version: 3.9.4 Vcs-Git: git://github.com/MythTV/packaging.git Build-Conflicts: libqt3-mt-dev Build-Depends: debhelper (>= 9), quilt, ccache, yasm, help2man, qtdeclarative5-dev, libqt5webkit5-dev, libqt5opengl5-dev, qtscript5-dev, qt5-qmake, po-debconf, linux-kernel-headers, libdvdnav-dev, libfreetype6-dev, libavc1394-dev, libiec61883-dev, liblircclient-dev, libxinerama-dev | xlibs-static-dev (<< 6.8.1-1), libxxf86vm-dev | xlibs-static-dev (<< 6.8.1-1), libcrystalhd-dev [i386 amd64], libxvmc-dev | xlibs-static-dev (<< 6.8.1-1), libxext-dev | xlibs-static-dev (<< 6.8.1-1), libimlib2-dev, libasound2-dev, libmp3lame-dev | liblame-dev, libvorbis-dev, libdts-dev, lsb-release, libpulse-dev, libxrandr-dev, libfftw3-dev, libva-dev, libvdpau-dev | nvidia-190-libvdpau-dev [i386 amd64] | nvidia-185-libvdpau-dev [i386 amd64] | nvidia-180-libvdpau-dev [i386 amd64], libudev-dev, libclass-dbi-perl, libnet-upnp-perl, libio-socket-inet6-perl, libdbd-mysql-perl, libjson-perl, libwww-perl, dh-python | python-central, python, python-oauth, python-lxml, python-mysqldb, python-pycurl, python-urlgrabber, libgl1-mesa-dev | xlibmesa-gl-dev | xlibmesa-dev | libgl-dev, libdvdread-dev | libdvdread3-dev, fftw-dev, libvorbis-dev, libflac-dev, libmad0-dev, libcdaudio-dev, libcdio-dev, libcdparanoia-dev | libcdparanoia0-dev, libsdl1.2-dev, libfaad-dev | libfaad2-dev, libexif-dev (>= 0.6.9-6), libtiff5-dev | libtiff4-dev | libtiff-dev, libxv-dev, libtag1-dev, libvisual-0.4-dev, libmysqlclient-dev, libdate-manip-perl, libxml-simple-perl, libimage-size-perl, libdatetime-format-iso8601-perl, libsoap-lite-perl, libx264-dev, libvpx-dev, libavahi-compat-libdnssd-dev, libssl-dev, libcdio-cdda-dev, libcdio-paranoia-dev, libxml2-dev, libass-dev, libcec-dev, libexiv2-dev, uuid-dev, libxml-xpath-perl, git, dh-systemd, php | php5, libraspberrypi-dev [armhf] | hello, Package: mythtv Architecture: all Depends: mysql-server | virtual-mysql-server | mysql-server-5.7 | mysql-server-5.6 | mariadb-server, mythtv-database, mythtv-frontend, mythtv-backend, ntp | time-daemon | ntp-simple, ${misc:Depends} Suggests: mythtv-doc Description: Personal video recorder application (client and server) MythTV implements the following PVR features, and more, with a unified graphical interface: . - Basic 'live-tv' functionality. Pause/Fast Forward/Rewind "live" TV. - Video compression using RTjpeg or MPEG-4 - Program listing retrieval using XMLTV - Themable, semi-transparent on-screen display - Electronic program guide - Scheduled recording of TV programs - Resolution of conflicts between scheduled recordings - Basic video editing . http://www.mythtv.org/ . This package will install a complete MythTV client/server environment on a single system. If you are intended on using this as your only MythTV machine, and this machine is already configured as a desktop, this package will get you up and running switfly. . If you are intended on installing this on a standalone/non-desktop machine, you should look into the Metapackages available: mythtv-backend-master (backend with a local database) mythtv-backend (backend needing a remote database) Package: mythtv-common Architecture: any Depends: pwgen, adduser, mysql-client | virtual-mysql-client | mysql-client-5.7 | mysql-client-5.6 | mariadb-client, fonts-liberation | ttf-liberation, fonts-droid-fallback | fonts-droid | ttf-droid, ttf-dejavu, fonts-tlwg-purisa, fonts-texgyre | tex-gyre, python, libxml-xpath-perl, pwgen, pciutils, usbutils, ${shlibs:Depends}, ${misc:Depends} Suggests: mythtv-doc Recommends: mythtv-dbg Conflicts: mythtv (<< 0.8-1), mythmusic (<< 0.20.99+trunk14393), mythweather (<< 0.20.99+trunk14393), mythcontrols, mythtv-themes, mythtv-theme-mythcenter, mythtv-theme-mythcenter-wide, mythtv-theme-gray-osd, mythtv-theme-isthmus, mythtv-theme-blootube, mythtv-theme-blootube-wide, mythtv-theme-blootubelite-wide, mythtv-theme-glass-wide, mythtv-theme-projectgrayhem, mythtv-theme-proejctgrayhem-wide, mythtv-theme-metallurgy, mythtv-theme-minimalist-wide, mythtv-theme-retro, mythtv-theme-titivillus, mythtv-theme-iulius, mythtv-theme-childish, mythtv-theme-neon-wide Replaces: mythtv (<< 0.8-1), mythtv-frontend (<< 0.23.0~trunk23548), mythmusic (<< 0.20.99+trunk14393), mythweather (<< 0.20.99+trunk14393), mythcontrols (<< 0.20.trunk19500), mythcontrols, mythtv-theme-mythcenter, mythtv-theme-mythcenter-wide, mythtv-theme-isthmus, mythtv-theme-gray-osd, mythtv-backend (<< 2:0.28.0~master.20150106.b8b9a1e-0ubuntu0mythbuntu4), mythtv-database (<< 0.24.0~trunk25638), mythvideo, mythtv-frontend (<< 2:0.28.0~master.20150106.b8b9a1e-0ubuntu0mythbuntu4) Breaks: mythtv-backend (<< 2:0.28.0~master.20150106.b8b9a1e-0ubuntu0mythbuntu4), mythvideo, mythtv-frontend (<< 2:0.28.0~master.20150106.b8b9a1e-0ubuntu0mythbuntu4) Description: Personal video recorder application (common data) MythTV provides a unified graphical interface for recording and viewing television programs. Refer to the mythtv package for more information. . This package contains infrastructure needed by both the client and the server. Package: mythtv-doc Architecture: all Conflicts: mythtv (<< 0.8-1) Section: doc Replaces: mythtv (<< 0.8-1) Depends: ${misc:Depends} Description: Personal video recorder application (documentation) MythTV provides a unified graphical interface for recording and viewing television programs. Refer to the mythtv package for more information. . This package contains documentation, including the MythTV HOWTO. Package: mythtv-database Architecture: all Depends: mythtv-common, libdbd-mysql-perl, mysql-client | virtual-mysql-client | mysql-client-5.7 | mysql-client-5.6 | mariadb-client, cron, ${misc:Depends} Recommends: update-notifier | update-notifier-kde Conflicts: mythtv (<< 0.8-1), mythtv-common (<< 0.8-2) Replaces: mythtv (<< 0.8-1), mythtv-common (<< 0.8-2) Description: Personal video recorder application (database) MythTV provides a unified graphical interface for recording and viewing television programs. Refer to the mythtv package for more information. . This package sets up a MySQL database for use by MythTV. It should be installed on the system where the MySQL server resides. Package: mythtv-backend Architecture: any Depends: mythtv-common, mythtv-transcode-utils, ${shlibs:Depends}, cron, wget, zenity | kdebase-bin, gksu | kdebase-bin, xterm, python, libjs-jquery, libxml-simple-perl, ${misc:Depends} Conflicts: mythtv (<< 0.8-1) Replaces: mythtv (<< 0.8-1), mythtv-frontend (<= 0.20-0.4) Recommends: ntp | time-daemon | ntp-simple, logrotate, libmyth-python, libmythtv-perl Suggests: mythtv-frontend, mythweb, mythtv-database, xmltv-util Description: Personal video recorder application (server) MythTV provides a unified graphical interface for recording and viewing television programs. Refer to the mythtv package for more information. . This package contains only the server software, which provides video and audio capture and encoding services. In order to be useful, it requires a mythtv-frontend installation, either on the same system or one reachable via the network. . A database is also required. The mythtv-database package must be installed, either on the same system, or one reachable via the network. . For a complete installation of all MythTV components, install the 'mythtv' package. Package: mythtv-transcode-utils Architecture: any Depends: mythtv-common, ${shlibs:Depends}, ${misc:Depends} Conflicts: mythtv-backend (<< 0.20.2-0ubuntu1) Replaces: mythtv-backend (<< 0.20.2-0ubuntu1) Suggests: mythtv-backend, mytharchive Description: Utilities used for transcoding MythTV tasks Some utilities are applicable for both a frontend or a backend machine. This package provides utilities that can be used on both without requiring an entire backend to be installed. Package: mythtv-frontend Architecture: any Depends: mythtv-common, ${shlibs:Depends}, ${misc:Depends}, libnotify-bin, adduser, zenity | kdebase-bin, gksu | kdebase-bin, wmctrl, libxml-simple-perl, libwww-perl, libmyth-python, transcode, python, python-imdbpy, Recommends: libmythtv-perl, python-imaging, udisks2 | udisks Suggests: mythtv-backend, mythmusic, mythweather, mythgallery, mythgame, ntp | time-daemon | ntp-simple Conflicts: mythtv (<< 0.8-1), mythappearance (<< 0.21.0), mythstream (<< 0.21.0), mythflix (<< 0.23.0) Replaces: mythtv (<< 0.8-1), mythappearance (<< 0.21.0), mythvideo Breaks: mythvideo Description: Personal video recorder application (client) MythTV provides a unified graphical interface for recording and viewing television programs. Refer to the mythtv package for more information. . This package contains only the client software, which provides a front-end for playback and configuration. It requires access to a mythtv-backend installation, either on the same system or one reachable via the network. . A database is also required. The mythtv-database package must be installed, either on the same system, or one reachable via the network. . For a complete installation of all MythTV components, install the 'mythtv' package. Package: libmyth-0.28-0 Architecture: any Section: libs Depends: ${shlibs:Depends}, libqt5sql5-mysql, ${misc:Depends} Conflicts: mythtv (<< 0.7-5), libmyth-0.23-0, libmyth-0.24-0, libmyth-0.25-0, libmyth-0.26-0, libmyth-0.27-0 Replaces: mythtv (<< 0.7-5), libmyth-0.23-0, libmyth-0.24-0, libmyth-0.25-0, libmyth-0.26-0, libmyth-0.27-0 Description: Common library code for MythTV and add-on modules (runtime) MythTV provides a unified graphical interface for recording and viewing television programs. Refer to the mythtv package for more information. . This package contains a shared library, libmyth, which is used by various components in the system. Package: libmyth-dev Architecture: any Section: libdevel Depends: libmyth-0.28-0 (= ${binary:Version}), ${misc:Depends} Provides: libmyth-0.28-0-dev Conflicts: libmyth-0.28-0-dev Description: Common library code for MythTV and add-on modules (development) MythTV provides a unified graphical interface for recording and viewing television programs. Refer to the mythtv package for more information. . This package contains files needed for developing applications which use libmyth (such as the various add-ons for MythTV) Package: php-mythtv Architecture: all Depends: ${misc:Depends} Description: PHP Bindings for MythTV MythTV provides a unified graphical interface for recording and viewing television programs. Refer to the mythtv package for more information. . This package contains files needed for using PHP based applications that connect to MythTV backends. Package: libmythtv-perl Architecture: all Section: perl Depends: ${misc:Depends}, ${perl:Depends}, libdbi-perl, libdbd-mysql-perl, libnet-upnp-perl, libio-socket-inet6-perl Replaces: mythtv-common (<< 0.20.98 ), libmyth-perl Conflicts: mythtv-common (<< 0.20.98 ), libmyth-perl Description: Perl library to access some MythTV features MythTV provides a unified graphical interface for recording and viewing television programs. Refer to the mythtv package for more information. . This package contains files needed for some PERL MythTV add-ons like nuvexport or mythrename.pl. Package: libmyth-python Architecture: all Section: libs Depends: ${python:Depends}, python, python-mysqldb, python-lxml, python-urlgrabber, ${misc:Depends} Replaces: mythtv-common (<< 0.20.98 ) Conflicts: mythtv-common (<< 0.20.98 ) Description: Python library to access some MythTV features MythTV provides a unified graphical interface for recording and viewing television programs. Refer to the mythtv package for more information. . This package contains files needed for some python MythTV add-ons. Package: mythtv-backend-master Architecture: all Section: metapackages Depends: mysql-server | virtual-mysql-server | mysql-server-5.7 | mysql-server-5.6 | mariadb-server, ntp | time-daemon | ntp-simple, mythtv-database, mythtv-backend, ${misc:Depends} Recommends: mythweb Description: Metapackage to setup and configure a "Master Backend" profile of MythTV This Meta-package will install and configure all necessary packages for this machine to behave as a "Master" Backend for a mythtv network. This package is intended to be installed on the machine that will behave as the first (and possibly only) backend for the network. Typically, this package will be installed on a server rather then a desktop. It makes no sense to install it on anything but the first backend machine on the network. Package: mythtv-dbg Architecture: any Section: debug Priority: extra Recommends: libc6-dbg Conflicts: mythplugins-dbg Replaces: mythplugins-dbg Depends: ${misc:Depends}, mythtv-backend (=${binary:Version}) | mythtv-frontend (=${binary:Version}) Description: Debug symbols for mythtv packages This package provides all debug symbols for mythtv packages since ddebs don't appear to always do the right thing. Package: mythplugins Architecture: all Section: metapackages Conflicts: mythflix, mythmovies Replaces: mythmovies Depends: ${misc:Depends}, mythgallery, mythgame, mythmusic, mythnews, mythweather, mythweb, mytharchive, mythbrowser, mythnetvision Description: Metapackage package for MythTV plugins This Metapackage will install all available MythTV plugins. Package: mythgallery Architecture: any Depends: mythtv-frontend (>= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: Image gallery/slideshow add-on module for MythTV MythGallery allows you to visually browse a directory tree containing image files. It can display any image file format supported by Qt, and supports image rotation and simple slideshows. Package: mythgame Architecture: any Depends: mythtv-frontend (>= ${binary:Version}), python, ${shlibs:Depends}, ${misc:Depends} Description: Emulator & PC Game frontend module for MythTV MythGame can be used as a frontend to start any emulator that your host OS runs. Package: mythmusic Architecture: any Depends: mythtv-frontend (>= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: Music add-on module for MythTV MythMusic provides a digital audio jukebox integrated with MythTV. It supports Ogg Vorbis, FLAC and MP3 streams, displays visualizations, and can also encode new Ogg Vorbis or FLAC streams from audio CDs using a CD-ROM drive. Package: mythnews Architecture: any Depends: mythtv-frontend (>= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: RSS feed news reader module for MythTV MythNews will fetch RSS feeds for you to read. Package: mythweather Architecture: any Depends: mythtv-frontend (>= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}, perl, libimage-size-perl, perlmagick, libxml-parser-perl, libxml-sax-perl, libcarp-clan-perl, libsoap-lite-perl, libdate-manip-perl, libdate-calc-perl, libwww-perl, libxml-simple-perl, libdatetime-format-iso8601-perl, libjson-perl, libxml-xpath-perl Conflicts: mythtv-common (<< 0.20.99) Replaces: mythtv-common (<< 0.20.99) Description: Weather add-on module for MythTV MythWeather displays current and forecast weather information within MythTV. Package: mythweb Architecture: all Depends: mythtv-common (>= ${binary:Version}), apache2 | httpd, libapache2-mod-php | libapache2-mod-php5 | php | php5, php-mysql | php5-mysql, php-mythtv, libhttp-date-perl, libjs-prototype, libjs-scriptaculous, ${misc:Depends} Recommends: libmath-round-perl Description: Web interface add-on module for MythTV MythWeb provides a web interface which can be used to view listings, schedule recordings, delete recordings, and search for programs. It can also browse mythmusic's music database, and may eventually support playing music streams as well. Package: mytharchive Architecture: any Depends: mythtv-transcode-utils(>= ${binary:Version}), mythtv-frontend (>= ${binary:Version}), mjpegtools, dvdauthor, genisoimage, dvd+rw-tools, python, python-imaging, python-mysqldb, pmount, ${shlibs:Depends}, ${misc:Depends} Recommends: m2vrequantiser Suggests: transcode, project-x Replaces: mytharchive-data Conflicts: mytharchive-data Description: create and burn DVD's from MythTV - binary file MythArchive is a plugin for MythTV that lets you create DVDs from your recorded shows, files and any video files available on your system. It can also archive recordings in a proprietary format that archives not only the file but also all the associated metadata like title, description and cut list information which will mean you can create backups of myth recordings which can later be restored or it will also allow you to move recordings between myth systems without losing any of the metadata. It is a complete rewrite of the old MythBurn bash scripts, now using Python, and the mythfrontend UI plugin. Package: mythzoneminder Architecture: any Suggests: zoneminder Depends: mythtv-frontend (>= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: view status and display footage recorded with zoneminder MythZoneMinder interfaces with Zoneminder, a CCTV solution. You can view the status of ZoneMinder and watch live camera shots and recorded surveillance footage. Package: mythbrowser Architecture: any Depends: mythtv-frontend (>= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: Web browser plugin for MythTV Mythbrowser is a standards compliant web browser plugin for MythTV built on top of Webkit. Package: mythnetvision Architecture: any Depends: mythtv-frontend (>= ${binary:Version}), mythbrowser (>= ${binary:Version}), python-feedparser, python-pycurl, ${shlibs:Depends}, ${misc:Depends} Recommends: flashplugin-installer | adobe-flashplugin, libxml-treebuilder-perl, Description: Internet Video Player plugin for MythTV MythNetvision is a plugin designed to make adding Internet video sources to MythTV fun and easy. MythNetvision consists of two components: - a search screen - a site/RSS browser screen. When installed, MythNetvision appears on the Media Library screen as the options "Search Internet Video" and "Browse Internet Video." Package: mythtv-theme-mythbuntu Architecture: all Depends: mythtv-common, ttf-dejavu, ${misc:Depends} Replaces: mythtv-common (<< 1:0.22.0~zrc1-0ubuntu1) Description: MythTV Theme used in the Mythbuntu distribution This theme is the default theme that MythTV is using when installed with the Mythbuntu OS distribution. It's also available to anyone not running the Mythbuntu OS distribution. debian/mythtv-database.dirs0000664000000000000000000000002612703351755013156 0ustar usr/share/mythtv/sql debian/mythtv-backend.configfiles0000664000000000000000000000007712703351755014336 0ustar /etc/logrotate.d/mythtv-backend /etc/cron.daily/mythtv-backend debian/mythtv-common.links0000664000000000000000000000246012703351755013065 0ustar usr/share/fonts/truetype/droid/DroidSans.ttf usr/share/mythtv/fonts/DroidSans.ttf usr/share/fonts/truetype/droid/DroidSerif-Bold.ttf usr/share/mythtv/fonts/DroidSerif-Bold.ttf usr/share/fonts/truetype/droid/DroidSerif-Regular.ttf usr/share/mythtv/fonts/DroidSerif-Regular.ttf usr/share/fonts/truetype/droid/DroidSans-Bold.ttf usr/share/mythtv/fonts/DroidSans-Bold.ttf usr/share/fonts/truetype/droid/DroidSansMono.ttf usr/share/mythtv/fonts/DroidSansMono.ttf usr/share/fonts/truetype/droid/DroidSerif-Italic.ttf usr/share/mythtv/fonts/DroidSerif-Italic.ttf usr/share/fonts/truetype/droid/DroidSerif-BoldItalic.ttf usr/share/mythtv/fonts/DroidSerif-BoldItalic.ttf usr/share/fonts/truetype/freefont/FreeSans.ttf usr/share/mythtv/fonts/FreeSans.ttf usr/share/fonts/truetype/freefont/FreeMono.ttf usr/share/mythtv/fonts/FreeMono.ttf usr/share/fonts/truetype/freefont/FreeSansBold.ttf usr/share/mythtv/fonts/FreeSansBold.ttf usr/share/fonts/truetype/tlwg/Purisa.ttf usr/share/mythtv/fonts/Purisa.ttf /usr/share/texmf/fonts/opentype/public/tex-gyre/texgyrechorus-mediumitalic.otf usr/share/mythtv/fonts/texgyrechorus-mediumitalic.otf usr/share/apport/package-hooks/source_mythtv.py usr/share/apport/package-hooks/source_mythplugins.py usr/share/apport/package-hooks/source_mythtv.py usr/share/apport/package-hooks/source_myththemes.py debian/mythweb.dirs0000664000000000000000000000017412703351755011544 0ustar var/cache/mythweb/image_cache var/www etc/mythtv usr/share/mythtv usr/share/mythtv/mythweb/data etc/apache2/sites-available debian/libmyth-python.manpages0000664000000000000000000000006512703351755013705 0ustar debian/man/mythpython.1 debian/man/mythwikiscripts.1 debian/mythmusic.postinst0000664000000000000000000000274612703351755013040 0ustar #! /bin/sh set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-deconfigure' `in-favour' # `removing' # MYTHSQL=/usr/share/mythtv/mythsql case "$1" in configure) if test -n "$2" && dpkg --compare-versions "$2" lt 0.8-1; then $MYTHSQL < /usr/share/mythtv/sql/mythmusic-0-7-to-0-8.sql fi if test -n "$2" && dpkg --compare-versions "$2" lt 0.9-1; then $MYTHSQL /usr/share/mythtv/sql/mythmusic-0-8-to-0-9.sql fi if [ -f /etc/mythtv/mythmusic-settings.txt ]; then mv /etc/mythtv/mythmusic-settings.txt \ /etc/mythtv/mythmusic-settings.dpkg-old fi for dir in /var/lib/mythtv/music; do if ! dpkg-statoverride --list $dir >/dev/null; then chown mythtv:mythtv $dir || true chmod 2775 $dir || true fi done ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 debian/mythmusic.dirs0000664000000000000000000000006512703351755012106 0ustar var/lib/mythtv/music etc/mythtv usr/share/mythtv/sql debian/40-mythtv.conf0000664000000000000000000000310712703351755011624 0ustar # Begin /etc/rsyslog.d/40-mythtv.conf # Make MythTV logs readable by world $FileCreateMode 0644 # Send all logging from MythTV applications to application-specific log files. if $msg startswith ' mythbackend' then /var/log/mythtv/mythbackend.log & ~ if $msg startswith ' mythfrontend' then /var/log/mythtv/mythfrontend.log & ~ if $msg startswith ' mythjobqueue' then /var/log/mythtv/mythjobqueue.log & ~ if $msg startswith ' mythmediaserver' then /var/log/mythtv/mythmediaserver.log & ~ if $msg startswith ' mythtv-setup' then /var/log/mythtv/mythtv-setup.log & ~ if $msg startswith ' mythfilldatabase' then /var/log/mythtv/mythfilldatabase.log & ~ if $msg startswith ' mythcommflag' then /var/log/mythtv/mythcommflag.log & ~ if $msg startswith ' mythpreviewgen' then /var/log/mythtv/mythpreviewgen.log & ~ if $msg startswith ' mythtranscode' then /var/log/mythtv/mythtranscode.log & ~ if $msg startswith ' mythmetadatalookup' then /var/log/mythtv/mythmetadatalookup.log & ~ if $msg startswith ' mythutil' then /var/log/mythtv/mythutil.log & ~ if $msg startswith ' mythwelcome' then /var/log/mythtv/mythwelcome.log & ~ if $msg startswith ' mythshutdown' then /var/log/mythtv/mythshutdown.log & ~ if $msg startswith ' mythlcdserver' then /var/log/mythtv/mythlcdserver.log & ~ if $msg startswith ' mythccextractor' then /var/log/mythtv/mythccextractor.log & ~ if $msg startswith ' mythavtest' then /var/log/mythtv/mythavtest.log & ~ # Set FileCreateMode back to default. This should be the same value as specified # in the /etc/rsyslog.conf file. $FileCreateMode 0640 # End /etc/rsyslog.d/40-mythtv.conf debian/mythtv-backend.dirs0000664000000000000000000000044012703351755013001 0ustar usr/share/doc/mythtv-backend var/cache/mythtv var/lib/mythtv/recordings var/lib/mythtv/videos var/lib/mythtv/fanart var/lib/mythtv/screenshots var/lib/mythtv/banners var/lib/mythtv/coverart var/lib/mythtv/db_backups var/lib/mythtv/livetv var/lib/mythtv/streaming var/lib/mythtv/trailers debian/mythfrontend.sh0000775000000000000000000000354712703351755012271 0ustar #!/bin/sh # Mario Limonciello, March 2007 # partially merged with startmythtv.sh by Michael Haas, October 2007 pidof mythfrontend.real 2>&1 >/dev/null && wmctrl -a "MythTV Frontend" 2>/dev/null && exit 0 #source our dialog functions . /usr/share/mythtv/dialog_functions.sh #find the session, dialog, and su manager we will be using for display find_session find_dialog find_su #check that we are in the mythtv group check_groups if [ "$1" = "--service" ]; then #source frontend session settings if [ -f /etc/mythtv/session-settings ]; then . /etc/mythtv/session-settings fi echo "Please note: additional command line arguments will not be passed" echo " to mythfrontend when using --service" echo "Please set them in /etc/mythtv/session-settings instead" #if group membership is okay, go ahead and launch if [ "$IGNORE_NOT" = "0" ]; then # start mythtv frontend software if [ "$MYTHWELCOME" = "true" ]; then # Note: if mythwelcome would support -O to override database settings, # we could tell it to start the frontend with $MYTHFRONTEND_OPTS # This is not possible yet, but maybe it'll happen in the future exec mythwelcome --syslog local7 else until /usr/bin/mythfrontend.real --syslog local7 ${MYTHFRONTEND_OPTS} RET=$? [ "$RET" = "0" -o "$RET" = "1" -o "$RET" = "254" ] do notify-send -i info 'Restarting Frontend' "The front-end crashed unexpectedly (exit code $RET) and is restarting. Please wait..." done fi fi # if we're not in --service mode, just behave normally elif [ "$1" != "--service" ]; then # if group membership is okay, go ahead and launch if [ "$IGNORE_NOT" = "0" ]; then exec /usr/bin/mythfrontend.real --syslog local7 "$@" fi fi debian/mythnetvision.docs0000664000000000000000000000010312703351755012764 0ustar mythplugins/mythnetvision/README mythplugins/mythnetvision/AUTHORS debian/mcc-mirobridge/0000775000000000000000000000000012703351755012063 5ustar debian/mcc-mirobridge/python/0000775000000000000000000000000012703351755013404 5ustar debian/mcc-mirobridge/python/mirobridgeconfig.py0000664000000000000000000020177212703351755017300 0ustar ## -*- coding: utf-8 -*- ## File name: mirobridgeconfig.py ## Mirobridge (Just.Another.Metadata.Utility) - Mythbuntu mcc plugin ## Purpose: This plugin allows a user install/uninstall and configure MiroBridge and its dependancies ## Author: R.D.Vaughan ## Original source was Mario Limonciello's "skeletory.py" mcc example # # «skeletor» - An Example Plugin for showing how to use MCC as a developer # # Copyright (C) 2009, Mario Limonciello, for Mythbuntu # # # Mythbuntu is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this application; if not, write to the Free Software Foundation, Inc., 51 # Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ################################################################################## __version__ = u"0.1.2" # 0.0.1 - Initial development # 0.1.0 - Public release # 0.1.1 - Added detection that the Live CD is being used and the plugin exists # 0.1.2 - Changed the gtk icon from MythbuntuControlCentre.plugin import MCCPlugin import gtk import sys, os, ConfigParser, subprocess, shutil, pwd, datetime import urllib2 import logging from socket import gethostname, gethostbyname import tarfile # Added for the crontab functions (os and sys) were already in the mirobridge.py script import re, tempfile class MirobridgeconfigPlugin_error(Exception): """An error which stops the MiroBridge MCC plugin from functioning """ pass class MirobridgeconfigPlugin(MCCPlugin): """A Mirobridge Configuration Plugin to install/uninstall and configure MiroBridge and its dependancies""" # #Load GUI & Calculate Changes # def __init__(self): #Initialize parent class information = {} information["name"] = "Mirobridgeconfig" information["icon"] = "gtk-media-play-ltr" information["ui"] = "tab_mirobridge" #Detect if booted from Live CD, exit is this is true. This plugin cannot be run from a Live CD boot. lines=[] try: file = open('/proc/cmdline') # Open for output (to read only) lines = file.readlines( ) # Read entire file into list of line strings file.close( ) # Flush output buffers to disk if lines[0].find('boot=casper') != -1: print "This is a Live CD boot, the MiroBridge MCC plugin cannot be run from the Live CD" sys.exit(0) except Exception, e: print 'An exception occured while trying to read the "/proc/cmdline" file to detect a Live CD boot.\nError (%s)' % e sys.exit(1) self.settings_initialized = True # Popular the screen variable on initial display # Create logger self.logger = logging.getLogger("mirobridgeconf") self.logger.setLevel(logging.DEBUG) hdlr = logging.FileHandler(u'/tmp/Mythbuntu_mirobridge_plugin.log') formatter = logging.Formatter(u"%(asctime)s - %(name)s - %(levelname)s - %(message)s") hdlr.setFormatter(formatter) self.logger.addHandler(hdlr) self.mbfunctions = MirobridgeConfigFunctions(self.logger) MCCPlugin.__init__(self, information) # end __init__() def captureState(self): """Determines the state of the items managed by this plugin and stores it into the plugin's own internal structures """ # Set the current condition of the MiroBridge installation and configuration self.mbfunctions.isInstalled() ### Used for debugging only. Usually commented out. # print '-----------------------' # print self.mbfunctions.config # print '-----------------------' self.changes = {} if self.settings_initialized: self.initialiseComboBoxLists() self.settings_initialized = False # Always reset active items according to the current installation conditions self.initialiseSettings() self.changes['enable_disable_combobox'] = self.enable_disable_combobox.get_active() self.changes['cronjob_freq_combobox'] = self.cronjob_freq_combobox.get_active() self.changes['behaviour_combobox'] = self.behaviour_combobox.get_active() # Force Step #2 so the user initiates Miro at least once incase the Miro package was re-installed if self.install_checkbutton.get_active() and self.mbfunctions.config['miro_test_passed']: self.mbfunctions.config['miro_test_passed'] = False # Always reset both check buttons to off for every screen rest. Stops both checked boxes being set. # for both (install/uninstall) self.changes['install'] = False self.changes['uninstall'] = False # Hide/Show UI objects depending on whether MiroBridge is installed or not if not self.mbfunctions.config['installed']: # Step #1: Something is missing and must be installed self.install_checkbutton.show() self.launch_miro_button.hide() self.import_opml_filechooserbutton.hide() self.uninstall_checkbutton.hide() self.enable_disable_combobox.hide() self.cronjob_freq_combobox.hide() self.behaviour_combobox.hide() elif not self.mbfunctions.config['miro_test_passed']: self.install_checkbutton.hide() self.launch_miro_button.show() # Step #2: Configure Miro Channels and options self.launch_miro_button.set_label(u'Step #2: Configure Miro Channels and options') self.import_opml_filechooserbutton.hide() self.uninstall_checkbutton.hide() self.enable_disable_combobox.hide() self.cronjob_freq_combobox.hide() self.behaviour_combobox.hide() else: # Regular maintenance/configuratio options self.install_checkbutton.hide() self.launch_miro_button.show() self.launch_miro_button.set_label(u'Launch Miro (Channel Add/Change/Delete)') self.import_opml_filechooserbutton.show() self.uninstall_checkbutton.show() self.enable_disable_combobox.show() self.cronjob_freq_combobox.show() self.behaviour_combobox.show() # end captureState() def applyStateToGUI(self): """Takes the current state information and sets the GUI for this plugin""" self.enable_disable_combobox.set_active(self.changes['enable_disable_combobox']) self.cronjob_freq_combobox.set_active(self.changes['cronjob_freq_combobox']) self.behaviour_combobox.set_active(self.changes['behaviour_combobox']) self.install_checkbutton.set_active(self.changes['install']) self.uninstall_checkbutton.set_active(self.changes['uninstall']) # end applyStateToGUI() def compareState(self): """Determines what items have been modified on this plugin""" MCCPlugin.clearParentState(self) if self.enable_disable_combobox.get_active() != self.changes['enable_disable_combobox']: if self.enable_disable_combobox.get_active() == 0: self._markReconfigureUser('enable_disable', True) else: self._markReconfigureUser('enable_disable', False) if self.cronjob_freq_combobox.get_active() != self.changes['cronjob_freq_combobox']: self._markReconfigureUser('cronjob_freq', self.cronjob_freq_combobox.get_active()) if self.behaviour_combobox.get_active() != self.changes['behaviour_combobox']: self._markReconfigureUser('behaviour', self.behaviour_combobox.get_active()) if self.install_checkbutton.get_active() != self.changes['install']: self._markReconfigureUser('install', self.install_checkbutton.get_active()) if self.install_checkbutton.get_active(): for package in self.mbfunctions.config['dependancies'].keys(): if not self.mbfunctions.config['dependancies'][package] and not package in self._to_install: self._markInstall(package, install=True) # Add a missing package to install else: for package in self.mbfunctions.config['dependancies'].keys(): if package in self._to_install: self._markInstall(package, install=False) # User cancelled install if self.uninstall_checkbutton.get_active() != self.changes['uninstall']: self._markReconfigureUser('uninstall', self.uninstall_checkbutton.get_active()) # Only the 'miro' package is uninstalled as the others are common and could be being used # by other installed apps package = 'miro' if self.uninstall_checkbutton.get_active(): if not package in self._to_remove: self._markRemove(package, remove=True) # A package to add to uninstall else: if package in self._to_remove: self._markRemove(package, remove=False) # A package to remove from uninstall list # end compareState() def initialiseSettings(self): """Initalize the tab values from the values in found during the MiroBridge installation/config check. This function will be ran by the frontend. """ # Set the active values if self.mbfunctions.config['cronjob']: self.enable_disable_combobox.set_active(0) else: self.enable_disable_combobox.set_active(1) self.cronjob_freq_combobox.set_active(0) if self.mbfunctions.config['cronjob_freq']: for index in range(len(self.mbfunctions.cronjob_freq)): if self.mbfunctions.cronjob_freq[index].lower() == self.mbfunctions.config['cronjob_freq']: self.cronjob_freq_combobox.set_active(index) break else: self.cronjob_freq_combobox.set_active(0) index = 0 if self.mbfunctions.config['cfg']: conflict_count = 0 # Check to see if there are conflicting "All" options in the config file for section in self.mbfunctions.config['cfg'].sections(): if section == u'watch_only': # All Channels will only not be moved to MythVideo for option in self.mbfunctions.config['cfg'].options(section): if option == u'all miro channels': index = 1 conflict_count+=1 break else: continue continue if section == u'mythvideo_only': # Add the Channel names to the array of Channels that will be moved to MythVideo only for option in self.mbfunctions.config['cfg'].options(section): if option == u'all miro channels': index = 2 conflict_count+=1 break else: continue continue if section == u'watch_then_copy': # Add the Channel names to the array of Channels once watched will be copied to MythVideo for option in self.mbfunctions.config['cfg'].options(section): if option == u'all miro channels': index = 3 conflict_count+=1 break else: continue continue if conflict_count > 1: errormsg = "Conflicting MiroBridge behavior options found. Only one 'all miro channels' can be set at a time.\nResetting to the default of no 'all miro channels'.\n" self.logger.error(errormsg) index = 0 self.behaviour_combobox.set_active(index) # end initialiseSettings() def initialiseComboBoxLists(self): '''Set the list values in the combo boxes ''' self.enable_disable_combobox.remove_text(0) # Remove the empty initial first element self.cronjob_freq_combobox.remove_text(0) # Remove the empty initial first element self.behaviour_combobox.remove_text(0) # Remove the empty initial first element # Populate the choice of Cronjob enable/disable list for value in self.mbfunctions.cronjob: self.enable_disable_combobox.append_text(value) # Populate the choice of Cronjob frequency for value in self.mbfunctions.cronjob_freq: self.cronjob_freq_combobox.append_text(value) # Populate the choice of MiroBridge processing behaviour for value in self.mbfunctions.behaviour: self.behaviour_combobox.append_text(value) # end initialiseComboBoxLists() # # Front end : Process selected activities # def user_scripted_changes(self,reconfigure): """Local changes that can be performed by the user account. This function will be run by the frontend """ # # Install MiroBridge configuration components # if reconfigure.has_key('install'): if reconfigure['install']: # Set defaults if self.mbfunctions.config['mirochannel'] == None: self.mbfunctions.addMiroBridgeChannel() self.mbfunctions.maintCronjobs('enable_disable', True) self.mbfunctions.maintCronjobs('cronjob_freq', 0) if not self.mbfunctions.config['cfg']: # If a conf file does not exist then use the example self.mbfunctions.readExampleConf(self.mbfunctions.location_mirobridge_example_conf_file) self.mbfunctions.maintConfigFile('behaviour', 0) self.mbfunctions.installDefaultImages() # # Uninstall MiroBridge configuration components # NOTE: Uninstall does not remove any existing Watch Recordings or MythVideo records or video files # elif reconfigure.has_key('uninstall'): if reconfigure['uninstall']: # Remove any the Mirobridge default images/Channel image/Folder image for key in self.mbfunctions.image_set.keys(): filepath = u'%s%s' % (self.mbfunctions.vid_graphics_dirs[key], self.mbfunctions.image_set[key]) if os.path.isfile(filepath): os.remove(filepath) # Remove any mirobridge cronjobs self.mbfunctions.maintCronjobs('enable_disable', False) # Remove any mirobridge.conf file filename = os.path.expanduser("~")+u'/.mythtv/mirobridge.conf' if os.path.isfile(filename): os.remove(filename) # Remove the MiroBridge Channel record if it exists channel = self.mbfunctions.MythDB(self.mbfunctions.mythdb).getChannel(9999) if channel['channum'] != None: if channel['channum'] == '999' and channel['name'] == 'Miro': self.mbfunctions.delChannel() # # Add/Change MiroBridge cronjob # Add/Change mirobridge.conf # else: for key in ['enable_disable', 'cronjob_freq']: # cronjob maintenance if reconfigure.has_key(key): self.mbfunctions.maintCronjobs(key, reconfigure[key]) if reconfigure.has_key('behaviour'): # mirobridge.conf maintenance self.mbfunctions.maintConfigFile('behaviour', reconfigure['behaviour']) # end user_scripted_changes() # # Callbacks # def callBacks(self, widget): """React to various button clicks or files selected """ if widget is not None: if widget.get_name() == "launch_miro_button": MCCPlugin.launch_app(self, widget, 'miro') self.captureState() elif widget.get_name() == "import_opml_filechooserbutton": filename = self.import_opml_filechooserbutton.get_filename() if filename: (dirName, fileName) = os.path.split(filename) (fileBaseName, fileExtension)=os.path.splitext(fileName) if not fileExtension.endswith(u'.opml'): self.logger.error(u'The OPML import file must have an extension of ".opml", the selected file has an extension of (%s)' % fileExtension) elif os.path.isfile(filename): MCCPlugin.launch_app(self, widget, u'%s -i "%s"' % (self.mbfunctions.location_mirobridge_script, filename)) else: self.logger.error(u'The import file(%s) does not exist' % filename) # end launch_app() # # Back end : Process selected activities # def root_scripted_changes(self,reconfigure): """System-wide changes that need root access to be applied. This function is run by the dbus backend """ # No root specific config changes required pass # end root_scripted_changes() ############################################################################################################ # MiroBridge MCC support functions ############################################################################################################ class MirobridgeConfigFunctions(): """A set of funtions that perform various tasks with the Mirobridge Configuration""" # # Evaluate the current installation of MiroBridge # def __init__(self, logger): self.logger = logger # Test and initialize the current configuration dictionary self.local_only = True # Default setting that determines to use local directories or storage groups self.accessMythDB() # Test that this is a BE # Test that there is internet access self.checkInternetAccess() # Option lists for UI selection self.cronjob = [u'Enabled', u'Disabled'] self.cronjob_freq = [u'Hourly', u'Daily', u'Weekly'] self.cronjob_keys = [u'hourly', u'daily', u'weekly'] self.behaviour = [ u'Default: Emulate Miro video processing', u'Watched Recordings screen only', u'Copy all Miro videos directly to MythVideo', u'Watch Miro videos then copy to MythVideo', ] self.behaviour_section = [ u'default', u'watch_only', u'mythvideo_only', u'watch_then_copy', ] self.cron_regx = [ # Hourly "?? * * * *" re.compile(u'''[0-9]|[0-9] \* \* \* \*''', re.UNICODE), # Daily "* ?? * * *" re.compile(u'''\* [0-9]|[0-9] \* \* \*''', re.UNICODE), # Weekly "* * * * ??" re.compile(u'''\* \* \* \* [0-9]|[0-9]''', re.UNICODE), ] # end __init__() def accessMythDB(self): '''Initialize MythTV python bindings return nothing ''' # Find out if the MythTV python bindings can be accessed and instances can be created try: '''If the MythTV python interface is found, we can insert data directly to MythDB or get the directories to store poster, fanart, banner and episode graphics. ''' from MythTV import MythDB, MythBE, Channel, MythError, MythLog, MythDBBase self.MythDB = MythDB self.MythBE = MythBE self.MythDBBase = MythDBBase self.Channel = Channel self.MythError = MythError self.MythLog = MythLog self.mythdb = None self.mythbeconn = None self.localhostname = gethostname() try: '''Create an instance of each: MythDB, MythVideo ''' self.MythLog._setlevel('none') # Some non option -M cannot have any logging on stdout self.mythdb = self.MythDB() self.MythLog._setlevel('important,general') except self.MythError, e: self.logger.critical(e.args[0]) filename = os.path.expanduser("~")+'/.mythtv/config.xml' if not os.path.isfile(filename): self.logger.critical('A correctly configured (%s) file must exist' % filename) else: self.logger.critical('Check that (%s) is correctly configured' % filename) raise MirobridgeconfigPlugin_error(e.args[0]) except Exception, e: errormsg = "Creating an instance caused an error for one of: MythDBConn or MythVideo, error(%s)\n" % e self.logger.critical(errormsg) raise MirobridgeconfigPlugin_error(errormsg) try: self.MythLog._setlevel('none') # Some non option -M cannot have any logging on stdout self.mythbeconn = MythBE(backend=self.localhostname, db=self.mythdb) self.MythLog._setlevel('important,general') except self.MythError, e: self.logger.critical("MiroBridge and its MCC plugin must be run on a MythTV backend,\nError(%s)" % e.args[0]) raise MirobridgeconfigPlugin_error(e.args[0]) except Exception, e: errormsg = "MythTV python bindings could not be imported, error(%s)\n" % e self.logger.critical(errormsg) raise MirobridgeconfigPlugin_error(errormsg) # end accessMythDB() def checkInternetAccess(self): '''Check that there is an Internet Access return nothing ''' try: urllib2.urlopen('http://www.google.com') except Exception, e: errormsg = "MiroBridge requiries an Internet connection, error(%s)\n" % e self.logger.critical(errormsg) raise MirobridgeconfigPlugin_error(errormsg) # end checkInternetAccess() def isInstalled(self): '''Check the system for MiroBridge script, all prerequisite packages, config file and default images. Establish what needs to be installed if anything. return nothing ''' # Get the location of the MB script and example conf file self.location_mirobridge_script = u'' self.location_mirobridge_example_conf_file = u'' results = self.callCommandLine(u'dpkg -L mythtv-backend | grep -iE "(mirobridge-example.conf.gz|mirobridge.py)"', stderr=False) if results: for line in results: line = line.strip().replace(u'\n', u'') if line.endswith('mirobridge.py'): self.location_mirobridge_script = line continue if line.endswith('mirobridge-example.conf.gz'): self.location_mirobridge_example_conf_file = line continue if not self.location_mirobridge_script or not self.location_mirobridge_example_conf_file: errormsg = u"The 'mythtv-backend' package is not installed. Install/Reinstall that package and then retry" self.logger.critical(errormsg) raise MirobridgeconfigPlugin_error(errormsg) # Check that mirobridge.py is installed if not os.path.isfile(self.location_mirobridge_script): errormsg = u"The file 'mirobridge.py' is not installed at (%s)\n" % (self.location_mirobridge_script, ) self.logger.critical(errormsg) raise MirobridgeconfigPlugin_error(errormsg) # Check that mirobridge-example.conf.gz is installed if not os.path.isfile(self.location_mirobridge_example_conf_file): errormsg = u"The file 'mirobridge-example.conf.gz' is not installed at (%s)\n" % (self.location_mirobridge_example_conf_file, ) self.logger.critical(errormsg) raise MirobridgeconfigPlugin_error(errormsg) self.config = { 'installed': False, 'dependancies': {'miro': False, 'ffmpeg': False, 'python-pyparsing': False, 'imagemagick': False}, 'mirochannel': None, # None is not created, False cannot be created, True already created 'cfg': None, # Current config file settings if there is a config file 'posterdir': False, 'bannerdir': False, 'fanartdir': False, 'cronjob': False, 'cronjob_freq': None, 'miro_test_passed': False, } # Check for MiroBridge package dependancies import apt cache = apt.cache.Cache() for package in self.config['dependancies'].keys(): try: if cache[package].installed != None: self.config['dependancies'][package] = True if package == 'miro': # version example: 2.5.4-0pcf1 version = cache[package].installed.version if version[:3] < '2.5': errormsg = "The installed Miro package must be at least version '2.5.x' or higher, yours is (%s).\nUninstall the Miro package then retry the MCC plugin MiroBridge install.\n" % (version, ) self.logger.critical(errormsg) raise MirobridgeconfigPlugin_error(errormsg) except KeyError, e: errormsg = "The MiroBridge dependancy package (%s) is not in your repository, error(%s)\n" % (package, e) self.logger.critical(errormsg) raise MirobridgeconfigPlugin_error(errormsg) # Check if channelid '9999' has been created and if it is assigned as the Miro channel channel = self.MythDB(self.mythdb).getChannel(9999) if channel['channum'] != None: if channel['channum'] != '999' or channel['name'] != 'Miro': self.logger.critical("MiroBridge found that there is already a Channel record for Channel num (%s) name (%s)\n" % (channel['channum'], channel['name'])) self.config['mirochannel'] = False # The channel is already being used! else: self.config['mirochannel'] = True # Check if the mirobridge.conf file exists in the users home directory filename = os.path.expanduser("~")+u'/.mythtv/mirobridge.conf' if os.path.isfile(filename): self.config['cfg'] = ConfigParser.SafeConfigParser() self.config['cfg'].read(filename) else: # Check that there is an example config, if there is then use it to create a mirobridge.conf file if not os.path.isfile(self.location_mirobridge_example_conf_file): errormsg = u"The MiroBridge example config file (%s) is missing and it is required\n" % (self.location_mirobridge_example_conf_file, ) self.logger.critical(errormsg) raise MirobridgeconfigPlugin_error(errormsg) # Get storage groups self.getStorageGroups() # Initialize the Video and graphics directory dictionary self.getMythtvDirectories() # Specify the MiroBridge default image set names self.image_set = { # posterdir the Miro logo used as the folder and channel image 'posterdir': u'mirobridge_coverart.jpg', 'bannerdir': u'mirobridge_banner.jpg', 'fanartdir': u'mirobridge_fanart.jpg', } # Check for the Mirobridge default images/Channel image/Folder image for key in self.image_set.keys(): if os.path.isfile(u'%s%s' % (self.vid_graphics_dirs[key], self.image_set[key])): self.config[key] = True continue # Check if there is a mirobridge cronjob and set the values if there is a cronjob self.getCronjobSettings() # Is MiroBridge fully installed? installed_total = len(self.config['dependancies'].keys())+len(self.image_set.keys())+3 install_count = 0 for package in self.config['dependancies'].keys(): if self.config['dependancies'][package]: install_count+=1 if self.config['cfg'] != None: install_count+=1 if self.config['mirochannel'] != None: install_count+=1 if self.config['cronjob_freq'] != None: install_count+=1 for key in self.image_set.keys(): if self.config[key]: install_count+=1 if installed_total == install_count: self.config['installed'] = True self.testEnv() # Verify that the Miro set up was completed with a MiroBridge environment test # end isInstalled() def getStorageGroups(self): '''Populate the storage group dictionary with the host's storage groups. return False if there is an error ''' self.storagegroupnames = {u'Default': u'default', u'Videos': u'mythvideo', u'Coverart': u'posterdir', u'Banners': u'bannerdir', u'Fanart': u'fanartdir', u'Screenshots': u'episodeimagedir'} self.storagegroups={} # The dictionary is only populated with the current hosts storage group entries records = self.mythdb.getStorageGroup(hostname=self.localhostname) if records: for record in records: if record.groupname in self.storagegroupnames.keys(): try: dirname = unicode(record.dirname, 'utf8') except (UnicodeDecodeError): self.logger.error(u"The local Storage group (%s) directory contained\ncharacters that caused a UnicodeDecodeError. This storage group has been rejected." % (record.groupname)) continue # Skip any line that has non-utf8 characters in it except (UnicodeEncodeError, TypeError): pass # Add a slash if missing to any storage group dirname if dirname[-1:] == u'/': self.storagegroups[self.storagegroupnames[record.groupname]] = dirname else: self.storagegroups[self.storagegroupnames[record.groupname]] = dirname+u'/' continue if len(self.storagegroups): # Verify that each storage group is an existing local directory storagegroup_ok = True for key in self.storagegroups.keys(): if not os.path.isdir(self.storagegroups[key]): self.logger.critical(u"The Storage group (%s) directory (%s) does not exist" % (key, storagegroups[key])) storagegroup_ok = False if not storagegroup_ok: errormsg = "There are MythTV storage group configuration errors correct and retry installation, errors are displayed in the log.\n" self.logger.critical(errormsg) raise MirobridgeconfigPlugin_error(errormsg) # end getStorageGroups def getMythtvDirectories(self): """Get all video and graphics directories found in the MythTV DB and add them to the dictionary. Ignore any MythTV Frontend setting when there is already a storage group configured. """ # Stop processing if this local host has any storage groups self.dir_dict={u'posterdir': u"VideoArtworkDir", u'bannerdir': u'mythvideo.bannerDir', u'fanartdir': 'mythvideo.fanartDir', u'episodeimagedir': u'mythvideo.screenshotDir', u'mythvideo': u'VideoStartupDir'} self.vid_graphics_dirs={u'default': u'', u'mythvideo': u'', u'posterdir': u'', u'bannerdir': u'', u'fanartdir': u'', u'episodeimagedir': u'',} # When there is NO SG for Videos then ALL graphics paths MUST be local paths set in the FE and accessable # from the backend if self.storagegroups.has_key(u'mythvideo'): self.local_only = False # Pick up storage groups first for key in self.storagegroups.keys(): self.vid_graphics_dirs[key] = self.storagegroups[key] for key in self.dir_dict.keys(): if key == u'default' or key == u'mythvideo': continue if not self.storagegroups.has_key(key): # Set fall back graphics directory to Videos self.vid_graphics_dirs[key] = self.storagegroups[u'mythvideo'] # Set fall back SG graphics directory to Videos self.storagegroups[key] = self.storagegroups[u'mythvideo'] else: self.local_only = True if self.storagegroups.has_key(u'default'): self.vid_graphics_dirs[u'default'] = self.storagegroups[u'default'] if self.local_only: self.logger.warning(u'There is no "Videos" Storage Group set so ONLY MythTV Frontend local paths for videos and graphics that are accessable from this MythTV Backend can be used.') for key in self.dir_dict.keys(): if self.vid_graphics_dirs[key]: continue graphics_dir = self.mythdb.settings[self.localhostname][self.dir_dict[key]] # Only use path from MythTV if one was found if key == u'mythvideo': if graphics_dir: tmp_directories = graphics_dir.split(u':') if len(tmp_directories): for i in range(len(tmp_directories)): tmp_directories[i] = tmp_directories[i].strip() if tmp_directories[i] != u'': if os.path.exists(tmp_directories[i]): if tmp_directories[i][-1] != u'/': tmp_directories[i]+=u'/' self.vid_graphics_dirs[key] = tmp_directories[i] break else: self.logger.error(u"MythVideo video directory (%s) does not exist(%s)" % (key, tmp_directories[i])) else: self.logger.error(u"MythVideo video directory (%s) is not set" % (key, )) if key != u'mythvideo': if graphics_dir and os.path.exists(graphics_dir): if graphics_dir[-1] != u'/': graphics_dir+=u'/' self.vid_graphics_dirs[key] = graphics_dir else: # There is the chance that MythTv DB does not have a dir self.logger.error(u"(%s) directory is not set or does not exist(%s)" % (key, self.dir_dict[key])) # Make sure there is a directory set for Videos and other graphics directories on this host dir_for_all = True for key in self.vid_graphics_dirs.keys(): if not self.vid_graphics_dirs[key]: self.logger.critical(u"There must be a directory for Videos and each graphics type the (%s) directory is missing." % (key)) dir_for_all = False if not dir_for_all: errormsg = "The MythTV video and/or image directories are not configured properly, correct and retry installation, errors are displayed in the log.\n" self.logger.critical(errormsg) raise MirobridgeconfigPlugin_error(errormsg) # Make sure that there is read/write access to all the directories Miro Bridge uses access_issue = False for key in self.vid_graphics_dirs.keys(): if not os.access(self.vid_graphics_dirs[key], os.F_OK | os.R_OK | os.W_OK): self.logger.critical(u"\nEvery Video and graphics directory must be read/writable for Miro Bridge to function. There is a permissions issue with (%s)." % (self.vid_graphics_dirs[key], )) access_issue = True if access_issue: errormsg = "The MythTV video and/or image directories do not have the proper read/write permission, correct and retry installation, errors are displayed in the log.\n" self.logger.critical(errormsg) raise MirobridgeconfigPlugin_error(errormsg) # end getMythtvDirectories() def readExampleConf(self, archivename): '''Extract the archive to /tmp and read the mirobridge-example.conf file as the new cfg return nothing ''' import gzip tmp_name = '/tmp/mirobridge-example.conf' try: zip_file = gzip.open(archivename, 'r') file_content = zip_file.read() zip_file.close except Exception, e: errormsg = "The mirobridge-example.conf archive file(%s), could not be opened, error(%s)\n" % (archivename, e) self.logger.critical(errormsg) raise MirobridgeconfigPlugin_error(errormsg) try: target_file = open(tmp_name, "w") target_file.write(file_content) target_file.close() except Exception, e: errormsg = "The mirobridge-example.conf could not be created in '/tmp', error(%s)\n" % (e, ) self.logger.critical(errormsg) raise MirobridgeconfigPlugin_error(errormsg) self.config['cfg'] = ConfigParser.SafeConfigParser() self.config['cfg'].read(tmp_name) os.remove(tmp_name) # readExampleConf() def callCommandLine(self, command, stderr=False): '''Perform the requested command line and return an array of stdout strings and stderr strings if stderr=True return array of stdout string array or stdout and stderr string arrays ''' stderrarray = [] stdoutarray = [] try: p = subprocess.Popen(command, shell=True, bufsize=4096, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True) except Exception, e: self.logger.error(u'callCommandLine Popen Exception, error(%s)' % e) if stderr: return [[], []] else: return [] if stderr: while True: data = p.stderr.readline() if not data: break try: data = unicode(data, 'utf8') except (UnicodeDecodeError): continue # Skip any line that has non-utf8 characters in it except (UnicodeEncodeError, TypeError): pass stderrarray.append(data) while True: data = p.stdout.readline() if not data: break try: data = unicode(data, 'utf8') except (UnicodeDecodeError): continue # Skip any line that has non-utf8 characters in it except (UnicodeEncodeError, TypeError): pass stdoutarray.append(data) if stderr: return [stdoutarray, stderrarray] else: return stdoutarray # end callCommandLine() def getCronjobSettings(self): '''Check the status of the MiroBridge cron job and initalize the values return nothing ''' self.tab = CronTab() # Check if there is an existing cronjob list = self.tab.find_command(self.location_mirobridge_script) self.config['cronjob'] = False if not len(list): return self.config['cronjob'] = True # Check whether the cronjob is a Hourly, Daily or Weekly mb_cronjob = (u'%s' % list[0]) for index in range(len(self.cron_regx)): if self.cron_regx[index].match(mb_cronjob): break else: index = 0 # Set to default of Daily as the cron job did not match hourly, daily or weekly options self.config['cronjob_freq'] = self.cronjob_keys[index] # end getCronjobSettings() def maintCronjobs(self, action, value): ''' Create the cron job if required Actions: (1) Enable/Disable the cronjob (2) Set the frequency of the cronjob (hourly, daily, weekly) return nothing ''' # MiroBrdige cronjob - debus additions added even though they may not be needed for all users miro_cronjob = u'''env `dbus-launch` sh -c 'trap "kill $DBUS_SESSION_BUS_PID" EXIT; %s ' >> '/var/log/mythtv/mirobridge.log' 2>&1''' list = self.tab.find_command(self.location_mirobridge_script) # Does the cronjob exist? if not len(list) and action == 'enable_disable' and not value: return # You cannot disable a cronjob that does not exist # Disable the conjob by removing it from the crontab if len(list) and action == 'enable_disable' and not value: self.tab.remove_all(self.location_mirobridge_script) # Write out changes self.tab.write() return # For all other actions a cronjob must exist so create one cron = None if not len(list): # Create the MiroBridge cronjob cron = self.tab.new(command=miro_cronjob % self.location_mirobridge_script, comment=u'MiroBridge cronjob') cron.valid = True # Enable the cronjob to be written to the crontab if self.config['cronjob_freq'] == None: cron.minute().on(45) # On the 45 minute mark on every hour if action == 'enable_disable': self.tab.write() return if action == 'cronjob_freq': if not cron: # Use either the newly created cron job or one that already exists. cron = list[0] cron.clear() # Reset any frequency settings for thus cronjob if value == 0: cron.minute().on(45) # Hourly - On the 45 minute mark of every hour elif value == 1: cron.hour().on(2) # Daily - At 2:00 AM every day else: cron.dow().on(0) # Weekly - Every Sunday night at midnight cron.valid = True # Enable the cronjob to be written to the crontab self.tab.write() # end maintCronjobs() def maintConfigFile(self, action, value): '''Actions: Set the behaviour of Mirobridge and how the Miro videos are processed. return nothing ''' if action == 'behaviour': tmp = {} if self.behaviour_section[value] == 'default': for key in self.behaviour_section: if key == 'default': continue tmp[key] = {u'all miro channels': u''} else: for key in self.behaviour_section: if key == 'default': continue if key == self.behaviour_section[value]: tmp[key] = {u'all miro channels': u' '} continue tmp[key] = {u'all miro channels': u''} self.writeMiroBridgeConf(tmp, self.config['cfg'], mythtv=False) # end maintConfigFile() def installDefaultImages(self): '''Download for image archives from the internet and install any missing default MiroBridge images return nothing ''' # Specify the MiroBridge default image download URLs self.image_links = { # posterdir the Miro logo used as the folder and channel image 'posterdir': u'http://img641.imageshack.us/img641/2396/mirocoverart.jpg', 'bannerdir': u'http://img402.imageshack.us/img402/7100/mirobridgebanner.jpg', 'fanartdir': u'http://img76.imageshack.us/img76/9897/mirobridgefanart.jpg', } # Download only the missing images for key in self.image_links: filename = u'%s%s' % (self.vid_graphics_dirs[key], self.image_set[key]) if not os.path.isfile(filename): url = self.image_links[key] org_url = url tmp_URL = url.replace("http://", "") url = "http://"+urllib2.quote(tmp_URL.encode("utf-8")) try: image = urllib2.urlopen(url).read() except IOError, e: errormsg = "The MiroBridge image image URL (%s) could not be opened, error(%s)\n" % (org_url, e, ) self.logger.error(errormsg) continue try: output_image = open(filename, "wb") output_image.write(image) output_image.close() except IOError, e: errormsg = "The MiroBridge image URL (%s) could not be downloaded, error(%s)\n" % (filename, e, ) self.logger.error(errormsg) continue os.chmod(filename, 0666) # end installDefaultImages() def readFile(self, filename): '''Read in the cron job and pass back an array of each line return array of strings return empty array of no file ''' try: myfile = open(filename) # Open for output (to read only) except IOError: return False aList = myfile.readlines( ) # Read entire file into list of line strings myfile.close( ) # Flush output buffers to disk array=[] # Initialize 2 dimensional array x=0 # Initialize array row value for rec in aList: array.append(rec) # Put record array into array of records return array # end readFile() def writeFile(self, filename, textarray): '''Write out the text array to the cron job return True if writing was successful return False if the writing failed ''' try: myfile = open(filename, 'w') # Open for output (creates file) except IOError: return False for rec in textarray: myfile.write(rec) # Write a new-line deliminated strings myfile.close() # Flush output buffers to disk return True # end writeFile() def writeMiroBridgeConf(self, configupdates, cfg, mythtv=True): '''Perform add/change/delete functions to the key/value pairs in the mirobridge.conf file return True if the task was completed successfully return False if there were issues ''' anything_updated = False for section in configupdates.keys(): if not len(configupdates[section]): # Skip any section that has not been changed continue anything_updated = True for key in configupdates[section].keys(): if not cfg.has_section(section): if configupdates[section][key] == u'': pass else: cfg.add_section(section) cfg.set(section, key, configupdates[section][key]) elif configupdates[section][key] == u'': if cfg.has_option(section, key): cfg.remove_option(section, key) else: cfg.set(section, key, configupdates[section][key]) filename = os.path.expanduser("~")+u'/.mythtv/mirobridge.conf' if not os.path.isfile(filename): # Create the file if it does not exist anything_updated = True if anything_updated: try: fd = open(filename, 'wb') cfg.write(fd) except IOError: return False # Change the owner and group from root to mythtv if mythtv: os.system('chown mythtv:mythtv %s & chmod g+rw %s' % (filename, filename)) return True # end writeMiroBridgeConf() def addMiroBridgeChannel(self): '''Add the Mirobridge Channel and icon if possible return nothing ''' # Check if channelid '9999' has been created and if it is assigned as the Miro channel channel = self.MythDB(self.mythdb).getChannel(9999) if channel['channum'] != None: if channel['channum'] != '999' or channel['name'] != 'Miro': self.logger.critical("MiroBridge cannot create a channel record as the channel is already used for Channel num (%s) name (%s)\n" % (channel['channum'], channel['name'])) return else: return # The channel has already been created for MiroBridge data={} data['chanid'] = 9999 data['channum'] = '999' data['freqid'] = '999' data['atsc_major_chan'] = 999 data['icon'] = u'%s%s' % (self.vid_graphics_dirs['posterdir'], self.image_set['posterdir']) data['callsign'] = u'Miro' data['name'] = u'Miro' data['last_record'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') # Create the MiroBridge Channel record try: self.Channel().create(data) except MythError, e: errmsg = u"Failed writing the Miro channel record. Most likely the Channel Id and number already exists.\nUse MythTV set up program (mythtv-setup) to alter or remove the offending channel.\nSpecified Channel ID (%d) and Channel Number (%d), error(%s)" % (channel_id, channel_num, e.args[0]) self.logger.critical(errmsg) raise MirobridgeconfigPlugin_error(errmsg) # end addMiroBridgeChannel() def delChannel(self): '''Just delete a Channel record. Never abort as sometimes a record may not exist. This routine is not supported in the native python bindings as MiroBridge uses the Channel table outside of its original intent. return nothing ''' db = self.MythDBBase(None) c = db.cursor() query = 'DELETE FROM channel WHERE chanid=9999 AND name="Miro"' try: c.execute(query) except Exception, e: self.logger.error(u"Channel record delete failed (%s)" % (e, )) pass c.close() def testEnv(self): '''Run the MiroBridge environment test to see if the installation and configuration is complete Use the return code to determine the results and set 'miro_test_passed' indicator accordingly. ''' try: retcode = subprocess.check_call([self.location_mirobridge_script, u"-t"]) except subprocess.CalledProcessError, e: self.logger.error(u'Testing the MiroBridge environment with the "-t" option failed, error(%s)' % e) return # MiroBridge is read to run self.config['miro_test_passed'] = True # end class delChannel()# end MirobridgeConfigFunctions() ########################################################################################### # This code has no package in the Ubuntu repository. It was easier to copy than install. # Found at: http://pypi.python.org/pypi/python-crontab/0.9.4 ########################################################################################### # # Copyright 2008, Martin Owens. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Rewritten from scratch, but based on the code from gnome-schedual by: # - Philip Van Hoof # - Gaute Hope # - Kristof Vansant # """ Example Use: from crontab import CronTab tab = CronTab() cron = tab.new(command='/usr/bin/echo') cron.minute().during(5,50).every(5) cron.hour().every(4) cron2 = tab.new(command='/foo/bar',comment='SomeID') cron2.every_reboot() list = tab.find_command('bar') cron3 = list[0] cron3.clear() cron3.minute().every(1) print unicode(tab.render()) for cron4 in tab.find_command('echo'): print cron4 for cron5 in tab: print cron5 tab.remove_all('echo') t.write() """ # These imports were moved to the top of the miroconfig.py file #import os, re, sys #import tempfile __version__ = '0.9.3' CRONCMD = "/usr/bin/crontab" ITEMREX = re.compile('^\s*([^@#\s]+)\s+([^@#\s]+)\s+([^@#\s]+)' + '\s+([^@#\s]+)\s+([^@#\s]+)\s+([^#\n]*)(\s+#\s*([^\n]*)|$)') SPECREX = re.compile('@(\w+)\s([^#\n]*)(\s+#\s*([^\n]*)|$)') DEVNULL = ">/dev/null 2>&1" MONTH_ENUM = [ 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec', ] WEEK_ENUM = [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun', ] SPECIALS = { "reboot" : '@reboot', "hourly" : '0 * * * *', "daily" : '0 0 * * *', "weekly" : '0 0 * * 0', "monthly" : '0 0 1 * *', "yearly" : '0 0 1 1 *', "annually": '0 0 1 1 *', "midnight": '0 0 * * *' } S_INFO = [ { 'name' : 'Minutes', 'max_v' : 59, 'min_v' : 0 }, { 'name' : 'Hours', 'max_v' : 23, 'min_v' : 0 }, { 'name' : 'Day of Month', 'max_v' : 31, 'min_v' : 1 }, { 'name' : 'Month', 'max_v' : 12, 'min_v' : 1, 'enum' : MONTH_ENUM }, { 'name' : 'Day of Week', 'max_v' : 7, 'min_v' : 0, 'enum' : WEEK_ENUM }, ] class CronTab(object): """ Crontab object which can access any time based cron using the standard. user = Set the user of the crontab (defaults to $USER) fake_tab = Don't set to crontab at all, set to testable fake tab variable. """ def __init__(self, user=None, fake_tab=None): self.user = user self.root = ( os.getuid() == 0 ) self.lines = None self.crons = None self.fake = fake_tab self.read() def read(self): """ Read in the crontab from the system into the object, called automatically when listing or using the object. use for refresh. """ self.crons = [] self.lines = [] if self.fake: lines = self.fake.split('\n') else: lines = os.popen(self._read_execute()).readlines() for line in lines: cron = CronItem(line) if cron.is_valid(): self.crons.append(cron) self.lines.append(cron) else: self.lines.append(line.replace('\n','')) def write(self): """Write the crontab to the system. Saves all information.""" # Add to either the crontab or the fake tab. if self.fake != None: self.fake = self.render() return filed, path = tempfile.mkstemp() fileh = os.fdopen(filed, 'w') fileh.write(self.render()) fileh.close() # Add the entire crontab back to the user crontab os.system(self._write_execute(path)) os.unlink(path) def render(self): """Render this crontab as it would be in the crontab.""" crons = [] for cron in self.lines: if type(cron) == CronItem and not cron.is_valid(): crons.append("# " + unicode(cron)) sys.stderr.write( "Ignoring invalid crontab line `%s`\n" % str(cron)) continue crons.append(unicode(cron)) result = '\n'.join(crons) if len(result): # This may be an empty crontab as if all cronjobs were deleted if result[-1] not in [ '\n', '\r' ]: result += '\n' return result def new(self, command='', comment=''): """ Create a new cron with a command and comment. Returns the new CronItem object. """ item = CronItem(command=command, meta=comment) self.crons.append(item) self.lines.append(item) return item def find_command(self, command): """Return a list of crons using a command.""" result = [] for cron in self.crons: if cron.command.match(command): result.append(cron) return result def remove_all(self, command): """Removes all crons using the stated command.""" l_value = self.find_command(command) for c_value in l_value: self.remove(c_value) def remove(self, item): """Remove a selected cron from the crontab.""" self.crons.remove(item) self.lines.remove(item) def _read_execute(self): """Returns the command line for reading a crontab""" return "%s -l%s" % (CRONCMD, self._user_execute()) def _write_execute(self, path): """Return the command line for writing a crontab""" return "%s %s%s" % (CRONCMD, path, self._user_execute()) def _user_execute(self): """User command switches to append to the read and write commands.""" if self.user: return ' -u %s' % str(self.user) return '' def __iter__(self): return self.crons.__iter__() def __unicode__(self): return self.render() class CronItem(object): """ An item which objectifies a single line of a crontab and May be considered to be a cron job object. """ def __init__(self, line=None, command='', meta=''): self.command = CronCommand(unicode(command)) self._meta = meta self.valid = False self.slices = [] self.special = False self.set_slices() if line: self.parse(line) def parse(self, line): """Parse a cron line string and save the info as the objects.""" result = ITEMREX.findall(line) if result: o_value = result[0] self.command = CronCommand(o_value[5]) self._meta = o_value[7] self.set_slices( o_value ) self.valid = True elif line.find('@') < line.find('#') or line.find('#')==-1: result = SPECREX.findall(line) if result and SPECIALS.has_key(result[0][0]): o_value = result[0] self.command = CronCommand(o_value[1]) self._meta = o_value[3] value = SPECIALS[o_value[0]] if value.find('@') != -1: self.special = value else: self.set_slices( value.split(' ') ) self.valid = True def set_slices(self, o_value=None): """Set the values of this slice set""" self.slices = [] for i_value in range(0, 5): if not o_value: o_value = [None, None, None, None, None] self.slices.append( CronSlice(value=o_value[i_value], **S_INFO[i_value])) def is_valid(self): """Return true if this slice set is valid""" return self.valid def render(self): """Render this set slice to a string""" time = '' if not self.special: slices = [] for i in range(0, 5): slices.append(unicode(self.slices[i])) time = ' '.join(slices) if self.special or time in SPECIALS.values(): if self.special: time = self.special else: time = "@%s" % SPECIALS.keys()[SPECIALS.values().index(time)] result = "%s %s" % (time, unicode(self.command)) if self.meta(): result += " # " + self.meta() return result def meta(self, value=None): """Return or set the meta value to replace the set values""" if value: self._meta = value return self._meta def every_reboot(self): """Set to every reboot instead of a time pattern""" self.special = '@reboot' def clear(self): """Clear the special and set values""" self.special = None for slice_v in self.slices: slice_v.clear() def minute(self): """Return the minute slice""" return self.slices[0] def hour(self): """Return the hour slice""" return self.slices[1] def dom(self): """Return the day-of-the month slice""" return self.slices[2] def month(self): """Return the month slice""" return self.slices[3] def dow(self): """Return the day of the week slice""" return self.slices[4] def __str__(self): return self.__unicode__() def __unicode__(self): return self.render() class CronSlice(object): """Cron slice object which shows a time pattern""" def __init__(self, name, min_v, max_v, enum=None, value=None): self.name = name self.min = min_v self.max = max_v self.enum = enum self.parts = [] self.value(value) def value(self, value=None): """Return the value of the entire slice.""" if value: self.parts = [] for part in value.split(','): if part.find("/") > 0 or part.find("-") > 0 or part == '*': self.parts.append( self.get_range( part ) ) else: if self.enum and part.lower() in self.enum: part = self.enum.index(part.lower()) try: self.parts.append( int(part) ) except: raise ValueError( 'Unknown cron time part for %s: %s' % ( self.name, part)) return self.render() def render(self): """Return the slice rendered as a crontab""" result = [] for part in self.parts: result.append(unicode(part)) if not result: return '*' return ','.join(result) def __str__(self): return self.__unicode__() def __unicode__(self): return self.render() def every(self, n_value): """Set the every X units value""" self.parts = [ self.get_range( '*/%d' % int(n_value) ) ] def on(self, *n_value): """Set the on the time value.""" self.parts += n_value def during(self, value_from, value_to): """Set the During value, which sets a range""" range_value = self.get_range( "%s-%s" % (str(value_from), str(value_to))) self.parts.append( range_value ) return range_value def clear(self): """clear the slice ready for new vaues""" self.parts = [] def get_range(self, range_value): """Return a cron range for this slice""" return CronRange( self, range_value ) class CronRange(object): """A range between one value and another for a time range.""" def __init__(self, slice_value, range_value=None): self.value_from = None self.value_to = None self.slice = slice_value self.seq = 1 if not range_value: range_value = '*' self.parse(range_value) def parse(self, value): """Parse a ranged value in a cronjob""" if value.find('/') > 0: value, self.seq = value.split('/') if value.find('-') > 0: from_val, to_val = value.split('-') self.value_from = self.clean_value(from_val) self.value_to = self.clean_value(to_val) elif value == '*': self.value_from = self.slice.min self.value_to = self.slice.max else: raise ValueError, 'Unknown cron range value %s' % value def render(self): """Render the ranged value for a cronjob""" value = '*' if self.value_from > self.slice.min or self.value_to < self.slice.max: value = "%d-%d" % (int(self.value_from), int(self.value_to)) if int(self.seq) != 1: value += "/%d" % (int(self.seq)) return value def clean_value(self, value): """Return a cleaned value of the ranged value""" if self.slice.enum and str(value).lower() in self.slice.enum: value = self.slice.enum.index(str(value).lower()) try: value = int(value) if value >= self.slice.min and value <= self.slice.max: return value except ValueError: raise ValueError('Invalid range value %s' % str(value)) def every(self, value): """Set the sequence value for this range.""" self.seq = int(value) def __str__(self): return self.__unicode__() def __unicode__(self): return self.render() class CronCommand(object): """Reprisent a cron command as an object.""" def __init__(self, line): self._command = line def match(self, command): """Match the command given""" if command in self._command: return True return False def command(self): """Return the command line""" return self._command def __str__(self): """Return a string as a value""" return self.__unicode__() def __unicode__(self): """Return unicode command line value""" return self.command() # end of crontab functions debian/mcc-mirobridge/ui/0000775000000000000000000000000012703351755012500 5ustar debian/mcc-mirobridge/ui/tab_mirobridge.ui0000664000000000000000000006114512703351755016017 0ustar True 6 vertical True 0 0 0 True vertical True 0 <big><b>MiroBridge Installation/Configuration</b></big> True 0 True False 1 True 0 Enjoy the best videos the Internet has to offer with MiroBridge providing an automated interface between Miro's videos and MythTV's Watch Recordings screen and MythVideo. 2 MiroBridge Wiki True True True True none 0 http://www.mythtv.org/wiki/MiroBridge 3 Miro True True True True none 0 http://www.getmiro.com/ 4 False 0 True False False 6 1 True vertical 10 True 0 0 0 25 Step #1: Install Miro and/or dependancies True True False Check this box then click the "Apply" button to install the dependencies and automatically configure MiroBridge. Until the install is complete the other options on this tab are hidden. This option will appear even after the initial install if individual components have been removed or delete. In effect you can repair a broken install. True 0 True False 6 1 True 0 0 0 True vertical True 0 0 0 True This selection stops or restarts MiroBridge processing. Suspend the MiroBridge cronjob by selecting "Disable". True 0 0 True MiroBridge cronjob: 0 True 10 True enable_disable_liststore 0 1 0 True 0 0 0 True Select one of three options for how frequent the MiroBridge processing is run: 1) Hourly starts: 45th minute of each hour (Default) 2) Daily starts: 2:00AM everyday 3) Weekly starts: Sunday Midnight each week True True MiroBridge conjob frequency: 0 True 10 True cronjob_freq_liststore 0 1 1 2 True 0 0 0 True vertical True False 6 0 True 0 0 0 True <b>Behaviour Options</b> True 1 True True Default: Emulate Miro video processing: All newly downloaded videos are added to the Watch Recordings screen, after they have been watched they are moved to MythVideo and eventually are removed by Miro according to Miro's own expiry settings (X number of days). Watched Recordings screen only: Force all Miro videos to never be added to MythVideo. This is a watch-and-forget option. The Videos will be removed by Miro according to Miro's own expiry settings (X number of days) Copy all Miro videos directly to MythVideo: Force all Miro Channel videos to be copied directly to MythVideo and never displayed in the MythTV's "Watch Recordings" screen. These copied videos are removed from Miro entirely. Miro never expires/removes a copied video which act like any other MythVideo video file. Watch Miro videos then copy to MythVideo: Force all Miro videos to be copied directly to MythVideo AFTER they have been watched in the MythTV "Watch Recordings" screen. This option is a good balance between having new videos highlighted through the MythTV's "Watch Recordings" screen and automatically saving the video in MythVideo once it has been watched. This option is most frequently used for Movie trailers. Miro never expires/removes a copied video which act like any other MythVideo video file. behaviour_liststore 0 2 True False 6 3 3 True 0 0 0 True vertical True 0 <b>Configure Miro Video Channels</b> True 0 True 0.60000002384185791 Launch Miro (Channel Add/Change/Delete) True True True Launch the Miro GUI application so that you can: 1) Set the location where Miro will download videos 2) Add or change Miro video channels 3) Modify the channel names 4) Set the auto expiry days 5) Ensure that auto download is enabled 1 True 0 <b>Import an OPML file (*.opml)</b> True 2 True 0 0.60000002384185791 True *** The file browser window stays displayed while the OPML file is being imported *** Import an OPML file that has been exported from a separate Miro configuration. The import file must have an extension of ".opml". This is an excellent way of copying your Miro Channel configuration from a previous Miro install or for using a separate PC with a keyboard to choose and rename your Miro Channels. False 3 True False 12 4 True 0 0 0 25 Uninstall MiroBridge True True False Uninstall the Miro package and remove MiroBridge related files including images, configuration file and the cronjob. Uninstall does not remove any existing Watch Recordings or MythVideo records or video files. Those must be removed by the through either the Watch Recordings screen delete 'd' and/or MythVideo delete 'd' options. True 5 4 False 6 2 debian/DESCRIBE0000664000000000000000000000006612705246045010302 0ustar BRANCH="fixes/0.28" SOURCE_VERSION="v0.28-2-g15cf421" debian/mythtv-frontend.logrotate0000664000000000000000000000215312703351755014273 0ustar /var/log/mythtv/mythavtest.log { daily size=10M rotate 7 notifempty copytruncate missingok postrotate reload rsyslog >/dev/null 2>&1 || true endscript } /var/log/mythtv/mythfrontend.log { daily size=10M rotate 7 notifempty copytruncate missingok postrotate reload rsyslog >/dev/null 2>&1 || true endscript } /var/log/mythtv/mythlcdserver.log { daily size=10M rotate 7 notifempty copytruncate missingok postrotate reload rsyslog >/dev/null 2>&1 || true endscript } /var/log/mythtv/mythmediaserver.log { daily size=10M rotate 7 notifempty copytruncate missingok postrotate reload rsyslog >/dev/null 2>&1 || true endscript } /var/log/mythtv/mythwelcome.log { daily size=10M rotate 7 notifempty copytruncate missingok postrotate reload rsyslog >/dev/null 2>&1 || true endscript } debian/mythtv-frontend.install0000664000000000000000000000053712703351755013745 0ustar #Come from make install usr/bin/mythfrontend.real usr/bin/mythlcdserver usr/bin/mythreplex usr/bin/mythavtest usr/bin/mythwelcome usr/bin/mythmediaserver usr/bin/mythscreenwizard usr/lib/mythtv/filters #Stuff we add from debian/ debian/mythtv.desktop usr/share/applications debian/mythfrontend.sh usr/share/mythtv debian/session-settings etc/mythtv debian/mythtv-frontend.postinst0000664000000000000000000000101312703351755014150 0ustar #!/bin/sh -e case "$1" in configure) . /usr/share/debconf/confmodule for dir in /var/lib/mythdvd /var/lib/mythdvd/temp; do if ! dpkg-statoverride --list $dir >/dev/null; then chown mythtv:mythtv $dir || true chmod 2775 $dir || true fi done ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac #DEBHELPER# exit 0 debian/mytharchive.postinst0000664000000000000000000000177212703351755013337 0ustar #!/bin/sh set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-deconfigure' `in-favour' # `removing' # case "$1" in configure) for dir in /var/lib/mytharchive/temp; do if ! dpkg-statoverride --list $dir >/dev/null; then chown mythtv:mythtv $dir || true chmod 2775 $dir || true fi done ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 debian/mythtv-backend.init0000664000000000000000000000403212703351755013004 0ustar #! /bin/sh ### BEGIN INIT INFO # Provides: mythtv-backend # Required-Start: $local_fs $remote_fs # Required-Stop: $local_fs $remote_fs # Should-Start: mysql # Should-Stop: mysql # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # X-Interactive: true # Short-Description: Start/Stop the MythTV server. ### END INIT INFO if [ -f /etc/default/locale ]; then . /etc/default/locale export LANG fi PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DAEMON=/usr/bin/mythbackend NAME="mythbackend" DESC="MythTV server" test -x $DAEMON || exit 0 . /lib/lsb/init-functions set -e USER=mythtv RUNDIR=/var/run/mythtv ARGS="--daemon --syslog local7 --pidfile $RUNDIR/$NAME.pid" EXTRA_ARGS="" NICE=0 if [ -f /etc/default/mythtv-backend ]; then . /etc/default/mythtv-backend fi ARGS="$ARGS $EXTRA_ARGS" mkdir -p $RUNDIR chown -R $USER $RUNDIR unset DISPLAY unset SESSION_MANAGER case "$1" in start) if test -e $RUNDIR/$NAME.pid ; then echo "mythbackend already running, use restart instead." else echo -n "Starting $DESC: $NAME " start-stop-daemon --start --pidfile $RUNDIR/$NAME.pid \ --chuid $USER --nicelevel $NICE --exec $DAEMON -- $ARGS echo "." fi ;; stop) echo -n "Stopping $DESC: $NAME " start-stop-daemon --stop --retry=TERM/30/KILL/5 --oknodo --pidfile $RUNDIR/$NAME.pid \ --chuid $USER --exec $DAEMON -- $ARGS test -e $RUNDIR/$NAME.pid && rm $RUNDIR/$NAME.pid echo "." ;; restart|force-reload) echo -n "Restarting $DESC: $NAME " start-stop-daemon --stop --retry=TERM/30/KILL/5 --oknodo --pidfile $RUNDIR/$NAME.pid \ --chuid $USER --exec $DAEMON -- $ARGS echo "." start-stop-daemon --start --pidfile $RUNDIR/$NAME.pid \ --chuid $USER --nicelevel $NICE --exec $DAEMON -- $ARGS echo "." ;; reload) start-stop-daemon --stop --oknodo --signal HUP --pidfile \ $RUNDIR/$NAME.pid --chuid $USER --exec $DAEMON -- $ARGS echo "." ;; *) N=/etc/init.d/$NAME echo "Usage: $N {start|stop|restart|force-reload}" >&2 exit 1 ;; esac exit 0 debian/mythweb.docs0000664000000000000000000000003312703351755011525 0ustar mythplugins/mythweb/README debian/mythtv-database.install0000664000000000000000000000021312703351755013661 0ustar #are added in (not part of make install) mythtv/database/*.sql usr/share/mythtv/sql #Come from debian/ debian/mythtv.cnf etc/mysql/conf.d debian/do-new-release.sh0000775000000000000000000000027512703351755012352 0ustar quilt pop -a 2>/dev/null || true debian/rules get-git-source debian/rules update-control-files if [ -n "$1" ]; then DIST="$1" else DIST="natty" fi dch -r -D $DIST --force-distribution "" debian/mythzoneminder.docs0000664000000000000000000000010512703351755013122 0ustar mythplugins/mythzoneminder/README mythplugins/mythzoneminder/AUTHORS debian/mytharchive.dirs0000664000000000000000000000005212703351755012403 0ustar var/lib/mytharchive/temp usr/share/mythtv debian/mythweb.preinst0000664000000000000000000000055012703351755012265 0ustar #!/bin/sh set -e if [ "$1" = install ] || [ "$1" = upgrade ]; then #migrate to php7 if need be if [ -f /etc/php5/apache2/conf.d/20-mythweb.conf ] && \ [ -d /etc/php/7.0/apache2/conf.d ]; then mv_conffile /etc/php5/apache2/conf.d/20-mythweb.ini /etc/php/7.0/apache2/conf.d/20-mythweb.ini 2:0.28.0+fixes.20160325.2520617-0ubuntu3~ fi fi #DEBHELPER# debian/mythtv-database.templates0000664000000000000000000000211012703351755014207 0ustar Template: mythtv/mysql_admin_user Type: string Default: root _Description: MySQL administrator account: This information will be used to create a database and user for MythTV. . Unless you have explicitly changed this on the MySQL server, and understand MySQL's privilege system, use the default of 'root'. Template: mythtv/mysql_admin_password Type: password _Description: Password for the MySQL administrator account '${user}': This information will be used to create a database and user for MythTV. . Unless you have explicitly changed the password on the MySQL server, leave this blank. Template: mythtv/public_bind Type: boolean Default: false _Description: Will other computers run MythTV? If any other computers (that includes other Front End machines) with MythTV will be used, this computer needs to be configured to allow remote connections. . Note that this is a security risk, as both the MythTV and MySQL services will be exposed. Be sure to place this machine behind a firewall. . If multiple interfaces are used, the first one listed in 'ifconfig' will be used. debian/changelog.in0000664000000000000000000065714212703351755011476 0ustar mythtv (2:0.28.0+fixes.20160325.2520617-0ubuntu3) xenial; urgency=medium [ Nishanth Aravamudan ] * Update to PHP7.0 dependencies (LP: #1562184). * debian/patches/update_mythweb_for_php7.patch: Update documentation and nginx configuration for php7.0. * Use dpkg-maintscript-helper to move the apache conf files. [ Steve Langasek ] * Use debian/mythweb.maintscript and dh_installdeb for the dpkg-maintscript-helper bits, to avoid code duplication everywhere. -- Steve Langasek Wed, 30 Mar 2016 18:03:18 +0000 mythtv (2:0.28.0+fixes.20160325.2520617-0ubuntu2) xenial; urgency=medium * cover one more pro file for mysql5.7 fix -- Mario Limonciello Sat, 26 Mar 2016 19:42:13 -0500 mythtv (2:0.28.0+fixes.20160325.2520617-0ubuntu1) xenial; urgency=medium * Scripted Build from fixes git packaging [8e429df] * Packaging changes between 20160321 and 20160325: * [7547247] let mysql-server 5.7 resolve things * [35b1bba] Add in support to compile against mysql 5.7 (LP: #1528583) * New upstream checkout (2520617) -- Mario Limonciello Fri, 25 Mar 2016 15:34:02 -0500 mythtv (2:0.28.0+fixes.20160321.39e409d-0ubuntu2) xenial; urgency=medium * Fix apache2 dependency to prevent aolserver4 coming into ISO. -- Mario Limonciello Thu, 24 Mar 2016 09:00:36 -0500 mythtv (2:0.28.0+fixes.20160321.39e409d-0ubuntu1) xenial; urgency=medium * Scripted Build from fixes git packaging [dc25446] * Packaging changes between 20160217 and 20160321: * [dc25446] sync changelog with ubuntu xenial * [2f24fa2] ignore .github directory that is throwing off builds * [ec3572f] fix building with systemd * [8c94617] depends on fonts-droid-fallback * New upstream checkout (39e409d) -- Mario Limonciello Mon, 21 Mar 2016 10:17:49 -0500 mythtv (2:0.28.0+fixes.20160217.44fd8a6-0ubuntu4) xenial; urgency=medium * Export QT version to fix builds on non x86/arm archs. -- Mario Limonciello Mon, 22 Feb 2016 16:28:08 -0600 mythtv (2:0.28.0+fixes.20160217.44fd8a6-0ubuntu3) xenial; urgency=medium * mythtv-common: Depend on fonts-droid-fallback. -- Matthias Klose Mon, 22 Feb 2016 16:37:49 +0100 mythtv (2:0.28.0+fixes.20160217.44fd8a6-0ubuntu1) xenial; urgency=medium * New upstream version (0.28) * Scripted Build from fixes git packaging [257769a] -- Mario Limonciello Wed, 17 Feb 2016 11:46:40 -0600 mythtv (2:0.27.0~master.20130828.b2b7022-0ubuntu1) saucy; urgency=low * New upstream checkout (b2b7022) * Scripted Build from master git packaging [18ab870] * Packaging changes between 20120505 and 20130828: * [18ab870] build packaging changes into debian/changelog upon release * [39d4449] switch to 0.27 builds for master * [efe0e0c] fix instances of test-virtualbox in SQL file (LP: #1215440) * [223a44c] rename 0.26 to 0.27 sql * [b02a69d] remove debian/control - it's generated every time on build * [ac72833] actually make mythtv-dbg recommends rather than suggests so it will be installed by default * [06e718d] add missing dependency on libhttp-date-perl * [7e395a1] daemonize mythbackend to avoid logging to upstart console. expect an extra fork in the upstart job * [7bd8396] don't log to upstart log that mysql is alive, only errors * [5ae84f0] add a message on why we are using sudo for installing build-deps * [08101bc] set SIGKILL timeout on upstart job to 30 seconds * [72cf6a0] remove versioned dependency on libiec61883-dev * [364850c] use mk-build-deps to resolve binary build dependencies * [7bfd285] don't allow the scripts to run without a debian/ directory * [6a8e25f] ignore warnings when loading time zones into mysql * [1809a5d] toggle public_bind setting in debconf database based on what's in flat files (LP: #1159992) * [7568a9c] depends on libdate-calc-perl for mythweather * [9a84893] recommends on m2vrequantiser for mytharchive (LP: #1131506) * [9a351c7] add FreeSansBold.ttf to the symlinks (LP: #1131280) * [d585530] set the kill timeout on the upstart job to 10 seconds to be safer on shutdown. * [aa67a49] let upstart handle the backend process correctly * [41a8fb2] add the new mythscreenwizard binary to the frontend packaging * [c5afd80] add conflict to older library versions * [623b954] rename 0.25 stuff to 0.26 * [00027cc] drop support for mysql.txt, using only config.xml going forward * [b2acc53] mythtv-common depends on libxml-xpath-perl for config.xml parsing * [a7d0a63] load timezones into mysql during mythtv-database postinst (LP: #1010491) * [5bb2c43] enable sdl so that mythffplay will work (see fb90f73) * [a634b5b] install README's for fonts in mythtv-doc * [9587925] switch libtiff5-dev and libtiff4-dev order to fix FTBFS on quantal * [37abce8] let libtiff5-dev resolve build dependencies too. * [c4b25d5] Remove extra dpkg-parsechangelog call that was mistakenly added. * [b071647] missed mythfrontend, add that in logging too. * [3dfd8f9] update rsyslog for 0.26. * [5240276] Install MythTV specific sysctl.conf file * [d861262] install libmythzmq pkgconfig pc file to libmyth-dev package * [928bfb4] install pkgconfig and static library for libmythzmq into the -dev package. the libtool library still needs an override (it probably shouldn't be installed anywhere) * [b8545e8] zmq/nzmq/QJson include paths were moved to usr/include/mythtv. remove override * [c1e4604] explicitly ignore libmythzmq.la as wildcards don't appear to work properly with dh_install * [28553da] fix wildcard matching for ignoring zmq files * [d29ecda] add zeromq_install_paths.patch to fix FTBFS. * [b42d0e4] drop recommends on adept-notifier * [9d06c29] update source_mythtv apport hook to python3 compatible * [e81f08d] install copy of zeromq libaries * [144e1d2] ignore libmythqjson.prl * [89f5e74] Don't install QJson libararies or headers. * [6fd1730] install mythlogserver * [f1298b5] Install otf fonts too * [c63df57] add support for droid fonts * [ae0095e] Add purisa font support * [d055b85] mythtv-common dependencies-> move to 1 for each line (more readable) * [9020a36] Pass INSTALL_ROOT during the build process of mythtv as well so that it gets applied to the zeromq ./configure run as well [ Mario Limonciello ] * Switch to 0.27 branch for master builds. * Cleanup lintian errors: - debian/control.in: description-synopsis-starts-with-article - debian/mythweb.config: maintainer-script-ignores-errors * Add build dependency for uuid-dev. * Add a workaround for FTBFS w/ linking when using binutils 2.21 - See http://goo.gl/KDK9o for more information. * Drop recommends on adept-notifier. * fix get-orig-source rule's broken tarball fetch from archive. * Enable libcec support (LP: #982272) * Add missingok to additional mythtv-backend logs. (LP: #982162) * Pull an updated snapshot of Mythbuntu theme, to avoid theme downloader telling the user there is an updated theme on first boot. * Test for an empty key on public mysql. (LP: #989371) [ Andres Mejia ] * Bump to Standards-Version 3.9.3. * Build 'release' type builds instead of 'profile'. * Support parallel builds. [ Thomas Mashos ] * Fix wanting to install mythweb to html dir on older releases (LP: #1309813) * Enable CGI module on apache2 for mythweb (LP: #1316409) -- Mario Limonciello Wed, 28 Aug 2013 22:06:14 -0500 mythtv (2:0.25.0+fixes.20120410.1f5962a-0ubuntu1) precise; urgency=low * Add a fallback to master for non-existant fixes branches. * Update to 0.25 gold release. * New upstream checkout (1f5962a) * >>Upstream changes since last upload (041ecad): * [1f5962a] RingBuffer: Make a few more attempts to read when oldfile=true. * [cffed2b] Merge branch 'master' of github.com:MythTV/mythtv * [4f16846] Update the Danish translation of mythfrontend and all plugins. * [31fa9dd] Revert "Fix popup windows from disappearing in MythCenter- wide when using the" * [d824ea2] Fix issues with 805453a6 and df8548e7. * [4b28a57] Remove the MythArchive date/time formats from the Hong Kong Chinese locale file. * [df8548e] Add a null pointer check on 'screen' * [805453a] Don't trigger hide/show animations if the screens should still be visible because the foreground screen isn't fullscreen. * [d1b081e] Updated Czech MythFrontend translation * [e6c4aa0] Updated Polish MythFrontend and alll plugins translation from Warpme * [39695b2] Revert "Fixes #10490. Don't return from safe_read() early on stopreads if we haven't read any bytes, this looks like an eof to higher levels of code." * [28db6ca] Merge branch 'master' of github.com:MythTV/mythtv * [e6d3ecb] Updated French MythFrontend, MythMusic, MythNetvision and MythNews translation from the French Language Translation Team * [6473241] Update the Danish translation of mythfrontend. * [c52a7cf] Updated Czech MythFrontend and MythMusic translation * [8c6c8cd] Updated German MythFrontend and MythZoneMinder translation from Florian Bittner * [aa2762f] Fix popup windows from disappearing in MythCenter-wide when using the virtual keyboard. * [393295c] Fixes #10490. Don't return from safe_read() early on stopreads if we haven't read any bytes, this looks like an eof to higher levels of code. * [81e72c8] Clear the UI object stores when deleting MythThemeBase, fixes themes using the wrong base window and fonts after displaying the locale/database prompts. This was already done implicitly when shutting down and explicitly when reloading themes but not in the third case, where we construct a temporary main window and MythMainWindow is torn down instead of being re-initialised. * [a970d72] Fixes #10545. Populate the Switch Input menu with all available cards. * [d80e54b] Fix #10558 * [14ca636] Bump binary version * [00bd9eb] Fix compilation following previous commit * [e84a9a8] Fix compilation following previous commit * [4c5b039] Initialise locale if it's not been done already by the time we call GetQLocale() * [9c73366] Translate dates/times in the DateFormat settings * [a0ae652] Move Setup Wizard at the top of settings menu (part #2) * [02216ca] Fix video setup wizard if audio test wasn't stopped in the previous screen * [13652d7] Fix audio setup and add handling of extra cases. * [b36827e] Better handling of unmounted volumes. Refs #10450. * [83671d5] Revert "Better handling of unmounted volumes. Refs #10450" * [58e8506] Better handling of unmounted volumes. Refs #10450 * [71a024d] Fix LoadFromOldRecorded query in ProgList. * [957917c] Replicate the spelling change I had done in 3740d7dda16b2a082f8d833f4459294202cb2687 * [8df36ec] Translate missed string. * [82f9818] Improve audio setup -- Mario Limonciello Tue, 10 Apr 2012 02:48:16 -0500 mythtv (2:0.25.0~master.20120406.041ecad-0ubuntu1) precise; urgency=low * Remove extra reference to libmysqlclient-16-dev. * Add b-d on libmysqlclient-dev (LP: #894377). * Drop dependency on ttf-freefont. * New upstream checkout (041ecad) * >>Upstream changes since last upload (c85fc55): * [041ecad] increases the maximal number of queued video packets to 220. * [5824030] Bump API version following addition of plist decoding * [91a2209] Add a binary property list parser. * [1b24a76] Make RAOP server properly handle any size of decoded audio packets. * [2d365d6] Tweak Smolt handling of digital tuners. * [65d89b5] Fix dates and time strings not being translated to the user-selected language. We were always using the system language and not respecting the language/country chosen in mythfrontend. * [640b0cd] Refs #10490. Switch ringbuffers a little earlier in LiveTV. * [c49b780] Fix translation of