diff options
author | Bob Igo <bob@stormlogic.com> | 2009-01-17 17:53:44 (GMT) |
---|---|---|
committer | Bob Igo <bob@stormlogic.com> | 2009-01-17 17:53:44 (GMT) |
commit | 18b8c17f24b9cd6d9600b212cbd615deb69fe500 (patch) | |
tree | ce8b68a2277d4d81706c9f71832540a91361919e | |
parent | e2f581d7a980085e0078e01f1a38886ab88127ec (diff) | |
download | linhes_pkgbuild-18b8c17f24b9cd6d9600b212cbd615deb69fe500.zip linhes_pkgbuild-18b8c17f24b9cd6d9600b212cbd615deb69fe500.tar.gz linhes_pkgbuild-18b8c17f24b9cd6d9600b212cbd615deb69fe500.tar.bz2 |
Expanded Tweaker tar file into individual files, and adjusted installation process to reflect this. Further integration will be required before this is ready for R6.
32 files changed, 5040 insertions, 15 deletions
diff --git a/abs/core-testing/tweaker/PKGBUILD b/abs/core-testing/tweaker/PKGBUILD index a11643b..bb5a401 100644 --- a/abs/core-testing/tweaker/PKGBUILD +++ b/abs/core-testing/tweaker/PKGBUILD @@ -6,7 +6,7 @@ arch=('i686' 'x86_64') depends=('bash' 'perl' 'perl-dbi' 'perl-exception-class' 'perl-log-log4perl' 'perl-log-dispatch' 'perl-getopt-lucid' 'perl-list-member' 'perl-class-data-inheritable' 'perl-devel-stacktrace' 'perl-xml-twig') -source=(${pkgname}.tar.bz2 tweaker.sh log4perl.conf) +source=(tweaker.sh log4perl.conf bin/tweaker.pl bin/twk_audio.pl bin/twk_audio_RP.pl bin/twk_cpu.pl bin/twk_dragon.pl bin/twk_EXAMPLE.pl bin/twk_fingerprint_hardware.sh bin/twk_general.pl bin/twk_graphics.pl bin/twk_keymap.sh bin/twk_linux.pl bin/twk_localization.pl bin/twk_misc.pl bin/twk_RAM.pl bin/twk_scrub_sql.pl bin/twk_tuners.pl bin/twk_upgrade.pl bin/twk_what_has_changed.sh tcf/EXAMPLE.tcf tcf/focus.tcf tcf/os.tcf tcf/tcf.dtd tcf/tweaker-core.tcf tcf/userland.tcf fs/etc/asound.conf fs/var/lib/alsa/ALC888.asound.state fs/var/lib/alsa/AV710.asound.state lib/Tweaker/Definitions.pm lib/Tweaker/Script.pm) license=('GPL2') #groups=('pvr') @@ -14,21 +14,24 @@ license=('GPL2') #install=tweaker.install build() { - TWEAKER_ROOT=$startdir/pkg/usr/LH/tweaker - cd $startdir/src/ || return 1 - mkdir -p $TWEAKER_ROOT/bin + TWEAKER_ROOT=/usr/LH/tweaker + mkdir -p $TWEAKER_ROOT + cd $TWEAKER_ROOT + # executables + install -m0777 -d bin $startdir/bin + # parallel root directory structure used for seeding configuration files + install -m0777 -d fs $startdir/fs + # Tweaker configuration files + install -m0555 -d tcf $startdir/tcf + # Tweaker-centric log4perl configuration + cd /etc + install -m0755 log4perl.conf $startdir/log4perl.conf + + # Ensure shell variables are configured at start; ensure $TWEAKER_ROOT/bin is in $PATH mkdir -p $startdir/pkg/etc/profile.d install -m0755 tweaker.sh $startdir/pkg/etc/profile.d/tweaker.sh - install -m0755 log4perl.conf $TWEAKER_ROOT/log4perl.conf - - #copy binary files - cd usr/local/bin - install -m0755 * $TWEAKER_ROOT/bin/ - rm -f $TWEAKER_ROOT/bin/tweaker-installer.sh - -#copied lib from km 5.5 because it was missing from the tar file - mkdir -p $TWEAKER_ROOT - cd $startdir/src/usr/LH/tweaker - cp -rp * $TWEAKER_ROOT + # Link our tweaker Perl modules for general use + /bin/ln -fs $TWEAKER_ROOT/lib/Tweaker /etc/perl/ + /bin/cp $startdir/fs/etc/log4perl.conf /etc } diff --git a/abs/core-testing/tweaker/bin/tweaker.pl b/abs/core-testing/tweaker/bin/tweaker.pl new file mode 100755 index 0000000..28519df --- /dev/null +++ b/abs/core-testing/tweaker/bin/tweaker.pl @@ -0,0 +1,333 @@ +#!/usr/bin/perl -w + +# Copyright 2007, 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +package Tweaker; + +use strict; +use Getopt::Lucid qw( :all ); +# see http://search.cpan.org/~dagolden/Getopt-Lucid-0.16/lib/Getopt/Lucid.pm for usage details +use XML::Twig; +# see http://xmltwig.com for usage details +use Log::Log4perl qw(get_logger); + +# see http://search.cpan.org/~mschilli/Log-Log4perl-1.14/lib/Log/Log4perl.pm for usage details +# http://www.perl.com/pub/a/2002/09/11/log4perl.html is highly recommended as well + +use Tweaker::Script; +use Tweaker::Definitions; + +# To install the above modules: +# -- +# sudo cpan install Getopt::Lucid XML::Twig Log::Log4perl List::Member +# choose the defaults for all options, agree to install all dependencies +# Copy TweakerDefinitions.pm to /etc/perl + +use vars qw($debug); +use vars qw($interactivity); +use vars qw($logfile); +use vars qw($twig); + +my $bottom = Tweaker::Definitions::get_global_variable_value("bottom"); +my $optional = Tweaker::Definitions::get_global_variable_value("optional"); +my $minimal = Tweaker::Definitions::get_global_variable_value("minimal"); +my $null = Tweaker::Definitions::get_global_variable_value("null"); + +# As each tweak tag is processed, this subroutine is called. Here we will +# see if any previous tweak tag had the same name attribute. If so, we will +# replace the previous tweak tag with this new tweak tag's contents. +sub uniquify_tweaks { + my ($twig, $this_tweak) = @_; + my $tweak_name = $this_tweak->att('name'); + my $previous_tweak = $this_tweak->prev_sibling( qq{tweak[\@name="$tweak_name"]}); + my $logger = get_logger('tweaker'); + + # If the tweak's name is found elsewhere, replace the first + # instance with the latest one, then delete the latest one. + if ($previous_tweak) { + my $log_entry; + # Requirement 6.3.1 + $log_entry = sprintf("\tReplacing\n\t\t%s\n\twith\n\t\t%s\n", $previous_tweak->sprint, $this_tweak->sprint); + $logger->info($log_entry); + $this_tweak->cut; + $this_tweak->replace($previous_tweak); + } +} + +$twig = XML::Twig->new(load_DTD => 1, + expand_external_ents => 1, + twig_handlers => { 'tweak' => \&uniquify_tweaks } + ); + +# Requirement 4.2 +# Print advice on usage and invocation. +sub help () { + my $logger = get_logger('tweaker'); + $logger->fatal("USAGE:\n$0 --tcf file1.tcf [--tcf file2.tcf ...] [--help]"); + exit; +} + +sub print_tcf { + my(@tweaks) = @_; + my $logger = get_logger('tweaker'); + + $logger->debug('<?xml version="1.0"?>'); # print the XML declaration + $logger->debug('<!DOCTYPE stats SYSTEM "tcf.dtd">'); + $logger->debug('<tcf>'); # then the root element start tag + + foreach my $tweak (@tweaks) { # the list of tweaks + $logger->debug($tweak->sprint); # print the xml content of the element + } + + $logger->debug("</tcf>\n"); # close the document +} + +# For each tweak, invoke the option that was selected. +# Requirement 9.1.5 +# Requirement 13 +sub invoke_selected_options { + my @tweaks= $twig->root->children; # get the tweak list + my $logger = get_logger('tweaker'); + my $has_selected_option; + my $recommendationlevel = $bottom; + + foreach my $tweak (@tweaks) { # the list of tweaks + if ($tweak->att('name')) { + $has_selected_option=0; + $logger->debug("TWEAK ", $tweak->att('name')); + my @options = $tweak->descendants('option'); + foreach my $option (@options) { + if ($option->first_child('selected')) { + $has_selected_option++; + $recommendationlevel = $option->first_child('selected')->text; + $logger->info("\t", $tweak->att('name'), " : ", $option->att('name'), " is selected (recommendationlevel is ", $recommendationlevel, ")"); + # If the selected option is merely $optional, and we are in $minimal interactivity mode, we + # really don't know if this option is useful for the user. Just skip it. + if (($recommendationlevel == $optional) && ($interactivity eq $minimal)) { # UI Requirement 9.1.4 + $logger->debug("\tSKIPPING"); + next; + } elsif (($tweak->first_child('script')->text) && + ($tweak->first_child('script')->text) ne $null) { + $logger->debug("\tRUNNING"); + my $command = sprintf("%s --implement %s", $tweak->first_child('script')->text, $option->att('name')); + $logger->info("\t\tRunning '$command' to run a tweak."); + + open(COMMAND, "$command|"); + while(<COMMAND>) { # should only be one line of results + if ($_) { + $logger->debug("script returned text: ", $_); + } else { + $logger->debug("no return value from script"); + } + } + close(COMMAND); + } else { + $logger->debug("\tNO SCRIPT TO RUN"); + } + } + } + if ($has_selected_option == 0) { + $logger->debug("\tNO OPTION SELECTED"); + } + } + } +} + + +# Parses an XML file in TCF format, loading its information into memory. +# Rely on the DTD to mandate required tags. +sub parse_tcf { + my $this_tcf = shift(@_); + my $logger = get_logger('tweaker'); + + $logger->info("Parsing $this_tcf..."); + $twig->safe_parsefile($this_tcf) || $logger->fatal("Bad TCF $this_tcf: $@"); + if ($@) { + return 0; + } + # ??? For Requirement 5.1, we need to catch parse errors here + # $twig now has the parsed $this_tcf + $logger->info("DONE parsing $this_tcf"); + + my $root= $twig->root; # get the root of the twig (tcf) + my @tweaks= $root->children; # get the tweak list + + print_tcf(@tweaks) if $debug; + + return 1; # successfully parsed $this_tcf +} + +sub parse_core_tcf { + my ($core_tcf_pathname) = @_; + my $logger = get_logger('tweaker'); + + $logger->debug("core TCF pathname: $core_tcf_pathname"); + + # Requirement 5.1 + if (!(parse_tcf($core_tcf_pathname))) { + # Part of Requirement 6.4.1 + $logger->fatal("$0 requires at least one valid .tcf file."); + $logger->fatal("$core_tcf_pathname, or a .tcf that it includes, did not parse."); + exit; + } + # $twig->root->print; +} + +sub process_parameters () { + # Accept these parameters: + # -- + my @parameters = ( + Switch("help")->anycase, # Requirement 4.2 + Switch("debug")->anycase, + # part of Requirement 8 + Param("interactivity")->default($minimal), # side-effect of UI Requirement 9 for v0.7 + ); + + my $opt = Getopt::Lucid->getopt( \@parameters ); + my $help = $opt->get_help; + $debug = $opt->get_debug; + $interactivity = $opt->get_interactivity; + + if ($interactivity ne $minimal) { # side-effect of UI Requirement 9 for v0.7 + my $logger = get_logger('tweaker'); + $logger->warn("This version of Tweaker ignores requests for $interactivity interactivity and defaults to $minimal."); + $interactivity = $minimal; + } + + if ( $help > 0 ) { + help; + } +} + +# Requirement 6.6: Tweaker shall determine Recommendation Levels and default Options +# Requirements 6.6.1 and 6.6.2 +sub post_process_tweaks { + my $logger = get_logger('tweaker'); + + # Requirement 6.6.1 + + my $root= $twig->root; # get the root of the twig (tcf) + my @tweaks= $root->children; # get the tweak list + + foreach my $tweak (@tweaks) { + $logger->debug("#######"); + my @options = $tweak->descendants('option'); + + my $name_of_most_recommended_option=""; + my $most_recommended_option; + my $highest_recommendationlevel=$bottom; + + foreach my $option (@options) { + $logger->debug("===== OPTION"); + $logger->debug($option->sprint); + + my $recommendationlevel = $option->first_child('recommendationlevel'); + if ($recommendationlevel) { + # Requirement 6.6.1.1 + $logger->debug("\t+++"); + $logger->debug("\tUsing predefined recommendation level:", $recommendationlevel->text); + } else { + # Requirement 6.6.1.4 + my $result="optional"; + my $explanation=""; + + if (($tweak->first_child('script')->text) && + ($tweak->first_child('script')->text) ne $null) { + # Requirement 6.6.1.2 + $logger->debug("\t---"); + $logger->debug("\tThis has no defined recommendation level."); + + # Get the name of the script for this tweak and invoke it with the name of the option. + my $command = sprintf("%s --poll %s", $tweak->first_child('script')->text, $option->att('name')); + $logger->debug("\t\tRunning '$command' to see what it should be."); + # Create a recommendationlevel element and populate it with the script's return value. + + open(COMMAND, "$command|"); + while(<COMMAND>) { # should only be one line of results + $logger->debug("Got this: ", $_); + if ($_) { + chop; + my @text = split(/\|/); + $result = $text[0]; + if ($text[1]) { + $explanation = $text[1]; + } + } + } + close(COMMAND); + } + # Requirement 6.6.1.3 + $option->set_field ( 'recommendationlevel', $result ); + if ($explanation) { + $option->set_field ( 'explanation', $explanation ); + } + #$logger->debug("*** Paste results: ", $option->sprint); + } + # Requirement 6.6.2 : Auto-select the Option with the highest non-negative Recommendation Level. + # Requirement 6.6.2.1 : If there is a tie, Tweaker shall auto-select the first Option with the highest Recommendation Level. + $recommendationlevel = $option->first_child('recommendationlevel'); + if ($recommendationlevel) { + if ($name_of_most_recommended_option) { + $logger->debug("comparing ", $name_of_most_recommended_option, "'s recommendationlevel ($highest_recommendationlevel) to ", $recommendationlevel->text, " (",Tweaker::Definitions::get_global_variable_value($recommendationlevel->text),")"); + } else { + $logger->debug("considering recommendationlevel ", $recommendationlevel->text, " (",Tweaker::Definitions::get_global_variable_value($recommendationlevel->text),")"); + } + if (($highest_recommendationlevel < Tweaker::Definitions::get_global_variable_value($recommendationlevel->text)) + && (Tweaker::Definitions::get_global_variable_value($recommendationlevel->text) >= 0)) { + $highest_recommendationlevel = Tweaker::Definitions::get_global_variable_value($recommendationlevel->text); + $name_of_most_recommended_option = $option->att('name'); + $most_recommended_option = $option; + $logger->debug("now recommending: ", $name_of_most_recommended_option, " at level ", $highest_recommendationlevel); + } + } else { + $logger->error("No recommendationlevel defined for ", $option->att('name')); + } + # Select the best option, based on recommendation level + } + if ($most_recommended_option) { + $logger->debug("(1) BEST OPTION: ", $most_recommended_option->sprint); + $most_recommended_option->set_field ( 'selected', $highest_recommendationlevel ); + } + } +} + +sub main () { + my $tweaker_root; + + if (!($tweaker_root = Tweaker::Script::get_environment_variable("\$TWEAKER_ROOT"))) { + Log::Log4perl->easy_init(); + my $logger = get_logger(); + $logger->fatal("\$TWEAKER_ROOT not defined. Exiting."); + exit -1; + } + my $core_tcf_path = "$tweaker_root/tcf"; + my $core_tcf = "tweaker-core.tcf"; + my $core_tcf_pathname = "$core_tcf_path/$core_tcf"; + my $log4perl_conf = "$tweaker_root/log4perl.conf"; + + Log::Log4perl::init_and_watch($log4perl_conf,10); + + process_parameters; + parse_core_tcf($core_tcf_pathname); + post_process_tweaks; + # ??? need to add Requirement 11 here + invoke_selected_options; +} + +main; + +#my @tweaks= $twig->root->children; # get the tweak list +#print_tcf(@tweaks) if $debug; diff --git a/abs/core-testing/tweaker/bin/twk_EXAMPLE.pl b/abs/core-testing/tweaker/bin/twk_EXAMPLE.pl new file mode 100755 index 0000000..4fc401a --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_EXAMPLE.pl @@ -0,0 +1,134 @@ +# This is not an executable. It provides an example of how you would implement a +# Tweaker Script. For details on the functions provided by Tweaker::Script, +# such as execute_shell_command, get_environment_variable, connect_to_db, etc. +# see Tweaker/Script.pm +# +# See the corresponding EXAMPLE.tcf for the Tweak that would correspond to this script. + +# +# BEGIN EXAMPLE +# + +#!/usr/bin/perl -w + +# Copyright 2008 YOUR NAME HERE +# +# 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 <http://www.gnu.org/licenses/>. + +use Switch; +use Tweaker::Script; +package Tweaker::Script; + +# List all the options that this script supports. Make sure it matches what's in +# the corresponding .tcf entry. +set_known_options( 'option1', 'option2', 'option3' ); + +# Try to implement the given option. +sub implement_option { + my($option) = @_; + + # If you need a subroutine that is specific to the task of implementing an option, + # define it inside the above subroutine. + sub my_subroutune { + # ... + } + + $dbconnectionstring = get_mythtv_connection_string(); + + if (connect_to_db("DBI:mysql:$dbconnectionstring")) { # You may not have to do this. It's only when you need to change MySQL settings for MythTV. + switch ($option) { + # List all the options that this script supports. You can have as many as you like. + case "option1" { + # Perform the actions necessary to implement option1. + # You may want to call do_query, change_or_make_setting, or change_or_make_entry to make changes to the MySQL database. + # You may want to call execute_shell_command to make changes from the shell. + } + case "option2" { + # Perform the actions necessary to implement option2. + # You may want to call do_query, change_or_make_setting, or change_or_make_entry to make changes to the MySQL database. + # You may want to call execute_shell_command to make changes from the shell. + } + case "option3" { + # Perform the actions necessary to implement option3. + # You may want to call do_query, change_or_make_setting, or change_or_make_entry to make changes to the MySQL database. + # You may want to call execute_shell_command to make changes from the shell. + } + } + } else { # You may not have to do this. It's only when you need to change MySQL settings for MythTV. + my $logger = get_logger('tweaker.script'); + $logger->error("ERROR: Unable to connect to mythconverg database"); + $logger->error("ERROR: Unable to implement option $option."); + exit -1; # You may not have to do this. It's only when you need to change MySQL settings for MythTV. + } # You may not have to do this. It's only when you need to change MySQL settings for MythTV. + disconnect_from_db(); # You may not have to do this. It's only when you need to change MySQL settings for MythTV. +} + +# Poll the system to see what recommendationlevel the given option has on the system. +sub poll_options { + my($option) = @_; + + # If you need a subroutine that is specific to the task of implementing an option, + # define it inside the above subroutine. + sub my_subroutune { + # ... + } + + $dbconnectionstring = get_mythtv_connection_string(); + + if (connect_to_db("DBI:mysql:$dbconnectionstring")) { # You may not have to do this. It's only when you need to change MySQL settings for MythTV. + switch ($option) { + # List all the options that this script supports. You can have as many as you like. + case "option1" { + # Perform the actions necessary to determine a recommendation level for option1. + # You may want to call do_query to query to the MySQL database. + # You may want to call execute_shell_command to check things in the shell. + # When you're done, you can use the recommendation_level subroutine to return the + # resulting recommendation level. + } + case "option2" { + # Perform the actions necessary to determine a recommendation level for option2. + # You may want to call do_query to query to the MySQL database. + # You may want to call execute_shell_command to check things in the shell. + # When you're done, you can use the recommendation_level subroutine to return the + # resulting recommendation level. + } + case "option3" { + # Perform the actions necessary to determine a recommendation level for option3. + # You may want to call do_query to query to the MySQL database. + # You may want to call execute_shell_command to check things in the shell. + # When you're done, you can use the recommendation_level subroutine to return the + # resulting recommendation level. + } + } + } else { # You may not have to do this. It's only when you need to change MySQL settings for MythTV. + exit -1; # You may not have to do this. It's only when you need to change MySQL settings for MythTV. + } # You may not have to do this. It's only when you need to change MySQL settings for MythTV. + disconnect_from_db(); # You may not have to do this. It's only when you need to change MySQL settings for MythTV. +} + +# Unimplemented in 0.7 +sub check_option { + help; +} + +# Unimplemented in 0.7 +sub count_iterations { + help; +} + +process_parameters; # mandatory + +# +# END EXAMPLE +# diff --git a/abs/core-testing/tweaker/bin/twk_RAM.pl b/abs/core-testing/tweaker/bin/twk_RAM.pl new file mode 100755 index 0000000..ead3e3c --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_RAM.pl @@ -0,0 +1,78 @@ +#!/usr/bin/perl -w + +# Copyright 2007, 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +use Switch; +use Tweaker::Script; +package Tweaker::Script; + +set_known_options( 'low', 'medium', 'high' ); + +# ??? Need to make this update a class variable so it only ever needs to run once. +sub determine_RAM_size() { + my $result = execute_shell_command("cat /proc/meminfo | grep MemTotal"); + if ($result =~ m/.*MemTotal:\s*(\d+) .*/) { + return $1; + } + return 0; +} + +# Try to implement the given option. +sub implement_option { + my($option) = @_; + + $dbconnectionstring = get_mythtv_connection_string(); + + if (connect_to_db("DBI:mysql:$dbconnectionstring")) { + # MythTV's GUI allows setting this value in multiples of 4700kB. + # We will arbitrarily set the HDRingbufferSize to the value that is closest to + # 3.3% of the total RAM. + my $RAM_size = determine_RAM_size(); + my $ringbuffer_size = int($RAM_size * 0.033 / 4700) * 4700; + change_or_make_setting('HDRingbufferSize', $ringbuffer_size) || exit -1; + + # change any existing mplayer cache setting to one based on available RAM size + # We will arbitrarily set the cache size to 1/16 of available RAM + my $cachesize = int($RAM_size / 16); + execute_shell_command("sed -i 's/cache.*=.*/cache=$cachesize/g' /etc/mplayer/mplayer.conf") || exit -1; + } else { + exit -1; # You may not have to do this. It's only when you need to change MySQL settings for MythTV. + } # You may not have to do this. It's only when you need to change MySQL settings for MythTV. + disconnect_from_db(); # You may not have to do this. It's only when you need to change MySQL settings for MythTV. +} + +# Poll the system to see what recommendationlevel the given option has on the system. +sub poll_options { + my($option) = @_; + my $fudge_factor = .985; + my $low_RAM = int($fudge_factor * 512*1024); # ~512MB + my $medium_RAM = int($fudge_factor * 1024*1024); # ~1GB + my $high_RAM = int($fudge_factor * 2048*1024); # ~2GB + + threshold_test($option, determine_RAM_size(), "RAM", $low_RAM, $medium_RAM, $high_RAM); +} + +# Unimplemented in 0.7 +sub check_option { + help; +} + +# Unimplemented in 0.7 +sub count_iterations { + help; +} + +process_parameters; diff --git a/abs/core-testing/tweaker/bin/twk_audio.pl b/abs/core-testing/tweaker/bin/twk_audio.pl new file mode 100755 index 0000000..72b9c86 --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_audio.pl @@ -0,0 +1,376 @@ +#!/usr/bin/perl -w + +# Copyright 2007, 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +use Switch; +use Tweaker::Script; +package Tweaker::Script; + +set_known_options( 'analogstereo', 'analogsurround', 'digital' ); + +# Poll the system to find the digital output device. +sub poll_for_digital_output_device { + my $card=-1; + my $device=-1; + my $poll_command = "aplay -l | grep card"; + + my @digital_matches = ( "digital", "IEC958" ); + + my $results = execute_shell_command($poll_command); + foreach my $digital_match (@digital_matches) { + if ($results =~ /card (\d):.*device (\d).*$digital_match.*/i) { + $card = $1; + $device = $2; + } + } + return ($card, $device); +} + +# Try to implement the given option. +sub implement_option { + my($option) = @_; + use vars qw($card); + use vars qw($device); + ($card, $device) = poll_for_digital_output_device; + use vars qw($asound_conf); + $asound_conf = "/etc/asound.conf"; + use vars qw($mplayer_conf); + $mplayer_conf = "/etc/mplayer/mplayer.conf"; + use vars qw($xine_conf); + $xine_conf = "/home/mythtv/.xine/config"; + + sub generate_asound_conf { + my($option) = @_; + my $command1; + my $command2; + + switch ($option) { + case "analogstereo" { + # Analog stereo usually needs no asound.conf, but sometimes it needs to be there to + # support more than one app using sound simultaneously. + $command1 = "[ -e $asound_conf ] && /bin/cp $asound_conf $asound_conf-TWEAKERBACKUP"; + # Assumption: The proper analog device is always device 0. + if ($card >= 0) { + $command2 = "[ -e $asound_conf ] && sed -i 's/hw:.,./hw:$card,0/g' $asound_conf"; + } else { + $command2 = "[ -e $asound_conf ] && sed -i 's/hw:.,./hw:0,0/g' $asound_conf"; + } + } + case "analogsurround" { + # Not supported yet. + } + case "digital" { + # Digital audio starts with an asound.conf that references the + # hardware address on the sound device corresponding to digital + # output. + $command1 = "/bin/cp \$TWEAKER_ROOT/fs$asound_conf /etc/"; + if (($card >= 0) && ($device >= 0)) { + $command2 = "sed -i 's/hw:.,./hw:$card,$device/g' $asound_conf"; + } else { + my $logger = get_logger('tweaker.script'); + $logger->error("ERROR: Unable to poll for digital sound output device."); + exit(-1); + } + } + } + if (my $error = execute_shell_command($command1)) { + my $logger = get_logger('tweaker.script'); + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + if (my $error = execute_shell_command($command2)) { + my $logger = get_logger('tweaker.script'); + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + my $logger = get_logger('tweaker.script'); + $logger->info("Generated $asound_conf for $option audio."); + } + + sub edit_mplayer_conf { + my($option) = @_; + # delete any old entries that Tweaker made, relevant to this particular edit + my $delete_old_tweaker_edits = "sed -i '/^.*a[o,c].*=.*#TWEAKER/d' $mplayer_conf"; + # comment out old entries that some other process may have made + my $comment_out_external_edits = "sed -i 's/^\\(a[o,c].*=.*\\)/#\\1/g' $mplayer_conf"; + my $command1; + my $command2=""; + ($card, $device) = poll_for_digital_output_device; + my $logger = get_logger('tweaker.script'); + + if (my $error = execute_shell_command("$delete_old_tweaker_edits && $comment_out_external_edits")) { + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + + switch($option) { + case "analogstereo" { + # No additional work needed; the above commands comment out ao and ac entries, + # leaving a baseline which works with analog stereo. + } + case "analogsurround" { + # Not supported yet. + } + case "digital" { + $command2 = "echo -e 'ac=hwac3,hwdts, #TWEAKER\nao=alsa:device=plughw=$card.$device #TWEAKER' >> $mplayer_conf"; + if (my $error = execute_shell_command($command2)) { + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + + my @digital_audio_device_patterns = ( + [ + # Asus T3-M2NC51PV onboard audio + ".*0403.*10de.*026c.*1043.*821f", "T3-M2NC51PV", "sed -i 's/plughw.* #TWEAKER/spdif #TWEAKER/g' $mplayer_conf" + ] + ); + + foreach my $pattern_and_workaround_command (@digital_audio_device_patterns) { + my $pattern=@$pattern_and_workaround_command[0]; + my $name=@$pattern_and_workaround_command[1]; + my $workaround_command=@$pattern_and_workaround_command[2]; + + if (execute_shell_command('lspci -mn | grep -e "'.$pattern.'"')) { + $logger->info("Applying workaround for $name audio"); + execute_shell_command($workaround_command); + last; + } + } + } + } + $logger->info("Edited $mplayer_conf for $option audio."); + } + + sub edit_xine_conf { + my($option)=@_; + # delete any old entries that Tweaker made, relevant to this particular edit + my $delete_old_tweaker_edits = "sed -i -e '/^.*audio.output.speaker_arrangement.*#TWEAKER/d' -e '/^.*audio.synchronization.passthrough_offset.*#TWEAKER/d' $xine_conf"; + # comment out entries that some other process may have made + my $comment_out_external_edits = "sed -i -e 's/^\\(audio.output.speaker_arrangement.*\\)/#\\1/g' -e 's/^\\(audio.synchronization.passthrough_offset.*\\)/#\\1/g' $xine_conf"; + my $logger = get_logger('tweaker.script'); + + if (my $error = execute_shell_command("$delete_old_tweaker_edits && $comment_out_external_edits")) { + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + + my $command1; + + switch($option) { + case "analogstereo" { + $command1 = "echo 'audio.output.speaker_arrangement:Stereo 2.0 #TWEAKER' >> $xine_conf"; + } + case "analogsurround" { + # Not supported yet. + } + case "digital" { + $command1 = "echo -e 'audio.output.speaker_arrangement:Pass Through #TWEAKER\naudio.synchronization.passthrough_offset:$device #TWEAKER' >> $xine_conf"; + } + } + if (my $error = execute_shell_command($command1)) { + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + $logger->info("Edited $xine_conf for $option audio."); + } + + sub reload_modules { + my($option) = @_; + my $command = "update-modules; depmod -a; rmmod snd-pcm-oss; modprobe snd-pcm-oss"; + my $logger = get_logger('tweaker.script'); + + if (my $error = execute_shell_command($command)) { + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + $logger->info("Reloaded sound modules for $option audio."); + } + + sub set_mixer_values { + my($option) = @_; + my $logger = get_logger('tweaker.script'); + + # Some sound devices work poorly in their default state, so we will load in a known-good + # state for them. + + my @digital_audio_device_patterns = ( + [ + # Chaintech AV-710 + ".*0401.*1412.*1724.*1412.*1724", "AV710" + ], + [ + # Realtek ALC888 High Definition onboard Audio + ".*0403.*10de.*055c.*1565.*820c", "ALC888" + ] + ); + + foreach my $pattern_and_name_pairing (@digital_audio_device_patterns) { + my $name=@$pattern_and_name_pairing[1]; + my $pattern=@$pattern_and_name_pairing[0]; + + if (execute_shell_command('lspci -mn | grep -e "'.$pattern.'"')) { + $logger->info("Applying ALSA state workaround for $name audio"); + execute_shell_command("/bin/cp \$TWEAKER_ROOT/fs/var/lib/alsa/$name.asound.state /var/lib/alsa/asound.state"); + execute_shell_command("alsactl restore"); + last; + } + } + + # Now, do what works for all sound devices. + + my $command = "su - mythtv -c \"aumix -v 70 -m 0 -l 0 -l R -w 70\""; # ok for analog and digital + + if (my $error = execute_shell_command($command)) { + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + + if ("$option" eq "digital") { + # Poll system for IEC958 controls, and try to turn them all 'on' + $command = "amixer scontrols | grep IEC958"; + my @results = split('\n', execute_shell_command($command)); + foreach my $line (@results) { + if ($line =~ /Simple mixer control (.*),.*/i) { + $command = "su - mythtv -c \"amixer set $1 on\""; # Tries to set all IEC958 devices to 'on' + # but some are just placeholders and can't be turned 'on', therefore don't error out if we fail + execute_shell_command($command); + } + } + } + execute_shell_command("alsactl store"); # persist the above change(s) + $logger->info("Reset mixer volume levels for $option audio."); + } + + sub edit_mythtv_configuration { + my($option)=@_; + + $dbconnectionstring = get_mythtv_connection_string(); + + if (connect_to_db("DBI:mysql:$dbconnectionstring")) { + switch ($option) { + case "analogstereo" { + change_or_make_setting('AC3PassThru', '0') || exit -1; + change_or_make_setting('DTSPassThru', '0') || exit -1; + change_or_make_setting('MTDac3Flag', '0') || exit -1; + change_or_make_setting('MythControlsVolume', '1') || exit -1; + } + case "analogsurround" { + # Not supported yet. + } + case "digital" { + change_or_make_setting('AC3PassThru', '1') || exit -1; + change_or_make_setting('DTSPassThru', '1') || exit -1; + change_or_make_setting('MTDac3Flag', '1') || exit -1; + change_or_make_setting('MythControlsVolume', '0') || exit -1; + } + } + change_or_make_setting('AudioOutputDevice', 'ALSA:default') || exit -1; + change_or_make_setting('MixerDevice', 'ALSA:default') || exit -1; + change_or_make_setting('MusicAudioDevice', 'default') || exit -1; + } else { + exit -1; + } + disconnect_from_db(); + } + + generate_asound_conf($option); + edit_mplayer_conf($option); + edit_xine_conf($option); + reload_modules($option); + set_mixer_values($option); + edit_mythtv_configuration($option); +} + +# Try to get a Recommendation Level for $option. +sub poll_options { + my($option) = @_; + my @digital_audio_device_patterns = ( + [ + # Pattern matches for PCI IDs of perfect devices, comma-separated within the brackets + [ ".*0403.*8086.*284b.*8086.*2504", # Intel DG965WH onboard audio + ".*0403.*10de.*026c.*1043.*821f", # Asus T3-M2NC51PV onboard audio + ".*0403.*8086.*293e.*8086.*3001" # Intel AusDragon onboard audio + ], + "optional|Your sound device works very well in digital mode. Unless you don't have a receiver that can accept digital inputs, you should use digital mode.", + ], + [ + # Pattern matches for PCI IDs of suboptimal devices, comma-separated within the brackets + [ ".*0401.*1412.*1724.*1412.*1724", # Chaintech AV-710 PCI card (regressions in R5.5) + ], + "inadvisable|Your sound device is known to have some problems in digital mode, but you may try it if you like, starting at low volume in your receiver.", + ], + [ + [ ], # Leave blank for unknown devices + "optional|Your sound device may or may not work well in digital mode. Please tell us if it works, and how well.", + ] + ); + + switch ($option) { + case "analogstereo" { + my ($card, $device) = poll_for_digital_output_device; + if (($card >= 0) && ($device >= 0)) { # A digital output device was detected. + recommendation_level("optional"); + } else { + recommendation_level("recommended", "You seem to have no digital output option. If this is not true, please tell us."); + } + } + case "analogsurround" { + recommendation_level("unsupported", "No configuration data exists yet for this option."); + } + case "digital" { + my ($card, $device) = poll_for_digital_output_device; + if (($card >= 0) && ($device >= 0)) { # A digital output device was detected. + my $recommendation_return_string; + foreach my $pattern_and_recommendation_pairing (@digital_audio_device_patterns) { + $recommendation_return_string=@$pattern_and_recommendation_pairing[1]; + foreach my $patterns (@$pattern_and_recommendation_pairing[0]) { + foreach my $pattern (@$patterns) { + if (execute_shell_command('lspci -mn | grep -e "'.$pattern.'"')) { + recommendation_level($recommendation_return_string); + return; + } + } + } + } + # Because we didn't return a recommendation level above, return a default recommendation level. + recommendation_level($recommendation_return_string); + return; + } else { # No digital output device was detected. + recommendation_level("not available"); + } + } + } +} + +# Unimplemented in 0.7 +sub check_option { + help; +} + +# Unimplemented in 0.7 +sub count_iterations { + help; +} + +process_parameters; diff --git a/abs/core-testing/tweaker/bin/twk_audio_RP.pl b/abs/core-testing/tweaker/bin/twk_audio_RP.pl new file mode 100755 index 0000000..2642fda --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_audio_RP.pl @@ -0,0 +1,307 @@ +#!/usr/bin/perl -w + +# Copyright 2007, 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +use Switch; +use Tweaker::Script; +package Tweaker::Script; + +set_known_options( 'analogstereo', 'analogsurround', 'digital' ); + +# Poll the system to find the digital output device. +sub poll_for_digital_output_device { + my $card=-1; + my $device=-1; + my $poll_command = "aplay -l | grep card"; + + my @digital_matches = ( "digital", "IEC958" ); + + my $results = execute_shell_command($poll_command); + foreach my $digital_match (@digital_matches) { + if ($results =~ /card (\d):.*device (\d).*$digital_match.*/i) { + $card = $1; + $device = $2; + } + } + return ($card, $device); +} + +# Try to implement the given option. +sub implement_option { + my($option) = @_; + use vars qw($card); + use vars qw($device); + ($card, $device) = poll_for_digital_output_device; + use vars qw($asound_conf); + $asound_conf = "/etc/asound.conf"; + use vars qw($mplayer_conf); + $mplayer_conf = "/etc/mplayer/mplayer.conf"; + use vars qw($xine_conf); + $xine_conf = "/home/mythtv/.xine/config"; + + sub generate_asound_conf { + my($option) = @_; + my $command1; + my $command2; + + switch ($option) { + case "analogstereo" { + # Analog stereo usually needs no asound.conf, but sometimes it needs to be there to + # support more than one app using sound simultaneously. + $command1 = "[ -e $asound_conf ] && /bin/cp $asound_conf $asound_conf-TWEAKERBACKUP"; + # Assumption: The proper analog device is always device 0. + if ($card >= 0) { + $command2 = "sed -i 's/hw:.,./hw:$card,0/g' $asound_conf"; + } else { + $command2 = "sed -i 's/hw:.,./hw:0,0/g' $asound_conf"; + } + } + case "analogsurround" { + # Not supported yet. + } + case "digital" { + # Digital audio starts with an asound.conf that references the + # hardware address on the sound device corresponding to digital + # output. + $command1 = "/bin/cp \$TWEAKER_ROOT/fs$asound_conf /etc/"; + if (($card >= 0) && ($device >= 0)) { + $command2 = "sed -i 's/hw:.,./hw:$card,$device/g' $asound_conf"; + } else { + my $logger = get_logger('tweaker.script'); + $logger->error("ERROR: Unable to poll for digital sound output device."); + exit(-1); + } + } + } + if (my $error = execute_shell_command($command1)) { + my $logger = get_logger('tweaker.script'); + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + if (my $error = execute_shell_command($command2)) { + my $logger = get_logger('tweaker.script'); + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + my $logger = get_logger('tweaker.script'); + $logger->info("Generated $asound_conf for $option audio."); + } + + sub edit_mplayer_conf { + my($option) = @_; + # delete any old entries that Tweaker made, relevant to this particular edit + my $delete_old_tweaker_edits = "sed -i '/^.*a[o,c].*=.*#TWEAKER/d' $mplayer_conf"; + # comment out old entries that some other process may have made + my $comment_out_external_edits = "sed -i 's/^\\(a[o,c].*=.*\\)/#\\1/g' $mplayer_conf"; + my $command1; + my $command2=""; + my $logger = get_logger('tweaker.script'); + + if (my $error = execute_shell_command("$delete_old_tweaker_edits && $comment_out_external_edits")) { + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + + switch($option) { + case "analogstereo" { + # No additional work needed; the above commands comment out ao and ac entries, + # leaving a baseline which works with analog stereo. + } + case "analogsurround" { + # Not supported yet. + } + case "digital" { + $command2 = "echo -e 'ac=hwac3,hwdts, #TWEAKER\nao=oss:/dev/adsp #TWEAKER' >> $mplayer_conf"; + if (my $error = execute_shell_command($command2)) { + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + } + } + $logger->info("Edited $mplayer_conf for $option audio."); + } + + sub edit_xine_conf { + my($option)=@_; + # delete any old entries that Tweaker made, relevant to this particular edit + my $delete_old_tweaker_edits = "sed -i -e '/^.*audio.output.speaker_arrangement.*#TWEAKER/d' -e '/^.*audio.synchronization.passthrough_offset.*#TWEAKER/d' $xine_conf"; + # comment out entries that some other process may have made + my $comment_out_external_edits = "sed -i -e 's/^\\(audio.output.speaker_arrangement.*\\)/#\\1/g' -e 's/^\\(audio.synchronization.passthrough_offset.*\\)/#\\1/g' $xine_conf"; + my $logger = get_logger('tweaker.script'); + + if (my $error = execute_shell_command("$delete_old_tweaker_edits && $comment_out_external_edits")) { + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + + my $command1; + + switch($option) { + case "analogstereo" { + $command1 = "echo 'audio.output.speaker_arrangement:Stereo 2.0 #TWEAKER' >> $xine_conf"; + } + case "analogsurround" { + # Not supported yet. + } + case "digital" { + $command1 = "echo -e 'audio.output.speaker_arrangement:Pass Through #TWEAKER\naudio.synchronization.passthrough_offset:$device #TWEAKER' >> $xine_conf"; + } + } + if (my $error = execute_shell_command($command1)) { + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + $logger->info("Edited $xine_conf for $option audio."); + } + + sub reload_modules { + my($option) = @_; + my $command = "update-modules; depmod -a; rmmod snd-pcm-oss; modprobe snd-pcm-oss"; + my $logger = get_logger('tweaker.script'); + + if (my $error = execute_shell_command($command)) { + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + $logger->info("Reloaded sound modules for $option audio."); + } + + sub set_mixer_values { + my($option) = @_; + my $command = "aumix -v 70 -m 0 -l 0 -l R -w 70"; + my $logger = get_logger('tweaker.script'); + + if (my $error = execute_shell_command($command)) { + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + $logger->info("Reset mixer volume levels for $option audio."); + } + + sub edit_mythtv_configuration { + my($option)=@_; + + $dbconnectionstring = get_mythtv_connection_string(); + + if (connect_to_db("DBI:mysql:$dbconnectionstring")) { + switch ($option) { + case "analogstereo" { + change_or_make_setting('AudioOutputDevice', '/dev/dsp') || exit -1; + change_or_make_setting('AC3PassThru', '0') || exit -1; + change_or_make_setting('DTSPassThru', '0') || exit -1; + change_or_make_setting('MTDac3Flag', '0') || exit -1; + + } + case "analogsurround" { + # Not supported yet. + } + case "digital" { + change_or_make_setting('AudioOutputDevice', '/dev/adsp') || exit -1; + change_or_make_setting('AC3PassThru', '1') || exit -1; + change_or_make_setting('DTSPassThru', '1') || exit -1; + change_or_make_setting('MTDac3Flag', '1') || exit -1; + } + } + change_or_make_setting('MusicAudioDevice', 'default') || exit -1; + change_or_make_setting('MythControlsVolume', '0') || exit -1; + } else { + exit -1; + } + disconnect_from_db(); + } + + generate_asound_conf($option); + edit_mplayer_conf($option); + edit_xine_conf($option); + reload_modules($option); + set_mixer_values($option); + edit_mythtv_configuration($option); +} + +# Try to get a Recommendation Level for $option. +sub poll_options { + my($option) = @_; + my @digital_audio_device_patterns = ( + [ + [ ".*0401.*1412.*1724.*1412.*1724" ], # Pattern matches for PCI IDs of perfect devices, comma-separated within the brackets + "optional|Your sound device works very well in digital mode. Unless you don't have a receiver that can accept digital inputs, you should use digital mode.", + ], + [ + [ ".*0403.*8086.*284b.*8086.*2504" ], # Pattern matches for PCI IDs of suboptimal devices, comma-separated within the brackets + "inadvisable|Your sound device is known to have some problems in digital mode, but you may try it if you like, starting at low volume in your receiver.", + ], + [ + [ ], # Leave blank for unknown devices + "optional|Your sound device may or may not work well in digital mode. Please tell us if it works, and how well.", + ] + ); + + switch ($option) { + case "analogstereo" { + my ($card, $device) = poll_for_digital_output_device; + if (($card >= 0) && ($device >= 0)) { # A digital output device was detected. + recommendation_level("optional"); + } else { + recommendation_level("recommended", "You seem to have no digital output option. If this is not true, please tell us."); + } + } + case "analogsurround" { + recommendation_level("unsupported", "No configuration data exists yet for this option."); + } + case "digital" { + my ($card, $device) = poll_for_digital_output_device; + if (($card >= 0) && ($device >= 0)) { # A digital output device was detected. + my $recommendation_return_string; + foreach my $pattern_and_recommendation_pairing (@digital_audio_device_patterns) { + $recommendation_return_string=@$pattern_and_recommendation_pairing[1]; + foreach my $patterns (@$pattern_and_recommendation_pairing[0]) { + foreach my $pattern (@$patterns) { + if (execute_shell_command('lspci -mn | grep -e "'.$pattern.'"')) { + recommendation_level($recommendation_return_string); + return; + } + } + } + } + # Because we didn't return a recommendation level above, return a default recommendation level. + recommendation_level($recommendation_return_string); + return; + } else { # No digital output device was detected. + recommendation_level("not available"); + } + } + } +} + +# Unimplemented in 0.7 +sub check_option { + help; +} + +# Unimplemented in 0.7 +sub count_iterations { + help; +} + +process_parameters; diff --git a/abs/core-testing/tweaker/bin/twk_cpu.pl b/abs/core-testing/tweaker/bin/twk_cpu.pl new file mode 100755 index 0000000..04a57cc --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_cpu.pl @@ -0,0 +1,132 @@ +#!/usr/bin/perl -w + +# Copyright 2007, 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +use Switch; +use Tweaker::Script; +package Tweaker::Script; + +set_known_options( 'low', 'medium', 'high' ); + +# These values are in BOGOMIPS. They are arbitrary and will be refined, if possible, +# as more data is collected. Obviously, BOGOMIPS are not the best CPU benchmarking +# tool. +my $rrd_threshold = 1650; # bogomips at or below this mean rrdtool is too much of a strain +#my $rrd_threshold = 3365; + +my $low_threshold = 2500; +my $medium_threshold = 4050; +my $high_threshold = 7400; + +# Poll the system to find the CPU type. Currently, we use bogomips (the bogosity of which +# is in the name itself) to guess how powerful the CPU is. +sub get_CPU_strength { + my $bogomips=0; + my @results = split("\n", execute_shell_command("cat /proc/cpuinfo | grep bogomips")); + foreach my $result (@results) { # Count the bogomips for each core. Again, this is rough. + if ($result =~ /bogomips\s*:\s*(\d+.\d+)/) { + $bogomips+=$1; + } + } + return $bogomips; +} + +# ??? Need to test for storage groups and LVM +# Specific to KnoppMyth +sub get_HDD_size { + my @HDD_info = split(" +", execute_shell_command("df -h /myth | grep myth")); + + chop($HDD_info[1]); + return($HDD_info[1] || 0); +} + +#sub disable_rrdtool { +# +#} + +# Try to implement the given option. +sub implement_option { + my($option) = @_; + + # ??? This will need some work to properly integrate with MythTV 0.21's own CPU-based playback settings. + # For now, set profile to CPU++ no matter what CPU type, and just change what CPU++ provides. + + $dbconnectionstring = get_mythtv_connection_string(); + + if (connect_to_db("DBI:mysql:$dbconnectionstring")) { + switch ($option) { + case "low" { + change_or_make_setting('AutoCommflagWhileRecording', '0') || exit -1; + change_or_make_setting('Theme', 'Iulius') || exit -1; # Low eye candy, high performance + #change_or_make_setting('PreferredMPEG2Decoder', 'libmpeg2') || exit -1; # Least CPU usage, lowest quality + #change_or_make_entry("displayprofiles", [["pref_decoder", "libmpeg2"]], [["profilegroupid", "1"], ["profileid", "1"]]) || exit -1; # Least CPU usage, lowest quality + change_or_make_setting('DefaultVideoPlaybackProfile', 'CPU--') || exit -1; # best playback defaults for weak hardware + # Should libmpeg2/ffmpeg be triggered based on CPU type? libmpeg2 is usually + # recommended for AMD CPUs. + # ??? when to use xvmc? + + # Weak CPUs may actually be too weak to run rrdtool without causing problems. +# if (get_CPU_strength() <= $rrd_threshold) { +# disable_rrdtool(); +# } + } + case "medium" { + change_or_make_setting('AutoCommflagWhileRecording', '0') || exit -1; + change_or_make_setting('Theme', 'blootubelite-wide') || exit -1; # Moderate eye candy, moderate performance + #change_or_make_setting('PreferredMPEG2Decoder', 'libmpeg2') || exit -1; # Least CPU usage, lowest quality + #change_or_make_entry("displayprofiles", [["pref_decoder", "libmpeg2"]], [["profilegroupid", "1"], ["profileid", "1"]]) || exit -1; # Least CPU usage, lowest quality + change_or_make_setting('DefaultVideoPlaybackProfile', 'CPU+') || exit -1; # best playback defaults for average hardware + # ??? when to use xvmc? + } + case "high" { + change_or_make_setting('AutoCommflagWhileRecording', '1') || exit -1; + # ??? Interacts with screen aspect ratio + change_or_make_setting('Theme', 'blootube-wide') || exit -1; # High eye candy, potentially low performance + #change_or_make_entry("displayprofiles", [["pref_decoder", "ffmpeg"]], [["profilegroupid", "1"], ["profileid", "1"]]) || exit -1; # Most CPU usage, best quality + #change_or_make_setting('PreferredMPEG2Decoder', 'ffmpeg') || exit -1; # Most CPU usage, best quality + change_or_make_setting('DefaultVideoPlaybackProfile', 'CPU++') || exit -1; # best playback defaults for powerful hardware + # ??? when to use xvmc? + } + } + change_or_make_setting('UseXvMcVld', '0') || exit -1; + #change_or_make_entry("displayprofiles", [["pref_deint0", "onefield"]], [["profilegroupid", "1"], ["profileid", "1"]]) || exit -1; # Most CPU usage, best quality + change_or_make_setting('OSDTheme', 'blootube-osd') || exit -1; + change_or_make_setting('PlayBoxShading', '0') || exit -1; + change_or_make_setting('PlaybackExitPrompt', '2') || exit -1; + } else { + exit -1; + } + disconnect_from_db(); +} + +# Try to get a Recommendation Level for $option. +sub poll_options { + my($option) = @_; + + threshold_test($option, get_CPU_strength(), "CPU", $low_threshold, $medium_threshold, $high_threshold); +} + +# Unimplemented in 0.7 +sub check_option { + help; +} + +# Unimplemented in 0.7 +sub count_iterations { + help; +} + +process_parameters; diff --git a/abs/core-testing/tweaker/bin/twk_dragon.pl b/abs/core-testing/tweaker/bin/twk_dragon.pl new file mode 100755 index 0000000..8bfccca --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_dragon.pl @@ -0,0 +1,66 @@ +#!/usr/bin/perl -w + +# Copyright 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +use Switch; +use Tweaker::Script; +package Tweaker::Script; + +# List all the options that this script supports. Make sure it matches what's in +# the corresponding .tcf entry. +set_known_options( 'all' ); + +# Try to implement the given option. +sub implement_option { + my($option) = @_; + my $logger = get_logger('tweaker.script'); + + $dbconnectionstring = get_mythtv_connection_string(); + + if (connect_to_db("DBI:mysql:$dbconnectionstring")) { + # Overrides SQL changes made in twk_general.pl + change_or_make_setting('DVDPlayerCommand', 'mplayer dvd:\/\/ -dvd-device %d -fs -zoom -vc mpeg12,ffmpeg12-vo xv -vf pp=lb') || return -1; + change_or_make_setting('VCDPlayerCommand', 'mplayer vcd:\/\/ -cdrom-device %d -fs -zoom -vo xv -vf pp=lb') || return -1; + + # Overrides SQL changes made in twk_tuners.pl + # WARNING: Very big harccoded hack. + do_query("UPDATE cardinput SET sourceid='10' WHERE sourceid='20'") || return -1; + } else { + my $logger = get_logger('tweaker.script'); + $logger->error("ERROR: Unable to connect to mythconverg database"); + $logger->error("ERROR: Unable to implement option $option."); + exit -1; + } + disconnect_from_db(); +} + +# Poll the system to see what recommendationlevel the given option has on the system. +sub poll_options { + my($option) = @_; + recommendation_level("recommended", "These tweaks benefit all users."); +} + +# Unimplemented in 0.7 +sub check_option { + help; +} + +# Unimplemented in 0.7 +sub count_iterations { + help; +} + +process_parameters; diff --git a/abs/core-testing/tweaker/bin/twk_fingerprint_hardware.sh b/abs/core-testing/tweaker/bin/twk_fingerprint_hardware.sh new file mode 100755 index 0000000..25111dd --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_fingerprint_hardware.sh @@ -0,0 +1,98 @@ +#!/bin/bash + +# Copyright 2007, 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +# This script will grab USB and PCI data and dump it to a file for the +# user to post. + +output_file=/tmp/fingerprint.txt +maintainer="Human" +thread="" + +Usage() { + echo "USAGE:" + echo `basename $0` " [-a]" + echo "-a: advanced mode" + echo + echo "EXAMPLE: $0" + exit 3 +} + +while getopts "a" FLAG ; do + case "$FLAG" in + a) ADVANCED_MODE=1;; + *) Usage;; + esac +done + +check_for_root() { + if [ `whoami` != "root" ]; then + echo -n `basename $0` + echo " must be run as root. Exiting."; + exit; + fi +} + +poll_PCI() { + echo \ +"##### +# lspci -vv +#####" >> $output_file + lspci -vv >> $output_file + echo "" >> $output_file + + echo \ +"##### +# lspci -mn +#####" >> $output_file + lspci -mn >> $output_file + echo "" >> $output_file +} + +poll_USB() { + echo \ +"##### +# /proc/bus/usb/devices +#####" >> $output_file +cat /proc/bus/usb/devices >> $output_file +} + +instruct() { + echo "Your hardware fingerprint is in $output_file" + echo -n "Please PM it to $maintainer" + if [ "$thread" != "" ]; then + echo " or post it to" + echo -n "$thread" + fi + echo "." + echo "It should be accompanied by a list of changes that you made to the baseline +installation in order to improve MythTV on your hardware." + + echo "If you feel up to the task, feel free to prune out any entries that are for +very low-level devices like memory controllers, USB subsystems, etc. before +sending the fingerprint." +} + +main() { + check_for_root + > $output_file + poll_PCI + poll_USB + instruct +} + +main + diff --git a/abs/core-testing/tweaker/bin/twk_general.pl b/abs/core-testing/tweaker/bin/twk_general.pl new file mode 100755 index 0000000..86da85d --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_general.pl @@ -0,0 +1,541 @@ +#!/usr/bin/perl -w + +# Copyright 2007, 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +use Switch; +use Tweaker::Script; +package Tweaker::Script; + +set_known_options( 'all' ); + +# Try to implement the given option. +sub implement_option { + my($option) = @_; + + # KnoppMyth-centric file-level tweaks + sub file_tweaks { + my($option) = @_; + + my @commands = ( + # keymap tweaks + "twk_keymap.sh", + # fix distro name in various html + "fix_index", + # fix 'motion' index to use our hostname + "sed -i 's/MythTVhost/`hostname`/g' /var/www/motion/index.html", + # + # These may or may not be necessary after GF21 + # + + # Change from "sid" to "stable" repository + "sed -i \"s/sid/stable/g\" /etc/apt/sources.list", + + # Fix bizarre ownership of files: + "chown -f root: /usr/bin/get_dual.sh", + "chown -fR root: /usr/lib/krp", + "chown -fR root: /usr/local/bin", + "chown -f root: /usr/share/man/man1/tv_grab_au.1.gz", + "chown -f root: /usr/share/xmltv/tv_grab_au/channel_ids", + "chown -fR root:src /usr/src/", + + # Install extra software + #"apt-get update && apt-get -y -q=2 install frozen-bubble &", + # prevent fluxbox toolbar from appearing + "fix_toolbar.sh" + ); + + foreach my $command (@commands) { + if (my $error = execute_shell_command($command)) { + my $logger = get_logger('tweaker.script'); + $logger->error("$error"); + $logger->error("Unable to implement option $option with command $command."); + } + } + return 1; + } + + # Enhance the default MythTV SQL + sub SQL_tweaks { + my($option) = @_; + + $dbconnectionstring = get_mythtv_connection_string(); + + if (connect_to_db("DBI:mysql:$dbconnectionstring")) { + # ??? This also exists in mkmythdir - it should be centralized + my $SQL_DirData="/myth"; # Top level dir. of structure, + my $SQL_DirTV="$SQL_DirData/tv"; # TV Recordings, + my $SQL_DirMusic="$SQL_DirData/music/"; # Music storage, + my $SQL_DirGames="$SQL_DirData/games"; # Games dir, + my $SQL_DirPics="$SQL_DirData/gallery"; # Pictures directory. + my $SQL_DirTmp="$SQL_DirData/tmp"; # DVD temp + my $SQL_DirVideo="$SQL_DirData/video"; # videos + + # ??? Eventually, put these into a text file so that 1) people can contribute without having to code, and 2) the data + # stays separate from the code and can be re-used by other (non-Perl) implementations + + # + # keybindings + # + change_or_make_entry("keybindings", [["keylist", "l"]], [["context", "Gallery"], ["action","PLAY"]]); + change_or_make_entry("keybindings", [["keylist", ">"]], [["context", "Music"], ["action","FFWD"]]); + change_or_make_entry("keybindings", [["keylist", "<"]], [["context", "Music"], ["action","RWND"]]); + change_or_make_entry("keybindings", [["keylist", "PgDown,.,Z,End"]], [["context", "Music"], ["action","NEXTTTRACK"]]); + change_or_make_entry("keybindings", [["keylist", "PgUp,Q,Home"]], [["context", "Music"], ["action","PREVTRACK"]]); + change_or_make_entry("keybindings", [["keylist", "P,l"]], [["context", "Music"], ["action","PAUSE"]]); + + change_or_make_entry("keybindings", [["keylist", ">"]], [["context", "Stream"], ["action","FORWARD"]]); + change_or_make_entry("keybindings", [["keylist", "<"]], [["context", "Stream"], ["action","REWIND"]]); + change_or_make_entry("keybindings", [["keylist", "F"]], [["context", "Stream"], ["action","FULLSCREEN"]]); + change_or_make_entry("keybindings", [["keylist", "|,\\,F9,Volume Mute"]], [["context", "Stream"], ["action","MUTE"]]); + change_or_make_entry("keybindings", [["keylist", "Y"]], [["context", "Stream"], ["action","STOREMARKED"]]); + + change_or_make_entry("keybindings", [["keylist", "l"]], [["context", "TV Frontend"], ["action","PLAYBACK"]]); + + change_or_make_entry("keybindings", [["keylist", "l"]], [["context", "TV Playback"], ["action","PLAY"]]); + change_or_make_entry("keybindings", [["keylist", "P"]], [["context", "TV Playback"], ["action","PAUSE"]]); # default, but here for completeness + + # + # better awareness of different video extensions + # + change_or_make_entry("videotypes", [["playcommand", "mplayer-resumer.pl -fs -zoom -vc theora,fftheora, -vo xv %s"]], [["extension", "ogg"]]); + change_or_make_entry("videotypes", [["playcommand", "mplayer-resumer.pl -fs -zoom -vc theora,fftheora, -vo xv %s"]], [["extension", "theora"]]); + foreach my $video_ext ("mp2", "tp", "ts", "m2p", "nuv") { + change_or_make_entry("videotypes", [["playcommand", "Internal"]], [["extension", $video_ext]]); + } + foreach my $non_video_ext ("jpg", "par2") { + change_or_make_entry("videotypes", [["f_ignore", "1"]], [["extension", $non_video_ext]]); + } + + # + # games, game players, and emulators + # + my @players = ( + [ 'SDLMAME', '/myth/games/xmame/roms', '/myth/games/xmame/screenshots', '/usr/games/mame -rp /myth/games/xmame/roms %s', 'MAME' ], + [ 'ZSNES','/myth/games/snes/roms','/myth/games/snes/screens','/usr/bin/zsnes','SNES' ], + [ 'FCEU','/myth/games/nes/roms','/myth/games/nes/screens','/usr/games/fceu','NES' ], + [ 'Frozen Bubble', '', '', '/usr/games/frozen-bubble --fullscreen','PC' ] + ); + + foreach my $player (@players) { + # These INSERTs will fail if the playername is already present, but we don't error out if it happens. + do_query("INSERT INTO gameplayers (playername, rompath, screenshots, commandline, gametype) VALUES ('".join("','",@$player)."');"); + } + # somewhat hardwired, but make sure Frozen Bubble shows up in the list of playable games. + do_query("INSERT INTO gamemetadata (system, romname, gamename, genre, year, publisher, rompath, gametype) VALUES ('". + join("','",($players[3][0], $players[3][3], $players[3][0], "action/puzzle", "2006", "Frozen Bubble Team", "/usr/games", $players[3][4]))."');"); + + # + # smart music playlists + # + # categoryid, name + change_or_make_entry("music_smartplaylist_categories", [["name", "Decades"]], [["categoryid", 1]]); + change_or_make_entry("music_smartplaylist_categories", [["name", "Favorite Tracks"]], [["categoryid", 2]]); + change_or_make_entry("music_smartplaylist_categories", [["name", "New Tracks"]], [["categoryid", 3]]); + + foreach my $decade (60, 70, 80, 90, 100) { + my $id = ($decade / 10) - 5; + my $query = "INSERT INTO music_smartplaylist_items (smartplaylistid, field, operator, value1, value2) VALUES ($id, 'Year', 'is between'," . ($decade+1900) . "," . ($decade+1909) . ");"; + do_query($query); + $query = "INSERT INTO music_smartplaylists (name, categoryid, matchtype, orderby, limitto) VALUES ('". ($decade+1900) . "\\'s', 1, 'All', 'Artist (A)', 0);"; + do_query($query); + } + + my @other_lists = ( + [ + ( 'Rating', 'is greater than', '7', 'Favorite Tracks', 2, 'Artist (A), Album (A)', 0 ), + ( 'Play Count', 'is greater than', '0', '100 Most Played Tracks', 2, 'Play Count (D)', 100 ), + ( 'Play Count', 'is equal to', '0', 'Never Played Tracks', 3, 'Artist (A), Album (A)', 0 ) + ]); + + my $id=6; + foreach my $other_list (@other_lists) { + change_or_make_entry("music_smartplaylist_items", [["field", @$other_list[0]], ["operator", @$other_list[1]], ["value1", @$other_list[2]]], [["smartplaylistid", $id]]); + change_or_make_entry("music_smartplaylists", [["name", @$other_list[3]], ["categoryid", @$other_list[4]], ["matchtype", "All"], ["orderby", @$other_list[5]], ["limitto", @$other_list[6]]], [["smartplaylistid", $id]]); + $id++; + } + + # + # default playgroup with time-related settings + # + change_or_make_entry("playgroup", [["skipahead", 10], ["skipback", 5], ["timestretch", 100], ["jump", 1]], [["name", "Default"]]); + + # + # useful recording profiles and transcoding options + # + change_or_make_entry("profilegroups", [["name", "Software Encoders (v4l based)"], ["cardtype", "V4L"], ["is_default", 1]], [["id", 1]]); + change_or_make_entry("profilegroups", [["name", "MPEG-2 Encoders (PVR-x50, PVR-500)"], ["cardtype", "MPEG"], ["is_default", 1]], [["id", 2]]); + change_or_make_entry("profilegroups", [["name", "Hardware MJPEG Encoders (Matrox G200-TV, Miro DC10, etc)"], ["cardtype", "MJPEG"], ["is_default", 1]], [["id", 3]]); + change_or_make_entry("profilegroups", [["name", "Hardware HDTV"], ["cardtype", "HDTV"], ["is_default", 1]], [["id", 4]]); + change_or_make_entry("profilegroups", [["name", "Hardware DVB Encoders"], ["cardtype", "DVB"], ["is_default", 1]], [["id", 5]]); + change_or_make_entry("profilegroups", [["name", "Transcoders"], ["cardtype", "TRANSCODE"], ["is_default", 1]], [["id", 6]]); + change_or_make_entry("profilegroups", [["name", "FireWire Input"], ["cardtype", "FIREWIRE"], ["is_default", 1]], [["id", 7]]); + change_or_make_entry("profilegroups", [["name", "USB Mpeg-4 Encoder (Plextor ConvertX, etc)"], ["cardtype", "GO7007"], ["is_default", 1]], [["id", 8]]); + change_or_make_entry("profilegroups", [["name", "DBOX2 Input"], ["cardtype", "DBOX2"], ["is_default", 1]], [["id", 9]]); + change_or_make_entry("profilegroups", [["name", "Freebox Input"], ["cardtype", "Freebox"], ["is_default", 1]], [["id", 10]]); + change_or_make_entry("profilegroups", [["name", "HDHomeRun Recorders"], ["cardtype", "HDHOMERUN"], ["is_default", 1]], [["id", 11]]); + change_or_make_entry("profilegroups", [["name", "CRC IP Recorders"], ["cardtype", "CRC_IP"], ["is_default", 1]], [["id", 12]]); + + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'transcodelossless', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'transcoderesize', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'mpeg4bitrate', 2200)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'mpeg4maxquality', 2)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'mpeg4minquality', 15)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'mpeg4qualdiff', 3)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'scalebitrate', 1)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'mpeg4optionvhq', 1)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'mpeg4option4mv', 1)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'mpeg4optionidct', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'mpeg4optionime', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'encodingthreadcount', 1)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'mpeg2bitrate', 4500)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'hardwaremjpegquality', 100)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'hardwaremjpeghdecimation', 4)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'hardwaremjpegvdecimation', 4)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'mpeg2streamtype', 'MPEG-2 PS')"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'mpeg2maxbitrate', 6000)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'samplerate', 48000)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (21, 'volume', 100)"); + + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'transcodelossless', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'transcoderesize', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'mpeg4bitrate', 2200)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'mpeg4maxquality', 2)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'mpeg4minquality', 15)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'mpeg4qualdiff', 3)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'scalebitrate', 1)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'mpeg4optionvhq', 1)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'mpeg4option4mv', 1)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'mpeg4optionidct', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'mpeg4optionime', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'encodingthreadcount', 1)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'mpeg2bitrate', 4500)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'hardwaremjpegquality', 100)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'hardwaremjpeghdecimation', 4)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'hardwaremjpegvdecimation', 4)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'mpeg2streamtype', 'MPEG-2 PS')"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'mpeg2maxbitrate', 6000)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'samplerate', 48000)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (22, 'volume', 100)"); + + do_query("INSERT INTO codecparams (profile, name, value) VALUES (27, 'transcodelossless', 1)"); + + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'transcodelossless', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'transcoderesize', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'mpeg4bitrate', 2200)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'mpeg4maxquality', 2)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'mpeg4minquality', 15)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'mpeg4qualdiff', 3)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'scalebitrate', 1)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'mpeg4optionvhq', 1)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'mpeg4option4mv', 1)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'mpeg4optionidct', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'mpeg4optionime', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'encodingthreadcount', 1)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'mpeg2bitrate', 4500)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'hardwaremjpegquality', 100)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'hardwaremjpeghdecimation', 4)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'hardwaremjpegvdecimation', 4)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'mpeg2streamtype', 'MPEG-2 PS')"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'mpeg2maxbitrate', 6000)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'samplerate', 48000)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (28, 'volume', 100)"); + + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'transcodelossless', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'transcoderesize', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'mpeg4bitrate', 1500)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'mpeg4maxquality', 2)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'mpeg4minquality', 15)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'mpeg4qualdiff', 3)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'scalebitrate', 1)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'mpeg4optionvhq', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'mpeg4option4mv', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'mpeg4optionidct', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'mpeg4optionime', 0)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'encodingthreadcount', 1)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'mpeg2bitrate', 4500)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'hardwaremjpegquality', 100)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'hardwaremjpeghdecimation', 4)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'hardwaremjpegvdecimation', 4)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'mpeg2streamtype', 'MPEG-2 PS')"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'mpeg2maxbitrate', 6000)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'samplerate', 44100)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'mp3quality', 7)"); + do_query("INSERT INTO codecparams (profile, name, value) VALUES (29, 'volume', 100)"); + + # I don't know why we have so many of these. Only profilegroup 6 seems to matter. + change_or_make_entry("recordingprofiles", [["name", 'Default'], ["profilegroup", 1]], [["id", 1]]); + change_or_make_entry("recordingprofiles", [["name", 'Live TV'], ["profilegroup", 1]], [["id", 2]]); + change_or_make_entry("recordingprofiles", [["name", 'High Quality'], ["profilegroup", 1]], [["id", 3]]); + change_or_make_entry("recordingprofiles", [["name", 'Low Quality'], ["profilegroup", 1]], [["id", 4]]); + change_or_make_entry("recordingprofiles", [["name", 'Default'], ["profilegroup", 2]], [["id", 5]]); + change_or_make_entry("recordingprofiles", [["name", 'Live TV'], ["profilegroup", 2]], [["id", 6]]); + change_or_make_entry("recordingprofiles", [["name", 'High Quality'], ["profilegroup", 2]], [["id", 7]]); + change_or_make_entry("recordingprofiles", [["name", 'Low Quality'], ["profilegroup", 2]], [["id", 8]]); + change_or_make_entry("recordingprofiles", [["name", 'Default'], ["profilegroup", 3]], [["id", 9]]); + change_or_make_entry("recordingprofiles", [["name", 'Live TV'], ["profilegroup", 3]], [["id", 10]]); + change_or_make_entry("recordingprofiles", [["name", 'High Quality'], ["profilegroup", 3]], [["id", 11]]); + change_or_make_entry("recordingprofiles", [["name", 'Low Quality'], ["profilegroup", 3]], [["id", 12]]); + change_or_make_entry("recordingprofiles", [["name", 'Default'], ["profilegroup", 4]], [["id", 13]]); + change_or_make_entry("recordingprofiles", [["name", 'Live TV'], ["profilegroup", 4]], [["id", 14]]); + change_or_make_entry("recordingprofiles", [["name", 'High Quality'], ["profilegroup", 4]], [["id", 15]]); + change_or_make_entry("recordingprofiles", [["name", 'Low Quality'], ["profilegroup", 4]], [["id", 16]]); + change_or_make_entry("recordingprofiles", [["name", 'Default'], ["profilegroup", 5]], [["id", 17]]); + change_or_make_entry("recordingprofiles", [["name", 'Live TV'], ["profilegroup", 5]], [["id", 18]]); + change_or_make_entry("recordingprofiles", [["name", 'High Quality'], ["profilegroup", 5]], [["id", 19]]); + change_or_make_entry("recordingprofiles", [["name", 'Low Quality'], ["profilegroup", 5]], [["id", 20]]); + change_or_make_entry("recordingprofiles", [["name", 'RTjpeg/MPEG4'], ["profilegroup", 6], ["videocodec", "MPEG-4"], ["audiocodec", "Uncompressed"]], [["id", 21]]); + change_or_make_entry("recordingprofiles", [["name", 'MPEG2'], ["profilegroup", 6], ["videocodec", "MPEG-4"], ["audiocodec", "Uncompressed"]], [["id", 22]]); + change_or_make_entry("recordingprofiles", [["name", 'Default'], ["profilegroup", 8]], [["id", 23]]); + change_or_make_entry("recordingprofiles", [["name", 'Live TV'], ["profilegroup", 8]], [["id", 24]]); + change_or_make_entry("recordingprofiles", [["name", 'High Quality'], ["profilegroup", 8]], [["id", 25]]); + change_or_make_entry("recordingprofiles", [["name", 'Low Quality'], ["profilegroup", 8]], [["id", 26]]); + change_or_make_entry("recordingprofiles", [["name", 'High Quality'], ["profilegroup", 6]], [["id", 27]]); + change_or_make_entry("recordingprofiles", [["name", 'Medium Quality'], ["profilegroup", 6], ["videocodec", "MPEG-4"], ["audiocodec", "Uncompressed"]], [["id", 28]]); + change_or_make_entry("recordingprofiles", [["name", 'Low Quality'], ["profilegroup", 6], ["videocodec", "MPEG-4"], ["audiocodec", "MP3"]], [["id", 29]]); + change_or_make_entry("recordingprofiles", [["name", 'Default'], ["profilegroup", 10]], [["id", 30]]); + change_or_make_entry("recordingprofiles", [["name", 'Live TV'], ["profilegroup", 10]], [["id", 31]]); + change_or_make_entry("recordingprofiles", [["name", 'High Quality'], ["profilegroup", 10]], [["id", 32]]); + change_or_make_entry("recordingprofiles", [["name", 'Low Quality'], ["profilegroup", 10]], [["id", 33]]); + change_or_make_entry("recordingprofiles", [["name", 'Default'], ["profilegroup", 11]], [["id", 34]]); + change_or_make_entry("recordingprofiles", [["name", 'Live TV'], ["profilegroup", 11]], [["id", 35]]); + change_or_make_entry("recordingprofiles", [["name", 'High Quality'], ["profilegroup", 11]], [["id", 36]]); + change_or_make_entry("recordingprofiles", [["name", 'Low Quality'], ["profilegroup", 11]], [["id", 37]]); + change_or_make_entry("recordingprofiles", [["name", 'Default'], ["profilegroup", 12]], [["id", 38]]); + change_or_make_entry("recordingprofiles", [["name", 'Live TV'], ["profilegroup", 12]], [["id", 39]]); + change_or_make_entry("recordingprofiles", [["name", 'High Quality'], ["profilegroup", 12]], [["id", 40]]); + change_or_make_entry("recordingprofiles", [["name", 'Low Quality'], ["profilegroup", 12]], [["id", 41]]); + change_or_make_entry("recordingprofiles", [["name", 'Default'], ["profilegroup", 7]], [["id", 42]]); + change_or_make_entry("recordingprofiles", [["name", 'Live TV'], ["profilegroup", 7]], [["id", 43]]); + change_or_make_entry("recordingprofiles", [["name", 'High Quality'], ["profilegroup", 7]], [["id", 44]]); + change_or_make_entry("recordingprofiles", [["name", 'Low Quality'], ["profilegroup", 7]], [["id", 45]]); + change_or_make_entry("recordingprofiles", [["name", 'Default'], ["profilegroup", 9]], [["id", 46]]); + change_or_make_entry("recordingprofiles", [["name", 'Live TV'], ["profilegroup", 9]], [["id", 47]]); + change_or_make_entry("recordingprofiles", [["name", 'High Quality'], ["profilegroup", 9]], [["id", 48]]); + change_or_make_entry("recordingprofiles", [["name", 'Low Quality'], ["profilegroup", 9]], [["id", 49]]); + + # + # settings + # + change_or_make_setting('AutoCommercialSkip', '1'); + change_or_make_setting('AutoExpireWatchedPriority', '1'); + change_or_make_setting('BackendServerPort', '6543'); + change_or_make_setting('BackendStatusPort', '6544'); + change_or_make_setting('CDWriterDevice', 'ATA:1,0,0'); +# change_or_make_setting('ChannelOrdering', 'chanid'); + change_or_make_setting('CommercialSkipMethod', '255'); + change_or_make_setting('DVDBookmarkPrompt', '1'); + change_or_make_setting('DVDPlayerCommand', 'xine -pfhq --no-splash dvd:\/\/'); + change_or_make_setting('DVDRipLocation', $SQL_DirTmp); + change_or_make_setting('DefaultRipQuality', '1'); + change_or_make_setting('DefaultTranscoder', '28'); # change this number if you redefine the transcoders above + change_or_make_setting('Deinterlace', '1'); + change_or_make_setting('EITCrawIdleStart','60'); + change_or_make_setting('EITIgnoresSource','0'); + change_or_make_setting('EITTimeOffset','Auto'); + change_or_make_setting('EITTransportTimeout','5'); + change_or_make_setting('EPGEnableJumpToChannel','1'); + change_or_make_setting('EPGFillType','12'); + change_or_make_setting('EnableDVDBookmark','1'); + change_or_make_setting('EndOfRecordingExitPrompt','1'); + change_or_make_setting('GalleryDir', $SQL_DirPics); + change_or_make_setting('GalleryRecursiveSlideshow', '1'); + change_or_make_setting('HaltCommand', 'sudo halt'); + change_or_make_setting('JobAllowCommFlag', '1'); + change_or_make_setting('JobAllowTranscode', '1'); + change_or_make_setting('JobAllowUserJob1', '1'); + change_or_make_setting('JobAllowUserJob2', '2'); + change_or_make_setting('JobQueueCPU','0'); + change_or_make_setting('JobQueueCheckFrequency','60'); + change_or_make_setting('JobQueueCommFlagCommand','mythcommflag'); + change_or_make_setting('JobQueueMaxSimultaneousJobs','1'); + change_or_make_setting('JobQueueTranscodeCommand','mythtranscode'); + change_or_make_setting('JobQueueWindowEnd','23:59'); + change_or_make_setting('JobQueueWindowStart','00:00'); + change_or_make_setting('JobsRunOnRecordHost','0'); + change_or_make_setting('LiveTVInAllPrograms','1'); + change_or_make_setting('MediaChangeEvents','1'); + change_or_make_setting('MonitorDrives', '1'); + change_or_make_setting('MusicLocation', $SQL_DirMusic); + change_or_make_setting('MythArchivePng2yuvCmd', 'png2yuv'); # ??? still used? + change_or_make_setting('MythArchiveShareDir','/myth/archive/'); + change_or_make_setting('MythArchiveTempDir', $SQL_DirTmp); + change_or_make_setting('MythFillDatabaseArgs', '--quiet'); + change_or_make_setting('MythFillDatabaseLog', '/var/log/mythtv/mythfilldatabase.log'); + change_or_make_setting('MythFillDatabasePath', '/usr/bin/nice -n 19 /usr/bin/mythfilldatabase'); + change_or_make_setting('MythFillEnabled', '1'); + change_or_make_setting('MythTVtv', $SQL_DirTV); + change_or_make_setting('PVR350VideoDev', '/dev/video16'); + change_or_make_setting('PlayBoxShading', '0'); + change_or_make_setting('PlayMode', 'none'); + change_or_make_setting('PlaybackExitPrompt', '2'); + change_or_make_setting('PlaybackPreviewLowCPU', '1'); +# change_or_make_setting('PlaybackReturnPrompt', '1'); +# change_or_make_setting('PlaybackReturnPrompt', '2'); + change_or_make_setting('RecordFilePrefix',$SQL_DirTV); + change_or_make_setting('SelectChangesChannel', '1'); + change_or_make_setting('ShowWholeTree', '1'); + change_or_make_setting('SmartChannelChange', '1'); + change_or_make_setting('TruncateDeletesSlowly', '1'); + change_or_make_setting('UserJob1', 'myth2ipod -cut \"%DIR%\" \"%FILE%\"'); + change_or_make_setting('UserJob2', 'myt2xvid3 -cut \"%DIR%\" \"%FILE%\"'); + change_or_make_setting('UserJobDesc1', 'Encode for iPod'); + change_or_make_setting('UserJobDesc2', 'Transcode to XviD'); + change_or_make_setting('UserJobDesc3', 'User Job #3'); + change_or_make_setting('UserJobDesc4', 'User Job #4'); + change_or_make_setting('VCDPlayerCommand', 'xine -pfhq --no-splash vcd://'); + change_or_make_setting('VideoArtworkDir', "$SQL_DirVideo/.covers"); + change_or_make_setting('VideoBrowserNoDB', '1'); + change_or_make_setting('VideoDefaultPlayer', 'mplayer-resumer.pl -fs -zoom -vo xv %s'); + change_or_make_setting('VideoGalleryNoDB', '1'); + change_or_make_setting('VideoStartupDir', $SQL_DirVideo); + change_or_make_setting('VideoTreeNoDB', '1'); + change_or_make_setting('VisualMode','BumpScope;Gears;Goom;MonoScope;Squares;StereoScope;Synaesthesia;LibVisual-bumpscope;LibVisual-corona;LibVisual-infinite;LibVisual-jakdaw;LibVisual-jess;AlbumArt'); + change_or_make_setting('weatherbackgroundfetch', '1'); + change_or_make_setting('WebBrowserCommand','/usr/bin/mythbrowser'); + change_or_make_setting('WebBrowserHideScrollbars','0'); + change_or_make_setting('WebBrowserScrollMode','1'); + change_or_make_setting('WebBrowserScrollSpeed','4'); + change_or_make_setting('WebBrowserZoomLevel','20'); + change_or_make_setting('WebcamDevice','/dev/video'); + change_or_make_setting('blockSDWUwithoutClient','1'); + change_or_make_setting('mythdvd.DVDPlayerCommand', 'xine -pfhq --no-splash dvd://'); + change_or_make_setting('mythvideo.VideoTreeRemember', '1'); + change_or_make_setting('mythfilldatabaseLastRunStart',''); + change_or_make_setting('mythfilldatabaseLastRunEnd',''); + change_or_make_setting('mythfilldatabaseLastRunStatus',''); + + + +# # As much of MythWeather as we can automate for now + my $units = 0; + my $metric_units = do_query("SELECT * FROM settings WHERE value='SIUnits' AND data='YES'"); + if ($metric_units) { + $units=0; + } else { + $units=1; + } +# change_or_make_entry("weatherscreens", [["draworder", "0"], ["container", "Six Day Forecast"], ["units", $units]], [["screen_id", 1]]); +# change_or_make_entry("weatherdatalayout", [["location", "0"], ["dataitem", "6dlocation"], ["weatherscreens_screen_id", 1]], [["weathersourcesettings_sourceid", 4]]); +# for (my $increment=0; $increment < 6; $increment++) { +# change_or_make_entry("weatherdatalayout", [["location", "0"], ["dataitem", "date-$increment"], ["weatherscreens_screen_id", 1]], [["weathersourcesettings_sourceid", 4]]); +# change_or_make_entry("weatherdatalayout", [["location", "0"], ["dataitem", "high-$increment"], ["weatherscreens_screen_id", 1]], [["weathersourcesettings_sourceid", 4]]); +# change_or_make_entry("weatherdatalayout", [["location", "0"], ["dataitem", "icon-$increment"], ["weatherscreens_screen_id", 1]], [["weathersourcesettings_sourceid", 4]]); +# change_or_make_entry("weatherdatalayout", [["location", "0"], ["dataitem", "low-$increment"], ["weatherscreens_screen_id", 1]], [["weathersourcesettings_sourceid", 4]]); +# } +# change_or_make_entry("weatherdatalayout", [["location", "0"], ["dataitem", "updatetime"], ["weatherscreens_screen_id", 1]], [["weathersourcesettings_sourceid", 4]]); +# +# change_or_make_entry("weathersourcesettings", [["sourceid", "1"], ["source_name", "BBC-Current-XML"], ["update_timeout", "7200"], ["retrieve_timeout", "30"], ["path", "/usr/share/mythtv/mythweather/scripts/bbccurrentxml.pl"], ["author", "Stuart Morgan"], ["version", "0.1"], ["email", "stuart\@tase.co.uk"], ["types", "cclocation,station_id,copyright,observation_time,weather,temp,relative_humidity,wind_dir,pressure,visibility,weather_icon,appt,wind_spdgst"]]); +# change_or_make_entry("weathersourcesettings", [["sourceid", "2"], ["source_name", "BBC-3day-XML"], ["update_timeout", "21600"], ["retrieve_timeout", "30"], ["path", "/usr/share/mythtv/mythweather/scripts/bbcthreedayxml.pl"], ["author", "Stuart Morgan"], ["version", "0.1"], ["email", "stuart\@tase.co.uk"], ["types", "3dlocation,station_id,copyright,weather_icon,date-0,icon-0,low-0,high-0,date-1,icon-1,low-1,high-1,date-2,icon-2,low-2,high-2,updatetime"]]); +# change_or_make_entry("weathersourcesettings", [["sourceid", "3"], ["source_name", "ENVCAN"], ["update_timeout", "900"], ["retrieve_timeout", "30"], ["path", "/usr/share/mythtv/mythweather/scripts/ca_envcan/envcan.pl"], ["author", "Joe Ripley"], ["version", "0.4"], ["email", "vitaminjoe\@gmail.com"], ["types", "cclocation,station_id,copyright,observation_time,observation_time_rfc822,weather,temp,relative_humidity,wind_dir,wind_degrees,wind_speed,wind_gust,pressure,dewpoint,heat_index,windchill,visibility,weather_icon,appt,wind_spdgst,3dlocation,6dlocation,date-0,icon-0,low-0,high-0,date-1,icon-1,low-1,high-1,date-2,icon-2,low-2,high-2,updatetime,date-3,icon-3,low-3,high-3,date-4,icon-4,low-4,high-4,date-5,icon-5,low-5,high-5"]]); +# change_or_make_entry("weathersourcesettings", [["sourceid", "4"], ["source_name", "NDFD-6_day"], ["update_timeout", "900"], ["retrieve_timeout", "30"], ["path", "/usr/share/mythtv/mythweather/scripts/ndfd.pl"], ["author", "Lucien Dunning"], ["version", "0.1"], ["email", "ldunning\@gmail.com"], ["types", "3dlocation,6dlocation,updatetime,high-0,high-1,high-2,high-3,high-4,high-5,low-0,low-1,low-2,low-3,low-4,low-5,icon-0,icon-1,icon-2,icon-3,icon-4,icon-5,date-0,date-1,date-2,date-3,date-4,date-5"]]); +# change_or_make_entry("weathersourcesettings", [["sourceid", "5"], ["source_name", "NDFD-18_hour"], ["update_timeout", "900"], ["retrieve_timeout", "30"], ["path", "/usr/share/mythtv/mythweather/scripts/ndfd18.pl"], ["author", "Lucien Dunning"], ["version", "0.1"], ["email", "ldunning\@gmail.com"], ["types", "18hrlocation,updatetime,temp-0,temp-1,temp-2,temp-3,temp-4,temp-5,18icon-0,18icon-1,18icon-2,18icon-3,18icon-4,18icon-5,pop-0,pop-1,pop-2,pop-3,pop-4,pop-5,time-0,time-1,time-2,time-3,time-4,time-5"]]); +# change_or_make_entry("weathersourcesettings", [["sourceid", "6"], ["source_name", "NWS-Alerts"], ["update_timeout", "600"], ["retrieve_timeout", "30"], ["path", "/usr/share/mythtv/mythweather/scripts/nws-alert.pl"], ["author", "Lucien Dunning"], ["version", "0.1"], ["email", "ldunning\@gmail.com"], ["types", "swlocation,updatetime,alerts"]]); +# change_or_make_entry("weathersourcesettings", [["sourceid", "7"], ["source_name", "NWS-XML"], ["update_timeout", "900"], ["retrieve_timeout", "30"], ["path", "/usr/share/mythtv/mythweather/scripts/nwsxml.pl"], ["author", "Lucien Dunning"], ["version", "0.2"], ["email", "ldunning\@gmail.com"], ["types", "cclocation,station_id,latitude,longitude,observation_time,observation_time_rfc822,weather,temperature_string,temp,relative_humidity,wind_string,wind_dir,wind_degrees,wind_speed,wind_gust,pressure_string,pressure,dewpoint_string,dewpoint,heat_index_string,heat_index,windchill_string,windchill,visibility,weather_icon,appt,wind_spdgst"]]); + + my $ipaddress = execute_shell_command("ifconfig | grep inet.addr | head -1"); + $ipaddress =~ s/.*inet addr:(\d+.\d+.\d+.\d+)\s.*/$1/g; + + # Change from the generic IP address to the real one. + do_query("UPDATE settings SET data='$ipaddress' where data='127.0.0.1'"); + do_query("UPDATE settings SET data='$ipaddress' where data='MythTVip'"); # ??? needed? + + my $hostname = execute_shell_command("hostname") || "localhost"; + # one table at a time, replace hostname with our actual hostname + # ??? can this be done all at once in MySQL? + foreach my $table ("capturecard", "inuseprograms", "jobqueue", "jumppoints", "keybindings", "music_playlists", + "musicplaylist", "recorded", "settings", "weatherscreens") { + do_query("UPDATE $table SET hostname='$hostname'"); + } + + # Some entries in 'settings' should stay NULL: http://www.mythtv.org/wiki/index.php/Settings_table + # There are fewer entries that stay NULL than there are that should have the hostname set, so while + # it duplicates some effort to change them from NULL to the hostname and them back to NULL, it's + # easier to maintain and more future-proof. + foreach my $entry ("mythfilldatabaseLastRunStart", "mythfilldatabaseLastRunEnd", "mythfilldatabaseLastRunStatus", + "DataDirectMessage", "HaveRepeats", "DBSchemaVer", "DefaultTranscoder", "MythFillSuggestedRunTime", + "MythFillGrabberSuggestsTime", "MasterServerIP", "MasterServerPort", "TVFormat", "VbiFormat", "FreqTable", + "TimeOffset", "MasterBackendOverride", "DeletesFollowLinks", "HDRingbufferSize", "EITTransportTimeout", + "EITIgnoresSource", "EITCrawIdleStart", "startupCommand", "blockSDWUwithoutClient", "idleWaitForRecordingTime", + "StartupSecsBeforeRecording", "WakeupTimeFormat", "SetWakeuptimeCommand", "ServerHaltCommand", "preSDWUCheckCommand", + "WOLbackendConnectRetry", "WOLbackendCommand", "WOLslaveBackendsCommand", "JobsRunOnRecordHost", + "AutoCommflagWhileRecording", "JobQueueCommFlagCommand", "JobQueueTranscodeCommand", + "AutoTranscodeBeforeAutoCommflag", "SaveTranscoding", "UserJobDesc1", "UserJob1", "UserJobDesc2", "UserJob2", + "UserJobDesc3", "UserJob3", "UserJobDesc4", "UserJob4", "PreviewPixmapOffset", "AllRecGroupPassword", + "MaximumCommercialSkip", "CommSkipAllBlanks", "LastFreeCard", "LiveTVPriority", "AutoExpireMethod", + "AutoExpireDefault", "RerecordWatched", "AutoExpireWatchedPriority", "AutoExpireLiveTVMaxAge", + "AutoExpireDayPriority", "AutoExpireExtraSpace", "AutoExpireInsteadOfDelete", "DeletedFifoOrder", + "CommercialSkipMethod", "AggressiveCommDetect", "AutoCommercialFlag", "AutoTranscode", "AutoRunUserJob1", + "AutoRunUserJob2", "AutoRunUserJob3", "AutoRunUserJob4", "OverTimeCategory", "CategoryOverTime", + "EPGEnableJumpToChannel", "LogEnabled", "MythFillEnabled", "MythFillDatabasePath", "MythFillDatabaseArgs", + "MythFillDatabaseLog", "MythFillPeriod", "MythFillMinHour", "MythFillMaxHour", "SchedMoveHigher", "SchedOpenEnd", + "ComplexPriority", "PrefInputPriority", "SingleRecordRecPriority", "FindOneRecordRecPriority", "ArchiveDBSchemaVer", + "FlixDBSchemaVer", "GalleryDBSchemaVer", "GameDBSchemaVer", "MusicDBSchemaVer", "PhoneDBSchemaVer", + "mythvideo.DBSchemaVer", "WeatherDBSchemaVer") { + do_query("UPDATE settings SET hostname=NULL WHERE value='$entry'"); + } + + change_or_make_setting('MasterBackendOverride','1'); # I don't remember why, but making the hostname NULL is important here + do_query("UPDATE settings SET hostname=NULL WHERE value='MasterBackendOverride'"); + + # storagegroup + change_or_make_entry("storagegroup", [["groupname", "Default"], ["hostname", $hostname], ["dirname", $SQL_DirTV]], [["id", 1]]); + + disconnect_from_db(); + + # Fix hostname for iPod feed URLs + $command = "sed -i \"s/hostname\\//$hostname\\//g\" /usr/local/bin/myth2ipod"; + execute_shell_command($command); + + # Fix hostname for XViD feed URLs + $command = "sed -i \"s/192.168.0.222\\//$hostname\\//g\" /usr/local/bin/myt2xvid3"; + execute_shell_command($command); + + # Customize default MythTV library.xml to reflect KnoppMyth's wider selection of + # online stream options. + #$command = "sed -i \"/<type>STREAM<\\/type>\$/{N; N; N; N; s/text>.*<\\/text/text>Online Streams<\\/text/; s/action>.*<\\/action/action>MENU is.xml<\\/action/; s/<depends.*depends>//; }\" /usr/share/mythtv/library.xml"; + $command = "/bin/cp /usr/share/mythtv/library.xml.km /usr/share/mythtv/library.xml"; + execute_shell_command($command); + + } else { + my $logger = get_logger('tweaker.script'); + $logger->error("Unable to connect to mythconverg database"); + $logger->error("Unable to implement option $option."); + return -1; + } + return 1; + } + + file_tweaks($option) || exit -1; + SQL_tweaks($option) || exit -1; +} + +# Try to get a Recommendation Level for $option. +sub poll_options { + my($option) = @_; + recommendation_level("recommended", "These tweaks benefit all users."); +} + +# Unimplemented in 0.7 +sub check_option { + help; +} + +# Unimplemented in 0.7 +sub count_iterations { + help; +} + +process_parameters; diff --git a/abs/core-testing/tweaker/bin/twk_graphics.pl b/abs/core-testing/tweaker/bin/twk_graphics.pl new file mode 100755 index 0000000..b2fdb17 --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_graphics.pl @@ -0,0 +1,149 @@ +#!/usr/bin/perl -w + +# Copyright 2007, 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +use Switch; +use Tweaker::Script; +package Tweaker::Script; + +# List all the options that this script supports. Make sure it matches what's in +# the corresponding .tcf entry. +set_known_options( 'low', 'medium', 'high' ); + +sub check_for_GL() { + # ??? Need to make this update a class variable instead of a temp file. + my $fps = execute_shell_command("[ -e /tmp/fps ] && cat /tmp/fps") || -1; + + # We think that any nVidia cards at or below NV25 are not well-supported + # for GL. Newer cards are NV34 or above, or have a different starting letter. + my $generation = execute_shell_command("lspci -v | grep \"nVidia Corporation\" | grep VGA | awk -FCorporation '{ print \$2 }' | awk '{ print \$1 }'"); + my $letters = substr($generation,0,2); + if (("$letters" eq "NV") && ("$generation" lt "NV24")) { + $fps = 0; + } + + if ($fps == -1) { + my $result = execute_shell_command("glxinfo | grep 'direct rendering'"); + if ($result =~ m/direct rendering: Yes/) { + my $logger = get_logger('tweaker.script'); + $logger->info("Hardware OpenGL rendering ability detected."); + # Now poll the strength, returning the FPS from glxgears, run at the default resolution. + # I would love to be able to poll this in a way that 1) doesn't pop up a GUI window and + # 2) doesn't rely on manually making a database that maps video cards to performance levels. + $result = execute_shell_command("script -q -c \"glxgears -fullscreen & sleep 11 ; pkill -15 glxgears\" | tail -1"); + if ($result =~ m/ (\d+)\.\d+ FPS/) { + $fps = $1; + execute_shell_command("echo $fps > /tmp/fps"); + } + } else { + $fps = 0; + execute_shell_command("echo $fps > /tmp/fps"); + } + } + return $fps; +} + +# Try to implement the given option. +sub implement_option { + my($option) = @_; + + $dbconnectionstring = get_mythtv_connection_string(); + + if (connect_to_db("DBI:mysql:$dbconnectionstring")) { + switch ($option) { + # List all the options that this script supports. You can have as many as you like. + case "low" { + change_or_make_setting('ThemePainter', 'Qt') || exit -1; + change_or_make_setting('SlideshowUseOpenGL', '0') || exit -1; + change_or_make_setting('SlideshowOpenGLTransition', 'none') || exit -1; + change_or_make_setting('SlideshowTransition', 'none') || exit -1; + } + case "medium" { + change_or_make_setting('ThemePainter', 'Qt') || exit -1; + change_or_make_setting('SlideshowUseOpenGL', '1') || exit -1; + change_or_make_setting('SlideshowOpenGLTransition', 'random (gl)') || exit -1; + change_or_make_setting('SlideshowTransition', 'random') || exit -1; + } + case "high" { + change_or_make_setting('ThemePainter', 'opengl') || exit -1; + change_or_make_setting('SlideshowUseOpenGL', '1') || exit -1; + change_or_make_setting('SlideshowOpenGLTransition', 'random (gl)') || exit -1; + change_or_make_setting('SlideshowTransition', 'random') || exit -1; + } + + # In all cases, do the following: + + # enable anti-aliased fonts + my $qtrc="/home/mythtv/.qt/qtrc"; + # clean out old Xft settings + my $command = "sed -i 's/.*Xft=.*//g' $qtrc"; + + if (my $error = execute_shell_command($command)) { + my $logger = get_logger('tweaker.script'); + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } else { + # Add Xft settings + my $command = "sed -i 's/embedFonts=true/embedFonts=true\nenableXft=true\nuseXft=true/g' $qtrc"; + if (my $error = execute_shell_command($command)) { + my $logger = get_logger('tweaker.script'); + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } else { + # Make sure to use an AA-capable font + my $command = "sed -i 's/font=.*/font=Sans Serif,12,-1,5,50,0,0,0,0,0/g' $qtrc"; + if (my $error = execute_shell_command($command)) { + my $logger = get_logger('tweaker.script'); + $logger->error("ERROR: $error"); + $logger->error("ERROR: Unable to implement option $option."); + exit(-1); + } + } + } + } + } else { + exit -1; + } + disconnect_from_db(); +} + +# Poll the system to see what recommendationlevel the given option has on the system. +sub poll_options { + my($option) = @_; + + # These are somewhat arbitrary at this point. Note that they correspond to + # _full screen_ glxgears results in Frames Per Second (FPS), since GL is used + # at full screen resolution in MythTV. + my $low_threshold = 350; # at or below $low_threshold FPS, GL is not considered good enough to use in MythTV + my $medium_threshold = 425; # GL is pretty usable here + my $high_threshold = 500; + + threshold_test($option, check_for_GL(), "video card", $low_threshold, $medium_threshold, $high_threshold); +} + +# Unimplemented in 0.7 +sub check_option { + help; +} + +# Unimplemented in 0.7 +sub count_iterations { + help; +} + +process_parameters; diff --git a/abs/core-testing/tweaker/bin/twk_keymap.sh b/abs/core-testing/tweaker/bin/twk_keymap.sh new file mode 100755 index 0000000..41341bf --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_keymap.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +# Copyright 2007, 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +# This script is called from twk_general.pl to implement keymap standardization in KnoppMyth + +KNOPPMYTH_SHARE=/usr/local/share/knoppmyth + +#################### +# Unify key mappings +#################### + +# Universal keybindings: +# Function Remote Key Keyboard Key +# ------------------------------------------ +# Skip Back << PgUp +# Skip Forward >> PgDn +# Play |> l +# Pause || p +# Stop [] ESC + +#Make xine use keymappings that get along with mplayer, MythMusic, and ATI remote button mappings. +#NOTE: "Prior" is PageUp and "Next" is PageDown +if [[ -f $MYTH_HOME/.xine/keymap ]]; then + sed -i "/Mute {$/{N; s/key = .*/key = VOID/; }" $MYTH_HOME/.xine/keymap + sed -i "/MrlBrowser {$/{N; s/key = .*/key = VOID/; }" $MYTH_HOME/.xine/keymap + sed -i "/NextMrl {$/{N; s/key = .*/key = VOID/; }" $MYTH_HOME/.xine/keymap + sed -i "/PriorMrl {$/{N; s/key = .*/key = VOID/; }" $MYTH_HOME/.xine/keymap + sed -i "/AudioVideoDecay+ {$/{N; s/key = .*/key = VOID/; }" $MYTH_HOME/.xine/keymap + sed -i "/ToggleLoopMode {$/{N; s/key = .*/key = VOID/; }" $MYTH_HOME/.xine/keymap + sed -i "/PlaylistStop {$/{N; s/key = .*/key = VOID/; }" $MYTH_HOME/.xine/keymap + sed -i "/Mute {$/{N; N; s/modifier = .*/modifier = none/; }" $MYTH_HOME/.xine/keymap + sed -i "/Quit {$/{N; s/key = .*/key = Escape/; }" $MYTH_HOME/.xine/keymap + sed -i "/^Menu {$/{N; s/key = .*/key = m/; }" $MYTH_HOME/.xine/keymap + sed -i "/Play {$/{N; s/key = .*/key = l/; }" $MYTH_HOME/.xine/keymap + sed -i "/Pause {$/{N; s/key = .*/key = p/; }" $MYTH_HOME/.xine/keymap + sed -i "/SeekRelative+60 {$/{N; s/key = .*/key = Next/; }" $MYTH_HOME/.xine/keymap + sed -i "/SeekRelative-60 {$/{N; s/key = .*/key = Prior/; }" $MYTH_HOME/.xine/keymap + sed -i "/Volume+ {$/{N; s/key = .*/key = ]/; }" $MYTH_HOME/.xine/keymap + sed -i "/Volume- {$/{N; s/key = .*/key = [/; }" $MYTH_HOME/.xine/keymap +else + mkdir -p $MYTH_HOME/.xine/ + /bin/cp $KNOPPMYTH_SHARE/xine_keymap $MYTH_HOME/.xine/keymap +fi +chown -fR mythtv:mythtv $MYTH_HOME/.xine + + +#Make mplayer use keymappings that get along with xine, MythMusic, and ATI remote button mappings. +#NOTE: PGUP is PageUp and PGDWN is PageDown +if [[ -f $MYTH_HOME/.mplayer/input.conf ]]; then + sed -i "s/^PGUP .*/PGUP seek -60/" $MYTH_HOME/.mplayer/input.conf + sed -i "s/^PGDWN .*/PGDWN seek +60/" $MYTH_HOME/.mplayer/input.conf + sed -i "s/^p .*/p pause/" $MYTH_HOME/.mplayer/input.conf + sed -i "s/^l .*/l pause/" $MYTH_HOME/.mplayer/input.conf +else + mkdir -p $MYTH_HOME/.mplayer/ + /bin/cp $KNOPPMYTH_SHARE/mplayer_keymap $MYTH_HOME/.mplayer/input.conf +fi +chown -fR mythtv:mythtv $MYTH_HOME/.mplayer + +echo "Tweaked keymap"
\ No newline at end of file diff --git a/abs/core-testing/tweaker/bin/twk_linux.pl b/abs/core-testing/tweaker/bin/twk_linux.pl new file mode 100755 index 0000000..107b4d9 --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_linux.pl @@ -0,0 +1,65 @@ +#!/usr/bin/perl -w + +# Copyright 2007, 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +use Switch; +use Tweaker::Script; +package Tweaker::Script; + +set_known_options( 'all' ); + +# Try to implement the given option. +sub implement_option { + my($option) = @_; + + my $command; + my $apacheconf = "/etc/apache2/apache2.conf"; + # Linux-centric tweaks + + my @commands = ( + # erases any previous ServerName and adds a new one + "sed -i 's/ServerName.*//g' $apacheconf && echo -n \"ServerName \" >> $apacheconf && hostname >> $apacheconf", + # make autofs run automatically + "/etc/init.d/autofs stop && /etc/init.d/autofs start && /usr/sbin/update-rc.d -f autofs remove && /usr/sbin/update-rc.d autofs start 45 3 5 .", + # set up NTP + "/etc/init.d/ntp restart && /usr/sbin/update-rc.d -f ntp remove && /usr/sbin/update-rc.d ntp defaults 85" + ); + + foreach my $command (@commands) { + if (my $result = execute_shell_command($command)) { + my $logger = get_logger('tweaker.script'); + $logger->info("result: $result"); + } + } +} + +# Try to get a Recommendation Level for $option. +sub poll_options { + my($option) = @_; + recommendation_level("recommended", "These tweaks benefit all users."); +} + +# Unimplemented in 0.7 +sub check_option { + help; +} + +# Unimplemented in 0.7 +sub count_iterations { + help; +} + +process_parameters; diff --git a/abs/core-testing/tweaker/bin/twk_localization.pl b/abs/core-testing/tweaker/bin/twk_localization.pl new file mode 100755 index 0000000..f517ff4 --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_localization.pl @@ -0,0 +1,70 @@ +#!/usr/bin/perl -w + +# Copyright 2007, 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +use Switch; +use Tweaker::Script; +package Tweaker::Script; + +set_known_options( 'US_English', 'GB_English' ); # Should eventually expand to handle all translations available for MythTV. + +# Try to implement the given option. +sub implement_option { + my($option) = @_; + + $dbconnectionstring = get_mythtv_connection_string(); + + if (connect_to_db("DBI:mysql:$dbconnectionstring")) { + # The entire planet except the US uses metric measurements. + change_or_make_setting('SIUnits', 'YES') || exit -1; + switch ($option) { + case "US_English" { + # Uses Imperial measurements for things like weather. + change_or_make_setting('SIUnits', 'NO') || exit -1; + change_or_make_setting('Language', 'EN') || exit -1; + change_or_make_setting('ISO639Language0', 'eng') || exit -1; + change_or_make_setting('ISO639Language1', 'eng') || exit -1; + } + case "GB_English" { + change_or_make_setting('Language', 'EN_GB') || exit -1; + change_or_make_setting('ISO639Language0', 'eng') || exit -1; + change_or_make_setting('ISO639Language1', 'eng') || exit -1; + } + } + } else { + exit -1; + } + disconnect_from_db(); +} + +# Try to get a Recommendation Level for $option. +sub poll_options { + my($option) = @_; + + recommendation_level("optional", "We don't yet have any way to know what your preferred language is. This option is as valid as any other."); +} + +# Unimplemented in 0.7 +sub check_option { + help; +} + +# Unimplemented in 0.7 +sub count_iterations { + help; +} + +process_parameters; diff --git a/abs/core-testing/tweaker/bin/twk_misc.pl b/abs/core-testing/tweaker/bin/twk_misc.pl new file mode 100755 index 0000000..96771a6 --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_misc.pl @@ -0,0 +1,13 @@ +# Placeholder for tweaks not yet implemented + +# Screen size / viewing distance +change_or_make_setting('chanPerPage', '4') || exit -1; +change_or_make_setting('timePerPage', '3') || exit -1; + +# Disk space / sound quality / compatibility +change_or_make_setting('DefaultRipQuality', '2') || exit -1; +change_or_make_setting('Mp3UseVBR', '1') || exit -1; + +# Localization / tuner type +# N. America +change_or_make_setting('VbiFormat', 'NTSC Closed Caption') || exit -1; diff --git a/abs/core-testing/tweaker/bin/twk_scrub_sql.pl b/abs/core-testing/tweaker/bin/twk_scrub_sql.pl new file mode 100755 index 0000000..2012d4d --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_scrub_sql.pl @@ -0,0 +1,96 @@ +#!/usr/bin/perl -w + +# Copyright 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +use Switch; +use Tweaker::Script; +package Tweaker::Script; + +# List all the options that this script supports. Make sure it matches what's in +# the corresponding .tcf entry. +set_known_options( 'scrub', 'protect' ); +my $beginning_of_user_index=65; + +# Try to implement the given option. +sub implement_option { + my($option) = @_; + + $dbconnectionstring = get_mythtv_connection_string(); + + if (connect_to_db("DBI:mysql:$dbconnectionstring")) { + + my @table_list = ( + [ 'capturecard', 'cardid' ], # tuner-related + [ 'cardinput', 'cardinputid' ], # tuner-related + [ 'videosource', 'sourceid' ], # tuner-related + + [ 'dvdinput', 'intid' ], + [ 'dvdtranscode', 'intid' ], + [ 'gameplayers', 'gameplayerid' ], + [ 'music_smartplaylist_categories', 'categoryid' ], + [ 'music_smartplaylist_items', 'smartplaylistitemid' ], + [ 'music_smartplaylists', 'smartplaylistid' ], + [ 'phonedirectory', 'intid' ], + [ 'profilegroups', 'id' ], + [ 'recordingprofiles', 'id' ], + [ 'storagegroup', 'id' ], + [ 'videotypes', 'intid' ], + ); + + switch ($option) { + case "scrub" { # delete the rows from the table + foreach my $table (@table_list) { + do_query("DELETE FROM @$table[0] WHERE @$table[1] < $beginning_of_user_index;"); + do_query("ALTER TABLE @$table[0] AUTO_INCREMENT = 0;"); + } + } + case "protect" { + foreach my $table (@table_list) { + do_query("ALTER TABLE @$table[0] AUTO_INCREMENT = $beginning_of_user_index;"); + } + } + } + } else { + exit -1; + } + disconnect_from_db(); +} + +sub poll_options { + my($option) = @_; + switch ($option) { + case "scrub" { + recommendation_level("recommended", "This is required to ensure that other KnoppMyth SQL Tweaks work."); + } + case "protect" { + recommendation_level("recommended", "This is required to ensure that other KnoppMyth SQL Tweaks do not clobber user-made changes."); + } + } +} + +# Unimplemented in 0.7 +sub check_option { + help; +} + +# Unimplemented in 0.7 +sub count_iterations { + help; +} + +process_parameters; + + diff --git a/abs/core-testing/tweaker/bin/twk_tuners.pl b/abs/core-testing/tweaker/bin/twk_tuners.pl new file mode 100755 index 0000000..ab7f029 --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_tuners.pl @@ -0,0 +1,488 @@ +#!/usr/bin/perl -w + +# Copyright 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +use Switch; +use Tweaker::Script; +package Tweaker::Script; + +set_known_options( 'all' ); # When Tweaker handles multiple instances of a script, this will be expanded to +# handle options for a given card, based on what it supports, e.g. ATSC, QAM, NTSC-coax, NTSC-Svideo, etc. +# The current version of this script will run once and set up defaults for all detected cards, choosing +# a default configuration based on some assumptions of common usage. Modes in this array should be listed +# from least desirable to most desirable. E.g. ["NTSC", "ATSC", "QAM"] + +my @capture_card_patterns = ( + # DIGITAL + # ------- + # ATSC-only devices + [ "pcHDTV hd-2000", [".*0400.*109e.*036e.*r11.*7063.*2000.*"], + ["DVB", ["ATSC"]]], + [ "BBTI Air2PC v2", [".*0280.*13d0.*2103.*r02.*13d0.*2103.*"], # ??? dupe 1; mihanson + ["DVB", ["ATSC"]]], + + # DVB-T devices + [ "DViCO FusionHDTV DVB-T Lite", [".*0400.*109e.*036e.*r11.*18ac.*db10.*"], + # secondary device "0480" "109e" "0878" -r11 "18ac" "d500" + ["DVB", ["DVB-T"]]], + [ "DViCO FusionHDTV DVB-T1", [".*0400.*14f1.*8800.*18ac.*db00.*"], + ["DVB", ["DVB-T"]]], # also has composite and S-Video in for frame grabbing + [ "DViCO FusionHDTV DVB-T Plus", [".*0400.*14f1.*8800.*8800.*db10.*"], + ["DVB", ["DVB-T"]]], + [ "DViCO FusionHDTV dual Express", [".*0400.*14f1.*8852.*18ac.*db78.*"], + ["DVB", ["DVB-T"]]], + [ "Twinhan VisionPlus DVB-T", [".*0400.*109e.*036e.*r11.*1822.*0001.*"], # ??? dupe 2; jbman, Girkers + ["DVB", ["DVB-T"]]], +# [ "EU Hauppauge PVR-500 (DVB-T)", [".*0400.*4444.*0016.*0070.*e807.*"], +# ["DVB", ["DVB-T"]]], + [ "Avermedia A777", [".*0480.*1131.*7133.*1461.*2c05.*", ".*0480.*1131.*7134.*1461.*2c05.*"], + ["DVB", ["DVB-T"]]], + [ "Compro T300", [".*0480.*1131.*7134.*185b.*c900.*", ".*0480.*1131.*7134.*7134.*c900.*"], + ["DVB", ["DVB-T"]]], + + # DVB-C devices + [ "Siemens DVB-C", [".*0480.*1131.*7146.*110a.*0000.*"], + ["DVB", ["DVB-C"]]], + + # DVB-S devices + [ "VisionPlus 1020A", [".*0480.*109e.*0878.*1822.*0001.*"], + ["DVB", ["DVB-S"]]], + [ "Technisat Skystar2", [".*0280.*13d0.*2103.*r01.*13d0.*2103.*"], # ??? dupe 1; nbdwt73, neutron68 + ["DVB", ["DVB-S"]]], + [ "Twinhan 102g", [".*0400.*109e.*036e.*r11.*1822.*0001.*"], # ??? dupe 2; neutron68 + # secondary device "0480" "109e" "0878" -r11 "1822" "0001" + ["DVB", ["DVB-S"]]], + + # ATSC/QAM devices + [ "Kworld ATSC-110", [".*0480.*1131.*7133.*17de.*"], + ["DVB", ["ATSC", "QAM"]]], + [ "pcHDTV hd-3000", [".*0400.*14f1.*8800.*3000.*"], + ["DVB", ["ATSC", "QAM"]]], # the hd-3000 has several sub-devices; this pattern matches the digital tuner + [ "BBTI HD5000AV / AirStar 2 TV", [".*0280.*13d0.*2103.*r02.*13d0.*2103.*"], # ??? dupe 1; manicmike + ["DVB", ["ATSC", "QAM", "DVB-T"]]], + [ "pcHDTV hd-5500", [".*0400.*14f1.*8800.*7063.*5500.*"], + ["DVB", ["ATSC", "QAM"]]], + [ "Hauppauge WinTV-HVR-1800", [".*0400.*14f1.*8880.*0070.*7801.*"], + ["DVB", ["ATSC", "QAM"]]], + [ "DViCO Fusion Express", [".*0400.*14f1.*8852.*r02.*18ac.*d500.*"], + ["DVB", ["ATSC", "QAM"]]], + + # card has one sub-device; this pattern matches the primary device + [ "DViCO Fusion HDTV5 Lite", [".*0400.*109e.*036e.*r11.*18ac.*d500.*"], + # secondary device "0480" "109e" "0878" -r11 "18ac" "d500" + ["DVB", ["ATSC", "QAM"]]], + + # ANALOG + # ------- + # NTSC cards + # MPEG-2 type + [ "Hauppauge PVR-150", [".*0400.*4444.*0016.*0070.*8003.*", ".*0400.*4444.*0016.*0070.*8801.*"], + ["MPEG", ["NTSC"]]], + [ "Hauppauge PVR-250", [".*0200.*10ec.*8139.*1799.*5000.*", ".*0400.*4444.*0016.*0070.*4009.*", ".*0400.*4444.*0016.*0070.*f7f9.*"], + ["MPEG", ["NTSC"]]], + [ "Hauppauge PVR-350", [".*0400.*4444.*0803.*0070.*4000.*"], + ["MPEG", ["NTSC"]]], + + # NTSC/PAL cards + # MPEG-2 type + [ "Hauppauge PVR-500", [".*0400.*4444.*0016.*0070.*e817.*", ".*0400.*4444.*0016.*0070.*e807.*"], # look for each of two devices on the card, since it's dual-tuner + ["MPEG", ["NTSC"]]], + + # Frame grabbers +# [ "bt878-based frame grabbers", [".*0400.*109e.*036e.*", ".*0480.*109e.*0878.*"], +# ["V4L", ["NTSC"]]], + + ); + +# USB patterns + +# "Hauppauge Nova-T 500 Dual DVB-T" + +#T: Bus=08 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 +#D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +#P: Vendor=2040 ProdID=9941 Rev= 1.00 +#S: Manufacturer=Hauppauge +#S: Product=WinTV Nova-DT +#S: SerialNumber=4027351140 +#C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=500mA +#I:* If#= 0 Alt= 0 #EPs= 4 Cls=ff(vend.) Sub=00 Prot=00 Driver=dvb_usb_dib0700 +#E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=125us +#E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +#E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +#E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +# "Hauppauge Nova-T-500" + +#T: Bus=08 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 +#D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +#P: Vendor=2040 ProdID=9950 Rev= 1.00 +#S: Manufacturer=Hauppauge +#S: Product=WinTV Nova-DT +#S: SerialNumber=4027353863 +#C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=500mA +#I: If#= 0 Alt= 0 #EPs= 4 Cls=ff(vend.) Sub=00 Prot=00 Driver=dvb_usb_dib0700 +#E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=125us +#E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +#E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +#E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +# Try to implement the given option. +sub implement_option { + my($option) = @_; + + $dbconnectionstring = get_mythtv_connection_string(); + + if (connect_to_db("DBI:mysql:$dbconnectionstring")) { + my $logger = get_logger('tweaker.script'); + + # Get a list of all PCI devices for later processing + my @lspci = split('\n', execute_shell_command("lspci -mn")); + + # Iterate through the list of known tuner cards, then the list of known network tuners. + # For each known tuner, configure a safe default for it if it's found. Set up + # well-named video sources for any mode supported by any tuner, and pick a default. + + # Determine the recording priority for a given device using the following priority rules, + # from top to bottom, the top being the most significant, and the bottom being the least + # significant + + # Input types in order of decreasing priority: + # Digital cable, digital satellite, digital OTA, analog cable, analog line-in, analog OTA + + # Device types in order of decreasing priority: + # local device, remote device + + # Capture types in order of decreasing priority: + # MPEG-2 creators (or passthrough of MPEG-2), MPEG-4 creators, frame grabbers + + # For example, if device1 supports a better input type than device2, device1 is always preferred. + # Ties are broken by the next level down. For example, if device1 and device2 both support the + # same input type, the tie is broken based on whether it's a local or remote device. Finally, + # ties of input type and device type are broken by the output of the device. It should be + # noted that it's possible to tie in all categories, and MythTV will break ties based on the + # order in which the devices are defined. + + + # For the following subroutines, $relative_device_count represents which device this is in + # the context of the total devices of its type. $global_device_count represents which device + # this is amongst all capture devices. Each returns a list of row names and values + # for the capturecard table, appropriate for the relevant type of device. + + # Create an entry in the capturecard table for the given tuner. + sub make_capturecard_SQL { + my($global_device_count, $relative_device_count, $cardtype, $tuner_number)=@_; + # $tuner_number is only used for HDHomeRuns + my $defaultinput=""; + my $hostname = execute_shell_command("hostname") || "localhost"; + my $checkfields = [["cardid", "$global_device_count"], + ["hostname", "$hostname"], + ["cardtype", "$cardtype"]]; + my $setfields; + my $logger = get_logger('tweaker.script'); + + # Because other devices use the /dev/video* and /dev/vbi* device + # files, the "device count" is used to determine which number follows the base + # device file name, e.g. /dev/video1, /dev/vbi1 + sub make_V4L_capturecard_SQL { + my($relative_device_count)=@_; # 0-indexed + + return [["videodevice", "/dev/video$relative_device_count"], + ["audiodevice", "/dev/dsp"], + ["vbidevice", "/dev/vbi$relative_device_count"], + ["audioratelimit", "0"]]; + } + + # Because other devices use the /dev/video* and /dev/vbi* device + # files, the "device count" is used to determine which number follows the base + # device file name, e.g. /dev/video1, /dev/vbi1 + sub make_MPEG_capturecard_SQL { + my($relative_device_count, $defaultinput)=@_; # 0-indexed + + return [["videodevice", "/dev/video$relative_device_count"], + ["defaultinput", $defaultinput]]; + } + + sub make_DVB_capturecard_SQL { + my($relative_device_count, # 0-indexed + $defaultinput)=@_; + my $logger = get_logger('tweaker.script'); + + $logger->debug("DEFAULTINPUT: $defaultinput"); + + return [["videodevice", "$relative_device_count"], # Rather than being a device file, it's a 0-indexed value indicating + # which of the N available DVB devices this is. Since a card can have more than one DVB device on it, there may + # be more DVB "videodevice"s on a system than there are distinct "cardid"s. + ["defaultinput", $defaultinput], + ["dvb_on_demand", "1"]]; + } + + # special case of DVB device + sub make_HDHOMERUN_capturecard_SQL { + my($hdhr_hex_id, $tuner_number, $defaultinput)=@_; + + return [["videodevice", "$hdhr_hex_id"], + ["defaultinput", $defaultinput], + ["dvb_on_demand", "0"], + ["dbox2_port", $tuner_number] # 0 or 1 + ]; + } + + $logger->debug("CARD TYPE: $cardtype"); + switch($cardtype) { + case "V4L" { + $setfields = make_V4L_capturecard_SQL($relative_device_count); + } + case "DVB" { + $defaultinput = "DVBInput"; + $setfields = make_DVB_capturecard_SQL($relative_device_count, $defaultinput); + } + case "HDHOMERUN" { + $defaultinput = "MPEG2TS"; + $setfields = make_HDHOMERUN_capturecard_SQL($relative_device_count, $tuner_number, $defaultinput); + } + case "MPEG" { + $defaultinput = "Tuner 1"; + $setfields = make_MPEG_capturecard_SQL($relative_device_count, $defaultinput); + } + } + + change_or_make_entry("capturecard", $setfields, $checkfields); + return $defaultinput; + } + + # Create an entry in videosource corresponding to the sub-type of input this device takes + # Return the sourceid for the entry we just made, which is a rough metric of desirability. + sub verify_or_make_videosource_SQL { + # sub-types are NTSC, PAL, ATSC, QAM, DVB-S, DVB-T, DVB-C, etc. + my($sub_type)=@_; + my $logger = get_logger('tweaker.script'); + + $logger->debug("\t\t\tUpdating or adding videosource for sub-type: $sub_type"); + + switch($sub_type) { + # North American options, from least desirable to most desirable (this is slightly arbitrary) + case "NTSC" { + change_or_make_entry("videosource", [["name", "analog_broadcast"], ["freqtable", "try-all"]], [["sourceid", 1]]); + # This is one of two cases where a sub_type can be used in two ways. Both videosources are made, but the preferred one is + # cable, the most common option. + change_or_make_entry("videosource", [["name", "analog_cable"], ["freqtable", "try-all"]], [["sourceid", 5]]); + return 5; + } + case "ATSC" { + change_or_make_entry("videosource", [["name", "digital_broadcast"], ["freqtable", "try-all"]], [["sourceid", 10]]); + return 10; + } + case "QAM" { + change_or_make_entry("videosource", [["name", "digital_cable"], ["freqtable", "try-all"]], [["sourceid", 20]]); + return 20; + } + + # Options for the rest of the planet + case "PAL" { + change_or_make_entry("videosource", [["name", "analog_broadcast"], ["freqtable", "try-all"]], [["sourceid", 1]]); + # This is one of two cases where a sub_type can be used in two ways. Both videosources are made, but the preferred one is + # cable, the most common option. + change_or_make_entry("videosource", [["name", "analog_cable"], ["freqtable", "try-all"]], [["sourceid", 5]]); + return 5; + } + case "DVB-T" { + change_or_make_entry("videosource", [["name", "digital_broadcast"], ["freqtable", "try-all"]], [["sourceid", 10]]); + return 10; + } + case "DVB-C" { + change_or_make_entry("videosource", [["name", "digital_cable"], ["freqtable", "try-all"]], [["sourceid", 20]]); + return 20; + } + + # Planet-wide options + case "DVB-S" { + change_or_make_entry("videosource", [["name", "digital_satellite"], ["freqtable", "try-all"]], [["sourceid", 15]]); + return 15; + } + } + } + + sub make_cardinput_SQL { + my($tuner_card_number, $sourceid, $inputname, $priority_modifier)=@_; + + change_or_make_entry("cardinput", [["sourceid", $sourceid], ["cardid", $tuner_card_number], + ["inputname", $inputname], ["preference", $sourceid], ["tunechan", ""], + ["startchan", "Please add"], ["freetoaironly", "1"], + ["recpriority", $sourceid+$priority_modifier]], + [["cardinputid", $tuner_card_number]]); + } + + sub max { + my($a, $b)=@_; + if ($a > $b) { + return $a; + } else { + return $b; + } + } + + my $global_device_count=0; + + # Configure each supported tuner/capture device detected on the system. + + # built-in, PCI, or PCI Express + $logger->debug("Processing local devices..."); + for my $pci_device (@lspci) { + $logger->debug("DEVICE: $pci_device"); + + for my $pci_device_data (@capture_card_patterns) { + $logger->debug("\tIs there a @$pci_device_data[0] at this location?"); + for my $patterns (@$pci_device_data[1]) { + for my $pattern (@$patterns) { + my $match=0; + $logger->debug("\t\tPATTERN: $pattern"); + $match += ($pci_device =~ m/$pattern/i); + if ($match) { + $global_device_count++; # 1-indexed + + $logger->debug("\t\tfound one!"); + # Each device has a device type (e.g. MPEG, DVB, V4L) that it supports, and a + # list of sub_types (e.g. PAL, NTSC, DVB-S, DVB-T, DVB-C, ATSC, QAM). + # The device type is used to configure the capturecard table and the cardinput table. + # The sub_types are used to populate the videosource table. + # The device type and "best" sub_type are used to set the 'sourceid' field of the cardinput table. + + for my $typeblock (@$pci_device_data[2]) { + my $pci_device_type = @$typeblock[0]; + $logger->debug("\t\tDEVICE TYPE: $pci_device_type"); # e.g. "DVB", "MPEG", etc. + $cardtypes{$pci_device_type}++; + my $sourceid = -1; + for my $sub_types (@$typeblock[1]) { + for my $sub_type (@$sub_types) { + $logger->debug("\t\tSUB-TYPE: $sub_type\n"); # e.g. "DVB-S", "QAM", etc. + # ensure that the videosource table has an entry for each sub_type + # that this device supports; use the "best" one for the device by + # default + + # + # POPULATE videosource table + # + $sourceid = max(verify_or_make_videosource_SQL($sub_type), $sourceid); + } + } + $logger->debug("\t\t\"BEST\" SOURCE ID: $sourceid\n"); + + # + # POPULATE capturecard table + # + my $defaultinput = make_capturecard_SQL($global_device_count, $cardtypes{$pci_device_type}-1, $pci_device_type, -1); + + # + # POPULATE cardinput table + # + make_cardinput_SQL($global_device_count, $sourceid, $defaultinput, 0); + } + } + } + } + } + } + + # network tuner devices + $logger->debug("Processing network devices..."); + + # get our IP address + my $ip_address; + open(SHELL, "ifconfig | grep \"inet addr\" | grep -v 127 |"); + while(<SHELL>) { + my @line = split(/:| +/); + $ip_address = $line[3]; + } + close(SHELL); + + # ??? eventually, just add LocalIPCheck.pl's code to Tweaker/Script.pm and avoid bizarre perl-to-shell-to-perl calls at this level + my $ip_class = execute_shell_command("echo $ip_address | LocalIPCheck.pl; echo \$?"); + + if ($ip_class > 0) { # we're on a LAN, not the internet + # Look for HDHomeRun, a DVB ATSC/QAM device + $sourceid=0; + $logger->debug("\tLooking for SiliconDust HDHomeRun..."); + open(SHELL2, "hdhomerun_config discover |"); + while(<SHELL2>) { + if (m/\d+\.\d+\.\d+\.\d+/) { + my @line = split(/ /); + my $hdhr_hex_id = $line[2]; + + $logger->debug("\tfound $hdhr_hex_id"); + $global_device_count++; # 1-indexed + $cardtypes{"DVB"}++; + # + # POPULATE videosource table + # + for my $sub_type ("ATSC", "QAM") { + $sourceid = max(verify_or_make_videosource_SQL($sub_type), $sourceid); + } + $logger->debug("\t\t\"BEST\" SOURCE ID: $sourceid\n"); + + # + # POPULATE capturecard table + # + + # there are two tuners per HDHomeRun + for (my $sub_tuner_count = 0; $sub_tuner_count < 2; $sub_tuner_count++) { + my $defaultinput = make_capturecard_SQL($global_device_count+$sub_tuner_count, $hdhr_hex_id, "HDHOMERUN", $sub_tuner_count); + # + # POPULATE cardinput table + # + make_cardinput_SQL($global_device_count+$sub_tuner_count, $sourceid, $defaultinput, -4); # the -4 is to make it less desirable + # than a local device + } + $global_device_count++; + + } + } + close(SHELL2); + } # else: don't scan the internet! + + # USB devices + $logger->debug("Processing USB devices..."); + $logger->debug("\t(no USB devices supported yet)"); + + # Filesystem Tweaks for tuners + # This only works with the Nova-T-500 card, but it doesn't hurt any other cards + execute_shell_command("echo \"#switch on onboard amplifier on Nova-T-500 card\" > /etc/modprobe.d/dvb-usb-dib0700"); + execute_shell_command("echo \"options dvb-usb-dib0700 force_lna_activation=1\" >> /etc/modprobe.d/dvb-usb-dib0700"); + } else { + my $logger = get_logger('tweaker.script'); + $logger->error("Unable to connect to mythconverg database"); + $logger->error("Unable to implement option $option."); + return -1; + } +} + +# Try to get a Recommendation Level for $option. +sub poll_options { + my($option) = @_; + + recommendation_level("recommended", "Everyone should scan for tuners to autoconfigure."); +} + +# Unimplemented in 0.7 +sub check_option { + help; +} + +# Unimplemented in 0.7 +sub count_iterations { + help; +} + +process_parameters; diff --git a/abs/core-testing/tweaker/bin/twk_tuners_notes.txt b/abs/core-testing/tweaker/bin/twk_tuners_notes.txt new file mode 100644 index 0000000..1f2e283 --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_tuners_notes.txt @@ -0,0 +1,55 @@ +# Some PCI devices have the same lspci -mn fingerprint, yet users are identifying them as having different functions. The example below is reported as an ATSC(DVB-T) card by one user and as a DVB-S card by two other users. lspci -vvxxx provides more fingerprint data, and I'm trying to see if there's a definitive way to tell the cards apart from it. + + [ "BBTI Air2PC v2", [".*0280.*13d0.*2103.*r02.*13d0.*2103.*"], # ??? dupe 1; mihanson + ["DVB", ["ATSC"]]], + # mihanson lspci -vvxxx info: + +#00: d0 13 03 21 07 01 00 04 02 00 80 02 00 40 00 00 +#10: 00 00 64 ed 81 70 00 00 00 00 00 00 00 00 00 00 +#20: 00 00 00 00 00 00 00 00 00 00 00 00 d0 13 03 21 +#30: 00 00 00 00 00 00 00 00 00 00 00 00 0c 01 00 00 + +#00: d0 13 03 21 07 01 00 04 02 00 80 02 00 40 00 00 +#10: 00 00 65 ed a1 70 00 00 00 00 00 00 00 00 00 00 +#20: 00 00 00 00 00 00 00 00 00 00 00 00 d0 13 03 21 +#30: 00 00 00 00 00 00 00 00 00 00 00 00 0b 01 00 00 + +#00: d0 13 03 21 07 01 00 04 02 00 80 02 00 40 00 00 +#10: 00 00 66 ed c1 70 00 00 00 00 00 00 00 00 00 00 +#20: 00 00 00 00 00 00 00 00 00 00 00 00 d0 13 03 21 +#30: 00 00 00 00 00 00 00 00 00 00 00 00 0a 01 00 00 + +#00: d0 13 03 21 07 01 00 04 02 00 80 02 00 40 00 00 +#10: 00 00 67 ed e1 70 00 00 00 00 00 00 00 00 00 00 +#20: 00 00 00 00 00 00 00 00 00 00 00 00 d0 13 03 21 +#30: 00 00 00 00 00 00 00 00 00 00 00 00 0c 01 00 00 + +# Among the above, there are only three sections that +# differ, shown by XX: +#10: -- -- XX -- XX -- -- -- -- -- -- -- -- -- -- -- +#30: -- -- -- -- -- -- -- -- -- -- -- -- XX -- -- -- + + + [ "Technisat Skystar2", [".*0280.*13d0.*2103.*r01.*13d0.*2103.*"], # ??? dupe 1; nbdwt73, neutron68 + ["DVB", ["DVB-S"]]], + # Neutron68 lspci -vvxxx info: +#00: d0 13 03 21 07 01 00 04 01 00 80 02 00 40 00 00 +#10: 00 00 ae fa 81 c8 00 00 00 00 00 00 00 00 00 00 +#20: 00 00 00 00 00 00 00 00 00 00 00 00 d0 13 03 21 +#30: 00 00 00 00 00 00 00 00 00 00 00 00 05 01 00 00 + +# when compared with mihanson's blocks, these entries differ: +#00: -- -- -- -- -- -- -- -- -- -- -- XX -- -- -- -- +#10: -- -- XX XX XX XX XX -- -- -- -- -- -- -- -- -- +#20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +#30: -- -- -- -- -- -- -- -- -- -- -- -- XX -- -- -- + +# eliminating the entries that even differ among mihanson's devices, we get: +#00: -- -- -- -- -- -- -- -- -- -- -- XX -- -- -- -- +#10: -- -- -- XX -- XX XX -- -- -- -- -- -- -- -- -- +#20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +#30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + +# Without more feedback, it's not clear whether or not this pattern is representative +# of the differences between the DVB-S and ATSC versions of this device. + diff --git a/abs/core-testing/tweaker/bin/twk_upgrade.pl b/abs/core-testing/tweaker/bin/twk_upgrade.pl new file mode 100755 index 0000000..479a675 --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_upgrade.pl @@ -0,0 +1,190 @@ +#!/usr/bin/perl -w + +# Copyright 2007, 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +# +# NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE +# +# Tweaker 0.7 is not interactive, so these post-upgrade changes are a stopgap +# measure to make sure people upgrading from R5F27 get sensible settings +# for things that MythTV 0.21 doesn't know how to handle properly. This file +# should shrink or disappear entirely once Tweaker becomes interactive. +# +# NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE +# + +use Switch; +use Tweaker::Script; +package Tweaker::Script; + +set_known_options( 'all' ); + +# Try to implement the given option. +sub implement_option { + my($option) = @_; + + $dbconnectionstring = get_mythtv_connection_string(); + + if (connect_to_db("DBI:mysql:$dbconnectionstring")) { + # use poll results from twk_cpu.pl to set playback decoder options + my @levels = ("low", "medium", "high"); + foreach my $level (@levels) { + my @results = split(/\|/, execute_shell_command("twk_cpu.pl --poll $level")); + foreach my $result (@results) { + if ($result eq "recommended") { + if ("$level" eq "low") { + change_or_make_setting('DefaultVideoPlaybackProfile', 'CPU--') || exit -1; # best playback defaults for weak hardware + } elsif ("$level" eq "medium") { + change_or_make_setting('DefaultVideoPlaybackProfile', 'CPU+') || exit -1; # best playback defaults for average hardware + } elsif ("$level" eq "high") { + change_or_make_setting('DefaultVideoPlaybackProfile', 'CPU++') || exit -1; # best playback defaults for powerful hardware + } + } + } + } + + # Update visualization modes for 0.21 + change_or_make_setting('VisualMode','BumpScope;Gears;Goom;MonoScope;Squares;StereoScope;Synaesthesia;LibVisual-bumpscope;LibVisual-corona;LibVisual-infinite;LibVisual-jakdaw;LibVisual-jess;AlbumArt'); + + # Remove possibly obsolete and conflicting theme cache entries. + execute_shell_command("/bin/rm -rf /home/mythtv/.mythtv/themecache/"); + + # Fix bizarre ownership of files: + execute_shell_command("chown -f root: /usr/bin/get_dual.sh"); + execute_shell_command("chown -fR root: /usr/lib/krp"); + execute_shell_command("chown -fR root: /usr/local/bin"); + execute_shell_command("chown -f root: /usr/share/man/man1/tv_grab_au.1.gz"); + execute_shell_command("chown -f root: /usr/share/xmltv/tv_grab_au/channel_ids"); + execute_shell_command("chown -fR root:src /usr/src/"); + + # Fix video problems for some nVidia users + execute_shell_command("grep nvidia /etc/X11/xorg.conf && sed -i -e 's/^[ \t]*Option.*\"XvmcUsesTextures\".*/#REMOVEME/g' -e 's/^[ \t]*Option.*\"UseEvents\".*/#REMOVEME/g' /etc/X11/xorg.conf"); # clear out old entries, if present + execute_shell_command("grep nvidia /etc/X11/xorg.conf && sed -i -n '1h;2,\$H;\${g;s/#REMOVEME\\n//g;p}' /etc/X11/xorg.conf"); # clear out old entries, if present + execute_shell_command("grep nvidia /etc/X11/xorg.conf && sed -i 's/\\(^[ \t]*Driver.*\"nvidia\".*\\)/\\1\\n\tOption \"XvmcUsesTextures\" \"false\"\\n\tOption \"UseEvents\" \"true\"/g' /etc/X11/xorg.conf"); + execute_shell_command("if [ -e /home/mythtv/.nvidia-settings-rc ] ; then sed -i -e \"s'.*XVideoTextureSyncToVBlank.*'#REMOVEME'g\" -e \"s'.*XVideoBlitterSyncToVBlank.*'#REMOVEME'g\" /home/mythtv/.nvidia-settings-rc; fi"); + execute_shell_command("grep nvidia /etc/X11/xorg.conf && echo 0/XVideoTextureSyncToVBlank=0 >> /home/mythtv/.nvidia-settings-rc && echo 0/XVideoBlitterSyncToVBlank=0 >> /home/mythtv/.nvidia-settings-rc && sed -i -n '1h;2,\$H;\${g;s/#REMOVEME\\n//g;p}' /home/mythtv/.nvidia-settings-rc"); + + + # Enable any digital audio out device we can. + my $command = "amixer scontrols | grep IEC958"; + my @results = split('\n', execute_shell_command($command)); + foreach my $line (@results) { + if ($line =~ /Simple mixer control (.*),.*/i) { + $command = "su - mythtv -c \"amixer set $1 on\""; # Tries to set all IEC958 devices to 'on' + # but some are just placeholders and can't be turned 'on', therefore don't error out if we fail + execute_shell_command($command); + } + } + execute_shell_command("alsactl store"); # persist the above change(s) + + # The Chaintech AV-710 was generally configured for digital audio in R5F27 in a way that worked + # great there but which is failing utterly in R5.5. Try to detect this old configuration, and if + # it's present, implement the new settings which seem to work for all digital audio devices. + # This may only match 80% of the AV-710 users, but the rest of them can just run the necessary + # tweaker command by hand to get the same result. + if (execute_shell_command('lspci -mn | grep -e ".*0401.*1412.*1724.*1412.*1724"')) { + # found an AV-710, now see if it's configured for digital audio + if (do_query("SELECT * FROM settings WHERE value='AudioOutputDevice' AND data='/dev/adsp'")) { + # The user was using this AV-710's spdif output, so give them the new good digital configuration + execute_shell_command("twk_audio.pl --implement digital"); + } + } + change_or_make_setting('MixerDevice', 'ALSA:default') || exit -1; + + # Undo obsolete mplayer workaround for aspect ratio + execute_shell_command("sed -i 's/.*monitoraspect.*//g' /home/mythtv/.mplayer/config"); + + my $hostname = execute_shell_command("hostname") || "localhost"; + # one table at a time, replace hostname with our actual hostname + # ??? can this be done all at once in MySQL? + foreach my $table ("capturecard", "inuseprograms", "jobqueue", "jumppoints", "keybindings", "music_playlists", + "musicplaylist", "recorded", "settings", "weatherscreens") { + do_query("UPDATE $table SET hostname='$hostname'"); + } + + # Some entries in 'settings' should stay NULL: http://www.mythtv.org/wiki/index.php/Settings_table + # There are fewer entries that stay NULL than there are that should have the hostname set, so while + # it duplicates some effort to change them from NULL to the hostname and them back to NULL, it's + # easier to maintain and more future-proof. + foreach my $entry ("mythfilldatabaseLastRunStart", "mythfilldatabaseLastRunEnd", "mythfilldatabaseLastRunStatus", + "DataDirectMessage", "HaveRepeats", "DBSchemaVer", "DefaultTranscoder", "MythFillSuggestedRunTime", + "MythFillGrabberSuggestsTime", "MasterServerIP", "MasterServerPort", "TVFormat", "VbiFormat", "FreqTable", + "TimeOffset", "MasterBackendOverride", "DeletesFollowLinks", "HDRingbufferSize", "EITTransportTimeout", + "EITIgnoresSource", "EITCrawIdleStart", "startupCommand", "blockSDWUwithoutClient", "idleWaitForRecordingTime", + "StartupSecsBeforeRecording", "WakeupTimeFormat", "SetWakeuptimeCommand", "ServerHaltCommand", "preSDWUCheckCommand", + "WOLbackendConnectRetry", "WOLbackendCommand", "WOLslaveBackendsCommand", "JobsRunOnRecordHost", + "AutoCommflagWhileRecording", "JobQueueCommFlagCommand", "JobQueueTranscodeCommand", + "AutoTranscodeBeforeAutoCommflag", "SaveTranscoding", "UserJobDesc1", "UserJob1", "UserJobDesc2", "UserJob2", + "UserJobDesc3", "UserJob3", "UserJobDesc4", "UserJob4", "PreviewPixmapOffset", "AllRecGroupPassword", + "MaximumCommercialSkip", "CommSkipAllBlanks", "LastFreeCard", "LiveTVPriority", "AutoExpireMethod", + "AutoExpireDefault", "RerecordWatched", "AutoExpireWatchedPriority", "AutoExpireLiveTVMaxAge", + "AutoExpireDayPriority", "AutoExpireExtraSpace", "AutoExpireInsteadOfDelete", "DeletedFifoOrder", + "CommercialSkipMethod", "AggressiveCommDetect", "AutoCommercialFlag", "AutoTranscode", "AutoRunUserJob1", + "AutoRunUserJob2", "AutoRunUserJob3", "AutoRunUserJob4", "OverTimeCategory", "CategoryOverTime", + "EPGEnableJumpToChannel", "LogEnabled", "MythFillEnabled", "MythFillDatabasePath", "MythFillDatabaseArgs", + "MythFillDatabaseLog", "MythFillPeriod", "MythFillMinHour", "MythFillMaxHour", "SchedMoveHigher", "SchedOpenEnd", + "ComplexPriority", "PrefInputPriority", "SingleRecordRecPriority", "FindOneRecordRecPriority", "ArchiveDBSchemaVer", + "FlixDBSchemaVer", "GalleryDBSchemaVer", "GameDBSchemaVer", "MusicDBSchemaVer", "PhoneDBSchemaVer", + "mythvideo.DBSchemaVer", "WeatherDBSchemaVer") { + do_query("UPDATE settings SET hostname=NULL WHERE value='$entry'"); + } + + change_or_make_setting('MythFillDatabaseLog', '/var/log/mythtv/mythfilldatabase.log'); + change_or_make_setting('MasterBackendOverride','1'); # I don't remember why, but making the hostname NULL is important here + do_query("UPDATE settings SET hostname=NULL WHERE value='MasterBackendOverride'"); + + disconnect_from_db(); + + # Fix hostname for iPod feed URLs + $command = "sed -i \"s/hostname\\//$hostname\\//g\" /usr/local/bin/myth2ipod"; + execute_shell_command($command); + + # Fix hostname for XViD feed URLs + $command = "sed -i \"s/192.168.0.222\\//$hostname\\//g\" /usr/local/bin/myt2xvid3"; + execute_shell_command($command); + + # Customize default MythTV library.xml to reflect KnoppMyth's wider selection of + # online stream options. + #$command = "sed -i \"/<type>STREAM<\\/type>\$/{N; N; N; N; s/text>.*<\\/text/text>Online Streams<\\/text/; s/action>.*<\\/action/action>MENU is.xml<\\/action/; s/<depends.*depends>//; }\" /usr/share/mythtv/library.xml"; + $command = "/bin/cp /usr/share/mythtv/library.xml.km /usr/share/mythtv/library.xml" + execute_shell_command($command); + + } else { + my $logger = get_logger('tweaker.script'); + $logger->error("ERROR: Unable to connect to mythconverg database"); + $logger->error("ERROR: Unable to implement option $option."); + exit -1; + } + disconnect_from_db(); +} + +# Try to get a Recommendation Level for $option. +sub poll_options { + my($option) = @_; + recommendation_level("recommended", "These tweaks benefit all users."); +} + +# Unimplemented in 0.7 +sub check_option { + help; +} + +# Unimplemented in 0.7 +sub count_iterations { + help; +} + +process_parameters; diff --git a/abs/core-testing/tweaker/bin/twk_what_has_changed.sh b/abs/core-testing/tweaker/bin/twk_what_has_changed.sh new file mode 100755 index 0000000..deff7cf --- /dev/null +++ b/abs/core-testing/tweaker/bin/twk_what_has_changed.sh @@ -0,0 +1,183 @@ +#!/bin/bash + +# Copyright 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv +# and Tom Culliton of <affiliation>. Most of restore_baseline_SQL taken from +# KnoppMyth R5F27's /usr/local/bin/KnoppMyth-run script (multiple authors) +# +# 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 <http://www.gnu.org/licenses/>. + + +#---------------------------------------------------------------------------- +. /usr/local/bin/backupcommon || { + echo "Can not find common settings!" + exit 1 +} +#---------------------------------------------------------------------------- + +# Target output file for our results +DIFF_RESULTS=/tmp/database_changes.txt +LOGFILE=/var/log/twk_what_has_changed.log +WORKING_DIR=/tmp/ + +# Restore the SQL to the way it would have been after R5F27 was installed +# and before the user made any changes to MythTV settings. +# This is KnoppMyth-centric and does not apply to general MythTV distros, +# however it is possible to generalize this to apply to any MythTV distro +# including generic Linux distros in which MythTV has been installed. +# +# Preconditions: MySQL daemon is running +# +# Postconditions: 'mythconverg' is deleted and re-created, just as it +# would be during the course of a normal installation. +restore_baseline_SQL() { + echo "restoring baseline SQL" >> $LOGFILE + KRP_RESULT=-1 + KRPAutoDetect.pl &> /dev/null # be quiet + KRP_RESULT=$?; + + # Parts from R5F27's KnoppMyth-run + KNOPPMYTH_SQL_FILE="/usr/local/share/knoppmyth/KnoppMyth.sql" + + # Try to detect and configure settings for various tuner + # and capture devices. + /usr/local/bin/TunerConfig.sh $KNOPPMYTH_SQL_FILE >> /dev/null + /usr/local/bin/ren_host.sh + GlobalSQLtweaker.sh $KNOPPMYTH_SQL_FILE + + if [[ ($KRP_RESULT != 1) && ($KRP_RESULT != 2) && ($KRP_RESULT != 3) && ($KRP_RESULT != 10) && (-n "$IS_AUS") ]]; then # not Dragon + /usr/local/bin/epia_sql.sh + fi + + # General MythTV SQL settings for all boxes + if [ -f "/usr/local/bin/MythTV-sql" ]; then + # Interject platform-specific SQL settings before we populate the SQL + # database. + if [[ ($KRP_RESULT == 1) || ($KRP_RESULT == 2) || ($KRP_RESULT == 3) || ($KRP_RESULT == 10) ]]; then # Dragon + DragonSQLtweaker.sh $KNOPPMYTH_SQL_FILE + fi + # Now use the (possibly modified) KnoppMyth.sql to populate initial + # MythTV settings. + + # This wipes out the current mythconverg and replaces it with what's in $KNOPPMYTH_SQL_FILE + sh /usr/local/bin/MythTV-sql $KNOPPMYTH_SQL_FILE + fi + + echo \ + "MythTV will re-launch in a tiny window. If it asks you about +upgrading the schema, agree. When the schema upgrade is complete, +exit MythTV. +You can exit MythTV immediately if you aren't asked to do a schema +upgrade." + echo "###" + echo "Press ENTER to re-launch MythTV." + read CONTINUE; + restart_mythtv "--geometry 640x480" +} + +# Call mysql and only dump the requested data in tab seperated columns +get_data () { + mysql mythconverg -u root -sNBe "$*" +} + +# Compares $MYTHTV_EXPECTED_DB_NAME to $USERS_DB_NAME +compare_databases() { + echo "comparing databases" >> $LOGFILE + tables_to_compare="capturecard cardinput codecparams displayprofilegroups displayprofiles dtv_multiplex keybindings playgroups profilegroups recordingprofiles settings videotypes weatherdatalayout weatherscreens weathersourcesettings" + hostnames=$(get_data "select distinct hostname from settings where hostname is not null") + + /etc/init.d/mysql start >> $LOGFILE + # Do some MySQL magic to compare $tables_to_compare between + # $MYTHTV_EXPECTED_DB_NAME (baseline) and $USERS_DB_NAME (user's version) + # ??? +} + +# This is somewhat KnoppMyth-centric, though minor modification would +# make it work generally. +function restart_mythtv { + echo "restarting MythTV" >> $LOGFILE + EXTRA_PARAMETERS=$1 ; shift + /etc/init.d/mythtv-backend start >> $LOGFILE + killall mythfrontend + # re-launches the frontend and gives the user a chance to upgrade to latest schema + su - mythtv -c "export DISPLAY=:0.0 ; mythfrontend --logfile /var/log/mythtv/mythfrontend.log $EXTRA_PARAMETERS" >> $LOGFILE +} + +function rename_database { + db_source=$1 ; shift + db_target=$1 ; shift + + echo "renaming database $db_source to $db_target" >> $LOGFILE + + # Exit the frontend before messing with the SQL + killall mythfrontend + # If we stop MySQL before stopping the MythTV backend, we'll probably trigger badness + /etc/init.d/mythtv-backend stop >> $LOGFILE + # MySQL needs to stop before we do this. + /etc/init.d/mysql stop >> $LOGFILE + /bin/mv $db_source $db_target +} + +main() { + echo -n "$0 started running: " >> $LOGFILE + date >> $LOGFILE + + echo "STEP 0..." + echo "STEP 0" >> $LOGFILE + # 0) acquire system settings + MYTHTV_EXPECTED_DB_NAME=`grep DBName /etc/mythtv/mysql.txt | awk -F= '{ print $2 }'` + USERS_DB_NAME="mythconverg-copy" + /etc/init.d/mysql start >> $LOGFILE + # MySQL needs to be running or mysqladmin won't return anything + SQL_HOME=`mysqladmin variables | grep datadir | awk -F\| '{ print $3 }' | sed 's/ //g'` + + echo "STEP 1..." + echo "STEP 1" >> $LOGFILE + # 1) rename the current MythTV MySQL database + rename_database $SQL_HOME$MYTHTV_EXPECTED_DB_NAME $WORKING_DIR$USERS_DB_NAME + + echo "STEP 2..." + echo "STEP 2" >> $LOGFILE + # 2) re-create the R5F27 baseline SQL. + /etc/init.d/mysql start >> $LOGFILE + restore_baseline_SQL + + echo "STEP 3..." + echo "STEP 3" >> $LOGFILE + # 3) compare the fresh baseline DB with the user's modified DB, and save the + # diffs to a text file + # ??? + + echo "STEP 4..." + echo "STEP 4" >> $LOGFILE + # 4) restore the user's database + rename_database $WORKING_DIR$USERS_DB_NAME $SQL_HOME$MYTHTV_EXPECTED_DB_NAME + /etc/init.d/mysql start >> $LOGFILE + + echo "STEP 5..." + echo "STEP 5" >> $LOGFILE + # 5) Tell them the comparison is done, tell them where to find the results, + # and prompt them to restart MythTV. + echo "Your results are in $DIFF_RESULTS" + echo "###" + echo "Press ENTER to re-launch MythTV." + read CONTINUE; + + restart_mythtv "&" + echo "DONE" + echo -n "$0 stopped running: " >> $LOGFILE + date >> $LOGFILE +} + +main + diff --git a/abs/core-testing/tweaker/fs/etc/asound.conf b/abs/core-testing/tweaker/fs/etc/asound.conf new file mode 100644 index 0000000..ffb665d --- /dev/null +++ b/abs/core-testing/tweaker/fs/etc/asound.conf @@ -0,0 +1,15 @@ +pcm.spdifdmix { + type dmix + ipc_key 1337 + slave { + pcm "hw:0,1" + format S32_LE + } +} + +pcm.!default { + type plug + slave { + pcm spdifdmix + } +} diff --git a/abs/core-testing/tweaker/fs/var/lib/alsa/ALC888.asound.state b/abs/core-testing/tweaker/fs/var/lib/alsa/ALC888.asound.state new file mode 100644 index 0000000..5540338 --- /dev/null +++ b/abs/core-testing/tweaker/fs/var/lib/alsa/ALC888.asound.state @@ -0,0 +1,354 @@ +state.NVidia { + control.1 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 31' + comment.dbmin -4650 + comment.dbmax 0 + iface MIXER + name 'Front Playback Volume' + value.0 25 + value.1 25 + } + control.2 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 2 + iface MIXER + name 'Front Playback Switch' + value.0 true + value.1 true + } + control.3 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 31' + comment.dbmin -4650 + comment.dbmax 0 + iface MIXER + name 'Surround Playback Volume' + value.0 0 + value.1 0 + } + control.4 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 2 + iface MIXER + name 'Surround Playback Switch' + value.0 true + value.1 true + } + control.5 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 31' + comment.dbmin -4650 + comment.dbmax 0 + iface MIXER + name 'Center Playback Volume' + value 0 + } + control.6 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 31' + comment.dbmin -4650 + comment.dbmax 0 + iface MIXER + name 'LFE Playback Volume' + value 0 + } + control.7 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Center Playback Switch' + value true + } + control.8 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'LFE Playback Switch' + value true + } + control.9 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 31' + comment.dbmin -4650 + comment.dbmax 0 + iface MIXER + name 'Side Playback Volume' + value.0 0 + value.1 0 + } + control.10 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 2 + iface MIXER + name 'Side Playback Switch' + value.0 true + value.1 true + } + control.11 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 2 + iface MIXER + name 'Headphone Playback Switch' + value.0 true + value.1 true + } + control.12 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 31' + comment.dbmin -3450 + comment.dbmax 1200 + iface MIXER + name 'Mic Playback Volume' + value.0 0 + value.1 0 + } + control.13 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 2 + iface MIXER + name 'Mic Playback Switch' + value.0 false + value.1 false + } + control.14 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 31' + comment.dbmin -3450 + comment.dbmax 1200 + iface MIXER + name 'Front Mic Playback Volume' + value.0 0 + value.1 0 + } + control.15 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 2 + iface MIXER + name 'Front Mic Playback Switch' + value.0 false + value.1 false + } + control.16 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 31' + comment.dbmin -3450 + comment.dbmax 1200 + iface MIXER + name 'Line Playback Volume' + value.0 0 + value.1 0 + } + control.17 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 2 + iface MIXER + name 'Line Playback Switch' + value.0 false + value.1 false + } + control.18 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 3' + comment.dbmin 0 + comment.dbmax 3000 + iface MIXER + name 'Mic Boost' + value.0 0 + value.1 0 + } + control.19 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 3' + comment.dbmin 0 + comment.dbmax 3000 + iface MIXER + name 'Front Mic Boost' + value.0 0 + value.1 0 + } + control.20 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 31' + comment.dbmin -1650 + comment.dbmax 3000 + iface MIXER + name 'Capture Volume' + value.0 0 + value.1 0 + } + control.21 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 2 + iface MIXER + name 'Capture Switch' + value.0 true + value.1 true + } + control.22 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 31' + comment.dbmin -1650 + comment.dbmax 3000 + iface MIXER + name 'Capture Volume' + index 1 + value.0 0 + value.1 0 + } + control.23 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 2 + iface MIXER + name 'Capture Switch' + index 1 + value.0 true + value.1 true + } + control.24 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 Mic + comment.item.1 'Front Mic' + comment.item.2 Line + iface MIXER + name 'Input Source' + value Mic + } + control.25 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 Mic + comment.item.1 'Front Mic' + comment.item.2 Line + iface MIXER + name 'Input Source' + index 1 + value Mic + } + control.26 { + comment.access read + comment.type IEC958 + comment.count 1 + iface MIXER + name 'IEC958 Playback Con Mask' + value '0fff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + } + control.27 { + comment.access read + comment.type IEC958 + comment.count 1 + iface MIXER + name 'IEC958 Playback Pro Mask' + value '0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + } + control.28 { + comment.access 'read write' + comment.type IEC958 + comment.count 1 + iface MIXER + name 'IEC958 Playback Default' + value '0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + } + control.29 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'IEC958 Playback Switch' + value false + } + control.30 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'IEC958 Default PCM Playback Switch' + value true + } + control.31 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'IEC958 Capture Switch' + value false + } + control.32 { + comment.access read + comment.type IEC958 + comment.count 1 + iface MIXER + name 'IEC958 Capture Default' + value '0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + } + control.33 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 31' + comment.dbmin -4650 + comment.dbmax 0 + iface MIXER + name 'Master Playback Volume' + value 31 + } + control.34 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Master Playback Switch' + value true + } + control.35 { + comment.access 'read write user' + comment.type INTEGER + comment.count 2 + comment.range '0 - 255' + comment.tlv '0000000100000008ffffec1400000014' + comment.dbmin -5100 + comment.dbmax 0 + iface MIXER + name 'PCM Playback Volume' + value.0 163 + value.1 163 + } +} diff --git a/abs/core-testing/tweaker/fs/var/lib/alsa/AV710.asound.state b/abs/core-testing/tweaker/fs/var/lib/alsa/AV710.asound.state new file mode 100644 index 0000000..7e57108 --- /dev/null +++ b/abs/core-testing/tweaker/fs/var/lib/alsa/AV710.asound.state @@ -0,0 +1,567 @@ +state.AV710 { + control.1 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Master Playback Switch' + value true + } + control.2 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 31' + comment.dbmin -4650 + comment.dbmax 0 + iface MIXER + name 'Master Playback Volume' + value.0 22 + value.1 22 + } + control.3 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Center Playback Switch' + value false + } + control.4 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 31' + comment.dbmin -4650 + comment.dbmax 0 + iface MIXER + name 'Center Playback Volume' + value 31 + } + control.5 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'LFE Playback Switch' + value false + } + control.6 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 31' + comment.dbmin -4650 + comment.dbmax 0 + iface MIXER + name 'LFE Playback Volume' + value 0 + } + control.7 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 2 + iface MIXER + name 'Surround Playback Switch' + value.0 false + value.1 false + } + control.8 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 31' + comment.dbmin -4650 + comment.dbmax 0 + iface MIXER + name 'Surround Playback Volume' + value.0 0 + value.1 0 + } + control.9 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Headphone Playback Switch' + value true + } + control.10 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 31' + comment.dbmin -4650 + comment.dbmax 0 + iface MIXER + name 'Headphone Playback Volume' + value.0 22 + value.1 22 + } + control.11 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Master Mono Playback Switch' + value true + } + control.12 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 31' + comment.dbmin -4650 + comment.dbmax 0 + iface MIXER + name 'Master Mono Playback Volume' + value 25 + } + control.13 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'PC Speaker Playback Switch' + value false + } + control.14 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 15' + comment.dbmin -4500 + comment.dbmax 0 + iface MIXER + name 'PC Speaker Playback Volume' + value 0 + } + control.15 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Phone Playback Switch' + value false + } + control.16 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 31' + comment.dbmin -3450 + comment.dbmax 1200 + iface MIXER + name 'Phone Playback Volume' + value 0 + } + control.17 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Mic Playback Switch' + value false + } + control.18 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 31' + comment.dbmin -3450 + comment.dbmax 1200 + iface MIXER + name 'Mic Playback Volume' + value 0 + } + control.19 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Mic Boost (+20dB)' + value false + } + control.20 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Line Playback Switch' + value false + } + control.21 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 31' + comment.dbmin -3450 + comment.dbmax 1200 + iface MIXER + name 'Line Playback Volume' + value.0 0 + value.1 0 + } + control.22 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'CD Playback Switch' + value true + } + control.23 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 31' + comment.dbmin -3450 + comment.dbmax 1200 + iface MIXER + name 'CD Playback Volume' + value.0 25 + value.1 25 + } + control.24 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Video Playback Switch' + value false + } + control.25 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 31' + comment.dbmin -3450 + comment.dbmax 1200 + iface MIXER + name 'Video Playback Volume' + value.0 0 + value.1 0 + } + control.26 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Aux Playback Switch' + value false + } + control.27 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 31' + comment.dbmin -3450 + comment.dbmax 1200 + iface MIXER + name 'Aux Playback Volume' + value.0 0 + value.1 0 + } + control.28 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'PCM Playback Switch' + value true + } + control.29 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 31' + comment.dbmin -3450 + comment.dbmax 1200 + iface MIXER + name 'PCM Playback Volume' + value.0 22 + value.1 22 + } + control.30 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 2 + comment.item.0 Mic + comment.item.1 CD + comment.item.2 Video + comment.item.3 Aux + comment.item.4 Line + comment.item.5 Mix + comment.item.6 'Mix Mono' + comment.item.7 Phone + iface MIXER + name 'Capture Source' + value.0 Line + value.1 Line + } + control.31 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Capture Switch' + value true + } + control.32 { + comment.access 'read write' + comment.type INTEGER + comment.count 2 + comment.range '0 - 15' + comment.dbmin 0 + comment.dbmax 2250 + iface MIXER + name 'Capture Volume' + value.0 0 + value.1 0 + } + control.33 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name '3D Control - Switch' + value false + } + control.34 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 Mix + comment.item.1 Mic + iface MIXER + name 'Mono Output Select' + value Mix + } + control.35 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 Mic1 + comment.item.1 Mic2 + iface MIXER + name 'Mic Select' + value Mic1 + } + control.36 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 15' + iface MIXER + name '3D Control - Center' + value 0 + } + control.37 { + comment.access 'read write' + comment.type INTEGER + comment.count 1 + comment.range '0 - 15' + iface MIXER + name '3D Control - Depth' + value 0 + } + control.38 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Alternate Level to Surround Out' + value false + } + control.39 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Downmix LFE and Center to Front' + value false + } + control.40 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Downmix Surround to Front' + value false + } + control.41 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'External Amplifier' + value true + } + control.42 { + comment.access read + comment.type BYTES + comment.count 52 + iface CARD + name 'ICE1724 EEPROM' + value '172414121c01020210c1ff0000ff0000ff0000000101010001000000000000000000000000000000ff000000ff000000ff000000' + } + control.43 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 '8000' + comment.item.1 '9600' + comment.item.2 '11025' + comment.item.3 '12000' + comment.item.4 '16000' + comment.item.5 '22050' + comment.item.6 '24000' + comment.item.7 '32000' + comment.item.8 '44100' + comment.item.9 '48000' + comment.item.10 '64000' + comment.item.11 '88200' + comment.item.12 '96000' + comment.item.13 '176400' + comment.item.14 '192000' + comment.item.15 'IEC958 Input' + iface MIXER + name 'Multi Track Internal Clock' + value '44100' + } + control.44 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Multi Track Rate Locking' + value false + } + control.45 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'Multi Track Rate Reset' + value true + } + control.46 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 'PCM Out' + comment.item.1 'H/W In 0' + comment.item.2 'H/W In 1' + comment.item.3 'IEC958 In L' + comment.item.4 'IEC958 In R' + iface MIXER + name 'H/W Playback Route' + value 'PCM Out' + } + control.47 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 'PCM Out' + comment.item.1 'H/W In 0' + comment.item.2 'H/W In 1' + comment.item.3 'IEC958 In L' + comment.item.4 'IEC958 In R' + iface MIXER + name 'H/W Playback Route' + index 1 + value 'PCM Out' + } + control.48 { + comment.access read + comment.type INTEGER + comment.count 22 + comment.range '0 - 255' + iface MIXER + name 'Multi Track Peak' + value.0 0 + value.1 0 + value.2 0 + value.3 0 + value.4 0 + value.5 0 + value.6 0 + value.7 0 + value.8 255 + value.9 255 + value.10 0 + value.11 0 + value.12 0 + value.13 0 + value.14 0 + value.15 0 + value.16 0 + value.17 0 + value.18 0 + value.19 0 + value.20 0 + value.21 0 + } + control.49 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 'PCM Out' + comment.item.1 'H/W In 0' + comment.item.2 'H/W In 1' + comment.item.3 'IEC958 In L' + comment.item.4 'IEC958 In R' + iface MIXER + name 'IEC958 Playback Route' + value 'PCM Out' + } + control.50 { + comment.access 'read write' + comment.type ENUMERATED + comment.count 1 + comment.item.0 'PCM Out' + comment.item.1 'H/W In 0' + comment.item.2 'H/W In 1' + comment.item.3 'IEC958 In L' + comment.item.4 'IEC958 In R' + iface MIXER + name 'IEC958 Playback Route' + index 1 + value 'PCM Out' + } + control.51 { + comment.access 'read write' + comment.type BOOLEAN + comment.count 1 + iface MIXER + name 'IEC958 Output Switch' + value true + } + control.52 { + comment.access 'read write' + comment.type IEC958 + comment.count 1 + iface PCM + device 1 + name 'IEC958 Playback Default' + value '0000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + } + control.53 { + comment.access read + comment.type IEC958 + comment.count 1 + iface PCM + device 1 + name 'IEC958 Playback Con Mask' + value '3fff000f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + } + control.54 { + comment.access read + comment.type IEC958 + comment.count 1 + iface PCM + device 1 + name 'IEC958 Playback Pro Mask' + value df00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + } +} diff --git a/abs/core-testing/tweaker/lib/Tweaker/Definitions.pm b/abs/core-testing/tweaker/lib/Tweaker/Definitions.pm new file mode 100644 index 0000000..cbadf29 --- /dev/null +++ b/abs/core-testing/tweaker/lib/Tweaker/Definitions.pm @@ -0,0 +1,66 @@ +# Copyright 2007 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +package Tweaker::Definitions; +use List::Member; +use Log::Log4perl qw(:easy); + +# To install the above modules: +# -- +# sudo cpan install List::Member + +# Recommendation Levels +my $bottom = -200; # a reserved value, under which no recommendationlevel can go +my $not_available = -100; +my $unsupported = -99; +my $inadvisable = -50; +my $optional = 0; +my $recommended = 100; + +# Interactivity Levels +my $guided = "guided"; +my $minimal = "minimal"; + +# Special variables +my $null = "null"; # reserved as the script name for special Tweaks that define Tweaker behavior + +my %global_variable_hash = ( + "bottom" => $bottom, + "not available" => $not_available, + "unsupported" => $unsupported, + "inadvisable" => $inadvisable, + "optional" => $optional, + "recommended" => $recommended, + "guided" => $guided, + "minimal" => $minimal, + "null" => $null +); + +sub get_global_variable_value { + my ($variable) = @_; + + my @known_variables = keys %global_variable_hash; + if (member($variable, @known_variables) + 1) { + if ($global_variable_hash{$variable}) { + return $global_variable_hash{$variable}; + } + } else { + my $logger = get_logger(); + $logger->error("No Tweaker Definition for variable named $variable"); + return $bottom; + } +} + +1; diff --git a/abs/core-testing/tweaker/lib/Tweaker/Script.pm b/abs/core-testing/tweaker/lib/Tweaker/Script.pm new file mode 100644 index 0000000..ec3a42a --- /dev/null +++ b/abs/core-testing/tweaker/lib/Tweaker/Script.pm @@ -0,0 +1,353 @@ +# Copyright 2007, 2008 Robert ("Bob") Igo of StormLogic, LLC and mythic.tv. +# +# 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 <http://www.gnu.org/licenses/>. + +package Tweaker::Script; + +use strict; +use DBI; +use Switch; +use Tweaker::Definitions; + +# To install the above modules: +# -- +# sudo apt-get install libdbi-perl liblog-log4perl-perl +# sudo cpan install Getopt::Lucid List::Member +# choose the defaults for all options, agree to install all dependencies + +use Getopt::Lucid qw( :all ); +# see http://search.cpan.org/~dagolden/Getopt-Lucid-0.16/lib/Getopt/Lucid.pm for usage details +use Log::Log4perl qw(get_logger); +# see http://search.cpan.org/~mschilli/Log-Log4perl-1.14/lib/Log/Log4perl.pm for usage details +# http://www.perl.com/pub/a/2002/09/11/log4perl.html is highly recommended as well + +use List::Member; + +my $dbh; # the database we connect to +my $sth; # +my $TWEAKER_ROOT; +my @known_options; + +# Print advice on usage and invocation. +sub help () { + my $logger = get_logger('tweaker.script'); + $logger->fatal("USAGE:\n$0 [--check Option] [--implement Option] [--poll Option] [--iterations] [--help]"); + $logger->fatal("Valid values for Option are: ", join(" ",@known_options)); + $logger->fatal("Only one of the above parameters may be passed."); + $logger->fatal("The --check and --iterations parameters are not yet supported."); + exit; +} + +sub execute_shell_command { + my($command) = @_; + my $results=""; + my $logger = get_logger('tweaker.script'); + + open(SHELL, "$command 2>&1 |"); + + while(<SHELL>) { + $results=$results."".$_; + } + close(SHELL); + chop($results); + $logger->debug("Command '$command' produced output '$results'"); + return $results; +} + +# Simple way to get the value of an environment variable from the executing shell. +sub get_environment_variable { + my($envvar) = @_; + open(SHELL, "echo $envvar|"); + while(<SHELL>) { + chop; + return $_; + } + close(SHELL); +} + +sub get_mythtv_connection_string { + # we want something like mythconverg:localhost + my $dbname = ""; + my $dbhostname = ""; + open(MYSQLTXT, "< /home/mythtv/.mythtv/mysql.txt"); + while(<MYSQLTXT>) { + if (/DBName=(.*)/) { + $dbname=$1; + } elsif (/DBHostName=(.*)/) { + $dbhostname=$1; + } + } + close(MYSQLTXT); + + return "$dbname:$dbhostname"; +} + +sub get_mythtv_authentication { + # we want something like ['root', ''] + my $dbusername = ""; + my $dbpassword = ""; + + open(MYSQLTXT, "< /home/mythtv/.mythtv/mysql.txt"); + while(<MYSQLTXT>) { + if (/DBUserName=(.*)/) { + $dbusername=$1; + } elsif (/DBPassword=(.*)/) { + $dbpassword=$1; + } + } + close(MYSQLTXT); + + return ($dbusername, $dbpassword); +} + +# Database routines. +sub connect_to_db { + my ($db) = @_; + my $logger = get_logger('tweaker.script'); + my ($dbusername, $dbpassword) = get_mythtv_authentication(); + if (!($dbh = DBI->connect($db, $dbusername, $dbpassword))) { + $logger->error("Couldn't connect to database: ", DBI->errstr); + return -1; + } + return 1; +} + +sub disconnect_from_db { + $dbh->disconnect; +} + +sub do_query { + my ($query) = @_; + my $logger = get_logger('tweaker.script'); + my $rv=""; + + $logger->debug("Processing statement: ", $query); + + if (!($sth = $dbh->prepare($query))) { + $logger->error("Couldn't prepare statement: ", $dbh->errstr); + return -1; + } + $rv = $sth->execute(); # Returns an integer when rows were affected; returns -1 when there's an + # error; returns 0E0 (true) when no error but no rows affected. + + if (!$rv) { + $logger->error("Couldn't execute statement: ", $sth->errstr); + return -1; + } + return $rv; +} + +# Make sure the option passed to this script is handled. +sub validate_option { + my($option) = @_; + + if (!(member($option, @known_options) + 1)) { + my $logger = get_logger('tweaker.script'); + $logger->fatal("Option '$option' is not known to $0."); + $logger->fatal("Valid Options are: ", join(", ",@known_options)); + exit -1; + } + return 1; +} + +# Prints out each option that the script handles, separated by '|'. +# This allows for a minimal .tcf entry. +sub get_options { + print join("|",@known_options),"\n"; +} + +# Prints out the passed Recommendation Level first, followed by any other +# strings, separated by '|'. This allows the author of a Tweaker Script to +# return explanatory information along with a Recommendation Level. +sub recommendation_level { + print join("|",@_),"\n"; +} + +sub process_parameters () { + # Accept these parameters: + # -- + my @parameters = ( + Switch("help")->anycase, + Param("check")->anycase, # Requirement 1.1 + Param("implement")->anycase, # Requirement 1.2 + Param("poll")->anycase, # Requirement 1.3 + Switch("iterations")->anycase, # Requirement 1.4 + Switch("getoptions")->anycase # Requirement 1.5 + ); + my $opt = Getopt::Lucid->getopt( \@parameters ); + + if (!(my $TWEAKER_ROOT = get_environment_variable("\$TWEAKER_ROOT"))) { + Log::Log4perl->easy_init(); + my $logger = get_logger(); + $logger->fatal("ERROR: \$TWEAKER_ROOT environment variable is not set."); + exit -1; + } else { + my $log4perl_conf = "$TWEAKER_ROOT/log4perl.conf"; + Log::Log4perl::init_and_watch($log4perl_conf,10); + my $logger = get_logger('tweaker.script'); + $logger->info("\$TWEAKER_ROOT is '$TWEAKER_ROOT'."); + } + + if ($opt->get_help > 0) { + help; + } + + my $check = $opt->get_check; + my $implement = $opt->get_implement; + my $poll = $opt->get_poll; + my $iterations = $opt->get_iterations; + my $getoptions = $opt->get_getoptions; + + # Requirement 1.6 + if ($check) { + if ($implement || $poll || $iterations || $getoptions) { + help; + } + validate_option($check); # exits with an error if option is invalid + check_option($check); # Requirement 1.1 + } elsif ($implement) { + if ($poll || $iterations || $getoptions) { + help; + } + validate_option($implement); # exits with an error if option is invalid + implement_option($implement); # Requirement 1.2 + } elsif ($poll) { + if ($iterations || $getoptions) { + help; + } + validate_option($poll); # exits with an error if option is invalid + poll_options($poll); # Requirement 1.3 + } elsif ($iterations) { + if ($getoptions) { + help; + } + #count_iterations; # Requirement 1.4 + } elsif ($getoptions) { + get_options; # Requirement 1.5 + } else { + help; + } +} + +sub set_known_options { + my(@options) = @_; + @known_options = @_; +} + +# These entries may or may not already exist. First, try updating them, and if that fails, insert them. +# Pass in array references for setfields and checkfields. Each must +# reference an array of lists, where each list is a key, value pair, e.g. +# [["data", "somedata"], ["name", "skippy"]] +sub change_or_make_entry { + my($table, $setfields, $checkfields) = @_; + my $query_string = "UPDATE $table SET "; + + my $fields=""; + foreach my $sets (@$setfields) { + if ($fields) { + $fields = $fields . ", "; + } + $fields = $fields . "@$sets[0]='@$sets[1]' "; + } + $query_string = $query_string . $fields . "WHERE "; + + my $checkstring=""; + foreach my $checks (@$checkfields) { + if ($checkstring) { + $checkstring = $checkstring . "AND "; + } + $checkstring = $checkstring . "@$checks[0]='@$checks[1]' "; + } + $query_string = $query_string . $checkstring; + + my $rv = do_query($query_string); + if (($rv == 0E0) || ($rv < 1)) { # UPDATE didn't apply; do an insert + my $fields=""; + my $values=""; + foreach my $sets (@$setfields) { + if ($fields) { + $fields = $fields . ", "; + $values = $values . ", "; + } + $fields = $fields . "@$sets[0]"; + $values = $values . "'@$sets[1]'"; + } + foreach my $sets (@$checkfields) { + if ($fields) { + $fields = $fields . ", "; + $values = $values . ", "; + } + $fields = $fields . "@$sets[0]"; + $values = $values . "'@$sets[1]'"; + } + + $query_string = "INSERT INTO $table (". $fields . ") VALUES (" . $values . ")"; + + $rv = do_query($query_string); + } + return $rv; +} + +# We update so many entries in the settings table that a subroutine makes coding and readability easier. +sub change_or_make_setting { + my($value, $data) = @_; + + return(change_or_make_entry("settings", [["data", $data]], [["value", $value]])); +} + +# Benchmark-driven tests for low, medium, or high "performance" often look the same. +# If your test falls into this pattern, you can use this subroutine to simplify your +# Tweaker Script's poll_options subroutine. +# NOTE: This only handles options for low, medium, or high right now. +# NOTE: You don't have to use this! Only use it if your poll_options subroutine +# would look like this anyway. Don't shoehorn it to fit! +sub threshold_test { + my($option, $benchmark_number, $name_of_benchmarked_device, $low_threshold, $medium_threshold, $high_threshold) = @_; + # e.g. ("medium", 512, "video card", 350, 425, 500) + + my $logger = get_logger('tweaker.script'); + $logger->debug("Threshold test for option '$option' ($name_of_benchmarked_device) with benchmark of $benchmark_number, where: low = $low_threshold, medium = $medium_threshold, high = $high_threshold"); + + switch ($option) { + case "low" { + if ($benchmark_number <= $low_threshold) { + recommendation_level("recommended", "Your $name_of_benchmarked_device seems to be unable to handle higher usage than this."); + } elsif ($benchmark_number <= $medium_threshold) { + recommendation_level("optional", "Your $name_of_benchmarked_device seems to be able to handle higher usage than this, but select this option if you want to reduce overall $name_of_benchmarked_device usage."); + } elsif ($benchmark_number >= $high_threshold) { + recommendation_level("optional", "Your $name_of_benchmarked_device seems to be quite capable of this setting, but select this option if you want to reduce overall $name_of_benchmarked_device usage."); + } + } + case "medium" { + if ($benchmark_number <= $low_threshold) { + recommendation_level("inadvisable", "Your $name_of_benchmarked_device seems to be unable to handle this usage level, but you are free to try."); + } elsif ($benchmark_number <= $medium_threshold) { + recommendation_level("recommended", "Your $name_of_benchmarked_device seems to be unable to handle higher usage than this."); + } elsif ($benchmark_number >= $high_threshold) { + recommendation_level("optional", "Your $name_of_benchmarked_device seems to be able to handle higher usage than this, but select this option if you want to reduce overall $name_of_benchmarked_device usage."); + } + } + case "high" { + if ($benchmark_number <= $low_threshold) { + recommendation_level("inadvisable", "Your $name_of_benchmarked_device seems to be unable to handle this usage level, and it is not recommended that you try."); + } elsif ($benchmark_number <= $medium_threshold) { + recommendation_level("inadvisable", "Your $name_of_benchmarked_device seems to be unable to handle this usage level, but you are free to try."); + } elsif ($benchmark_number >= $high_threshold) { + recommendation_level("recommended", "Your $name_of_benchmarked_device seems to be quite capable of this setting."); + } + } + } +} + +1; diff --git a/abs/core-testing/tweaker/tcf/EXAMPLE.tcf b/abs/core-testing/tweaker/tcf/EXAMPLE.tcf new file mode 100644 index 0000000..0064fba --- /dev/null +++ b/abs/core-testing/tweaker/tcf/EXAMPLE.tcf @@ -0,0 +1,38 @@ +<!-- This is an example TCF. See TCFProgrammingSpecifications.odt for details. + //--> +<tweak name = "Put a human-readable name for the tweak here. Make sure it's unique."> <!-- REQUIRED //--> + <description>Put a human-readable description of the tweak here.</description> <!-- OPTIONAL but usually a good idea, unless the user + will never see the description. + //--> + <complexity>Put a complexity level here.</complexity> <!-- OPTIONAL human-readable assessment of how complex this Tweak is to understand. + A complete list of complexity levels is listed in tweaker-core.tcf + //--> + <script>twk_EXAMPLE.pl</script> <!-- REQUIRED: An executable script in the $PATH of the shell that invoked Tweaker. + For consistency, adhere to the naming convention by beginning the script name with + 'twk_'. You can make the tweaker script in any language you wish, but Perl is + supported well. + //--> + <alwaysaskuser>boolean</alwaysaskuser> <!-- OPTIONAL field with values: yes, no - not used in Tweaker v0.7 + //--> + <options> <!-- REQUIRED //--> + <option name = "Human-readable name for this option"> <!-- REQUIRED: Option names must match those handled in the + corresponding tweaker script. + //--> + <description>Human-readable description of what this option does.</description> <!-- OPTIONAL //--> + <complexity>Put a complexity level here.</complexity> <!-- OPTIONAL human-readable assessment of how complex this Tweak is to + understand. A complete list of complexity levels is listed in + tweaker-core.tcf + //--> + <recommendationlevel>recommendationlevel</recommendationlevel> <!-- OPTIONAL human-readable recommendation level for this tweak. + If this field is absent, the script will be run to acquire + the recommendationlevel. The default recommendationlevel + is $optional if it cannot otherwise be determined. For a + complete list of recommendation levels, see Tweaker/Definitions.pm + //--> + </option> + <!-- Put any additional options here. If you only have one option and it ends up with a recommendationlevel at or above $optional, + it will be selected automatically. Otherwise, the option with the highest recommendationlevel above $optional will be selected. + //--> + </options> +</tweak> +<!-- Put any additional tweaks here. //--> diff --git a/abs/core-testing/tweaker/tcf/focus.tcf b/abs/core-testing/tweaker/tcf/focus.tcf new file mode 100644 index 0000000..353662c --- /dev/null +++ b/abs/core-testing/tweaker/tcf/focus.tcf @@ -0,0 +1,113 @@ +<tweak name = "SQL table scrubber"> + <script>twk_scrub_sql.pl</script> + <description>Scrubs the sections of mythconverg that KnoppMyth controls, preparing for the Tweaks below.</description> + <options> + <option name = "scrub"> + <description>Everyone should run this, or some the Tweaks below may fail.</description> + <recommendationlevel>recommended</recommendationlevel> + </option> + </options> +</tweak> +<tweak name = "Audio"> + <script>twk_audio.pl</script> + <description>Configures MythTV, xine, and mplayer to output audio the way you want.</description> + <options> + <option name = "analogstereo"> + <description>Suitable for output to headphones, amplified speakers, or analog inputs on a receiver.</description> + <recommendationlevel>recommended</recommendationlevel> + </option> + <option name = "analogsurround"> + <description>Suitable for direct output to multiple individual speakers.</description> + </option> + <option name = "digital"> + <description>The best option if your hardware supports it. Sends audio directly to a reciever to be processed.</description> + </option> + </options> +</tweak> +<tweak name = "CPU"> + <script>twk_cpu.pl</script> + <description>Configures MythTV to use CPU-appropriate features and themes.</description> + <options> + <option name = "low"> + <description>Uses the least amount of CPU but enables the fewest extra options.</description> + </option> + <option name = "medium"> + <description>Uses a moderate amount of CPU and enables typical extra options.</description> + </option> + <option name = "high"> + <description>Uses the most amount of CPU of the above options but enables the most extra options.</description> + </option> + </options> +</tweak> +<tweak name = "RAM"> + <script>twk_RAM.pl</script> + <description>Configures MythTV to use the right-sized RAM cache for various options.</description> + <options> + <option name = "low"> + <description>Uses the least amount of RAM but may cause buffering delays.</description> + </option> + <option name = "medium"> + <description>Uses a moderate amount of RAM as a tradeoff between buffering and RAM usage.</description> + </option> + <option name = "high"> + <description>Uses the most amount of RAM to reduce buffering and improve performance.</description> + </option> + </options> +</tweak> +<tweak name = "graphics"> + <script>twk_graphics.pl</script> + <description>Configures MythTV to use graphical options that are appropriate for your video card.</description> + <options> + <option name = "low"> + <description>Puts little stress on the video card.</description> + </option> + <option name = "medium"> + <description>Puts the video card to work a bit and enables some eye candy.</description> + </option> + <option name = "high"> + <description>Puts the video card hardest to work and enables more eye candy.</description> + </option> + </options> +</tweak> +<tweak name = "localization"> + <script>twk_localization.pl</script> + <description>Configures the system to use your native language, system of measurements, etc.</description> + <options> + <option name = "US_English"> + <description>This is for most North Americans. Any units seen are in imperial units, such as Fahrenheit, pounds, feet, etc.</description> + </option> + <option name = "GB_English"> + <description>This is for most UK residents. Any units seen are in metric, such as Celsius, kilograms, meters, etc.</description> + </option> + </options> +</tweak> +<tweak name = "Tuner Configuration"> + <script>twk_tuners.pl</script> + <description>Recommended for everyone.</description> + <options> + <option name = "all"> + <description>Detects and auto-configures many tuner devices.</description> + <recommendationlevel>recommended</recommendationlevel> + </option> + </options> +</tweak> +<tweak name = "KnoppMyth Customizations"> + <script>twk_general.pl</script> + <description>Recommended for everyone.</description> + <options> + <option name = "all"> + <description>Changes made to the MythTV and KnoppMyth baseline settings for integration and functionality.</description> + <recommendationlevel>recommended</recommendationlevel> + </option> + </options> +</tweak> +<tweak name = "SQL table protecter"> + <script>twk_scrub_sql.pl</script> + <description>Protects the sections of mythconverg that KnoppMyth controls, keeping our changes separate from user-made changes.</description> + <options> + <option name = "protect"> + <description>Everyone should run this, or user-made changes might get clobbered.</description> + <recommendationlevel>recommended</recommendationlevel> + </option> + </options> +</tweak> diff --git a/abs/core-testing/tweaker/tcf/os.tcf b/abs/core-testing/tweaker/tcf/os.tcf new file mode 100644 index 0000000..e70f4ee --- /dev/null +++ b/abs/core-testing/tweaker/tcf/os.tcf @@ -0,0 +1,10 @@ +<tweak name = "Linux-related Customizations"> + <script>twk_linux.pl</script> + <description>Recommended for everyone.</description> + <options> + <option name = "all"> + <description>Changes made to the Linux baseline settings for integration and functionality.</description> + <recommendationlevel>recommended</recommendationlevel> + </option> + </options> +</tweak> diff --git a/abs/core-testing/tweaker/tcf/tcf.dtd b/abs/core-testing/tweaker/tcf/tcf.dtd new file mode 100644 index 0000000..64ce67e --- /dev/null +++ b/abs/core-testing/tweaker/tcf/tcf.dtd @@ -0,0 +1,11 @@ +<!ELEMENT tcf (tweak+)> +<!ELEMENT tweak (description?, complexity?, script, alwaysaskuser?, options)> + <!ATTLIST tweak name CDATA #REQUIRED> +<!ELEMENT description (#PCDATA)> +<!ELEMENT complexity (#PCDATA)> +<!ELEMENT script (#PCDATA)> +<!ELEMENT alwaysaskuser (#PCDATA)> +<!ELEMENT options (option+)> +<!ELEMENT option (description?, complexity?, recommendationlevel?)> + <!ATTLIST option name CDATA #REQUIRED> +<!ELEMENT recommendationlevel (#PCDATA)> diff --git a/abs/core-testing/tweaker/tcf/tweaker-core.tcf b/abs/core-testing/tweaker/tcf/tweaker-core.tcf new file mode 100644 index 0000000..d9c4bb6 --- /dev/null +++ b/abs/core-testing/tweaker/tcf/tweaker-core.tcf @@ -0,0 +1,47 @@ +<?xml version="1.0" ?> +<!DOCTYPE tcf SYSTEM "/usr/LH/tweaker/tcf/tcf.dtd" [ + <!ENTITY os SYSTEM "/usr/LH/tweaker/tcf/os.tcf"> +<!-- <!ENTITY distro SYSTEM "/usr/LH/tweaker/tcf/distro.tcf"> //--> + <!ENTITY focus SYSTEM "/usr/LH/tweaker/tcf/focus.tcf"> + <!ENTITY userland SYSTEM "/usr/LH/tweaker/tcf/userland.tcf"> + ]> +<tcf> + <tweak name = "Complexity Level"> + <description>Some configuration options require more understanding than others.</description> + <complexity>basic</complexity> + <script>null</script> + <options> + <option name = "Basic"> + <description>Show only the most basic configuration options. This is best for new Users.</description> + <recommendationlevel>recommended</recommendationlevel> + </option> + <option name = "Intermediate"> + <description>Show the basic configuration options as well as the options that veteran Users will understand.</description> + </option> + <option name = "Advanced"> + <description>Show all configuration options, including those that only advanced Users will understand.</description> + <recommendationlevel>inadvisable</recommendationlevel> + </option> + </options> + </tweak> + <tweak name = "Interactivity"> + <description>Tweaker can guess answers to some configuration options. Interactivity determines whether or not these guesses are used automatically, or whether you have a chance to intervene.</description> + <complexity>basic</complexity> + <script>null</script> + <options> + <option name = "Minimal"> + <description>Show only the most basic configuration options. This is best for new Users.</description> + <recommendationlevel>inadvisable</recommendationlevel> + </option> + <option name = "Guided"> + <description>Show the basic configuration options as well as the options that veteran Users will understand.</description> + <recommendationlevel>recommended</recommendationlevel> + </option> + </options> + </tweak> + &os; + &distro; + &focus; + &userland; +</tcf> + diff --git a/abs/core-testing/tweaker/tcf/userland.tcf b/abs/core-testing/tweaker/tcf/userland.tcf new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/abs/core-testing/tweaker/tcf/userland.tcf diff --git a/abs/core-testing/tweaker/tweaker.tar.bz2 b/abs/core-testing/tweaker/tweaker.tar.bz2 Binary files differdeleted file mode 100644 index 6fd6a92..0000000 --- a/abs/core-testing/tweaker/tweaker.tar.bz2 +++ /dev/null |