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 /abs/core-testing | |
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.
Diffstat (limited to 'abs/core-testing')
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 |