| 1 | #!/usr/bin/perl -w |
|---|
| 2 | |
|---|
| 3 | my $version = '0.1'; |
|---|
| 4 | |
|---|
| 5 | use strict; |
|---|
| 6 | |
|---|
| 7 | use Data::Dumper; |
|---|
| 8 | use XMLTV::Ask; |
|---|
| 9 | |
|---|
| 10 | my $config; |
|---|
| 11 | my $s; |
|---|
| 12 | |
|---|
| 13 | print "GConf Builder for Shepherd\n\n"; |
|---|
| 14 | |
|---|
| 15 | my $grabber = lc(ask("Name of grabber? ")); |
|---|
| 16 | |
|---|
| 17 | die "I don't think so.\n" if ($grabber eq 'shepherd'); |
|---|
| 18 | |
|---|
| 19 | print "\nCATEGORY: Grabber Type\n\n" . |
|---|
| 20 | "Grabbers generally fall into two categories:\n" . |
|---|
| 21 | "(1) Grabbers that fetch detailed data by downloading one page\n" . |
|---|
| 22 | " per show\n" . |
|---|
| 23 | "(2) Grabbers that either cannot fetch detailed data, or fetch\n" . |
|---|
| 24 | " it for many shows with each download (e.g. one download\n" . |
|---|
| 25 | " per day, or one download for all shows)\n" . |
|---|
| 26 | "Category 1 grabbers tend to be slow and use relatively large\n" . |
|---|
| 27 | "amounts of bandwidth. Category 2 grabbers are quite fast\n" . |
|---|
| 28 | "and download relatively few files.\n\n"; |
|---|
| 29 | $config->{category} = ask_choice("Which category is $grabber?", 1, 1, 2); |
|---|
| 30 | |
|---|
| 31 | print "\nCATEGORY: Channel type\n\n" . |
|---|
| 32 | "If $grabber supports free-to-air channels only, just hit enter.\n" . |
|---|
| 33 | "If $grabber supports paytv only, enter 'paytv' below.\n" . |
|---|
| 34 | "If $grabber supports both paytv and free-to-air, enter 'both' below.\n\n"; |
|---|
| 35 | $config->{type} = ask("Channel types supported?"); |
|---|
| 36 | |
|---|
| 37 | print "\nCATEGORY: Channels Supported\n\n" . |
|---|
| 38 | "Enter the names of channels supported by $grabber. If $grabber\n" . |
|---|
| 39 | "supports all free-to-air channels, just hit Enter. If it supports\n" . |
|---|
| 40 | "a limited number of channels, enter these separated by commas\n" . |
|---|
| 41 | "(e.g. \"SBS,SBS News\"). If it supports most channels with a\n" . |
|---|
| 42 | "limited number of exceptions, enter a minus sign then a list\n" . |
|---|
| 43 | "of the exceptions, separated by spaces (e.g. \"-ABC,Nine\").\n" . |
|---|
| 44 | "Please use standard channel names (e.g. Nine, TEN, Seven, etc).\n\n"; |
|---|
| 45 | |
|---|
| 46 | $config->{channels} = ask("Channels supported?"); |
|---|
| 47 | $config->{channels} =~ s/ /_/g; |
|---|
| 48 | |
|---|
| 49 | print "\nCATEGORY: Days Supported\n\n" . |
|---|
| 50 | "Enter the maximum number of days of data $grabber can retrieve.\n\n"; |
|---|
| 51 | |
|---|
| 52 | $config->{max_days} = ask("Days supported? [default=7]"); |
|---|
| 53 | $config->{max_days} ||= 7; |
|---|
| 54 | |
|---|
| 55 | print "\nSome grabbers aren't always able to retrieve the maximum number\n" . |
|---|
| 56 | "of days, because their datasource isn't always topped up. Enter\n" . |
|---|
| 57 | "the minimum number of days of data that $grabber can reliably fetch.\n\n"; |
|---|
| 58 | |
|---|
| 59 | $config->{max_reliable_days} = ask("Days reliably supported? [default=7]"); |
|---|
| 60 | $config->{max_reliable_days} ||= 7; |
|---|
| 61 | |
|---|
| 62 | my $example = $config->{max_days} - 1; |
|---|
| 63 | print "\nIf $grabber retrieves different numbers of days of data for different\n". |
|---|
| 64 | "channels, specify that here. For example, if $grabber retrieves\n". |
|---|
| 65 | "$config->{max_days} days of data for most channels, but only $example of ABC2 and SBS News,\n" . |
|---|
| 66 | "enter \"ABC2:$example,SBS News:$example\". If $grabber doesn't vary by channel, just hit Enter.\n\n"; |
|---|
| 67 | $s = ask("Channel variations of days supported?"); |
|---|
| 68 | if ($s) |
|---|
| 69 | { |
|---|
| 70 | my %h; |
|---|
| 71 | my @a = split(/,\s*/, $s); |
|---|
| 72 | foreach my $chday (@a) |
|---|
| 73 | { |
|---|
| 74 | if ($chday =~ /(.*):(\d+)/) |
|---|
| 75 | { |
|---|
| 76 | $h{$1} = $2; |
|---|
| 77 | } |
|---|
| 78 | } |
|---|
| 79 | $config->{max_days_per_chan} = \%h; |
|---|
| 80 | } |
|---|
| 81 | |
|---|
| 82 | print "\nCATEGORY: Regions Supported\n\n" . |
|---|
| 83 | "Enter the region IDs supported by $grabber. If $grabber supports\n" . |
|---|
| 84 | "all regions, just hit Enter. If it supports a limited number of regions,\n" . |
|---|
| 85 | "enter these separated by spaces (e.g. \"94 104 118\"). If it supports\n" . |
|---|
| 86 | "most but not all regions, enter a minus sign followed by a list of the\n" . |
|---|
| 87 | "unsupported regions (e.g. \"-112 114 128\").\n\n"; |
|---|
| 88 | |
|---|
| 89 | $config->{regions} = ask("Regions supported?"); |
|---|
| 90 | |
|---|
| 91 | print "\nCATEGORY: Configuration Requirements\n\n" . |
|---|
| 92 | "Specify whether $grabber requires any manual configuration\n" . |
|---|
| 93 | "before it can run (such as registration on a remote web site).\n\n"; |
|---|
| 94 | |
|---|
| 95 | if (ask_boolean("Requires manual configuration?")) |
|---|
| 96 | { |
|---|
| 97 | $config->{config_reqd} = 1; |
|---|
| 98 | |
|---|
| 99 | print "\nShepherd needs a way of detecting whether $grabber has been\n" . |
|---|
| 100 | "correctly configured or not. Please enter a command-line option\n" . |
|---|
| 101 | "that will cause $grabber to exit with status 0 if it is configured\n" . |
|---|
| 102 | "correctly, and exit with another status if it is not.\n\n"; |
|---|
| 103 | $config->{option_ready} = ask("Command-line option for readiness? [default=--ready]"); |
|---|
| 104 | $config->{option_ready} ||= '--ready'; |
|---|
| 105 | |
|---|
| 106 | print "\nShepherd needs to know the commend-line parameter $grabber uses\n" . |
|---|
| 107 | "uses for manual configuration. This will be used when the user\n" . |
|---|
| 108 | "runs shepherd's --configure option.\n\n"; |
|---|
| 109 | $config->{option_config} = ask("Command-line option for configure? [default=--configure]"); |
|---|
| 110 | $config->{option_config} ||= '--configure'; |
|---|
| 111 | } |
|---|
| 112 | else |
|---|
| 113 | { |
|---|
| 114 | print "\nShepherd needs a way to run $grabber just to check that it compiles\n" . |
|---|
| 115 | "on the user's system. Please enter a command-line option that will cause\n" . |
|---|
| 116 | "$grabber to exit with status 0 as quickly as possible, i.e. preferably\n" . |
|---|
| 117 | "without fetching any data.\n\n"; |
|---|
| 118 | $config->{option_ready} = ask("Command-line option for compilation check? " . |
|---|
| 119 | "[default=--version]"); |
|---|
| 120 | $config->{option_ready} ||= '--version'; |
|---|
| 121 | } |
|---|
| 122 | |
|---|
| 123 | print "\nCATEGORY: Data Quality\n\n" . |
|---|
| 124 | "Rate the accuracy of the data $grabber fetches; i.e. how often it\n" . |
|---|
| 125 | "can be relied upon to report the right programs in the right timeslots.\n" . |
|---|
| 126 | "(This is a measure of the source $grabber relies upon rather than a\n". |
|---|
| 127 | "a judgement of $grabber itself.)\n" . |
|---|
| 128 | "(1) Guide data is often inaccurate\n" . |
|---|
| 129 | "(2) Guide data is occasionally or sometimes inaccurate\n" . |
|---|
| 130 | "(3) Guide data is 100% accurate, or very close to it\n\n"; |
|---|
| 131 | |
|---|
| 132 | $config->{quality} = ask_choice("Data quality?", 3, 1, 2, 3); |
|---|
| 133 | |
|---|
| 134 | print "\nCATEGORY: Granularity\n\n" . |
|---|
| 135 | "Specify whether $grabber is able to fetch data in slices,\n" . |
|---|
| 136 | "as opposed to having to fetch all or nothing.\n\n"; |
|---|
| 137 | |
|---|
| 138 | if (ask_boolean("Can $grabber fetch a single day of data only?", 1)) |
|---|
| 139 | { |
|---|
| 140 | print "\nWhat option needs to be sent to $grabber to specify the\n" . |
|---|
| 141 | "number of days wanted? (E.g. if $grabber supports an option\n" . |
|---|
| 142 | "\"--days n\", where n is the number of days to fetch data for,\n". |
|---|
| 143 | "enter \"--days\").\n\n"; |
|---|
| 144 | $config->{option_days} = ask("Command-line option for max days? " . |
|---|
| 145 | "[default=--days]"); |
|---|
| 146 | $config->{option_days} ||= '--days'; |
|---|
| 147 | |
|---|
| 148 | print "\nWhat option needs to be sent to $grabber to specify that it should\n" . |
|---|
| 149 | "not start grabbing at day 1? (E.g. if $grabber supports an option\n" . |
|---|
| 150 | "\"--offset n\", which indicates that it should skip the first\n" . |
|---|
| 151 | "n days, enter \"--offset\".)\n\n"; |
|---|
| 152 | $config->{option_days_offset} = ask("Command-line option for offset? " . |
|---|
| 153 | "[default=--offset]"); |
|---|
| 154 | $config->{option_days_offset} ||= '--offset'; |
|---|
| 155 | |
|---|
| 156 | print "\nIf invoked with the command:\n" . |
|---|
| 157 | " ./$grabber $config->{option_days} 2 $config->{option_days_offset} 1\n" . |
|---|
| 158 | "... how many days of data will $grabber fetch?\n\n"; |
|---|
| 159 | $s = ask("Days fetched? [default=2]"); |
|---|
| 160 | $s ||= 2; |
|---|
| 161 | unless ($s == 2) |
|---|
| 162 | { |
|---|
| 163 | $config->{option_offset_eats_days} = 1; |
|---|
| 164 | } |
|---|
| 165 | |
|---|
| 166 | print "\nDoes $grabber support Shepherd-compliant micro-grabbing? Micro-\n". |
|---|
| 167 | "grabbing is when a grabber fetches a small part a single day; for\n". |
|---|
| 168 | "example, 2:30pm to 2:45pm. In order to be compliant, $grabber must be\n". |
|---|
| 169 | "able to interpret the --gaps_file <s> command-line option, where <s>\n". |
|---|
| 170 | "is the file name of a Shepherd gaps data structure.\n\n"; |
|---|
| 171 | if (ask_boolean("Does $grabber support micro-grabbing?")) |
|---|
| 172 | { |
|---|
| 173 | $config->{micrograbs} = 1; |
|---|
| 174 | } |
|---|
| 175 | } |
|---|
| 176 | |
|---|
| 177 | if ($config->{category} == 1) |
|---|
| 178 | { |
|---|
| 179 | print "\nCATEGORY: Verified Caching\n\n" . |
|---|
| 180 | "Category 1 grabbers often have an internal cache. They can use this\n" . |
|---|
| 181 | "to greatly reduce the amount of downloads necessary, by returning the\n" . |
|---|
| 182 | "cached data rather than fetching it anew. An important part of this\n" . |
|---|
| 183 | "process is verification, or checking to make sure that the schedule\n" . |
|---|
| 184 | "hasn't changed significantly from the cache.\n\n"; |
|---|
| 185 | |
|---|
| 186 | $config->{cache} = ask_boolean("Can $grabber reduce downloads by through verified caching?", 1); |
|---|
| 187 | } |
|---|
| 188 | |
|---|
| 189 | print "\nCATEGORY: Running Time\n\n". |
|---|
| 190 | "One of the key attributes of shepherd is that it handles failure\n" . |
|---|
| 191 | "of individual grabbers. It is possible that a grabber could fail in such\n" . |
|---|
| 192 | "a manner that it never finishes or runs for an excessive amount of time.\n\n"; |
|---|
| 193 | $config->{max_runtime} = ask("How many minutes (maximum) should Shepherd allow $grabber to run for? [default=60]"); |
|---|
| 194 | $config->{max_runtime} ||= '60'; |
|---|
| 195 | |
|---|
| 196 | print "\nCATEGORY: TOR\n\n" . |
|---|
| 197 | "Some grabbers work better (faster) if they fetch data via multiple\n" . |
|---|
| 198 | "sources. Tor (The Onion Router, tor.eff.org) makes it possible\n" . |
|---|
| 199 | "to do this, allowing a single user to fetch data via multiple\n" . |
|---|
| 200 | "endpoints around the internet. $grabber can make use of this\n" . |
|---|
| 201 | "if it is useful; Shepherd can signal to a grabber that this\n" . |
|---|
| 202 | "is available via a command-line parameter (e.g. --socks localhost:9050).\n" . |
|---|
| 203 | "If this grabber supports SOCKS and wishes to use Tor, provide the\n". |
|---|
| 204 | "command-line option to enable it here, or blank if not desired/required.\n\n"; |
|---|
| 205 | $config->{option_anon_socks} = ask("Anon SOCKS command-line option (or blank)?"); |
|---|
| 206 | |
|---|
| 207 | print "\nCATEGORY: Description\n\n" . |
|---|
| 208 | "Please enter a brief description of $grabber.\n\n"; |
|---|
| 209 | |
|---|
| 210 | $config->{desc} = ask("Description?"); |
|---|
| 211 | |
|---|
| 212 | print "\nCONFIGURATION COMPLETE!\n\n" . |
|---|
| 213 | "Grabber: $grabber\n" . |
|---|
| 214 | Dumper($config); |
|---|
| 215 | |
|---|
| 216 | abort() unless (ask_boolean("\nDo you want to go ahead and create $grabber.conf?")); |
|---|
| 217 | |
|---|
| 218 | if (-e "$grabber.conf") |
|---|
| 219 | { |
|---|
| 220 | print "WARNING: $grabber.conf already exists!\n"; |
|---|
| 221 | abort() unless (ask_boolean("Do you want to overwrite $grabber.conf?")); |
|---|
| 222 | } |
|---|
| 223 | |
|---|
| 224 | print "Creating $grabber.conf.\n"; |
|---|
| 225 | open(CONF, ">$grabber.conf") or die "cannot write to $grabber.conf: $!"; |
|---|
| 226 | print CONF Data::Dumper->Dump([$config], ['config']); |
|---|
| 227 | close CONF; |
|---|
| 228 | |
|---|
| 229 | print "Done.\n"; |
|---|
| 230 | |
|---|
| 231 | sub abort |
|---|
| 232 | { |
|---|
| 233 | print "Aborting.\n"; |
|---|
| 234 | exit; |
|---|
| 235 | } |
|---|