pax_global_header00006660000000000000000000000064140527321130014510gustar00rootroot0000000000000052 comment=fbdc386baf56f5bf1133f53842644667340145a2 vdr-plugin-epgsearch-2.4.1/000077500000000000000000000000001405273211300155425ustar00rootroot00000000000000vdr-plugin-epgsearch-2.4.1/.gitignore000066400000000000000000000002221405273211300175260ustar00rootroot00000000000000/createcats /.dependencies /.dependencies_doc /.doc_stmp /MANUAL /README.DE /doc/ /html/ /man/ /po/epgsearch.pot /po/*.mo *.o *.so *.tgz *.tmp *~ vdr-plugin-epgsearch-2.4.1/COPYING000066400000000000000000000431061405273211300166010ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. vdr-plugin-epgsearch-2.4.1/HISTORY000066400000000000000000002237261405273211300166420ustar00rootroot00000000000000VDR Plugin 'epgsearch' Revision History --------------------------------------- 2021-05-24; Version 2.4.1 fixes: - Fixed conflictcheck for encrypted channels with internal CAMs - Fixed compiling with gcc11 - Updated deprecated calls to SetItemEvent - Temporally(?) added #define DISABLE_TEMPLATES_COLLIDING_WITH_STL for compatibility with vdr 2.5.4 2021-04-12 new: - Improved handling of remote timers - Replace auto_ptr with unique_ptr for c++11 (kfb77@vdr-portal.de) - Delay threads after pluginstart 10 secs (configurable) - Changed fgets to allow compiling with clang - Clarified "avoid repeats". Forced subtitle-comparison is named "yes" again New option "allow empty" fixes: - Fixed several lock sequence errors - Fix utf-8 encoding in docs and manpages (kfb77 and seahawk1986@vdr-portal.de) - Fixed possible format overflow - Fixed displaying NAME in generated manpages thanks to etobi 2018-04-16; Version 2.4.0 new: - Create man pages only once. by jasminj@vdr-portal.de - Remove useless member "useEpisode" from cBlacklist by jasminj@vdr-portal.de - Remove useless member "useEpisode" from cBlacklist by jasminj@vdr-portal.de - Remove useless "LOCK_CHANNELS_READ" in cBlacklist run by jasminj@vdr-portal.de - Change shell in docsrc2*.sh to /bin/bash, suggested by TomJoad@vdr-portal.de - Added operator to cListObject derived classes by jasminj@vdr-portal.de - Add patches/vdr.epgsearch-exttimeredit-2.3.5.diff by Dietmar Spingler - Adapt new makefile style of VDR 2.3.6 by TomJoad@vdr-portal.de - Use vdr timerids instead of index by TomJoad@vdr-portal.de - Fix many lock sequences by TomJoad@vdr-portal.de - New vdr.epgsearch-exttimeredit-2.3.6.diff (thx to Claus Muus) - Add conflict check for remote timers by Johann Friedrichs - Search timers should create only local timers - Use namespace for svdrpclient - Add icon for inactive timer - Use separate thread for recdone processing - get rid of some casts - unified indentation - Preserve timerflags in searchtimerupdate 2017-05-xx; Version 2.3.1 - development release new: - Commit vdr-2.3.2-epgsearch-1.0.1.beta5~git20150715_v2.diff by fnu@vdr-portal.de based on inputs from kamel5, mini73 & TomJoad @ vdr-portal.de => http://www.vdr-portal.de/board17-developer/board97-vdr-core/p1284612-produktive-problem-und-pluginl%C3%B6sungen-f%C3%BCr-vdr-2-3-2-und-h%C3%B6her/#post1284612 - Commit 0004-Added-patches-vdr.epgsearch-exttimeredit-2.3.3.diff.diff by jasminj@vdr-portal.de => http://www.vdr-portal.de/board17-developer/board21-vdr-plugins/p1289938-epgsearch-f%C3%BCr-vdr-2-3-x/#post1289938 - Commit 0005-epgsearch-inactive-records-v2.diff by jasminj@vdr-portal.de => http://www.vdr-portal.de/board17-developer/board21-vdr-plugins/p1289983-epgsearch-f%C3%BCr-vdr-2-3-x/#post1289983 - Commit 0001-Fix-warning-in-pending_notifications.c.diff by jasminj@vdr-portal.de - Commit 0002-Fixed-warnings-in-man-page-generation.diff by jasminj@vdr-portal.de => http://www.vdr-portal.de/board17-developer/board21-vdr-plugins/p1289704-epgsearch-f%C3%BCr-vdr-2-3-x/#post1289704 - Commit 0003-Use-HandleRemoteTimerModifications-instead-of-Handle.diff by jasminj@vdr-portal.de => http://www.vdr-portal.de/board17-developer/board21-vdr-plugins/p1289764-epgsearch-f%C3%BCr-vdr-2-3-x/#post1289764 - Commit menu_category_recsdone.diff by tomas & louis @vdr-portal.de http://www.vdr-portal.de/board1-news/board2-vdr-news/p1271995-skindesigner-1-0-0-neuer-default-skin-estuary4vdr/#post1271995 - Commit 0001-revert-seperate-status-thread.diff by TomJoad@vdr-portal.de - Commit 0002-fix-incorrect-lock-sequences.diff by TomJoad@vdr-portal.de - Commit 0003-revert-now-obsolete-pointer-params.diff by TomJoad@vdr-portal.de - Commit 0004-some-small-fixes.diff by TomJoad@vdr-portal.de http://www.vdr-portal.de/board17-developer/board21-vdr-plugins/p1291452-epgsearch-f%C3%BCr-vdr-2-3-x/#post1291452 - Drop legacy code prior VDR 2.3.x - Commit 0001-fixed-unresponsive-vdr.diff by TomJoad@vdr-portal.de - Commit 0002-removed-variableduplications.diff by TomJoad@vdr-portal.de - Commit 0003-more-cleanups.diff by TomJoad@vdr-portal.de - Commit 0004-Remote-timers-in-menu-myedittimer.diff by TomJoad@vdr-portal.de http://www.vdr-portal.de/board17-developer/board21-vdr-plugins/p1291771-epgsearch-f%C3%BCr-vdr-2-3-x/#post1291771 - Commit fixblacklist_handling.diff by TomJoad@vdr-portal.de http://www.vdr-portal.de/board16-video-disk-recorder/board99-distributionen/board107-mld/p1292085-epgsearch-in-verbindung-mit-epgd-epg2vdr-live-absturz-unter-vdr-2-3-4/#post1292085 - Commit epgsearch_min_max_from_stl.diff by jasminj@vdr-portal.de http://www.vdr-portal.de/board17-developer/board21-vdr-plugins/p1292145-epgsearch-f%C3%BCr-vdr-2-3-x/#post1292145 2013-03-xx; Version 1.0.1 - maintenance release new: - new Makefile style as introduced in vdr-1.7.36, the old Makefile still exists as Makefile.before.1.7.36 for previous vdr builds. Many thanks to Copperhead, Stefan Hofmann and Christopher Reimer for their work. - implement device bonding in conflict checker, thanks to Joachim Wilke for providing a patch - new service interface "Epgsearch-enablesearchtimers-v1.0" to switch the search timers background update on/off. Updated the sample in source/vdr-epgsearchclient-0.0.2.tgz to use the new service. - new format specifier like %02i in the epgsearchcats.conf, thanks to Joe_D for providing a patch ('man 5 epgsearchcats.conf' for more information). - in the menu 'recordings done' you can now toggle the blue key to 'Orphaned' to show recordings with vanished search timers. - when channel separators are displayed the filling '-' can cause problems in the output of graphlcd. Set PLUGIN_EPGSEARCH_SEP_ITEMS=--- in your Make.config to avoid this. Most skins (except classic, st:tng) will translate '---' into a single line anyway (Feature #857, thanks to 'KeineAhnung' for providing a patch) - search timers are now processed by their descending timer priority. Search timers with the same priority are sorted by their search term. Thanks to Anonym for providing a patch - new bugtracker at http://projects.vdr-developer.org/projects/plg-epgsearch - thanks to Tobias Grimm - dropped old code for vdr < 1.6.0, thanks to Ville Skyttä for whole pile of patches - updated MainMenuHooks patch to 1.0.1 - czech translation, thanks to Radek Stastny fixes: - fixed a memory leak, thanks to Sundararaj Reel for the patch - fixed a crash when editing blacklists 2011-09-11; Version 1.0.0 new: - supports vdr-1.6.0 to vdr-1.7.21 - avoid repeats with new 'compare date' entry: compare two events by their date to ignore repeats within the same day, week or month - global blacklists: blacklists for search timers can now be global to exclude generally unwanted events (like on my double SD/HD channels). Default mode for search timers is now 'only global', but can be set to 'none' to ignore also global blacklists. - new setup variable epgsearch.ConflCheckCmd (no gui for this, so edit setup.conf!), that allows executing a command for each timer causing a conflict, see the MANUAL for details. - vdr-1.7.15 has changed the SVDRP default port to 6419, please update this in epgsearch's setup menu too! - there is now an official git repository for epgsearch, that contains the latest development. First usage: git clone git://projects.vdr-developer.org/vdr-plugin-epgsearch.git Keep up-to-date with: git pull Web-git: http://projects.vdr-developer.org/git/?p=vdr-plugin-epgsearch.git many thanks to the maintainers of projects.vdr-developer.org, especially Tobias Grimm - directory entries from VDR's folders.conf are now also read and offered in the directory selection of the timer menu. - Search timer support for content descriptors as introduced in vdr-1.7.11. This lets you search for broadcasts by their type, like "Movie/Drama", "Documentation",... - Search timers now have a new action "Announce and switch". This announces the event via OSD right before it starts and lets you switch to its channel with 'Ok'. Switch timers now have the same option. - in addition to the announcements via OSD new events can now also be reported by mail. To do so, there's a new search timer action "Announce by mail". You also have to update your mail template file epgsearchupdmail.templ (s. the updated html sample in the conf directory and/or read the MANUAL '13. Email notification'). - The time in hours between the search timer mails can now be configured in the setup to avoid flooding your inbox. epgsearch buffers the contents of the pending mails in the new file pendingnotifications.conf. - New setup option to check if there is EPG content for the next x hours. If not you get warned by OSD and/or mail (Setup -> Search and search timers), suggested by Andreas Mair. - new internal variables: * %day%, %month% and %year% which return the numeric day, month and year (with century) of an event * %chgrp% returns the VDR channel group name corresponding to an event * %liveeventid% returns the encoded event ID as used in the frontend 'live' to add direct links e.g. in the search timer mails (see sample conf/epgsearchupdmail-html.templ). * %timer.liveid% returns the encoded timer ID as used in the frontend 'live' to add direct links e.g. in the search timer mails. * %date_iso% and %date_iso_now% return the (current) date in 'YYYY-MM-DD' format, suggested by Andreas Mair. * %search.series% returns 1 or 0 depending on the flag "series recording" of a search and can be used in the directory entry of a search or its depending variables. - new command 'connect' within internal variables: with this command you can connect to a TCP service, pass data and assign the result to a variable. See the MANUAL for details. - new command 'length' within internal variables: this returns the length of the given arguments - in memory to pat: french translation update, thanks to Patrice Staudt - italian translation update, thanks to Diego Pierotto - finnish translation update, thanks to Rolf Ahrenberg and Ville Skyttä - new lithuanian translation, thanks to Valdemaras Pipiras - new slovak translation, thanks to Milan Hrala - new SVDRP command 'MENU [NOW|PRG|SUM]' to call one of the main OSD menus or the summary of the current event. If any epgsearch menu is open a subsequent SVDRP call will close it again. - changed the maximum number of days for a timer conflict check from 99 to 14 - patch by Jörg Wendel for new graphtft patch - Two events with both empty episode names are now handled different within the feature 'Avoid repeats'. This will result in more recordings, but ensures not to miss one only because of a buggy EPG. - searchtimers: if a timers filename results in an empty string or contains "!^invalid^!" it will be skipped for programming now. - Avoid repeats: The option 'Yes' for 'Compare subtitle' is now replaced with 'if present'. With this setting epgsearch will classify two events only as equal if their episode names match and are not empty. - epgsearch now uses the shutdown handler (introduced in vdr 1.5.1) to prevent a search timer update to be interrupted. - the SVDRP command UPDS for triggering search timer updates has now a new option 'SCAN' that will execute an EPG scan before the search timer update actually starts. - when deleting a search timer now its list of created timers is also cleared, suggested by Sundararaj Reel - moved 'file' and 'directory' to the top in the timer edit menu, since at least in my case its the most common entry to change, e.g. to select a folder for the recording. - auto enable Wareagle icons if VDRSymbols font is used (can be overwritten with WarEagleIcons=0 in epgsearchmenu.conf), suggested by Ronny Kornexl - the correct content encoding for mail notifications is now automatically detected - epgsearch now autodetects an installed pin plugin or graphtft, also the optional libraries libpcre und libtre (can be turned off by commenting AUTOCONFIG in the Makefile) - new patch vdr.epgsearch-exttimeredit.diff: this patch against VDR integrates epgsearch's timer edit menu to VDR's timer menu, thanks S:oren@vdr-portal for providing it. - some speed enhancements, thanks to Tobias Bratfisch for providing patches - if the VPS time differs from the start time of an event the VPS marker is now 'v' instead of 'V' - the first run of the background threads (searchtimer, switchtimer, conflict check) is now triggered by the first call to cPlugin::MainThreadHook instead of waiting 20s after VDRs startup. - The update check for manual timers does now ignore timers whose start or stop time was edited by the user. - default path to sendmail is now '/usr/sbin/sendmail' and can be configured in the Makefile, thanks to Ville Skyttä for providing a patch. - externally triggered search timer updates (via service interface or SVDRP) will now automatically activate the setting "Use search timers" in the setup. - epgsearch now also checks the recordings length among the correct start and stop time of a timer when testing for complete recordings. 98% and more are handled as complete. - switch timers are now also visible in all search results EPG menus - Avoid repeats: in 'compare summary' one can now adjust the required match, default is 90%. - if there is no subtitle the filename now defaults to YYYY.MM.DD-HH.MM-Weekday to ease sorting in some frontends, thanks to Dominic Evans for providing a patch - should now compile in FreeBSD, thanks to Juergen Lock for providing a patch - new SVDRP command UPDT to reload the list of search timers in epgsearch.conf fixes: - fixed a crash when pressing 'Ok' in an empty timers done menu - fixed a crash when using the progressbar and events with 0 duration exist, thanks to egal@vdrportal - when an incomplete recording triggers a search timer update for a search timer with 'avoid repeats' now running events are ignored for the repeats. - now using cCondWait::Wait instead of cCondWait:SleepMs to avoid shutdown problems, thanks to e9hack@vdrportal for providing a patch - fixed line breaks in SVDRP command LSTT, thanks to Andreas Mair for providing a patch - improved response time when canceling the search timer thread - fixed a segfault occurring when navigating to a userdefined epg menu that has expired in the meantime, thanks to Mike Constabel for reporting - the day selection menu in the timer edit menu was hidden - if an event was matched by multiple search timers with 'announce only' setting, it was also listed more than once. Thanks to Andreas Mair for reporting. - fixed a bug in search timer announcements concerning the display of the corresponding search timer - fixed some memory leaks, thanks to Bittor Corl for providing a patch - some fixes to compile with gcc-4.4, thanks to firefly@vdrportal for providing a patch - fixed wrong man section of some man pages, thanks to Ville Skyttä for providing a patch - some fixes regarding libtre includes, thanks to Ville Skyttä for providing a patch - fix UTF8-character handling in timer file names, thanks to Rolf Ahrenberg for providing a patch - fixed a crash when adding huge episode names to the timer's file name, thanks to Lari Tuononen for reporting - make sure only one regular expression library is linked against epgsearch, thanks to Ville Skyttä for providing a patch. - some providers have strange EPG time changes only by some seconds. epgsearch now ignores changes less than 60s and does not touch the corresponding timer or report by mail, thanks to cmichel@mantis for reporting - possible fix of the old problem with a crash in libpcre, thanks to Andreas Cz. for the patch and to Stefan Bauer for pointing me to it. - fix a crash when toggling between with/without subtitle in timer info view for events that have (very) long "short" texts, thanks to Ville Skyttä for providing a patch. - fixed file descriptor handling when there are errors in SVDRP communication, thanks to Teemu Rantanen for providing a patch. - fixed the service interface for switchtimers because of wrong parameter handling, thanks to gnapheus@vdrportal for reporting. - fixed case insensitve searching when Utf-8 characters are involved, thanks to Ville Skyttä for reporting - fixed check of complete VPS recordings, thanks to durchflieger@vdr-portal for providing a patch. 2008-04-29: Version 0.9.24 new: - support for vdr-1.6.x/1.7.x - speedup in searching and search timer updates (about 25%) - speedup in EPG menues, thanks to patch authors from http://www.open7x0.org - support for VDRSymbols font (activate it with 'WarEagle=1' in epgsearchmenu.conf) - the EPG command 'Search in recordings' now evaluates the info.vdr instead of the recordings path name and also does fuzzy searching, suggested by Mase@vdrportal - search timers with action 'switch only' and switch timers now have an additional option 'unmute sound' which unmutes audio at the event, if it was off, suggested by Michael Brückner - the timer update notification mails supports now an additional variable %timer.modreason%, that holds the reason for a timer update in plain text (see epgsearchupdmail(-html).templ for a sample) - support for a conf.d mechanism (s. MANUAL -> 14. The conf.d subdirectory), suggested by Mike Constabel. - new SVDRP command 'LSCC' that returns the results of a timer conflict check. See the MANUAL for details about the format of the result list. - new patch against VDR (vdr-1.5.17-progressbar-support-0.0.1.diff) that adds support for graphical progressbars in skins classic and st:tng, thanks to zulu@vdrportal - '0' in the menu of done recordings now toggles the display of the episode name only - the favorites menu can now also be displayed after 'Overview - Now' via setup, suggested by Bittor Corl - menu of recordings done now sorts the date top down - support for new info key behaviour in vdr-1.5.13 - changes for builtin graphtft-patch (when using VDR-extension-patch you need > v.37) - updated the timercmd-patch for vdr-1.5.12 (patches/timercmd-0.1_1.5.12.diff) - added patches/README.patches to describe the existing patches - update of 'undoneepgsearch.sh', a script to remove recordings from the done file via reccmds.conf, thanks to Viking@vdrportal. - update of finnish translation, thanks to Rolf Ahrenberg - full spanish translation, many thanks to agusmir, dragondefuego, GenaroL, lopezm and nachofr from todopvr.com, and especially to bittor - update of italian translation, thanks to Diego Pierotto - update of dutch translation, thanks to carel@bugtracker - the setup option "No announcements when replaying" is now ignored, if the search timer update was triggered manually, suggested by Andreas Mair. fixes: - shifting the time display: the start time now only gets displayed in 'Overview - Now' instead of a progressbar, if there's not already a start time in the menu template ('%time%') as in the default template, thanks to Getty@vdrportal for reporting - fixed some issues regarding GPL, thanks to Thomas Günther for reporting - fixed a crash when no EPG is present, thanks to Petri Helin for providing a patch - the default value for maximum duration is now '23:59' to avoid problems with external tools, thanks to ralf-naujokat@bugtracker for reporting (bug-id #371) - after an EPG change of less then 10 minutes epgsearch modified a timer instead of creating a new one. This caused problems with events with less then 10 minutes. The tolerance is therefore now min(, 10 min). Thanks to Janne Liimatainen for reporting. - fixed some translations, thanks to ramirez@vdrportal for reporting - speed improvement when scrolling through EPG menus, thanks to ramirez@vdrportal for reporting - fixed a crash, when SIGINT is signaled while background threads startup - channel group separators in 'Overview Now/Next/...' are now hidden if they are empty like in ':@30', thanks to Ulf Kiener for providing a patch - fixed a crash in the setup of the addon plugins when VDR is patched with the ext-patch and active LIEMIKUUTIO - 'avoid repeats' combined with 'pause on ... recordings' created to less timers, thanks to spockele@vdrportal for reporting - fixed some compiler warnings with g++ 4.3 - fine-tuning fuzzy matching of descriptions, thanks to Alf Fahland for providing a patch - fixed a problem with pipes in the pattern of blacklists, thanks to Andreas Mair for reporting. - fixed labeling the green/yellow color keys after toggling the keys in menu 'Schedule', thanks to Andreas Mair for reporting. - fixed evaluation of compiler flags like WITHOUT_EPGSEARCHONLY,... 2007-09-02: Version 0.9.23 new: - full support for new i18n system in vdr>=1.5.7, but keeps fully backwards compatible - when using extended EPG categories one can now also compare by value, e.g. to search for events after some year. Therefore new searchmodes (10 which means '<', 11 which means '<=', ...) were introduced in the file epgsearchcats.conf. Example: # 'until year' 3|Year|until year||11 # 'from year' 12|Year|from year||13 One could use this also to search for a specific season of a series, if this data is part of the EPG. See the section in the documentation for a complete list of all search modes. - The edit menu for search timers has now a switch 'Ignore missing categories' for extended EPG categories. If set to 'Yes' this tells epgsearch that a missing EPG category should not exclude an event from the results. Caution: Using this without any other criterions could flood your timers. - Search timers have now an 'auto delete' feature. The edit menu therefor provides: * after x recordings, or * after x days after first recording Only complete recordings are counted. The deletion of the search timer is executed directly after the end of the corresponding recording - new action "Create a copy" in menu Search/Actions to create and edit a copy of the current search, suggested by Michael Brückner. - the option "use as search timer" has now a third value 'user defined' besides 'yes' and 'no', that allows specifying a time margin where the search timer is active, suggested by jo01@vdrportal - the progressbar now displays the start time instead of an empty bar, when shifting to future events, thanks to zulu@vdrportal for providing a patch. - menu "show timers created" shows now summary for the timers done with 'Ok'. Also the shortcuts '1..9' for the EPG-commands are available. - built-in pin-plugin patch (no more need to patch epgsearch). Activate it by compiling with 'USE_PINPLUGIN' in VDR's Make.config (as already done in VDR extension patch) - built-in graphtft-plugin patch (no more need to patch epgsearch). Activate it by compiling with 'USE_GRAPHTFT' in VDR's Make.config (as already done in VDR extension patch) - update of finnish translation, thanks to Rolf Ahrenberg - update of french translation, thanks to Patrice Staudt - added file README.Translators with notes for translators fixes: - fixed a bug in timer creation after navigating through the summary menu, thanks to Rolf Ahrenberg for reporting - Label "Record" or "Timer" in menu summary fixed with respect to existing timer. - fixed switch timers in the case when EPG has changed, thanks to Juergen Urban for providing a patch - fixed some compiler warnings in g++-4.2, thanks to Michael Brückner for reporting - added "," to the allowed characters for a search timer, thanks to Mike Constabel for reporting. 2007-05-27: Version 0.9.22 new: - new option in timer conflict check "When a recording starts": This performs a conflict check when any recording starts and informs about it via OSD if the conflict is within the next 2h. So also timers not created with epgsearch are checked, the same for instant recordings. - new service interface "Epgsearch-services-v1.0": This allows other plugins to access and manage many components of epgsearch as searchtimers, setup values,... and execute tasks like searching for repeats (Have a look at services.h for more information). - new project homepage: http://winni.vdr-developer.org/epgsearch, many thanks to Thomas Keil, sorry, only german at the moment ;) - update for finnish translation, thanks to Rolf Ahrenberg fixes: - complete rewrite of the summary menu and its navigation to avoid problems with skins and fix some other bugs. - when testing for repeats now also the comparison with the done-file only checks the alphanumeric portions of title and episode - fixed another issue with quotes when calling commands for EPG events - some license changes and additions for integration in Debian repositories - fixed a bug in displayed time, when using user defined times and shifting with FRew/FFwd, thanks to Torsten Weigelt for reporting - the aux info about the channel was not added in 'one press timer creation'. Thanks to Rolf Ahrenberg for providing a patch. 2007-04-29: Version 0.9.21 new: - support for the new MainMenuHooksPatch. This replaces the vdr-replace-schedulemenu patch. The new patch is used by other plugins too, so from now on only one patch is needed. The old patch is still supported, but this will be removed in the next releases. - announcements of broadcasts via OSD have been completely redesigned. Instead of displaying them event by event, you get now "x new broadcast(s) found! Show them?". Pressing 'Ok' shows a menu of all events with the usual functions as in other EPG menus. With "Edit" you can modify the announce settings (like "announce again: yes/no" or announce again after day x). - timer conflict notifications via OSD can now be suppressed while replaying. Nevertheless, if a conflict comes up within the next 2 hours the message gets still displayed. - all addon plugins (epgsearchonly, quickepgsearch, conflictcheckonly) now have a setup option to toggle the main menu entry on/off, thanks to Tobias Grimm for providing a patch. - channel name in aux info of manual timers, thanks to Rolf Ahrenberg for providing a patch. - new script undoneepgsearch.sh to undo a timer within the recordings menu, more info at: http://www.vdr-portal.de/board/thread.php?postid=574109#post574109 Thanks to the author Christian Jacobsen - update for french translation, thanks to Patrice Staudt - update for finnish translation, thanks to Rolf Ahrenberg - menu 'timer conflicts details' now also shows the date of the conflict in menu title, suggested by Rusk@vdrportal. - the password for mail authentication is now hidden in the OSD, i.e. represented with '***...' - the setup for mail notifications now also has a "Send to" address, because some providers don't allow the same address for sender and recipient. If "Send to" is not set, epgsearch automatically uses the sender address as recipient. - when testing for repeats (with feature 'Avoid repeats') epgsearch now only compares the alphanumeric portions of title and episode and ignores the case too. Suggested by chello@vdrportal. - thanks to Rolf Ahrenberg for finnish translation update - added '&' to the set of valid chars for search terms fixes: - the tags stored in the aux info of the timers created with search timers conform now to correct XML syntax (no capitals, no blanks). E.g. "Search timer" will be changed to "searchtimer". So don't wonder if the first search timer update will modify all existent timers created with search timers. Thanks to Rolf Ahrenberg for reporting. - update of recordingdone.sh because of the previous changes, thanks to Mike Constabel for providing a patch - fixed a segfault in the case of misconfigured extended EPG categories. - scrolling text items now works again, if your skin supports this. Thanks to ufauser@vdrportal for reporting. - setup option "Use search timers" now always gets automatically enabled, if one toggles a search to 'active' or manually starts a search timer update. - fixed handling of double quotes in title/episode when passed to userdefined EPG commands, thanks to Mike Constabel for reporting. - fixed menu handling in search timer templates menu, thanks to wombel@vdrportal for reporting. 2007-01-30: Version 0.9.20 new: - support for vdr-1.5.0. Note: the CA support in the timer conflict check is highly experimental because I have no CAMs to test it! - epgsearch can now also modify manual timers according to EPG changes. When using epgsearch's own timer edit menu you can select between * no check * by event ID * by channel/time Please refer to the README (1.4.4 Setup/Timer Programming/Default timer check method) for further notes. - the timespan used in the favorites menu can now be adjusted via setup. Default is 24h. - Event announcements: If the user presses one of the keys 'Ok', '0', ... '9' while the announcement of an event is displayed, he will be asked if further announcements of this event should be disabled for ever (user hit '0' or 'Ok') or for the next 'x' days (user hit '1' to '9'). After pressing 'Ok' again, this setting will be stored. - With the new setup option "No announcements when replaying" you can now suppress any announcements of broadcasts when you currently replay anything. Suggested by Andreas Mair. - Besides the done file for recordings there is now a done file for timers (timersdone.conf). This allows deleting timers without getting them again with the next search timer update. With the new menu 'Show timers created' in Search/Actions one can edit this list. The whole feature can be disabled in the search timers setup. Note: the done list is only populated with timers that were newly created with this release. - new addon plugin 'quickepgsearch': it creates a main menu entry 'Quick search' and can be used to search for any event in the EPG. Include it with '-Pquickepgsearch' , suggested by SurfaceCleanerZ@vdrportal. - new setup option "Limit channels from 1 to" to speed up epgsearchs call. If the current channel is above the limit, all channels will be displayed. Suggested by Uwe@vdrportal. - new SVDRP commands: * 'LSRD' returns a list of all recording directories used in existing recordings, timers, search timers or as specified in epgsearchdirs.conf * 'LSTT [ID]' to list all search templates, or the one with the passed ID (format is the same as epgsearch.conf) * 'NEWT ' to add a new search template REMARK: the value of element ID is ignored. epgsearch will always assign the next free ID * 'DELT ' to delete the search template with ID * 'EDIT ' to modify an existing search template * 'DEFT [ID]' returns the ID of the default search template. When passing an ID it activates the corresponding template as default. - modified SVDRP commands: * 'DELS [ID] [DELT]' now also deletes created timers for search with ID when passing the optional 'DELT'. - you can now also use sendmail for mail delivery besides the script sendemail.pl (-> setup), suggested by Patrick Cernko - new variables: * '%timespan%' to be used in menus or mails. It will be replaced with the timespan from now to the begin of an event (e.g. 'in 15m'). It is now used in the default menu template of the favorites menu, where the date field was removed. * '%length%' for the length of a broadcast in seconds. - thanks to Rolf Ahrenberg for finnish translation update fixes: - manually created timers are now neither deleted nor modified by any search timers. - the addon conflictcheckonly was compiled even if WITHOUT_CONFLICTCHECKONLY was defined in the Makefile, thanks to Ronny Kornexl for reporting. - search term and directory support now the characters 'ß' (only for language german) and '@'. - 'avoid repeats' had a bug (in some special cases) that created a timer for any later repeat instead of the first event. - a search with "Use day of week" AND "Use time" where "Start before" is after midnight now also matches events on the next day til "Start before". E.g. "Start after 22:00" and "Start before 03:00" on monday will also match an event at 01:00 at tuesday. - already recording timers are now modified only, if the timers stop time has changed (e.g. by an EPG update), thanks to Mike Constabel for reporting. - fixed a bug in evaluation of user variables, thanks to Mike Constabel for reporting and remote debugging - fixed a bug in conflict mail notification concerning timers without assigned events 2006-10-27: Version 0.9.19 new: - if search results of different searches intersect, now only the search that initially created a corresponding timer may modify it. - new variables: * '%search.query%' to be used in the recording directory of a search timer. Will be substituted to the query of a search timer. * '%videodir%' VDR video directory (e.g. /video) * '%plugconfdir%' VDR plugin config directory (e.g. /etc/vdr/plugins) * '%epgsearchdir%' epgsearchs config directory (e.g. /etc/vdr/plugins/epgsearch) - the syntax of the 'system' command within a user variable has changed to be more flexible. It's now: %uservar%=system(/path/to/script[, parameters]) where the optional 'parameters' can now be any expression using other variables except directly using conditional expressions or other system calls. - update for french translation, thanks to Patrice Staudt fixes: - VPS timers created by search timers are now always updated to their VPS time, even if the user has changed start/stop time. - after editing the setup any menu templates defined in epgsearchmenu.conf were reset to defaults, thanks to s.krueger@vdrportal for reporting. - existing VDR serial timers are not modified anymore to regular timers by the search timer update. 2006-10-01: Version 0.9.18 new: - IMPORTANT!!! PLEASE READ THIS!: epgsearch expects its conf files now in a separate configuration directory 'epgsearch' and not in the general plugin configuration directory as with previous versions! Please create this directory in your plugins configuration directory and move all epgsearch-files to it before running this version. Like this: mkdir /etc/vdr/plugins/epgsearch mv /etc/vdr/plugins/epgsearch*.* /etc/vdr/plugins/epgsearch mv /etc/vdr/plugins/.epgsearch* /etc/vdr/plugins/epgsearch This is only important if you don't already use epgsearchs '--config' or '-c' parameter. - new 'Favorites menu' besides 'Now' and 'Next': This menu can show a list of all your favorite broadcasts for the next 24h. To enable it activate 'Show favorites menu' in the setup. To let epgsearch know what your favorites are create/edit some searches and enable 'Use in favorites menu'. - new setup option for timer conflict check: 'After each timer programming'. This performs a conflict check after each manual timer programming and - if the new/modified timer is involved in a conflict - pops up an OSD message about it. - new email notifications about search timer updates or timer conflicts with a customizable mail content. Please refer to the MANUAL section 'Email notification' for further details. - epgsearch has now a set of man pages. A very BIG thanks to Mike Constabel (vejoun@vdrportal) who did the complete job of rewriting/correcting and formatting the current docs. The man pages cover the README's, MANUAL and a documentation of all conf's that epgsearch uses. Available for german and english. Install them with 'make install-doc' in epgsearch's src-directory. - you can now define your own variables to be used in the default recordings directory, search timer recording directory or your own menu templates. Since this is quite complex please refer to the MANUAL section 'User defined variables'. Just an example to see what is possible: # Weekday, Date, Time %DateStr%=%time_w% %date% %time% # Themes or Subtitle or Date %ThemesSubtitleDate1%=%Subtitle% ? %Subtitle% : %DateStr% %ThemesSubtitleDate%=%Themes% ? %Themes% : %ThemesSubtitleDate1% # Calls this script to get a recording path %DocuScript%=system(doku.pl,%Title%,%Subtitle%,%Episode%,%Themes%,%Category%,%Genre%) %Docu%=%DocuScript% - key 'Ok' can now also be configured to switch to a channel instead of displaying the summary, suggested by malachay@vdrportal. - if a timer was created by a search timer then epgsearch's own timer edit menu now displays the name of the search timer in a non selectable item at the bottom of the menu. - when an event is announced via search timers you can now create a timer for it, when you press the red key while the announce is visible, suggested by Andreas Mair - if search timers are disabled by setup then creating/editing a search timer now automatically activates them in setup, suggested by Andreas Mair. - you can now use more than one menu template for search results, please refer to the MANUAL section "Customizing the EPG menus". - the check for a complete recording now also accepts short breaks (< 2s, e.g. a channel pid change) - new SVDRP commands: * LSTC [channel group name] list all channel groups or if given the one with name 'group name' * NEWC create a new channel group, format as in epgsearchchangrps.conf * EDIC modify an existing channel group, format as in epgsearchchangrps.conf * DELC delete an existing channel group * RENC rename an existing channel group * 'LSTB [ID]' to list all blacklists, or the one with the passed ID (format is the same as epgsearchblacklists.conf, see MANUAL) * 'NEWB ' to add a new blacklist REMARK: the value of element ID is ignored. epgsearch will always assign the next free ID * 'DELB ' to delete the blacklist with ID * 'EDIB ' to modify an existing blacklist * 'QRYS < ID(s) >' to get the results for a search with the given ID. Multiple IDs can also be passed and have to be separated with '|'. * 'QRYS ' to get the results for a search with the given search settings. * 'QRYF [hours]' to get the results for the favorites menu. The optional parameter specifies the number of hours to evaluate and defaults to 24h. * 'LSTE [ID] to get the extended EPG categories defined in epgsearchcats.conf or the one with the given ID. * 'MODS ID ON|OFF' turns on/off the option 'Use as search timer'. * 'SETP option' returns the current value of the setup option (see MANUAL). - epgsearch has now a bug tracking system (german) and a mailing list (english) http://www.vdr-developer.org/mantisbt http://www.vdr-developer.org/mailman/listinfo/epgsearch thanks to the providers of developer.org - new service interface "Epgsearch-switchtimer-v1.0" to access and manage switch timers, thanks to Dirk Leber for his extension. - update for french translation (including setup help!), thanks to Patrice Staudt - thanks to Rolf Ahrenberg for finnish translation update - thanks to Mike Constabel for providing a HTML update mail template (conf/epgsearchupdmail-html.templ) fixes: - the first day of a repeating timer is now taken into consideration in the timer conflict check, thanks to zimuland@vdrportal for reporting - fixed search timer update for VPS timers, thanks to Chello and oholler@vdrportal for reporting. - fixed handling of the sign '|' when changing the search type of a search timer, thanks to Chello@vdrportal for reporting - changed some default search mode values in the epgsearchcats.conf samples for multiple selection - removed extra line feeds in SVDRP response of LSTS, thanks to Andreas Mair for reporting - channel criterion 'no pay tv' in search timers was ignored, thanks to Andreas Mair for reporting - fixed initial min/max values for search criterion 'duration', thanks to Mike Constabel for reporting - fixed a bug when selecting the conflict check 'after each search timer update' in setup, thanks to Ronny Kornexl for reporting - some changes for thread safeness - added '--remove-destination' to the Makefile as introduced in vdr-1.4.2-3 2006-08-07: Version 0.9.17d (maintenance release) fixes: - fixed a wrong usage of 'cPlugin::ConfigDirectory' in search timer thread, thanks to Udo Richter and Petri Hintukainen for reporting 2006-06-12: Version 0.9.17c fixes: - fixed a problem with multiple selection of extended epg category values, thanks to Christian Jacobsen for reporting - another compilation fix for linvdr, thanks to toxic-tonic@vdrportal 2006-06-10: Version 0.9.17b fixes: - fixed some problems with repeating timers in timer conflict check, thanks to Peter Juenger for reporting - fixed a crash in timer conflict check when there was an active recording on a device provided by a plugin (e.g. pvr, streamdev), thanks to Gerhard Steiner for reporting. 2006-06-06: Version 0.9.17a fixes: - menu 'timer conflicts' automatically returned if there where periodic timers, thanks to lostinspc@vdrportal - fixed some compiling problems with gcc-2.95 and gcc-4.1.0, thanks to ferdi03@vdrportal, smudo81@vdrportal, toxic-tonic@vdrportal 2006-06-05: Version 0.9.17 - dropped support for vdr < 1.3.46 :-( - changed logic in jumping through menus with user-defined times: you can now also access times on next day, if they are less then 20 hours in the future. Thanks to egal@vdrportal and CKone@vdrportal. - epgsearch has now its own timer conflict check which can be customized by setup regarding relevant priorities, the time span to check or the relevant conflict duration. There is also a conflict manager in Search/Actions that can be used to resolve conflicts. Many thanks to Mike Constabel for heavy testing ;-) - if there is a timer conflicts notification via OSD, you can now press 'Ok' to go directly to the timer conflicts overview. - if you like to have a separate main menu entry for the timer conflict check use '-P conflictcheckonly' which comes as 'mini'-plugin with epgsearch and simply calls epgsearch's conflict menu. conflictcheckonly has a setup option to display an info about the last conflict check directly in its main menu entry. - setup is now completely restructured and has now something like an 'online' help. - menu 'switch timers' now also displays the channel number - input logic for extended EPG categories changed to allow multiple values. - added script 'timercmds-auxinfo.sh' that displays the aux info (e.g. the search timer responsible for the timer) in VDR's timer menu (requires the timercmd patch), thanks to the author Mike Constabel - user-defined EPG times with empty description get now their associated time as description, suggested by Thiemo Gehrke - new service interface "Epgsearch-conflictmenu-v1.0" to call epgsearch's conflict menu from other plugins. - new service interface "Epgsearch-lastconflictinfo-v1.0" to get an info about the last conflict check result. - epgsearchmenu.conf is not more reloaded with every plugin call, since this is only useful when testing the conf file. To activate the permanent reload again, pass the new start parameter '-r' or '--reloadmenuconf' in your runvdr - thanks to Rolf Ahrenberg for finnish translation update - added HISTORY.DE (german HISTORY) fixes: - loading epgsearchmenu.conf now falls back to menu defaults, if the conf file contains any errors. - fixed handling of '%' in LSTS in SVDRP for vdr > 1.3.44, thanks to Mike Constabel - fixed loading epgsearchmenu.conf for epgsearchonly and service interface "Epgsearch-searchmenu-v1.0", thanks to Daniel Dorau for reporting. - fixed display update in menu 'Search templates', thanks to Mike Constabel - fixed a bug when deleting associated timers of a search timer when there are no timers present, thanks to Patrick Koppen for reporting. - hopefully fixed a bug when adding a search entry to templates, thanks to Patrick Koppen for reporting. 2006-04-18: Version 0.9.16 (maintenance release) fixes: - the display of 'Overview - Now' was broken, when using progressbar and channel numbers in default menu look. Thanks to Gerhard Steiner for reporting this one. - when using small OSD fonts, the progressbars where flickering because of 1 pixel line height. Thanks to holymoly and TomG@vdrportal. - support for the APIVERSION define as introduced in vdr-1.3.47 2006-04-14: Version 0.9.15 new: - the EPG menus can now be customized with the file epgsearchmenu.conf (sample file in 'conf' subdirectory), e.g. the entry: MenuWhatsOnNow=%chnr%:3|%progrt2s%:5| %time% %t_status%:8|%category%:6| %title% ~ %subtitle%:35 creates a menu line starting with the channel number, followed by a progress bar in text2skin style, the start time, the timer status, the EPG category (like "movie") and finally the title and subtitle. You can customize each menu ('What's on now, next, other times, schedule and search results with a separate line). Please refer to the MANUAL for more information. - IMPORTANT change to search timers: epgsearch now removes timers, that are not needed anymore (if vdr >= 1.3.44). These are: * timers, that are no more valid because of EPG changes. This should avoid the double recordings after an EPG change. * timers, that do not match the search criterions after a change of the search timer. So you don't have to remove them manually anymore. If the user has modified start or stop of such a timer, it will be kept. - new search mode 'fuzzy' in searches. This performs a fuzzy search applying an algorithm like it's used in agrep. The error tolerance can be set with the edit field 'Tolerance'. - added the 'one press' timer creation feature in EPG menus as introduced in vdr-1.3.38 with one small difference: If the event is already running or about to start within MarginStart + 2 minutes, the timer edit menu will be popup to allow editing the file/directory entry, because this cannot be changed when the recording immediately starts. Else, the timer is created immediately. Can be turned off in setup. - with the red button in epgsearch's own timer edit menu one can now delete an existing timer, suggested by Rolf Ahrenberg. - if the main menu entry is not hidden, its name can now be set by setup. (Note: when changing the name to something different than the default, it is no more dependent on the OSD language) - changed the default main menu entry from 'Search' to 'Program guide' - some people requested a separate main menu entry for epgsearch's search menu. Therefore I've added a little plugin called 'epgsearchonly' that simply calls epgsearch's search menu. Its main menu entry is 'Search'. Compilation of epgsearchonly is automatically done, but can be switched off in the Makefile when uncommenting the line #WITHOUT_EPGSEARCHONLY=1. To use it simply put '-P epgsearchonly' to your VDR start script. (requires >= vdr-1.3.30) - new service interface "Epgsearch-searchmenu-v1.0" to call epgsearch's search menu from other plugins. - new action 'Delete created timers?' for search entries to delete all timers created from the current search timer. Does not affect recording timers. - When deleting a search, you can now decide if all timers created from this search should also be deleted. - If the user modifies the start/stop time of a timer created by epgsearch this timer will not be changed anymore(only vdr >= 1.3.44 ) - If an event is currently recorded, the status flag in the EPG menus is now 'R' instead of 'T' - Support for wareagle-icon-patch (activate it by adding the line 'WarEagleIcons=1' to epgsearchmenu.conf) - Progressbar in Now/Next beautified when using setup option 'graphical', inspired by Nordlichts-EPG-Plugin - new setup option to show/hide radio channels in the EPG menus, suggested by Patrice Staudt. - new service interface "Epgsearch-searchresults-v1.0", that returns a result list of events matching a given search, suggested by Andreas Brugger - removed some special setup options, because their function can also be realized with a customized menu now: * "show progress bar in 'Next'", in default menu now off * "display width for progressbar", in default menu now 4 * "show short channel name", in default now always short * "Show episode text in schedules", now always displayed - update for finnish translation, thanks to Rolf Ahrenberg - aux field is now formatted in full XML style (if vdr >= 1.3.44). As a result of this, an updated recordingdone.sh is provided in the 'scripts' subdirectory. Thanks to Mike Constabel for providing a patch. - search timer update now always runs in low priority, suggested by Christian Jacobsen - new SVDRP command 'FIND'. This allows searching an event and returns a list of results consisting of 'NEWT' lines, that can be used to immediately create a timer for a result. Suggested by Lari Tuononen fixes: - thanks to Darren Salt for patches for g++ 4.1 and some things concerning thread safeness and code review - fixed some memory leaks - fixed calling user defined EPG commands, thanks to rzndl@vdrportal - fixed blacklist match for search timers, thanks to Christian Jacobsen - make sure that the episode name of a timer is less then MAX_SUBTITLE_LENGTH, thanks to Mike Constabel - speedup for search timer update 2006-03-05: Version 0.9.14a fixes: - EPG command 'mark as already recorded' crashed, thanks to Mike Constabel for reporting this 2006-03-04: Version 0.9.14 new: - when disabling/enabling a search timer you can now decide if the associated timers should also be disabled/enabled. - new built-in EPG command 'Create blacklist' to create a blacklist from any EPG menu. - the summary of an entry in the menu 'recordings done' has now an additional button 'Aux info', that displays the content of the aux field. - update for the script recordingdone.sh to work also with vdr-1.3.44, thanks to Mike Constabel for his changes. - conversion scripts for upgrade to vdr-1.3.44: Because of the different handling of auxiliary info (summary -> aux) some features of epgsearch won't work with recordings made before vdr-1.3.44. This applies to the done-Feature and to the automatic deletion of recordings. Without using these scripts you will simply have some more recordings. So you actually don't have to apply them, but when using them, all works fine. Thanks to Mike Constable for providing them. * new script convert_info_vdr.pl. This converts the info file of recordings made before vdr-1.3.44 and moves epgsearch aux data to the new aux field. * new script convert_epgsearchdone_data.pl. This converts the epgsearchdone.data file adding an 'aux' section to it. - update for script mtdone2epgsearchdone.sh, thanks to Christian Jacobsen - update for french translation, thanks to Patrice Staudt - update for finnish translation, thanks to Rolf Ahrenberg fixes: - done-feature was broken with vdr-1.3.44, thanks to Mike Constabel for reporting this - another fix of high cpu load in search timer thread, thanks to sledgehammer@vdrportal for reporting this - automatic linking after extracting the tarball removed again, requested by distribution maintainers. - fixed some compiler warnings when using -Wformat=2, thanks to Darren Salt for reporting and providing a patch 2006-02-28: Version 0.9.13 new: - support for vdr-1.3.44: works now, but: because of the summary/aux changes in vdr-1.3.44 the additional info about the search timer, that triggered a timer/recording, or the recording channel is currently not available. This info is now stored in the new aux field of timers/recordings. - blacklists: you can now maintain one or more blacklists and select them within a search or search timer. A blacklist works like a normal search and defines events that should be ignored in a search or search timer. Blacklists can be managed from setup or with the new search action 'Show blacklists' or directly when editing a search. Within a search you can select one or more or all blacklists. If any search result is also contained in a black list result set it will be skipped. - the switchtimer background thread is now only active, while there are any active switch timers. - when you unpack the tar file, the necessary link is now automatically created (like text2skin) - the result list of repeats of an event now omits the currently running event, suggested by Ronny Kornexl - thanks for beta testing to Mike Constabel - update for finnish translation, thanks to Rolf Ahrenberg fixes: - the setup option 'Add episode to manual timers' was not stored 2006-02-12: Version 0.9.12 new: - new feature 'pause when ... recordings exist" for search timers. If the given number (>0) of recordings exist, then the search timer will not create further timers. After deleting one or more recordings new timers are generated again. fixes: - fixed a crash when surfing to a channel without epg in schedule menu 2006-02-08: Version 0.9.11a fixes: - high cpu load fixed 2006-02-07: Version 0.9.11 new: - support for vdr-1.3.42 - new feature switch timers: add an event with the new epg command 'Add to switch list' to the switch list and epgsearch will switch the channel one minute before the event starts. The current content of the switch list can be controlled within the search menu with the new action 'Show switch list'. If there is a switch timer for an event its menu item is labeled with 'S', if there is no real timer. - switch timers also for search timers: a search timer can now be configured to 'switch only'. Its search results are then added to the switch list and epgsearch will switch to the found events one minute before they start. There will be no real timer for such a search timer. - search criterion 'Use channel' has now an additional value 'only FTA' to search in non encrypted channels only - new setup option 'Show day separators' for menu 'Schedule', that displays an additional line at day break. - epgsearch has now a SVDRP interface with the following commands (requires vdr > 1.3.30): * 'LSTS [ID]' to list all searches, or the one with the passed ID (format is the same as epgsearch.conf, see MANUAL) * 'NEWS ' to add a new search REMARK: the value of element ID is ignored. epgsearch will always assign the next free ID * 'DELS ' to delete the search with ID * 'EDIS ' to modify an existing search * 'UPDS [OSD]' to update the search timers. Passing the optional keyword 'OSD' pops up an OSD message after the update has finished. * 'UPDD' to reload the file epgsearchdone.data, e.g. after an external tool has modified it. * 'SETS ' to activate or cancel the search timer background thread. - since setup gets too big it has now the modes 'Standard' and 'Extended'(toggled with key 'red'), suggested by Rolf Ahrenberg - update for finnish translation, thanks to Rolf Ahrenberg - update for italian translation, thanks to reelbox users - update for french translation, thanks to Patrice Staudt - new dutch translation, thanks to reelbox users - using 127.0.0.1 instead of resolving 'localhost' for SVDRP, suggested by Thiemo Gehrke - added script recordingdone.sh for your reccmds.conf to add a recording to epgsearch's done file, thanks to Patrice Staudt, Christian Jacobsen and Mike Constabel - added script mtdone2epgsearchdone.sh to move recordings from mastertimer's done file to epgsearch's done file, thanks to Christian Jacobsen. - thanks to Mike Constabel and Andreas Brugger for testing and bug reports fixes: - fixed a bug after using templates, thanks to Christian Jacobsen 2006-01-15: Version 0.9.10 new: - update of all schedule and search result menus after creating/changing a timer, as introduced in vdr-1.3.38 - button 'Record' now labeled with 'Record' or 'Timer' depending on existing timer for the event, as introduced in vdr-1.3.38 - epgsearch's own timer edit menu now displays the recording device number for a currently recording timer - new setup option: 'Add episode to manual timers' affects adding the subtitle to the timer file in manual timer programming. The setting 'smart' skips the subtitle if the event has more that 80 min. - search edit menu for search timers changed for future extensions: 'Action' now selects the job to do for the search results, currently 'record' (default) or 'announce only' - thanks to Rolf Ahrenberg for finnish translation update fixes: - in vdr-1.3.38 some translations were broken - updated the timercmds-patches to work with vdr-1.3.38 2006-01-08: Version 0.9.9 new: - support for vdr-1.3.38 - search templates: the settings of a search are often quite the same as already done with other searches. You can now create templates that can be selected when editing a search (with key blue). A template can also be set as default. A new search will then get the default settings automatically. - extended setup with 'search templates' to manage the new templates - new action 'Use as template' to copy a search to the templates - setup option to display the subtitle in the schedules, thanks to Darren Salt for his patch - extension of feature 'Delete recordings after ... days' with 'Keep ... recordings'. This will asure, that last x recordings will not be deleted, even if they are expired. fixes: - the search timer feature 'Delete recordings after ... days' also deleted recordings that were edited. fixed now. 2005-11-27: Version 0.9.8 new: ATTENTION: this version converts epgsearch.conf (the file that stores the searches) to a NEW FORMAT. A backup of the old file is stored as epgsearch.conf.bak. If you switch back to an older version you have to move the backup file back to epgsearch.conf. - new feature 'avoid repeats' for search timers, aka 'done' feature (please read the README before using it!). A special thanks to Mike Constabel (vejoun@vdrportal) for many hours of testing and bug reports. * timer preview * recognition of broken recordings * fuzzy event comparison - the menu of search results for a search timer with 'avoid repeats' has an additional mode for key 'blue' to preview the timers, that will be programmed with it. - new setup option to display channels without EPG in 'What's on...', idea from 'Nordlicht's EPG plugin' - new setup option to show channel separators in 'What's on...', idea from 'Nordlicht's EPG plugin' - new feature 'Delete recordings after ... days'. This removes a recording automatically after the given days. It's a nice thing for e.g. news recordings (like Tagesschau), that are only interesting for a few days - the timer summary now contains additional information about the event: event title, subtitle (if present) at the top, the name and ID of the search timer, that triggered the timer, and also the recording channel (after the real summary) at the bottom - the summary of timers that are manually programmed now also contains info about title, subtitle (if present) and the recording channel - 'Execute' in searches menu has been replaced with 'Actions' that list a menu consisting of * Execute search * Use as search timer on/off * Trigger search timer update * Show recordings done You can also use the short keys to trigger the corresponding action without opening this menu - introduced a logfile (default file is plugin-configdir/epgsearch.log, but can be specified with commandline option '-l /path/to/logfile'. Commandline option '-v n' specifies the verbose level of the logfile. n=0 means no logging, allowed values are n=0(default),1(standard),2(extended),3(for debug). - setup has now a default recording directory entry, that is used in manual timer programming. It supports also entries like '%Category%~%Genre%'. The directory gets automatically replaced with the values of the event (but only if all variables were replaced). - depending on the calling menu the event menu (summary) now labels the buttons green/yellow with the previous/next channel or the start of the previous/next event, suggested by Andreas Brugger - the channel number is now also listed in menu 'search results', if the setup option 'show channel numbers' is set, suggested by Gerhard Steiner. - short keys (1,2,...) to EPG commands are now also available in the EPG summary menu, suggested by Frank Krömmelbein - if VDR version >= 1.3.31 then setup has now an option to choose between epgsearch's timer edit menu and VDR's built-in menu (useful when using a patched VDR timer edit menu, suggested by Frank Krömmelbein) - if a subtitle is present the menu for manual timer programming now always adds the subtitle to the timer file as default, suggested by Gerhard Steiner - optimized the splitting of the directory and file entry when re-editing a timer in manual programming, thanks to Andreas Brugger - the EPG menus now always display a subtitle in the form 'title ~ subtitle' if present - new service 'Epgsearch-updatesearchtimers-v1.0' to trigger a search timer update - if a search timer update is triggered from the actions menu then an osd message is displayed when it has finished (also when using the service 'Epgsearch-updatesearchtimers-v1.0' optional) - the menu of search timers now displays the number of (active) searchtimers in its title - now checking if manual timer programming has failed and display an osd message in that case (needs vdr >= 1.3.30 to work) - thanks to Rolf Ahrenberg for updating the finnish translation - thanks to Mike Constabel for corrections in READMEs and MANUAL fixes: - epgsearch now exits to main menu when not called directly via a short key, thanks to Andreas Brugger - fixed editing menu search term in english translation - fixed sorting search timer list after editing a search timer, thanks to Mike Constabel - fixed menu navigation with respect to empty schedules, thanks to Darren Salt for his patch - fixed misaligned search entries in searches menu, thanks to Andreas Brugger 2005-09-04: Version 0.9.7 new: - changes in the events summary now also trigger a timer update fixes: - fixed a memory leak in search timers with regular expressions, thanks to TomG@vdrportal - fixed channel name display in color buttons when a channel separator exists, thanks to viking@vdrportal 2005-08-27: Version 0.9.6 new: - search criterion 'use channel' extended by 'channel groups'. Channel groups can be managed with their own menu and allow a much more flexible way to select channels for the search procedure. - epgsearch now exposes its extended timer edit menu and searching the epg as services to other plugins (s. MANUAL or contact me, if you are interested) - if a timer is programmed for an event (searchtimer or manual programming) then the summary is now also passed to the timer (allows displaying the summary pressing 'ok' in timer menu), thanks to TomG@vdrportal - after toggling the color buttons with '0' in the schedule menu the yellow/green button now move to the schedule of the previous/next channel - added a patch from Uwe/egal@vdrportal that replaces vdr's standard schedule menu with the epgsearch plugin. Also big thanks to Uwe for the changes in epgsearch. After patching VDR you have to activate the patch in epgsearch's setup. - after editing a new search, its entry now gets correctly sorted in the list of all searches, thanks to Mike Constabel - added Gerhard Steiner's timercmd patch for vdr >= 1.3.25 - a 'back' in the start menu now always closes the osd (should solve some trouble with the submenu patch) - events without title are now ignored, regardless of the search criteria, thanks to Mike Constabel - new EPG variable '%channel%', that can be used in directory entries and gets replaced with the channels name - recording margins in search timers can now be negative (allows intentional cutting the begin/end of recording), suggested by Mike Constabel - extended EPG categories are now compared case insensitive - updated finnish translation, thanks to Rolf Ahrenberg fixes: - '.epgsearchrc' now too is expected in the config path specified with -c (if given), thanks to Ronny Kornexl - fixed programming of timers with empty file and directory, thanks to Andreas Brugger - fixed search timer programming in case of midnight between start and stop time - fixed directory selection when listing of dirs is empty, thanks to harvey@vdrportal - (de)activating a searchtimer with '0' did not store, thanks to Mike Constabel - fixed menu navigation (green-yellow-yellow-green displayed the summary instead of 'whats on now'), thanks to Mike Constabel 2005-07-02: Version 0.9.5 - epgsearch has now its own menu for standard timer editing with the following extensions (timer programming is based on SVDRP, so this should be configured!): * additional item 'directory' with selection of existing directories with key 'blue' (also supports EPG variables like "%category%" when using ext. EPG info) * item 'file' can be extended with subtitle (if present) pressing key 'blue' * item 'file' and 'directory' can be reset to standard pressing key 'yellow' * when editing weekdays then item 'day' can be customized with a submenu for arbitrary weekdays selection - menu 'userdefined days of week' for search timers now starts with 'Monday' instead of 'Sunday' - menu 'Select directory' now lists distinct items of the following sources: * current recording directories * current timer directories * directories used in search timers * directories specified in epgsearchdirs.conf key 'yellow' can be used to change the depth of the directory listing. - Progressbar in 'Next' can now be switched on/off with its own setup item. - support for language dependent commands for EPG (default loading uses epgsearchcmds.conf, if there is no epgsearchcmds-XXX.conf, where XXX is the language code as shown in i18n.c, see MANUAL) - directly calling a command with key '1'..'9' will now go back to the calling menu after execution instead of displaying menu 'commands' - added a commandline option '-c' or '--config' to specify the plugins own config directory (option). - added commandline help for 'vdr --help - thanks again to Mike Constabel (vejoun@vdrportal) for great beta testing and suggestions, and to Rolf Ahrenberg for finnish translation. 2005-05-24: Version 0.9.4 - support for extended EPG info (categories) in search timers (please refer to the README 'Using extended EPG info'). - added a submenu to select an existing directory when editing a search timer. This menu can also be extended with entries in the file epgsearchdirs.conf - usage of variables like "%Genre%" or "%Category% in the directory entry of a search timer. These are replaced with the current extended EPG info when a timer is created. - key '0' in search menu now toggles the flag 'use as search timer' - fixed compilation for vdr < 1.3.18 (thanks to TomG@vdrportal) - updated script rememberevent.sh (thanks to Ronny Kornexl for complete rewrite and extensions) - added script epg2master-timer.sh for the commands menu, that adds an event to master-timer, thanks to the author Christian Jacobsen / Viking (vdrportal) - some changes to compile with bigpatch - removed font patch for progressbar, since runtime patch seems to work fine - added a script timerrep.sh to search the repeats of a timer from timer menu (requires the timercmds.conf-patch from Gerhard Steiner, see dir patches) - updated/rearranged README(.DE) and added also a MANUAL (only english) for detailed info about some topics, since README gets too big. - Added a description of the format of epgsearch.conf to MANUAL - fixed a bug with buttons display in search timer edit menu - a special thanks to Mike Constabel (vejoun@vdrportal) for great beta testing and suggestions, and to Rolf Ahrenberg for finnish translation. 2005-04-14: Version 0.9.3 - implemented direct SVDRP communication (no more need for svdrpsend. For now, the old external method can still be used when you pass it with -f as parameter, if you omit -f the internal method is used) - added buttons '<<' and '>>' in detailed epg view (summary) to jump to the previous/next event of the menu behind (schedule, now, next, ..., search results) - new feature to use epgsearch for searching from other plugins or scripts (see the README 'Usage from other plugins or scripts') - shifting displayed time with FF, FR or by toggling with '0' is now also available in schedule menu - added a setup option to set a default for handling pay tv channels when searching (does not affect search timers) - fixed day check in searchtimer scan with respect to changes in vdr-1.3.23 - changed detection of existing timers to reduce superfluous timer modifications. - added channel name and subtitle to parameters for custom commands - small change in input logic of 'from channel' when editing a search entry - updated screen shots on project homepage 2005-03-20: Version 0.9.2 - update for vdr-1.3.23 2005-03-19: Version 0.9.1 - french translation update, thanks to Patrice Staudt - fixed a problem with priority and lifetime when modifying a timer 2005-03-19: Version 0.9.0 - new search mode 'regular expressions' (POSIX(default) or Perl compatible by compiler switch HAVE_PCREPOSIX in the Makefile, see README - Installation) - new search mode 'match exactly' to simplify matching of short search terms - new option for search timers: 'only annouce' will not add a timer, but display an OSD message about the found event - new progressbar in 'what's on next', that displays the time span to the next event (0 minutes(=100%) to max. 30 minutes(=0%)) - timer conficts can now be checked in the background and are displayed via OSD after each search timer scan (requires a recent timeline plugin running) - key blue in search results now toggles between "only FTA" and "all channels" (to hide results from pay tv channels) - removed some superfluous search timer modifications - finnish translation, thanks to Rolf Ahrenberg - updated README and added a description of the search process - shifted version number to allow subversions 2005-02-15: Version 0.0.8 - added support for VPS in search timers - channels of search timers are now stored with ID rather than number (avoids editing your searches after channel modifications) - corrections in the english version, thanks to Darren Salt - fixed a bug in criterion duration - fixed channel selection when shifting displayed time, thanks to Ronny Kornexl - put some space between progressbar and event info (TtV*) for text2skin 1.0 - fixed compilaton problems in vdr-1.3.10 - switch display in search results to 'episode name only' with key yellow - fixed width of start time, when displaying channel number, thanks to Gerhard Steiner 2005-01-22: Version 0.0.7 - Start menu can now be setup between 'schedule' and 'now' - runtime patch for progressbar (no need to patch vdr anymore, experimental) - Added lifetime, priority and margins for start and stop for searchtimers - Added new font-patch for vdr-1.3.18 - new: italian translation, thanks to Sean Carlos - french translation, thanks to Patrice Staudt - finnish translation by Rolf Ahrenberg - search term can now be empty to search for anything, that matches other criterions searchtimers - Fixed editing of criterion 'to channel', thanks to gunnar@vdrportal 2005-01-11: Version 0.0.6 - now compiles also with vdr-1.3.18 - Search criterion 'channel' can now be a range of channels (thanks to gunnar@vdrportal) - Setup option 'short channel names' for display in 'now', 'next',... (only available for >= vdr-1.3.15, thanks to dido@vdrportal) - french translation, thanks to Patrice Staudt - added external trigger to force a search scan (e.g. at shutdown, thanks to Ronny Kornexl) - fixed display of color keys while editing search term and directory (thanks to Ronny Kornexl) - recordings found with 'search in recordings' can now be replayed from result list - fixed menu switching now-program-now (thanks to dido@vdrportal) 2005-01-03: Version 0.0.5 - time in 'now', 'next',... can now be shifted with FastFwd and FastRew or with Green/Yellow when toggling with '0' (see README) - search results now display 't' ,'T', if there is already a timer for an entry, thanks to LordPSI@vdrportal. - translation of new things to finnish (as always thanks to Rolf Ahrenberg) - sorting by channel in repeatings should work now, thanks to LordPSI@vdrportal. - fixed searching in mode 'one word', thanks to LordPSI@vdrportal - fixed key blue and red in an empty search list, thanks to Ronny Kornexl - fixed compilation problem with vdr-1.3.10, thanks to rockclimber@vdrportal - fixed some function calls to thread safeness (thanks to ?) - fixed graphical progressbar, thanks to white_@vdrportal - rewritten the README's 2004-11-30: Version 0.0.4 - New feature 'search timers' (like vdradmins 'auto timers', see the readme, thanks to Rolf Ahrenberg for idea and code review) - Progressbar can now be set to graphical bars in setup (you have to apply a vdr-patch for this, see README, thanks to Uwe/egal from vdrportal for creating the needed fonts) - Added builtin command to commands menu to create a search from epg entry - Added builtin command to commands menu to switch to channel of selected entry - Added builtin command to commands menu to search the current epg entry in recordings (thanks to Adreas Kool for his patch) - Key "Blue" can now also be customized by setup (switch/search) - Key '0' toggles key mapping of red and blue key (thanks to Roman (Uatschitchun) from vdrportal for his idea) - Added 'day(s) of week' as search criterion - Executing a command on an epg entry now only closes command menu, not the whole plugin - Display of channel number in "what's on" controlled by setup - fixed column display to prevent cutting of channel name - fixed selection of current channel in "what's on now" (thanks to Leo from vdrportal for reporting this) - button 'ok' in empty search results jumps back to search list 2004-11-08: Version 0.0.3 - Added an ASCII-based progress bar to the 'what's on now' view of the schedules. (Usage and display width customizable by setup). - Added up to 4 user defined times besides "now" and "next" (you can use this for example for "primetime" or "late night") - Renamed plugin main entry from "EPG search" to "Search" - Added duration to search criterions - Added commands menu in 'search results' list - Behaviour of red key is now the same in 'search results' as in main menu of the plugin. - Updated history and readme's 2004-09-11: Version 0.0.2 - New feature for executing commands on epg items (see README) - Added script epg2autotimer.sh to create autotimers from epg - Added finnish translation (thanks to Rolf Ahrenberg, also for code review) - Behaviour of red key can now be switched by setup form "Standard" to "Commands". - code is now more structured - BUGFIX: Blue key for switching in summary should work now (thanks to Sir James Lachtveel and others for reporting this one) 2004-08-15: Version 0.0.1 - Initial revision. vdr-plugin-epgsearch-2.4.1/HISTORY.DE000066400000000000000000002140251405273211300171210ustar00rootroot00000000000000VDR Plugin 'epgsearch' Revision History --------------------------------------- -2021-05-24; Version 2.4.1 -fixes: -- Fixed conflictcheck for encrypted channels with internal CAMs -- Fixed compiling with gcc11 -- Updated deprecated calls to SetItemEvent -- Temporally(?) added #define DISABLE_TEMPLATES_COLLIDING_WITH_STL for -- compatibility with vdr 2.5.4 - -2021-04-12 -neu: -- Improved handling of remote timers -- Replace auto_ptr with unique_ptr for c++11 (kfb77@vdr-portal.de) -- Delay threads after pluginstart 10 secs (configurable) -- Changed fgets to allow compiling with clang -- Clarified "avoid repeats". Forced subtitle-comparison is named "yes" again - New option "allow empty" -fixes: -- Fixed several lock sequence errors -- Fix utf-8 encoding in docs and manpages (kfb77 and seahawk1986@vdr-portal.de) -- Fixed possible format overflow -- Fixed displaying NAME in generated manpages thanks to etobi 2018-04-16; Version 2.4.0 neu: - Create man pages only once. by jasminj@vdr-portal.de - Remove useless member "useEpisode" from cBlacklist by jasminj@vdr-portal.de - Remove useless member "useEpisode" from cBlacklist by jasminj@vdr-portal.de - Remove useless "LOCK_CHANNELS_READ" in cBlacklist run by jasminj@vdr-portal.de - Change shell in docsrc2*.sh to /bin/bash, suggested by TomJoad@vdr-portal.de - Added operator to cListObject derived classes by jasminj@vdr-portal.de - Add patches/vdr.epgsearch-exttimeredit-2.3.5.diff by Dietmar Spingler - Adapt new makefile style of VDR 2.3.6 by TomJoad@vdr-portal.de - Use vdr timerids instead of index by TomJoad@vdr-portal.de - Fix many lock sequences by TomJoad@vdr-portal.de - New vdr.epgsearch-exttimeredit-2.3.6.diff (thx to Claus Muus) - Add conflict check for remote timers by Johann Friedrichs - Search timers should create only local timers - Use namespace for svdrpclient - Add icon for inactive timer - Use separate thread for recdone processing - get rid of some casts - unified indentation - Preserve timerflags in searchtimerupdate 2017-05-xx; Version 2.3.1 - development release neu: - Anwenden vdr-2.3.2-epgsearch-1.0.1.beta5~git20150715_v2.diff von fnu@vdr-portal.de basierend auf Eingaben von kamel5, mini73 & TomJoad @ vdr-portal.de => http://www.vdr-portal.de/board17-developer/board97-vdr-core/p1284612-produktive-problem-und-pluginl%C3%B6sungen-f%C3%BCr-vdr-2-3-2-und-h%C3%B6her/#post1284612 - Anwenden 0004-Added-patches-vdr.epgsearch-exttimeredit-2.3.3.diff.diff von jasminj@vdr-portal.de => http://www.vdr-portal.de/board17-developer/board21-vdr-plugins/p1289938-epgsearch-f%C3%BCr-vdr-2-3-x/#post1289938 - Anwenden 0005-epgsearch-inactive-records-v2.diff von jasminj@vdr-portal.de => http://www.vdr-portal.de/board17-developer/board21-vdr-plugins/p1289983-epgsearch-f%C3%BCr-vdr-2-3-x/#post1289983 - Anwenden 0001-Fix-warning-in-pending_notifications.c.diff von jasminj@vdr-portal.de - Anwenden 0002-Fixed-warnings-in-man-page-generation.diff von jasminj@vdr-portal.de => http://www.vdr-portal.de/board17-developer/board21-vdr-plugins/p1289704-epgsearch-f%C3%BCr-vdr-2-3-x/#post1289704 - Anwenden 0003-Use-HandleRemoteTimerModifications-instead-of-Handle.diff von jasminj@vdr-portal.de => http://www.vdr-portal.de/board17-developer/board21-vdr-plugins/p1289764-epgsearch-f%C3%BCr-vdr-2-3-x/#post1289764 - Anwenden menu_category_recsdone.diff von tomas & louis @vdr-portal.de http://www.vdr-portal.de/board1-news/board2-vdr-news/p1271995-skindesigner-1-0-0-neuer-default-skin-estuary4vdr/#post1271995 - Anwenden 0001-revert-seperate-status-thread.diff von TomJoad@vdr-portal.de - Anwenden 0002-fix-incorrect-lock-sequences.diff von TomJoad@vdr-portal.de - Anwenden 0003-revert-now-obsolete-pointer-params.diff von TomJoad@vdr-portal.de - Anwenden 0004-some-small-fixes.diff von TomJoad@vdr-portal.de http://www.vdr-portal.de/board17-developer/board21-vdr-plugins/p1291452-epgsearch-f%C3%BCr-vdr-2-3-x/#post1291452 - Löschen Alt-Code vor VDR 2.3.x - Anwenden 0001-fixed-unresponsive-vdr.diff von TomJoad@vdr-portal.de - Anwenden 0002-removed-variableduplications.diff von TomJoad@vdr-portal.de - Anwenden 0003-more-cleanups.diff von TomJoad@vdr-portal.de - Anwenden 0004-Remote-timers-in-menu-myedittimer.diff von TomJoad@vdr-portal.de http://www.vdr-portal.de/board17-developer/board21-vdr-plugins/p1291771-epgsearch-f%C3%BCr-vdr-2-3-x/#post1291771 - Anwenden fixblacklist_handling.diff von TomJoad@vdr-portal.de http://www.vdr-portal.de/board16-video-disk-recorder/board99-distributionen/board107-mld/p1292085-epgsearch-in-verbindung-mit-epgd-epg2vdr-live-absturz-unter-vdr-2-3-4/#post1292085 - Anwenden epgsearch_min_max_from_stl.diff von jasminj@vdr-portal.de http://www.vdr-portal.de/board17-developer/board21-vdr-plugins/p1292145-epgsearch-f%C3%BCr-vdr-2-3-x/#post1292145 2013-03-xx: Version 1.0.1 - Maintenance Release neu: - neuer Stil für das Makefile wie in vdr-1.7.36 eingeführt. Das alte Makefile gibt es noch als Makefile.before.1.7.36 für frühere VDR-Versionen. Vielen Dank an Copperhead, Stefan Hofmann und Christopher Reimer für deren Arbeit. - device bonding in der Timer-Konflikt-Prüfung implementiert, Danke an Joachim Wilke für den Path - Neue Service-Schnittstelle "Epgsearch-enablesearchtimers-v1.0" zum Ein- und Ausschalten des Suchtimer-Updates im Hintergrund. Das Beispiel in source/vdr-epgsearchclient-0.0.2.tgz wurde aktualisiert und nutzt die neue Schnittstelle. - Neuer Format-Eintrag wie z.B. %02i in der epgsearchcats.conf, Danke an Joe_D für den Patch ('man 5 epgsearchcats.conf' für mehr Information). - Im Menu 'Erledigte Aufnahmen' kann nun mit der blauen Taste zu 'Verwaiste' umgeschaltet werden, um Aufnahmen anzuzeigen, zu denen es keine Suchtimer mehr gibt. - Wenn Kanalseparatoren angezeigt werden, kann das in der Ausgabe von graphlcd Probleme machen. Um das zu vermeiden, bitte PLUGIN_EPGSEARCH_SEP_ITEMS=--- in der Make.config setzen. Die meisten Skins (ausser classic, st:tng) ersetzen '---' ohnehin in eine durch- gehende Linie. (Feature #857, Danke an 'KeineAhnung' für den Patch) - Suchtimer werden jetzt anhand absteigender Timer-Priorität abgearbeitet. Bei gleicher Priorität wird nach dem Suchbegriff sortiert. Danke an Anonym für den Patch. - Neuer Bugtracker unter http://projects.vdr-developer.org/projects/plg-epgsearch - Danke an Tobias Grimm - alten Code für vdr < 1.6.0 entfernt, Danke an Ville Skyttä für einen ganzen Haufen Patches - MainMenuHooks-Patch auf 1.0.1 aktualisiert - tschechische Übersetzung, Danke an Radek Stastny fixes: - Speicherleck behoben, Danke an Sundararaj Reel für den Patch - Crash beim Editieren von Ausschlusslisten korrigiert 2011-09-11: Version 1.0.0 neu: - unterstützt vdr-1.6.0 bis vdr-1.7.21 - Vermeide Wiederholungen mit 'Vergleiche Zeitpunkt': dabei werden 2 Sendungen anhand des Zeitpunkts der Ausstrahlung verglichen, um z.B. Wiederholungen innerhalb des gleichen Tages, der Woche oder des Monats zu ignorieren. - Globale Ausschlusslisten: Ausschlusslisten für Suchtimer können nun als global markiert werden, um unerwünschte Sendungen generell auszuschliessen (wie z.B auf doppelten SD/HD- Kanälen). Vorbelegung für Suchtimer ist nun "nur globale", kann aber auch auf "keine" gesetzt werden, um auch globale Ausschlusslisten zu ignorieren. - neue Setup-Option epgsearch.ConflCheckCmd (keine GUI dazu, also nur per setup.conf zu setzen!), mit der man je Konflikt-Timer einen Befehl ausführen kann, mehr dazu im MANUAL. - vdr-1.7.15 benutzt einen anderen SVDRP Standard-Port (6419), bitte im Setupmenü von epgsearch ebenfalls anpassen! - Es gibt nun ein offizielles git repository für epgsearch, das die neueste Entwicklung enthält. Zuerst: git clone git://projects.vdr-developer.org/vdr-plugin-epgsearch.git Auf den aktuellen Stand kommt man einfach mit: git pull Web-git: http://projects.vdr-developer.org/git/?p=vdr-plugin-epgsearch.git Vielen Dank an die Leute von projects.vdr-developer.org, besonders an Tobias Grimm - Verzeichnis-Einträge in VDR's folders.conf werden nun ausgelesen und in der Verzeichnis- auswahl der Timerprogrammierung angeboten. - Suchtimer unterstützen nun content descriptors, die in vdr-1.7.11 eingeführt wurden. Damit können Sendungen nach ihrem Typ gesucht werden, z.B. "Film/Drama", "Dokumentation",... - Suchtimer haben nun eine neue Aktion "Ankündigen und Umschalten". Damit wird eine Sendung via OSD kurz vor ihrem Start angekündigt. Mit 'Ok' kann zum entsprechenden Kanal gewechselt werden. Umschalttimer haben die gleiche Option erhalten. - Zusätzlich zur Ankündigung per OSD können neue Sendungen nun auch per Mail bekannt- gegeben werden. Dazu gibt es eine neue Suchtimeraktion "Per Mail ankündigen". Man muss ausserdem das Mail-Templatefile epgsearchupdmail.templ anpassen (s. aktualisiertes HTML-Beispiel im conf-Verzeichnis bzw. MANUAL '13. Email notification'). - Die Zeit in Stunden zwischen den Suchtimer-Emails kann nun im Setup eingestellt werden um eine Überflutung des Posteingangs zu vermeiden. epgsearch puffert den Inhalt ausstehender Mails in der neuen Datei pendingnotifications.conf. - Neue Setup-Option zur Prüfung, ob es EPG für die nächsten x Stunden gibt. Falls nicht, kann man per OSD und/oder Mail gewarnt werden. (Setup -> Suche und Suchtimer), vorgeschlagen von Andreas Mair. - neue interne Variablen: * %day%, %month% und %year% liefern den numerische Tag, das Monat und das Jahr (mit Jahrhundert) einer Sendung * %chgrp% liefert die VDR Kanalgruppe einer Sendung * %liveeventid% liefert die kodierte Event-ID wie sie im Frontend 'live' benutzt wird. Damit können nun z.B. in den Suchtimer-Mails direkte Links angegeben werden. (s. Beispiel conf/epgsearchupdmail-html.templ) * %timer.liveid% liefert die kodierte Timer-ID wie sie im Frontend 'live' benutzt wird. Damit können nun z.B. in den Suchtimer-Mails direkte Links angegeben werden. * %date_iso% und %date_iso_now% ergeben das (aktuelle) Datum im Format 'YYYY-MM-DD', vorgeschlagen von Andreas Mair. * %search.series% liefert 1 oder 0 abhängig vom Flag "Serienaufnahme" der Suche und kann im Verzeichniseintrag einer Suche oder in deren abhängigen Variablen benutzt werden. - neues Kommando 'connect' innerhalb interner Variablen: damit kann eine Verbindung zu einem TCP-Dienst aufgebaut werden, Daten übergeben und das Ergebnis einer Variable zugewiesen werden. S. MANUAL für Details. - neues Kommando 'length' innerhalb interner Variablen: liefert die Länge des Arguments zurück. - Im Gedenken an pat: Update der französischen Übersetzung, Danke an Patrice Staudt - Update der italienischen Übersetzung, Danke an Diego Pierotto - Update der finnischen Übersetzung, Danke an Rolf Ahrenberg und Ville Skyttä - Neue litauische Übersetzung, Danke an Valdemaras Pipiras - Neue slowakische Übersetzung, Danke an Milan Hrala - neues SVDRP-Kommando 'MENU [NOW|PRG|SUM]' zum Aufruf eines der OSD-Hauptmenüs oder der Inhaltsangabe der aktuellen Sendung. Falls irgendein epgsearch-Menü geöffnet ist, schließt ein weiteres SVDRP-Kommando dieses wieder. - Die maximale Anzahl von Tagen für eine Timerkonfliktprüfung ist nun von 99 auf 14 geändert. - Patch von Jörg Wendel für neuen graphtft-Patch - Zwei Episoden mit leerem Untertitel innerhalb 'Vermeide Wiederholung' werden jetzt als unterschiedlich gewertet. Damit ergeben sich mehr Aufnahmen, aber es wird verhindert, dass man eine Folge nur wegen eines fehlerhaften EPGs verpasst. - Suchtimer: Falls der Datei-Eintrag eines Timers leer ist oder "!^invalid^!" enthält, wird er für die Programmierung übersprungen. - Wiederholung vermeiden: Die Option 'ja' bei 'Vergleiche Untertitel' wurde durch 'falls vorhanden' ersetzt. Damit stuft epgsearch zwei Sendungen nur dann als identisch ein, wenn die Episodennamen gleich sind und nicht leer. - epgsearch verwendet nun den shutdown handler (eingeführt in vdr 1.5.1) um die Unter- brechung eines Suchtimerupdates zu verhindern. - das SVDRP-Kommando UPDS zum Auslösen von Suchtimer-Updates hat nun eine neue Option 'SCAN' mit der vor dem eigentlichen Update noch ein EPG-Scan ausgeführt wird. - beim Löschen eines Suchtimers wird nun auch dessen Liste erstellter Timer gelöscht, vorgeschlagen von Sundararaj Reel - 'Datei' und 'Verzeichnis' an den Anfang des Timeredit-Menüs verlegt, da es zumindest bei mir das am meisten editierte Feld ist, z.B. bei wegen der Auswahl eines Ordners für die Aufnahme. - Wareagle Icons werden bei Verwendung des VDRSymbols-Font nun automatisch aktiv (kann aber mit WarEagleIcons=0 in epgsearchmenu.conf überschrieben werden), vorgeschlagen von Ronny Kornexl - Das korrekte Encoding für Email-Benachrichtigungen wird nun automatisch erkannt. - Es wird nun automatisch erkannt, ob Pin-Plugin oder Graphtft installiert sind, ebenso die optionalen Libs libpcre und libtre (läßt sich im Makefile mit Kommentieren von AUTOCONFIG abschalten) - neuer Patch vdr.epgsearch-exttimeredit.diff: Dieser VDR-Patch integriert epgsearch's Timer-Edit-Menü in VDR's Timer-Menü, Danke dafür an S:oren@vdr-portal. - einige Geschwindigkeitsverbesserungen, Danke an Tobias Bratfisch für die Patches - falls die VPS-Zeit von der Startzeit einer Sendung abweicht, wird die VPS-Kennung nun mit 'v' statt 'V' angezeigt. - Der erste Lauf der Hintergrund-Threads (Suchtimer, Umschalttimer, Konfliktprüfung) wird nun durch den ersten Aufruf von cPlugin::MainThreadHook ausgelöst, anstatt 20s nach dem VDR-Start. - Die Überwachung manueller Timer ignoriert nun Timer, deren Start- oder Stopzeit vom Anwender geändert wurde. - Der Default-Pfad zu sendmail ist nun '/usr/sbin/sendmail' und kann per Makefile konfiguriert werden, Danke an Ville Skyttä für den Patch. - Externe Suchtimer-Updates (via service interface oder SVDRP) aktivieren nun automatisch die Option "Suchtimer verw." im Setup. - epgsearch prüft nun neben korrekter Start- und Stopzeit des Timers auch die Aufnahmelänge bei der Prüfung auf vollständige Aufnahmen. 98% und mehr gelten als vollständig. - Umschalttimer sind nun ebenfalls in alle EPG-Menüs mit Suchergebnissen sichtbar. - Vermeide Wiederholung: Bei 'Vergleiche Beschreibung' kann nun angegeben werden wie hoch die Übereinstimmung sein muss, Default ist 90%. - falls kein Episodenname existiert, wird nun als Dateiname YYYY.MM.DD-HH.MM-Weekday verwendet, um die Sortierung in manchen Frontends zu erleichtern. Danke an Dominic Evans für einen Patch. - sollte nun auch unter FreeBSD compilieren, Danke an Juergen Lock für einen Patch - neuer SVDRP-Befehl UPDT zum Neuladen der Suchtimer aus der Datei epgsearch.conf fixes: - Absturz beim Drücken von 'Ok' in leerem Menü erledigter Timer behoben - Absturz bei Verwendung des Fortschrittsbalkens in Verbindung mit Sendungen der Länge 0 behoben. Danke an egal@vdrportal - Wenn eine unvollständige Aufnahme ein Suchtimer-Update für einen Suchtimer mit 'Wiederholung vermeiden' auslöst, werden nun bereits laufende Sendungen als Wieder- holung ignoriert. - Es wird nun cCondWait::Wait anstelle von cCondWait:SleepMs verwendet um Probleme beim Beenden zu vermeiden, danke e9hack@vdrportal für den Patch - Zeilenumbrüche im SVDRP-Befehl LSTT korrigiert, Danke an Andreas Mair für einen Patch - Antwortzeit beim Abbruch des Suchtimer-Threads verbessert - Absturz beim Navigieren zu benutzerdef. EPG-Menüs behoben, die zwischenzeitlich schon in der Vergangenheit lagen, Danke an Mike Constabel für den Hinweis - Im Timer-Edit-Menu war das Menu zur Tagesauswahl nicht mehr sichtbar - Wurde eine Sendung von mehreren Suchtimern mit "Nur ankündigen" gefunden, wurde sie auch mehrfach gelistet, Danke an Andreas Mair für den Hinweis. - Fehler bei "Nur ankündigen"-Suchtimer im Zusammenhang mit der Anzeige des zugehörigen Such- timernamens korrigiert. - Einige Speicherlecks korrigiert, Danke an Bittor Corl für einen Patch - Einige Korrekturen damit es mit gcc-4.4 compiliert, Danke an firefly@vdrportal für einen Patch. - Falsche Man-Sektion einiger Man-Pages korrigiert, Danke an Ville Skyttä für den Patch. - Einige Korrekturen bzgl. libtre-Includes, Danke an Ville Skyttä für den Patch. - Korrektur beim UTF8-Zeichensatz-Handling bei Timer-Filenamen, Danke an Rolf Ahrenberg für den Patch. - Absturz beim Hinzufügen sehr langer Episodentexte zum Verzeichnis eines Timers behoben, Danke an Lari Tuononen für den Hinweis. - Sichergestellt, dass nur noch ein Library für reguläre Ausdrücke von epgsearch benutzt wird, Danke an Ville Skyttä für den Patch. - Einige Provider haben seltsame Änderungen in den EPG-Zeiten von nur wenigen Sekunden. epgsearch ignoriert nun Änderungen von weniger als 60s und ändert den zugehörigen Timer nicht. Es erfolgt auch keine Emailbenachrichtigung. Danke an cmichel@mantis für den Hinweis. - möglicher Fix für das alte Problem mit dem crash in libpcre, Danke an Andreas Cz. für den Patch und an Stefan Bauer für den Hinweis darauf. - Fix für einen Absturz beim Hin- und Herschalten von mit/ohne Untertitel bei Timern mit mit sehr langen Episodennamen, Danke an Ville Skyttä für den Patch. - Korrektur beim file descriptor handling bei fehlerhafter SVDRP-Verbindung, Danke an Teemu Rantanen für einen Patch. - Service-Schnittstelle für Umschalttimer wegen falschem Parameterhandling korrigiert, Danke an gnapheus@vdrportal für den Hinweis. - Korrektur der Suche ohne Unterscheidung von Groß-/Kleinschreibung in Verbindung mit Utf-8-Zeichen, danke an Ville Skyttä für den Hinweis. - Prüfung auf Vollständigkeit von VPS-Aufnahmen korrigiert, Danke an durchflieger@vdr-portal für einen Patch. 2008-04-29: Version 0.9.24 neu: - Unterstützung von vdr-1.6.x/1.7.x - Die Suche und damit das Suchtimer-Update sind nun etwa 25% schneller - Schnellere EPG-Menüs, danke an die Patch-Authoren von http://www.open7x0.org - Unterstützung des VDRSymbols-Font (aktivieren mit 'WarEagle=1' in epgsearchmenu.conf) - der EPG-Befehl 'Suche in Aufnahmen' wertet nun die info.vdr anstelle des Aufnahmepfades aus und macht zusätzlich eine fuzzy-Suche, vorgeschlagen von Mase@vdrportal - Suchtimer mit Aktion 'Nur umschalten' und Switchtimer haben jetzt eine weitere Option 'Ton anschalten', wodurch der Ton beim Umschalten aktiviert wird, falls er aus war, vorgeschlagen von Michael Brückner - Die Timer-Benachrichtigungsmail unterstützt nun eine weitere Variable %timer.modreason%, in der im Klartext der Grund einer Timeränderung steht (s. epgsearchupdmail(-html).templ für ein Beispiel) - Unterstützung für einen conf.d-Mechanismus (s. MANUAL -> 14. The conf.d subdirectory), vorgeschlagen von Mike Constabel - neuer SVDRP-Befehl 'LSCC', der das Ergebnis einer Timerkonfliktprüfung zurückgibt. Zum Format der Ergebnisliste bitte ins MANUAL schauen. - Neuer Patch für VDR (vdr-1.5.17-progressbar-support-0.0.1.diff), der die Unter- stützung eines grafischen Fortschrittsbalkens in den Skins classic und st:tng einbaut, Danke an zulu@vdrportal. - '0' im Menü der erledigten Aufnahmen schaltet nun die Anzeige zwischen '~Episode' und 'Titel~Episode' um. - Das Favoriten-Menü kann jetzt auch per Setup nach 'Übersicht - Jetzt' angezeigt werden, vorgeschlagen von Bittor Corl - Im Menü "erledigte Aufnahmen" wird nun beim Datum absteigend sortiert. - Unterstützung für das neue Info-Key-Verhalten in vdr-1.5.13 - Änderungen für den eingebauten graphtft-patch (bei Verwendung von VDR-extension-patch ist > v.37 notwendig) - Update des timercmd-patches für vdr-1.5.12 (patches/timercmd-0.1_1.5.12.diff) - Neue Datei patches/README.patches für eine Beschreibung der vorhandenen Patches - Update von 'undoneepgsearch.sh', einem Skript zum Entfernen einer Aufnahme aus dem done-File über die reccmds.conf, Danke an Viking@vdrportal. - Update der finnischen Übersetzung, Danke an Rolf Ahrenberg - Spanische Übersetzung, vielen Dank an agusmir, dragondefuego, GenaroL, lopezm und nachofr von todopvr.com, und ein besonderer Dank an bittor - Update der italienischen Übersetzung, Danke an Diego Pierotto - Update der niederländischen Übersetzung, Danke an carel@bugtracker - Die Setup-Option "Keine Ankündigungen bei Wiedergabe" wird jetzt ignoriert, wenn das Suchtimer-Update manuell gestartet wurde, vorgeschlagen von Andreas Mair. fixes: - Shiften der Uhrzeit: die Startzeit wird jetzt nur noch dann anstelle des Fortschrittsbalken angezeigt, wenn in der Menüvorlage nicht bereits eine Startzeit enthalten ist ("%time%"), so wie in der Standardvorlage. Danke an Getty@vdrportal für den Hinweis. - einige Punkte bzgl. GPL korrigiert, Danke an Thomas Günther für den Hinweis. - Crash behoben bei nicht vorhandenem EPG, Danke an Petri Helin für einen Patch. - Der Standardwert für die maximale Dauer ist nun '23:59' um Probleme mit externen Tools zu vermeiden, Danke an ralf-naujokat@bugtracker für den Hinweis (bug-id #371) - bei EPG-Änderungen mit weniger als 10 Minuten hat epgsearch bisher einen Timer modifiziert anstatt einen neuen anzulegen. Das verursachte jedoch Probleme mit Sendungen unter 10 Minuten Länge. Die Toleranz ist deshalb nun min(, 10 min). Danke an Janne Liimatainen für den Hinweis. - einige Übersetzungen korrigiert, Danke an ramirez@vdrportal für den Hinweis. - Scrollgeschwindigkeit in den EPG-Menüs verbessert, Danke an ramirez@vdrportal für den Hinweis. - Absturz behoben, wenn SIGINT während des Startens der Background-Threads signalisiert wird. - Kanalgruppen-Separatoren in 'Übersicht Jetzt/Nächste/...' werden nun ausgeblendet, wenn sie leer sind, wie in ':@30', Danke an Ulf Kiener für einen entspr. Patch. - Absturz beim Aufruf des Setups der Addon-Plugins behoben, wenn VDR mit dem ext-Patch und aktivem LIEMIKUUTIO versehen wurde. - 'Wiederholung vermeiden' kombiniert mit 'Pause, wenn ... Aufnahmen existieren' hat zu wenige Timer erzeugt, Danke an spockele@vdrportal für den Hinweis - einige Compilerwarnungen von g++ 4.3 behoben - fine-tuning beim fuzzy-Vergleich von Inhaltsangaben, Danke an Alf Fahland für einen Patch - Problem mit Pipes im Suchbegriff einer Blacklist behoben, Danke anAndreas Mair für den Hinweis. - Beschriftung der grünen/gelben Taste nach Umschalten im Menü "Schedule" korrigiert. Danke an Andreas Mair für den Hinweis. - Auswertung von Compiler-Flags wie WITHOUT_EPGSEARCHONLY,... korrigiert. 2007-09-02: Version 0.9.23 neu: - unterstützt das neue i18n-System in vdr>=1.5.7, ist aber weiterhin abwärtskompatibel - bei den erweiterten EPG-Kategorien kann nun auch wertmäßig verglichen werden, z.B. um nach Sendungen nach einem bestimmten Jahr zu suchen. Dazu wurden neue Suchmodi für die epgsearchcats.conf eingeführt (10 entspricht '<', 11 entspricht '<=', ...) Beispiel: # 'bis Jahr' 3|Year|bis Jahr||11 # 'ab Jahr' 12|Year|ab Jahr||13 Denkbar wäre auch die Suche nach einer bestimmten Staffel einer Serie, falls dies im EPG enthalten ist. Eine vollständige Liste der Suchmodi ist im Bereich in der Dokumentation aufgeführt - Neuer Schalter "Ignoriere fehlende Kategorien" im Edit-Menü eines Suchtimers bei den erweiterten EPG-Kategorien: Wenn 'Ja' gewählt ist, verhindert das, dass eine Sendung aus dem Suchergebnis ausgeschlossen wird, falls die entsprechende Kategorie nicht im EPG vorhanden ist. Vorsicht: Ohne weitere Suchkriterien kann das zu einer Flut von Timern führen. - Suchtimer können jetzt automatisch gelöscht werden. Im Edit-Menü gibt es dafür: * nach x Aufnahmen, oder * nach x Tagen nach erster Aufnahme gezählt werden nur erfolgreiche Aufnahmen. Das Löschen erfolgt direkt nach dem Ende der entsprechenden Aufnahme. - Neue Aktion "Kopie anlegen" im Menü Suche/Aktionen zum Anlegen und Editieren einer Kopie der aktuellen Suche, vorgeschlagen von Michael Brückner. - Die Option "Verw. als Suchtimer" hat nun einen dritten Wert 'benutzerdef.' neben 'Ja' und 'Nein', mit dem man über die Taste 'Blau' ein Zeitfenster angeben kann, in dem der Suchtimer aktiv sein soll. Vorgeschlagen von jo01@vdrportal. - Der Fortschrittsbalken zeigt nun die Startzeit anstelle eines leeren Balkens an, wenn man zu einer noch nicht laufenden Sendung shiftet, Danke an zulu@vdrportal für den Patch. - Das Menü "Zeige erstellte Timer" zeigt nun mit 'Ok' die Inhaltsangabe der erstellten Timer. Ebenfalls funktionieren die Kurztasten '1..9' für die EPG- Befehle. - eingebauter pin-plugin patch (epgsearch muss nicht mehr gepatcht werden) Zum Aktivieren bitte mit 'USE_PINPLUGIN' in VDR's Make.config kompilieren (ist mit VDR extension patch bereits automatisch der Fall) - eingebauter graphtft-plugin patch (epgsearch muss nicht mehr gepatcht werden) Zum Aktivieren bitte mit 'USE_GRAPHTFT' in VDR's Make.config kompilieren (ist mit VDR extension patch bereits automatisch der Fall) - Update der finnischen Übersetzung, Danke an Rolf Ahrenberg - Update der französischen Übersetzung, Danke an Patrice Staudt fixes: - Fehler beim Anlegen eines Timers korrigiert, nachdem man durch die Inhalts- angabe navigiert hat, danke an Rolf Ahrenberg für den Hinweis. - Beschriftung "Aufnehmen" bzw. "Timer" im Menü Inhaltsangabe je nach vorhandenem Timer korrigiert. - Fehler bei Umschalttimern und geändertem EPG behoben, Danke an Juergen Urban für einen Patch - einige Compiler-Warnungen in g++-4.2 gefixed, Danke an Michael Brückner für den Hinweis. - "," als erlaubtes Zeichen für Suchtimer hinzugefügt, Danke an Mike Constabel für den Hinweis. 2007-05-27: Version 0.9.22 neu: - neue Option in der Timerkonflikt-Prüfung "Beim Beginn einer Aufnahme": Dadurch wird beim Start einer Aufnahme eine Konfliktprüfung durchgeführt und per OSD über Konflikte informiert, wenn der Konflikt innerhalb der nächsten 2h auftritt. Somit werden also auch Timer überwacht, die nicht innerhalb epgsearch programmiert wurden, ebenso Sofortaufnahmen. - Neues Service-Interface "Epgsearch-services-v1.0": Damit können andere Plugins auf viele Komponenten von epgsearch wie z.B. Suchtimer, Setup-Werte, ... zugreifen, diese verwalten und Aufgaben wie 'Nach Wiederholung suchen' ausführen (Mehr dazu in services.h). - Neue Projekt-Homepage: http://winni.vdr-developer.org/epgsearch, vielen Dank an Thomas Keil - Update der finnischen Übersetzung, Danke an Rolf Ahrenberg. fixes: - vollständige Neuentwicklung des Menüs zur Inhaltsangabe und dessen Navi- gation, um Probleme mit Skins zu vermeiden und andere Bugs zu beheben. - beim Test auf Wiederholungen wird nun auch im Vergleich mit dem Done-File nur der alphanumerische Teil von Titel und Episode verwendet. - weiteres Problem mit Anführungszeichen beim Aufrunf von EPG-Befehlen korrigiert. - Lizenzänderungen und -ergänzungen für den Einzug ins Debian-Repository - Fehler in der Zeitanzeige bei benutzerdef. Zeiten in Verbindung mit Zeit- sprung mit FRew/FFwd behoben, Danke an Torsten Weigelt für den Hinweis - Die Zusatzinfo über den Kanal wurde bei 'Timer mit 'Aufnehmen' sofort anlegen' nicht erzeugt. Danke an Rolf Ahrenberg für den Patch. 2007-04-29: Version 0.9.21 neu: - Unterstützung für den MainMenuHooksPatch. Dieser löst den vdr-replace-schedulemenu-Patch ab. Der neue Patch wird auch von anderen Plugins verwendet. Somit ist dafür nur noch ein Patch notwendig. Der alte Patch wird vorübergehend ebenfalls noch unterstützt. - Die Sendungs-Ankündigungen per OSD wurden vollständig überarbeitet. Statt einer Anzeige jeder einzelnen Sendung erhält man nun "x neue Sendungen gefunden! Anzeigen?". Mit 'Ok' wird ein Menü aller Sendungen eingeblendet, das die üblichen Funktionen anderer EPG-Menüs hat. Mit "Editieren" kann man die Ankündigungs-Einstellungen verändern (z.B. "Erneut ankündigen: ja/nein" oder erst wieder nach Tag x ankündigen). - Timer-Konflikt-Benachrichtigungen per OSD können nun während einer Wieder- gabe unterdrückt werden. Die Benachrichtigung erfolgt aber trotzdem, wenn der nächste Konflikt innerhalb der nächsten 2 Stunden liegt. - alle sub-Plugins (epgsearchonly, quickepgsearch, conflictcheckonly) haben nun eine Setupoption zum Ein-/Ausschalten des Hauptmenüeintrags. Danke an Tobias Grimm für den Patch. - Kanalname in der Aux-Info von manuellen Timern, Danke an Rolf Ahrenberg für den Patch. - neues Skript undoneepgsearch.sh zum Rücksetzen eines Timers im Aufnahmemenü. Mehr dazu unter: http://www.vdr-portal.de/board/thread.php?postid=574109#post574109 Danke an den Author Christian Jacobsen - Update der französischen Übersetzung, Danke an Patrice Staudt. - Update der finnischen Übersetzung, Danke an Rolf Ahrenberg. - Im Menü 'Timer-Konflikt-Details' wird im Titel nun auch das Datum des Konflikts angezeigt, vorgeschlagen von Rusk@vdrportal. - Das Passwort für die Mail-Authentifizierung wird im OSD nun versteckt angezeigt, d.h. mit '***...' - Das Setup für Mail-Benachrichtigungen hat nun auch ein "Senden an"-Feld, weil einige Provider keine Mails mit gleichem Sender/Empfänger akzeptieren. Falls das Feld nicht besetzt ist, benutzt epgsearch automatisch den Sender als Empfänger. - Beim Prüfen auf Wiederholung (beim Feature "Wiederholung vermeiden") vergleicht epgsearch nun nur noch die alphanumerischen Teile von Titel und Episode und ignoriert dabei auch die Groß-/Kleinschreibung. Vorschlag von chello@vdrportal. - Danke an Rolf Ahrenberg für das Update der finnischen Übersetzung - '&' zu den erlaubten Zeichen eines Suchbegriffs hinzugefügt fixes: - Die Tags in der Aux-Info von Timern, die per Suchtimer erzeugt wurden, sind nun XML-konform (keine Großbuchstaben oder Leerzeichen). Z.B. wird aus "Search timer" nun "searchtimer". Also nicht wundern, wenn beim ersten Suchtimer-Update alle Timer aktualisiert werden, die von Suchtimern angelegt wurden. Danke an Rolf Ahrenberg für den Hinweis. - Update von recordingdone.sh wegen der vorherigen Änderung, Danke an Mike Constabel für einen entsprechenden Patch. - segfault bei falsch konfigurierten erw. EPG-Kategorien behoben. - Scrollende Menütexte funktionieren nun wieder, wenn der gewählte Skin das unterstützt. Danke an ufauser@vdrportal für den Hinweis. - Die Setup-Option "Verw. Suchtimer" wird nun automatisch aktiv, wenn ein Suchtimer aktiv gesetzt wird oder ein manuelles Suchtimer-Update gestartet wird. - Behandlung von Anführungszeichen in Titel/Untertitel bei Übergabe an benutzerdef. EPG-Befehle korrigiert, Danke an Mike Constabel für den Hinweis. - Handling im Suchtimer-Vorlagenmenü korrigiert, Danke an wombel@vdrportal für den Hinweis. 2007-01-30: Version 0.9.20 neu: - Unterstützung von vdr-1.5.0: Hinweis: Der CA-Support im Timerkonflikt-Check ist ziemlich experimentell, weil ich es mangels CAMs nicht testen kann. - epgsearch kann nun auch manuell programmierte Timer auf EPG-Änderungen überwachen. Wenn epgsearch's eigenes Timer-Edit-Menü benutzt wird, stehen folgende Methoden zur Auswahl: * ohne Überwachung * anhand Sendungskennung * anhand Kanal/Uhrzeit Mehr dazu in der README.DE (unter 1.4.4 Setup/Timer-Programmierung/Standard-Timer-Prüfmethode) - die im Favoritenmenü verwendete Zeitspanne kann jetzt über das Setup angepaßt werden. Standard sind 24h. - Sendungs-Ankündigungen: Wenn während der Ankündigung einer Sendung eine der Tasten '0', ... '9' oder 'Ok' gedrückt wird, wird nachgefragt, ob zukünftige Ankündigungen vollständig (bei den Tasten '0' oder 'Ok') oder nur für die nächsten x Tage (bei den Tasten '1' bis '9') unterdrückt werden sollen. Bestätigt man diese Abfrage durch ein erneutes 'Ok', wird die Einstellung entsprechend übernommen. - Mit der neuen Setup-Option "Keine Ankündigungen bei Wiedergabe" können Ankündigungen von Sendungen während einer Wiedergabe nun abgeschaltet werden. Vorgeschlagen von Andreas Mair. - Neben der Erledigt-Liste für Aufnahmen gibt es nun auch eine für Timer (timersdone.conf). Damit können nun Timer gelöscht werden, ohne dass diese mit dem nächsten Suchtimer-Update wieder neu angelegt werden. Mit dem neuen Menü 'Zeige erzeugte Timer' unter Suche/Aktionen kann diese Liste bearbeitet werden. Das ganze Verfahren kann im Suchtimer-Setup auch abgeschaltet werden. Achtung: Diese Timer-Erledigungsliste wird nur mit Timern gefüllt, die ab dieser Version neu angelegt wurden. - neues Zusatzplugin 'quickepgsearch': Dieses erstellt einen Hauptmenüeintrag "Schnellsuche", der dazu dient einfach nach einem beliebigen Begriff im EPG zu suchen. Mit '-Pquickepgsearch' einbinden. Vorgeschlagen von SurfaceCleanerZ@vdrportal. - neue Setup-Option "Kanäle begrenzen von 1 bis" zur Beschleunigung von epgsearch's Aufruf. Ist der aktuelle Kanal über dem Limit werden alle Kanäle angezeigt. Vorgeschlagen von Uwe@vdrportal. - neue SVDRP-Befehle: * 'LSRD' liefert eine Liste aller Verzeichnisse zurück, die aktuell bei Aufnahmen, Timern, Suchtimern oder in epgsearchdirs.conf verwendet werden. * 'LSTT [ID]' liefert alle Such-Vorlagen, oder die Vorlage mit der angegebeenen ID (Format wie in epgsearch.conf). * 'NEWT ' zum Anlegen einer neuen Suchvorlage. * 'DELT ' zum Löschen der Suchvorlage mit der angegebenen ID. * 'EDIT ' zum Ändern einer Suchvorlage. * 'DEFT [ID]' liefert die aktuelle Standard-Suchvorlage. Wird eine ID übergeben wird die zugehörige Suchvorlage zur Standard-Suchvorlage. - geänderte SVDRP-Befehle: * 'DELS [ID] [DELT]' löscht nun neben der Suche auch zugehörige Timer, wenn das optionale 'DELT' mitübergeben wird. - man kann nun neben dem Skript sendemail.pl auch sendmail für den Mailversand verwenden (->Setup), vorgeschlagen von Patrick Cernko - Neue Variablen: * '%timespan%' zur Verwendung in Menüs oder Mails. Zurückgegeben wird die Zeitspanne von Jetzt bis zum Beginn einer Sendung (z.B. 'in 15m'). Die Variable wird nun im Standard-Menütemplate des Favoritenmenüs verwendet, in dem das Datumsfeld entfernt wurde. * '%length%' für die Länge einer Sendung in Sekunden. - Danke an Rolf Ahrenberg für das Update der finnischen Übersetzung fixes: - manuell programmierte Timer werden durch Suchtimer nun weder gelöscht noch geändert. - das Zusatzplugin conflictcheckonly wurde kompiliert auch wenn WITHOUT_CONFLICTCHECKONLY im Makefile gesetzt war, Danke an Ronny Kornexl für den Hinweis. - Für Suchbegriff und Verzeichnis gibt es nun auch die Zeichen 'ß' (nur bei Sprache Deutsch) und '@'. - Bei Verwendung von 'Wiederholung verm.' war es in bestimmten Fällen möglich, dass nicht die Erstausstrahlung, sondern eine Wiederholung programmiert wurde. - Eine Suche mit "Verw. Wochentag" UND "Verw. Uhrzeit", bei der "Start vor:" nach Mitternacht liegt, findet nun auch Sendungen des nächsten Tages bis "Start vor:", z.B. "Start nach 22:00" und "Start vor 03:00" am Montag findet nun auch eine Sendung um 01:00 am Dienstag. - bereits aufnehmende Timer werden nun nur noch aktualisiert, falls sich die Stopzeit des Timers (z.B. wegen EPG-Update) ändert, Danke an Mike Constabel für den Hinweis. - Fehler beim Auswerten von Uservariablen behoben, Danke an Mike Constabel für den Hinweis und für's remote debugging. - Fehler bei Timerkonflikt-Mails im Zusammenhang mit Timern ohne zugeordneten Event behoben. 2006-10-27: Version 0.9.19 - neu: wenn sich die Suchergebnisse unterschiedlicher Suchen überschneiden, wird der zugehörige Timer nun nur noch von der Suche aktualisiert, die ihn ursprünglich angelegt hat. - neue Variablen: * '%search.query%' für die Verwendung im Aufnahmeverzeichnis eines Suchtimers. Diese wird mit dem Suchbegriff eines Suchtimers ersetzt. * '%videodir%' VDR Videoverzeichnis (z.B. /video) * '%plugconfdir%' VDR plugin Konfigurationsverzeichnis (z.B. /etc/vdr/plugins) * '%epgsearchdir%' epgsearchs Konfigurationsverzeichnis (z.B. /etc/vdr/plugins/epgsearch) - die Syntax des 'system'-Kommandos innerhalb einer Uservariable hat sich geändert, um die Parameter flexibler übergeben zu können. Sie lautet nun: %uservar%=system(/path/to/script[, parameters]) wobei das optionale 'parameters' ein beliebiger Ausdruck unter Verwendung weiterer Uservariablen sein kann. Ausnahme: es dürfen nicht direkt weitere system-Calls oder bedingte Ausdrücke verwendet werden. - Update der französischen Übersetzung, Danke an Patrice Staudt fixes: - VPS-Timer, die von Suchtimern angelegt wurden, werden nun immer auf Ihre VPS-Zeit aktualisiert, selbst wenn der Anwender Start- und/oder Stopzeit verändert hat. - nach Änderungen im Setup wurden Menü-Templates aus epgsearchmenu.conf wieder auf den Standard zurückgesetzt, Danke an s.krueger@vdrportal für den Hinweis. - vorhandene VDR-Wiederholungstimer werden durch das Suchtimer-Update nicht mehr zu normalen Timern abgeändert. 2006-10-01: Version 0.9.18 neu: - WICHTIG!!! BITTE LESEN!: epgsearch erwartet seine conf-Dateien nun in einem eigenen Konfig-Verzeichnis 'epgsearch' innerhalb des Plugin-Konfig-Verzeichnis und nicht mehr wie bisher direkt im Plugin-Konfig-Verzeichnis. Bitte legt dieses Verzeichnis an und verschiebt alle epgsearch-Dateien dorthin, bevor Ihr diese Version verwendet. Etwa so: mkdir /etc/vdr/plugins/epgsearch mv /etc/vdr/plugins/epgsearch*.* /etc/vdr/plugins/epgsearch mv /etc/vdr/plugins/.epgsearch* /etc/vdr/plugins/epgsearch Wer bereits epgsearch's '--config' oder '-c' Parameter verwendet hat, für den ist das nicht weiter wichtig. - 'Favoriten-Menü' neben 'Jetzt' and 'Nächste': Dieses Menü kann eine Liste der Lieblingssendungen der nächsten 24h zeigen. Dazu zunächst im Setup 'Zeige Favoriten-Menü' aktivieren. Um epgsearch zu sagen, was die Lieblingssendungen sind, dann Suchen anlegen/editieren und dort 'In Favoritenmenü verw.' auswählen. - neue Setup-Option für den Timer-Konflikt-Check: 'Nach jeder Timer-Programmierung'. Das bewirkt eine Konfliktprüfung nach jeder manuellen Timer-Programmierung und erzeugt sofort eine OSD-Nachricht, falls der neue/geänderte Timer in einen Konflikt verwickelt ist. - neue Email-Benachrichtigungen über Suchtimer-Updates oder Timer-Konflikte. Der Inhalt der Mails kann beliebig gestaltet werden. Bitte im MANUAL-Abschnitt 'Email notification' für weitere Details nachlesen. - epgsearch hat jetzt einen Satz von man-Pages. Ein GROSSES Danke an Mike Constabel (vejoun@vdrportal), der die ganze Arbeit des Umschreibens, Korrigierens und Formattieren gemacht hat. Die man-Pages enthalten die README's, das MANUAL, sowie eine Beschreibung aller conf's, die epgsearch verwendet. Das alles auf DE/EN. Einfach mit 'make install-doc' im epgsearch-src-Verzeichnis einrichten. - man kann jetzt eigene Variablen definieren um diese im Standard-Aufnahme-Verzeichnis, im Suchtimer-Aufnahme-Verzeichnis oder in den Menü-Templates zu verwenden. Nachdem das Ganze etwas komplex ist, bitte den Abschnitt 'User defined variables' im MANUAL lesen. Hier nur ein Beispiel was möglich ist: # Weekday, Date, Time %DateStr%=%time_w% %date% %time% # Themes or Subtitle or Date %ThemesSubtitleDate1%=%Subtitle% ? %Subtitle% : %DateStr% %ThemesSubtitleDate%=%Themes% ? %Themes% : %ThemesSubtitleDate1% # Calls this script to get a recording path %DocuScript%=system(doku.pl,%Title%,%Subtitle%,%Episode%,%Themes%,%Category%,%Genre%) %Docu%=%DocuScript% - Taste 'Ok' kann jetzt auch so konfiguriert werden, dass der Kanal gewechselt wird anstelle der Anzeige der Inhaltsanzeige. Vorschlag von malachay@vdrportal - wenn ein Timer von einem Suchtimer erzeugt wurde, wird nun in epgsearch's eigenem Timer-Edit-Menü der Name der Suche am Ende in einem nicht selektierbaren Feld angezeigt. - wenn eine Sendung via Suchtimer angekündigt wird, kann man nun dafür einen Timer erzeugen, wenn man während der Ankündigung die rote Taste drückt, vorgeschlagen von Andreas Mair. - Wenn Suchtimer im Setup abgeschaltet sind, dann bewirkt ein Anlegen/Ändern eines Suchtimers nun auch eine automatische Aktivierung im Setup, vorgeschlagen von Andreas Mair. - man kann jetzt mehr als ein Menü-Template für die Suchergebnisse verwenden. (s. MANUAL, Abschnitt "Customizing the EPG menus") - die Prüfung auf Vollständigkeit einer Aufnahme erlaubt nun auch kurze Unterbrechungen (unter 2s, z.B. bei einem Kanal-PID-Wechsel). - neue SVDRP-Befehle: * LSTC [channel group name] zeigt alle Kanalgruppen an oder nur die optional angegebene * NEWC erstellt eine neue Kanalgruppe, Format wie in epgsearchchangrps.conf * EDIC ändert eine vorhandene Kanalgruppe, Format wie in epgsearchchangrps.conf * DELC löscht eine vorhandene Kanalgruppe * RENC benennt eine Kanalgruppe um * LSTB [ID] zeigt alle Ausschlusslisten an, oder nur diejenige mit der angegebenen ID (Format ist dasgleiche wie in epgsearchblacklists.conf, s. MANUAL) * NEWB zum Anlegen einer neuen Blacklist Anmerkung: der Wert ID wird ignoriert und von epgsearch automatisch vergeben. * DELB zum Löschen einer Blacklist mit der angegebenen ID * EDIB zum Ändern einer Blacklist * 'QRYS < ID(s) >' liefert die Ergebnisse einer Suche mit der angegebenen ID zurück. Es können auch mehrere IDs übergeben werden, getrennt durch '|'. (s. MANUAL) * 'QRYS ' liefert die Ergebnisse einer Suche mit den angegebenen Werten zurück. * 'QRYF [hours]' liefert die Ergebnisse des Favoriten-Menüs (s. MANUAL). Der optionale Parameter gibt die Anzahl der auszuwertenden Stunden an. Standardwert ist 24h. * 'LSTE [ID] liefert die erweiterten EPG-Kategorien, wie sie in epgsearchcats.conf definiert sind, oder nur diejenige mit der angegebenen ID. * 'MODS ID ON|OFF' schaltet die Option 'als Suchtimer verw.' ein/aus. * 'SETP option' liefert den aktuellen Wert einer Setup-Option (s. MANUAL). - epgsearch hat jetzt ein Bug-Tracking-System (deutsch) und eine Mailinglist (englisch): http://www.vdr-developer.org/mantisbt http://www.vdr-developer.org/mailman/listinfo/epgsearch Danke an die Betreiber von developer.org - neues Service-Interface "Epgsearch-switchtimer-v1.0" zum Zugriff und zur Verwaltung der Umschaltlisten (switch timer). Danke an Dirk Leber für die Erweiterung. - Update für die französische Übersetzung (mit Setup-Hilfe!), Danke an Patrice Staudt - Danke an Rolf Ahrenberg für das Update der finnischen Übersetzung fixes: - der erste Tag eines Wiederholungstimers wird nun beim Timer-Konflikt-Check berücksichtigt, Danke an zimuland@vdrportal für den Hinweis - Suchtimer-Update für VPS-Timer korrigiert, Danke an Chello und oholler@vdrportal für den Hinweis - Behandlung des Zeichens '|' beim Wechsel des Suchmodus einer Suche korrigiert, Danke an Chello@vdrportal für den Hinweis - einige Suchmodi in den epgsearchcats.conf-Beispielen für die Mehrfachauswahl geändert. - zusätzliche Linefeeds in der SVDRP-Antwort von LSTS entfernt, Danke an Andreas Mair für den Hinweis - Kanal-Kriterium 'ohne Pay-TV' wurde ignoriert, Danke an Andreas Mair für den Hinweis - Min/Max-Initial-Werte für Suchkriterium "Dauer" korrigiert, Danke an Mike Constabel für den Hinweis - einen Bug bei der Auswahl der Konfliktprüfung nach jedem Suchtimer-Update behoben, Danke an Ronny Kornexl für den Hinweis - '--remove-destination' ins Makefile integriert, wie in vdr-1.4.2-3 eingeführt. 2006-08-07: Version 0.9.17d (maintenance release) fixes: - falsche Verwendung von 'cPlugin::ConfigDirectory' im Suchtimer-Thread korrigiert, Danke an Udo Richter und Petri Hintukainen für den Hinweis 2006-06-12: Version 0.9.17c fixes: - Problem mit Mehrfachauswahl bei erweiterten EPG-Kategorie-Werten behoben, Danke an Christian Jacobsen für den Hinweis - Nochmal ein Fix für den gcc unter linvdr, Danke an toxic-tonic@vdrportal 2006-06-10: Version 0.9.17b fixes: - einige Probleme mit Wiederholungstimer im Timer-Konflit-Check behoben, Danke an Peter Juenger für den Hinweis - Crash beim Konflikt-Check behoben bei einer aktiven Aufnahme auf einem Gerät, das über ein Plugin zur Verfügung gestellt wird (z.B. pvr, streamdev), Danke an Gerhard Steiner für den Hinweis. 2006-06-06: Version 0.9.17a (bug fix release) - Menü 'Timer-Konlfikte' wurde automatisch geschlossen, wenn Wiederholungstimer existierten, Danke an lostinspc@vdrportal - einige Compiler-Probleme mit gcc-2.95 und gcc-4.1.0 behoben, Danke an ferdi03@vdrportal, smudo81@vdrportal, toxic-tonic@vdrportal 2006-06-05: Version 0.9.17 - Kein Support mehr für vdr < 1.3.46 :-( - Die Logik beim Springen durch die benutzerdef. EPG-Zeiten hat sich geändert: Es können jetzt auch Zeiten des nächsten Tages erreicht werden, wenn diese nicht mehr als 20 Stunden in der Zukunft liegen. Danke an egal@vdrportal und CKone@vdrportal. - epgsearch hat jetzt einen eigenen Timer-Konflikt-Check, der über das Setup angepasst werden kann. Einstellbar sind relevante Prioritäten, die Zeitspanne der Prüfung und die relevante Dauer eines Konflikts. Begleitet wird dieser Check von einem "Konflikt-Manager" unter Suchen/Aktionen, der bei der Auflösung von Konflikten hilft. Vielen Dank an Mike Constabel für seine ausführlichen Tests. - Falls über einen Konflikt per OSD eine Nachricht erfolgt, kann nun mit 'Ok' direkt in die Konflikt-Übersicht des Konflikt-Managers gewechselt werden. - Falls jemand für die Konfliktprüfung einen eigenen Hauptmenü-Eintrag opfern will, kann dazu das Mini-Plugin 'conflictcheckonly' verwenden, das automatisch mitkompiliert wird. Wie üblich mit '-Pconflictcheckonly' einbinden. conflictcheckonly hat eine Setup-Option, mit der Informationen über den letzten Check direkt im Hauptmenü angezeigt werden. - Das Setup ist nun vollständig umgekrempelt (in Kategorien) und hat nun soetwas wie eine 'Online'-Hilfe, die die einzelnen Punkte näher erklärt. - Im Menü 'Umschalttimer' wird nun auch die Kanalnummer angezeigt. - Die Eingabe-Logik bei den erweiterten EPG-Kategorien für eine Suche hat sich geändert um eine Mehrfachauswahl von Kategorien zu erlauben. - Neues Skript 'timercmds-auxinfo.sh' zur Anzeige der Aux-Infos (z.B. welcher Suchtimer hat diesen Timer erzeugt?) im VDR-Timer-Menü (erfordert den timercmd-Patch), Danke an den Author Mike Constabel. - bei benutzer-def. EPG-Zeiten mit leerer Beschreibung wird nun die Uhrzeit als Beschreibung verwendet, vorgeschlagen von Thiemo Gehrke - Neues Service-Interface "Epgsearch-conflictmenu-v1.0" zum Aufruf der Timer-Konlfikt-Übersicht durch andere Plugins - Neues Service-Interface "Epgsearch-lastconflictinfo-v1.0" zur Abfrage der Ergebnisse des letzten Konfliktchecks durch andere Plugins. - epgsearchmenu.conf wird nun nicht mehr bei jedem Plugin-Aufruf neu geladen, weil das nur zum Testen eines conf-Files sinnvoll ist. Um das permanente Neuladen trotzdem zu aktivieren, kann man als Plugin-Parameter '-r' oder '--reloadmenuconf' in der runvdr angeben. - Danke an Rolf Ahrenberg für das Update der finnischen Übersetzung - HISTORY.DE hinzugefügt fixes: - Beim Laden der epgsearchmenu.conf wird im Fehlerfall nun auf ein Default-Menü geschaltet. - Behandlung von '%' in LSTS für SVDRP bei vdr > 1.3.44 korrigiert, Danke an Mike Constabel - Rechtzeitiges Laden der epgsearchmenu.conf für epgsearchonly und das Service-Interface "Epgsearch-searchmenu-v1.0", Danke an Daniel Dorau für den Hinweis. - Menü-Anzeigefehler in 'Suchvorlagen' korrigiert, Danke an Mike Constabel - Bug beim Löschen zugehöriger Timer eines Suchtimers behoben, wenn es überhaupt keine Timer gibt, Danke an Patrick Koppen für den Hinweis. - hoffentlich :-) einen Bug beim Übernehmen einer Suche in die Vorlagen behoben, Danke an Patrick Koppen für den Hinweis. 2006-04-18: Version 0.9.16 (maintenance release) fixes: - Die Anzeige in 'Übersicht - Jetzt' war fehlerhaft, wenn Fortschrittsbalken und Kanalnummern im Standard-Menü-Look aktiv waren. Danke an Gerhard Steiner. - Bei Verwendung von kleinen OSD-Fonts hat der Fortschrittsbalken geflimmert, weil er nur 1 Pixel hoch war. Danke an holymoly und TomG@vdrportal. - support für das APIVERSION-Define, das mit vdr-1.3.47 eingeführt wurde. 2006-04-14: Version 0.9.15 neu: - die EPG-Menüs können nun über die Datei epgsearchmenu.conf in Aussehen und Inhalt konfiguriert werden (Beispiel im 'conf'-Unterverzeichnis), z.B. erzeugt der Eintrag: MenuWhatsOnNow=%chnr%:3|%progrt2s%:5| %time% %t_status%:8|%category%:6| %title% ~ %subtitle%:35 im Menü 'Übersicht Jetzt' Einträge die mit der Kanalnummer beginnen, gefolgt von einem Fortschrittsbalken im text2skin-Stil, der Startzeit, dem Timerstatus, der EPG-Kategorie (z.B. 'Spielfilm') sowie schließlich Titel und Untertitel. Jedes Menü ('Übersicht Jetzt', 'Nächste', benutzerdef. Zeiten, 'Programm' und 'Suchergebnisse' kann mit einer eigenen Zeile angepaßt werden. Weitere Infos dazu im MANUAL. - WICHTIGE Änderung bei Suchtimern: epgsearch entfernt nun Timer, die nicht mehr notwendig sind (ab vdr >= 1.3.44). Darunter fallen: * Timers, die aufgrund von EPG-Änderungen nicht mehr gültig sind. Damit sollten die doppelten Aufnahmen vermieden werden, die es bisher evtl. bei einer EPG-Änderung gab * Timers, bei denen die Suchkriterien nicht mehr stimmen, z.B. nach Änderung im Suchtimer. Derartige Timer müssen also nicht mehr manuell gelöscht werden. Ausnahme: Timer, deren Start/Stop-Zeit manuell geändert wurde. Diese werden nicht gelöscht oder verändert. - Neuer Such-Modus 'unscharf': Damit wird eine 'Fuzzy'-Suche durchgeführt, die einen Algorithmus verwendet, wie er auch bei agrep benutzt wird. Die Fehler-Toleranz kann im Feld 'Toleranz' eingestellt werden. - Neue Setup-Option "Timer mit 'Aufnehmen' sofort anlegen", wie in vdr-1.3.38 eingeführt. Bei Drücken von 'Aufnehmen' wird damit sofort ein Timer angelegt. Kleine Abweichung zur VDR-Logik: Wenn die Sendung bereits läuft oder innerhalb der nächsten Vorlauf-Puffer-Minuten +2 beginnt, wird trotzdem das Timer-Edit-Menü angezeigt, damit man noch Änderungen z.B. beim Verzeichnis vornehmen kann, was bei einer lfd. Aufnahme ja nicht mehr geht. Die ganze Logik kann per Setup auch wieder abgeschaltet werden, zumindest mir ist die alte lieber ;-) - Bei Verwendung von epgsearch Timer-Edit-Menü gibts nun auch einen Löschen-Button, um einen Timer ohne Umweg über das Timer-Menü löschen zu können, vorgeschlagen von Rolf Ahrenberg. - Wenn der Hauptmenüeintrag von epgsearch nicht ausgeblendet ist, kann der anzuzeigende Name nun per Setup eingestellt werden. (Anmerkung: ändert man den Eintrag abweichend zur Standard-Vorgabe, ist dieser nicht mehr sprachabhängig) - Der Standard-Menü-Eintrag lautet jetzt nicht mehr 'Suche' sondern 'Programmführer' - einige Leute wollten einen eigenen Hauptmenü-Eintrag für epgsearch's Suchen-Menü. Deshalb gibt's nun ein Mini-Plugin names 'epgsearchonly' das einfach dieses Menü aufruft. Sein Hauptmenu-Eintrag lautet 'Suche'. Übersetzt wird es automatisch mit epgsearch. Man kann das aber auch im Makefile abschalten, indem man #WITHOUT_EPGSEARCHONLY=1 auskommentiert. Zur Verwendung einfach '-P epgsearchonly' ins VDR-Startskript eintragen (ab vdr-1.3.30) - Neues Service-Interface "Epgsearch-searchmenu-v1.0" um epgsearch's Suchmenu aufzurufen (genau das macht epgsearchonly ;-) ) - Neue Aktion 'Erstellte Timer löschen?' um alle Timer eines Suchtimers zu entfernen. Betrifft nicht aufnehmende Timer. - Beim Löschen einer Suche erfolgt nun eine Abfrage, ob alle zugehörigen Timer ebenfalls gelöscht werden sollen. - Wenn die Start/Stop-Zeit eines Timers, der per Suchtimer angelegt wurde, manuell verändert wird, wird dieser Timer von epgsearch nicht mehr angefaßt (ab vdr-1.3.44 ) - Eine Sendung, die gerade aufgenommen wird, hat in den EPG-Menüs nun ein 'R' statt eines 'T'. - Unterstützung des wareagle-icon-patch (kann in der epgsearchmenu.conf mit 'WarEagleIcons=1' aktiviert werden) - Fortschrittsbalken in Jetzt/Nächste 'verschönert' (bei Verwendung der Setup-Option 'graphisch'), angelehnt an Nordlichts-EPG-Plugin - Neue Setup-Option um Radio-Kanäle in den EPG-Menüs zu unterdrücken, vorgeschlagen von Patrice Staudt. - Neues Service-Interface "Epgsearch-searchresults-v1.0", das die Suchergebnisse einer übergebenen Suche zurückliefert, vorgeschlagen von Andreas Brugger - Damit das Setup nicht platzt, wurden einige Optionen entfernt, weil diese mit dem konfigurierbaren Menü nun genauso machbar sind: * "Zeige Fortschrittsbalen in 'Nächste', default ist 'nein' * "Anzeigenbreite für Fortschrittsbalken", default ist 4 * "Zeige kurze Kanalnamen", default ist 'ja' * "Zeige Untertitel in EPG-Menüs', default ist 'ja' - Update der finnischen Übesetzung, Danke an Rolf Ahrenberg - Das Aux-Feld eines Timers wird nun komplett im XML-Stil gefüllt (ab vdr-1.3.44). Deshalb gibt es auch ein Update für die recordingdone.sh im 'scripts'-Unterverzeichnis. Danke an Mike Constabel für den Patch des Skripts. - Das Suchtimer-Update läuft nun immer mit niedriger Priorität, vorgeschlagen von Christian Jacobsen - neues SVDRP-Kommando 'FIND'. Damit kann ein Sendung gesucht werden. Zurückgeliefert wird eine Ergebnisliste bestehend aus 'NEWT'-Zeilen, die somit direkt zum Programmieren des Timers verwendet werden können. Vorgeschlagen ovn Lari Tuononen. fixes: - Danke an Darren Salt für einige Patches im Zusammenhang mit g++ 4.1, Thread safeness und code review - einige Speicherlecks geflickt. - Korrektur für Aufruf von benutzerdef. EPG-Befehlen, Danke an rzndl@vdrportal - Korrektur für blacklist-Suche bei Suchtimern, Danke an Christian Jacobsen - der Episoden-Name eines Timer ist nun max. MAX_SUBTITLE_LENGTH lang, Danke an Mike Constabel - Geschwindigkeit des Suchtimer-Updates etwas verbessert (~15%) 2006-03-05: Version 0.9.14a fixes: - EPG-Befehl 'als bereits aufgezeichnet markieren' hat einen Absturz verursacht, Danke an Mike Constabel für den Hinweis 2006-03-04: Version 0.9.14 neu: - beim Aktivieren/Deaktivieren eines Suchtimers kann man nun angeben, ob die zugehörigen Timer ebenfalls aktiviert/deaktiviert werden sollen. - Neuer EPG-Befehl 'Ausschlussliste anlegen' zum Anlegen einer Ausschlussliste aus einem EPG-Menü. - Die Inhaltsangabe eines Eintrags im Menü 'Erledigte Aufnahmen' hat nun einen zusätzlichen Button 'Zusatzinfo', der den Inhalt des Aux-Feld (in vdr-1.3.44 eingeführt) anzeigt, falls verfügbar. - Update für das Skript recordingdone.sh, funktioniert nun auch mit vdr-1.3.44, Danke an Mike Constabel für die Anpassungen. - Konvertierungsskripts für das Upgrade auf vdr-1.3.44: Aufgrund der geänderten Behandlung der Zusatzinfos in der Inhaltsangabe (summary -> aux) funktionieren einige Suchtimer-Features nicht mit Aufnahmen die vor dem Umstieg auf vdr-1.3.44 gemacht wurden. Das betrifft das done-Feature und das automatische Löschen von Aufnahmen. Wer die Skripts nicht anwendet, hat einfach einige überflüssige Aufnahmen mehr ;-). Muss also nicht unbedingt gemacht werden, aber mit den Skripts läuft alles wie gewohnt. Danke an Mike Constabel, der die Skripts gebaut hat. * neues Skript convert_info_vdr.pl. Dieses konvertiert das Info-File von Aufnahmen und verschiebt die Zusatzinfo von epgsearch in das aux-Feld. * neues Skript convert_epgsearchdone_data.pl. Dieses konvertiert die Datei epgsearchdone.data, indem es einen Aux-Abschnitt hinzufügt. - Update für das Skript mtdone2epgsearchdone.sh, Danke an Christian Jacobsen. - Update der französischen Übersetzung, Danke an Patrice Staudt - Update der finnischen Übersetzung, Danke an Rolf Ahrenberg fixes: - Das done-Feature funktioniert nun auch mit vdr-1.3.44, Danke an Mike Constabel - fix für hohe CPU-Last durch Suchtimer-Thread im 30sek-Abstand, Danke an sledgehammer@vdrportal - Das automatische Verlinken des Tarballs wurde wieder entfernt, gewünscht von Distri-Maintainern - einige Compiler-Warnings gefixed bei Verwendung von -Wformat=2, Danke an Darren Salt für den Hinweis und einen Patch 2006-02-28: Version 0.9.13 neu: - Unterstützung für vdr-1.3.44: funktioniert nun, aber: wegen der Änderung summary -> aux in vdr-1.3.44 sind die Zusatzinfo über den Suchtimer, der den Timer/die Aufnahme erzeugt hat, im Moment nicht mehr verfügbar. Diese werden jetzt im neuen Aux-Feld des Timers/der Aufnahme gespeichert. - Ausschlusslisten: man kann nun eine oder mehrere Ausschlusslisten anlegen und diese innerhalb einer Suche oder eines Suchtimers auswählen. Eine Ausschlussliste arbeitet wie eine normale Suche und legt die Sendungen fest, die in einer Suche oder einem Suchtimer ignoriert werden sollen. Ausschlusslisten können im Setup oder in der neuen Such-Aktion 'Ausschlusslisten anzeigen' sowie direkt beim Editieren einer Suche verwaltet werden. In der Suche selbst können eine, mehrere oder alle Ausschlusslisten ausgewählt werden. Falls ein Suchergebnis auch in einer der gewählten Ausschlusslisten enthalten ist, wird es ignoriert. - Der Hintergrund-Thread für die Umschalttimer läuft jetzt nur noch, wenn auch ein Umschalttimer aktiv ist. - Beim entpacken des tar-Files wird der Link zu epgsearch-x.x.x nun automatisch erzeugt (wie bei text2skin) - Die Ergebnisliste bei "Wiederholungen anzeigen" zeigt nun nicht mehr auch die laufende Sendung an, Vorschlag von Ronny Kornexl - Danke fürs Betatesten an Mike Constabel - Danke fürs Update der finnischen Übersetzung an Rolf Ahrenberg fixes: - die Setup-Option 'Untertitel in manuellen Timern' wurde nicht gespeichert. 2006-02-12: Version 0.9.12 neu: - Neues Feature 'Pause, wenn ... Aufnahmen exist." für Suchtimer. Sobald die angegebene Anzahl (>0) von Aufnahmen existiert, erzeugt epgsearch keine weiteren Timer mehr für diesen Suchtimer. Erst wenn eine oder mehrere Auf- nahmen gelöscht wurden, werden erneut Timer angelegt. fixes: - Absturz beim Navigieren zu einem Kanal ohne EPG im Programme-Menü behoben 2006-02-08: Version 0.9.11a fixes: - hohe CPU-Last im 5 Sekunden-Takt beseitigt 2006-02-07: Version 0.9.11 neu: - Unterstützung von vdr-1.3.42 - Neues Feature 'Umschalttimer': mit dem neuen EPG-Befehl 'In/Aus Umschalt- liste' kann eine Sendung in eine Umschaltliste aufgenommen werden. VDR schaltet dann kurz (einstellbar) vor Beginn zu dieser Sendung um. Der Inhalt der Umschaltliste kann über 'Suche/Aktionen/Umschaltliste anzeigen' kontrolliert und geändert werden. Falls eine Sendung in der Umschaltliste ist, wird Sie in den Menüs mit einem 'S' markiert (falls kein echter Timer dafür existiert). - Umschalttimer auch für Suchtimer: Ein Suchtimer kann ebenfalls als Umschalt- timer verwendet werden (Aktion: nur umschalten). Sobald Suchergenisse vorliegen werden diese in die Umschaltliste aufgenommen. Es wird kein echter Timer erzeugt. - Suchkriterium 'Verwende Kanal' hat nun einen weiteren Wert 'nur FTA', um die Suche auf alle nicht verschlüsselten Programme einzuschränken. - Neue Setup-Option 'Zeige Tagesseparatoren', zur Anzeige von Trennlinien zwischen den Tagen im Menu Programm - epgsearch hat jetzt ein SVDRP-Interface mit folgenden Befehlen (ab vdr > 1.3.30): * 'LSTS [ID]' zeigt alle Suchen an, oder nur diejenige mit der angegebenen ID (Format ist dasgleiche wie in epgsearch.conf, s. MANUAL) * 'NEWS ' zum Anlegen einer neuen Suche Anmerkung: der Wert ID wird ignoriert und von epgsearch automatisch vergeben. * 'DELS ' zum Löschen einer Suche mit der angegebenen ID * 'EDIS ' zum Ändern einer Suche * 'UPDS [OSD]' zum Starten eines Suchtimer-Updates. Wird der optionale Parameter 'OSD' angegeben, informiert das OSD, wann das Update beendet ist. * 'UPDD' zum Nachladen der epgsearchdone.data in den Speicher, z.B. nach einer Änderung durch ein externes Tool * 'SETS ' zum Ein-/Ausschalten der Suchtimersuche im Hintergrund - weil das Setup allmählich zu groß wird, gibt es dort jetzt die Modi "Standard" und "Erweitert" (umschaltbar über Taste rot), vorgeschlagen von Rolf Ahrenberg - Update der finnischen Übersetzung, Danke an Rolf Ahrenberg - Update der italienischen Übersetzung, Danke an Reelbox User - Update der französischen Übersetzung, Danke an Patrice Staudt - Neue holländische Übersetzung, Danke an Reelbox User - Verwendung von '127.0.0.1' anstatt der Auflösung von 'localhost' für SVDRP, vorgeschlagen von Thiemo Gehrke - neues Skript recordingdone.sh für die reccmds.conf, um eine Aufnahme als erlegigt zu kennzeichnen (für epgsearch's done-Feature), Danke an Patrice Staudt, Christian Jacobsen und Mike Constabel - neues Skript mtdone2epgsearchdone.sh zur Übernahme von erledigten Aufnahmen von mastertimer in epgsearch's done-Datei, Danke an Christian Jacobsen. - Danke an Mike Constabel und Andreas Brugger fürs Testen und die Bug Reports fixes: - Fehler bei der Verwendung von Vorlagen behoben, Danke an Christian Jacobsen 2006-01-15: Version 0.9.10 neu: - Aktualisierung aller Programm- und Suchergebnismenüs nach dem Anlegen oder Ändern eines Timers, wie in vdr-1.3.38 eingeführt - Die Taste 'Aufnehmen' wird jetzt mit 'Aufnehmen' oder 'Timer' beschriftet, abhängig davon, ob für die Sendung ein Timer existiert, wie in vdr-1.3.38 eingeführt - Im Timer-Edit-Menu von epgsearch (Setup-Einstellung beachten!) wird nun bei einer laufenden Aufnahme angezeigt, über welche Karte der Timer aufnimmt - Neue Setup-Option: 'Untertitel in manuellen Timern' Betrifft das autom. Ergänzen des Untertitels bei einem manuell angelegten Timer. Die Einstellung 'intelligent' verwirft den Untertitel, falls die Sendung länger als 80min ist. Ist noch nicht sooo intelligent ;-) - Das Menü zum Editieren der Suche wurde für zukünftige Erweiterungen geändert: 'Aktion' bestimmt nun, was mit den Suchergebnissen gemacht werden soll, im Moment gibts 'Aufnehmen' als Standard und 'Nur Ankündigen' - Danke an Rolf Ahrenberg für das Update der finnischen Übersetzung fixes: - in vdr-1.3.38 waren einige Übersetzungen defekt - timercmds-patches für vdr-1.3.38 aktualisiert 2006-01-08: Version 0.9.9 neu: - Unterstützung für vdr-1.3.38 - Suchvorlagen: da die Einstellungen zu einer Suche oft die gleichen sind, gibt es nun Vorlagen, die beim Anlegen/Ändern einer Suche mit der Taste 'Blau' verwendet werden können. Eine Vorlage kann auch als "Standard" definiert werden, wodurch deren Einträge beim Anlegen einer Suche auto- matisch übernommen werden. - Setup um 'Suchvorlagen' erweitert (zur Verwaltung der Vorlagen) - Neue Aktion 'Als Vorlage verwenden', um eine Suche in die Vorlagen zu kopieren - Neue Setup-Option, um die Anzeige der Untertitel in der Übersicht zu steuern, danke an Darren Salt für den Patch - Erweiterung des Features 'Aufnahmen nach ... Tagen löschen' um 'Erhalte ... Aufnahmen'. Dadurch werden die letzten x Aufnahmen immer erhalten, auch wenn diese bereits das Zeitlimit überschritten haben. fixes: - Das Feature 'Aufnahmen nach ... Tagen löschen' hat auch editierte/ge- schnittene Aufnahmen gelöscht. Behoben. 2005-11-27: Version 0.9.8 neu: ACHTUNG!: diese Version konvertiert die epgsearch.conf (die Datei, in der die Sucheinträge gespeichert werden) in ein NEUES FORMAT. Es wird ein Backup der alten Datei unter epgsearch.conf.bak angelegt.Geht man also auf eine alte Version zurück, muss das Backup nach epgsearch.conf zurückkopiert werden. - Neues Feature 'Wiederholungen vermeiden' (aka done-Feature) für Suchtimer (bitte die README.DE vor dem ersten Gebrauch lesen!). Ein besonderer Dank an Mike Constable (vejoun@vdrportal) für viele viele Test-Stunden und Bug- Reports. * Vorschau von geplanten Timern * Erkennung unvollständiger Aufnahmen * Fuzzy-Vergleich von Sendungen - Das Menü der Suchergebnisse hat bei Suchtimern mit 'Wiederh. vermeiden' nun eine zusätzliche Belegung für die Taste 'Blau', um sich die geplanten Timer anzeigen zu lassen, die mit dem nächsten Suchtimer-Update programmiert werden. - Neue Setup-Option zur Anzeige von Sendern ohne EPG in 'Was läuft jetzt?', Idee von 'Nordlicht's EPG plugin' übernommen - Neue Setup-Option 'Zeige Kanal-Separatoren' in 'Was läuft jetzt?' Idee von 'Nordlicht's EPG plugin' übernommen - Neues Suchtimer-Feature 'Lösche Aufnahmen nach ... Tagen'. Damit werden Auf- nahmen nach den eingestellen Tagen automatisch gelöscht. Praktisch z.B. für Nachrichtensendungen wie Tagesschau, die nur für einige Tage interessieren. - Die Inhaltsangabe von Timern (über ok im Timermenu), die epgsearch erzeugt hat, enthalten nun zusätzliche Infos: Titel und Untertitel (falls vorhanden) am Anfang, sowie Name und ID des Suchtimers und den Sender am Ende - Die Inhaltsangabe von manuell programmierten Timern enthält nun: Titel und Untertitel (falls vorhanden) am Anfang, sowie Sender am Ende - 'Ausführen' im Suchmenu wurde ersetzt durch 'Aktionen' und listet: * Suche ausführen (wie zuvor auch mit ok) * 'Als Suchtimer verwenden' an/aus * Suchtimer-Update ausführen * Erledigte Aufnahmen anzeigen Es können natürlich genauso die Tasten als Abkürzung verwendet werden, ohne das Menu aufzurufen. '0' ruft das Menü auf. - Einführung eines Logfiles (Standard ist plugin-configdir/epgsearch.log, kann aber über den Startparameter '-l /path/to/logfile' geändert werden. Der Para- meter '-v n' bestimmt das Log-Level. n=0 bedeutet kein Logging (default), 1 (eingeschränktes Logging),2(detailliert),3(umfangreich). - Im Setup gibts nun ein Standard-Aufnahmeverzeichnis, das beim manuellen Pro- grammieren von Timern vorgegeben wird. Unterstützt werden auch Einträge der Form '%Category%~%Genre%'. - abhängig vom aufrufenden Menu sind nun die Tasten 'Grün/Geld' im Event-Menu (also der Inhaltsangabe) nun mit dem vorh./nächsten Sender bzw. der vorh./ nächsten Startzeit beschriftet, danke an Andreas Brugger (brougs78@vdrportal) - Sendernummern werden nun auch im Menü Suchergebnisse gelistet, falls die Option im Setup geschaltet ist, danke an Gerhard Steiner (gestein@vdrportal). - Kurztasten (1,2,...) für EPG-Befehle sind nun auch im Menu der Inhaltsangabe verfügbar, danke an Frank Krömmelbein (frank99@vdrportal) - Ab VDR version >= 1.3.31 kann im Setup nun eingestellt werden, ob man für die manuelle Timerprogrammierung das Timer-Editmenü von epgsearch oder von VDR ver- wenden will.(evtl. sinnvoll, wenn man einen gepatchten VDR benutzt). Danke an Frank Krömmelbein (frank99@vdrportal) - Falls ein Untertitel existiert wird er beim manuellen Timer-Programmieren nun automatisch ans Verzeichnis angehängt. Danke an Gerhard Steiner (gestein@vdrportal) - Aufteilung von Verzeichnis und File beim erneuten Bearbeiten von Timern opti- miert, Danke Andreas Brugger (brougs78@vdrportal) - In den Hauptmenus werden Untertitel nun immer angezeigt, in der Form 'Titel ~ Untertitel', falls vorhanden - Neue service-Funktion 'Epgsearch-updatesearchtimers-v1.0' zum Aufruf eines Suchtimer-Updates - Falls ein Suchtimer-Update über das Aktionenmenu aufgerufen wird, gibt es nun im OSD eine Nachricht, sobald das Update fertig ist. (Ebenso bei Verwendung von des Services 'Epgsearch-updatesearchtimers-v1.0' - Das Such-Menü zeigt nun die Anzahl der (aktiven) Suchen im Titel an - Danke an Rolf Ahrenberg für die Aktualisierung der finnischen Übersetzung. - Danke an Mike Constabel für die Überarbeitung der READMEs und des MANUALs. fixes: - epgsearch springt nun zum Hauptmenu zurück, falls es nicht über eine Kurztaste aufgerufen wurde. Danke an Andreas Brugger (brougs78@vdrportal) - Eingabe von Suchbegriffen bei englischem OSD korrigiert - Sortierung von Suchtimern nach dem Editieren einer Suche korrigiert, Danke an Mike Constabel (vejoun@vdrportal) - Menü-Navigation bei leerem EPG korrigiert, Danke an Darren Salt für den Patch - Falsche optische Ausrichtung von Sucheinträgen im Suchmenü korrigiert, Danke an Andreas Brugger (brougs78@vdrportal) 2005-09-04: Version 0.9.7 neu: - Änderungen in der Beschreibung einer Sendung bewirken jetzt auch ein Update eines Timers fixes: - bei der Verwendung von reg. Ausdrücken in Suchtimern gab es ein böses Speicherleck, Danke an TomG@vdrportal - Kanalanzeige in den Farbtasten funktionierte nicht wenn es Kanaltrenner gab. Danke an viking@vdrportal 2005-08-27: Version 0.9.6 neu: - Suchkriterium 'Verw. Kanal' um 'Kanalgruppen' erweitert. Diese Kanalgruppen können über ein eigenes Menu verwaltet werden (im Suchtimer oder im Setup) und erlauben eine flexiblere Kanalauswahl für Suchtimer als bisher. (s. Screenshot) - epgsearch stellt das erweiterte Timer-Editmenu und die Suche im EPG jetzt als 'Service' anderen Plugins zur Verfügung (ab 1.3.30 oder mit Udo Richters backport, s. MANUAL oder mail an mich, falls jemand Interesse hat) - Beim Programmieren eines Timers (manuell oder per Suchtimer) wird nun die Inhaltsangabe an den Timer übergeben (damit kann im VDR-Timermenu mit 'ok' die Inhaltsangabe angezeigt werden), Danke an TomG - Nach dem Umschalten der Farbtasten mit '0' im Menu 'Programm' kann mit den Farbtasten Grün/Gelb zum Programm des vorherigen/nächsten Senders gewechselt werden (s. Farbtasten im Screenshot) - patch von Uwe/egal hinzugefügt, der es erlaubt, das VDR-Programmmenu durch epgsearch zu ersetzen. Danke an Uwe auch für die Anpassungen in epgsearch (Nach dem Patchen von VDR muss der patch noch im epgsearch-Setup aktiviert werden!) - Nach dem Anlegen einer neuen Suche wird diese jetzt im Suchmenu korrekt einsortiert, Danke an Mike Constabel - Gerhard Steiner's timercmd patch für vdr >= 1.3.25 hinzugefügt - ein 'back' im Anfangsmenu schließt nun immer das OSD (sollte Probleme mit dem submenu-Patch lösen) - Events ohne Titel (ja, sowas gibts) werden in der Suche nun immer ignoriert, Danke an Mike Constabel - neue EPG-Variable '%channel%', die im Verzeichnis-Eintrag verwendet werden kann und durch den Sendernamen ersetzt wird - Anfangs- und Endpuffer einer Aufnhame dürfen jetzt auch negativ sein (das erlaubt ein absichtliches Abschneiden einer Sendung am Anfang oder Ende), Danke an Mike Constabel - Groß-/Kleinschreibung wird nun in erweiterten EPG-Kategorien ignoriert - Finnische Übersetzung aktualisiert, Danke an Rolf Ahrenberg fixes: - Beim Laden von '.epgsearchrc' wird jetzt auch ein evtl. angegebener Config-Pfad (-c) berücksichtigt, Danke an Ronny Kornexl - Programmierung von Suchtimern mit leerem Verzeichnis oder Namen korrigiert, Danke an Andreas Brugger - Programmierung von Suchtimern korrigiert, bei denen Mitternacht zwischen Start und Ende liegt - Menu Verzeichnisauswahl machte Probleme, wenn keine Verzeichnisse existierten, Danke an harvey@vdrportal - (De)Aktivieren von Suchtimern mit '0' speichert nun sofort, Danke an Mike Constabel - Menu Navigation (Grüm-Gelb-Gelb-Grün) zeigt nun korrekterweise 'Was läuft jetzt' und nicht mehr Inhaltsangabe, Danke an Mike Constabel vdr-plugin-epgsearch-2.4.1/INSTALL000066400000000000000000000027341405273211300166010ustar00rootroot00000000000000Theres nothing special about it. Install it like any other standard plugin (unpack, soft link, make plugins). Optional libraries: ------------------- libpcre ------- For support of Perl compatible regular expressions in a search you have to use libpcre: simply edit the plugins Makefile and uncomment '#REGEXLIB = pcre' to 'REGEXLIB = pcre' or append 'REGEXLIB=pcre' to your 'make plugins' call. (you will need pcreposix installed, comes with libpcre from www.pcre.org, but it's already part of most distributions HINT: if all compiles well, but after starting VDR you get: ERROR: /usr/lib/libpcreposix.so.0: undefined symbol: pcre_free). update libpcre from www.pcre.org and recompile the plugin. There seems to be a problem with PCRE on some systems, that produce a crash when using regexp. Til now, I could not find the reason. So perhaps dont use REGEXLIB=pcre, if you don't really need it. libtre ------ epgsearch has a fuzzy search algorithm. Unfortunately it's restricted to search patterns with a maximum of 31 characters. This results in empty results if more than 31 characters are used. To avoid this limitation you can use the TRE package (http://laurikari.net/tre/). Install tre (on debian: apt-get install tre-agrep libtre4 libtre-dev) and activate epgsearch's support for it in the Makefile by uncommenting '#REGEXLIB = pcre' to 'REGEXLIB = tre' or append it to your 'make plugins' call. After recompiling epgsearch will now use an algorithm similar to 'agrep' with no limits. vdr-plugin-epgsearch-2.4.1/INSTALL.DE000066400000000000000000000020061405273211300170600ustar00rootroot00000000000000Hier gibt es nichts besonderes. Bitte wie jedes andere Standard-Plugin installieren (entpacken, soft link, make plugins). Eine kleine Besonderheit: Wer lieber mit Perl compatible regular expressions in der Suche arbeitet, sollte einfach im Makefile des Plugins '#REGEXLIB = pcre' in 'REGEXLIB = pcre' ändern oder einfach REGEXLIB=pcre an den 'make plugins'-Aufruf anhängen. Hierzu muss pcreposix installiert sein, das in der libpcre von www.pcre.org enthalten ist. Dies sollte aber in den meisten Distributionen bereits enthalten sein. HINWEIS: wenn alles normal kompiliert, aber beim Start von VDR folgendes kommt: ERROR: /usr/lib/libpcreposix.so.0: undefined symbol: pcre_free). dann bitte libpcre von www.pcre.org updaten und das Plugin neu kompilieren. Scheinbar gibt es auf manchen Systemen Probleme mit PCRE, die sich in einem Crash äußern, wenn man reg. Ausdrücke benutzt. Da ich die Ursache bisher nicht finden konnte, empfehle ich deshalb auf REGEXLIB=pcre zu verzichten, wenn es nicht unbedingt notwendig ist. vdr-plugin-epgsearch-2.4.1/Makefile000066400000000000000000000256141405273211300172120ustar00rootroot00000000000000# # Makefile for epgsearch, a Video Disk Recorder plugin # # Christian Wieninger cwieninger at gmx.de # # Adapted to the new VDR makefile environment by Copperhead, # refined by Stefan Hofmann # ### ------------ ### CONFIG START ### ### to change an option just edit the value: 0 => false, 1 => true ### edit one of these lines to '1', if you don't want the addon epgsearchonly, ### conflictcheckonly or quickepgsearch WITHOUT_EPGSEARCHONLY=0 WITHOUT_CONFLICTCHECKONLY=0 WITHOUT_QUICKSEARCH=0 ### edit this to '0' if you don't want epgsearch to auto config itself AUTOCONFIG=1 ### if AUTOCONFIG is not active you can manually enable the ### optional modules or patches for other plugins ifeq ($(AUTOCONFIG),0) # if you want to use Perl compatible regular expressions (PCRE) or libtre for # unlimited fuzzy searching, uncomment this and set the value to pcre or tre # also have a look at INSTALL for further notes on this #REGEXLIB = pcre # uncomment this to enable support for the pin plugin. #USE_PINPLUGIN = 1 # uncomment this to enable support for the graphtft plugin. #USE_GRAPHTFT = 1 endif ### the sendmail executable to use when epgsearch is configured to use the ### sendmail method for sending mail SENDMAIL = /usr/sbin/sendmail ### ### CONFIG END ### do not edit below this line if you don't know what you do ;-) ### ------------------------------------------------------------- PLUGIN = epgsearch MAINMENUSHORTCUT = epgsearchmainmenushortcut PLUGIN2 = epgsearchonly PLUGIN3 = conflictcheckonly PLUGIN4 = quickepgsearch ### The version number of this plugin (taken from the main source file): VERSION = $(shell grep 'static const char VERSION\[\] *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g') ### The directory environment: # Use package data if installed...otherwise assume we're under the VDR source directory: PKG_CONFIG ?= pkg-config #PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell $(PKG_CONFIG) --variable=$(1) vdr || $(PKG_CONFIG) --variable=$(1) ../../../vdr.pc)) PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=$(1) vdr)) LIBDIR = $(call PKGCFG,libdir) LOCDIR = $(call PKGCFG,locdir) MANDIR = $(call PKGCFG,mandir) CONFDIR = $(call PKGCFG,configdir) BINDIR = $(call PKGCFG,bindir) # TMPDIR ?= /tmp PLGCFG = $(call PKGCFG,plgcfg) -include $(PLGCFG) ### The compiler options: export CFLAGS = $(call PKGCFG,cflags) export CXXFLAGS = $(call PKGCFG,cxxflags) ### configuring modules ifeq ($(AUTOCONFIG),1) ifeq (exists, $(shell $(PKG_CONFIG) libpcre && echo exists)) REGEXLIB = pcre else ifeq (exists, $(shell $(PKG_CONFIG) tre && echo exists)) REGEXLIB = tre endif ifeq (exists, $(shell test -e ../pin && echo exists)) USE_PINPLUGIN = 1 endif ifeq (exists, $(shell test -e ../graphtft && echo exists)) USE_GRAPHTFT = 1 endif ifeq (exists, $(shell test -e ../graphtftng && echo exists)) USE_GRAPHTFT = 1 endif endif ### The version number of VDR's plugin API: APIVERSION = $(call PKGCFG,apiversion) ### The name of the distribution archive: ARCHIVE = $(PLUGIN)-$(VERSION) PACKAGE = vdr-$(ARCHIVE) ### Includes and Defines (add further entries here): INCLUDES += DEFINES += ifneq ($(SENDMAIL),) DEFINES += -DSENDMAIL='"$(SENDMAIL)"' endif ### The object files (add further files here): ALL = libvdr-$(PLUGIN).so createcats ifeq ($(WITHOUT_EPGSEARCHONLY), 0) ALL += libvdr-$(PLUGIN2).so endif ifeq ($(WITHOUT_CONFLICTCHECKONLY), 0) ALL += libvdr-$(PLUGIN3).so endif ifeq ($(WITHOUT_QUICKSEARCH), 0) ALL += libvdr-$(PLUGIN4).so endif OBJS = afuzzy.o blacklist.o changrp.o confdloader.o conflictcheck.o conflictcheck_thread.o distance.o $(PLUGIN).o epgsearchcats.o epgsearchcfg.o epgsearchext.o epgsearchsetup.o epgsearchsvdrp.o epgsearchtools.o mail.o md5.o menu_announcelist.o menu_blacklistedit.o menu_blacklists.o menu_commands.o menu_conflictcheck.o menu_deftimercheckmethod.o menu_dirselect.o menu_event.o menu_favorites.o menu_main.o menu_myedittimer.o menu_quicksearch.o menu_recsdone.o menu_search.o menu_searchactions.o menu_searchedit.o menu_searchresults.o menu_searchtemplate.o menu_switchtimers.o menu_templateedit.o menu_timersdone.o menu_whatson.o noannounce.o pending_notifications.o rcfile.o recdone.o recdone_thread.o recstatus.o searchtimer_thread.o services.o switchtimer.o switchtimer_thread.o templatefile.o timer_thread.o timerdone.o timerstatus.o uservars.o varparser.o ifeq ($(REGEXLIB), pcre) LIBS += $(shell pcre-config --libs-posix) #LIBS += -L/usr/lib -lpcreposix -lpcre INCLUDE += $(shell pcre-config --cflags) DEFINES += -DHAVE_PCREPOSIX else ifeq ($(REGEXLIB), tre) LIBS += -L$(shell $(PKG_CONFIG) --variable=libdir tre) $(shell $(PKG_CONFIG) --libs tre) #LIBS += -L/usr/lib -ltre DEFINES += -DHAVE_LIBTRE INCLUDE += $(shell $(PKG_CONFIG) --cflags tre) endif ifdef USE_PINPLUGIN DEFINES += -DUSE_PINPLUGIN endif ifdef USE_GRAPHTFT DEFINES += -DUSE_GRAPHTFT endif ifdef CFLC DEFINES += -DCFLC endif ifdef DEBUG_CONFL DEFINES += -DDEBUG_CONFL endif ifdef PLUGIN_EPGSEARCH_MAX_SUBTITLE_LENGTH DEFINES += -DMAX_SUBTITLE_LENGTH='$(PLUGIN_EPGSEARCH_MAX_SUBTITLE_LENGTH)' endif ### length of the filling '-' in the channel separators, defaults to ### "----------------------------------------" ### overwrite this with PLUGIN_EPGSEARCH_SEP_ITEMS=--- ### to avoid problems with graphlcd ifdef PLUGIN_EPGSEARCH_SEP_ITEMS DEFINES += -DMENU_SEPARATOR_ITEMS='"$(PLUGIN_EPGSEARCH_SEP_ITEMS)"' endif OBJS2 = mainmenushortcut.o epgsearchonly.o LIBS2 = OBJS3 = mainmenushortcut.o conflictcheckonly.o LIBS3 = OBJS4 = mainmenushortcut.o quickepgsearch.o LIBS4 = ### The main target: all: $(ALL) i18n docs ### Implicit rules: %.o: %.c @echo CC $@ $(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) -DPLUGIN_NAME_I18N='"$(PLUGIN)"' $(INCLUDES) -o $@ $< mainmenushortcut.o: mainmenushortcut.c @echo CC $@ $(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) -DPLUGIN_NAME_I18N='"$(MAINMENUSHORTCUT)"' $(INCLUDES) -o $@ $< epgsearchonly.o: epgsearchonly.c @echo CC $@ $(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) -DPLUGIN_NAME_I18N='"$(PLUGIN2)"' $(INCLUDES) -o $@ $< conflictcheckonly.o: conflictcheckonly.c @echo CC $@ $(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) -DPLUGIN_NAME_I18N='"$(PLUGIN3)"' $(INCLUDES) -o $@ $< quickepgsearch.o: quickepgsearch.c @echo CC $@ $(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) -DPLUGIN_NAME_I18N='"$(PLUGIN4)"' $(INCLUDES) -o $@ $< # Dependencies: MAKEDEP = $(CXX) -MM -MG DEPFILE = .dependencies $(DEPFILE): Makefile @$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) $(OBJS2:%.o=%.c) $(OBJS3:%.o=%.c) $(OBJS4:%.o=%.c)> $@ ifneq ($(MAKECMDGOALS),clean) -include $(DEPFILE) endif DEPFILE_DOC = .dependencies_doc DEPFILE_stmp = .doc_stmp $(DEPFILE_DOC): Makefile @rm -f $(DEPFILE_DOC) @./docsrc2man.sh --depend $(DEPFILE_stmp) > $(DEPFILE_DOC) ifneq ($(MAKECMDGOALS),clean) -include $(DEPFILE_DOC) endif ### Internationalization (I18N): PODIR = po I18Npo = $(wildcard $(PODIR)/*.po) I18Nmo = $(addsuffix .mo, $(foreach file, $(I18Npo), $(basename $(file)))) I18Nmsgs = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file)))))) I18Npot = $(PODIR)/$(PLUGIN).pot %.mo: %.po @echo MO $@ $(Q)msgfmt -c -o $@ $< $(I18Npot): $(wildcard *.c) @echo GT$@ $(Q)xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='' -o $@ `ls $^` %.po: $(I18Npot) @echo PO $@ $(Q)msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $< @touch $@ $(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo @echo IN $@ $(Q)install -D -m644 $< $@ .PHONY: i18n i18n: $(I18Nmo) $(I18Npot) install-i18n: $(I18Nmsgs) ### Targets: libvdr-$(PLUGIN).so: $(OBJS) @echo LD $@ $(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@ libvdr-$(PLUGIN2).so: $(OBJS2) @echo LD $@ $(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS2) $(LIBS2) -o $@ libvdr-$(PLUGIN3).so: $(OBJS3) @echo LD $@ $(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS3) $(LIBS3) -o $@ libvdr-$(PLUGIN4).so: $(OBJS4) @echo LD $@ $(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS4) $(LIBS4) -o $@ createcats: createcats.o Makefile @echo LD $@ $(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) createcats.o -o $@ $(DEPFILE_stmp): ./docsrc2man.sh ./docsrc2html.sh ln -sf ./doc/en/epgsearch.4.txt MANUAL ln -sf ./doc/en/epgsearch.1.txt README ln -sf ./doc/de/epgsearch.1.txt README.DE @rm -f $(DEPFILE_stmp) @date > $(DEPFILE_stmp) docs: $(DEPFILE_stmp) install-$(PLUGIN): libvdr-$(PLUGIN).so @echo IN $@ $(Q)install -D libvdr-$(PLUGIN).so $(DESTDIR)$(LIBDIR)/libvdr-$(PLUGIN).so.$(APIVERSION) install-$(PLUGIN2): libvdr-$(PLUGIN2).so @echo IN $@ $(Q)install -D libvdr-$(PLUGIN2).so $(DESTDIR)$(LIBDIR)/libvdr-$(PLUGIN2).so.$(APIVERSION) install-$(PLUGIN3): libvdr-$(PLUGIN3).so @echo IN $@ $(Q)install -D libvdr-$(PLUGIN3).so $(DESTDIR)$(LIBDIR)/libvdr-$(PLUGIN3).so.$(APIVERSION) install-$(PLUGIN4): libvdr-$(PLUGIN4).so @echo IN $@ $(Q)install -D libvdr-$(PLUGIN4).so $(DESTDIR)$(LIBDIR)/libvdr-$(PLUGIN4).so.$(APIVERSION) install-conf: mkdir -p $(DESTDIR)$(CONFDIR)/plugins/$(PLUGIN)/conf.d cp -n conf/* $(DESTDIR)$(CONFDIR)/plugins/$(PLUGIN) install-doc: mkdir -p $(DESTDIR)$(MANDIR)/man1 mkdir -p $(DESTDIR)$(MANDIR)/man4 mkdir -p $(DESTDIR)$(MANDIR)/man5 mkdir -p $(DESTDIR)$(MANDIR)/de/man1 mkdir -p $(DESTDIR)$(MANDIR)/de/man5 cp man/en/*1.gz $(DESTDIR)$(MANDIR)/man1/ cp man/en/*4.gz $(DESTDIR)$(MANDIR)/man4/ cp man/en/*5.gz $(DESTDIR)$(MANDIR)/man5/ cp man/de/*1.gz $(DESTDIR)$(MANDIR)/de/man1/ cp man/de/*5.gz $(DESTDIR)$(MANDIR)/de/man5/ install-bin: createcats mkdir -p $(DESTDIR)$(BINDIR) cp createcats $(DESTDIR)$(BINDIR) install: install-lib install-i18n install-conf install-doc install-bin install-lib: install-$(PLUGIN) install-$(PLUGIN2) install-$(PLUGIN3) install-$(PLUGIN4) dist: docs clean @-rm -rf $(TMPDIR)/$(ARCHIVE) @mkdir $(TMPDIR)/$(ARCHIVE) @cp -a * $(TMPDIR)/$(ARCHIVE) @-rm -rf $(TMPDIR)/$(ARCHIVE)/doc-src @-rm -rf $(TMPDIR)/$(ARCHIVE)/html @-rm -rf $(TMPDIR)/$(ARCHIVE)/docsrc2man.sh @-rm -rf $(TMPDIR)/$(ARCHIVE)/docsrc2html.sh @tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE) @-rm -rf $(TMPDIR)/$(ARCHIVE) @ln -sf README.git README @echo Distribution package created as $(PACKAGE).tgz distfull: docs clean @-rm -rf $(TMPDIR)/$(ARCHIVE) @mkdir $(TMPDIR)/$(ARCHIVE) @cp -a * $(TMPDIR)/$(ARCHIVE) @tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE) @-rm -rf $(TMPDIR)/$(ARCHIVE) @ln -sf README.git README @echo complete distribution package created as $(PACKAGE).tgz clean: @-rm -f $(PODIR)/*.mo $(PODIR)/*.pot @-rm -f $(OBJS) $(OBJS2) $(OBJS3) $(OBJS4) $(DEPFILE) *.so *.tgz core* createcats createcats.o pod2*.tmp @-find . \( -name "*~" -o -name "#*#" \) -print0 | xargs -0r rm -f @-rm -rf doc html man @-rm -f MANUAL README README.DE @-rm -f $(DEPFILE_stmp) $(DEPFILE_DOC) vdr-plugin-epgsearch-2.4.1/Makefile.before.1.7.36000066400000000000000000000221311405273211300211750ustar00rootroot00000000000000# # Makefile for epgsearch, a Video Disk Recorder plugin # # Christian Wieninger cwieninger at gmx.de # ### ------------ ### CONFIG START ### ### to change an option just edit the value: 0 => false, 1 => true ### edit one of these lines to '1', if you don't want the addon epgsearchonly, ### conflictcheckonly or quickepgsearch WITHOUT_EPGSEARCHONLY=0 WITHOUT_CONFLICTCHECKONLY=0 WITHOUT_QUICKSEARCH=0 ### edit this to '0' if you don't want epgsearch to auto config itself AUTOCONFIG=1 ### if AUTOCONFIG is not active you can manually enable the ### optional modules or patches for other plugins ifeq ($(AUTOCONFIG),0) # if you want to use Perl compatible regular expressions (PCRE) or libtre for # unlimited fuzzy searching, uncomment this and set the value to pcre or tre # also have a look at INSTALL for further notes on this #REGEXLIB = pcre # uncomment this to enable support for the pin plugin. #USE_PINPLUGIN = 1 # uncomment this to enable support for the graphtft plugin. #USE_GRAPHTFT = 1 endif ### the sendmail executable to use when epgsearch is configured to use the ### sendmail method for sending mail SENDMAIL = /usr/sbin/sendmail ### ### CONFIG END ### do not edit below this line if you don't know what you do ;-) ### ------------------------------------------------------------- PLUGIN = epgsearch MAINMENUSHORTCUT = epgsearchmainmenushortcut PLUGIN2 = epgsearchonly PLUGIN3 = conflictcheckonly PLUGIN4 = quickepgsearch ### The version number of this plugin (taken from the main source file): VERSION = $(shell grep 'static const char VERSION\[\] *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g') ### The C++ compiler and options: CXX ?= g++ CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses -Wno-format-y2k ### The directory environment: #DVBDIR = ../../../../DVB VDRDIR = ../../.. LIBDIR = ../../lib TMPDIR = /tmp ### auto configuring modules ifeq ($(AUTOCONFIG),1) ifeq (exists, $(shell pkg-config libpcre && echo exists)) REGEXLIB = pcre else ifeq (exists, $(shell pkg-config tre && echo exists)) REGEXLIB = tre endif ifeq (exists, $(shell test -e ../pin && echo exists)) USE_PINPLUGIN = 1 endif ifeq (exists, $(shell test -e ../graphtft && echo exists)) USE_GRAPHTFT = 1 endif endif ### Make sure that necessary options are included: -include $(VDRDIR)/Make.global ### Allow user defined options to overwrite defaults: -include $(VDRDIR)/Make.config ALL = libvdr-$(PLUGIN).so createcats ifeq ($(WITHOUT_EPGSEARCHONLY), 0) ALL += libvdr-$(PLUGIN2).so endif ifeq ($(WITHOUT_CONFLICTCHECKONLY), 0) ALL += libvdr-$(PLUGIN3).so endif ifeq ($(WITHOUT_QUICKSEARCH), 0) ALL += libvdr-$(PLUGIN4).so endif ### The version number of VDR (taken from VDR's "config.h"): VDRVERSION = $(shell grep 'define VDRVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g') APIVERSION = $(shell grep 'define APIVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g') ifeq ($(strip $(APIVERSION)),) APIVERSION = $(VDRVERSION) endif ### The name of the distribution archive: ARCHIVE = $(PLUGIN)-$(VERSION) PACKAGE = vdr-$(ARCHIVE) ### Includes and Defines (add further entries here): INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include #INCLUDES += -I$(VDRDIR)/include EPGSEARCH_DEFINES += -D_GNU_SOURCE ifneq ($(SENDMAIL),) EPGSEARCH_DEFINES += -DSENDMAIL='"$(SENDMAIL)"' endif DEFINES += $(EPGSEARCH_DEFINES) ### The object files (add further files here): OBJS = afuzzy.o blacklist.o changrp.o confdloader.o conflictcheck.o conflictcheck_thread.o distance.o $(PLUGIN).o epgsearchcats.o epgsearchcfg.o epgsearchext.o epgsearchsetup.o epgsearchsvdrp.o epgsearchtools.o mail.o md5.o menu_announcelist.o menu_blacklistedit.o menu_blacklists.o menu_commands.o menu_conflictcheck.o menu_deftimercheckmethod.o menu_dirselect.o menu_event.o menu_favorites.o menu_main.o menu_myedittimer.o menu_quicksearch.o menu_recsdone.o menu_search.o menu_searchactions.o menu_searchedit.o menu_searchresults.o menu_searchtemplate.o menu_switchtimers.o menu_templateedit.o menu_timersdone.o menu_whatson.o noannounce.o pending_notifications.o rcfile.o recdone.o recstatus.o searchtimer_thread.o services.o switchtimer.o switchtimer_thread.o templatefile.o timer_thread.o timerdone.o timerstatus.o uservars.o varparser.o ifeq ($(REGEXLIB), pcre) LIBS += $(shell pcre-config --libs-posix) #LIBS += -L/usr/lib -lpcreposix -lpcre INCLUDE += $(shell pcre-config --cflags) DEFINES += -DHAVE_PCREPOSIX else ifeq ($(REGEXLIB), tre) LIBS += -L$(shell pkg-config --variable=libdir tre) $(shell pkg-config --libs tre) #LIBS += -L/usr/lib -ltre DEFINES += -DHAVE_LIBTRE INCLUDE += $(shell pkg-config --cflags tre) endif ifdef USE_PINPLUGIN DEFINES += -DUSE_PINPLUGIN endif ifdef USE_GRAPHTFT DEFINES += -DUSE_GRAPHTFT endif ifdef CFLC DEFINES += -DCFLC endif ifdef DEBUG_CONFL DEFINES += -DDEBUG_CONFL endif ifdef PLUGIN_EPGSEARCH_MAX_SUBTITLE_LENGTH DEFINES += -DMAX_SUBTITLE_LENGTH='$(PLUGIN_EPGSEARCH_MAX_SUBTITLE_LENGTH)' endif ### length of the filling '-' in the channel separators, defaults to ### "----------------------------------------" ### overwrite this with PLUGIN_EPGSEARCH_SEP_ITEMS=--- in your Make.config ### to avoid problems with graphlcd ifdef PLUGIN_EPGSEARCH_SEP_ITEMS DEFINES += -DMENU_SEPARATOR_ITEMS='"$(PLUGIN_EPGSEARCH_SEP_ITEMS)"' endif OBJS2 = mainmenushortcut.o epgsearchonly.o LIBS2 = OBJS3 = mainmenushortcut.o conflictcheckonly.o LIBS3 = OBJS4 = mainmenushortcut.o quickepgsearch.o LIBS4 = ### The main target: all: $(ALL) i18n ### Implicit rules: %.o: %.c $(CXX) $(CXXFLAGS) -c $(DEFINES) -DPLUGIN_NAME_I18N='"$(PLUGIN)"' $(INCLUDES) $< mainmenushortcut.o: mainmenushortcut.c $(CXX) $(CXXFLAGS) -c $(DEFINES) -DPLUGIN_NAME_I18N='"$(MAINMENUSHORTCUT)"' $(INCLUDES) $< epgsearchonly.o: epgsearchonly.c $(CXX) $(CXXFLAGS) -c $(DEFINES) -DPLUGIN_NAME_I18N='"$(PLUGIN2)"' $(INCLUDES) $< conflictcheckonly.o: conflictcheckonly.c $(CXX) $(CXXFLAGS) -c $(DEFINES) -DPLUGIN_NAME_I18N='"$(PLUGIN3)"' $(INCLUDES) $< quickepgsearch.o: quickepgsearch.c $(CXX) $(CXXFLAGS) -c $(DEFINES) -DPLUGIN_NAME_I18N='"$(PLUGIN4)"' $(INCLUDES) $< # Dependencies: MAKEDEP = $(CXX) -MM -MG DEPFILE = .dependencies $(DEPFILE): Makefile @$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) $(OBJS2:%.o=%.c) $(OBJS3:%.o=%.c) $(OBJS4:%.o=%.c)> $@ -include $(DEPFILE) ### Internationalization (I18N): PODIR = po LOCALEDIR = $(VDRDIR)/locale I18Npo = $(wildcard $(PODIR)/*.po) I18Nmsgs = $(addprefix $(LOCALEDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file)))))) I18Npot = $(PODIR)/$(PLUGIN).pot %.mo: %.po msgfmt -c -o $@ $< $(I18Npot): $(wildcard *.[ch]) xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP -kI18nTranslate --msgid-bugs-address='' -o $@ `ls $^` %.po: $(I18Npot) msgmerge -U --no-wrap --no-location --backup=none -q $@ $< @touch $@ $(I18Nmsgs): $(LOCALEDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo @mkdir -p $(dir $@) cp $< $@ .PHONY: i18n i18n: $(I18Nmsgs) $(I18Npot) ### Targets: libvdr-$(PLUGIN).so: $(OBJS) $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@ @cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION) libvdr-$(PLUGIN2).so: $(OBJS2) $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS2) $(LIBS2) -o $@ @cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION) libvdr-$(PLUGIN3).so: $(OBJS3) $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS3) $(LIBS3) -o $@ @cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION) libvdr-$(PLUGIN4).so: $(OBJS4) $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS4) $(LIBS4) -o $@ @cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION) createcats: createcats.o Makefile $(CXX) $(CXXFLAGS) $(LDFLAGS) createcats.o -o $@ dist: docs clean @-rm -rf $(TMPDIR)/$(ARCHIVE) @mkdir $(TMPDIR)/$(ARCHIVE) @cp -a * $(TMPDIR)/$(ARCHIVE) @-rm -rf $(TMPDIR)/$(ARCHIVE)/doc-src @-rm -rf $(TMPDIR)/$(ARCHIVE)/html @-rm -rf $(TMPDIR)/$(ARCHIVE)/docsrc2man.sh @-rm -rf $(TMPDIR)/$(ARCHIVE)/docsrc2html.sh @tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE) @-rm -rf $(TMPDIR)/$(ARCHIVE) @ln -sf README.git README @echo Distribution package created as $(PACKAGE).tgz distfull: docs clean @-rm -rf $(TMPDIR)/$(ARCHIVE) @mkdir $(TMPDIR)/$(ARCHIVE) @cp -a * $(TMPDIR)/$(ARCHIVE) @tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE) @-rm -rf $(TMPDIR)/$(ARCHIVE) @ln -sf README.git README @echo complete distribution package created as $(PACKAGE).tgz docs: @./docsrc2man.sh @./docsrc2html.sh @ln -sf ./doc/en/epgsearch.4.txt MANUAL @ln -sf ./doc/en/epgsearch.1.txt README @ln -sf ./doc/de/epgsearch.1.txt README.DE install-doc: docs @mkdir -p $(MANDIR)/man1 @mkdir -p $(MANDIR)/man4 @mkdir -p $(MANDIR)/man5 @mkdir -p $(MANDIR)/de/man1 @mkdir -p $(MANDIR)/de/man5 @cp man/en/*1.gz $(MANDIR)/man1/ @cp man/en/*4.gz $(MANDIR)/man4/ @cp man/en/*5.gz $(MANDIR)/man5/ @cp man/de/*1.gz $(MANDIR)/de/man1/ @cp man/de/*5.gz $(MANDIR)/de/man5/ clean: @-rm -f $(PODIR)/*.mo $(PODIR)/*.pot @-rm -f $(OBJS) $(OBJS2) $(OBJS3) $(OBJS4) $(DEPFILE) *.so *.tgz core* createcats createcats.o pod2*.tmp @-find . \( -name "*~" -o -name "#*#" \) -print0 | xargs -0r rm -f @-rm -rf doc html man vdr-plugin-epgsearch-2.4.1/README000077700000000000000000000000001405273211300225622./doc/en/epgsearch.1.txtustar00rootroot00000000000000vdr-plugin-epgsearch-2.4.1/README.Translators000066400000000000000000000017701405273211300207420ustar00rootroot00000000000000--------------------------------------------------- Building and maintaining translations for EPGSearch --------------------------------------------------- If your language is not yet supported in EPGSearch or any updates are needed it would be great if you could give your support for this. To do so please follow these steps: 1. Check if there is a current beta version of EPGSearch at http://winni.vdr-developer.org/epgsearch/downloads/beta If not please use the latest known release. 2. Copy the original po file for your language to any backup destination. Now edit the original po file for your language in the po subdirectory. All entries with 'msgstr ""' should be filled with your translation. 3. To test your translations, simply recompile EPGSearch and check your changes. 4. When done please send me your po file or even better a patch for it, created like cd po diff -Nru /path-to-backup-po-file/x.po x.po > epgsearch_x.diff Many thanks for your support Christian vdr-plugin-epgsearch-2.4.1/README.git000066400000000000000000000005151405273211300172050ustar00rootroot00000000000000Note: This is a dummy README needed by some maintainers that use the git repository to fetch epgsearch. In the official or beta tar balls it is replaced by a symbolic link to ./doc/en/epgsearch.1.txt which is not part of the git repository since it is built from the sources (via 'make docs'). If its in the way, just remove it. vdr-plugin-epgsearch-2.4.1/afuzzy.c000066400000000000000000000172521405273211300172450ustar00rootroot00000000000000/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #include #include #include #include "afuzzy.h" static int afuzzy_checkFLT(const char *t, AFUZZY *fuzzy); /****************************************************************************** FUNCTION afuzzy_init() Initialization of the fuzzy search routine. This applies to the consequent calls of the afuzzy_CheckRTR (whole string matching) and afuzzy_CheckSUB (substring match) routines. afuzzy_init() should be called for each new pattern or error length. The search is case sensitive ARGUMENTS: p Pattern kerr Number of possible errors. Shouldn't exceed pattern length UseFilter Use agrep filter algorithm that speeds up search. fuzzy pointer to the structure that will be later passes to Check* (the first 6 elements should be NULLs for the first call) RETURN VALUE: none ALGORITHM see. the article on agrep algorithms. The only change is accounting transpositions as one edit operation . ******************************************************************************/ void afuzzy_init(const char *p, int kerr, int UseFilter, AFUZZY *fuzzy) { int cnt, p_len, i, l, d, m; char PatFilter[sizeof(Uint) * 8 + 1]; fuzzy->k = kerr; m = strlen(p); fuzzy->FilterSet = 0; memset(fuzzy->Map, 0 , sizeof(fuzzy->Map)); if (fuzzy->S) free(fuzzy->S); if (fuzzy->R) free(fuzzy->R); if (fuzzy->R1) free(fuzzy->R1); if (fuzzy->RP) free(fuzzy->RP); if (fuzzy->RI) free(fuzzy->RI); if (fuzzy->FilterS) free(fuzzy->FilterS); fuzzy->FilterS = NULL; fuzzy->S = (Uint *)calloc(m + 1, sizeof(Uint)); fuzzy->R = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint)); fuzzy->R1 = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint)); fuzzy->RI = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint)); fuzzy->RP = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint)); for (i = 0, cnt = 0; i < m; i++) { l = fuzzy->Map[(unsigned char)p[i]]; if (!l) { l = fuzzy->Map[(unsigned char)p[i]] = ++cnt; fuzzy->S[l] = 0; } fuzzy->S[l] |= 1 << i; } for (d = 0; d <= fuzzy->k; d++) fuzzy->RI[d] = (1 << d) - 1; fuzzy->mask_ok = (1 << (m - 1)); fuzzy->r_size = sizeof(Uint) * (fuzzy->k + 1); p_len = m; if (p_len > (int) sizeof(Uint) * 8) p_len = (int) sizeof(Uint) * 8; /* If k is zero then no filter is needed! */ if (fuzzy->k && (p_len >= 2 * (fuzzy->k + 1))) { if (UseFilter) { fuzzy->FilterSet = 1; memset(fuzzy->FilterMap, 0 , sizeof(fuzzy->FilterMap)); fuzzy->FilterS = (Uint *)calloc(m + 1, sizeof(Uint)); /* Not let's fill the interleaved pattern */ int dd = p_len / (fuzzy->k + 1); p_len = dd * (fuzzy->k + 1); for (i = 0, cnt = 0; i < dd; i++) for (int j = 0; j < fuzzy->k + 1; j++, cnt++) PatFilter[cnt] = (unsigned char)p[j * dd + i]; PatFilter[p_len] = 0; for (i = 0, cnt = 0; i < p_len; i++) { l = fuzzy->FilterMap[(unsigned char)PatFilter[i]]; if (!l) { l = fuzzy->FilterMap[(unsigned char)PatFilter[i]] = ++cnt; fuzzy->FilterS[l] = 0; } fuzzy->FilterS[l] |= 1 << i; } fuzzy->filter_ok = 0; for (i = p_len - fuzzy->k - 1; i <= p_len - 1; i++) /* k+1 times */ fuzzy->filter_ok |= 1 << i; /* k+1 first bits set to 1 */ fuzzy->filter_shift = (1 << (fuzzy->k + 2)) - 1; } } } /****************************************************************************** FUNCTION afuzzy_free() Cleaning up after previous afuzzy_init() call. ARGUMENTS: fuzzy pointer to the afuzzy parameters structure RETURN VALUE: none ******************************************************************************/ void afuzzy_free(AFUZZY *fuzzy) { if (fuzzy->S) { free(fuzzy->S); fuzzy->S = NULL; } if (fuzzy->R) { free(fuzzy->R); fuzzy->R = NULL; } if (fuzzy->R1) { free(fuzzy->R1); fuzzy->R1 = NULL; } if (fuzzy->RP) { free(fuzzy->RP); fuzzy->RP = NULL; } if (fuzzy->RI) { free(fuzzy->RI); fuzzy->RI = NULL; } if (fuzzy->FilterS) { free(fuzzy->FilterS); fuzzy->FilterS = NULL; } } /****************************************************************************** FUNCTION afuzzy_CheckSUB() Perform a fuzzy pattern substring matching. afuzzy_init() should be called previously to initialize the pattern and error length. Positive result means that some part of the string given matches the pattern with no more than afuzzy->k errors (1 error = 1 letter replacement or transposition) ARGUMENTS: t the string to test fuzzy pointer to the afuzzy parameters structure RETURN VALUE: 0 - no match > 0 - strings match ALGORITHM ???????????????? ******************************************************************************/ int afuzzy_checkSUB(const char *t, AFUZZY *fuzzy) { char c; int j, d; /* For eficciency this case should be little bit optimized */ if (!fuzzy->k) { Uint R = 0, R1; for (j = 0; (c = t[j]) != '\0'; j++) { R1 = (((R << 1) | 1) & fuzzy->S[fuzzy->Map[(unsigned char)c]]); R = R1; if (R1 & fuzzy->mask_ok) return 1; } /* end for (int j = 0 ... */ return 0; } if (fuzzy->FilterSet && !afuzzy_checkFLT(t, fuzzy)) return 0; memcpy(fuzzy->R, fuzzy->RI, fuzzy->r_size); /* R = RI */ for (j = 0; (c = t[j]); j++) { for (d = 0; d <= fuzzy->k; d++) { fuzzy->R1[d] = (((fuzzy->R[d] << 1) | 1) & fuzzy->S[fuzzy->Map[(unsigned char)c]]); if (d > 0) fuzzy->R1[d] |= ((fuzzy->R[d - 1] | fuzzy->R1[d - 1]) << 1) | 1 | fuzzy->R[d - 1]; } if (fuzzy->R1[fuzzy->k] & fuzzy->mask_ok) return j; memcpy(fuzzy->R, fuzzy->R1, fuzzy->r_size); } /* end for (int j = 0 ... */ return 0; } static int afuzzy_checkFLT(const char *t, AFUZZY *fuzzy) { Uint FilterR = 0; Uint FilterR1; int j; for (j = 0; t[j] != '\0'; j++) { FilterR1 = (((FilterR << (fuzzy->k + 1)) | fuzzy->filter_shift) & fuzzy->FilterS[fuzzy->FilterMap[(unsigned char)t[j]]]); if (FilterR1 & fuzzy->filter_ok) return 1; FilterR = FilterR1; } /* end for (int j = 0 ... */ return 0; } vdr-plugin-epgsearch-2.4.1/afuzzy.h000066400000000000000000000034711405273211300172500ustar00rootroot00000000000000/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #ifndef _AFUZZY_H #define _AFUZZY_H #include // source from: /* Leonid Boitsov 2002. (itman@narod.ru) C version of Stas Namin. This code is a GPL software and is distributed under GNU public licence without any warranty. */ typedef unsigned int Uint; #define MaxPatSize (sizeof(Uint) * 8) typedef struct { Uint *R, *R1, *RP, *S, *RI; Uint *FilterS; int Map[256]; int FilterMap[256]; int k; Uint mask_ok; Uint filter_ok; Uint filter_shift; int r_size; int FilterSet; } AFUZZY; void afuzzy_init(const char *p, int kerr, int UseFilter, AFUZZY *fuzzy); void afuzzy_free(AFUZZY *fuzzy); int afuzzy_checkSUB(const char *t, AFUZZY *fuzzy); #endif vdr-plugin-epgsearch-2.4.1/blacklist.c000066400000000000000000000563161405273211300176710ustar00rootroot00000000000000/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #include #include "epgsearchtools.h" #include "blacklist.h" #include "epgsearchcats.h" #include #include "menu_dirselect.h" #include "changrp.h" #include "menu_search.h" #include "menu_searchedit.h" #include "menu_searchresults.h" #include cBlacklists Blacklists; // -- cBlacklist ----------------------------------------------------------------- char *cBlacklist::buffer = NULL; cBlacklist::cBlacklist(void) { ID = -1; *search = 0; options = 1; useTime = false; startTime = 0000; stopTime = 2359; useChannel = false; { LOCK_CHANNELS_READ; channelMin = Channels->GetByNumber(cDevice::CurrentChannel()); channelMax = channelMin; } channelGroup = NULL; useCase = false; mode = 0; useTitle = true; useSubtitle = true; useDescription = true; useDuration = false; minDuration = 0; maxDuration = 130; useDayOfWeek = false; DayOfWeek = 0; buffer = NULL; isGlobal = 0; useExtEPGInfo = false; catvalues = (char**) malloc(SearchExtCats.Count() * sizeof(char*)); cSearchExtCat *SearchExtCat = SearchExtCats.First(); int index = 0; while (SearchExtCat) { catvalues[index] = (char*)malloc(MaxFileName); *catvalues[index] = 0; SearchExtCat = SearchExtCats.Next(SearchExtCat); index++; } ignoreMissingEPGCats = 0; fuzzyTolerance = 1; } cBlacklist::~cBlacklist(void) { if (buffer) { free(buffer); buffer = NULL; } if (catvalues) { cSearchExtCat *SearchExtCat = SearchExtCats.First(); int index = 0; while (SearchExtCat) { free(catvalues[index]); SearchExtCat = SearchExtCats.Next(SearchExtCat); index++; } free(catvalues); catvalues = NULL; } } cBlacklist& cBlacklist::operator= (const cBlacklist &Blacklist) { char** catvaluesTemp = this->catvalues; memcpy(this, &Blacklist, sizeof(*this)); this->catvalues = catvaluesTemp; cSearchExtCat *SearchExtCat = SearchExtCats.First(); int index = 0; while (SearchExtCat) { *catvalues[index] = 0; strcpy(catvalues[index], Blacklist.catvalues[index]); SearchExtCat = SearchExtCats.Next(SearchExtCat); index++; } return *this; } void cBlacklist::CopyFromTemplate(const cSearchExt* templ) { options = templ->options; useTime = templ->useTime; startTime = templ->startTime; stopTime = templ->stopTime; useChannel = templ->useChannel; useCase = templ->useCase; mode = templ->mode; useTitle = templ->useTitle; useSubtitle = templ->useSubtitle; useDescription = templ->useDescription; useDuration = templ->useDuration; minDuration = templ->minDuration; maxDuration = templ->maxDuration; useDayOfWeek = templ->useDayOfWeek; DayOfWeek = templ->DayOfWeek; useExtEPGInfo = templ->useExtEPGInfo; isGlobal = 0; cSearchExtCat *SearchExtCat = SearchExtCats.First(); int index = 0; while (SearchExtCat) { strcpy(catvalues[index], templ->catvalues[index]); SearchExtCat = SearchExtCats.Next(SearchExtCat); index++; } channelMin = templ->channelMin; channelMax = templ->channelMax; if (channelGroup) free(channelGroup); if (templ->channelGroup) channelGroup = strdup(templ->channelGroup); fuzzyTolerance = templ->fuzzyTolerance; ignoreMissingEPGCats = templ->ignoreMissingEPGCats; } bool cBlacklist::operator< (const cListObject &ListObject) { cBlacklist *BL = (cBlacklist *)&ListObject; return strcasecmp(search, BL->search) < 0; } const char *cBlacklist::ToText(void) { char tmp_Start[5] = ""; char tmp_Stop[5] = ""; char tmp_minDuration[5] = ""; char tmp_maxDuration[5] = ""; char* tmp_chanSel = NULL; char* tmp_search = NULL; char* tmp_catvalues = NULL; free(buffer); tmp_search = strdup(search); while (strstr(tmp_search, "|")) tmp_search = strreplace(tmp_search, "|", "!^pipe^!"); // ugly: replace a pipe with something, that should not happen to be part of a regular expression strreplace(tmp_search, ':', '|'); if (useTime) { sprintf(tmp_Start, "%04d", startTime); sprintf(tmp_Stop, "%04d", stopTime); } if (useDuration) { sprintf(tmp_minDuration, "%04d", minDuration); sprintf(tmp_maxDuration, "%04d", maxDuration); } if (useChannel == 1) { if (channelMin->Number() < channelMax->Number()) msprintf(&tmp_chanSel, "%s|%s", CHANNELSTRING(channelMin), CHANNELSTRING(channelMax)); else msprintf(&tmp_chanSel, "%s", CHANNELSTRING(channelMin)); } if (useChannel == 2) { int channelGroupNr = ChannelGroups.GetIndex(channelGroup); if (channelGroupNr == -1) { LogFile.eSysLog("channel group %s does not exist!", channelGroup); useChannel = 0; } else tmp_chanSel = strdup(channelGroup); } if (useExtEPGInfo) { cSearchExtCat *SearchExtCat = SearchExtCats.First(); int index = 0; while (SearchExtCat) { char* catvalue = NULL; if (msprintf(&catvalue, "%s", catvalues[index]) != -1) { while (strstr(catvalue, ":")) catvalue = strreplace(catvalue, ":", "!^colon^!"); // ugly: replace with something, that should not happen to be part ofa category value while (strstr(catvalue, "|")) catvalue = strreplace(catvalue, "|", "!^pipe^!"); // ugly: replace with something, that should not happen to be part of a regular expression if (index == 0) msprintf(&tmp_catvalues, "%d#%s", SearchExtCat->id, catvalue); else { char* temp = tmp_catvalues; msprintf(&tmp_catvalues, "%s|%d#%s", tmp_catvalues, SearchExtCat->id, catvalue); free(temp); } } SearchExtCat = SearchExtCats.Next(SearchExtCat); index++; free(catvalue); } } msprintf(&buffer, "%d:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d:%d:%d:%s:%s:%d:%d:%d:%s:%d:%d:%d", ID, tmp_search, useTime, tmp_Start, tmp_Stop, useChannel, (useChannel > 0 && useChannel < 3) ? tmp_chanSel : "0", useCase, mode, useTitle, useSubtitle, useDescription, useDuration, tmp_minDuration, tmp_maxDuration, useDayOfWeek, DayOfWeek, useExtEPGInfo, useExtEPGInfo ? tmp_catvalues : "", fuzzyTolerance, ignoreMissingEPGCats, isGlobal); if (tmp_chanSel) free(tmp_chanSel); if (tmp_search) free(tmp_search); if (tmp_catvalues) free(tmp_catvalues); return buffer; } bool cBlacklist::Parse(const char *s) { char *line; char *pos; char *pos_next; int parameter = 1; int valuelen; char value[MaxFileName]; pos = line = strdup(s); pos_next = pos + strlen(pos); if (*pos_next == '\n') *pos_next = 0; while (*pos) { while (*pos == ' ') pos++; if (*pos) { if (*pos != ':') { pos_next = strchr(pos, ':'); if (!pos_next) pos_next = pos + strlen(pos); valuelen = pos_next - pos + 1; if (valuelen > MaxFileName) valuelen = MaxFileName; strn0cpy(value, pos, valuelen); pos = pos_next; switch (parameter) { case 1: ID = atoi(value); break; case 2: strcpy(search, value); break; case 3: useTime = atoi(value); break; case 4: startTime = atoi(value); break; case 5: stopTime = atoi(value); break; case 6: useChannel = atoi(value); break; case 7: if (useChannel == 0) { channelMin = NULL; channelMax = NULL; } else if (useChannel == 1) { int minNum = 0, maxNum = 0; int fields = sscanf(value, "%d-%d", &minNum, &maxNum); if (fields == 0) { // stored with ID #ifdef __FreeBSD__ char *channelMinbuffer = MALLOC(char, 32); char *channelMaxbuffer = MALLOC(char, 32); int channels = sscanf(value, "%31[^|]|%31[^|]", channelMinbuffer, channelMaxbuffer); #else char *channelMinbuffer = NULL; char *channelMaxbuffer = NULL; int channels = sscanf(value, "%m[^|]|%m[^|]", &channelMinbuffer, &channelMaxbuffer); #endif LOCK_CHANNELS_READ; channelMin = Channels->GetByChannelID(tChannelID::FromString(channelMinbuffer), true, true); if (!channelMin) { LogFile.eSysLog("ERROR: channel %s not defined", channelMinbuffer); channelMin = channelMax = NULL; useChannel = 0; } if (channels == 1) channelMax = channelMin; else { channelMax = Channels->GetByChannelID(tChannelID::FromString(channelMaxbuffer), true, true); if (!channelMax) { LogFile.eSysLog("ERROR: channel %s not defined", channelMaxbuffer); channelMin = channelMax = NULL; useChannel = 0; } } free(channelMinbuffer); free(channelMaxbuffer); } } else if (useChannel == 2) channelGroup = strdup(value); break; case 8: useCase = atoi(value); break; case 9: mode = atoi(value); break; case 10: useTitle = atoi(value); break; case 11: useSubtitle = atoi(value); break; case 12: useDescription = atoi(value); break; case 13: useDuration = atoi(value); break; case 14: minDuration = atoi(value); break; case 15: maxDuration = atoi(value); break; case 16: useDayOfWeek = atoi(value); break; case 17: DayOfWeek = atoi(value); break; case 18: useExtEPGInfo = atoi(value); break; case 19: if (!ParseExtEPGValues(value)) { LogFile.eSysLog("ERROR reading ext. EPG values - 1"); free(line); return false; } break; case 20: fuzzyTolerance = atoi(value); break; case 21: ignoreMissingEPGCats = atoi(value); break; case 22: isGlobal = atoi(value); break; default: break; } //switch } parameter++; } if (*pos) pos++; } //while strreplace(search, '|', ':'); while (strstr(search, "!^pipe^!")) strreplace(search, "!^pipe^!", "|"); free(line); return (parameter >= 19) ? true : false; } bool cBlacklist::ParseExtEPGValues(const char *s) { char *line; char *pos; char *pos_next; int valuelen; char value[MaxFileName]; pos = line = strdup(s); pos_next = pos + strlen(pos); if (*pos_next == '\n') *pos_next = 0; while (*pos) { while (*pos == ' ') pos++; if (*pos) { if (*pos != '|') { pos_next = strchr(pos, '|'); if (!pos_next) pos_next = pos + strlen(pos); valuelen = pos_next - pos + 1; if (valuelen > MaxFileName) valuelen = MaxFileName; strn0cpy(value, pos, valuelen); pos = pos_next; if (!ParseExtEPGEntry(value)) { LogFile.eSysLog("ERROR reading ext. EPG value: %s", value); free(line); return false; } } } if (*pos) pos++; } //while free(line); return true; } bool cBlacklist::ParseExtEPGEntry(const char *s) { char *line; char *pos; char *pos_next; int parameter = 1; int valuelen; char value[MaxFileName]; int currentid = -1; pos = line = strdup(s); pos_next = pos + strlen(pos); if (*pos_next == '\n') *pos_next = 0; while (*pos) { while (*pos == ' ') pos++; if (*pos) { if (*pos != '#') { pos_next = strchr(pos, '#'); if (!pos_next) pos_next = pos + strlen(pos); valuelen = pos_next - pos + 1; if (valuelen > MaxFileName) valuelen = MaxFileName; strn0cpy(value, pos, valuelen); pos = pos_next; switch (parameter) { case 1: { currentid = atoi(value); int index = SearchExtCats.GetIndexFromID(currentid); if (index > -1) strcpy(catvalues[index], ""); } break; case 2: if (currentid > -1) { int index = SearchExtCats.GetIndexFromID(currentid); if (index > -1) { while (strstr(value, "!^colon^!")) strreplace(value, "!^colon^!", ":"); while (strstr(value, "!^pipe^!")) strreplace(value, "!^pipe^!", "|"); strcpy(catvalues[index], value); } } break; default: break; } //switch } parameter++; } if (*pos) pos++; } //while free(line); return (parameter >= 2) ? true : false; } bool cBlacklist::Save(FILE *f) { return fprintf(f, "%s\n", ToText()) > 0; } const cEvent * cBlacklist::GetEventByBlacklist(const cSchedule *schedule, const cEvent *Start, int MarginStop) { const cEvent *pe = NULL; const cEvent *p1 = NULL; if (Start) p1 = schedule->Events()->Next(Start); else p1 = schedule->Events()->First(); time_t tNow = time(NULL); char* szTest = NULL; char* searchText = strdup(search); if (!useCase) ToLower(searchText); int searchStart = 0, searchStop = 0; if (useTime) { searchStart = startTime; searchStop = stopTime; if (searchStop < searchStart) searchStop += 2400; } int minSearchDuration = 0; int maxSearchDuration = 0; if (useDuration) { minSearchDuration = minDuration / 100 * 60 + minDuration % 100; maxSearchDuration = maxDuration / 100 * 60 + maxDuration % 100; } for (const cEvent *p = p1; p; p = schedule->Events()->Next(p)) { if (!p) { break; } if (szTest) { free(szTest); szTest = NULL; } // ignore events without title if (!p->Title() || strlen(p->Title()) == 0) continue; msprintf(&szTest, "%s%s%s%s%s", (useTitle ? p->Title() : ""), (useSubtitle || useDescription) ? "~" : "", (useSubtitle ? p->ShortText() : ""), useDescription ? "~" : "", (useDescription ? p->Description() : "")); if (tNow < p->EndTime() + MarginStop * 60) { if (!useCase) ToLower(szTest); if (useTime) { time_t tEvent = p->StartTime(); struct tm tmEvent; localtime_r(&tEvent, &tmEvent); int eventStart = tmEvent.tm_hour * 100 + tmEvent.tm_min; int eventStart2 = tmEvent.tm_hour * 100 + tmEvent.tm_min + 2400; if ((eventStart < searchStart || eventStart > searchStop) && (eventStart2 < searchStart || eventStart2 > searchStop)) continue; } if (useDuration) { int duration = p->Duration() / 60; if (minSearchDuration > duration || maxSearchDuration < duration) continue; } if (useDayOfWeek) { time_t tEvent = p->StartTime(); struct tm tmEvent; localtime_r(&tEvent, &tmEvent); if (DayOfWeek >= 0 && DayOfWeek != tmEvent.tm_wday) continue; if (DayOfWeek < 0) { int iFound = 0; for (int i = 0; i < 7; i++) if (abs(DayOfWeek) & (int)pow(2, i) && i == tmEvent.tm_wday) { iFound = 1; break; } if (!iFound) continue; } } if (strlen(szTest) > 0) { if (!MatchesSearchMode(szTest, searchText, mode, " ,;|~", fuzzyTolerance)) continue; } if (useExtEPGInfo && !MatchesExtEPGInfo(p)) continue; pe = p; break; } } if (szTest) free(szTest); free(searchText); return pe; } // returns a pointer array to the matching search results cSearchResults* cBlacklist::Run(cSearchResults* pSearchResults, int MarginStop) { LogFile.Log(3, "start search for blacklist '%s'", search); LOCK_CHANNELS_READ; LOCK_SCHEDULES_READ; const cSchedule *Schedule = Schedules->First(); while (Schedule) { const cChannel* channel = Channels->GetByChannelID(Schedule->ChannelID(), true, true); if (!channel) { Schedule = Schedules->Next(Schedule); continue; } if (useChannel == 1 && channelMin && channelMax) { if (channelMin->Number() > channel->Number() || channelMax->Number() < channel->Number()) { Schedule = Schedules->Next(Schedule); continue; } } if (useChannel == 2 && channelGroup) { cChannelGroup* group = ChannelGroups.GetGroupByName(channelGroup); if (!group || !group->ChannelInGroup(channel)) { Schedule = Schedules->Next(Schedule); continue; } } if (useChannel == 3) { if (channel->Ca() >= CA_ENCRYPTED_MIN) { Schedule = Schedules->Next(Schedule); continue; } } const cEvent *pPrevEvent = NULL; do { const cEvent* event = GetEventByBlacklist(Schedule, pPrevEvent, MarginStop); pPrevEvent = event; if (event && Channels->GetByChannelID(event->ChannelID(), true, true)) { if (!pSearchResults) pSearchResults = new cSearchResults; pSearchResults->Add(new cSearchResult(event, this)); } } while (pPrevEvent); Schedule = Schedules->Next(Schedule); } LogFile.Log(3, "found %d event(s) for blacklist '%s'", pSearchResults ? pSearchResults->Count() : 0, search); return pSearchResults; } bool cBlacklist::MatchesExtEPGInfo(const cEvent* e) { if (!e || !e->Description()) return false; cSearchExtCat* SearchExtCat = SearchExtCats.First(); while (SearchExtCat) { char* value = NULL; int index = SearchExtCats.GetIndexFromID(SearchExtCat->id); if (index > -1) value = catvalues[index]; if (value && strlen(value) > 0) { char* testvalue = GetExtEPGValue(e, SearchExtCat); if (!testvalue) return false; // compare not case sensitive char* valueLower = strdup(value); ToLower(valueLower); ToLower(testvalue); if (!MatchesSearchMode(testvalue, valueLower, SearchExtCat->searchmode, ",;|~", fuzzyTolerance)) { free(testvalue); free(valueLower); return false; } free(testvalue); free(valueLower); } SearchExtCat = SearchExtCats.Next(SearchExtCat); } return true; } // -- cBlacklists ---------------------------------------------------------------- int cBlacklists::GetNewID() { int newID = -1; cMutexLock BlacklistLock(this); cBlacklist *l = (cBlacklist *)First(); while (l) { newID = std::max(newID, l->ID); l = (cBlacklist *)l->Next(); } return newID + 1; } cBlacklist* cBlacklists::GetBlacklistFromID(int ID) { if (ID == -1) return NULL; cMutexLock BlacklistLock(this); cBlacklist *l = (cBlacklist *)First(); while (l) { if (l->ID == ID) return l; l = (cBlacklist *)l->Next(); } return NULL; } bool cBlacklists::Exists(const cBlacklist* Blacklist) { cMutexLock BlacklistLock(this); cBlacklist *l = (cBlacklist*)First(); while (l) { if (l == Blacklist) return true; l = (cBlacklist*)l->Next(); } return false; } vdr-plugin-epgsearch-2.4.1/blacklist.h000066400000000000000000000063711405273211300176720ustar00rootroot00000000000000/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #ifndef __EPGSEARCHBL_H #define __EPGSEARCHBL_H #include class cSearchExt; class cSearchResults; class cBlacklist : public cListObject { friend class cMenuEditSearchExt; public: int ID; char search[MaxFileName]; int options; int useTime; int startTime; int stopTime; int useChannel; const cChannel *channelMin; const cChannel *channelMax; char* channelGroup; int useCase; int mode; int useTitle; int useSubtitle; int useDescription; int useDuration; int minDuration; int maxDuration; int useDayOfWeek; int DayOfWeek; int useExtEPGInfo; int ignoreMissingEPGCats; char** catvalues; int fuzzyTolerance; int isGlobal; static char *buffer; public: cBlacklist(void); virtual ~cBlacklist(void); cBlacklist& operator= (const cBlacklist&); virtual bool operator< (const cListObject &ListObject); const char *Search(void) { return search; } int Options(void) { return options; } int StartTime(void) { return startTime; } int StopTime(void) { return stopTime; } int UseChannel(void) { return useChannel; } const cChannel *ChannelMin(void) { return channelMin; } const cChannel *ChannelMax(void) { return channelMax; } const cEvent * GetEventByBlacklist(const cSchedule *schedules, const cEvent *Start, int MarginStop = 0); bool MatchesExtEPGInfo(const cEvent* e); const char *ToText(void); bool Parse(const char *s); bool ParseExtEPGValues(const char *s); bool ParseExtEPGEntry(const char *s); bool Save(FILE *f); cSearchResults* Run(cSearchResults* pSearchResults = NULL, int MarginStop = 0); void CopyFromTemplate(const cSearchExt* templ); }; class cBlacklists : public cConfig, public cMutex { public: int GetNewID(void); cBlacklist* GetBlacklistFromID(int ID); bool Exists(const cBlacklist* Blacklist); }; class cBlacklistObject: public cListObject { public: cBlacklist* blacklist; cBlacklistObject(cBlacklist* Blacklist) : blacklist(Blacklist) {} }; extern cBlacklists Blacklists; #endif vdr-plugin-epgsearch-2.4.1/changrp.c000066400000000000000000000367261405273211300173460ustar00rootroot00000000000000/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #include "changrp.h" #include "epgsearchtools.h" #include "epgsearchcfg.h" #include "epgsearchext.h" #include // -- cChannelGroup ----------------------------------------------------------------- cChannelGroup::cChannelGroup(void) { strcpy(name, ""); channels.Clear(); } cChannelGroup::~cChannelGroup(void) { channels.Clear(); } bool cChannelGroup::Parse(const char *s) { char *line; char *pos; char *pos_next; int parameter = 1; int valuelen; #define MAXVALUELEN (10 * MaxFileName) char value[MAXVALUELEN]; pos = line = strdup(s); pos_next = pos + strlen(pos); if (*pos_next == '\n') *pos_next = 0; while (*pos) { while (*pos == ' ') pos++; if (*pos) { if (*pos != '|') { pos_next = strchr(pos, '|'); if (!pos_next) pos_next = pos + strlen(pos); valuelen = pos_next - pos + 1; if (valuelen > MAXVALUELEN) { LogFile.eSysLog("entry '%s' is too long. Will be truncated!", pos); valuelen = MAXVALUELEN; } strn0cpy(value, pos, valuelen); pos = pos_next; switch (parameter) { case 1: strcpy(name, value); break; default: { #ifdef __FreeBSD__ char *channelbuffer = MALLOC(char, 32); int numChannels = sscanf(value, "%31[^|]", channelbuffer); #else char *channelbuffer = NULL; int numChannels = sscanf(value, "%m[^|]", &channelbuffer); #endif if (numChannels == 1) { LOCK_CHANNELS_READ; const cChannel* channel = Channels->GetByChannelID(tChannelID::FromString(channelbuffer), true, true); if (channel) { cChannelGroupItem* channelitem = new cChannelGroupItem(channel); channels.Add(channelitem); } } free(channelbuffer); } break; } //switch } parameter++; } if (*pos) pos++; } //while free(line); return (parameter >= 1) ? true : false; } const char *cChannelGroup::ToText(void) { char* channelbuffer = NULL; cChannelGroupItem* ChannelGroupItem = channels.First(); int index = 0; while (ChannelGroupItem) { const cChannel* channel = ChannelGroupItem->channel; if (index++ == 0) channelbuffer = strdup(CHANNELSTRING(channel)); else { char* temp = channelbuffer; msprintf(&channelbuffer, "%s|%s", channelbuffer, CHANNELSTRING(channel)); free(temp); } ChannelGroupItem = channels.Next(ChannelGroupItem); } char* buffer = NULL; msprintf(&buffer, "%s|%s", name, channelbuffer); free(channelbuffer); return buffer; } int* cChannelGroup::CreateChannelSel() { LOCK_CHANNELS_READ; int* channelSel = (int*) malloc(Channels->Count() * sizeof(int)); const cChannel* channel = Channels->First(); int index = 0; while (channel) { if (channel->GroupSep()) { channel = Channels->Next(channel); continue; } channelSel[index] = 0; cChannelGroupItem* channelInGroup = channels.First(); while (channelInGroup) { if (channel == channelInGroup->channel) { channelSel[index] = 1; break; } channelInGroup = channels.Next(channelInGroup); } index++; channel = Channels->Next(channel); } return channelSel; } void cChannelGroup::CreateChannelList(int* channelSel) { channels.Clear(); LOCK_CHANNELS_READ; const cChannel* channel = Channels->First(); int index = 0; while (channel) { if (!channel->GroupSep()) { if (channelSel[index] == 1) channels.Add(new cChannelGroupItem(channel)); index++; } channel = Channels->Next(channel); } } bool cChannelGroup::Save(FILE *f) { return fprintf(f, "%s\n", ToText()) > 0; } bool cChannelGroup::ChannelInGroup(const cChannel* channel) { cChannelGroupItem* channelInGroup = channels.First(); while (channelInGroup) { if (channel == channelInGroup->channel) return true; channelInGroup = channels.Next(channelInGroup); } return false; } // -- cChannelGroups ----------------------------------------------------------------- int cChannelGroups::GetIndex(char* channelGroup) { if (!channelGroup) return -1; cChannelGroup* ChannelGroup = First(); int index = 0; while (ChannelGroup) { if (strcmp(channelGroup, ChannelGroup->name) == 0) return index; index++; ChannelGroup = Next(ChannelGroup); } return -1; } cChannelGroup* cChannelGroups::GetGroupByName(const char* channelGroup) { if (!channelGroup) return NULL; cChannelGroup* ChannelGroup = First(); while (ChannelGroup) { if (strcmp(channelGroup, ChannelGroup->name) == 0) return ChannelGroup; ChannelGroup = Next(ChannelGroup); } return NULL; } cSearchExt* cChannelGroups::Used(cChannelGroup* group) { if (!group) return NULL; if (SearchExts.Count() == 0) SearchExts.Load(AddDirectory(CONFIGDIR, "epgsearch.conf")); cMutexLock SearchExtsLock(&SearchExts); cSearchExt *SearchExt = SearchExts.First(); while (SearchExt) { if (SearchExt->useChannel == 2 && strcmp(SearchExt->channelGroup, group->name) == 0) return SearchExt; SearchExt = SearchExts.Next(SearchExt); } return NULL; } char** cChannelGroups::CreateMenuitemsList() { char** menuitemsChGr = new char*[ChannelGroups.Count() + 1]; cChannelGroup* ChannelGroup = First(); menuitemsChGr[0] = strdup(""); int index = 1; while (ChannelGroup) { menuitemsChGr[index++] = ChannelGroup->name; ChannelGroup = Next(ChannelGroup); } return menuitemsChGr; } // -- cMenuChannelGroupItem ----------------------------------------------------------------- cMenuChannelGroupItem::cMenuChannelGroupItem(cChannelGroup* Group) { group = Group; Set(); } void cMenuChannelGroupItem::Set(void) { cString channelbuffer; cChannelGroupItem* channelInGroup = group->channels.First(); int channelNr, chIntBegin = -1, chIntEnd = -1, chLast = -1; while (channelInGroup) { channelNr = channelInGroup->channel->Number(); if (chIntBegin == -1) chIntBegin = channelNr; if (chIntEnd == -1) chIntEnd = channelNr; if (chLast == channelNr - 1) chIntEnd = channelNr; else { chIntEnd = chLast; if (chIntBegin == chIntEnd) channelbuffer = cString::sprintf("%s %d", *channelbuffer ? *channelbuffer : "", chIntBegin); else if (chIntEnd != -1) channelbuffer = cString::sprintf("%s %d-%d", *channelbuffer ? *channelbuffer : "", chIntBegin, chIntEnd); chIntBegin = chIntEnd = channelNr; } chLast = channelNr; channelInGroup = group->channels.Next(channelInGroup); if (!channelInGroup) { if (chLast == chIntBegin) channelbuffer = cString::sprintf("%s %d", *channelbuffer ? *channelbuffer : "", chIntBegin); else channelbuffer = cString::sprintf("%s %d-%d", *channelbuffer ? *channelbuffer : "", chIntBegin, chLast); } } SetText(cString::sprintf("%s\t%s", group->name, *channelbuffer ? *channelbuffer : "")); } // --- cMenuChannelGroups ---------------------------------------------------------- cMenuChannelGroups::cMenuChannelGroups(char** GroupName) : cOsdMenu(tr("Channel groups"), 20) { SetMenuCategory(mcSetupPlugins); groupSel = -1; groupName = GroupName; if (groupName && *groupName) groupSel = ChannelGroups.GetIndex(*groupName); cChannelGroup* ChannelGroup = ChannelGroups.First(); int index = 0; while (ChannelGroup) { Add(new cMenuChannelGroupItem(ChannelGroup), (index == groupSel ? true : false)); ChannelGroup = ChannelGroups.Next(ChannelGroup); index++; } if (groupName && *groupName) SetHelp(trVDR("Button$Edit"), trVDR("Button$New"), trVDR("Button$Delete"), tr("Button$Select")); else SetHelp(trVDR("Button$Edit"), trVDR("Button$New"), trVDR("Button$Delete"), NULL); Sort(); Display(); } cChannelGroup *cMenuChannelGroups::CurrentGroup(void) { cMenuChannelGroupItem *item = (cMenuChannelGroupItem *)Get(Current()); return item ? item->group : NULL; } eOSState cMenuChannelGroups::New(void) { if (HasSubMenu()) return osContinue; return AddSubMenu(new cMenuEditChannelGroup(new cChannelGroup, true)); } eOSState cMenuChannelGroups::Delete(void) { cChannelGroup *curGroup = CurrentGroup(); if (curGroup) { cSearchExt* search = ChannelGroups.Used(curGroup); if (search) { cString Message = cString::sprintf("%s %s", tr("Channel group used by:"), search->search); INFO(Message); return osContinue; } if (Interface->Confirm(tr("Edit$Delete group?"))) { ChannelGroups.Del(curGroup); ChannelGroups.Save(); cOsdMenu::Del(Current()); Display(); } } return osContinue; } eOSState cMenuChannelGroups::ProcessKey(eKeys Key) { int GroupNumber = HasSubMenu() ? Count() : -1; eOSState state = cOsdMenu::ProcessKey(Key); if (state == osUnknown) { if (HasSubMenu()) return osContinue; switch (Key) { case kRed: if (CurrentGroup()) state = AddSubMenu(new cMenuEditChannelGroup(CurrentGroup())); else state = osContinue; break; case kGreen: state = New(); break; case kYellow: state = Delete(); break; case kOk: case kBlue: if (groupName && *groupName) { free(*groupName); *groupName = strdup(CurrentGroup()->name); return osBack; } default: break; } } if (GroupNumber >= 0 && !HasSubMenu() && ChannelGroups.Get(GroupNumber)) { // a newly created group was confirmed with Ok cChannelGroup* group = ChannelGroups.Get(GroupNumber); Add(new cMenuChannelGroupItem(group), true); Display(); } return state; } // --- cMenuEditChannelGroup -------------------------------------------------------- cMenuEditChannelGroup::cMenuEditChannelGroup(cChannelGroup *Group, bool New) : cOsdMenu(tr("Edit channel group"), 30) { SetMenuCategory(mcSetupPlugins); group = Group; channelSel = group->CreateChannelSel(); strcpy(name, group->name); addIfConfirmed = New; if (group) Set(); } cMenuEditChannelGroup::~cMenuEditChannelGroup() { free(channelSel); } void cMenuEditChannelGroup::Set() { int current = Current(); Clear(); Add(new cMenuEditStrItem(tr("Group name"), name, sizeof(group->name), trVDR(FileNameChars))); LOCK_CHANNELS_READ; // TODO THIS MAY LOCK Channels A LONG TIME! const cChannel* channel = Channels->First(); int index = 0; while (channel) { if (channel->GroupSep()) { channel = Channels->Next(channel); continue; } Add(new cMenuEditBoolItem(CHANNELNAME(channel), &channelSel[index++], trVDR("no"), trVDR("yes"))); channel = Channels->Next(channel); } SetCurrent(Get(current)); } eOSState cMenuEditChannelGroup::ProcessKey(eKeys Key) { eOSState state = cOsdMenu::ProcessKey(Key); const char* ItemText = Get(Current())->Text(); if (strlen(ItemText) > 0 && strstr(ItemText, tr("Group name")) != ItemText) SetHelp(tr("Button$Invert selection"), tr("Button$All yes"), tr("Button$All no"), NULL); else if (!InEditMode(ItemText, tr("Group name"), name)) SetHelp(NULL, NULL, NULL, NULL); if (state == osUnknown) { switch (Key) { case kOk: if (strlen(name) == 0) { ERROR(tr("Group name is empty!")); return osContinue; } if (addIfConfirmed && ChannelGroups.GetGroupByName(name)) { ERROR(tr("Group name already exists!")); return osContinue; } { bool saveSearchExts = false; if (strcmp(group->name, name) != 0 && !addIfConfirmed) { // if group name changed, update searches cMutexLock SearchExtsLock(&SearchExts); cSearchExt *SearchExt = SearchExts.First(); while (SearchExt) { if (SearchExt->useChannel == 2 && SearchExt->channelGroup && strcmp(SearchExt->channelGroup, group->name) == 0) { free(SearchExt->channelGroup); SearchExt->channelGroup = strdup(name); } SearchExt = SearchExts.Next(SearchExt); } saveSearchExts = true; // save them after groups are saved! } strcpy(group->name, name); group->CreateChannelList(channelSel); if (addIfConfirmed) ChannelGroups.Add(group); ChannelGroups.Save(); if (saveSearchExts) SearchExts.Save(); } addIfConfirmed = false; return osBack; break; case kRed: case kGreen: case kYellow: { LOCK_CHANNELS_READ; const cChannel* channel = Channels->First(); int index = 0; while (channel) { if (channel->GroupSep()) { channel = Channels->Next(channel); continue; } channelSel[index] = (Key == kGreen ? 1 : (Key == kRed ? 1 - channelSel[index] : 0)); index++; channel = Channels->Next(channel); } Set(); Display(); return osContinue; } default: break; } } return state; } vdr-plugin-epgsearch-2.4.1/changrp.h000066400000000000000000000063661405273211300173500ustar00rootroot00000000000000/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #ifndef __EPGSEARCHCHANGRP_H #define __EPGSEARCHCHANGRP_H #include #include #include class cSearchExt; // --- cChannelGroupItem -------------------------------------------------------- class cChannelGroupItem : public cListObject { public: const cChannel* channel; public: cChannelGroupItem(const cChannel* ch) : channel(ch) {} }; // --- cChannelGroup -------------------------------------------------------- class cChannelGroup : public cListObject { public: char name[MaxFileName]; cList channels; public: cChannelGroup(void); virtual ~cChannelGroup(void); bool Parse(const char *s); const char *ToText(void); bool Save(FILE *f); int* CreateChannelSel(); void CreateChannelList(int*); bool ChannelInGroup(const cChannel*); }; // --- cChannelGroups -------------------------------------------------------- class cChannelGroups : public cConfig { private: public: cChannelGroups(void) {} ~cChannelGroups(void) {} int GetIndex(char* channelGroup); cChannelGroup* GetGroupByName(const char* channelGroup); cSearchExt* Used(cChannelGroup*); char** CreateMenuitemsList(); }; extern cChannelGroups ChannelGroups; // --- cMenuChannelGroupItem ---------------------------------------------------------- class cMenuChannelGroupItem : public cOsdItem { private: public: cChannelGroup* group; cMenuChannelGroupItem(cChannelGroup*); void Set(void); }; // --- cMenuChannelGroups -------------------------------------------------------- class cMenuChannelGroups : public cOsdMenu { private: cChannelGroup *CurrentGroup(void); eOSState New(void); eOSState Delete(void); int groupSel; char** groupName; protected: virtual eOSState ProcessKey(eKeys Key); public: cMenuChannelGroups(char** groupName = NULL); }; // --- cMenuEditChannelGroup -------------------------------------------------------- class cMenuEditChannelGroup : public cOsdMenu { private: cChannelGroup *group; bool addIfConfirmed; char name[MaxFileName]; int* channelSel; public: cMenuEditChannelGroup(cChannelGroup *group, bool New = false); ~cMenuEditChannelGroup(); void Set(); virtual eOSState ProcessKey(eKeys Key); }; #endif vdr-plugin-epgsearch-2.4.1/conf/000077500000000000000000000000001405273211300164675ustar00rootroot00000000000000vdr-plugin-epgsearch-2.4.1/conf/epgsearchcats.conf-epgdata000066400000000000000000000043161405273211300235610ustar00rootroot00000000000000# ----------------------------------------------------------------------------- # This is just a template based on your current epg.data. Please edit! # Perhaps a category or its value list should be removed. Also the # 'name in menu' should be adjusted to your language. # The order of items determines the order listed in epgsearch. It does not # depend on the ID, which is used by epgsearch. # Format: # ID|category name|name in menu|values separated by ',' (option)|searchmode (option) # - 'ID' should be a unique positive integer # (changing the id later on will force you to reedit your search timers!) # - 'category name' is the name in your epg.data # - 'name in menu' is the name displayed in epgsearch. # - 'values' is an optional list of possible values # - 'searchmode' is an optional parameter specifying the mode of search: # text comparison: # 0 - the whole term must appear as substring # 1 - all single words (delimiters are ',', ';', '|' or '~') # must exist as substrings. This is the default search mode. # 2 - at least one word (delimiters are ',', ';', '|' or '~') # must exist as substring. # 3 - matches exactly # 4 - regular expression # numerical comparison: # 10 - less # 11 - less or equal # 12 - greater # 13 - greater or equal # 14 - equal # 15 - not equal # ----------------------------------------------------------------------------- 1|Category|Kategorie|Information,Kinder,Musik,Serie,Show,Spielfilm,Sport|3 2|Genre|Genre|Abenteuer,Action,Boxen,Comedy,Dokumentarfilm,Drama,Erotik,Familien-Show,Fantasy,Fussball,Geschichte,Gesellschaft,Gesundheit,Gymnastik,Handball,Heimat,Humor,Jazz,Kinderfilme,Kindernachrichten,Kinderserien,Klassik,Krankenhaus,Krimi,Kultur,Kurzfilm,Motor+Verkehr,Motorsport,Musik,Mystery,Nachrichten,Natur,Politik,Radsport,Ratgeber,Reise,Rock,Romantik/Liebe,Science Fiction,Soap,Spielshows,Talkshows,Tennis,Thriller,Verschiedenes,Volksmusik,Wassersport,Western,Wintersport,Wirtschaft,Wissen,Zeichentrick|2 3|Format|Video-Format|16:9,4:3|2 4|Audio|Audio|Dolby Surround,Stereo|2 5|Year|Jahr||0 6|Cast|Besetzung||2 7|Director|Regisseur||2 8|Moderation|Moderation||2 9|Rating|Bewertung|Tagestip,Tip|2 10|FSK|FSK|6,12,16,18|2 vdr-plugin-epgsearch-2.4.1/conf/epgsearchcats.conf-tvm2vdr-hoerzu000066400000000000000000000047011405273211300250700ustar00rootroot00000000000000# ----------------------------------------------------------------------------- # This is just a template based on your current epg.data. Please edit! # Perhaps a category or its value list should be removed. Also the # 'name in menu' should be adjusted to your language. # The order of items determines the order listed in epgsearch. It does not # depend on the ID, which is used by epgsearch. # Format: # ID|category name|name in menu|values separated by ',' (option)|searchmode (option) # - 'ID' should be a unique positive integer # (changing the id later on will force you to reedit your search timers!) # - 'category name' is the name in your epg.data # - 'name in menu' is the name displayed in epgsearch. # - 'values' is an optional list of possible values # - 'searchmode' is an optional parameter specifying the mode of search: # text comparison: # 0 - the whole term must appear as substring # 1 - all single words (delimiters are ',', ';', '|' or '~') # must exist as substrings. This is the default search mode. # 2 - at least one word (delimiters are ',', ';', '|' or '~') # must exist as substring. # 3 - matches exactly # 4 - regular expression # numerical comparison: # 10 - less # 11 - less or equal # 12 - greater # 13 - greater or equal # 14 - equal # 15 - not equal # ----------------------------------------------------------------------------- 1|Category|Kategorie|Information,Kinder,Musik,Serie,Show,Spielfilm,Sport|3 2|Genre|Genre|Abenteuer,Action,Boxen,Comedy,Dokumentarfilm,Drama,Erotik,Familien-Show,Fantasy,Fussball,Geschichte,Gesellschaft,Gesundheit,Gymnastik,Handball,Heimat,Humor,Jazz,Kinderfilme,Kindernachrichten,Kinderserien,Klassik,Krankenhaus,Krimi,Kultur,Kurzfilm,Motor+Verkehr,Motorsport,Musik,Mystery,Nachrichten,Natur,Politik,Radsport,Ratgeber,Reise,Rock,Romantik/Liebe,Science Fiction,Soap,Spielshows,Talkshows,Tennis,Thriller,Verschiedenes,Volksmusik,Wassersport,Western,Wintersport,Wirtschaft,Wissen,Zeichentrick|2 3|Format|Video-Format|16:9,4:3|2 4|Audio|Audio|Dolby Surround,Dolby,Hoerfilm,Stereo|2 5|Year|Jahr||0 6|Cast|Besetzung||2 7|Director|Regisseur||2 8|Moderation|Moderation||2 9|Rating|Bewertung|Groartig besonders wertvoll,Groartig wertvoll,Groartig,Gelungen besonders wertvoll,Gelungen wertvoll,Gelungen,Annehmbar besonders wertvoll,Annehmbar wertvoll,besonders wertvoll,Annehmbar,Schwach|3 10|FSK|FSK|6,12,16,18|3 11|Country|Land||0 12|Episode|Episode||0 vdr-plugin-epgsearch-2.4.1/conf/epgsearchcats.conf-tvm2vdr-tvmovie000066400000000000000000000102001405273211300252340ustar00rootroot00000000000000# ----------------------------------------------------------------------------- # This is just a template based on your current epg.data. Please edit! # Perhaps a category or its value list should be removed. Also the # 'name in menu' should be adjusted to your language. # The order of items determines the order listed in epgsearch. It does not # depend on the ID, which is used by epgsearch. # Format: # ID|category name|name in menu|values separated by ',' (option)|searchmode (option) # - 'ID' should be a unique positive integer # (changing the id later on will force you to reedit your search timers!) # - 'category name' is the name in your epg.data # - 'name in menu' is the name displayed in epgsearch. # - 'values' is an optional list of possible values # - 'searchmode' is an optional parameter specifying the mode of search: # text comparison: # 0 - the whole term must appear as substring # 1 - all single words (delimiters are ',', ';', '|' or '~') # must exist as substrings. This is the default search mode. # 2 - at least one word (delimiters are ',', ';', '|' or '~') # must exist as substring. # 3 - matches exactly # 4 - regular expression # numerical comparison: # 10 - less # 11 - less or equal # 12 - greater # 13 - greater or equal # 14 - equal # 15 - not equal # ----------------------------------------------------------------------------- 1|Category|Category|Film,Kultur,Serie,Show,Spielfilm,Sport|2 2|Genre|Genre|Abenteuer,Abenteuerkomdie,Action,Actiondrama,Action-Fantasy,Actionkomdie,Actionkrimi,Actionthriller,Animations,Anime,Ansprache,Arzt,Auslandsmagazin,Auslandsreportage,Automagazin,Ballett,Bericht,Bibelverfilmung,Bildungsprogramm,Biographie,Boulevardmagazin,Boxen,Bchermagazin,Brgersendung,Chart,Chronik,Clip,Clips,Comedy,Daily Soap,Dauerwerbesendung,Detektiv,Diskussion,Doku,Dokudrama,Doku-Drama,Dokumentar,Dokumentation,Doku-Soap,Drama,Dramedy,Ehedrama,Ehekomdie,Erotik,Erotikthriller,Familien,Familienchronik,Familiendrama,Familienkomdie,Fantasy,Fantasyabenteuer,Fantasykomdie,Fernseh,Festakt,Frauenmagazin,Frhmagazin,Fuball,Gala,Gehrlosenmagazin,Gerichts,Gesellschaftsdrama,Gesellschaftskomdie,Gesellschaftssatire,Gesprch,Gesundheitsmagazin,Gottesdienst,Groteske,Gruselkomdie,Heimat,Heimatmelodram,Historien,Historiendrama,Horror,Horrorkomdie,Horrorthriller,Impressionen,Informationen,Interview,Jazz,Jugend,Jugenddrama,Jugendmagazin,Jugendmemoiren,Justizdrama,Kabarett,Kammermusik,Katastrophen,Kinder,Kinderabenteuer,Kinder<80><94>Magazin,Kinderkomdie,Kinderkrimi,Kindermagazin,Kinder-Magazin,Kinomagazin,Klassik,Koch,Komdie,Konzert,Kriegs,Kriegsdrama,Krimi,Krimiabenteuer,Krimidrama,Krimikomdie,Kriminalmagazin,Kriminal-Magazin,Kulinarisches,Kulturmagazin,Kurz,Liebes,Liebeskomdie,Lifestylemagazin,Literaturverfilmung,Lotterie,Lustspiel,Magazin,Mrchen,Medienmagazin,Melodram,Militrsatire,Mittagsmagazin,Motorsport,Musical,Musicalverfilmung,Musik,Musikkomdie,Musikmagazin,Mystery,Mythen-Doku,Nachrichten,Nachrichtenmagazin,Naturdokumentation,nn,kokrimi,Oper,Politdrama,Politmagazin,Polit-Report,Politthriller,Polizei,Portrt,Prsentation,Predigt,Preisverleihung,Programminformation,Psychothriller,Puppen,Puppentrick,Quiz,Ratgeber,Reisedokumentation,Reisemagazin,Reisereportage,Reitsport,Religion,Reportage,Rock,Romanze,Sammelsendung,Satire,Satiremagazin,Schwank,schwarze Komdie,Science-fiction,Science-fiction-Film,Science-Fiction-Horror,Science-fiction-Komdie,Sitcom,Sitzung,Sketch,Slapstickkomdie,Sonstiges,Spiel,Sport,Sportmagazin,Sportsendung,Sprachkurs,Talk,Teenagerkomdie,Telenovela,Tennis,Theater,Thriller,Tier,Tier-doku,Tierdokumentation,Tiermagazin,Tragikomdie,Trick,Turnen,Umzug,Unterhaltung,Unterhaltungs,Unterhaltungsmusik,Verkaufs,Verkehrsmagazin,Volksmusik,Volkstheater,Vortrag,Weltmusik,Werbung,Western,Westerndrama,Wetter,Wirtschaftsmagazin,Wissenschaftsmagazin,Wochenmagazin,Zeichentrick,Zusammenfassung|2 3|Format|Format|4:3,16:9|3 4|Audio|Audio|Dolby,DolbyDigital, - O-Ton,Stereo,Stereo - O-Ton,Surround,Zweikanal|3 5|Year|Jahr||0 6|Cast|Darsteller||2 7|Director|Regisseur||2 8|Rating|Bewertung|TagesTipp,Tipp,TopTipp|2 9|FSK|FSK|3,4,5,6,7,8,9,12,16,18|3 vdr-plugin-epgsearch-2.4.1/conf/epgsearchconflmail.templ000066400000000000000000000043731405273211300233670ustar00rootroot00000000000000######################################################################### # This is a sample template for email notifications about timer conflicts. # # There are 4 sections to be defined: # - "subject" to be used as mail subject # - "mailbody" the body of the mail (put %conflicts% in the place where the # list of conflicts should appear!) # - "conflictsat" the description of one time where one or more conflicts # exists (put %confltimers% in the place where the list of conflict # timers should appear!) # - "confltimer" the description of one conflicting timer # # close each section with the correspondig end tag! ######################################################################### ######################################################################### # here's the subject definition (no CR!) ######################################################################### [epgsearch] timer conflict info: %conflict.count% conflicting timers! ######################################################################### # here's the body definition ######################################################################### information about conflicting timers ---------------------------------------------------------------------- check at: %datenow% %timenow% conflicts: %conflict.count% ---------------------------------------------------------------------- %conflict.conflicts% Have fun! ######################################################################### # here's the conflictsat definition ######################################################################### the following timers have a conflict at: %conflict.date% %conflict.time% %conflict.confltimers% ######################################################################### # here's the definition of a conflict timer ######################################################################### Title: %title% ~ %subtitle% Start/End: %time_w% %date% %time%-%timeend% (Timer: %timer.start%-%timer.stop%) Channel: %chlng% (%chnr%) File: %timer.file% Search: %timer.search% (%timer.searchid%) ---------------------------------------------------------------------- vdr-plugin-epgsearch-2.4.1/conf/epgsearchmenu.conf000066400000000000000000000030331405273211300221630ustar00rootroot00000000000000######################################################### # sample file for epgsearchmenu.conf # # The following variables exist: # # %time% - start time in format HH:MM # %date% - start date in format TT.MM.YY # %datesh% - start date in format TT.MM. # %time_w% - weekday name # %time_d% - start day in format TT # %title% - title # %subtitle% - subtitle # %t_status% - timer status ('T', 't', 'R') # %v_status% - VPS status # %r_status% - running status # %status% - complete status, the same as # '%t_status%%v_status%%r_status%' # %colon% - the sign ':' # %% - a value from the extended EPG categories, specified in # epgsearchcats.conf, like %genre% or %category% # # for the 'Whats on...' menus there is also: # # %chnr% - channel number # %chsh% - the short channel name # %chlng% - the 'normal' channel name # %progr% - graphical progress bar # %progrT2S% - progress bar in text2skin style # ######################################################### MenuWhatsOnNow= %chnr%:4|%progrt2s%:5| %time% %t_status%:8|%category%:6| %title% ~ %subtitle%:35 MenuWhatsOnNext=%chnr%:4|%time% %t_status%:8|%category%:8| %title% ~ %subtitle%:35 MenuWhatsOnElse=%chnr%:4|%time% %t_status%:8|%category%:8| %title% ~ %subtitle%:35 MenuSchedule=%time% %t_status%:8|%genre%:14| %title% ~ %subtitle%:35 MenuSearchResults=%chsh%:12|%datesh%:6|%time%:6|%t_status%:2|%title% ~ %subtitle%:35 # WarEagleIcons=1 vdr-plugin-epgsearch-2.4.1/conf/epgsearchupdmail-html.templ000066400000000000000000000160411405273211300240130ustar00rootroot00000000000000######################################################################### # This is a sample template for email notifications about timer changes # (NOTE: This is a sample for a HTML mail, but you could use only text # as well) # # There are 3 sections that have to be defined: # - "subject" to be used as mail subject # - "mailbody" the body of the mail: # put %update.newtimers% in the place where the list of new timers should # appear. The same for %update.modtimers%, %update.deltimers% and # %update.newevents& for the list of changed or deleted timers and event # announcements. # - "timer" the description of one timer and "event" with the description of # one event. This section is used to display one timer within a timer list, # e.g. in %update.newtimers%. The same for "event". # # All sections are optional, e.g. if you don't use event announcements you # can drop "%update.newevents%" in the mailbody and the "event" section. But # of course you should have at least a mailbody ;-) # # close each section with the correspondig end tag! # Please have a look at the MANUAL for the available variables. ######################################################################### # # Version: 0.4 Date: 20.09.2009 # # Author: Mike Constabel # Christian Wieninger # ######################################################################### ######################################################################### # here's the mail's subject definition (no CR!) ######################################################################### [epgsearch] update info: %update.countnewtimers% new / %update.countmodtimers% modified / %update.countdeltimers% deleted timers / %update.countnewevents% new events / ######################################################################### # here's the mail's body definition ######################################################################### Information about search timer update
Information about search timer update
update at:%datenow% %timenow%
new timers:%update.countnewtimers%
modified timers:%update.countmodtimers%
deleted timers:%update.countdeltimers%
new events to report:%update.countnewevents%

Top New timers
%update.newtimers%

Top Modified timers
%update.modtimers%

Top Deleted timers
%update.deltimers%

Top New events to report
%update.newevents%

Have fun!

############################################################################## # here's the timer definition, which is used to display information about # a timer within one of the timer lists. You can use any variables that refer # to an event or timer. (Please note, that a timer may have no event assigned # to it, resulting in an empty variable substitution!). You can also use 'user # defined' variables from epgsearchuservars.conf. ##############################################################################
Title:
Subtitle:%subtitle%
Start/End:%time_w% %date% %time%-%timeend% (Timer: %timer.start%-%timer.stop%)
Channel:%timer.chlng% (%timer.chnr%)
File:%timer.file%
Search:%timer.search% (%timer.searchid%)
Modification:%timer.modreason%
Summary:%htmlsummary%

############################################################################## # here's the event definition, which is used to display information about # an event in the announcement list. You can use any variables that refer # to an event. You can also use 'user defined' variables from # epgsearchuservars.conf. ##############################################################################
Title:
Subtitle:%subtitle%
Start/End:%time_w% %date% %time%-%timeend%
Channel:%chlng% (%chnr%)
Search:%search% (%searchid%)
Summary:%htmlsummary%

vdr-plugin-epgsearch-2.4.1/conf/epgsearchupdmail.templ000066400000000000000000000101771405273211300230550ustar00rootroot00000000000000######################################################################### # This is a sample template for email notifications about timer changes # and/or events announcements # (NOTE: This is a sample for a text mail, but you could use HTML as well) # # There are 3 sections that have to be defined: # - "subject" to be used as mail subject # - "mailbody" the body of the mail: # put %update.newtimers% in the place where the list of new timers should # appear. The same for %update.modtimers%, %update.deltimers% and # %update.newevents& for the list of changed or deleted timers and event # announcements. # - "timer" the description of one timer and "event" with the description of # one event. This section is used to display one timer within a timer list, # e.g. in %update.newtimers%. The same for "event". # # All sections are optional, e.g. if you don't use event announcements you # can drop "%update.newevents%" in the mailbody and the "event" section. But # of course you should have at least a mailbody ;-) # # close each section with the correspondig end tag! # Please have a look at the MANUAL for the available variables. ######################################################################### ######################################################################### # here's the mail's subject definition (no CR!) ######################################################################### [epgsearch] update info: %update.countnewtimers% new / %update.countmodtimers% modified / %update.countdeltimers% deleted timers / %update.countnewevents% new events ######################################################################### # here's the mail's body definition ######################################################################### information about search timer update ---------------------------------------------------------------------- update at: %datenow% %timenow% new timers: %update.countnewtimers% modified timers: %update.countmodtimers% deleted timers: %update.countdeltimers% new events: %update.countnewevents% the following timers have been added: ---------------------------------------------------------------------- %update.newtimers% the following timers have been modified: ---------------------------------------------------------------------- %update.modtimers% the following timers have been deleted: ---------------------------------------------------------------------- %update.deltimers% the following events where found: ---------------------------------------------------------------------- %update.newevents% Have fun! ############################################################################## # here's the timer definition, which is used to display information about # a timer within one of the timer lists. You can use any variables that refer # to an event or timer. (Please note, that a timer may have no event assigned # to it, resulting in an empty variable substitution!). You can also use 'user # defined' variables from epgsearchuservars.conf. ############################################################################## Title: %title% ~ %subtitle% Start/End: %time_w% %date% %time%-%timeend% (Timer: %timer.start%-%timer.stop%) Channel: %timer.chlng% (%timer.chnr%) File: %timer.file% Modification: %timer.modreason% Search: %timer.search% (%timer.searchid%) Summary: %summary% ---------------------------------------------------------------------- ############################################################################## # here's the event definition, which is used to display information about # an event within the list of event announcements. You can use any variables # that refer to an event. You can also use 'user defined' variables from # epgsearchuservars.conf. ############################################################################## Title: %title% ~ %subtitle% Start/End: %time_w% %date% %time%-%timeend% Channel: %chlng% (%chnr%) Search: %search% (%searchid%) Summary: %summary% ---------------------------------------------------------------------- vdr-plugin-epgsearch-2.4.1/confdloader.c000066400000000000000000000111761405273211300201740ustar00rootroot00000000000000/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #include #include #include "confdloader.h" #include "log.h" #include "uservars.h" #include "menu_dirselect.h" #include "templatefile.h" #include "epgsearchcats.h" using std::string; // --------------------------- // Loads all files in the conf.d subdirectory of and // applies found settings. // --------------------------- bool cConfDLoader::Load() { const string dirPath(AddDirectory(CONFIGDIR, "conf.d")); LogFile.Log(2, "loading entries in %s", dirPath.c_str()); cReadDir d(dirPath.c_str()); struct dirent* e; string parent(".."); string current("."); int count = 0; bool success = true; while ((e = d.Next())) { string direntry = e->d_name; if ((current == direntry) || (parent == direntry) || (direntry[direntry.size() - 1] == '~')) { continue; } /* Check if entry is a directory: I do not rely on e->d_type here because on some systems it is always DT_UNKNOWN. Also testing for DT_DIR does not take into account symbolic links to directories. */ struct stat buf; if ((stat((dirPath + "/" + e->d_name).c_str(), &buf) != 0) || (S_ISDIR(buf.st_mode))) { continue; } success &= LoadFile((dirPath + "/" + e->d_name).c_str()); count++; } LogFile.Log(2, "loaded %d entries in %s", count, dirPath.c_str()); return success; } // --------------------------- // Each file has the form // // [
] // // ... // [
] // ... // // where section is one: // // epgsearchuservars // epgsearchdirs // epgsearchmenu // epgsearchcats // // corresponds to the entries in the related conf files. // --------------------------- bool cConfDLoader::LoadFile(const char *FileName) { if (FileName && access(FileName, F_OK) == 0) { LogFile.Log(1, "loading %s", FileName); FILE *f = fopen(FileName, "r"); if (f) { char *s; int line = 0; cReadLine ReadLine; std::string section; while ((s = ReadLine.Read(f)) != NULL) { line++; char *p = strchr(s, '#'); if (p) *p = 0; stripspace(s); if (!isempty(s)) { if (*s == '[' && *(s + strlen(s) - 1) == ']') // Section? section = s; else { if (EqualsNoCase(section, "[epgsearchuservars]")) cUserVarLine::Parse(s); if (EqualsNoCase(section, "[epgsearchdirs]")) { cDirExt* D = new cDirExt; if (D && D->Parse(s)) ConfDDirExts.Add(D); else delete D; } if (EqualsNoCase(section, "[epgsearchmenu]")) { cTemplLine T; if (T.Parse(s)) cTemplFile::Parse(T.Name(), T.Value()); } if (EqualsNoCase(section, "[epgsearchcats]")) { cSearchExtCat* cat = new cSearchExtCat; if (cat && cat->Parse(s)) SearchExtCats.Add(cat); else delete cat; } } } } fclose(f); } return true; } else { LOG_ERROR_STR(FileName); return false; } } vdr-plugin-epgsearch-2.4.1/confdloader.h000066400000000000000000000022601405273211300201730ustar00rootroot00000000000000/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #ifndef VDR_EPGSEARCH_CONFDLOADER_INC #define VDR_EPGSEARCH_CONFDLOADER_INC class cConfDLoader { public: cConfDLoader() {} bool Load(); bool LoadFile(const char *FileName); }; #endif vdr-plugin-epgsearch-2.4.1/conflictcheck.c000066400000000000000000001111571405273211300205130ustar00rootroot00000000000000/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #include #include #include "conflictcheck.h" #include "epgsearchcfg.h" /*#include */ #include "conflictcheck_thread.h" #include "recstatus.h" #include "timerstatus.h" #include "uservars.h" #include #define FULLMATCH 1000 #define EPGLIMITBEFORE (1 * 3600) // Time in seconds before a timer's start time and #define EPGLIMITAFTER (1 * 3600) // after its stop time within which EPG events will be taken into consideration. // --- cConflictCheckTimerObj -------------------------------------------------------- cConflictCheckTimerObj::cConflictCheckTimerObj(cTimer* Timer, time_t Start, time_t Stop, int Device, int OrigIndex) : cTimerObj(Timer), start(Start), stop(Stop), device(Device), origIndex(OrigIndex), conflCheckTime(NULL), concurrentTimers(NULL), ignore(false) { event = Timer->Event(); recDuration = 0; lastRecStart = 0; lastRecStop = 0; } cConflictCheckTimerObj::~cConflictCheckTimerObj() { // conflict checks works on a copy of a timer, so delete it again DELETENULL(timer); } int cConflictCheckTimerObj::Compare(const cListObject &ListObject) const { cConflictCheckTimerObj *p = (cConflictCheckTimerObj *)&ListObject; long diff = start - p->start; if (diff == 0) diff = p->timer->Priority() - timer->Priority(); if (diff == 0) diff = origIndex - p->origIndex; return diff; } const cEvent* cConflictCheckTimerObj::Event() { if (timer->Event()) return timer->Event(); else if (!event) event = SetEventFromSchedule(); return event; } const cEvent* cConflictCheckTimerObj::SetEventFromSchedule() { LOCK_SCHEDULES_READ; if (!Schedules) return NULL; const cSchedule *Schedule = Schedules->GetSchedule(timer->Channel()); if (Schedule && Schedule->Events()->First()) { const cEvent *Event = NULL; if (timer->HasFlags(tfVps) && Schedule->Events()->First()->Vps()) { // VPS timers only match if their start time exactly matches the event's VPS time: for (const cEvent *e = Schedule->Events()->First(); e; e = Schedule->Events()->Next(e)) { if (e->StartTime() && e->RunningStatus() != SI::RunningStatusNotRunning) { // skip outdated events int overlap = 0; Matches(e, &overlap); if (overlap > FULLMATCH) { Event = e; break; // take the first matching event } } } } else { // Normal timers match the event they have the most overlap with: int Overlap = 0; // Set up the time frame within which to check events: timer->Matches(0, true); time_t TimeFrameBegin = start - EPGLIMITBEFORE; time_t TimeFrameEnd = stop + EPGLIMITAFTER; for (const cEvent *e = Schedule->Events()->First(); e; e = Schedule->Events()->Next(e)) { if (e->EndTime() < TimeFrameBegin) continue; // skip events way before the timer starts if (e->StartTime() > TimeFrameEnd) break; // the rest is way after the timer ends int overlap = 0; Matches(e, &overlap); if (overlap && overlap >= Overlap) { if (Event && overlap == Overlap && e->Duration() <= Event->Duration()) continue; // if overlap is the same, we take the longer event Overlap = overlap; Event = e; } } } return Event; } return NULL; } int cConflictCheckTimerObj::Matches(const cEvent *Event, int *Overlap) const { // Overlap is the percentage of the Event's duration that is covered by // this timer (based on FULLMATCH for finer granularity than just 100). // To make sure a VPS timer can be distinguished from a plain 100% overlap, // it gets an additional 100 added, and a VPS event that is actually running // gets 200 added to the FULLMATCH. if (timer->Channel()->GetChannelID() == Event->ChannelID()) { bool UseVps = timer->HasFlags(tfVps) && Event->Vps(); timer->Matches(UseVps ? Event->Vps() : Event->StartTime(), true); int overlap = 0; if (UseVps) overlap = (start == Event->Vps()) ? FULLMATCH + (Event->IsRunning() ? 200 : 100) : 0; if (!overlap) { if (start <= Event->StartTime() && Event->EndTime() <= stop) overlap = FULLMATCH; else if (stop <= Event->StartTime() || Event->EndTime() <= start) overlap = 0; else overlap = (std::min(stop, Event->EndTime()) - std::max(start, Event->StartTime())) * FULLMATCH / std::max(Event->Duration(), 1); } if (Overlap) *Overlap = overlap; if (UseVps) return overlap > FULLMATCH ? tmFull : tmNone; return overlap >= FULLMATCH ? tmFull : overlap > 0 ? tmPartial : tmNone; } return tmNone; } // --- cConflictCheck ------------------------------------------------------- cConflictCheck::cConflictCheck() { evaltimeList = NULL; timerList = NULL; failedList = NULL; relevantConflicts = 0; numConflicts = 0; devices = NULL; localConflicts = !(EPGSearchConfig.RemoteConflictCheck && Setup.SVDRPPeering); InitDevicesInfo(); } cConflictCheck::~cConflictCheck() { if (failedList && (failedList != evaltimeList)) { // if no local active timers but remote failed // we have a new list failedList->Clear(); DELETENULL(failedList); } if (evaltimeList) { evaltimeList->Clear(); DELETENULL(evaltimeList); } if (timerList) { timerList->Clear(); DELETENULL(timerList); } if (devices) delete [] devices; } void cConflictCheck::InitDevicesInfo() { if (devices) delete [] devices; devices = new cConflictCheckDevice[MAXDEVICES]; #ifdef DEBUG_CONFL numDevices = 4; for (int i = 0; i < numDevices; i++) { devices[i].devicenr = i; devices[i].device = NULL; } #else numDevices = cDevice::NumDevices(); for (int i = 0; i < numDevices; i++) devices[i].device = cDevice::GetDevice(i); #endif BondDevices(Setup.DeviceBondings); } void cConflictCheck::BondDevices(const char *Bondings) { LogFile.Log(3, "Bond Devices"); if (Bondings) { cSatCableNumbers SatCableNumbers(MAXDEVICES, Bondings); int* array = SatCableNumbers.Array(); for (int i = 0; i < SatCableNumbers.Size(); i++) { for (int j = 0; j < SatCableNumbers.Size(); j++) { if (array[i] > 0 && array[i] == array[j] && i != j) { LogFile.Log(3, "Bond devices %i and %i.", i + 1, j + 1); devices[i].bondedDevices.push_back(&(devices[j])); } } } } LogFile.Log(3, "Bond Devices done."); } void cConflictCheck::Check() { if (failedList && (failedList != evaltimeList)) DELETENULL(failedList); if (evaltimeList) DELETENULL(evaltimeList); if (timerList) DELETENULL(timerList); relevantConflicts = 0; numConflicts = 0; LogFile.Log(3, "check only local conflicts = %s", GetLocal() ? "yes" : "no"); timerList = CreateCurrentTimerList(); if (timerList) evaltimeList = CreateEvaluationTimeList(timerList); if (evaltimeList) failedList = CreateConflictList(evaltimeList, timerList); if ((!localConflicts) && timerList) failedList = CreateRemoteConflictList(timerList, failedList); if (failedList) for (cConflictCheckTime* checkTime = failedList->First(); checkTime; checkTime = failedList->Next(checkTime)) { LogFile.Log(2, "result of conflict check for %s:", DAYDATETIME(checkTime->evaltime)); std::set::iterator it; for (it = checkTime->failedTimers.begin(); it != checkTime->failedTimers.end(); ++it) { if (!localConflicts) LogFile.Log(2, "timer '%s' (%s, channel %s) %s%s failed", (*it)->timer->File(), DAYDATETIME((*it)->timer->StartTime()), CHANNELNAME((*it)->timer->Channel()), (*it)->timer->Remote() ? "@" : "", (*it)->timer->Remote() ? (*it)->timer->Remote() : ""); else LogFile.Log(2, "timer '%s' (%s, channel %s) failed", (*it)->timer->File(), DAYDATETIME((*it)->timer->StartTime()), CHANNELNAME((*it)->timer->Channel())); } } if (numConflicts > 0 && gl_timerStatusMonitor) gl_timerStatusMonitor->SetConflictCheckAdvised(); } cList* cConflictCheck::CreateCurrentTimerList() { LogFile.Log(3, "current timer list creation started"); cList* CurrentTimerList = NULL; // collect single event timers time_t tMax = 0; LOCK_TIMERS_READ; const cTimer* ti = NULL; for (ti = Timers->First(); ti; ti = Timers->Next(ti)) { tMax = std::max(tMax, ti->StartTime()); if (localConflicts && ti->Remote()) continue; if (!ti->IsSingleEvent()) continue; // already recording? int deviceNr = -1; if (ti->Local()) // we check devices only for local timers deviceNr = gl_recStatusMonitor->TimerRecDevice(ti) - 1; // create a copy of this timer cTimer* clone = new cTimer(*ti); clone->SetEvent(ti->Event()); cConflictCheckTimerObj* timerObj = new cConflictCheckTimerObj(clone, ti->StartTime(), ti->StopTime(), deviceNr, ti->Id()); if (deviceNr >= 0) { devices[deviceNr].recTimers.insert(timerObj); timerObj->lastRecStart = ti->StartTime(); } LogFile.Log(3, "add timer '%s' (%s, channel %s) for conflict check", ti->File(), DAYDATETIME(ti->StartTime()), CHANNELNAME(ti->Channel())); if (deviceNr >= 0) LogFile.Log(3, "timer already recording since %s on device %d", DAYDATETIME(ti->StartTime()), deviceNr + 1); if (!CurrentTimerList) CurrentTimerList = new cList; CurrentTimerList->Add(timerObj); } // collect repeating timers from now until the date of the timer with tMax time_t maxCheck = time(NULL) + std::min(14, EPGSearchConfig.checkMaxDays) * SECSINDAY; tMax = std::max(tMax, maxCheck); for (ti = Timers->First(); ti; ti = Timers->Next(ti)) { if (ti->IsSingleEvent()) continue; if (localConflicts && ti->Remote()) continue; //JF??? time_t day = time(NULL); while (day < tMax) { if (ti->DayMatches(day)) { time_t Start = cTimer::SetTime(day, cTimer::TimeToInt(ti->Start())); int deviceNr = -1; if (Start < time(NULL)) { #ifndef DEBUG_CONFL if (ti->Local() && ti->Recording()) deviceNr = gl_recStatusMonitor->TimerRecDevice(ti) - 1; #else if (Start + ti->StopTime() - ti->StartTime() > time(NULL)) deviceNr = 0; #endif if (deviceNr == -1) { // currently not recording, skip it day += SECSINDAY; continue; } } else if (Start < ti->StartTime()) { day += SECSINDAY; continue; } // create a copy of this timer cTimer* clone = new cTimer(*ti); clone->SetEvent(ti->Event()); cConflictCheckTimerObj* timerObj = new cConflictCheckTimerObj(clone, Start, Start + ti->StopTime() - ti->StartTime(), deviceNr, ti->Id()); LogFile.Log(3, "add timer '%s' (%s, channel %s) for conflict check", ti->File(), DAYDATETIME(Start), CHANNELNAME(ti->Channel())); if (deviceNr >= 0) { LogFile.Log(3, "timer already recording since %s on device %d", DAYDATETIME(Start), deviceNr + 1); devices[deviceNr].recTimers.insert(timerObj); timerObj->lastRecStart = Start; } if (!CurrentTimerList) CurrentTimerList = new cList; CurrentTimerList->Add(timerObj); } day += SECSINDAY; } } if (CurrentTimerList) CurrentTimerList->Sort(); LogFile.Log(3, "current timer list created"); return CurrentTimerList; } // create a list of all times that have to be checked cList* cConflictCheck::CreateEvaluationTimeList(cList* TimerList) { LogFile.Log(3, "create check time list"); cList* EvalTimeList = NULL; for (cConflictCheckTimerObj* TimerObj = TimerList->First(); TimerObj; TimerObj = TimerList->Next(TimerObj)) { if (!TimerObj->timer->HasFlags(tfActive)) continue; if (TimerObj->timer->Remote()) continue; // here we check local timers only if (!EvalTimeList) EvalTimeList = new cList; cConflictCheckTime* checkTime = NULL; // add all timer start times for (cConflictCheckTime* checkTimeTest = EvalTimeList->First(); checkTimeTest; checkTimeTest = EvalTimeList->Next(checkTimeTest)) { if (checkTimeTest->evaltime == TimerObj->start) { checkTime = checkTimeTest; break; } } if (!checkTime) { checkTime = new cConflictCheckTime(TimerObj->start); EvalTimeList->Add(checkTime); } checkTime->startingTimers.insert(TimerObj); // add all timer stop times checkTime = NULL; for (cConflictCheckTime* checkTimeTest = EvalTimeList->First(); checkTimeTest; checkTimeTest = EvalTimeList->Next(checkTimeTest)) { if (checkTimeTest->evaltime == TimerObj->stop) { checkTime = checkTimeTest; break; } } if (!checkTime) { checkTime = new cConflictCheckTime(TimerObj->stop); EvalTimeList->Add(checkTime); } checkTime->stoppingTimers.insert(TimerObj); } if (EvalTimeList) EvalTimeList->Sort(); LogFile.Log(3, "create check time list - done"); return EvalTimeList; } // this return a list of all conflicts cList* cConflictCheck::CreateConflictList(cList* EvalTimeList, cList* TimerList) { LogFile.Log(3, "create conflict list"); maxCheck = time(NULL) + std::min(14, EPGSearchConfig.checkMaxDays) * SECSINDAY; // check each time for (cConflictCheckTime* checkTime = EvalTimeList->First(); checkTime; checkTime = EvalTimeList->Next(checkTime)) { int Conflicts = ProcessCheckTime(checkTime); if (Conflicts > 0) { // if there were conflicts do a retry as VDR would do a few seconds after the conflict LogFile.Log(3, "retry check time %s", DAYDATETIME(checkTime->evaltime)); int OldConflicts = Conflicts; while (true) { Conflicts = ProcessCheckTime(checkTime); if (Conflicts == OldConflicts) break; // no change after retry? OldConflicts = Conflicts; }; } } nextRelevantConflictDate = 0; for (cConflictCheckTime* checkTime = EvalTimeList->First(); checkTime;) { // clear the list cConflictCheckTime* checkTimeNext = EvalTimeList->Next(checkTime); if (checkTime->failedTimers.empty()) EvalTimeList->Del(checkTime); else { bool allTimersIgnored = true; std::set::iterator it; for (it = checkTime->failedTimers.begin(); it != checkTime->failedTimers.end(); ++it) { numConflicts++; if (!(*it)->ignore) { if (!nextRelevantConflictDate) nextRelevantConflictDate = checkTime->evaltime; else nextRelevantConflictDate = std::min(nextRelevantConflictDate, checkTime->evaltime); relevantConflicts++; allTimersIgnored = false; break; } } if (allTimersIgnored) checkTime->ignore = true; } checkTime = checkTimeNext; } // store for external access cConflictCheckThread::m_cacheNextConflict = nextRelevantConflictDate; cConflictCheckThread::m_cacheRelevantConflicts = relevantConflicts; cConflictCheckThread::m_cacheTotalConflicts = numConflicts; LogFile.Log(3, "create conflict list - done"); return EvalTimeList; } cList* cConflictCheck::CreateRemoteConflictList(cList* TimerList, cList* failedList) { LogFile.Log(3, "add remote conflicts to list"); bool foundRemote = false; cStringList RemoteHosts; // check if we have any Remote timers RemoteHosts.Clear(); for (cConflictCheckTimerObj* TimerObj = TimerList->First(); TimerObj; TimerObj = TimerList->Next(TimerObj)) { if (!TimerObj->timer->HasFlags(tfActive)) continue; if (TimerObj->timer->Remote()) { if (RemoteHosts.Find(TimerObj->timer->Remote()) < 0) { foundRemote = true; RemoteHosts.Append(strdup(TimerObj->timer->Remote())); } } } if (!foundRemote) { LogFile.Log(3, "no remote timers to add"); return failedList; } RemoteHosts.Sort(); cStringList Response; // for all RemoteHosts for (int i = 0; i < RemoteHosts.Size(); i++) { Response.Clear(); if (ExecSVDRPCommand(RemoteHosts[i], "PLUG epgsearch LSCC REL", &Response)) { for (int j = 0; j < Response.Size(); j++) { const char *s = Response[j]; int Code = SVDRPCode(s); if (Code == 901) { LogFile.Log(3, "conflictcheck %s no remote conflicts found", RemoteHosts[i]); continue; } else if (Code != 900) { LogFile.Log(2, "Invalid remote response %d %s", Code, SVDRPValue(s)); break; } else if (const char* line = SVDRPValue(s)) { LogFile.Log(2, "remote conflictcheck line %s", line); int Id, recPart; char rest[256]; time_t evaltime; sscanf(line, "%ld:%d|%s", &evaltime, &Id, rest); cConflictCheckTime* checkTime = new cConflictCheckTime(evaltime); if (!failedList) failedList = new cList; LogFile.Log(2, "added remote checkTime %s to failedList", DAYDATETIME(evaltime)); failedList->Add(checkTime); if (!nextRelevantConflictDate) nextRelevantConflictDate = checkTime->evaltime; else nextRelevantConflictDate = std::min(nextRelevantConflictDate, checkTime->evaltime); numConflicts++; // find TimerObj with id Id in timerList cConflictCheckTimerObj* failedTimer = NULL; bool foundfT = false; for (failedTimer = TimerList->First(); failedTimer; failedTimer = TimerList->Next(failedTimer)) { if (failedTimer->timer->Id() == Id) { foundfT = true; break; } } if (!foundfT) { LogFile.Log(2, "remote failed Timer disappeared"); continue; } LogFile.Log(2, "create remote failedTimer with Id %d", Id); failedTimer->conflCheckTime = checkTime; failedTimer->origIndex = Id; sscanf(rest, "%d|%s", &recPart, rest); failedTimer->recDuration = ((failedTimer->stop - failedTimer->start) * recPart / 100); cConflictCheckTimerObj* concurrentTimer = NULL; while (strlen(rest) > 0) { int n = sscanf(rest, "%d#%s", &Id, rest); if (n < 2) { if (sscanf(rest, "%d", &Id) <= 0) { LogFile.Log(2, "error scanning rest of line %s", rest); break; } *rest = 0; // TODO : possible ?? } // find TimerObj itcc for with Id in timerList bool foundcT = false; for (concurrentTimer = TimerList->First(); concurrentTimer; concurrentTimer = TimerList->Next(concurrentTimer)) { if (concurrentTimer->timer->Id() == Id) { foundcT = true; break; } } if (!foundcT) { LogFile.Log(2, "remote concurrent Timer disappeared"); continue; } if (!failedTimer->concurrentTimers) failedTimer->concurrentTimers = new std::set; LogFile.Log(2, "insert remote Id %d into concurrentTimers", concurrentTimer->timer->Id()); failedTimer->concurrentTimers->insert(concurrentTimer); } // while concurrent Timers LogFile.Log(2, "insert Id %d into checkTime->failedTimers", failedTimer->timer->Id()); checkTime->failedTimers.insert(failedTimer); relevantConflicts++; } else LogFile.Log(2, "got Code %d, but no Value from %s", Code, RemoteHosts[i]); } // received response } else { LogFile.Log(2, "ExecSVDRPCommand failed for %s", RemoteHosts[i]); } } // for all RemoteHosts cConflictCheckThread::m_cacheNextConflict = nextRelevantConflictDate; cConflictCheckThread::m_cacheTotalConflicts = numConflicts; cConflictCheckThread::m_cacheRelevantConflicts = relevantConflicts; LogFile.Log(3, "add remote conflicts done"); return failedList; } // checks for conflicts at one special time int cConflictCheck::ProcessCheckTime(cConflictCheckTime* checkTime) { if (!checkTime) return 0; LogFile.Log(3, "check time %s", DAYDATETIME(checkTime->evaltime)); LogFile.Log(3, "detach stopping timers"); int Conflicts = 0; // detach all stopping timers from their devices std::set::iterator it; for (it = checkTime->stoppingTimers.begin(); it != checkTime->stoppingTimers.end(); ++it) if ((*it) && (*it)->device >= 0) { LogFile.Log(3, "detach device %d from timer '%s' (%s, channel %s) at %s", ((*it)->device) + 1, (*it)->timer->File(), DAYDATETIME((*it)->start), CHANNELNAME((*it)->timer->Channel()), DAYDATETIME(checkTime->evaltime)); devices[(*it)->device].recTimers.erase(*it); (*it)->lastRecStop = checkTime->evaltime; if ((*it)->lastRecStart > 0 && (*it)->lastRecStart < (*it)->lastRecStop) { (*it)->recDuration += (*it)->lastRecStop - (*it)->lastRecStart; (*it)->lastRecStart = 0; if (((*it)->stop - (*it)->start - (*it)->recDuration) < EPGSearchConfig.checkMinDuration * 60) (*it)->ignore = true; } } LogFile.Log(3, "add pending timers"); // if we have pending timers add them to the current start list for (it = pendingTimers.begin(); it != pendingTimers.end(); ++it) { if ((*it) && (*it)->stop > checkTime->evaltime) checkTime->startingTimers.insert(*it); } pendingTimers.clear(); LogFile.Log(3, "attach starting timers"); // handle starting timers for (it = checkTime->startingTimers.begin(); it != checkTime->startingTimers.end(); ++it) { bool NeedsDetachReceivers = false; if (!(*it) || (*it)->device >= 0) continue; // already has a device int device = GetDevice(*it, &NeedsDetachReceivers); if (device >= 0) { // device will be attached? if (NeedsDetachReceivers) { // but needs to detach all others? // disable running timers std::set::iterator it2 = devices[device].recTimers.begin(); for (; it2 != devices[device].recTimers.end(); ++it2) { LogFile.Log(3, "stopping timer '%s' (%s, channel %s) at %s on device %d because of higher priority", (*it2)->timer->File(), DAYDATETIME((*it2)->start), CHANNELNAME((*it2)->timer->Channel()), DAYDATETIME(checkTime->evaltime), device + 1); AddConflict((*it2), checkTime, pendingTimers); Conflicts++; } devices[device].recTimers.clear(); } devices[device].recTimers.insert(*it); (*it)->device = device; (*it)->lastRecStart = checkTime->evaltime; LogFile.Log(3, "recording timer '%s' (%s, channel %s) at %s on device %d", (*it)->timer->File(), DAYDATETIME((*it)->start), CHANNELNAME((*it)->timer->Channel()), DAYDATETIME(checkTime->evaltime), device + 1); } else { AddConflict((*it), checkTime, pendingTimers); Conflicts++; } } LogFile.Log(3, "check time %s - done", DAYDATETIME(checkTime->evaltime)); return Conflicts; } eModuleStatus cConflictCheck::CamSlotModuleStatus(cCamSlot *CamSlot) { if (!CamSlot) return msNone; if ((int)camSlotStatusArray.size() != CamSlots.Count()) for (cCamSlot *CamSlot = CamSlots.First(); CamSlot; CamSlot = CamSlots.Next(CamSlot)) camSlotStatusArray.push_back(CamSlot->ModuleStatus()); if (CamSlot->Index() < (int)camSlotStatusArray.size()) return camSlotStatusArray[CamSlot->Index()]; else return msNone; } int cConflictCheck::GetDevice(cConflictCheckTimerObj* TimerObj, bool* NeedsDetachReceivers) { int Priority = TimerObj->timer->Priority(); const cChannel* Channel = TimerObj->timer->Channel(); // Collect the current priorities of all CAM slots that can decrypt the channel: int selDevice = -1; int NumCamSlots = CamSlots.Count(); int SlotPriority[NumCamSlots]; int NumUsableSlots = 0; bool InternalCamNeeded = false; if (Channel->Ca() >= CA_ENCRYPTED_MIN) { for (cCamSlot *CamSlot = CamSlots.First(); CamSlot; CamSlot = CamSlots.Next(CamSlot)) { SlotPriority[CamSlot->Index()] = MAXPRIORITY + 1; // assumes it can't be used if (CamSlotModuleStatus(CamSlot) == msReady) { if (CamSlot->ProvidesCa(Channel->Caids())) { if (!ChannelCamRelations.CamChecked(Channel->GetChannelID(), CamSlot->MasterSlotNumber())) { SlotPriority[CamSlot->Index()] = CamSlot->Priority(); NumUsableSlots++; } } } } #ifdef CFLC int NumUsableSlots = 1; #endif if (!NumUsableSlots) InternalCamNeeded = true; // no CAM is able to decrypt this channel } if (NeedsDetachReceivers) *NeedsDetachReceivers = false; uint32_t Impact = 0xFFFFFFFF; // we're looking for a device with the least impact for (int j = 0; j < NumCamSlots || !NumUsableSlots; j++) { if (NumUsableSlots && SlotPriority[j] > MAXPRIORITY) continue; // there is no CAM available in this slot for (int i = 0; i < numDevices; i++) { if (Channel->Ca() && Channel->Ca() <= CA_DVB_MAX && Channel->Ca() != devices[i].CardIndex() + 1) continue; // a specific card was requested, but not this one bool HasInternalCam = devices[i].HasInternalCam(); if (InternalCamNeeded && !HasInternalCam) continue; // no CAM is able to decrypt this channel and the device uses vdr handled CAMs if (NumUsableSlots && !HasInternalCam && !CamSlots.Get(j)->Assign(devices[i].device, true)) continue; // CAM slot can't be used with this device bool ndr; if (devices[i].ProvidesChannel(Channel, Priority, &ndr)) { // this device is basically able to do the job if (NumUsableSlots && !HasInternalCam && devices[i].CamSlot() && devices[i].CamSlot() != CamSlots.Get(j)) ndr = true; // using a different CAM slot requires detaching receivers // Put together an integer number that reflects the "impact" using // this device would have on the overall system. Each condition is represented // by one bit in the number (or several bits, if the condition is actually // a numeric value). The sequence in which the conditions are listed corresponds // to their individual severity, where the one listed first will make the most // difference, because it results in the most significant bit of the result. uint32_t imp = 0; // prefer the primary device for live viewing if we don't need to detach existing receivers imp <<= 1; ; // use receiving devices if we don't need to detach existing receivers imp <<= 1; imp |= !devices[i].Receiving() || ndr; // avoid devices that are receiving imp <<= 1; imp |= devices[i].Receiving(); // do we have GetClippedNumProvidedSystems ??? uses MaxNumProvidedSystems in vdr since V1.7 !! // but should not be needed imp <<= 2; imp |= devices[i].NumProvidedSystems(); // avoid cards which support multiple delivery systems // imp <<= 2; // imp |= GetClippedNumProvidedSystems(2, device[i]) - 1; // avoid cards which support multiple delivery systems // use the device with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used) imp <<= 8; imp |= std::min(std::max(devices[i].Priority() + MAXPRIORITY, 0), 0xFF); // use the CAM slot with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used) imp <<= 8; imp |= std::min(std::max((NumUsableSlots ? SlotPriority[j] : 0) + MAXPRIORITY, 0), 0xFF); // avoid devices if we need to detach existing receivers imp <<= 1; imp |= ndr; // avoid the primary device imp <<= 1; imp |= devices[i].IsPrimaryDevice(); // avoid cards with Common Interface for FTA channels imp <<= 1; imp |= (NumUsableSlots || InternalCamNeeded) ? 0 : devices[i].HasCi(); // avoid full featured cards imp <<= 1; imp |= devices[i].HasDecoder(); // prefer CAMs that are known to decrypt this channel imp <<= 1; imp |= (NumUsableSlots && !HasInternalCam) ? !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), CamSlots.Get(j)->MasterSlotNumber()) : 0; if (imp < Impact) { // This device has less impact than any previous one, so we take it. Impact = imp; selDevice = i; if (NeedsDetachReceivers) *NeedsDetachReceivers = ndr; } } } if (!NumUsableSlots) break; // no CAM necessary, so just one loop over the devices } return selDevice; } void cConflictCheck::AddConflict(cConflictCheckTimerObj* TimerObj, cConflictCheckTime* CheckTime, std::set& pendingTimers) { for (cConflictCheckTimerObj* concTimer = timerList->First(); concTimer; concTimer = timerList->Next(concTimer)) { if (concTimer->timer->Remote()) continue; // ignore overlapping remote timers if (concTimer->start >= TimerObj->stop) continue; if (concTimer->stop <= TimerObj->start) continue; if (!TimerObj->concurrentTimers) TimerObj->concurrentTimers = new std::set; TimerObj->concurrentTimers->insert(concTimer); } TimerObj->ignore = (TimerObj->timer->Priority() < EPGSearchConfig.checkMinPriority) || TimerObj->start > maxCheck; CheckTime->concurrentRecs.insert(TimerObj); pendingTimers.insert(TimerObj); TimerObj->lastRecStop = CheckTime->evaltime; if (TimerObj->lastRecStart > 0 && TimerObj->lastRecStart < TimerObj->lastRecStop) { TimerObj->recDuration += TimerObj->lastRecStop - TimerObj->lastRecStart; TimerObj->lastRecStart = 0; if ((TimerObj->stop - TimerObj->start - TimerObj->recDuration) < EPGSearchConfig.checkMinDuration * 60) TimerObj->ignore = true; } TimerObj->device = -1; if (!TimerObj->conflCheckTime) TimerObj->conflCheckTime = CheckTime; else return; CheckTime->failedTimers.insert(TimerObj); LogFile.Log(3, "conflict found for timer '%s' (%s, channel %s)", TimerObj->timer->File(), DAYDATETIME(TimerObj->start), CHANNELNAME(TimerObj->timer->Channel())); } bool cConflictCheck::TimerInConflict(const cTimer* timer) { if (!failedList) return false; for (cConflictCheckTime* checkTime = failedList->First(); checkTime; checkTime = failedList->Next(checkTime)) { std::set::iterator it; for (it = checkTime->failedTimers.begin(); it != checkTime->failedTimers.end(); ++it) { if (!(*it)->ignore) { std::set::iterator it2; if ((*it)->concurrentTimers) { LOCK_TIMERS_READ; for (it2 = (*it)->concurrentTimers->begin(); it2 != (*it)->concurrentTimers->end(); ++it2) { if ((*it2)->OrigTimer(Timers) == timer) return true; } } } } } return false; } void cConflictCheck::EvaluateConflCheckCmd() { if (strlen(EPGSearchConfig.conflCheckCmd) > 0) { LogFile.Log(2, "evaluating conflict check command '%s'", EPGSearchConfig.conflCheckCmd); for (cConflictCheckTime* ct = failedList->First(); ct; ct = failedList->Next(ct)) { if (ct->ignore) continue; std::set::iterator it; for (it = ct->failedTimers.begin(); it != ct->failedTimers.end(); ++it) if ((*it) && !(*it)->ignore) { string result = EPGSearchConfig.conflCheckCmd; LOCK_TIMERS_READ; if (!(*it)->OrigTimer(Timers)) { LogFile.Log(3, "timer has disappeared meanwhile"); continue; } else LogFile.Log(3, "evaluating conflict check command for timer '%s' (%s, channel %s)", (*it)->timer->File(), DAYDATETIME((*it)->start), CHANNELNAME((*it)->timer->Channel())); if ((*it)->Event()) { cVarExpr varExprEvent(result); result = varExprEvent.Evaluate((*it)->Event()); } cVarExpr varExprTimer(result); result = varExprTimer.Evaluate((*it)->timer); cVarExpr varExpr(result); varExpr.Evaluate(); } } } } vdr-plugin-epgsearch-2.4.1/conflictcheck.h000066400000000000000000000267521405273211300205260ustar00rootroot00000000000000/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #ifndef __EPGSEARCHCONFLCH_H #define __EPGSEARCHCONFLCH_H #include "epgsearchtools.h" #include #include #include #include #define DO_MULTIPLE_RECORDINGS 1 #define DO_REC_AND_PLAY_ON_PRIMARY_DEVICE 1 class cConflictCheckTime; class TimerObjSort; // --- cConflictCheckTimerObj -------------------------------------------------------- class cConflictCheckTimerObj : public cTimerObj { const cEvent* event; public: time_t start; time_t stop; int device; int origIndex; int recDuration; time_t lastRecStart; time_t lastRecStop; cConflictCheckTime* conflCheckTime; std::set* concurrentTimers; bool ignore; cConflictCheckTimerObj(cTimer* Timer, time_t Start, time_t Stop, int Device = -1, int OrigIndex = -1); ~cConflictCheckTimerObj(); int Compare(const cListObject &ListObject) const; const cEvent* Event(); const cEvent* SetEventFromSchedule(); int Matches(const cEvent *Event, int *Overlap) const; const cTimer* OrigTimer(const cTimers* timers) const { return timers->GetById(timer->Id(), timer->Remote()); } cTimer* OrigTimer(cTimers* timers) { return timers->GetById(timer->Id(), timer->Remote()); } }; class TimerObjSort { public: bool operator()(const cConflictCheckTimerObj* a, const cConflictCheckTimerObj* b) const { return (a->Compare(*b) < 0); } }; // --- cConflictCheckTime -------------------------------------------------------- class cConflictCheckTime : public cListObject { public: time_t evaltime; std::set startingTimers; std::set stoppingTimers; std::set failedTimers; std::set concurrentRecs; bool ignore; cConflictCheckTime(time_t EvalTime) : evaltime(EvalTime), ignore(false) {} int Compare(const cListObject &ListObject) const { cConflictCheckTime *p = (cConflictCheckTime *)&ListObject; return evaltime - p->evaltime; } }; // --- cConflictCheckDevice -------------------------------------------------------- // This class tries to emulate the behaviour of a DVB device // NOTE: The case device == NULL is only for debugging purposes class cConflictCheckDevice { public: std::set recTimers; cDevice* device; int devicenr; std::vector bondedDevices; cConflictCheckDevice() { device = NULL; devicenr = 0; } int Priority() const { int prio = -1; for (std::set::iterator it = recTimers.begin(); it != recTimers.end(); ++it) prio = std::max(prio, (*it)->timer->Priority()); return prio; }; bool HasInternalCam(void) { if (device) return device->HasInternalCam(); else return false; } int NumProvidedSystems(void) const { if (device) return device->NumProvidedSystems(); else return 1; } int CardIndex(void) const { if (device) return device->CardIndex(); else return devicenr; } bool Receiving() const { return !recTimers.empty(); } bool IsTunedTo(const cChannel* Channel) const { for (std::set::iterator it = recTimers.begin(); it != recTimers.end(); ++it) if ((*it)->timer->Channel()->Source() == Channel->Source() && (*it)->timer->Channel()->Transponder() == Channel->Transponder()) return true; return false; } bool HasDecoder() const { if (device) return device->HasDecoder(); else return (devicenr == 3); } bool HasCi() const { if (device) return device->HasCi(); else return (devicenr == 3); } bool IsPrimaryDevice() const { if (device) return device->IsPrimaryDevice(); else return (devicenr == 3); } bool ProvidesSource(int Source) const { if (device) return device->ProvidesSource(Source); else { // int type = Source & cSource::st_Mask; // if (devicenr == 0) return type == cSource::stCable; // if (devicenr > 0) return type == cSource::stTerr; // return false; return true; } } cCamSlot *CamSlot(void) const { if (device) return device->CamSlot(); else return NULL; } int Ca() const { for (std::set::iterator it = recTimers.begin(); it != recTimers.end(); ++it) return (*it)->timer->Channel()->Ca(); return 0; } bool HasPid(int Pid) const { return true; } bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL) const { bool result = false; bool hasPriority = Priority < 0 || Priority > this->Priority(); bool needsDetachReceivers = false; if (ProvidesSource(Channel->Source())) { result = hasPriority; if (Priority >= 0 && Receiving()) { if (IsTunedTo(Channel)) { if ((Channel->Vpid() && !HasPid(Channel->Vpid())) || (Channel->Apid(0) && !HasPid(Channel->Apid(0)))) { #ifdef DO_MULTIPLE_RECORDINGS if (CamSlot() && Channel->Ca() >= CA_ENCRYPTED_MIN) { if (CamSlot()->CanDecrypt(Channel)) result = true; else needsDetachReceivers = true; } else if (!IsPrimaryDevice()) result = true; #ifdef DO_REC_AND_PLAY_ON_PRIMARY_DEVICE else result = Priority >= 0; #endif #endif } else result = !IsPrimaryDevice() || Priority >= 0; } else needsDetachReceivers = true; } } if (result) { if (!BondingOk(Channel)) { // This device is bonded, so we need to check the priorities of the others: for (size_t i = 0; i < bondedDevices.size(); i++) { if (bondedDevices[i]->Priority() >= Priority) { LogFile.Log(3, "Attached receiver to bonded device %i has higher priority.", bondedDevices[i]->CardIndex() + 1); result = false; break; } } if (result) LogFile.Log(3, "Bonding ok, but detaches receiver on device %i.", CardIndex()); else LogFile.Log(3, "Bonding not okay on device %i.", CardIndex()); needsDetachReceivers = Receiving(); } else { LogFile.Log(3, "Bonding ok on device %i.", CardIndex()); } } if (NeedsDetachReceivers) *NeedsDetachReceivers = needsDetachReceivers; return result; } bool BondingOk(const cChannel *Channel) const { if (bondedDevices.empty()) return true; LogFile.Log(3, "Checking for bonding constraints on device %i", CardIndex() + 1); cString BondingParams = GetBondingParams(Channel); for (size_t i = 0; i < bondedDevices.size(); i++) { // bonding not okay, if a bonded devices records on another polarization or freq. band if (!bondedDevices[i]->recTimers.empty()) { if (strcmp(BondingParams, GetBondingParams((*bondedDevices[i]->recTimers.begin())->timer->Channel())) != 0) { LogFile.Log(3, "Bonded device %i has receiver attached. Not safe to use device.", bondedDevices[i]->CardIndex() + 1); return false; } else { LogFile.Log(3, "Bonded device %i has receiver attached but its safe.", bondedDevices[i]->CardIndex() + 1); } } else { LogFile.Log(3, "Bonded device %i has no receivers attached - ok.", bondedDevices[i]->CardIndex() + 1); } } return true; } cString GetBondingParams(const cChannel *Channel) const { //copied from cDVBTuner cDvbTransponderParameters dtp(Channel->Parameters()); if (Setup.DiSEqC) { if (const cDiseqc *diseqc = Diseqcs.Get(device->CardIndex() + 1, Channel->Source(), Channel->Frequency(), dtp.Polarization(), NULL)) return diseqc->Commands(); } else { bool ToneOff = Channel->Frequency() < Setup.LnbSLOF; bool VoltOff = dtp.Polarization() == 'V' || dtp.Polarization() == 'R'; return cString::sprintf("%c %c", ToneOff ? 't' : 'T', VoltOff ? 'v' : 'V'); } return ""; } }; // --- cConflictCheck -------------------------------------------------------- class cConflictCheck { cList* timerList; cList* evaltimeList; cList* failedList; std::set pendingTimers; cConflictCheckDevice *devices; int numDevices; time_t maxCheck; std::vector camSlotStatusArray; public: int relevantConflicts; int numConflicts; bool localConflicts; time_t nextRelevantConflictDate; cConflictCheck(); ~cConflictCheck(); void InitDevicesInfo(); void Check(); void BondDevices(const char* bondings); void SetLocal() { localConflicts = true; } bool GetLocal() { return localConflicts; } cList* CreateCurrentTimerList(); cList* CreateEvaluationTimeList(cList*); cList* CreateConflictList(cList*, cList* timerList); cList* CreateRemoteConflictList(cList* timerList, cList* failedList); int GetDevice(cConflictCheckTimerObj* TimerObj, bool *NeedsDetachReceivers); cList* GetFailed() { return failedList; } cList* GetTimers() { return timerList; } void AddConflict(cConflictCheckTimerObj* TimerObj, cConflictCheckTime* Checktime, std::set& pendingTimers); int ProcessCheckTime(cConflictCheckTime* checkTime); bool TimerInConflict(const cTimer*); void EvaluateConflCheckCmd(); eModuleStatus CamSlotModuleStatus(cCamSlot *CamSlot); }; #endif vdr-plugin-epgsearch-2.4.1/conflictcheck_thread.c000066400000000000000000000141341405273211300220370ustar00rootroot00000000000000/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #include #include "conflictcheck_thread.h" #include "epgsearchcfg.h" #include "mail.h" #include "epgsearch.h" #define CONFLICTCHECK_NICE 19 cConflictCheckThread *cConflictCheckThread::m_Instance = NULL; time_t cConflictCheckThread::m_cacheNextConflict = 0; int cConflictCheckThread::m_cacheRelevantConflicts = 0; int cConflictCheckThread::m_cacheTotalConflicts = 0; bool cConflictCheckThread::m_runOnce = false; bool cConflictCheckThread::m_forceUpdate = false; cConflictCheckThread::cConflictCheckThread(cPluginEpgsearch* thePlugin) : cThread("EPGSearch: conflictcheck") { m_plugin = thePlugin; m_Active = false; m_lastUpdate = time(NULL); m_runOnce = false; m_forceUpdate = false; } cConflictCheckThread::~cConflictCheckThread() { if (m_Active) Stop(); } void cConflictCheckThread::Init(cPluginEpgsearch* thePlugin, bool runOnce) { if (EPGSearchConfig.checkTimerConflictsAfterUpdate || EPGSearchConfig.conflictCheckIntervall == 0) { if (!runOnce) return; m_runOnce = true; } if (m_Instance == NULL) { m_Instance = new cConflictCheckThread(thePlugin); m_Instance->Start(); } else if (runOnce) m_forceUpdate = true; // force an update, because thread is already running } void cConflictCheckThread::Exit(void) { if (m_Instance != NULL) { m_Instance->Stop(); DELETENULL(m_Instance); } } void cConflictCheckThread::Stop(void) { m_Active = false; Wait.Signal(); Cancel(6); } void cConflictCheckThread::Action(void) { SetPriority(CONFLICTCHECK_NICE); m_Active = true; // let VDR do its startup if (!m_runOnce) { if (!cPluginEpgsearch::VDR_readyafterStartup) LogFile.Log(2, "ConflictCheckThread: waiting for VDR to become ready..."); while (m_Active && !cPluginEpgsearch::VDR_readyafterStartup) Wait.Wait(1000); if (EPGSearchConfig.delayThreads > 0) LogFile.Log(2, "ConflictCheckThread: startup delayed %d seconds", EPGSearchConfig.delayThreads); cCondWait::SleepMs(EPGSearchConfig.delayThreads * 1000); } time_t nextUpdate = time(NULL); while (m_Active && Running()) { time_t now = time(NULL); if (now >= nextUpdate || m_forceUpdate) { m_forceUpdate = false; { LOCK_TIMERS_WRITE; Timers->SetExplicitModify(); } LogFile.iSysLog("timer conflict check started"); cConflictCheck conflictCheck; conflictCheck.Check(); time_t nextConflict = 0; if (conflictCheck.relevantConflicts > 0) { cString msgfmt = ""; if (conflictCheck.relevantConflicts == 1) msgfmt = cString::sprintf(tr("timer conflict at %s! Show it?"), *DateTime(conflictCheck.nextRelevantConflictDate)); else msgfmt = cString::sprintf(tr("%d timer conflicts! First at %s. Show them?"), conflictCheck.relevantConflicts, *DateTime(conflictCheck.nextRelevantConflictDate)); bool doMessage = EPGSearchConfig.noConflMsgWhileReplay == 0 || !cDevice::PrimaryDevice()->Replaying() || conflictCheck.nextRelevantConflictDate - now < 2 * 60 * 60; if (doMessage && SendMsg(msgfmt, true, 7, mtWarning) == kOk) { m_plugin->showConflicts = true; cRemote::CallPlugin("epgsearch"); } if (EPGSearchConfig.sendMailOnConflicts) { cMailConflictNotifier mailNotifier; mailNotifier.SendConflictNotifications(conflictCheck); } conflictCheck.EvaluateConflCheckCmd(); } // store for external access cConflictCheckThread::m_cacheNextConflict = conflictCheck.nextRelevantConflictDate; cConflictCheckThread::m_cacheRelevantConflicts = conflictCheck.relevantConflicts; cConflictCheckThread::m_cacheTotalConflicts = conflictCheck.numConflicts; LogFile.iSysLog("timer conflict check finished"); m_lastUpdate = time(NULL); int Intervall = EPGSearchConfig.conflictCheckIntervall; if (nextConflict > 0 && EPGSearchConfig.conflictCheckWithinLimit > 0 && nextConflict - time(NULL) < EPGSearchConfig.conflictCheckWithinLimit * 60) Intervall = EPGSearchConfig.conflictCheckIntervall2; nextUpdate = long(m_lastUpdate / 60) * 60 + (Intervall * 60); } if (m_Active && Running()) Wait.Wait(2000); // to avoid high system load if time%30==0 ????????????????????? // no waiting in the while loop if m_runOnce is true while (Running() && m_Active && time(NULL) % 30 != 0 && !m_runOnce) // sync heart beat to a multiple of 5secs Wait.Wait(1000); }; m_Active = false; // always false at this point LogFile.iSysLog("Leaving conflict check thread"); } vdr-plugin-epgsearch-2.4.1/conflictcheck_thread.h000066400000000000000000000034031405273211300220410ustar00rootroot00000000000000/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #ifndef VDR_CONFLICTCHECK_THREAD_H #define VDR_CONFLICTCHECK_THREAD_H #include #include "conflictcheck.h" #include "epgsearch.h" class cConflictCheckThread: public cThread { private: bool m_Active; time_t m_lastUpdate; cPluginEpgsearch* m_plugin; static bool m_runOnce; static bool m_forceUpdate; cCondWait Wait; protected: virtual void Action(void); void Stop(void); public: static cConflictCheckThread *m_Instance; static time_t m_cacheNextConflict; static int m_cacheRelevantConflicts; static int m_cacheTotalConflicts; cConflictCheckThread(cPluginEpgsearch* thePlugin); virtual ~cConflictCheckThread(); static void Init(cPluginEpgsearch* thePlugin, bool runOnce = false); static void Exit(void); }; #endif vdr-plugin-epgsearch-2.4.1/conflictcheckonly.c000066400000000000000000000066341405273211300214200ustar00rootroot00000000000000/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #include #include #include #include "services.h" #include "mainmenushortcut.h" static const char VERSION[] = "0.0.1"; static const char DESCRIPTION[] = trNOOP("Direct access to epgsearch's conflict check menu"); static const char MAINMENUENTRY[] = trNOOP("Timer conflicts"); static const char SETUPTEXT[] = trNOOP("Conflict info in main menu"); cString DateTime(time_t t) { char buffer[32]; if (t == 0) { time(&t); } struct tm tm_r; tm *tm = localtime_r(&t, &tm_r); snprintf(buffer, sizeof(buffer), "%02d.%02d. %02d:%02d", tm->tm_mday, tm->tm_mon + 1, tm->tm_hour, tm->tm_min); return buffer; } class cPluginConflictcheckonly: public cMainMenuShortcut { private: char *_menuText; public: cPluginConflictcheckonly(); ~cPluginConflictcheckonly(); virtual const char *Version() { return VERSION; } virtual const char *Description() { return I18nTranslate(DESCRIPTION, I18nEpgsearch); } virtual bool Initialize(); virtual cOsdObject *MainMenuAction() { return GetEpgSearchMenu("Epgsearch-conflictmenu-v1.0"); } protected: virtual const char *SetupText() { return I18nTranslate(SETUPTEXT, I18nEpgsearch); } virtual const char *MainMenuText(void); }; cPluginConflictcheckonly::cPluginConflictcheckonly(): _menuText(NULL) { } cPluginConflictcheckonly::~cPluginConflictcheckonly() { free(_menuText); } const char *cPluginConflictcheckonly::MainMenuText(void) { const char *menuText = I18nTranslate(MAINMENUENTRY, I18nEpgsearch); cPlugin *epgSearchPlugin = cPluginManager::GetPlugin("epgsearch"); if (epgSearchPlugin) { Epgsearch_lastconflictinfo_v1_0 *serviceData = new Epgsearch_lastconflictinfo_v1_0; if (epgSearchPlugin->Service("Epgsearch-lastconflictinfo-v1.0", serviceData)) { if (serviceData->relevantConflicts > 0) { free(_menuText); if (asprintf(&_menuText, "%s (%d, %s: %s)", menuText, serviceData->relevantConflicts, I18nTranslate(trNOOP("next"), I18nEpgsearch), *DateTime(serviceData->nextConflict))) menuText = _menuText; } } delete serviceData; } return menuText; } bool cPluginConflictcheckonly::Initialize(void) { return cMainMenuShortcut::Initialize(); } VDRPLUGINCREATOR(cPluginConflictcheckonly); // Don't touch this! vdr-plugin-epgsearch-2.4.1/createcats.c000066400000000000000000000270041405273211300200270ustar00rootroot00000000000000/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ #include #include #include #include #include #define MINAPPEARANCE 100 // the minimum appearance of a category #define MAXVALUES 60 // the maximum of values for a category #define MAXNAMELENGTH 30 // the maximum length of a category name or value // some helping stuff copied from VDR sources #define KILOBYTE(n) ((n) * 1024) #define MAXPARSEBUFFER KILOBYTE(10) #ifdef __FreeBSD__ #ifdef isnumber #undef isnumber #endif #endif bool isnumber(const char *s) { if (!*s) return false; while (*s) { if (!isdigit(*s)) return false; s++; } return true; } // --- cReadLine ------------------------------------------------------------- class cReadLine { private: char buffer[MAXPARSEBUFFER]; public: cReadLine() { buffer[0] = 0; } char *Read(FILE *f); }; char *cReadLine::Read(FILE *f) { if (fgets(buffer, sizeof(buffer), f) != 0) { int l = strlen(buffer) - 1; if (l >= 0 && buffer[l] == '\n') buffer[l] = 0; return buffer; } return NULL; } char *skipspace(const char *s) { while (*s && isspace(*s)) s++; return (char *)s; } int comparevalue(const void *arg1, const void *arg2) { char* value1 = *(char**) arg1; char* value2 = *(char**) arg2; return strcmp(value1, value2); } // --- cCat ------------------------------------------------------------- class cCat { public: int appeared; char name[MAXPARSEBUFFER]; int numvalues; char** values; cCat(char* n) : appeared(0), numvalues(0), values(NULL) { strcpy(name, n); } void addvalue(char* value) { if (valueexists(value)) return; char* newvalue = (char*) malloc(sizeof(char) * (strlen(value) + 1)); strcpy(newvalue, value); char **tmp = (char**) realloc(values, sizeof(char*) * (numvalues + 1)); if (tmp) { values = tmp; values[numvalues++] = newvalue; } else { free(newvalue); } } bool valueexists(char* value) { for (int i = 0; i < numvalues; i++) if (strcmp(values[i], value) == 0) return true; return false; } void sort() { qsort(values, numvalues, sizeof(char*), comparevalue); } }; int comparecat(const void *arg1, const void *arg2) { cCat* cat1 = *(cCat**) arg1; cCat* cat2 = *(cCat**) arg2; if (cat1->appeared == cat2->appeared) return 0; if (cat1->appeared < cat2->appeared) return 1; else return -1; } // --- cCats ------------------------------------------------------------- class cCats { private: int numcats; cCat** cats; public: cCats(): numcats(0), cats(NULL) {} int num() { return numcats; } cCat* add(char* name) { cCat* newCat = new cCat(name); cCat **tmp = (cCat**) realloc(cats, sizeof(cCat*) * (numcats + 1)); if (tmp) { cats = tmp; cats[numcats++] = newCat; return newCat; } else { delete newCat; return NULL; } } cCat* get(int i) { if (i >= 0 && i < numcats) return cats[i]; else return NULL; } cCat* exists(char* name) { for (int i = 0; i < numcats; i++) if (strcmp(cats[i]->name, name) == 0) return cats[i]; return NULL; } void sort() { for (int i = 0; i < numcats; i++) cats[i]->sort(); qsort(cats, numcats, sizeof(cCat*), comparecat); } }; int main(int argc, char *argv[]) { FILE* f = NULL; cCats catlist; unsigned int minappearance = MINAPPEARANCE; unsigned int maxvalues = MAXVALUES; unsigned int maxlength = MAXNAMELENGTH; static const struct option long_options[] = { { "minappearance", required_argument, NULL, 'm' }, { "maxvalues", required_argument, NULL, 'v' }, { "maxlength", required_argument, NULL, 'l' }, { "help", no_argument, NULL, 'h' }, { NULL, no_argument, NULL, 0 } }; int c; while ((c = getopt_long(argc, argv, "m:v:l:h", long_options, NULL)) != -1) { switch (c) { case 'm': if (isnumber(optarg)) { minappearance = atoi(optarg); break; } fprintf(stderr, "invalid parameter minappearance: %s\n", optarg); return 2; break; case 'v': if (isnumber(optarg)) { maxvalues = atoi(optarg); break; } fprintf(stderr, "invalid parameter maxvalues: %s\n", optarg); return 2; break; case 'l': if (isnumber(optarg)) { maxlength = atoi(optarg); break; } fprintf(stderr, "invalid parameter maxlength: %s\n", optarg); return 2; break; case 'h': printf("usage: createcats [OPTIONS] /path_to/epg.data\n\n"); printf("-m N, --minappearance=N the minimum number a category has to appear\n"); printf(" to be used\n"); printf("-v N, --maxvalues=N values of a category are omitted if they exceed\n"); printf(" this number\n"); printf("-l N, --maxlength=N the maximum length of a text to be accepted\n"); printf(" as a category value\n"); printf("-h, --help this help\n\n"); return 0; default: break; } } if (argc < 2) { fprintf(stderr, "ERROR: please pass your epg.data\nusage: createcats epg.data\n"); return 1; } f = fopen(argv[argc - 1], "r"); if (f == NULL) { fprintf(stderr, "ERROR: could not open: %s\n", argv[1]); return 1; } char *s; cReadLine ReadLine; while ((s = ReadLine.Read(f)) != NULL) { if (*s == 'D') { s = strchr(s, '|'); // jump to possibly first category if (!s) continue; s++; char *pstrSearchToken; char *pstrSearch = strdup(s); pstrSearchToken = strtok(pstrSearch, "|"); while (pstrSearchToken) { // must have a ':' char* szPos = NULL; if ((szPos = strchr(pstrSearchToken, ':')) == NULL) { pstrSearchToken = strtok(NULL, "|"); continue; } char catname[MAXPARSEBUFFER] = ""; char catvalue[MAXPARSEBUFFER] = ""; strncpy(catname, pstrSearchToken, szPos - pstrSearchToken); catname[szPos - pstrSearchToken] = 0; strcpy(catvalue, skipspace(szPos + 1)); cCat* cat = catlist.exists(catname); if (!cat && strlen(catname) < maxlength) // accept only names up to 30 chars cat = catlist.add(catname); if (cat) { cat->appeared++; if (strlen(catvalue) < maxlength) // accept only values up to 30 chars cat->addvalue(catvalue); } pstrSearchToken = strtok(NULL, "|"); } free(pstrSearch); } } fclose(f); catlist.sort(); f = fopen("epgsearchcats.conf", "w"); if (f == NULL) { fprintf(stderr, "ERROR: could not open outputfile\n"); return 1; } fprintf(f, "# -----------------------------------------------------------------------------\n"); fprintf(f, "# This is just a template based on your current epg.data. Please edit!\n"); fprintf(f, "# Perhaps a category or its value list should be removed. Also the\n"); fprintf(f, "# 'name in menu' should be adjusted to your language.\n"); fprintf(f, "# The order of items determines the order listed in epgsearch. It does not\n"); fprintf(f, "# depend on the ID, which is used by epgsearch.\n"); fprintf(f, "# Format:\n"); fprintf(f, "# ID|category name|name in menu|values separated by ',' (option)|searchmode(option)\n"); fprintf(f, "# - 'ID' should be a unique positive integer\n"); fprintf(f, "# (changing the id later on will force you to reedit your search timers!)\n"); fprintf(f, "# - 'category name' is the name in your epg.data\n"); fprintf(f, "# - 'name in menu' is the name displayed in epgsearch.\n"); fprintf(f, "# - 'values' is an optional list of possible values\n"); fprintf(f, "# if you omit the list, the entry turns to an edit field in epgsearch,\n"); fprintf(f, "# else it's a list of items to select from\n"); fprintf(f, "# - 'searchmode' is an optional parameter specifying the mode of search:\n"); fprintf(f, "# text comparison:\n"); fprintf(f, "# 0 - the whole term must appear as substring\n"); fprintf(f, "# 1 - all single words (delimiters are ',', ';', '|' or '~')\n"); fprintf(f, "# must exist as substrings. This is the default search mode.\n"); fprintf(f, "# 2 - at least one word (delimiters are ',', ';', '|' or '~')\n"); fprintf(f, "# must exist as substring.\n"); fprintf(f, "# 3 - matches exactly\n"); fprintf(f, "# 4 - regular expression\n"); fprintf(f, "# numerical comparison:\n"); fprintf(f, "# 10 - less\n"); fprintf(f, "# 11 - less or equal\n"); fprintf(f, "# 12 - greater\n"); fprintf(f, "# 13 - greater or equal\n"); fprintf(f, "# 14 - equal\n"); fprintf(f, "# 15 - not equal\n"); fprintf(f, "# -----------------------------------------------------------------------------\n\n"); int id = 1; for (int i = 0; i < catlist.num(); i++) { cCat* cat = catlist.get(i); if (cat->appeared > (int)minappearance && cat->numvalues > 1) { // accept only category, that have at least 2 values and appear more than MINAPPEARANCE timers fprintf(f, "# '%s' found %d times with %d different values %s\n", cat->name, cat->appeared, cat->numvalues, cat->numvalues >= (int)maxvalues ? "(values omitted, too much)" : ""); fprintf(f, "%d|%s|%s|", id++, cat->name, cat->name); for (int j = 0; cat->numvalues < (int)maxvalues && j < cat->numvalues; j++) fprintf(f, "%s%s", cat->values[j], (j == cat->numvalues - 1 ? "" : ",")); fprintf(f, "|1\n\n"); } } fclose(f); printf("epgsearchcats.conf created!\n"); return 0; } vdr-plugin-epgsearch-2.4.1/distance.c000066400000000000000000000103631405273211300175030ustar00rootroot00000000000000/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ //--------------------------------------------------- // Levenshtein Distance // by Michael Gilleland, Merriam Park Software // // source: // http://www.merriampark.com/ld.htm#CPLUSPLUS // //--------------------------------------------------- #include "distance.h" #include #ifdef __FreeBSD__ #include #else #include #endif #include //**************************** // Get minimum of three values //**************************** int Distance::Minimum(int a, int b, int c) { int mi; mi = a; if (b < mi) { mi = b; } if (c < mi) { mi = c; } return mi; } //************************************************** // Get a pointer to the specified cell of the matrix //************************************************** int *Distance::GetCellPointer(int *pOrigin, int col, int row, int nCols) { return pOrigin + col + (row * (nCols + 1)); } //***************************************************** // Get the contents of the specified cell in the matrix //***************************************************** int Distance::GetAt(int *pOrigin, int col, int row, int nCols) { int *pCell; pCell = GetCellPointer(pOrigin, col, row, nCols); return *pCell; } //******************************************************* // Fill the specified cell in the matrix with the value x //******************************************************* void Distance::PutAt(int *pOrigin, int col, int row, int nCols, int x) { int *pCell; pCell = GetCellPointer(pOrigin, col, row, nCols); *pCell = x; } //***************************** // Compute Levenshtein distance //***************************** int Distance::LD(char const *s, char const *t, int maxLength) { int *d; // pointer to matrix int n; // length of s int m; // length of t int i; // iterates through s int j; // iterates through t char s_i; // ith character of s char t_j; // jth character of t int cost; // cost int result; // result int cell; // contents of target cell int above; // contents of cell immediately above int left; // contents of cell immediately to left int diag; // contents of cell immediately above and to left int sz; // number of cells in matrix // Step 1 n = min((int)strlen(s), maxLength); m = min((int)strlen(t), maxLength); if (n == 0) { return m; } if (m == 0) { return n; } sz = (n + 1) * (m + 1) * sizeof(int); d = (int *) malloc(sz); // Step 2 for (i = 0; i <= n; i++) { PutAt(d, i, 0, n, i); } for (j = 0; j <= m; j++) { PutAt(d, 0, j, n, j); } // Step 3 for (i = 1; i <= n; i++) { s_i = s[i - 1]; // Step 4 for (j = 1; j <= m; j++) { t_j = t[j - 1]; // Step 5 if (s_i == t_j) { cost = 0; } else { cost = 1; } // Step 6 above = GetAt(d, i - 1, j, n); left = GetAt(d, i, j - 1, n); diag = GetAt(d, i - 1, j - 1, n); cell = Minimum(above + 1, left + 1, diag + cost); PutAt(d, i, j, n, cell); } } // Step 7 result = GetAt(d, n, m, n); free(d); return result; } vdr-plugin-epgsearch-2.4.1/distance.h000066400000000000000000000031321405273211300175040ustar00rootroot00000000000000/* -*- c++ -*- Copyright (C) 2004-2013 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch */ //--------------------------------------------------- // Levenshtein Distance // by Michael Gilleland, Merriam Park Software // // source: // http://www.merriampark.com/ld.htm#CPLUSPLUS // //--------------------------------------------------- #ifndef _DISTANCE_INC_ #define _DISTANCE_INC_ class Distance { public: int LD(char const *s, char const *t, int maxLength); private: int Minimum(int a, int b, int c); int *GetCellPointer(int *pOrigin, int col, int row, int nCols); int GetAt(int *pOrigin, int col, int row, int nCols); void PutAt(int *pOrigin, int col, int row, int nCols, int x); }; #endif vdr-plugin-epgsearch-2.4.1/doc-src/000077500000000000000000000000001405273211300170745ustar00rootroot00000000000000vdr-plugin-epgsearch-2.4.1/doc-src/de/000077500000000000000000000000001405273211300174645ustar00rootroot00000000000000vdr-plugin-epgsearch-2.4.1/doc-src/de/epgsearch.1.txt000066400000000000000000001323531405273211300223340ustar00rootroot00000000000000=encoding utf8 =head1 NAME F - Suchtimer und Ersatz für VDR's Standard-Programm-Menü =head1 BESCHREIBUNG EPG-Search kann als Ersatz für VDR's Standard-Programm-Menü verwendet werden. Es sieht genauso aus, erweitert es aber um einige zusätzliche Funktionen. Ein weiterer Punkt sind die sog. Suchtimer die dafür sorgen, dass Timer automatisch programmiert werden. - Befehle für EPG-Einträge mit verschiedenen integrierten Befehlen wie z.B. 'Wiederholungen anzeigen', 'Suche anlegen'. Man kann eigene Befehle hinzufügen, um z.B. einen VDRAdmin Autotimer anzulegen. - Bis zu 4 weitere Zeitpunkte im Menü 'Was läuft jetzt?' neben 'Jetzt' und 'Nächste', sowie ein optionales Favoritenmenü. - Suche im EPG: Anlegen von wiederverwendbaren Abfragen, die auch als 'Suchtimer' verwendet werden können. - Suchtimer: Sucht im Hintergrund nach Sendungen und erzeugt einen Timer bei passenden EPG-Einträgen (ähnlich zu VDRAdmins Autotimern) oder informiert über die Sendung via OSD. - Vermeidung von doppelten Aufnahmen der gleichen Sendung * Timer-Vorschau * Erkennung abgebrochener Aufnahmen * Fuzzy-Vergleich von Sendungen - Fortschrittsbalken in 'Jetzt' und 'Nächste' - Zeit im Menü 'Jetzt', 'Nächste' kann per Tastendruck verschoben werden, z.B. was läuft 'Jetzt' + 30 Minuten - Startmenü 'Programm' oder 'Jetzt' einstellbar. - das Menü zur detaillierten EPG-Anzeige (Zusammenfassung) erlaubt den Sprung zur vorherigen/nächsten Sendung - Unterstützung erweiterter EPG-Infos in Suchtimern - Erweiterung des Timer-Edit-Menüs um Verzeichnisse, benutzerdefinierte Wochentage und Untertitel-Auswahl - Timer Konfliktcheck, informiert über OSD-Meldung - Timer Konfliktmenü, zeigt die Konflikte an und erleichtert die Konfliktlösung - Email-Benachrichtigungen über Suchtimer-Updates und Timer-Konflikte Teile der Quelltexte basieren auf dem repeating-epg-patch von Gerhard Steiner, der mir die Erlaubnis gab, diese zu verwenden. Danke für seine Arbeit! =head1 OPTIONEN =over 4 =item -f file, --svdrpsendcmd=file Pfad zu svdrpsend für externe SVDRP-Kommunikation (Standard ist interne Kommunikation, deshalb ist dieser Paramter normalerweise nicht notwendig) =item -c path, --config=path zur Angabe eines eigenen Konfigurationsverzeichnisses für alle epgsearch-Dateien, Standard ist '/epgsearch' =item -l file, --logfile=file zur Angabe eines abweichenden Dateipfades für epgsearch's Log-File (Standard ist epgsearch.log in epgsearch's Konfig-Verzeichnis) =item -v n, --verbose=n verbose level für das Log-File. Wert 0 bedeutet kein Logging. Weiter Werte sind 1 (allgemeine Meldungen), 2 (detaillierte Meldungen), 3 (für Debug-Zwecke) =item -r, --reloadmenuconf bewirkt ein Neuladen der epgsearchmenu.conf bei jedem Plugin-Aufruf am OSD. Kann für das Testen eines selbst angepaßten Menü-Layouts praktisch sein. =item -m file, --mailcmd=file das externe Kommando für den Emailversand. Als Standard wird 'sendEmail.pl' benutzt. Wenn ein abweichendes Kommando oder Skript verwendet wird, muss sichergestellt sein, dass das gleiche Paramter-Interface verwendet wird, wie bei sendEmail.pl. =back =head1 Inhalt 1. Beschreibung 1.1 Menü Befehle 1.2 Menü Suche 1.2.1 Menü Suche editieren 1.2.2 Menü Suchergebnisse 1.3 Erweitertes 'Jetzt' und 'Nächste' 1.4 Menü Setup 23. Suchtimer 2.1 'Wiederholungen vermeiden' - Im Detail 2.2 Wie funktioniert der Vergleichstest zwischen 2 Sendungen? 2.3 Wie und wo wird der Vergleichstest eingesetzt? 3. Verwendung der Suche durch andere Plugins oder Skripte 4. Verwendung erweiterter EPG Infos 5. Ersetzen des Standardmenü 6. Addons =head1 1. Beschreibung Auf den ersten Blick sieht EPG-Search wie der Programm-Menü-Punkt des VDR aus. Ein Tastendruck auf '0' schaltet die Farbtasten um, so dass weitere Funktionen erreicht werden können (die vorgegebene Zuweisung kann per Setup angepasst werden): =head2 1.1 Menü Befehle Dieses Menü zeigt Befehle an, die auf den ausgewählten Menüeintrag angewandt werden können. Es gibt 8 vorgegebene Befehle: - Wiederholung: Zeigt Wiederholungen an - Aufnehmen - Umschalten - Suche anlegen: schaltet zum Suchmenü und erzeugt eine Suche mit dem Namen der aktuellen Sendung als Suchbegriff (um die manuelle Erfassung zu vermeiden - Suche in Aufnahmen: durchsucht die Aufnahmen nach einer Sendung mit diesem Namen - Als 'bereits aufgezeichnet' markieren: Hiermit wird die ausgewählte Sendung in die Datei epgsearchdone.data übernommen und epgsearch angewiesen, diese Sendung nicht aufzunehmen, falls der zugehörige Suchtimer mit "Wiederholung vermeiden" geschaltet ist. Ein bereits erzeugter Timer wird beim nächsten Suchtimer-Update automatisch gelöscht. - In/Aus Umschaltliste?: Zum Bearbeiten der Umschaltliste. Wenn eine Sendung in der Umschaltliste enthalten ist, wird kurz vor Beginn eine Ankündigung eingeblendet und dann umgeschaltet. Um die gesamte Umschaltliste einzusehen, bitte 'Suche/Aktionen/Zeige Umschaltliste' aufrufen. - Erzeuge Ausschlussliste: Eine Ausschlussliste wird verwendet um bestimmte Sendungen bei der Verwendung von Suchtimern zu ignorieren. Ein Suchtimer kann beliebige Ausschlusslisten verwenden. Man kann eigene Befehle hinzufügen, indem man die Datei epgsearchcmds.conf im epgsearch-Konfig-Verzeichnis editiert. Eine Beispiel-Datei mit Bespielscripts liegt dem Plugin bei (s. Unterverzeichnis 'scripts', stammt von vdr-wiki.de. Danke an die Autoren). Das Format der Datei ist identisch zu VDRs commands.conf oder reccmds.conf. Wenn ein Befehl ausgeführt wird, werden folgende Parameter übergeben: $1: Titel des Programmeintrags $2: Startzeit als time_t-Wert (wie im Shutdown-Skript) $3: Endzeit $4: Programmplatz $5: langer Kanalname $6: Untertitel des Programmeintrags, "" falls nicht vorhanden Zum Ausführen eines Befehls aus dem Hauptmenü ohne Öffnen des Befehlsmenüs genügt es, die zugehörige Nummer des Befehls zu drücken. =head2 1.2 Menü Suche Hier kann man eine Suche im EPG erzeugen, editieren, löschen und ausführen. Bedienung und Verhalten ist ähnlich zu VDR's Timer-Menü. =head3 1.2.1 Menü Suche editieren Das meiste in diesem Menü ist selbsterklärend, deshalb nur einige Anmerkungen zu: =over 4 =item - B Suchbegriff. Will man nach mehreren Worten suchen, dann bitte mit Leerzeichen trennen. Lässt man den Suchbegriff leer (in Verbindung mit Suchmodus 'Ausdruck') wird alles akzeptiert. Das kann praktisch sein, um z.B. alles zu suchen, was zu einer bestimmten Zeit auf einem bestimmten Sender kommt. Mit 'Blau' kann man auch eine Vorlage für eine Suche übernehmen. Falls eine Vorlage als Standard definiert wurde, wird bei einer neuen Suche automatisch der Inhalt der Standard-Vorlage verwendet. Hinweis: Die unscharfe Suche ist auf 32 Zeichen begrenzt! =item - B 'Ausdruck' sucht nach diesem Ausdruck innerhalb eines EPG-Eintrags. 'alle Worte' erfordert, dass jedes Wort im EPG-Eintrag vorkommt, 'ein Wort' dagegen nur, dass zumindest ein Wort auftaucht. 'exakt' vergleicht den gesamten Suchbegriff mit dem EPG-Eintrag (praktisch bei kurzen Titeln wie z.B. "Alf"). 'regulärer Ausdruck' erlaubt die Angabe eines regulären Ausdrucks zur Suche. Ein führender und abschließender '/' ist nicht notwendig. Als Standard werden POSIX extended regular expressions verwendet. Wer lieber mit Perl kompatiblen regulären Ausdrücken arbeitet, muss lediglich im Makefile des Plugins #HAVE_PCREPOSIX=1 in HAVE_PCREPOSIX=1 ändern und neu kompilieren. (Dafür ist pcreposix notwendig, das mit libpcre von www.pcre.org installiert wird, aber auf den meisten Distributionen bereits vorhanden sein sollte). Eine Beschreibung des Suchprozesses gibt es im MANUAL. =item - B Einige Provider liefern Kennungen für den Inhalt einer Sendung, z.B. "Film/Drama", "Dokumentation",...(erst ab vdr-1.7.11 verfügbar) Hiermit können diesen Kennungen ausgewählt werden. Es ist auch eine Mehrfachauswahl möglich, die dann in allen Kennungen übereinstimmen muss (UND-Verknüpfung). =item - B (nur verfügbar, wenn konfiguriert. Siehe weiter unten 'Verwendung erweiterter EPG Infos') =item - B Wenn 'Ja' gewählt ist, verhindert das, dass eine Sendung aus dem Suchergebnis ausgeschlossen wird, falls die entsprechende Kategorie nicht im EPG vorhanden ist. Vorsicht: Ohne weitere Suchkriterien kann das zu einer Flut von Timern führen. =item - B sucht nur im angegebenen Kanalbereich, der hinterlegten Kanalgruppe, z.B. 'Öffentl. Rechtl.' oder 'Sportsender'... oder in FTA-Sendern. ACHTUNG: Nach einer Änderung der Kanal-Reihenfolge sollten unbedingt diese Einstellungen der Suchtimer kontrolliert werden! =item - B Neben den Wochentagen kann auch eine benutzerdefinierte Auswahl getroffen werden, um z.B. nur Montags und Freitags zu suchen. Die benutzerdefinierte Auswahl findet sich am Ende der Liste Son, Mon, ..., Sam, benutzerdefiniert =item - B Ausschlusslisten können benutzt werden, um unerwünschte Sendungen auszuschließen. Hier können nur globale, eine oder mehrere oder alle Ausschlusslisten selektiert werden. Falls ein Suchergebnis auch in einer der gewählten Ausschlusslisten erscheint, wird es verworfen. =item - B Nur verfügbar, wenn im Setup aktiviert. Mit dieser Option kann eine Suche zur Verwendung im Favoritenmenü markiert werden. Dieses Menü listet alle Suchergebnisse von Suchen mit dieser Option. =item - B Nur verfügbar, wenn mehr als eine Menüvorlage für Suchergebnisse in epgsearchmenu.conf angegeben wurde. Mit dieser Option kann ein anderes Layout für die Suchergebnisse dieser Suche gewählt werden. =item - B falls ja, sucht das Plugin im Hintergrund nach passenden Sendungen und erzeugt dafür einen Timer (im Setup muss dazu die Verwendung von Suchtimern aktiv sein). Bei der Einstellung läßt sich über die Taste 'Blau' ein Zeitfenster einstellen, in dem der Suchtimer aktiv sein soll. =item - B Standard ist 'Aufnehmen', also das Erzeugen eines Timers für das Suchergebnis. Man kann aber auch wählen, dass nur eine Ankündigung der Sendung per OSD vorgenommen werden soll, sobald diese gefunden wird. Eine weitere Möglichkeit ist 'nur umschalten'. Dadurch wird automatisch eine Minute vor Beginn der Sendung auf deren Kanal gewechselt. Ebenso kann mit 'Ankündigen und Umschalten' die Sendung vor ihrem Beginn angekündigt werden und mit 'Ok' zum entsprechenden Kanal gewechselt werden. =item - B falls ja, wird die Aufnahme in einem Ordner mit dem Seriennamen gespeichert. Die Aufnahme selbst erhält den Episondennamen. Falls es keinen gibt, wird Datum und Uhrzeit als Episondenname verwendet. =item - B hier kann man ein Verzeichnis angeben, in dem die Aufnahme gespeichert wird, z.B. 'SciFi'. Mit der Taste 'Blau' kann ein Verzeichnis gewählt werden, das bereits bei anderen Sucheinträgen verwendet wird. Die Liste kann außerdem durch Einträge in der Datei epgsearchdirs.conf erweitert werden (pro Zeile ein Verzeichnis, ohne das führende video-Verzeichnis, s. auch MANUAL). Wenn man erweiterte EPG-Infos von einem Provider erhält, können im Verzeichnis-Eintrag auch Variablen wie "%Genre%" oder "%Category%" verwendet werden. Diese werden durch die aktuellen erw. EPG-Infos ersetzt, sobald ein Timer erzeugt wird. Siehe MANUAL 'Using variables in the directory entry of a search timer') =item - B Manchen Aufnahmen sollen nur ein paar Tage existieren, z.B. Tagesschau. Mit diesem Feature kann man epgsearch sagen, dass es die Aufnahme automatisch nach ... Tagen löschen soll =item - B Wenn die angegebene Anzahl von Aufnahmen existiert, dann pausiert epgsearch mit dem Erzeugen neuer Timer. Erst nach dem Löschen einer oder mehrerer Aufnahmen, wird wieder nach neuen Sendungen gesucht. =item - B Wenn man keine Wiederholungen aufnehmen will, versucht dieses Feature festzustellen, ob eine Sendung bereits aufgenommen/programmiert wurde und überspringt diese dann. Bitte vor Verwendung den Abschnitt 'Wiederholungen vermeiden - Im Detail' weiter unten lesen. =item - B Will man eine gewisse Anzahl von Wiederholungen einer Sendung erlauben, kann dies hier hinterlegt werden. =item - B Falls Wiederholungen nur innerhalb einer anzugebenden Anzahl Tage erlaubt werden sollen, kann dies hier eingestellt werden. 0 entspricht unbegrenzt. =item - B Einstellung, ob beim Test, ob eine Sendung identisch ist, auch der Titel verglichen werden soll. =item - B Einstellung, ob beim Test, ob eine Sendung identisch ist, auch der Untertitel verglichen werden soll. Bei 'ja' stuft epgsearch zwei Sendungen nur dann als identisch ein, wenn die Episodennamen gleich sind und nicht leer. Bei 'erlaube leere' können auch Sendungen identisch sein, wenn beide Unterttitel leer sind. Im Normalfall sollte dann auf "nein" gestellt werden. =item - B Einstellung, ob beim Test, ob eine Sendung identisch ist, auch die Inhaltsbeschreibung verglichen werden soll. Dabei wird zunächst alles aus dem Inhalt entfernt, das einer Kategorienangabe gleicht. Der verbleibende Text wird dann verglichen. Ist dieser zum Prozentsatz der folgenden Option ähnlich (im Sinne des Levinshtein-Distance-Algorithmus) wird er als gleich behandelt. =item - C Die notwendige Übereinstimmung zweier Beschreibung in %. =item - B Manchmal wird eine Sendung häufig innerhalb einer gewissen Zeitspanne (Tag, Woche, Monat,...) wiederholt, die einzelnen Sendungen lassen sich aber anhand des EPG Inhalts nicht unterscheiden. Somit ist der Zeitpunkt also die einzige Information. Um damit zu vergelichen, kann man hier die entsprechende Zeitspanne auswählen, um die Wiederholungen zu ignorieren. =item - B Über die Schaltfläche 'Einstellungen' kann angegeben werden welche Kategorien ebenfalls miteinander verglichen werden sollen. =item - B Jeder Suchtimer kann für diese Parameter eigene Einstellungen haben. Die Voreinstellung wird im Setup vorgenommen. =item - B aktiviert VPS, falls im VDR-Setup aktiv und für die gefundene Sendung auch VPS-Informationen vorhanden sind. =item - B zum automatischen Löschen eines Suchttimers bei folgenden Bedingungen: * nach x Aufnahmen, oder * nach x Tagen nach erster Aufnahme Gezählt werden dabei nur erfolgreiche Aufnahmen. Das Löschen erfolgt direkt nach dem Ende der entsprechenden Aufnahme. =back Um den Status 'Als Suchtimer verw.' zu ändern, ohne das Menü zu öffnen, kann die Taste '2' verwendet werden. Dies ruft direkt den 2. Befehl im Befehlsmenü auf. =head3 1.2.2 Menü Suchergebnisse Dieses Menü zeigt die Suchergebnisse an. Ein 'T' sagt aus, dass es zu diesem Eintrag bereits einen Timer gibt, ein 't', dass es nur teilweise aufgenommen wird, also wie im Standard-Programm-Menü. =head2 1.3 Erweitertes 'Jetzt' and 'Nächste' Im Setup können bis zu 4 zusätzliche Zeiten, als Erweiterung zu 'Jetzt' und 'Nächste', angegeben werden um die Taste Grün zu erweitern. Z.B. 'nachmittags', 'abends', 'spätabends'. Zeiten, die bereits verstrichen sind, werden übersprungen, man erhält abends also kein 'nachmittags'. Ausnahme: Ist ein Zeitpunkt nicht mehr als 20 Stunden in der Zukunft wird das Menü des nächsten Tages angezeigt. In diesen Menü kann die aktuell angezeigte Zeit durch Drücken auf FastRew und FastFwd verschoben werden um die Zeit nach hinter oder vorne zu verstellen. Falls diese Tasten auf der Fernbedienung nicht existieren, kann diese Funktion durch Umschalten mit '0' erreicht werden. Die Tasten Grün und Gelb wechseln dann zu '<<' und '>>'. Das Umschalten kann über das Setup angepasst werden. Man kann einen Fortschrittsbalken im Menü 'Jetzt'/'Nächste' anzeigen lassen. =head2 1.4 Menü Setup =head3 1.4.1 Allgemein =over 4 =item - B Damit wird der Eintrag 'Suche' im Hauptmenü ausgeblendet. Achtung: wenn das Plugin der Taste Grün zugeordnet ist, dann bewirkt das Ausblenden, dass wieder das VDR-Standardmenü gerufen wird (um das zu vermeiden s. unten). =item - B Falls nicht ausgeblendet, kann hier der Name des Hauptmenü-Eintrags hinterlegt werden. Vorgabe ist 'Programmführer'. Hinweis: Wenn man den Eintrag abweichend von der Vorgabe setzt, ist der Eintrag nicht mehr abhängig von der gewählten OSD-Sprache. Setzt man den Eintrag wieder auf den Default oder auf leer ist die Abhängigkeit wieder gegeben. =item - B Auswahl von 'Programm' oder 'Jetzt' als Startmenü. =back =head3 1.4.2 EPG Menüs =over 4 =item - B Hier kann das Verhalten der 'Ok'-Taste bestimmt werden. Man kann damit die Inhaltsangabe anzeigen oder zum entsprechenden Sender wechseln. Hinweis: Die Funktion der Taste 'Blau' (Umschalten/Info/Suche) hängt von dieser Einstellung ab. =item - B Auswahl, ob man den Standard ('Aufnehmen') oder 'Befehle' als Vorbelegung möchte. =item - B Auswahl, ob man den Standard ('Umschalten') oder 'Suche' als Vorbelegung möchte. =item - B Im Menü 'Jetzt' kann ein Fortschrittsbalken angezeigt werden, der den Fortschritt der laufenden Sendung anzeigt. =item - B auswählen, um eine führende Programmnummer vor jedem EPG-Eintrag anzuzeigen. =item - B zur Anzeige einer Trennzeile zwischen Kanalgruppen im Menü 'Übersicht - Jetzt' ... =item - B zur Anzeige einer Trennzeile zwischen Sendungen unterschiedlicher Tage im Menü 'Programm'. =item - B Zeigt auch Radiokanäle an. =item - B Bei einer sehr großen Kanalliste läßt sich der Menü-Aufbau mit dieser Einstellung durch eine Einschränkung der angezeigten Kanäle beschleunigen. Mit '0' wird das Limit aufgehoben. Wenn der aktuelle Kanal über dem Limit liegt, wird das Limit ignoriert und wieder alle Kanäle angezeigt. =item - B Falls 'Ja' wird ein Timer sofort erzeugt, sobald man 'Aufnehmen' drückt, sonst wird das Timer-Edit-Menü angezeigt. =item - B zur Anzeige von Programmen ohne EPG, um auf diese umschalten zu können oder einen Timer zu programmieren =item - B Falls 'Ja' wird nach Drücken von 'Aufnahme' sofort ein Timer angelegt, falls 'Nein' erscheint das Timer-Edit-Menü. =item - B In den Menüs 'Programm', 'Jetzt', 'Nächste', 'Benutzerdef. Zeit 1', ... kann die angezeigte Zeit durch drücken von FastRew, FastFwd verschoben werden. Die Anzahl Minuten für den Sprung kann hier angepasst werden. =item - B Falls die Tasten FastRew, FastFwd auf der Fernbedienung nicht vorhanden sind, dann auf 'ja' setzen. Wenn die Taste '0' gedrückt wird, werden somit auch die Tasten Grün/Gelb auf z.B. '<<' und '>>' umgeschaltet. =item - B Das Favoritenmenü kann dazu verwendet werden, eine Liste von bevorzugten Sendungen anzuzeigen, die innerhalb der nächsten 24 Stunden laufen. Je nach Einstellung erscheint dieses Menü vor oder nach den EPG-Menüs mit benutzerdef. Zeiten. Die Auswahl von Sendungen wird durch setzen der Option 'In Favoriten-Menü verw.' innerhalb einer Suche geregelt. =item - B Mit diesem Wert wird die Zeitspanne eingestellt, für die Favoriten angezeigt werden sollen. =back =head3 1.4.3 Benutzerdef. EPG-Zeiten =over 4 =item - B Bis zu 4 benutzerdefinierte Zeiten können zu 'Jetzt' und 'Nächste' hinzugefügt werden. =item - B Name der benutzerdef. Zeit, z.B. 'Nachmittags', 'Abends', 'Spätabends'. =item - B zugehörige Uhrzeit. =back =head3 1.4.4 Timer-Programmierung =over 4 =item - B Beim normalen Programmieren eines Timers verwendet epgsearch ein erweitertes Timer-Edit-Menü, das einen Verzeichniseintrag, benutzerdefinierte Wochentage und die Vervollständigung um Untertitel anbietet. Falls man einen gepatchten VDR verwendet der ebenfalls ein erweitertes Timer-Edit-Menü anbietet und lieber dieses verwenden will, dann einfach diese Option auf 'Ja' setzen. =item - B Dieser Eintrag wird beim normalen Programmieren eines Timers verwendet. Man kann auch EPG-Variablen verwenden (z.B.. 'Meine Filme~%Category%~%Genre%'). Wird das Timer-Edit-Menü aufgerufen versucht epgsearch alle Variablen durch die Werte in der Beschreibung der Sendung zu ersetzen. Konnten nicht alle ersetzt werden, bleibt der Verzeichniseintrag leer. =item - B Beim manuellen Programmieren eines Timers kann epgsearch den Untertitel automatisch im Dateinamen ergänzen, wodurch die spätere Aufnahme in einem Unterverzeichnis für diese Episode gespeichert wird. Hier wählt man wie die Ergänzung gemacht werden soll. 'Intelligent' versucht zu prüfen, ob es Sinn macht und prüft dazu die Länge einer Sendung. Ist diese länger als 80min wird keine Untertitel ergänzt. =item - B Manuell angelegte Timer können auf Änderungen im EPG überprüft werden. Hier kann die Standardeinstellung für die Prüfmethode je Kanal hinterlegt werden. Folgende Prüfmethoden existieren: * ohne Überwachung * anhand Sendungskennung: geprüft wird anhand einer Kennung, die durch den Sender vergeben wird. (Achtung: nicht jeder Sender liefert vernünftige Kennungen!) * anhand Sender/Uhrzeit: geprüft wird anhand der Sendung, die am besten zur Dauer der ursprünglichen Sendung passt. Nicht alle Sender liefern eine vernünftige Sendungskennung. Deshalb kann hier die Standardeinstellung für jeden Kanal einzeln gesetzt werden. Bei der Programmierung eines manuellen Timers wird diese im Timer-Edit-Menü vorgegeben, falls das epgsearch-eigene Menü benutzt wird. =back =head3 1.4.5 Suche und Suchtimer =over 4 =item - B falls ja, untersucht das Plugin im Hintergrund die EPG-Daten und erzeugt Timer, falls passende Einträge gefunden werden. Dies betrifft nur Sucheinträge, die mit 'Als Suchtimer verwenden' markiert sind. Suchtimer werden immer lokal erzeugt, auch wenn ein anderer Defaulthost für Aufnahmen definiert ist. =item - B Das Intervall in Minuten, in dem die Hintergrundsuche vorgenommen wird. =item - B Falls nicht der Standard-SVDRP-Port 6419 (2001 vor vdr-1.7.15) verwendet wird, dann bitte hier anpassen, damit die Suchtimer funktionieren. =item - B Der Start des Suchtimer-Updatethreads und des folgenden Konflikt-Checks kann um 0...300 Sekunden nach VDR-Ready verzögert werden. Default sind 10 Sekunden =item - B Voreinstellungen =item - B zum Unterdrücken von Sendungs-Ankündigungen während einer aktiven Wiedergabe. =item - B epgsearch merkt sich standardmäßig welche Timer bereits durch Suchtimer angelegt wurden und programmiert diese nicht erneut, wenn sie gelöscht wurden. Zum Abschalten dieses Verhaltens bitte 'Ja' wählen. =item - B Falls EPG von externen Anbietern bezogen wird, kann es vorkommenm, dass hier auch mal etwas schiefläuft und somit wegen fehlendem EPG Aufzeichnungen verlorengehen. Hiermit kann geprüft werden, ob für die nächsten ... Stunden EPG bei den gewünschten Sendern vorhanden ist. Mit '0' wird die Prüfung deaktiviert. =item - C falls ja, erscheint die Warnung als OSD-Einblendung =item - C falls ja, wird die Warnung per Mail versandt. Bitte das Email-Konto unter Email-Benachrichtigung konfigurieren. =item - C hier die Kanalgruppe auswählen, für die die Prüfung durchgeführt werden soll. Gegebenefalls zuvor unter Kanalgruppen anlegen. =item - B Auf 'Ja' setzen, wenn man bei der Suche nach Wiederholungen keine Sendungen von PayTV-Sendern haben will. =item - B Hier können Suchvorlagen verwaltet werden, die beim Anlegen neuer Suchen verwendet werden können. =item - B Hier können Ausschlusslisten verwalten werden. Diese können innerhalb einer Suche verwendet werden um unerwünschte Sendungen zu vermeiden. Eine Ausschlussliste kann auch als global gekennzeichnet werden. Da die Standardeinstellung beim Suchtimer für die Option 'Ausschlusslisten verw.' auf 'nur globale' steht, kann man somit einfach unerwünschte Sendungen von allen Suchtimern ausschließen. Ausnahme: Falls beim Suchtimer die Option 'Ausschlusslisten verw.: keine' gewählt ist, hat eine globale Ausschlussliste keine Auswirkung. Ebenso werden globale Ausschlusslisten bei der Suche nach Wiederholungen über das OSD ignoriert. =item - B verwaltet die Kanalgruppen, die als Suchkriterium in einer Suche verwendet werden können. Die Verwaltung ist auch im Edit-Menü einer Suche möglich. =back B: wenn der EPG aus einer externen Quelle bezogen wird, sollte dafür gesorgt werden, dass die Suchtimer-Updates während des EPG-Updates abgeschaltet sind. Der Grund dafür ist, dass epgsearch Timer löscht, denen keine Sendungen zugeordnet sind. Während der neue EPG an VDR übermittelt wird, kann diese Situation auftreten. Am einfachsten geht das mit dem SVDRP-Befehl SETS im EPG-Update-Skript: svdrpsend plug epgsearch SETS off svdrpsend plug epgsearch SETS on =head3 1.4.6 Timer-Konflikt-Prüfung =over 4 =item - B Falls ein Timer fehlschlagen wird, dessen Priorität unter dem angegebene Wert liegt, wird darauf nicht per OSD-Nachricht hingewiesen und der Konflikt wird als 'nicht relevant' in der Konflikt-Übersicht angezeigt. =item - B Falls ein Konflikt nicht länger als die angegebene Anzahl Minuten dauert, wird darauf nicht per OSD-Nachricht hingewiesen und der Konflikt wird als 'nicht relevant' in der Konflikt-Übersicht angezeigt. =item - B Hier kann der Zeitraum der Prüfung angegeben werden. =item - B Falls SVDRPPeering aktiv ist, werden auch Konflikte bei entfernten Timern überpüft. Dazu muss am entsprechenden Remote-Rechner das epgsearch-Plugin ebenfalls aktiviert sein. Default ist nein. =item - B Das bewirkt eine Konfliktprüfung nach jeder manuellen Timer-Programmierung und erzeugt eine OSD-Nachricht, falls der neue/geänderte Timer in einen Konflikt verwickelt ist. =item - B Hier auf 'Ja' setzen, wenn die Konfliktprüfung beim Beginn jeder Aufnahme erfolgen soll. Im Falle eines Konflikts wird dann sofort eine Nachricht angezeigt. Diese erscheint nur, wenn der Konflikt innerhalb der nächsten 2 Stunden auftritt. =item - B Hier kann eingestellt werden, ob eine Konfliktprüfung nach jedem Suchtimer-Update erfolgen soll. Falls nicht: =item - B gibt an nach wievielen Minuten im Hintergrund eine automatische Konfliktprüfung erfolgen soll. Bei relevanten Konflikten erfolgt eine Nachricht per OSD. Mit '0' wird diese Funktion deaktiviert. =item - B Wenn nächster Konflikt in ... Minuten eintritt, verwende folgendes Prüfintervall. =over 4 =item - B um einen Konflikt in Kürze nicht zu übersehen, kann hier ein kürzeres Prüfintervall eingestellt werden. =back =item - B Bitte auf 'Ja' setzen, wenn während einer Wiedergabe keine OSD-Benachrichtigungen über Timer-Konflikte gewünscht sind. Die Benachrichtigung erfolgt trotzdem, wenn der nächste Konflikt innerhalb der nächsten 2 Stunden auftritt. =back Bitte ebenfalls den Abschnitt 'Working with the timer conflict menu' im MANUAL berücksichtigen. =head3 1.4.7 Email-Benachrichtigungen (Bitte sicherstellen, dass 'sendEmail.pl' im Pfad der ausführbaren Dateien liegt und 'epgsearchupdmail.templ' und 'epgsearchconflmail.templ' im Konfig-Verzeichnis von epgsearch existieren!) =over 4 =item - B Diese Option aktivieren, wenn man eine Email-Benachrichtigung wünscht, sobald der Suchtimer-Hintergrund-Thread - neue Timer angelegt hat - vorhandene Timer geändert hat - Timer gelöscht hat, weil diese wegen EPG-Änderungen oder anderen Benutzeraktionen nicht mehr gültig sind. (Dazu muss ebenfalls die Option 'Verwende Suchtimer' im Suchtimer-Setup aktiv sein.) =item - B Für Benachrichtigungen zu Suchtimern kann hier angegeben werden, welchen Mindestabstand in Stunden die Mails haben sollen. Sobald die entsprechende Zeit verstrichen ist, wird eine Mail nach dem nächsten Suchtimer-Update versandt. Der Wert '0' bedeutet keine Verzögerung und bewirkt einen sofortigen Mailversand. =item - B Diese Option aktivieren, wenn man eine Email-Benachrichtigung bei Timer-Konflikten wünscht. Es werden nur Konflikte gemeldet, die laut Setup-Einstellungen 'relevant' sind. Neue Benachrichtigungen werden nur versandt, sobald sich etwas bei den Konflikten verändert. (Dazu muss ebenfalls die Option 'Nach jedem Suchtimer-Update' oder 'nach ... Minuten' im Timer-Konflikt-Setup aktiv sein.) =item - B Hier bitte die volle (!) Email-Adresse hinterlegen, an die die Nachrichten verschickt werden sollen. Hinweis: Einigen Provider (z.B. Arcor) erlauben nicht die gleiche Adresse für Sender und Empfänger. =item - B Zur Auswahl stehen - sendEmail.pl: ein einfaches Skript, das auch auf Systemen ohne konfigurierten Mailserver den Versand von Emails erlaubt. Das Skript wird mit epgsearch ausgeliefert und sollte im $PATH liegen. - sendmail: setzt ein korrekt aufgesetzes Mailsystem voraus. =item - B Hier bitte die volle (!) Email-Adresse hinterlegen, von der die Nachricht versandt werden soll. =item - B Der Name des SMTP Servers, über den der Mailversand erfolgt. =item - B 'Ja' wählen wenn das Emailkonto eine SMTP-Authentifizierung für den Emailversand benötigt. =item - B Hier bitte den Benutzernamen angeben, falls das Email-Konto mit Authentifizierung arbeitet. =item - B Hier bitte das Passwort angeben, falls das Email-Konto mit Authentifizierung arbeitet. Achtung: Das Passwort wird im Klartext gespeichert. Man muss selber dafür sorgen, dass das System sicher ist und nicht authorisierten Personen kein Zugriff auf VDR-Konfigurations-Dateien möglich ist. =back Nach Angabe der Email-Konto-Daten bitte mit 'Test' prüfen, ob alles funktioniert. Wenn mit 'sendEmail.pl' gearbeitet wird, sollte am Ende der Test-Ausgabe etwas wie 'Email sent successfully' auftauchen. Die Testfunktion gibt es bei der Methode 'sendmail' leider nicht. Bitte ebenfalls den Abschnitt 'Email notifications' im Manual berücksichtigen. =head1 2. Suchtimer Das ist ziemlich das gleiche wie VDRAdmin's Autotimer, benötigt jedoch kein externes Programm. Beim Anlegen einer Suche kann man die Option setzen, ob diese als Suchtimer verwendet werden soll. Das Plugin sucht nun im Hintergrund in bestimmten Zeitabständen (->Setup->Update Intervall [min]) nach passenden Sendungen und erzeugt Timer für die Ergebnisse. Gerade für Serien ist dies sehr praktisch, weshalb es in der Suche die Option "Serienaufnahme" gibt. In diesem Fall wird ein Timer mit zusätzlichem Episodennamen angelegt. Die Aufnahme erscheint dann in einem Ordner mit dem Seriennamem. Falls es keinen Episodennamen gibt wird stattdessen automatisch Datum und Uhrzeit verwendet. Die Suchtimer-Funktion muss ausserdem im Setup aktiviert werden. Falls für SVDRP nicht der Standardport verwendet wird, bitte ebenfalls im Setup eintragen. Falls man eine Hintergrund-Suche manuell anstoßen will, genügt ein touch /etc/vdr/plugins/epgsearch/.epgsearchupdate Das kann ebenfalls Teil des shutdown-Skripts sein (hier sollte man dann noch einen sleep von ein paar Sekunden anhängen, damit das Plugin Zeit hat, den Scan zu beenden). Mehr Infos zu Suchtimern gibts im MANUAL unter 'Description of the search process' und 'How do Search Timers work?'. =head1 2.1 'Wiederholungen vermeiden' - Im Detail Hier soll erklärt werden wie die Option 'Wiederholungen vermeiden' eines Suchtimers funktioniert. Nicht immer lässt sich durch entsprechende Suchkriterien vermeiden, dass auch Timer für Wiederholungen erzeugt werden. Um das zu verhindern, versucht das Feature 'Wiederholungen vermeiden' vor dem Programmieren einer Sendung zu prüfen, ob eine gleiche Sendung schon mal aufgenommen wurde oder ein Timer existiert, der die gleiche (nicht dieselbe!) Sendung aufzeichnet. Ist dies der Fall, wird kein Timer für die zu überprüfende Sendung erzeugt. =head2 2.2 Wie funktioniert der Vergleichstest zwischen 2 Sendungen? Für den Test auf Gleichheit zwischen 2 Sendungen gibt es viele Einstellmöglichkeiten beim Suchtimer. Man kann wählen, ob Titel, Untertitel, Beschreibung und bestimmte Kategorien innerhalb der Beschreibung einer Sendung mit den jeweiligen Angaben einer anderen Sendung verglichen werden sollen. Der Vergleich der einzelnen Angaben selbst prüft immer auf vollständige Identität. Die Beschreibung einer Sendung bildet hier aber eine Ausnahme. Hier wird zunächst alles aus dem Text entfernt, das einer Kategorie-Angabe gleicht, z.B. 'Bewertung: Tagestipp'. Als Kategorie-Angabe wird alles gewertet, was am Anfang einer Zeile maximal 40 Zeichen hat, von einem ':' gefolgt wird und dann maximal weitere 60 Zeichen hat. Hintergrund für dieses Rausschneiden sind die oft vorhandenen Bewertungen wie 'Tagestipp', die bei der Wiederholung aber nicht mehr enthalten sind. Der verbleibende Text wird nun zunächst in der Länge verglichen. Ist der Unterschied größer als 90% wird die Beschreibung als unterschiedlich gewertet. Andernfalls wird über den Levinsthein-Distance-Algorithmus (LD), der einen Fuzzy-Textvergleich macht, ein Test vorgenommen. Hier wird die Beschreibung als gleich akzeptiert, wenn LD mehr als 90% Identität zurückgibt. Da dieser Algorithmus ziemlich laufzeitintensiv ist (O(mn)), sollte nach Möglichkeit nicht nur 'Vergleiche Beschreibung' als einziges Vergleichskriterium ausgewählt werden, sondern am besten immer nur in Kombination mit anderen Vergleichen. =head2 2.3 Wie und wo wird der Vergleichstest eingesetzt? Wie zuvor erwähnt wird bei einem Suchtimer-Update für Suchtimer mit diesem Feature zusätzlich geprüft, ob eine Sendung bereits irgendwann schon aufgezeichnet wurde, oder in der Timerliste ein Timer steht, der die gleiche Sendung aufzeichnen würde. Letzteres sollte klar sein, während für ersteres das File epgsearchdone.data ins Spiel kommt. Nach jeder Aufnahme, die durch einen Suchtimer mit 'Wiederholung vermeiden' erzeugt wurde, werden alle Angaben zu dieser Sendung im genannten File gespeichert. Über das Aktionenmenü im Menü 'Suche' kann man sich alle Sendungen, die ein solcher Timer bisher aufgenommen hat, anzeigen lassen und diese auch bearbeiten. In dieses File werden nur Aufnahmen aufgenommen, die bezüglich der Timerangaben korrekt begonnen und auch beendet wurden. D.h. dass teilweise unvollständige Aufnahmen nicht registriert werden und somit beim nächsten Suchtimer-Update automatisch ein neuer Timer für diese Sendung erzeugt wird, falls gefunden. B Man sieht, dass das ganze Feature stark von der Qualität und dem Umfang des verwendeten EPGs abhängt. Hat man einen entsprechenden Suchtimer angelegt, ist es sinnvoll erstmal zu prüfen, ob er auch das richtige macht. Dazu gibt es für solche Timer im Suchergebnis-Menü auf der Taste 'Blau' die zusätzliche Belegung 'Timer-Vorschau'. Sendungen, die noch keinen Timer haben ('T'), aber für die einer aufgrund des Features beim nächsten Suchtimer-Update programmiert würde, haben dort ein 'P' stehen. Hinweis: Möchte man wegen Konflikten einen bereits programmierten Timer nicht verwenden, dann sollte dieser im Timermenü deaktiviert werden. Beim nächsten Suchtimer-Update wird dann einfach die nächste mögliche Wiederholung programmiert, falls vorhanden. B Damit das Programmieren oder Nicht-Programmieren von Timern gerade bei Verwendung dieses Features besser nachvollziehbar ist, wurde ein Logfile für epgsearch eingeführt. Startet man epgsearch mit einem Loglevel >= 2 (-P'epgsearch -v 2) werden beim Suchtimer-Update in der Datei epgsearch.log hilfreiche Infos abgelegt. Siehe MANUAL für 'command line options'. =head1 3. Verwendung der Suche durch andere Plugins oder Skripte Siehe C. =head1 4. Verwendung erweiterter EPG Infos Einige EPG Provider liefern zusätzliche EPG Infos wie die Art der Sendung, das Video und Audio Format, die Besetzung,... in der Beschreibung der Sendung. Anmerkung: Dies hat nichts mit den content descriptors seit vdr-1.7.11 zu tun, die als zusätzliche Daten nach einem gemeinsamen Standard aufgeliefert werden. Leider liefern nicht alle Provider diese Daten oder setzen die Kennungen nicht korrekt. Deshalb gibt es den Ansatz der "erweiterten EPG Infos", der versucht diese Information aus der Inhaltsbeschreibung zu extrahieren. Mit tvmovie2vdr oder epg4vdr können diese Daten in den VDR importiert werden. Somit kann man also z.B. einfach einen Suchtimer erzeugen, der alle Tagestipps findet, die in 16:9 ausgestrahlt werden. Um diese Informationen in Suchtimern zu verwenden, muss anhand der Datei epgsearchcats.conf im epgsearch-Konfig-Verzeichnis eine Konfiguration vorgenommen werden. Das Format dieser Datei ist folgendes: ID|category name|name in menu|values separated by ','(option)|searchmode(option) - 'ID' sollte eine eindeutige ganze Zahl sein Achtung: Ändert man später aus irgendeinem Grund diese ID müssen die Suchtimer neu editiert werden! - 'category name' ist der Name der Info lt. EPG Provider, z.B. 'Genre' - 'name in menu' ist der Name im Menü von epgsearch. - 'values' ist eine optionale Liste von Werten für diese Info. - 'searchmode' gibt optional an, wie gesucht werden soll: Textvergleich: 0 - Der gesamte Begriff muss als Substring erscheinen 1 - Die einzelnen Worte (getrennt durch ',', ';', '|' oder '~') müssen alle als Substring auftauchen. Diese Einstellung ist der Standardwert. 2 - mindestens ein Wort (getrennt durch ',', ';', '|' oder '~') muss als Substring auftauchen 3 - exakte Übereinstimmung 4 - als regulärer Ausdruck Numerischer Vergleich: 10 - kleiner 11 - kleiner oder gleich 12 - größer 13 - größer oder gleich 14 - gleich 15 - ungleich Beispiel-Dateien für epgsearchcats.conf kommen mit dem Plugin im Verzeichnis 'conf'. Einfach die passende ins epgsearch-Konfig-Verzeichnis als epgsearchcats.conf kopieren, VDR neu starten und dann das Eingabe-Menü eines Suchtimers aufrufen. Weil das Aufsetzen einer neuen epgsearchcats.conf ziemlich lästig ist, habe ich ein kleines Tool 'createcats' mitgeliefert, das den Großteil der Arbeit erledigt. Es sollte mit dem Plugin übersetzt worden sein und sich im Quellverzeichnis befinden. Einfach folgendermaßen aufrufen: createcats /pfad_zu/epg.data Dieses Tool scannt nun die vorhandenen EPG infos und versucht daraus die erweiterten Infos zu extrahieren. Das Ergebnis ist eine neue epgsearchcats.conf, die aber noch editiert werden muss, weil sicher nicht alles genau passt. Danach ins epgsearch-Konfig-Verzeichnis kopieren. (Mehr über createcats im Manual 'Using createcats') Details: epgsearch durchsucht die Zusammenfassung einer Sendung nach dem Namen einer Kategorie gefolgt von ': '. Das geschieht für alle Kategorien, für die im Suchtimer ein Wert gesetzt wurde. Die Suche berücksichtigt die Groß/Kleinschreibung sowohl bezüglich des Kategorie-Namens als auch des Wertes. =head1 5. Ersetzen des Standardmenü Um das Plugin als Ersatz für VDR's Standard-Menü zu verwenden, genügt es die Zeile Green @epgsearch in die Datei keymacros.conf zu setzen. Falls kein weiterer Menüeintrag im Hauptmenü erscheinen soll, dann den Eintrag des Plugins zunächst im Setup ausblenden. Um das Plugin trotzdem mit der Taste "Grün" aufrufen zu können, könnte man z.B. mein launcher-Plugin verwenden und die Zeile Green @launcher x in die keymacros.conf schreiben, wobei x die Position von epgsearch innerhalb des launcher listings ist. Ein weiterer Ansatz ist ein Patch gegen VDR, der das Standardmenü 'Programm' gegen epgsearch austauscht. Hierzu VDR mit dem Patch vdr-replace-schedulemenu.diff.gz aus dem Patches-Verzeichnis patchen. Danke an den Autor Uwe/egal@vdrportal. Bei Anwendung dieses Patches sollte der Eintrag Green Schedule heißen. Dieser Patch ist bereits in manchen Patchsammlungen, z.B. Bigpatch, enthalten. =head1 6. Addons Mit epgsearch werden 2 weitere 'Mini'-Plugins ausgeliefert. Beide Plugins erfordern, dass epgsearch ebenfalls installiert ist (epgsearch kann aber aus dem Hauptmenü ausgeblendet werden): =over 4 =item - B Wer nur die Suchfunktionen und/oder die Suchtimer von epgsearch verwenden möchte oder einfach einen eigenen Hauptmenüeintrag für die Suche wünscht, kann dies mit diesem Plugin erreichen. Es wird damit ein Hauptmenüeintrag "Suche" erzeugt, der einen direkt in das Suchenmenü führt. Aktivierung im VDR-Startskript mit "-Pepgsearchonly". =item - B Die Timer-Konfliktprüfung kann ebenfalls als eigener Hauptmenüeintrag angelegt werden. Über eine Setup-Option läßt sich auch das Ergebniss der letzten Konfliktprüfung direkt im Hauptmenü anzeigen. Aktivierung im VDR-Startskript mit "-Pconflictcheckonly". =back Viel Spass! Christian Wieninger =head1 Ausführliche Beschreibung Die ausführliche Beschreibung der internen Funktionen des Plugins findest Du in der Datei MANUAL, die dem Plugin beigelegt sein sollten. Ob Du diese auf deinem System hast verrät dir C Sollte Deine Distribution diese Dateien nicht enthalten, kannst Du sie dir online durchlesen L L L =head1 SIEHE AUCH C, C, C, C, C, C, C, C, C, C =head1 DATEIEN F Enthält die Suchtimer. Siehe C. F Enthält die Kategorien des erweiterten EPG. Siehe C. F Enthält Befehle ähnlich der commands.conf, die auf EPG-Einträge angewandt werden können. Siehe C. F Enthält Pfade die beim Bearbeiten eines Suchtimers ausgewählt werden können. Siehe C. F Enthält die vom User gewählte Konfiguration der OSD Menüdarstellung. Siehe C. F Enthält die User-Variablen. Siehe C. F Enthält die done-Liste. Siehe C. F Enthält die Umschalttimer. Siehe C. F Enthält die Ausschlussliste. Siehe C. F Enthält die Kanalgruppen. Siehe C. F Enthält die Vorlagen für Suchtimer. Siehe C. =head1 AUTOR (man pages) Mike Constabel =head1 FEHLER MELDEN Fehlerberichte bitte im Bugtracker. L Mailinglist: L =head1 COPYRIGHT and LIZENZ Copyright © 2004-2010 Christian Wieninger Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Oder rufen Sie in Ihrem Browser http://www.gnu.org/licenses/old-licenses/gpl-2.0.html auf. Der Author kann über cwieninger@gmx.de erreicht werden. Die Projektseite ist http://winni.vdr-developer.org/epgsearch Der MD5-Code ist abgeleitet aus dem Message-Digest Algorithm von RSA Data Security, Inc.. vdr-plugin-epgsearch-2.4.1/doc-src/de/epgsearch.conf.5.txt000066400000000000000000000125151405273211300232610ustar00rootroot00000000000000=encoding utf8 =head1 NAME F - Die gespeicherten Suchtimer =head1 BESCHREIBUNG Die in epgsearch angelegten Suchtimer werden in dieser Datei gespeichert. Sie sollte nicht manuell editiert werden. Verwende stattdessen lieber SVDRP. =head1 FORMAT Aufgrund von möglichen Formatänderungen enthält die Datei eine Versionsangabe. Die Format-Version befindet sich in der ersten Zeile der Datei. Der allgemeine Feldtrenner ist C<':'>. Folgende Felder sind möglich: 1 - Einmalige Suchtimer ID 2 - Suchstring 3 - Verwende Zeit? 0/1 4 - Startzeit in HHMM 5 - Stopzeit in HHMM 6 - Verwende Kanal? 0 = nein, 1 = Intervall, 2 = Kanalgruppe, 3 = nur FTA 7 - Wenn 'verwende Kanal' = 1 dann ist Kanal ID[|Kanal ID] im VDR Format, Einträge oder min/max Einträge getrennt durch |, wenn 'Verwende Kanal' = 2 dann der Kanalgruppenname 8 - Beachte Gross-/Kleinschreibung? 0/1 9 - Suchmodus: 0 - Der gesamte Suchbegriff muss genau so enthalten sein 1 - Alle Suchbegriffe (Trenner sind Leerzeichen,',', ';', '|' oder '~') müssen enthalten sein. 2 - Mindestens ein Suchbegriff muss enthalten sein (Trenner sind Leerzeichen, ',', ';', '|' oder '~'). 3 - Der Suchbegriff muss genau zutreffen 4 - Regulärer Ausdruck 10 - Suche in Titel? 0/1 11 - Suche in Untertitel? 0/1 12 - Suche in Beschreibung? 0/1 13 - Verwende Länge? 0/1 14 - Minimale Länge der Sendung in HHMM 15 - Maximale Länge der Sendung in HHMM 16 - Verwende als Suchtimer? 0/1 17 - Verwende Tag der Woche? 0/1 18 - Tag der Woche (0 = Sonntag, 1 = Montag...; -1 Sonntag, -2 Montag, -4 Dienstag, ...; -7 So, Mo, Di) 19 - Verwende als Serienaufnahme? 0/1 20 - Verzeichnis für Aufnahme 21 - Priorität der Aufnahme 22 - Lebensdauer der Aufnahme 23 - Zeitpuffer am Anfang in Minuten 24 - Zeitpuffer am Ende in Minuten 25 - Verwende VPS? 0/1 26 - Aktion: 0 = Lege Timer an 1 = Benachrichtige nur per OSD (kein Timer) 2 = Schalte nur um (kein Timer) 27 - Verwende erweitertes EPG? 0/1 28 - Felder des erweiterten EPGs. Dieser Eintrag hat folgendes Format (Trenner ist '|' für jede Kategorie, '#' trennt ID vom Wert): 1 - Die ID der Kategorie des erweiterten EPGs, festgelegt in F, s. C 2 - Wert des erweiterten EPGs für diese Kategorie (Ein ':' wird übersetzt in "!^colon^!", z.B. "16:9" -> "16!^colon^!9") 29 - vermeide Wiederholungen? 0/1 30 - erlaubte Anzahl Wiederholungen 31 - Vergleiche Titel bei Prüfung auf Wiederholung? 0/1 32 - Vergleiche Untertitel bei Prüfung auf Wiederholung? 0/1 0 - Nein 1 - Ja 2 - Ja oder beide leer 33 - Vergleiche Beschreibung bei Prüfung auf Wiederholung? 0/1 34 - Vergleiche erweitertes EPG bei Prüfung auf Wiederholung? Dieser Eintrag ist ein Bitfeld von Kategorie IDs. 35 - Erlaube Wiederholungen nur innerhalb x Tagen 36 - Lösche eine Aufnahme automatisch nach x Tagen 37 - Aber behalte mindestens x Aufnahmen 38 - Schalte x Minuten vor der Sendung um, wenn Aktion = 2 39 - Pausiere das Anlegene von Timern wenn x Aufnahmen vorhanden sind 40 - Modus der Ausschlussliste: 0 = Aus, 1 = Wähle aus, 2 = Alle 41 - Verwende diese Ausschluss-Suchtimer, IDs getrennt durch '|' 42 - Fuzzy Toleranz für Suche 43 - Verwende diese Suche im Favoriten Menü, 0 = Nein, 1 = Ja 44 - ID einer Menüvorlage für das Suchergebnis Folgende Zeichen werden bei der Speicherung übersetzt: : => | | => !^pipe^! Es müssen nicht alle Felder belegt sein. Gefordert sind lediglich die ersten 11. =head1 BEISPIELE #version 2 - DONT TOUCH THIS! 1:Kommissar Beck:0:::2:ÖffRecht:0:0:1:0:0:0:::1:0:0:1:%Category%~%Genre%:50:99:10:60:0:0:0::1:0:1:1:0:0:0:0:0 2:* Sägebrecht:0:::2:Hauptsender:0:0:0:0:0:0:::0:0:0:0:%Category%~%Genre%:50:99:10:10:0:0:1:1#|2#|3#|4#|5#|6#Marianne Sägebrecht|7#|8#|9#|10#|11#|12#|13#:1:0:1:0:0:0:0:0:0 =head1 SIEHE AUCH C =head1 AUTOR (man pages) Mike Constabel =head1 FEHLER MELDEN Fehlerberichte bitte im Bugtracker. L Mailinglist: L =head1 COPYRIGHT and LIZENZ Copyright © 2004-2010 Christian Wieninger Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Oder rufen Sie in Ihrem Browser http://www.gnu.org/licenses/old-licenses/gpl-2.0.html auf. Der Author kann über cwieninger@gmx.de erreicht werden. Die Projektseite ist http://winni.vdr-developer.org/epgsearch Der MD5-Code ist abgeleitet aus dem Message-Digest Algorithm von RSA Data Security, Inc.. vdr-plugin-epgsearch-2.4.1/doc-src/de/epgsearchblacklists.conf.5.txt000066400000000000000000000043521405273211300253350ustar00rootroot00000000000000=encoding utf8 =head1 NAME F - Die gespeicherten Auschlusslisten-Suchtimer =head1 BESCHREIBUNG In epgsearch können Ausschlusslisten (Blacklists) angelegt werden. Dies sind im Grunde normale Suchtimer die in der Datei F gespeichert werden. Zu jedem Suchtimer kann man dann einen oder mehrere Einträge aus der Ausschlussliste auswählen. =head2 Funktion Suchtimer "Krimi" verwendet Ausschlusssuchtimer "Tatort" Ausschlusssuchtimer "Tatort" sucht "Tatort" Es werden alle Krimis gesucht und anschliessend wird nachgesehen ob ein Ergebnisse auf den Ausschlusssuchtimer zutrifft. Dieses wird dann verworfen. =head1 FORMAT Diese Datei hat dasselbe Format wie die Datei F. Für den Aufbau verweise ich auf C. =head1 SIEHE AUCH C =head1 AUTOR (man pages) Mike Constabel =head1 FEHLER MELDEN Fehlerberichte bitte im Bugtracker. L Mailinglist: L =head1 COPYRIGHT and LIZENZ Copyright © 2004-2010 Christian Wieninger Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Oder rufen Sie in Ihrem Browser http://www.gnu.org/licenses/old-licenses/gpl-2.0.html auf. Der Author kann über cwieninger@gmx.de erreicht werden. Die Projektseite ist http://winni.vdr-developer.org/epgsearch Der MD5-Code ist abgeleitet aus dem Message-Digest Algorithm von RSA Data Security, Inc.. vdr-plugin-epgsearch-2.4.1/doc-src/de/epgsearchcats.conf.5.txt000066400000000000000000000110111405273211300241220ustar00rootroot00000000000000=encoding utf8 =head1 NAME F - Die Kategorien des erweiterten EPGs, sofern vorhanden. =head1 BESCHREIBUNG Wenn man das EPG aus dem Internet bezieht, z.B. von Hörzu, enthält das EPG erweiterte Daten. Zusätzlich zum Titel, Untertitel un der Beschreibung findet man dann eine Liste der Darsteller, Jahr des Drehs, Episode der Serie, Kategorie und Genre des Film, etc. Damit epgsearch diese verwenden kann müssen die Felder des erweiterten EPGs Variablen zugeordnet werden. Einige Beispieldateien werden dem Plugin mitgeliefert und finden sich im Verzeichnis "conf". Um eine eigene F zu erstellen dient das mitgelieferte Tool F. Es scannt das vorhandene EPG und erstellt eine F. Diese sollte an die eigenen Wünscche angepasst werden, eine Formatbeschreibung findet sich im Kopf der Datei. =head1 FORMAT Auszug aus einer F: -------------------------------------------------------------------- This is just a template based on your current epg.data. Please edit! Perhaps a category or its value list should be removed. Also the 'name in menu' should be adjusted to your language. The order of items determines the order listed in epgsearch. It does not depend on the ID, which is used by epgsearch. Format: ID|category name(,format)|name in menu|values separated by ',' (option)|searchmode - 'ID' should be a unique positive integer (changing the id later on will force you to reedit your search timers!) - 'category name' is the name in your epg.data you can optionally add a format specifier for numeric values e.g. Episode,%02i - 'name in menu' is the name displayed in epgsearch. - 'values' is an optional list of possible values if you omit the list, the entry turns to an edit field in epgsearch, else it's an list of items to select from - 'searchmode' is an optional parameter specifying the mode of search: text comparison: 0 - the whole term must appear as substring 1 - all single terms (delimiters are ',', ';', '|' or '~') must exist as substrings. This is the default search mode. 2 - at least one term (delimiters are ',', ';', '|' or '~') must exist as substring. 3 - matches exactly 4 - regular expression numerical comparison: 10 - less 11 - less or equal 12 - greater 13 - greater or equal 14 - equal 15 - not equal -------------------------------------------------------------------- =head1 BEISPIELE (Die Zeilen sind gekürzt, daher unvollständig) Beispiel für EPG von Hörzu, bezogen von epgdata.com mit tvmovie2vdr. 1|Category|Kategorie|Information,Kinder,Musik,Serie,Show,Spielfilm,Sport|2 2|Genre|Genre|Abenteuer,Action,Wirtschaft,Wissen,Zeichentrick|2 3|Format|Video-Format|16:9,4:3|2 4|Audio|Audio|Dolby Surround,Dolby,Hoerfilm,Stereo|2 5|Year|Jahr||2 6|Cast|Besetzung||2 7|Director|Regisseur||2 8|Moderator|Moderation||2 9|Rating|Bewertung|Großartig besonders wertvoll,Annehmbar,Schwach|2 10|FSK|FSK|6,12,16,18|2 11|Country|Land||2 12|Episode|Episode||4 13|Themes|Thema||4 =head1 SIEHE AUCH C =head1 AUTOR (man pages) Mike Constabel =head1 FEHLER MELDEN Fehlerberichte bitte im Bugtracker. L Mailinglist: L =head1 COPYRIGHT and LIZENZ Copyright © 2004-2010 Christian Wieninger Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Oder rufen Sie in Ihrem Browser http://www.gnu.org/licenses/old-licenses/gpl-2.0.html auf. Der Author kann über cwieninger@gmx.de erreicht werden. Die Projektseite ist http://winni.vdr-developer.org/epgsearch Der MD5-Code ist abgeleitet aus dem Message-Digest Algorithm von RSA Data Security, Inc.. vdr-plugin-epgsearch-2.4.1/doc-src/de/epgsearchchangrps.conf.5.txt000066400000000000000000000042441405273211300250070ustar00rootroot00000000000000=encoding utf8 =head1 NAME F - Liste der Kanalgruppen =head1 BESCHREIBUNG In epgsearch kann man Sender zu Kanalgruppen zusammenfassen die dann in den Suchtimern verwendet werden können. Hierdurch können für viele Suchtimer auf einmal die durchsuchten Kanäle zentral neu konfiguriert werden. In dieser Datei werden die Kanalgruppen gespeichert. =head1 FORMAT Jede Zeile eine Kanalgruppe. Jede Zeile beginnt mit dem Gruppennamen, dahinter, getrennt durch '|', die Liste der Kanäle. =head1 BEISPIELE (Die Zeilen sind gekürzt, daher unvollständig) Private|S19.2E-133-33-46|S19.2E-133-33-51 ProsiebenSat.1|S19.2E-133-33-46|S19.2E-133-33-47 RTL World|S19.2E-1-1089-12003||S19.2E-1-1089-12090 =head1 SIEHE AUCH C =head1 AUTOR (man pages) Mike Constabel =head1 FEHLER MELDEN Fehlerberichte bitte im Bugtracker. L Mailinglist: L =head1 COPYRIGHT and LIZENZ Copyright © 2004-2010 Christian Wieninger Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Oder rufen Sie in Ihrem Browser http://www.gnu.org/licenses/old-licenses/gpl-2.0.html auf. Der Author kann über cwieninger@gmx.de erreicht werden. Die Projektseite ist http://winni.vdr-developer.org/epgsearch Der MD5-Code ist abgeleitet aus dem Message-Digest Algorithm von RSA Data Security, Inc.. vdr-plugin-epgsearch-2.4.1/doc-src/de/epgsearchcmds.conf.5.txt000066400000000000000000000045151405273211300241310ustar00rootroot00000000000000=encoding utf8 =head1 NAME F - EPG-Befehle =head1 BESCHREIBUNG Diese Datei enthält ähnlich der commands.conf oder der reccmds.conf Befehle, die auf die in der Programmübersicht ausgewählte Sendung angewandt werden können. Intern besitzt epgsearch 8 nicht veränderbare EPG-Befehle. Wenn eine F existiert, werden die darin aufgeführten Befehle beginnend mit Nummer 9 gelistet. =head2 Sprachen Man kann für verschiedene Sprachen unterschiedliche Dateien anlegen. Sie müssen dann z.B. F für deutsch oder F für englisch heissen. Wenn eine Datei entsprechend der im VDR eingestellten Sprache existiert wird diese geladen. Existiert eine solche nicht wird versucht F zu laden. =head1 FORMAT Befehlsname : Befehl =head1 BEISPIELE epg2taste (de): /usr/local/vdr/epg2taste.sh =head1 SIEHE AUCH C =head1 AUTOR (man pages) Mike Constabel =head1 FEHLER MELDEN Fehlerberichte bitte im Bugtracker. L Mailinglist: L =head1 COPYRIGHT and LIZENZ Copyright © 2004-2010 Christian Wieninger Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Oder rufen Sie in Ihrem Browser http://www.gnu.org/licenses/old-licenses/gpl-2.0.html auf. Der Author kann über cwieninger@gmx.de erreicht werden. Die Projektseite ist http://winni.vdr-developer.org/epgsearch Der MD5-Code ist abgeleitet aus dem Message-Digest Algorithm von RSA Data Security, Inc.. vdr-plugin-epgsearch-2.4.1/doc-src/de/epgsearchdirs.conf.5.txt000066400000000000000000000057451405273211300241520ustar00rootroot00000000000000=encoding utf8 =head1 NAME F - Liste von Aufnahmepfaden zur einfachen Auswahl =head1 BESCHREIBUNG In epgsearch, speziell beim Editieren von Suchtimern, muss man häufig ganze Verzeichnisspfade eingeben. Da dies oft mühselig ist, können in dieser Datei häufig genutzte Pfade vorgegeben werden, die dann im Menü einfach ausgewählt werden können. =head1 FORMAT Pro Zeile ein Pfad. Pfade können Variablen enthalten. Verwendet werden können interne Variablen, die Variablen des erweiterten EPG (F) sowie die in der Datei F konfigurierten Variablen. Folgende internen Variablen stehen zur Verfügung: %title% - Title der Sendung %subtitle% - Subtitle der Sendung %time% - Startzeit im Format HH:MM %date% - Startzeit im Format TT.MM.YY %datesh% - Startdatum im Format TT.MM. %time_w% - Name des Wochentages %time_d% - Tag der Sendung im Format TT %chnr% - Kanalnummer %chsh% - Kanalname kurz %chlng% - Kanalname lang Für weitere Variablen siehe C und C. Im Auswahlmenü werden die Pfade alphabetisch sortiert dargestellt. Pfade die Variablen enthalten stehen am Anfang der Liste. =head1 BEISPIELE %Category%~%Genre% %Category%~%Genre%~%Title%~%Episode%: %Subtitle% Information~Natur~%Title%~%Episode%: %Subtitle% %Serie% Spielfilm~Action Spielfilm~Doku Spielfilm~Drama Spielfilm~Horror Musik Sport Show Serie =head1 SIEHE AUCH C, C, C =head1 AUTOR (man pages) Mike Constabel =head1 FEHLER MELDEN Fehlerberichte bitte im Bugtracker. L Mailinglist: L =head1 COPYRIGHT and LIZENZ Copyright © 2004-2010 Christian Wieninger Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Oder rufen Sie in Ihrem Browser http://www.gnu.org/licenses/old-licenses/gpl-2.0.html auf. Der Author kann über cwieninger@gmx.de erreicht werden. Die Projektseite ist http://winni.vdr-developer.org/epgsearch Der MD5-Code ist abgeleitet aus dem Message-Digest Algorithm von RSA Data Security, Inc.. vdr-plugin-epgsearch-2.4.1/doc-src/de/epgsearchmenu.conf.5.txt000066400000000000000000000115371405273211300241510ustar00rootroot00000000000000=encoding utf8 =head1 NAME F - Konfiguration der Menüdarstellung =head1 BESCHREIBUNG Die Darstellung des Menüs des Plugins kann auf die eigenen Wünsche angepasst werden. Die Konfiguration erfolgt mit Hilfe dieser Datei. =head1 FORMAT In dieser Datei können den Variablen MenuWhatsOnNow MenuWhatsOnNext MenuWhatsOnElse MenuSchedule MenuSearchResults Zeichenketten zugewiesen werden die die Darstellung der Menüs im OSD regeln. Eine Besonderheit stellt MenuSearchResults. Hier kann man der Variablen MenuSearchResults eine beliebige Zeichenkette anhängen: MenuSearchResultsSerienlayout=... Dies bewirkt das man beim Editieren eines Suchtimers nun auch dieses Layout unter dem Namen "Serienlayout" auswählen kann. So kann man jedem Suchtimer seine eigene OSD Darstellung verpassen. Es können alle Variablen verwendet werden. Die Variablen aus dem erweiterten EPG, die in der F konfigurierten sowie die folgenden internen: %title% - Title der Sendung %subtitle% - Subtitle der Sendung %time% - Startzeit im Format HH:MM %date% - Startzeit im Format TT.MM.YY %datesh% - Startdatum im Format TT.MM. %time_w% - Name des Wochentages %time_d% - Tag der Sendung im Format TT %time_lng% - Startzeit in Sekunden seit 1970-01-01 00:00 %t_status% - Timerstatus ('T', 't', 'R') %v_status% - VPS Status %r_status% - Running Status %status% - Kompletter Status, das selbe wie '%t_status%%v_status%%r_status%' Für die Menüs "Was läuft jetzt" und "Suchergebniss", also die Variablen MenuWhatsOnNow und MenuSearchResults, stehen fünf weitere Variablen zur Verfügung: %chnr% - Kanalnummer %chsh% - Kanalname kurz %chlng% - Kanalname lang %chdata% - VDR's interne Kanaldarstellung (z.B. 'S19.2E-1-1101-28106') %progr% - Grafischer Fortschrittsbalken (nicht für das Menü "Suchergenis") %progrT2S% - Fortschrittsbalken im text2skin Stil (nicht für das Menü "Suchergenis") Es wird bei den Variablen nicht zwischen Gross-/Kleinschreibung unterschieden. Ein Eintrag besteht aus bis zu 6 Tabellenspalten, die Spalten werden durch '|' getrennt. Der letzte Eintrag jeder Spalte kann die Spaltenbreite durch angabe einer Breite in Zeichen festlegen. Die Breitenangabe wird durch ':' vom Variablennamen getrennt. Wenn du Trenner wie '~', '-' oder '#' verwendest um einzelne Bestandteile zu trennen, z.B. %title% ~ %subtitle%, dann achtet epgsearch darauf das ein solcher Trenner nicht am Ende einer Spalte steht. Die einzelnen Spaltenbreiten sollten angepasst werden, das Aussehen ist vom verwendeten Skin abhängig. Wenn diese Datei verändert werden soll während VDR läuft kann man dem Plugin den Startparamter '-r' oder '--reloadmenuconf' übergeben, die Datei wird dann bei jedem öffnen des Menüs neu eingelesen. =head1 BEISPIELE MenuWhatsOnNow=%chnr%:3|%progrt2s%:5| %time% %t_status%:8|%category%:6| %title% ~ %subtitle%:35 MenuWhatsOnNext=%chnr%:3|%time% %t_status%:8|%category%:8| %title% ~ %subtitle%:35 MenuWhatsOnElse=%chnr%:3|%time% %t_status%:8|%category%:8| %title% ~ %subtitle%:35 MenuSchedule=%time% %t_status%:8|%genre%:14| %title% ~ %subtitle%:35 MenuSearchResults=%chnr%:3|%datesh% %time% %t_status%:14|%genre%:8| %title%%colon% %subtitle%:35 MenuFavorites=%chnr%:3|%datesh% %time% %t_status%:14|%genre%:8| %title%%colon%%subtitle%:35 =head1 SIEHE AUCH C, C, C =head1 AUTOR (man pages) Mike Constabel =head1 FEHLER MELDEN Fehlerberichte bitte im Bugtracker. L Mailinglist: L =head1 COPYRIGHT and LIZENZ Copyright © 2004-2010 Christian Wieninger Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Oder rufen Sie in Ihrem Browser http://www.gnu.org/licenses/old-licenses/gpl-2.0.html auf. Der Author kann über cwieninger@gmx.de erreicht werden. Die Projektseite ist http://winni.vdr-developer.org/epgsearch Der MD5-Code ist abgeleitet aus dem Message-Digest Algorithm von RSA Data Security, Inc.. vdr-plugin-epgsearch-2.4.1/doc-src/de/epgsearchswitchtimers.conf.5.txt000066400000000000000000000037761405273211300257400ustar00rootroot00000000000000=encoding utf8 =head1 NAME F - Die gespeicherten Umschalttimer =head1 BESCHREIBUNG In epgsearch kann man über das Programmenü und die Suchtimer Umschalttimer anlegen, die einem zu beginn der Sendung auf die Sendung hinweisen oder gleich umschalten. Die Umschalttimer werden in dieser Datei gespeichert. =head1 FORMAT Der allgemeine Feldtrenner ist C<':'>. Folgende Felder sind möglich: 1 - Kanal 2 - Event ID 3 - Startzeit 4 - Vorlaufzeit 5 - Nur ankündigen =head1 BEISPIELE S19.2E-1-1089-12060:52221:1153322700:1:0 =head1 SIEHE AUCH C =head1 AUTOR (man pages) Mike Constabel =head1 FEHLER MELDEN Fehlerberichte bitte im Bugtracker. L Mailinglist: L =head1 COPYRIGHT and LIZENZ Copyright © 2004-2010 Christian Wieninger Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Oder rufen Sie in Ihrem Browser http://www.gnu.org/licenses/old-licenses/gpl-2.0.html auf. Der Author kann über cwieninger@gmx.de erreicht werden. Die Projektseite ist http://winni.vdr-developer.org/epgsearch Der MD5-Code ist abgeleitet aus dem Message-Digest Algorithm von RSA Data Security, Inc.. vdr-plugin-epgsearch-2.4.1/doc-src/de/epgsearchtemplates.conf.5.txt000066400000000000000000000034321405273211300251760ustar00rootroot00000000000000=encoding utf8 =head1 NAME F - Die gespeicherten Suchtimer-Vorlagen =head1 BESCHREIBUNG Für die Suchtimer können Vorlagen angelegt werden. Diese werden hier gespeichert. =head1 FORMAT Diese Datei hat dasselbe Format wie die Datei F. Für den Aufbau verweise ich auf C. =head1 SIEHE AUCH C =head1 AUTOR (man pages) Mike Constabel =head1 FEHLER MELDEN Fehlerberichte bitte im Bugtracker. L Mailinglist: L =head1 COPYRIGHT and LIZENZ Copyright © 2004-2010 Christian Wieninger Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Oder rufen Sie in Ihrem Browser http://www.gnu.org/licenses/old-licenses/gpl-2.0.html auf. Der Author kann über cwieninger@gmx.de erreicht werden. Die Projektseite ist http://winni.vdr-developer.org/epgsearch Der MD5-Code ist abgeleitet aus dem Message-Digest Algorithm von RSA Data Security, Inc.. vdr-plugin-epgsearch-2.4.1/doc-src/de/epgsearchuservars.conf.5.txt000066400000000000000000000132231405273211300250510ustar00rootroot00000000000000=encoding utf8 =head1 NAME F - Die Uservariablen =head1 BESCHREIBUNG In dieser Datei können Variablen definiert werden die dann in epgsearch in allen Feldern, in denen Variablen möglich sind, zur Verfügung stehen. =head1 FORMAT Die Variablen selbst sind in dem Format %Variablenname% aufgebaut. "Variablenname" kann aus alphanumerischen Zeichen bestehen, Leerzeichen und Sonderzeichen sind nicht erlaubt. Zwischen Gross-/und Kleinschreibung wird nicht unterscheiden. Beispiele für mögliche Namen: %Serie% %DokuVar1% %ThemesSubtitleDate1% =head2 Zuweisung Die Zuweisung eines Wertes erfolgt so: %Serie%=Neue Serie~Krimi Hier wird der Variablen %Serie% die Zeichenkette "Neue Serie~Krimi" zugewiesen. Es wird immer eine Zeichenkette zugewiesen. Leerzeichen werden daher auch als Leerzeichen mit übernommen. %Pfad%=%Serie% Hier wird der Variablen %Pfad% der Inhalt der Variablen %Serie% zugewiesen. Das lässt sich beliebig verwenden. %Pfad%=%Serie%~Tatort Pfad enthält hier den String "Neue Serie~Krimi~Tatort". =head2 Kontroll-Strukturen Einfache "if then else" Konstrukte sind mögliche. Innerhalb dieser Konstrukte können keine Strings, wohl aber Variablen zugwiesen werden. Leerzeichen werden ignoriert. %Foo%=Verschiedenes %Variable%=%Pfad% ? %Pfad% : %Foo% Ist Pfad nicht leer, weise %Variable% den Inhalt aus %Pfad% zu, sonst den Inhalt aus %Foo%. "%Pfad% ?" bedeutet also "nicht leer?". Es sind auch andere Prüfungen möglich. %Variable%=%Pfad%!=5 ? %Pfad% : %Foo% "%Pfad%!=5 ?" bedeutet "ist %Pfad% ungleich 5?" Es können auch Variablen verglichen werden. %Fuenf%=5 %Variable%=%Pfad%!=%Fuenf% ? %Pfad% : %Foo% Folgende Prüfungen sind möglich: == ist gleich != ist nicht gleich =head2 Systemaufruf Es können auch externe Programme/Scripte aufgerufen werden. Die zurück- gegebene Zeichenkette wird dann einer Variablen zugewiesen. %Ergebnis%=system(scriptname,%Variable1% %Variable2% -f %Variable3% --dir=%Variable4% --dummy) Ruft das Script "scriptname" mit den Parametern "%Variable1%", "%Variable2%", usw. auf. Das Ergebnis wird der Variablen %Ergebnis% zugewiesen. Es sind beliebig viele Variablen möglich. Wenn nötig, umfasst epgsearch die Variablen automatisch mit "". Das Script darf nur eine Zeichenkette ohne Zeilenumbruch zurückgeben. Erfolgt keine Rückgabe wird der Variablen %Ergebnis% eine leere Zeichenkette zugewiesen. =head2 Verfügbare Variablen Folgende Variablen sind bereits intern definiert und können verwendet werden. %title% - Title der Sendung %subtitle% - Subtitle der Sendung %time% - Startzeit im Format HH:MM %timeend% - Endzeit im Format HH:MM %date% - Startzeit im Format TT.MM.YY %datesh% - Startdatum im Format TT.MM. %time_w% - Name des Wochentages %time_d% - Tag der Sendung im Format TT %time_lng% - Startzeit in Sekunden seit 1970-01-01 00:00 %chnr% - Kanalnummer %chsh% - Kanalname kurz %chlng% - Kanalname lang %chdata% - VDR's interne Kanaldarstellung (z.B. 'S19.2E-1-1101-28106') %summary% - Beschreibung %htmlsummary% - Beschreibung, alle CR ersetzt durch '
' %eventid% - Event ID %colon% - Das Zeichen ':' %datenow% - Aktuelles Datum im Format TT.MM.YY %dateshnow% - Aktuelles Datum im Format TT.MM. %timenow% - Aktuelle Zeit im Format HH:MM %videodir% - VDRs Aufnahme-Verzeichnis (z.B. /video) %plugconfdir% - VDRs Verzeichnis für Plugin-Konfigurationsdateien (z.B. /etc/vdr/plugins) %epgsearchdir% - epgsearchs Verzeichnis für Konfiguratzionsdateien (z.B. /etc/vdr/plugins/epgsearch) Desweiteren können die in der Datei F definierten Variablen verwendet werden. Siehe dazu C. =head1 BEISPIELE # Wochentag, Datum, Uhrzeit %Datum%=%time_w% %date% %time% # Themes oder Subtitle oder Datum %ThemesSubtitleDate1%=%Subtitle% ? %Subtitle% : %Datum% %ThemesSubtitleDate%=%Themes% ? %Themes% : %ThemesSubtitleDate1% # Rufe das Script auf das den Aufnahmepfad erzeugt %DokuScript%=system(doku.pl,%Title%,%Subtitle%,%Episode%,%Themes%,%Category%,%Genre%) %Doku%=%DokuScript% =head1 SIEHE AUCH C, C =head1 AUTOR (man pages) Mike Constabel =head1 FEHLER MELDEN Fehlerberichte bitte im Bugtracker. L Mailinglist: L =head1 COPYRIGHT and LIZENZ Copyright © 2004-2010 Christian Wieninger Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Oder rufen Sie in Ihrem Browser http://www.gnu.org/licenses/old-licenses/gpl-2.0.html auf. Der Author kann über cwieninger@gmx.de erreicht werden. Die Projektseite ist http://winni.vdr-developer.org/epgsearch Der MD5-Code ist abgeleitet aus dem Message-Digest Algorithm von RSA Data Security, Inc.. vdr-plugin-epgsearch-2.4.1/doc-src/de/noannounce.conf.5.txt000066400000000000000000000027011405273211300234570ustar00rootroot00000000000000=encoding utf8 =head1 NAME F - Liste von Sendungen, die nicht mehr per OSD angekündigt werden sollen. =head1 BESCHREIBUNG Diese Datei enthält eine Liste von Sendungen die markiert wurden, sodass diese nicht mehr durch den Suchtimer-Hintergrund-Thread per OSD angekündigt werden. Wenn während der Ankündigung einer Sendung eine der Tasten '0', ... '9' oder 'Ok' gedrückt wird, wird nachgefragt, ob zukünftige Ankündigungen vollständig (bei den Tasten '0' oder 'Ok') oder nur für die nächsten x Tage (bei den Tasten '1' bis '9') unterdrückt werden sollen. Bestätigt man diese Abfrage durch ein erneutes 'Ok', wird die Einstellung entsprechend übernommen. =head1 FORMAT Pro Zeile eine Sendung, die Felder werden durch ':' getrennt. Folgende Felder existieren: 1 - Titel 2 - Episode 3 - Kanal-Kennung 4 - Startzeit 5 - Zeitpunkt für nächste Ankündigung =head1 SIEHE AUCH C =head1 AUTOR (man pages) Mike Constabel =head1 FEHLER MELDEN Fehlerberichte bitte im Bugtracker. L Mailinglist: L =head1 COPYRIGHT und LIZENZ Copyright © 2005 - 2007 Christian Wieninger Dieses Dokument wird unter den Bedingungen der Gnu Public License (GPL) veröffentlicht. Alle Angaben sind nach bestem Wissen, aber natürlich ohne Gewähr (no warranty in any kind). vdr-plugin-epgsearch-2.4.1/doc-src/de/timersdone.conf.5.txt000066400000000000000000000043171405273211300234720ustar00rootroot00000000000000=encoding utf8 =head1 NAME F - Liste von anstehenden Timern, die von Suchtimern erzeugt wurden. =head1 BESCHREIBUNG Diese Datei enthält eine Liste von anstendenden Timern, die von Suchtimern erzeugt wurden. Wenn die Setup-Option 'Timer nach Löschen neuprogrammieren' auf nein steht, benutzt epgsearch diese Liste, um zu prüfen, ob ein Timer bereits angelegt wurde und erstellt den Timer in diesem Fall nicht nochmals. Sobald die zugehörige Aufnahme stattgefunden hat, wird der Timer automatisch aus dieser Liste entfernt. =head1 FORMAT Pro Zeile ein Timer, die Felder werden durch ':' getrennt. Folgende Felder existieren: 1 - Kanal-Kennung 2 - Startzeit 3 - Stopzeit 4 - Suchtimer-ID 5 - Titel der Sendung 6 - Untertitel der Sendung =head1 SIEHE AUCH C =head1 AUTOR (man pages) Mike Constabel =head1 FEHLER MELDEN Fehlerberichte bitte im Bugtracker. L Mailinglist: L =head1 COPYRIGHT und LIZENZ Copyright (c) 2005-2006 Christian Wieninger Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Oder rufen Sie in Ihrem Browser http://www.gnu.org/licenses/old-licenses/gpl-2.0.html auf. Der Author kann über cwieninger@gmx.de erreicht werden. Die Projektseite ist http://winni.vdr-developer.org/epgsearch Der MD5-Code ist abgeleitet aus dem Message-Digest Algorithm von RSA Data Security, Inc.. vdr-plugin-epgsearch-2.4.1/doc-src/en/000077500000000000000000000000001405273211300174765ustar00rootroot00000000000000vdr-plugin-epgsearch-2.4.1/doc-src/en/createcats.1.txt000066400000000000000000000072271405273211300225240ustar00rootroot00000000000000=head1 NAME B - helps you creating your own F =head1 SYNOPSIS B [OPTIONS] F =head1 DESCRIPTION This tool is deliverd with the plugin and should exist in the plugins source directory after compilation. It helps you in creating your own epgsearchcats.conf, if the samples in directory 'conf' don't fit your needs. createcats takes your epg.data as argument and scans it for suitable EPG infos. Such an info is a set of a category name and a coresponding value at the beginning of a line (represented with '|') and has the form '|category: value', e.g. |Genre: Action So simply call it with B /path_to/epg.data The output is a file epgsearchcats.conf, that should be copied to your plugins config dir. Before using it, you should do some customizing, since not all things in the file will be suitable to be used as extended EPG info. =head1 OPTIONS The full set of arguments is: usage: B [OPTIONS] F -m N, --minappearance=N the minimum number a category has to appear to be used -v N, --maxvalues=N values of a category are omitted if they exceed this number -l N, --maxlength=N the maximum length of a text to be accepted as a category value -h, --help this help Some notes: =over 4 =item -m N, --minappearance=N createcats counts how often a category is used in your current epg.data. If this is less than N, then this category will not be part of the resulting epgsearchcats.conf. =item -v N, --maxvalues=N if the number of values for a category is more than N then createcats will not output a value list for this category. As a consequence in epgsearch the menu item gets an edit item, that can be filled with every text. Else, the item gets a selection item, that lets you select from a list of values. =item -l N, --maxlength=N if the text length of a value is more than N, this value is not part of the value list. =back B Results are best, if your current EPG is as big as possible. So update it, if you are using an external EPG provider, before calling createcats. Please edit this file now, since it will contain also things not suitable. After that copy it to your plugins config directory. =head1 SEE ALSO C, C, C =head1 AUTHOR (man pages) Mike Constabel =head1 REPORT BUGS Bugreports (german): L Mailinglist: L =head1 COPYRIGHT and LICENSE Copyright (C) 2004-2010 Christian Wieninger 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html The author can be reached at cwieninger@gmx.de The project's page is at http://winni.vdr-developer.org/epgsearch The MD5 code is derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm. vdr-plugin-epgsearch-2.4.1/doc-src/en/epgsearch.1.txt000066400000000000000000001161771405273211300223540ustar00rootroot00000000000000=head1 NAME F - Searchtimer and replacement of the VDR program menu =head1 OVERVIEW EPG-Search can be used as a replacement for the default schedules menu entry. It looks like the standard schedules menu, but adds some additional functions: - Commands for EPG entries with 5 built-in commands like 'show repeats', 'create search'. One can add own commands for other needs, like adding a VDRAdmin auto-timer. - Add up to 4 user-defined times to 'now' and 'next' and an optional favorites menu - Searching the EPG: Create reusable queries, which can also be used as 'search timers'. - Search timers: Search for broadcasts in the background and add a timer if one matches (similar to VDRAdmin's auto-timers) or simply make an announcement about it via OSD - Avoid double recordings of the same event * timer preview * recognition of broken recordings * fuzzy event comparison - Progress bar in 'What's on now' and 'What's on next' - Shift the time displayed by key press, e.g. 'What's on now' + 30 minutes - Start menu can be setup between 'Schedule' or 'What's on now' - background check for timer conflicts with a timer conflict manager - detailed EPG menu (summary) allows jumping to the next/previous event - support for extended EPG info for search timers - extension of the timer edit menu with a directory item, user defined weekday selection and a subtitle completion. - Timer conflict check, informs you over the OSD about conflicts - Timer conflict menu, show detailed information about the conflicts and let you resolve them - Email notifications about search timer updates and timer conflicts Parts of the sources are based on the repeating-ECG patch from Gerhard Steiner, who gave me the permission to use them. Thanks for his work! =head1 OPTIONS =over 4 =item -f file, --svdrpsendcmd=file the path to svdrpsend for external SVDRP communication (default is internal communication, so this is usually not needed anymore) =item -c path, --config=path to specify a specific config directory for all epgsearch config files, default is '/epgsearch' =item -l file, --logfile=file to specify a specific log file for epgsearch (default log file is epgsearch.log in the epgsearch config directory) =item -v n, --verbose=n verbose level for log file. Value 0 means no logging. Other values are 1 (general messages), 2 (detailed messages), 3 (planned for extra detailed info for debugging purposes) =item -r, --reloadmenuconf reload epgsearchmenu.conf with plugin call. This can be useful when testing customized menu layouts. =item -m file, --mailcmd=file the external command to be used for mail delivery. The default uses 'sendEmail.pl'. If you are using a different command or script make sure that it has the same parameter interface as sendEmail.pl. =back =head1 CONTENT 1. Description 1.1 Menu commands 1.2 Menu search 1.2.1 Menu edit search 1.2.2 Menu search results 1.3 Extended 'now' and 'next' 1.4 Menu setup 2. Search timers 2.1 'Avoid repeats' - internals 2.2 How do we compare two events? 2.3 How and when do we compare? 3. Usage from other plugins or scripts 4. Using extended EPG info 5. Replacing the standard schedule menu 6. Add-ons =head1 1. Description At first glance EPG-Search looks like the schedules menu entry of VDR. By pressing the key '0', one can toggle the bottom color keys to access additional functions (the default assignment of the color keys can be adjusted by setup): =head2 1.1 Menu Commands This menu displays commands that can be executed on the current item. There are 8 built-in commands: - Repeats: Searches for repeats - Record - Switch - Create search Switches to search menu and adds a new search with the name of the current item (to avoid editing the name manually) - Search in recordings: Search the recordings for a broadcast with the same name - Mark as 'already recorded': This puts the selected event in the file epgsearchdone.data and instructs epgsearch to avoid recording this event if an according search timer is set to "avoid repeats". An already created timer will be automatically removed with the next search timer update. - Add/Remove to/from switch list?: Controls the switch list. If there is an event in the switch list, epgsearch will announce it and switch to the event before it starts. To access the complete switch list, call 'Search/Actions/Switch list'. - Create blacklist: A blacklist is used to ignore events when using search timers. A search timer can be setup to ignore events from arbitrary blacklists. You can add your own commands to this menu by editing the file epgsearchcmds.conf in the epgsearch config directory. There's a sample conf file with some sample commands (see directory 'scripts', taken from vdr-wiki.de, thanks to the authors). The format of the file is the same as VDR's commands.conf or reccmds.conf. When a command is executed the following parameters are passed to it: $1: the title of the EPG entry $2: the start time of the EPG entry as time_t value (like in the shutdown script) $3: the end time $4: the channel number of the EPG entry $5: the long channel name of the EPG entry $6: the subtitle of the EPG entry, "" if not present To execute a command from the main menu you can also press its associated number without opening the commands menu. =head2 1.2 Menu search Here you can add, edit, delete and execute your own queries on the EPG. The usage and behavior of this menu is similar to VDR's timer menu. =head3 1.2.1 Menu edit search Most things in this menu are quite clear, so only some notes on: =over 4 =item - B The term to search for. If you like to search for more words, separate them by blanks. Leaving this empty (combined with search mode 'Phrase') will match anything. This is useful, if you search e.g. for anything that starts between some times on a specific channel. With 'blue' you can also select a template for the new search. If one of the templates is set to default, new searches will automatically get the settings of the default template. Note: fuzzy searching is limited to 32 chars! =item - B 'Phrase' searches for the expression within the EPG. 'All words' requires, that each word of the expression occurs in the EPG item. 'at least one word' requires, that only one word occurs in the EPG item. 'Match exactly' requires, that your search term matches exactly the found title, subtitle or description. With 'Regular expression' you can setup a regular expression as search term. You don't need a leading and trailing '/' in the expression. By default these are POSIX extended regular expressions. If you like to have Herl compatible regular expression, simply edit the plugins Makefile and uncomment '#REGEXLIB = pcre' to 'REGEXLIB = pcre' (you will need pcreposix installed, comes with libpcre from www.pcre.org, but it's already part of most distributions). See also C 'Description of the search process'. =item - B Some providers deliver content descriptors in their EPG, like "Movie/Drama", "Documentation",...(available with vdr-1.7.11) Select here the descriptors to search for. Multiple choice is possible, that must match with all given descriptors (AND operator). =item - B Only available if configured, see below 'Using extended EPG info'. =item - B If set to 'Yes' this tells epgsearch that a missing EPG category should not exclude an event from the results. Caution: Using this without any other criterions could flood your timers. =item - B Search only for events in the given channels interval, channel groups or FTA channels only. Channel groups (e.g. sport channels or Pay-TV channels) can be managed with a sub-menu called with 'blue'. ATTENTION: After changing the channels order please check the settings of your search timers! =item - B Besides the weekdays you can also set up a user-defined selection, e.g. search only on Monday and Friday. You'll find the user-defined selection in the list after Friday. =item - B Blacklists are a way to exclude unwanted events. Select only global, one, more or all blacklists here. If any search result is also contained in one of the selected blacklists it will be skipped. =item - B Only available if turned on in setup. With this option you can mark a search to be used in the favorites menu. The search results of all these searches are listed in the favorites menu. =item - B Only available if you have defined more than one menu template for search results in epgsearchmenu.conf. This option is used to assign a different menu layout for the search results of this search. =item - B If set to yes, the plugin will do a background scan of the EPG in certain intervals and add a timer, if there is a match. You have to activate the 'search timers' in the setup. If set to "user defined" one can specify time margins with key 'blue' where the search timer is active or not. =item - B Default action is creating a timer for the search results. But you can also choose to simply announce the found event via OSD as soon as it is found or to automatically switch to the event before it starts. It's also possible to get an announcement via OSD before the event starts and to switch to its channel with 'Ok'. =item - B If set to yes, the recordings will be stored in a folder with the name of the broadcasting and the recordings itself will have the name of the episode. If there is no episode name, the date and time of the recording will be used. =item - B Here you can assign a directory, where the recording should be stored, e.g. 'SciFi'. Use the key 'blue' to select directory entries already used in other search entries or given by entries in the file epgsearchdirs.conf (simply place your directories here one at each line without the leading video directory, also see MANUAL). If your provider delivers extended EPG infos you can also use variables like "%Genre%" or "%Category%" in your directory entry. These are replaced with the current EPG info, when a timer is created. See also C 'Using variables in the directory entry of a search timer'. =item - B Some recordings should only be kept for a few days, like news. With this feature you can tell epgsearch to delete them automatically after ... days. =item - B If the given numbers of recordings currently exists, then epgsearch will not create further timers. After deleting one or more recordings it will go on generating new timers. =item - B If you don't want to record repeats, this feature tries to check if an event was already recorded/programmed and skips it. Please refer to the section 'Avoid repeats - internals' below before using it. =item - B If you like to accept a certain amount of repeats you can give here their number. =item - B Give here the number of days a repeat has to follow its first broadcast. 0 is equal to no restriction. =item - B When comparing to events then specify here if the title should be compared. =item - B When comparing to events then specify here if the subtitle should be compared. With 'yes' epgsearch will classify two events only as equal if their episode names match and are not empty. With 'allow empty' two events may be equal if both subtitles are empty. Normally you would choose "no" in this case. =item - B When comparing to events then specify here if the description should be compared. For comparison all parts of the description, that look like a category value, are removed first. The remaining text will be compared. If this is similar at the value of the next option (regarding the Levinshtein-Distance algorithm) then it will be accepted as equal. =item - C The needed minimum match of descriptions in percent. =item - B Sometimes an event is repeated many times within some period (day, week, month,...), but one cannot distinguish the repeats based on the EPG contents. So the only information is its time. To use this for comparison select the appropriate period. =item - B With the button 'setup' you can also specify which categories should be compared. As with subtitles an event is different if it has no according category value. =item - B Each search timer can have its own settings for these parameters. Defaults can be adjusted in the plugins setup. =item - B If set to yes, VPS is used, but only, if activated in VDR's setup menu and if the broadcasting has VPS information. =item - B to automatically delete a search timer if the following is true: * after x recordings, or * after x days after the first recording Only complete recordings are counted. The deletion is executed directly after the correspondig recording =back To toggle the flag 'Use as search timer' without editing the search entry you can use the key '2'. This will call directly the second command of the command menu. =head3 1.2.2 Menu search results This menu displays the search results. A 'T' lets you know, that there is already a timer for the event. A 't' means that there's only a partial timer for it, as in standard schedules menu. =head2 1.3 Extended 'now' and 'next' and favorites By setup, one can add up to 4 additional times to extend the green button, e.g. 'afternoon', 'prime time', 'late night'. Times, that are already passed, are skipped (you will not get 'afternoon' at evening) with the exception that a time will be displayed for the next day, if it is less then 20h in the future. In these menus you can shift the currently displayed time by pressing FastRew or FastFwd to move back and forward in time. If you don't have these keys on your remote, you can access this function by pressing '0' to toggle the green and yellow button to '<<' and '>>'. This toggling can be adjusted by setup. You can display a progress bar in 'now' and 'next'. Furthermore you can enable in the setup an favorites list. You can configure your searchtimers ("Use in favorite list") to display their results in you favorite list. This list display event in the next 24 hours ordered by time. =head2 1.4 Menu setup =head3 1.4.1 General =over 4 =item - B This hides the main menu entry 'search'. Attention: when the plugin is assigned to key 'green' then hiding the plugin will give you VDR's standard schedule menu (see below to avoid this). =item - B
If not hidden, the name of main menu entry can be set here. Default is 'Program guide'. Note: If you set it to something different from the default then the main menu entry is no longer dependent on the OSD language. Setting it back to default or empty restores this behavior again. =item - B Select the starting menu 'Schedules' or 'Now' =back =head3 1.4.2 EPG menus =over 4 =item - B Choose here the behavior of key 'Ok'. You can use it to display the summary or to switch to the corresponding channel. Note: the functionality of key 'blue' (Switch/Info/Search) depends on this setting. =item - B Select if you like to have Standard ('Record') or 'Commands' as assignment for key 'red'. =item - B select if you like to have Standard ('Switch') or 'Search' as assignment for key 'blue'. =item - B In the menu 'what's on now' you can display a progress bar, that displays the progress of the current item. =item - B Select this if you like to have a leading channel number before each item in the EPG menus. =item - B Display channel group separators between channel in the menus 'Overview now',... =item - B Display a day separator between events on different days in the schedule menu. =item - B Also list radio channels. =item - B If you have a large channel set you can speed up things when you limit the displayed channels with this setting. Use '0' to disable the limit. If the current channel is above the limit, the limit is ignored and all channels will be displayed again. =item - B<'One press' timer creation:> If set to 'yes' a timer is immediately created when pressing 'Record', else the timer edit menu is displayed. =item - B Display channels without EPG to allow switching or create a timer. =item - B