diff options
author | video src <videosrc@vdr.muc.bieringer.de> | 2008-12-20 08:50:04 +0100 |
---|---|---|
committer | video src <videosrc@vdr.muc.bieringer.de> | 2008-12-20 08:50:04 +0100 |
commit | 21fd75ff07fe1f3655a758603571b03f18737157 (patch) | |
tree | feda8b931a103cde74f86694fe14f744a5bd9375 | |
parent | 8850eea8baddb579346d6977a2980f8f587687e4 (diff) | |
download | vdr-plugin-tvtv-21fd75ff07fe1f3655a758603571b03f18737157.tar.gz vdr-plugin-tvtv-21fd75ff07fe1f3655a758603571b03f18737157.tar.bz2 |
Import of last official release 0.3.3
-rw-r--r-- | COPYING | 340 | ||||
-rw-r--r-- | HISTORY | 205 | ||||
-rw-r--r-- | Makefile | 90 | ||||
-rw-r--r-- | README | 88 | ||||
-rw-r--r-- | channelmap.c | 89 | ||||
-rw-r--r-- | channelmap.h | 35 | ||||
-rw-r--r-- | config.c | 33 | ||||
-rw-r--r-- | config.h | 45 | ||||
-rw-r--r-- | examples/tvtv_channelmap.conf_DVB-S | 506 | ||||
-rw-r--r-- | examples/tvtv_channelmap.conf_DVB_Mch | 62 | ||||
-rw-r--r-- | i18n.c | 590 | ||||
-rw-r--r-- | i18n.h | 16 | ||||
-rw-r--r-- | md5tools.c | 207 | ||||
-rw-r--r-- | md5tools.h | 47 | ||||
-rw-r--r-- | tvtv.c | 308 | ||||
-rw-r--r-- | update.c | 703 | ||||
-rw-r--r-- | update.h | 82 |
17 files changed, 3446 insertions, 0 deletions
@@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library 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. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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. + + <signature of Ty Coon>, 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 Library General +Public License instead of this License. @@ -0,0 +1,205 @@ +VDR Plugin 'tvtv' Revision History +----------------------------------- + +2007-02-06: Version 0.3.3 +- The plugin needed to be restarted if username or password were changed + since the "Packed String" (contains username and password) was only + generated once during start-up +- The time shift bugfix is now configurable via a new setup option + solving problems with timers not using CET/CEST as timezone (e.g. BBC) +- In case a channel is not found in the tvtv_channelmap.conf file, the + channels name as well as its ID is printed in the logfile. This should + help adding new channels to the config file. +- tvtv_channelmap.conf updated + +2007-01-02: Version 0.3.2 +- Code clean up +- Deleted timer object might cause VDR to be killed if timer is deleted + within TVTV. (thx to monty35) + +2006-10-23: Version 0.3.1 +- added some #IFs making it compile on older VDR versions again. +- Code clean up +- tvtv_channelmap.conf updated +- "not confirmed" message removed from logfile by using an own routine + to display OSD-Message +- TVTV bugfix now also works with VPS-Timers +- empty entry in config file may lead to segfault (thx to monty35 for + reporting this one) + +2006-10-09: Version 0.3.0 +- new SVDRP command "UPDATE" to update TVTV timers. +- ChannelMap.h replaced by config file tvtv_channelmap.conf making it + easier to maintain. The format of the configfile is slightly different + to the older ChannelMap.h now supporting different satellites and + countries. The channel map can be reloaded by the plugins setup menu. +- The new SVDRP command "RELOAD" reloads the channel map configuration + file. +- Timer updates are rejected if shifted 1 or 2 hours earlier (depending + on the current time zone). This behaviour can be controlled by a new + setup option. +- Replaced comparison of string::npos with "unsigned int" in routine + ProcessImportedFile() since it may lead to problems on 64bit machines. + + +2006-09-25: Version 0.2.14 +- i18n.c updated +- ChannelMap.h updated +- Timer updates are rejected if shifted 2 hours earlier. Successful and + rejected updates are documented in the logfile (thx to monty35). + +2006-04-25: Version 0.2.13a +- Function ShowName() in class cChannel is not available on VDR + older than 1.3.15. Added an ifdef to solve this (thanks to GTRDRIVER + for reporting this one) + +2006-04-18: Version 0.2.13 +- new setup option decides whether to use the description coming + with the data from TVTV or not (just available for VDR 1.3.44+). + Starting with VDR 1.3.44 timer description is only taken from + EPG so there is no need for the description from TVTV anymore. +- Added logging of downloaded data to /var/log/vdr_tvtv.log for + debugging purpose (suggested by Schlappo) +- Station name of timer is now added to File Name of recording. + This behaviour can be controlled by a new setup option. +- Adapted Makefile due to new requirements of VDR 1.3.47+ + +2006-03-16: Version 0.2.12 +- added basic support for VDR 1.3.44. Timer description coming + from TVTV is now put into the Aux field of Timer-Object. Need + to investigate how this works with recordings without EPG. +- Non-initialized data structure for HTTP download might cause + VDR to be killed. Proper initialization should solve this. +- Missing define statements disabled VPS support in 0.2.11 +- added BBC channels to ChannelMap.h + +2006-02-17: Version 0.2.11 +- split the source code into separate files making it easier to + maintain. +- TVTV-Server can now be selected via OSD +- libcurl is now used to download data from TVTV adding proxy + support to the plugin. +- do not delete timers that are currently recording, even if it's + just updated. +- Plugin may hang on 64bit machines in routine calc_field_cnt() due + to compare values with different types (thx to bunghole) + +2005-12-15: Version 0.2.10a +- VDR crashes if a timer with an empty summary exists and a timer + is added by TVTV (thx to mag128) + +2005-12-14: Version 0.2.10 +- ostringstream is used instead of snprintf() to create timer + entries. +- Buffer for http download increased to 500kB +- Timer entries are now created with full date if VDR 1.3.23+ + is used +- Debug messages added + +2005-11-07: Version 0.2.9 +- Updated for VDR 1.3.36: Timer entry is no longer limited + and description is not cut off if VDR-Version 1.3.36+ is + detected + +2005-11-02: Version 0.2.8a +- Timer entry needs an additional cut off + +2005-11-01: Version 0.2.8 +- TVTV crashes if timer entry exceeds 10kB. Description is + cut off to keep it shorter (thx to monty35) +- Global constant MAXPARSEBUFFER is used instead of + plain values + +2005-10-16: Version 0.2.7 +- ChannelMap.h updated + +2005-10-03: Version 0.2.6b +- Timers are deleted even if they have changed since the + last update (thx to monty35) +- Debug messages updated (thx to monty35) + +2005-10-03: Version 0.2.6a +- ChannelMap.h updated ('NICK' added, thx to wilderigel) + +2005-10-03: Version 0.2.6 +- Timers may be updated by adding the UID coming from + TVTV at the end of the description (thx to monty35) +- Timers with colon in title will be handled as suggested in + VDRs manual + +2005-09-28: Version 0.2.5 +- ChannelMap.h updated ('Das Vierte' added) +- split_csv() routine might cause vdr to be killed + (thx to ck-one for reporting this one) + +2005-09-24: Version 0.2.4 +- English translations updated +- Debug messages updated (thx to monty35) +- Fixed handling of VPS-Timers starting at midnight + (thx to uclara) + +2005-05-15: Version 0.2.3 +- ChannelMap.h updated +- Number of timers is no longer limited by the plugin. +- "Delete-Patch" replaced by following the action coming + with the timer. +- Filename of created timer does not contain "TVTV+" anymore +- New setup option "Use VPS" decides whether timers created + via TVTV use VPS or not. Timers set via EPG are not effected. +- Compiles on VDR older than 1.3.18 +- German translations updated + +2005-05-09: Version 0.2.2 +- Timer is now created by using the time zone information + to be able to record e.g. english channels. + (thx to Briandorling for bringing this up) +- does not use clear() method anymore + +2005-05-08: Version 0.2.1 +- ChannelMap.h updated (thx to monty35) +- Ignore folder setting if nature is empty (thx to monty35) + +2005-05-06: Version 0.2.0 +- Data format changed to CSV (Comma Separated Values) + + +2003-01-28: Version 0.1.6 +- Plugin can make a HTTP-Request without "wget". + And XML File will be not more created ;-)) +- OSD-Setup Menu Item "Show/Hide TVTV in Main menu" + +2002-12-01: Version 0.1.5 + +- You are need a no changes (tools.h) in VDR Version >= 1.1.18 +- For XML file will be used your "Video" Directory + +2002-11-24: Version 0.1.4 + +- IMPORTANT: Command Line settings is default settings. + after Save in OSD Setup, it will be skipped. + You can delete now your default settings. + Your settings will be saved in (/video)/setup.conf +- Support VDR 1.1.17 + You are need VDR Version >= 1.1.17 +- DefaultPriority & DefaultLifeTime Settings will be used +- Timers After (Now + 1 Month) will be imported later +- Extended File Format Setup Line inserted + If you want to have Nature like Main-Folder then set it to "yes" + (Default "no") + +2002-11-23: Version 0.1.3 + +- MarginStart & MarginStop will be used +- EPG Text Data will be saved too +- File name format will be so one: Nature~Title ,-) + +2002-11-20: Version 0.1.2 + +- Autoupdate +- OSD Plugin Setup. Command Line will be used as Default Settings. + +2002-11-19: Version 0.1.0 + +- Initial revision. + +This ist a Initial Version. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..60d668b --- /dev/null +++ b/Makefile @@ -0,0 +1,90 @@ +# +# Makefile for a Video Disk Recorder plugin +# +# $Id$ + +# The official name of this plugin. +# This name will be used in the '-P...' option of VDR to load the plugin. +# By default the main source file also carries this name. +# +PLUGIN = tvtv + +### 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 ?= -O2 -Wall -Woverloaded-virtual + +### The directory environment: + +VDRDIR = ../../.. +LIBDIR = ../../lib +TMPDIR = /tmp + +### Libraries + +LIBS = -lcurl + +### Allow user defined options to overwrite defaults: + +-include $(VDRDIR)/Make.config + +### The version number of VDR's plugin API (taken from VDR's "config.h"): + +APIVERSION = $(shell grep 'define APIVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g') + +# This is required for VDRs older than 1.3.47 +ifeq ($(strip $(APIVERSION)),) + APIVERSION = $(shell grep 'define VDRVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g') +endif + +### The name of the distribution archive: + +ARCHIVE = $(PLUGIN)-$(VERSION) +PACKAGE = vdr-$(ARCHIVE) + +### Includes and Defines (add further entries here): + +INCLUDES += -I$(VDRDIR)/include + +DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' + +### The object files (add further files here): + +OBJS = $(PLUGIN).o i18n.o config.o update.o md5tools.o channelmap.o + +### Implicit rules: + +%.o: %.c + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< + +# Dependencies: + +MAKEDEP = $(CXX) -MM -MG +DEPFILE = .dependencies +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + +### Targets: + +all: libvdr-$(PLUGIN).so + +libvdr-$(PLUGIN).so: $(OBJS) + $(CXX) $(CXXFLAGS) -shared $(OBJS) $(LIBS) -o $@ + @cp $@ $(LIBDIR)/$@.$(APIVERSION) + +dist: clean + @-rm -rf $(TMPDIR)/$(ARCHIVE) + @mkdir $(TMPDIR)/$(ARCHIVE) + @cp -a * $(TMPDIR)/$(ARCHIVE) + @tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE) + @-rm -rf $(TMPDIR)/$(ARCHIVE) + @echo Distribution package created as $(PACKAGE).tgz + +clean: + @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ @@ -0,0 +1,88 @@ +This is a "plugin" for the Video Disk Recorder (VDR). + +Written by: Mario Gross <vdr-tvtv-plugin@arcor.de> + (based on Version 0.1.6 created by Gerald Berwolf <genka@vdrportal.de>) + +Project's homepage: http://home.arcor.de/grossmar + + +See the file COPYING for license information. + + +Requirements: + + - VDR 1.2.0+ (VPS requires VDR 1.3.5+) + - libcurl 7.10+ + - a valid tvtv subscription with "Linux PVR" as registered product + + +Description: + +This plugin can be used to create timers from the job list of TVTVs website. +Unlike the job list on the website, only the most recent 32 timer jobs within +the upcoming 2 weeks are transfered by TVTV. Programs already on air cannot +be added to the timer list since they are not sent by TVTV. + + +Setup Menu: + + TVTV Server + TVTV Server to download the data from + + TVTV User Name + TVTV Password + Username and Password as used on the website + + Use HTTP Proxy + HTTP Proxy + Use HTTP Proxy to connect to TVTV + + Auto Update + Updatetime (min) + Perform automatic update (default: 30 minutes) + + Show In Main Menu + Shows entry in main menu to perform update manually + + Use VPS + Add timers using VPS if available (only VDR 1.3.5+) + + Use Nature within File Name + Use Station Name within File Name + Nature and/or Station Name are added to the filename as separate + directory. + + Use TVTV description in info.vdr + Starting with VDR 1.3.44, the description of a recording is + taken from EPG. This switch decides whether or not the description + coming from TVTV will be added as a comment to info.vdr. + + Time shift bugfix + Time shift (hrs) + Sometimes a timer is wrongly updated due to a bug in the TVTV database. + It is shifted 1 hour (2 hours during daylight saving time) ealier. This can + be avoided by enabling this fix. + + Reload ChannelMap + If channel map is changed it can be reloaded with this command + + +SVDRP Commands: + + The plugin provides SVDRP commands to control the plugin via command line or + shell scripts. + + RELOAD - Reloads the channel map config file + UPDATE - update timer list from TVTV + + +Installation: + +cd /put/your/path/here/VDR/PLUGINS/src +tar -xzf /put/your/path/here/vdr-tvtv-X.Y.Z.tgz +ln -s tvtv-X.Y.Z tvtv +cp tvtv/examples/tvtv_channelmap.conf VDR_Config_Dir/plugins +cd /put/your/path/here/VDR +make +make plugins +./vdr -P tvtv diff --git a/channelmap.c b/channelmap.c new file mode 100644 index 0000000..5b4e5fb --- /dev/null +++ b/channelmap.c @@ -0,0 +1,89 @@ +/* + * channelmap.c: TVTV plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include "channelmap.h" + + +cChannelMap::cChannelMap() { + chanmap.clear(); + read_config_file(); +} + +cChannelMap::~cChannelMap() { + chanmap.clear(); +} + + +void cChannelMap::remove_whitespaces(char *s) // Whitespaces werden entfernt +{ + unsigned int i=0; + char *dum; + if (s != NULL) { + dum=(char *)calloc(1,strlen(s)+1); + for (i=0;i<strlen(s);i++) if (!isspace(s[i])) strncat(dum,&(s[i]),1); + memset(s,0,strlen(s)); + strcpy(s,dum); + free(dum); + } +} + + +int cChannelMap::read_config_file() { + ifstream cmfile; + string s; + size_t p; + int tvtvid; + int n; + char *cfg_fname = NULL; + + asprintf(&cfg_fname, "%s/tvtv_channelmap.conf", cPlugin::ConfigDirectory()); + cmfile.open(cfg_fname); + if (!cmfile) { + esyslog("TVTV: Error reading '%s'!", cfg_fname); + return -1; + } + isyslog("TVTV: Loading '%s'", cfg_fname); + n=0; + while (!cmfile.eof()) { + getline(cmfile, s); + + if (!s.empty()) { + remove_whitespaces((char *)s.c_str()); + + // remove comments + p=s.find_first_of("//"); + if (p != string::npos) s.erase(p); + + // split line + p=s.find_first_of("="); + if (p != string::npos) { + tvtvid=atoi(s.substr(0,p).c_str()); + chanmap[tvtvid] = (char *)calloc(s.substr(p+1).length()+1, sizeof(char)); + strcpy(chanmap[tvtvid], s.substr(p+1).c_str()); + n++; + } + } + } + cmfile.close(); + isyslog("TVTV: %d channel mappings read.", n); + return n; +} + +char *cChannelMap::GetChanStr(int tvtvid) { + return chanmap[tvtvid]; +} + +tChannelID cChannelMap::GetChanID(int tvtvid) { + if (chanmap[tvtvid] == NULL) return tChannelID::InvalidID; + return tChannelID::FromString(chanmap[tvtvid]); +} + + +int cChannelMap::ReloadChannelMap() { + chanmap.clear(); + return read_config_file(); +} diff --git a/channelmap.h b/channelmap.h new file mode 100644 index 0000000..de40039 --- /dev/null +++ b/channelmap.h @@ -0,0 +1,35 @@ +/* + * channelmap.h: TVTV plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#ifndef _CHANNELMAP__H +#define _CHANNELMAP__H + +#include <map> +#include <fstream> +#include <string> +#include <stdlib.h> + +#include <vdr/plugin.h> +#include <vdr/tools.h> + +using namespace std; + + +class cChannelMap { +private: + map<int, char *> chanmap; + void remove_whitespaces(char *s); + int read_config_file(); +public: + cChannelMap(); + ~cChannelMap(); + int ReloadChannelMap(); + char *GetChanStr(int tvtvid); + tChannelID GetChanID(int tvtvid); +}; + +#endif diff --git a/config.c b/config.c new file mode 100644 index 0000000..7edb2bd --- /dev/null +++ b/config.c @@ -0,0 +1,33 @@ +/* + * config.c: TVTV plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include "config.h" + +cTVTVConfig TVTVConfig; + +cTVTVConfig::cTVTVConfig(void) { + tvtv_server=0; + strn0cpy(username, "", sizeof(username)); + strn0cpy(password, "", sizeof(password)); + autoupdate=0; + updatetime=30; + usegenre=1; + usestation=1; + show_in_mainmenu=1; + useproxy=0; + strn0cpy(httpproxy, "127.0.0.1:8000", sizeof(httpproxy)); +// VPS was introduced with VDR 1.3.5 +#if VDRVERSNUM >= 10305 + usevps=1; +#endif +#if VDRVERSNUM >= 10344 + usetvtvdescr=0; +#endif + tvtv_bugfix=0; + tvtv_bugfix_hrs=1; +} + diff --git a/config.h b/config.h new file mode 100644 index 0000000..d24d744 --- /dev/null +++ b/config.h @@ -0,0 +1,45 @@ +/* + * config.h: TVTV plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + * $Id$ + */ + +#ifndef __TVTV_CONFIG_H +#define __TVTV_CONFIG_H + +#include <vdr/interface.h> +#include <vdr/plugin.h> +#include <vdr/tools.h> +#include <vdr/status.h> + +struct cTVTVConfig +{ +public: + cTVTVConfig(void); + + int tvtv_server; + char username[30]; + char password[30]; + int updatetime; + int autoupdate; + int usegenre; + int usestation; + int show_in_mainmenu; + int useproxy; + char httpproxy[256]; +// VPS was introduced with VDR 1.3.5 +#if VDRVERSNUM >= 10305 + int usevps; +#endif +#if VDRVERSNUM >= 10344 + int usetvtvdescr; +#endif + int tvtv_bugfix; + int tvtv_bugfix_hrs; +}; + +extern cTVTVConfig TVTVConfig; + +#endif // __TVTV_CONFIG_H diff --git a/examples/tvtv_channelmap.conf_DVB-S b/examples/tvtv_channelmap.conf_DVB-S new file mode 100644 index 0000000..827d5fd --- /dev/null +++ b/examples/tvtv_channelmap.conf_DVB-S @@ -0,0 +1,506 @@ +////////////////////////////////////////////////////////////// +// ChannelMap for TVTV-Plugin +////////////////////////////////////////////////////////////// +// +// TVTV ChannelID = VDR ChannelID (Src-NID-TID-SID) +// +// +// ARD/ZDF +1 = S19.2E-1-1101-28106 // ARD +2 = S19.2E-1-1079-28006 // ZDF +962 = S19.2E-1-1073-28201 // Eins Extra +955 = S19.2E-1-1073-28202 // Eins Festival +956 = S19.2E-1-1073-28203 // EinsPlus +963 = S19.2E-1-1079-28011 // ZDF infokanal +960 = S19.2E-1-1079-28014 // ZDF dokukanal +961 = S19.2E-1-1079-28016 // ZDF theaterkanal +// +// 3. Programme +//17 = S19.2E-1-1101-28111 // WDR Köln +//17 = S19.2E-1-1201-28305 // WDR Aachen +//17 = S19.2E-1-1201-28306 // WDR Bielefeld +//17 = S19.2E-1-1201-28307 // WDR Dortmund +17 = S19.2E-1-1201-28308 // WDR Düsseldorf +//17 = S19.2E-1-1201-28309 // WDR Essen +//17 = S19.2E-1-1201-28310 // WDR Münster +//17 = S19.2E-1-1201-28311 // WDR Siegen +//17 = S19.2E-1-1201-28312 // WDR Wuppertal +//19 = S19.2E-1-1073-28224 // NDR FS MV +19 = S19.2E-1-1073-28225 // NDR FS HH +//19 = S19.2E-1-1073-28226 // NDR FS NDS +//19 = S19.2E-1-1073-28227 // NDR FS SH +18 = S19.2E-1-1101-28107 // BR3 +29 = S19.2E-1-1101-28113 // SWR BW +30 = S19.2E-1-1073-28231 // SWR RP +31 = S19.2E-1-1101-28110 // SR +26 = S19.2E-1-1101-28108 // HR +33 = S19.2E-1-1073-28204 // MDR +//33 = S19.2E-1-1073-28228 // MDR SACHSEN +//33 = S19.2E-1-1073-28229 // MDR S-ANHALT +//33 = S19.2E-1-1073-28230 // MDR THÜRINGEN +//35 = S19.2E-1-1073-28205 // rbb Brandenburg +35 = S19.2E-1-1073-28206 // rbb Berlin +118 = S19.2E-1-1079-28007 // 3sat +63 = S19.2E-1-1079-28008 // KiKa +// +// Privatsender [de] +4 = S19.2E-1-1089-12003 // RTL +5 = S19.2E-133-33-46 // SAT.1 +6 = S19.2E-133-33-898 // ProSieben +8 = S19.2E-133-33-899 // Kabel eins +9 = S19.2E-1-1089-12020 // RTL2 +179 = S19.2E-1-1089-12040 // Super RTL +11 = S19.2E-1-1089-12060 // VOX +885 = S19.2E-133-5-1793 // Das Vierte +105 = S19.2E-133-33-51 // TELE-5 +59 = S19.2E-133-33-897 // 9Live +704 = S19.2E-133-5-776 // GigaTV +842 = S19.2E-133-5-659 // TV Gusto +882 = S19.2E-1-1078-28680 // NICK +716 = S19.2E-1-1078-28677 // Comedy Central +// +// Doku +57 = S19.2E-1-1101-28112 // BR-alpha +206 = S19.2E-1-1101-28114 // Phoenix +10 = S19.2E-1-1101-28109 // ARTE +227 = S19.2E-1-1113-12602 // DMAX +974 = S19.2E-1-1094-17033 // Terra Nova +837 = S19.2E-1-1057-61900 // bibel TV +831 = S19.2E-1-1022-6907 // EWTN +846 = S19.2E-1-1113-12601 // K-TV +801 = S19.2E-1-1091-31210 // HSE24 +973 = S19.2E-1-1108-12100 // QVC +802 = S19.2E-1-1089-12080 // RTL Shop +// +// Nachrichten +7 = S19.2E-1-1089-12090 // n-tv +953 = S19.2E-133-33-47 // N24 +13 = S19.2E-1-1091-31220 // EuroNews +901 = S19.2E-1-1026-28707 // Sky News +126 = S19.2E-1-1068-28522 // CNN +112 = S19.2E-1-1026-10050 // BBC World Germany +168 = S19.2E-1-1026-10030 // CNBC +954 = S19.2E-1-1108-12160 // Bloomberg TV +// +// Sport +12 = S19.2E-133-33-900 // DSF +107 = S19.2E-1-1091-31200 // Eurosport +// +// Premiere +986 = S19.2E-133-1-8 // Premiere Start +910 = S19.2E-133-2-10 // Premiere 1 +983 = S19.2E-133-2-11 // Premiere 2 +984 = S19.2E-133-2-43 // Premiere 3 +911 = S19.2E-133-2-9 // Premiere 4 +912 = S19.2E-133-3-20 // Premiere Filmfest +985 = S19.2E-133-3-41 // Prem. Filmclassics +935 = S19.2E-133-2-16 // Premiere Serie +913 = S19.2E-133-4-42 // 13th Street +934 = S19.2E-133-4-36 // SCI FI +941 = S19.2E-133-4-515 // MGM +936 = S19.2E-133-2-23 // Premiere Krimi +940 = S19.2E-133-3-516 // Premiere Nostalgie +942 = S19.2E-133-1-24 // Classica +916 = S19.2E-133-1-22 // Heimatkanal +979 = S19.2E-133-4-27 // Premiere Win +931 = S19.2E-133-17-34 // Disney Channel +976 = S19.2E-133-17-28 // Jetix +930 = S19.2E-133-17-19 // Junior +933 = S19.2E-133-17-14 // Discovery +903 = S19.2E-133-17-13 // Discovery Geschichte +943 = S19.2E-133-17-12 // Animal Planet +988 = S19.2E-133-17-15 // Focus Gesundheit +932 = S19.2E-133-1-168 // hit24 +975 = S19.2E-133-1-518 // Goldstar TV +944 = S19.2E-133-17-21 // BEATE-UHSE.TV +952 = S19.2E-133-1-671 // Blue Movie Gay +// +// arena +// 847 = S19.2E-1-1102-13203 // AXN +902 = S19.2E-1-1102-13204 // Cartoon +865 = S19.2E-1-1102-13205 // EuroSport 2 +854 = S19.2E-1-1102-13201 // The History Channel +844 = S19.2E-1-1102-13206 // Kinowelt +867 = S19.2E-1-1115-13109 // NASN Germany +// 845 = S19.2E-1-1102-13202 // National Geographic +149 = S19.2E-1-1068-28520 // TCM +// +// Regionalsender +829 = S19.2E-1-1113-12614 // rheinmaintv +825 = S19.2E-133-7-768 // RNFplus +889 = S19.2E-1-1092-10106 // München.TV +// +// Oesterreich +14 = S19.2E-1-1117-13001 // ORF1 +15 = S19.2E-1-1117-13002 // ORF2 +//15 = S19.2E-1-1117-13003 // ORF2 W +//15 = S19.2E-1-1117-13004 // ORF2 N +//15 = S19.2E-1-1117-13005 // ORF2 B +//15 = S19.2E-1-1117-13006 // ORF2 O +//15 = S19.2E-1-1117-13007 // ORF2 S +//15 = S19.2E-1-1117-13008 // ORF2 T +//15 = S19.2E-1-1117-13009 // ORF2 V +//15 = S19.2E-1-1117-13010 // ORF2 St +//15 = S19.2E-1-1117-13011 // ORF2 K +//15 = S19.2E-1-1117-13014 // ORF2E +958 = S19.2E-1-1117-13012 // ATVplus +959 = S19.2E-1-1115-13101 // TW1 +836 = S19.2E-1-1091-28800 // RTL AT +896 = S19.2E-1-1091-28810 // RTL 2 AT +835 = S19.2E-1-1082-20002 // ProSieben AT +834 = S19.2E-1-1082-20005 // SAT.1 AT +866 = S19.2E-1-1082-20004 // Kabel eins AT +914 = S19.2E-133-7-53 // Premiere Austria +887 = S19.2E-1-1115-13102 // gotv +// +// Easy.TV +845 = S19.2E-1-1115-13104 // National Geographic +838 = S19.2E-1-1115-13105 // Silverline +847 = S19.2E-1-1115-13106 // AXN +849 = S19.2E-1-1115-13107 // Extreme Sports DE +839 = S19.2E-1-1115-13108 // Erotik First +// +// MTV +121 = S19.2E-1-1078-28676 // VIVA +109 = S19.2E-1-1078-28673 // MTV +2151 = S19.2E-1-1066-28666 // VH1. +897 = S19.2E-1-1066-28657 // VH1 Classic +// +// Italien +3062 = S13.0E-64511-10100-9472 // Boomerang +3001 = S13.0E-272-6000-2 // CANALE 5 +3003 = S13.0E-64511-6300-8129 // Cartoon Network +3007 = S13.0E-64511-5900-11440 // Classica +3008 = S13.0E-64511-6300-8137 // Cult Network +3009 = S13.0E-64511-6600-11113 // Discovery Channel +3065 = S13.0E-64511-5700-11303 // Discovery Scienza +3010 = S13.0E-64511-6200-10928 // Disney Channel +3071 = S13.0E-64511-6600-11111 // E! Entertainment Int +3072 = S13.0E-64511-6700-11511 // ESPN Classic Sports +3012 = S13.0E-64511-5700-11305 // Eurosport +3068 = S13.0E-64511-10100-9474 // Fox +3015 = S13.0E-272-6000-1 // ITALIA 1 +3061 = S13.0E-64511-6300-8131 // Jetix +3000 = S13.0E-64511-5600-3530 // Jimmy +3051 = S13.0E-64511-5900-11445 // La 7 +3073 = S13.0E-64511-5800-3631 // Leonardo +3019 = S13.0E-64511-5900-11426 // MTV +3067 = S13.0E-64511-10100-9470 // National Geographic +//3034 = S19.2E-1-1024-9015 // Rai Uno (Astra 1 FTA) +3034 = S13.0E-318-5200-3401 // Rai Uno (Eutelsat FTA) +3023 = S13.0E-318-5200-3402 // Rai Due +3033 = S13.0E-318-5200-3403 // Rai Tre +//3034 = S13.0E-318-12400-8511 // Rai Uno (Eutelsat encrypted) +//3023 = S13.0E-318-12400-8512 // Rai Due +//3033 = S13.0E-318-12400-8513 // Rai Tre +3070 = S13.0E-318-5400-3301 // RaiNews24 +3026 = S13.0E-64511-8600-11718 // Raisat Cinema +3058 = S13.0E-318-5400-3305 // Raisat Sport +3031 = S13.0E-64511-8600-11727 // Raisat YOYO +3035 = S13.0E-272-6000-3 // RETE 4 +3074 = S13.0E-64511-5600-3578 // Sailing Channel (IT) +3060 = S13.0E-64511-6600-11101 // Sky Cinema 1 +3045 = S13.0E-64511-8600-11724 // Sky Cinema 16:9 +3048 = S13.0E-64511-6600-11105 // Sky Cinema 3 +3049 = S13.0E-64511-6600-11103 // Sky Cinema Mania +3050 = S13.0E-64511-6600-11115 // Sky Cinema Max +3063 = S13.0E-64511-6200-10920 // Sky Sport 1 +3064 = S13.0E-64511-6200-10921 // Sky Sport 2 +3042 = S13.0E-64511-10100-9477 // Studio Universal +3066 = S13.0E-64511-10100-9471 // The History Channel +// +// Luxemburg +1055 = S19.2E-1-1108-3994 // RTL Tele Letzeburg +// +// Niederlande +1050 = S19.2E-53-1097-2020 // Animal Planet +1032 = S19.2E-53-1109-5025 // BVN-TV +1074 = S19.2E-53-1097-2030 // Cartoon Network NL +1051 = S19.2E-53-1097-2015 // Discovery Channel +1052 = S19.2E-53-1097-2025 // Eurosport +1082 = S19.2E-53-1105-4005 // Film1.1 +1083 = S19.2E-53-1105-4007 // Film1.2 +1042 = S19.2E-53-1097-2035 // Hallmark +1045 = S19.2E-1-1078-28679 // MTV NL +1053 = S19.2E-53-1105-4015 // National Geographic +88 = S19.2E-53-1105-4011 // Nederland 1 +89 = S19.2E-53-1105-4012 // Nederland 2 +90 = S19.2E-53-1105-4013 // Nederland 3 +1047 = S19.2E-53-1109-5004 // Net 5 +1048 = S19.2E-53-1109-5010 // Nickelod./Talpa +1057 = S19.2E-53-1105-4014 // Nickelod/The Box +1054 = S19.2E-53-1097-2004 // RTL 4 +1061 = S19.2E-53-1097-2005 // RTL 5 +1071 = S19.2E-53-1097-2006 // RTL 7 +1062 = S19.2E-53-1109-5005 // SBS 6 +1065 = S19.2E-53-1097-2030 // TCM +1056 = S19.2E-53-1109-5015 // TMF +1070 = S19.2E-53-1109-5020 // Veronica +// +// Frankreich +2507 = S19.2E-1-1080-8801 // France 2 +2508 = S19.2E-1-1080-8802 // France 3 +2555 = S19.2E-1-1110-9301 // France 4 +2535 = S19.2E-1-1090-8501 // France 5 Sat +2546 = S19.2E-1-1024-9012 // TV5 Monde +2559 = S19.2E-1-1112-12240 // TV5 Europe +2500 = S19.2E-1-1024-9019 // Arte +2501 = S19.2E-1-1072-8201 // Canal+ +2522 = S19.2E-1-1072-8202 // Canal+ Décalé +2523 = S19.2E-1-1072-8203 // Canal+ Cinema +2524 = S19.2E-1-1072-8208 // Canal+ Sport +2584 = S19.2E-1-1072-8213 // Canal+ Hi-Tech +2576 = S19.2E-1-1074-8351 // Cinécinéma Auteur +2526 = S19.2E-1-1072-8206 // Cinécinéma Premier +2568 = S19.2E-1-1070-8002 // Cinécinéma Emotion +2569 = S19.2E-1-1070-8003 // Cinécinéma Frisson +2558 = S19.2E-1-1100-8709 // Cinécinéma Classic +2575 = S19.2E-1-1100-8711 // Cinécinéma Famiz +2567 = S19.2E-1-1068-28521 // Cartoon Network +2517 = S19.2E-1-1068-28525 // TCM +2591 = S19.2E-1-1070-8001 // Seasons +2564 = S19.2E-1-1070-8004 // EuroNews +2512 = S19.2E-1-1070-8005 // Paris Première +2503 = S19.2E-1-1070-8006 // Jimmy +2540 = S19.2E-1-1070-8007 // Mezzo +2543 = S19.2E-1-1070-8009 // Sport+ +2606 = S19.2E-1-1070-8010 // I>Télé +2533 = S19.2E-1-1070-8011 // Histoire +2531 = S19.2E-1-1072-8207 // Disney Channel +2511 = S19.2E-1-1074-8352 // MCM +2587 = S19.2E-1-1074-8354 // MCM Pop +2595 = S19.2E-1-1074-8365 // MCM Top +2538 = S19.2E-1-1066-28652 // MTV France +2537 = S19.2E-1-1074-8357 // W 9 +2607 = S19.2E-1-1074-8358 // Europe 2 TV +2506 = S19.2E-1-1076-8151 // Eurosport +2519 = S19.2E-1-1076-8152 // TMC +2513 = S19.2E-1-1076-8153 // Planète +2548 = S19.2E-1-1076-8155 // Voyage +2534 = S19.2E-1-1076-8156 // LCI +2502 = S19.2E-1-1076-8157 // Canal J +2585 = S19.2E-1-1076-8160 // Cuisine.TV +2592 = S19.2E-1-1076-8162 // TiJi +2514 = S19.2E-1-1080-8805 // RTL 9 +2530 = S19.2E-1-1100-8702 // Comédie ! +2520 = S19.2E-1-1100-8703 // 13ème Rue +2532 = S19.2E-1-1100-8705 // Jetix +2589 = S19.2E-1-1100-8708 // National Geographic +2597 = S19.2E-1-1100-8710 // NRJ 12 +2510 = S19.2E-1-1108-12122 // M6 +2609 = S19.2E-1-1114-8903 // Gulli +2516 = S19.2E-1-1114-8905 // Téva +2588 = S19.2E-1-1114-8910 // Motors TV +2563 = S19.2E-1-1094-17022 // AB Animaux +2521 = S19.2E-1-1094-17021 // AB 1 +2525 = S19.2E-1-1094-17024 // XXL +// +// Spanien +3268 = S19.2E-1-1032-30202 // Andalucía TV +3270 = S19.2E-1-1056-29956 // AXN +3271 = S19.2E-1-1046-30510 // Calle 13 +3254 = S19.2E-1-1038-30400 // Canal+ +3290 = S19.2E-1-1034-30651 // Canal Clásico +3301 = S19.2E-1-1056-29953 // Canal Cocina +3298 = S19.2E-1-1034-30658 // Canal de Historia +3275 = S19.2E-1-1032-30206 // Canal Estrellas +3278 = S19.2E-1-1034-30657 // Canal Hollywood +3307 = S19.2E-1-1034-30663 // Cuatro +3295 = S19.2E-1-1038-30406 // Discovery Channel +3277 = S19.2E-1-1038-30403 // Disney Channel +3297 = S19.2E-1-1038-30401 // Docu TVE +3284 = S19.2E-1-1034-30680 // Eurosport +3272 = S19.2E-1-1056-29955 // Fox TV +3293 = S19.2E-1-1008-29801 // Jetix +3302 = S19.2E-1-1032-30204 // La Otra +3308 = S19.2E-1-1054-30356 // La Sexta +3286 = S19.2E-1-1066-28651 // MTV España +3299 = S19.2E-1-1060-30605 // National Geographic +3294 = S19.2E-1-1066-28660 // Nickelodeon +3273 = S19.2E-1-1046-30506 // Paramount Comedy +3285 = S19.2E-1-1038-30404 // Sportmania +3281 = S19.2E-1-1068-28526 // TCM +3276 = S19.2E-1-1034-30656 // Telenovelas +3303 = S19.2E-1-1032-30201 // TVC Internacional +3250 = S19.2E-1-1054-30355 // TVE 1 +3274 = S19.2E-1-1034-30654 // TVE 50 Años +3251 = S19.2E-1-1046-30509 // TVE La 2 +3262 = S19.2E-1-1032-30222 // TV Galicia +// +// Portugal +2562 = S19.2E-1-1024-9017 // RTPi +// +// Schweiz +24 = S13.0E-318-8500-901 // SF 1 +900 = S13.0E-318-8500-907 // SF zwei +820 = S13.0E-318-8500-911 // SF info +2544 = S13.0E-318-1700-14002 // TSR 1 +2545 = S13.0E-318-1700-14008 // TSR 2 +3043 = S13.0E-318-1700-14003 // TSI 1 +3053 = S13.0E-318-1700-14009 // TSI 2 +2207 = S19.2E-1-1114-8909 // BBC Prime (CET), ch +855 = S19.2E-1-1082-20001 // ProSieben Schweiz +832 = S19.2E-133-7-48 // SAT.1 Schweiz +//4 = S13.0E-318-12700-8003 // RTL +//9 = S13.0E-318-15500-609 // RTL2 +//179 = S13.0E-318-15500-610 // Super RTL +//11 = S13.0E-318-12700-8002 // VOX +// +// Türkei +40 = S19.2E-1-1026-10003 // TRT International +// +// UK +2195 = S28.2E-2-2051-9010 // ABC1 +2006 = S28.2E-2-2316-53595 // Adult Channel +2130 = S28.2E-2-2025-5703 // Adventure One +2169 = S28.2E-2-2009-6202 // Animal Planet dig. +2008 = S28.2E-2-2045-6301 // BBC 1 London +//2008 = S28.2E-2-2046-10301 // BBC 1 W Mids +//2008 = S28.2E-2-2046-10302 // BBC 1 N West +//2008 = S28.2E-2-2046-10303 // BBC 1 Yrks&Lin +//2008 = S28.2E-2-2046-10304 // BBC 1 Yorks +//2008 = S28.2E-2-2046-10305 // BBC 1 E Mids +//2008 = S28.2E-2-2046-10306 // BBC 1 East (E) +//2008 = S28.2E-2-2048-10351 // BBC 1 West +//2008 = S28.2E-2-2048-10352 // BBC 1 S East +//2008 = S28.2E-2-2048-10353 // BBC 1 South +//2008 = S28.2E-2-2048-10354 // BBC 1 S West +//2008 = S28.2E-2-2048-10355 // BBC 1 NE & C +//2008 = S28.2E-2-2048-10356 // BBC 1 Oxford +//2008 = S28.2E-2-2050-6903 // BBC 1 East (W) +//2008 = S28.2E-2-2050-6904 // BBC 1 CI +2002 = S28.2E-2-2047-6411 // BBC 1 Wales +2001 = S28.2E-2-2047-6421 // BBC 1 Scotland +2000 = S28.2E-2-2045-6331 // BBC 1 NI +2009 = S28.2E-2-2045-6302 // BBC 2 England +2003 = S28.2E-2-2047-6432 // BBC2 NI +2005 = S28.2E-2-2047-6412 // BBC 2W +2004 = S28.2E-2-2047-6422 // BBC 2 Scotland +2020 = S28.2E-2-2045-6319 // BBC Three +2070 = S28.2E-2-2045-6316 // BBC Four +2042 = S28.2E-2-2013-6705 // BBC Parliament +2037 = S28.2E-2-2045-6304 // BBC News 24 +2191 = S28.2E-2-2017-7250 // Bid TV +2011 = S28.2E-2-2306-52550 // Bloomberg TV +2162 = S28.2E-2-2018-7102 // Boomerang +2013 = S28.2E-2-2002-6004 // Bravo (Digital) +2027 = S28.2E-2-2025-5710 // British Eurosport +2060 = S28.2E-2-2018-7100 // Cartoon Network +2182 = S28.2E-2-2045-6317 // CBBC +2183 = S28.2E-2-2045-6318 // CBeebies +2170 = S28.2E-2-2002-6002 // Challenge dig. +2015 = S28.2E-2-2024-9201 // Channel 4 +2090 = S28.2E-2-2044-10071 // CITV +2024 = S28.2E-2-2311-52111 // CNBC Europe +2025 = S28.2E-2-2018-7140 // CNN +2188 = S28.2E-2-2027-5802 // Community Channel +2081 = S28.2E-2-2009-6207 // Disc. Civilisations +2079 = S28.2E-2-2009-6201 // Discovery Channel +2083 = S28.2E-2-2009-6209 // Discovery Kids +2084 = S28.2E-2-2009-6206 // Discovery Science +2086 = S28.2E-2-2009-6219 // Discovery Wings +2082 = S28.2E-2-2009-6203 // Discov. Real Time +2085 = S28.2E-2-2009-6205 // Disc. Travel Living +2026 = S28.2E-2-2051-9001 // Disney +2228 = S28.2E-2-2051-9002 // Disney Cinemagic +2209 = S28.2E-2-2025-5770 // E! +2160 = S28.2E-2-2042-8305 // E4 +2214 = S28.2E-2-2042-8300 // E4 +1 +2087 = S28.2E-2-2602-54104 // Euronews +2164 = S28.2E-2-2403-4164 // Fashion TV +2210 = S28.2E-2-2409-50850 // Fashion TV +2028 = S28.2E-2-2042-8335 // Film4 +2219 = S28.2E-2-2042-8330 // Film4 +1 +2016 = S28.2E-2-2031-9342 // Five +2190 = S28.2E-2-2303-52231 // Ftn +2229 = S28.2E-2-2305-52408 // Golf Channel UK +2091 = S28.2E-2-2023-5010 // Hallmark UK +2173 = S28.2E-2-2408-4653 // History Channel dig. +2192 = S28.2E-2-2017-7200 // Ideal World +2017 = S28.2E-2-2044-10060 // ITV1 London +2018 = S28.2E-2-2044-10100 // ITV1 Central +2067 = S28.2E-2-2049-10040 // ITV1 West Country +2036 = S28.2E-2-2053-10140 // ITV1 Meridian +2068 = S28.2E-2-2053-10160 // ITV1 Yorkshire +2007 = S28.2E-2-2041-10180 // ITV1 Anglia +2061 = S28.2E-2-2041-10190 // ITV1 Tyne Tees +2034 = S28.2E-2-2049-10030 // ITV1 West +2032 = S28.2E-2-2044-10080 // ITV1 Granada +2012 = S28.2E-2-2049-10050 // ITV1 Border +2033 = S28.2E-2-2049-10020 // ITV1 Wales +2035 = S28.2E-2-2044-10070 // ITV2 +2194 = S28.2E-2-2054-10260 // ITV3 +2215 = S28.2E-2-2044-10072 // ITV4 +2030 = S28.2E-2-2031-9350 // Jetix +2095 = S28.2E-2-2002-6001 // LIVINGtv +2171 = S28.2E-2-2037-7560 // Men & Motors +2211 = S28.2E-2-2042-8340 // More4 +2158 = S19.2E-1-1066-28665 // MTV Base. +// 2158 = S28.2E-2-2010-7007 // MTV Base +2159 = S19.2E-1-1066-28669 // MTV2. +// 2159 = S28.2E-2-2010-7003 // MTV 2 +2225 = S28.2E-2-2010-7014 // MTV Dance +2156 = S19.2E-1-1066-28664 // MTV Hits. +// 2156 = S28.2E-2-2010-7006 // MTV Hits +2096 = S28.2E-2-2010-7001 // MTV UK +2097 = S28.2E-2-2025-5701 // MUTV +2189 = S28.2E-2-2409-50839 // NASN +2174 = S28.2E-2-2030-4607 // Nat. Geographic dig. +2216 = S28.2E-2-2030-4608 // Nat. Geogrpahic +1 +2099 = S28.2E-2-2029-5602 // Nickelodeon (dig.) +2100 = S28.2E-2-2029-5605 // Nick Junior +2041 = S28.2E-2-2025-5904 // Paramount Comedy +2103 = S28.2E-2-2305-52402 // Performance +2104 = S28.2E-2-2403-4131 // Playboy TV +2222 = S28.2E-2-2051-9004 // Playhouse Disney +2198 = S28.2E-2-2017-7252 // price-drop.tv +2044 = S28.2E-2-2017-7230 // QVC +2221 = S28.2E-2-2409-50836 // Racing UK +2193 = S28.2E-2-2612-8652 // Reality TV UK +2045 = S28.2E-2-2043-9601 // RT One +2046 = S28.2E-2-2043-9602 // RT Two +2073 = S28.2E-2-2022-7301 // S4C digidol +2107 = S28.2E-2-2023-4905 // Sci-Fi Satelite +2112 = S28.2E-2-2027-4705 // Sky One, uk +2217 = S28.2E-2-2027-5103 // Sky Three, uk +2054 = S28.2E-2-2007-4303 // Sky Movies 1, uk +2051 = S28.2E-2-2007-4302 // Sky Movies 2, uk +2114 = S28.2E-2-2007-4403 // Sky Movies 3, uk +2111 = S28.2E-2-2007-4304 // Sky Movies 4, uk +2179 = S28.2E-2-2007-4305 // Sky Movies 5, uk +2176 = S28.2E-2-2007-4306 // Sky Movies 6, uk +2180 = S28.2E-2-2030-4603 // Sky Movies 7, uk +2178 = S28.2E-2-2007-5502 // Sky Movies 8, uk +2177 = S28.2E-2-2030-4602 // Sky Movies 9, uk +2226 = S28.2E-2-2030-4604 // Sky Movies 10, uk +2056 = S28.2E-2-2023-4914 // Sky Sports 1, uk +2057 = S28.2E-2-2052-9314 // Sky Sports 2, uk +2058 = S28.2E-2-2021-4219 // Sky Sports 3, uk +2131 = S28.2E-2-2023-4907 // Sky Sports News, uk +2050 = S28.2E-2-2408-4651 // Sky Cinema, uk +2175 = S28.2E-2-2408-4652 // Sky Movies Cinema 2, uk +2116 = S28.2E-2-2052-5005 // Sky Travel, uk +2053 = S28.2E-2-2026-4706 // Sky News, uk +2117 = S28.2E-2-2014-7420 // Sony Entertainment +2123 = S28.2E-2-2025-5714 // TCM +2218 = S28.2E-2-2037-7500 // Teachers' TV +2059 = S28.2E-2-2043-9603 // TG4 +2119 = S28.2E-2-2027-5206 // The Box +2200 = S28.2E-2-2019-9349 // The Hits +2199 = S28.2E-2-2010-7009 // TMF (UK) +2223 = S28.2E-2-2018-7103 // Toonami +2121 = S28.2E-2-2002-6003 // Trouble Digital +2062 = S28.2E-2-2043-9605 // TV3 +2163 = S28.2E-2-2052-9313 // TV Travel Shop +2186 = S28.2E-2-2015-7635 // UKTV Bright Ideas +2127 = S28.2E-2-2006-6502 // UKTV Documentary +2125 = S28.2E-2-2006-6521 // UKTV Drama +2197 = S28.2E-2-2006-6508 // UKTV Food +2126 = S28.2E-2-2006-6506 // UKTV G2 +2063 = S28.2E-2-2006-6504 // UKTV Gold +2184 = S28.2E-2-2006-6505 // UKTV History +2187 = S28.2E-2-2015-7611 // UKTV People +2128 = S28.2E-2-2006-6501 // UKTV Style +2066 = S28.2E-2-2010-7002 // VH1 +2157 = S28.2E-2-2010-7008 // VH1 Classic +2129 = S28.2E-2-2014-7460 // Zee TV diff --git a/examples/tvtv_channelmap.conf_DVB_Mch b/examples/tvtv_channelmap.conf_DVB_Mch new file mode 100644 index 0000000..f63252c --- /dev/null +++ b/examples/tvtv_channelmap.conf_DVB_Mch @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////// +// ChannelMap for TVTV-Plugin +////////////////////////////////////////////////////////////// +// +// TVTV ChannelID = VDR ChannelID (Src-NID-TID-SID) +// +//// Kabelfernsehen Muenchen +// +// 394 MHz +2 = C-1-1079-28006 // ZDF +118 = C-1-1079-28007 // 3sat +963 = C-1-1079-28011 // ZDF infokanal +960 = C-1-1079-28014 // ZDF dokukanal +961 = C-1-1079-28016 // ZDF theaterkanal +63 = C-1-1079-28008 // KiKa +// +// 410 MHz +1 = C-1-1101-28106 // ARD +10 = C-1-1101-28109 // ARTE +206 = C-1-1101-28114 // Phoenix +17 = C-1-1101-28111 // WDR Köln +26 = C-1-1101-28108 // HR +57 = C-1-1101-28112 // BR-alpha +18 = C-1-1101-28107 // BR3 +29 = C-1-1101-28113 // SWR BW +// +// 426 MHz +962 = C-1-1073-28201 // Eins Extra +955 = C-1-1073-28202 // Eins Festival +956 = C-1-1073-28203 // EinsPlus +//35 = C-1-1073-28205 // rbb Brandenburg +35 = C-1-1073-28206 // rbb Berlin +30 = C-1-1073-28231 // SWR RP +//19 = C-1-1073-28224 // NDR FS MV +19 = C-1-1073-28225 // NDR FS HH +//19 = C-1-1073-28226 // NDR FS NDS +//19 = C-1-1073-28227 // NDR FS SH +33 = C-1-1073-28204 // MDR +//33 = C-1-1073-28228 // MDR SACHSEN +//33 = C-1-1073-28229 // MDR S-ANHALT +//33 = C-1-1073-28230 // MDR THÜRINGEN +// +// +//// DVB-T Muenchen +// +// Kanal 34 +4 = T-8468-12801-16405 // RTL +9 = T-12338-0-16406 // RTL2 +11 = T-12338-0-16418 // VOX +179 = T-12338-0-16411 // Super RTL +// +// Kanal 48 +5 = T-8468-13057-16408 // SAT.1 +6 = T-8468-13057-16403 // ProSieben +8 = T-8468-13057-16394 // Kabel eins +953 = T-8468-13313-16420 // N24 +// +// Kanal 66 +105 = T-8468-13313-16413 // TELE-5 +107 = T-8468-13313-16420 // Eurosport +40 = T-8468-13313-16393 // HSE24 +889 = T-8468-13313-1856 // München.TV @@ -0,0 +1,590 @@ +/* + * i18n.c: Internationalization + * + */ + +#include "i18n.h" + +const tI18nPhrase Phrases[] = { + { "TVTV", // English + "TVTV", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "TVTV Timers update", // English + "TVTV Timers update", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "TVTV User Name", // English + "TVTV Benutzername", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "TVTV Password", // English + "TVTV Passwort", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "Auto Update", // English + "Automatisches Update", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "Updatetime (min)", // English + "Updatezeit (min)", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "Use Nature within File Name", // English + "Genre im Dateinamen verwenden", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "Use Station Name within File Name", // English + "Sendernamen im Dateinamen verwenden", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "TVTV update will be started", // English + "TVTV update wird ausgeführt", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "Show In Main Menu", // English + "Im Hauptmenü anzeigen", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "Use VPS", // English + "VPS benutzen", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "TVTV Server", // English + "TVTV Server", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "Use HTTP Proxy", // English + "HTTP Proxy benutzen", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { " HTTP Proxy", // English + " HTTP Proxy", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "Use TVTV description in info.vdr", // English + "Beschreibung in info.vdr übernehmen", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "Time shift bugfix", // English + "\"Zeitproblem\"-Fix aktivieren", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { " Time shift (hrs)", // English + " Zeitverschiebung (Std)", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "Reload ChannelMap", // English + "ChannelMap neu laden", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "Really reload ChannelMap?", // English + "ChannelMap wirklich neu laden?", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { "TVTV Download Error", // English + "TVTV: Fehler beim Download", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "", // Suomi + "", // Polski + "", // Español + "", // Greek + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Català +#if VDRVERSNUM > 10302 + "", // Russian +#if VDRVERSNUM > 10307 + "", // Hrvatski +#if VDRVERSNUM > 10313 + "", // Eesti +#if VDRVERSNUM > 10316 + "", // Dansk +#endif +#endif +#endif +#endif + }, + { NULL } + }; @@ -0,0 +1,16 @@ +/* + * i18n.h: Internationalization + * + * See the README file for copyright information and how to reach the author. + * + * $Id: i18n.h 1.2 2002/05/11 14:48:16 kls Exp $ + */ + +#ifndef _I18N__H +#define _I18N__H + +#include <vdr/i18n.h> + +extern const tI18nPhrase Phrases[]; + +#endif //_I18N__H diff --git a/md5tools.c b/md5tools.c new file mode 100644 index 0000000..9021537 --- /dev/null +++ b/md5tools.c @@ -0,0 +1,207 @@ +/* + * md5tools.c: TVTV plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + + +#include "md5tools.h" + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. +*/ +void MD5Transform(uint32_t buf[4], uint32_t in[16]) +{ + register uint32_t a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. +*/ +void MD5Init(MD5_CTX *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. +*/ +void MD5Update(MD5_CTX *ctx, unsigned char *buf, unsigned len) +{ + uint32_t t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if (len < t) { + memcpy(p, buf, len); + return; + } + memcpy(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + buf += t; + len -= t; + } + + /* Process data in 64-byte chunks */ + + while (len >= 64) { + memcpy(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) +*/ +void MD5Final(unsigned char digest[16], MD5_CTX *ctx) +{ + unsigned count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ((uint32_t *) ctx->in)[14] = ctx->bits[0]; + ((uint32_t *) ctx->in)[15] = ctx->bits[1]; + + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + byteReverse((unsigned char *) ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ +} + diff --git a/md5tools.h b/md5tools.h new file mode 100644 index 0000000..a52bf25 --- /dev/null +++ b/md5tools.h @@ -0,0 +1,47 @@ +/* + * md5tools.h: TVTV plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#ifndef __MD5TOOLS_H +#define __MD5TOOLS_H + +#include <stdint.h> +#include <string.h> + + +/* ---- MD5 ---- */ +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) + +// MD5 + +typedef unsigned long uint32; + +struct MD5Context { + uint32_t buf[4]; + uint32_t bits[2]; + unsigned char in[64]; +}; + +typedef struct MD5Context MD5_CTX; +#define byteReverse(buf, len) /* Nothing */ + + +void MD5Init(MD5_CTX *ctx); +void MD5Update(MD5_CTX *ctx, unsigned char *buf, unsigned len); +void MD5Final(unsigned char digest[16], MD5_CTX *ctx); + + +#endif //__MD5TOOLS_H @@ -0,0 +1,308 @@ +/* + * tvtv.c: TVTV plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include "i18n.h" +#include "config.h" +#include "update.h" + + +static const char *VERSION = "0.3.3"; +static const char *DESCRIPTION = "TVTV Timers update"; +static const char *MAINMENUENTRY = "TVTV"; + +cUpdate *oUpdate; + +class cPluginTVTV : public cPlugin { +private: +#if VDRVERSNUM >= 10307 + cSkinDisplayMessage *displayMessage; +#endif +public: + cPluginTVTV(void); + virtual ~cPluginTVTV(); + virtual const char *Version(void) { return VERSION; } + virtual const char *Description(void) { return tr(DESCRIPTION); } + virtual const char *CommandLineHelp(void); +#if VDRVERSNUM >= 10331 + virtual const char **SVDRPHelpPages(void); + virtual cString SVDRPCommand(const char *Cmd, const char *Option, int &ReplyCode); +#endif + virtual bool Start(void); + virtual const char *MainMenuEntry(void) { return (TVTVConfig.show_in_mainmenu ? MAINMENUENTRY : NULL); } + virtual cOsdMenu *MainMenuAction(void); + virtual cMenuSetupPage *SetupMenu(void); + virtual bool SetupParse(const char *Name, const char *Value); + + void DisplayMessage(const char *s); + }; + +// --- cMenuSetupTVTV ------------------------------------------------------- + +class cMenuSetupTVTV : public cMenuSetupPage { +private: + cTVTVConfig data; + virtual void Setup(void); +protected: + virtual eOSState ProcessKey(eKeys Key); + virtual void Store(void); +public: + cMenuSetupTVTV(void); + }; + +cMenuSetupTVTV::cMenuSetupTVTV(void) { + data = TVTVConfig; + Setup(); +} + +void cMenuSetupTVTV::Setup(void) { + int current = Current(); + + Clear(); + + Add(new cMenuEditStraItem( tr("TVTV Server"), &data.tvtv_server, TVTVSRV_CNT, TVTV_SERVERS)); + Add(new cMenuEditStrItem( tr("TVTV User Name"), data.username, sizeof(data.username), tr(FileNameChars))); + Add(new cMenuEditStrItem( tr("TVTV Password"), data.password, sizeof(data.password), tr(FileNameChars))); + Add(new cMenuEditBoolItem( tr("Use HTTP Proxy"), &data.useproxy)); + if (data.useproxy) + Add(new cMenuEditStrItem( tr(" HTTP Proxy"), data.httpproxy, sizeof(data.httpproxy), tr(FileNameChars))); + Add(new cMenuEditBoolItem( tr("Auto Update"), &data.autoupdate)); + Add(new cMenuEditIntItem( tr("Updatetime (min)"), &data.updatetime)); + Add(new cMenuEditBoolItem( tr("Show In Main Menu"), &data.show_in_mainmenu)); + +// VPS was introduced with VDR 1.3.5 +#if VDRVERSNUM >= 10305 + Add(new cMenuEditBoolItem( tr("Use VPS"), &data.usevps)); +#endif + + Add(new cMenuEditBoolItem( tr("Use Nature within File Name"), &data.usegenre)); + Add(new cMenuEditBoolItem( tr("Use Station Name within File Name"), &data.usestation)); + +// Starting with VDR 1.3.44, the description of a recording is +// taken from EPG. This switch decides whether or not the description +// coming from TVTV will be added as a comment to info.vdr. +#if VDRVERSNUM >= 10344 + Add(new cMenuEditBoolItem( tr("Use TVTV description in info.vdr"), &data.usetvtvdescr)); +#endif + + Add(new cMenuEditBoolItem( tr("Time shift bugfix"), &data.tvtv_bugfix)); + if (data.tvtv_bugfix) + Add(new cMenuEditIntItem( tr(" Time shift (hrs)"), &data.tvtv_bugfix_hrs, 1, 4)); + + Add(new cOsdItem(tr("Reload ChannelMap"),osUser9)); + + SetCurrent(Get(current)); + Display(); +} + + +eOSState cMenuSetupTVTV::ProcessKey(eKeys Key) { + int olduseproxy = data.useproxy; + int oldtvtvbugfix = data.tvtv_bugfix; + eOSState state = cMenuSetupPage::ProcessKey(Key); + + switch(state) { + case osUser9: + state=osContinue; + if(Interface->Confirm(tr("Really reload ChannelMap?"))) { + if (oUpdate) oUpdate->ReloadChannelMap(); + state=osEnd; + } + break; + + case osContinue: + if(NORMALKEY(Key)==kUp || NORMALKEY(Key)==kDown) { + cOsdItem *item=Get(Current()); + if(item) item->ProcessKey(kNone); + } + break; + + default: + break; + } + + if (Key != kNone && ((data.useproxy != olduseproxy) || (data.tvtv_bugfix != oldtvtvbugfix))) Setup(); + return state; +} + + +void cMenuSetupTVTV::Store(void) +{ + dsyslog("TVTV: cMenuSetupTVTV::Store()"); + TVTVConfig = data; + SetupStore("TVTVServer", TVTVConfig.tvtv_server); + SetupStore("UserName", TVTVConfig.username); + SetupStore("Password", TVTVConfig.password); + SetupStore("UseProxy", TVTVConfig.useproxy); + SetupStore("HTTPProxy", TVTVConfig.httpproxy); + SetupStore("AutoUpdate", TVTVConfig.autoupdate); + SetupStore("UpdateTime", TVTVConfig.updatetime); + SetupStore("UseGenreInFName", TVTVConfig.usegenre); + SetupStore("UseStationInFName", TVTVConfig.usestation); + SetupStore("ShowInMainMenu", TVTVConfig.show_in_mainmenu); + +// VPS was introduced with VDR 1.3.5 +#if VDRVERSNUM >= 10305 + SetupStore("UseVps", TVTVConfig.usevps); +#endif + +#if VDRVERSNUM >= 10344 + SetupStore("UseTVTVDescr", TVTVConfig.usetvtvdescr); +#endif + + SetupStore("TVTVBugfix", TVTVConfig.tvtv_bugfix); + SetupStore("TVTVBugfixHrs", TVTVConfig.tvtv_bugfix_hrs); + + if (TVTVConfig.autoupdate) + if (oUpdate) + oUpdate->StartUpdate(); +} + +// --- cPluginTVTV ---------------------------------------------------------- + +cPluginTVTV::cPluginTVTV(void) +{ + // Initialize any member variables here. + // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL + // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT! + oUpdate = NULL; +} + +cPluginTVTV::~cPluginTVTV() +{ + // Clean up after yourself! + if (oUpdate) + delete oUpdate; +} + + +void cPluginTVTV::DisplayMessage(const char *s) { + + isyslog("TVTV: %s", s); + +#if VDRVERSNUM >= 10307 + if (!Skins.Current()) return; + if (!cSkinDisplay::Current() && !displayMessage) + displayMessage = Skins.Current()->DisplayMessage(); + cSkinDisplay::Current()->SetMessage(mtWarning, s); + cSkinDisplay::Current()->Flush(); + cStatus::MsgOsdStatusMessage(s); + Interface->Wait(0); + if (displayMessage) { + delete displayMessage; + displayMessage = NULL; + cStatus::MsgOsdClear(); + } + else { + cSkinDisplay::Current()->SetMessage(mtWarning, NULL); + cStatus::MsgOsdStatusMessage(NULL); + } +#else + Interface->Open(Setup.OSDwidth, -1); + Interface->Status(s, clrBlack, clrYellow); + + // Wait some seconds + time_t timeout = time(NULL) + Setup.OSDMessageTime; + for (;;) { if (time(NULL) > timeout) break; } + + Interface->Status(NULL); + Interface->Close(); +#endif +} + + +const char *cPluginTVTV::CommandLineHelp(void) +{ + // Return a string that describes all known command line options. + return NULL; +} + +#if VDRVERSNUM >= 10331 +const char **cPluginTVTV::SVDRPHelpPages(void) { + static const char *HelpPages[] = { + "RELOAD\n" + " Reloads the channel map configuration file.", + "UPDATE\n" + " Update TVTV timer list.", + NULL + }; + return HelpPages; +} + +cString cPluginTVTV::SVDRPCommand(const char *Cmd, const char *Option, int &ReplyCode) { + if (strcasecmp(Cmd, "RELOAD") == 0) { + oUpdate->ReloadChannelMap(); + return "Channel map reloaded."; + } + else if (strcasecmp(Cmd, "UPDATE") == 0) { + oUpdate->StartUpdate(); + return "TVTV update done."; + } + return NULL; +} +#endif + +bool cPluginTVTV::Start(void) +{ + // Start any background activities the plugin shall perform. + RegisterI18n(Phrases); + + oUpdate = new cUpdate(); + + if (oUpdate && TVTVConfig.autoupdate) + oUpdate->StartUpdate(); + + return (oUpdate != NULL); +} + +cOsdMenu *cPluginTVTV::MainMenuAction(void) +{ + // Perform the action when selected from the main VDR menu. + if (oUpdate) oUpdate->StartUpdate(); + DisplayMessage(tr("TVTV update will be started")); + return NULL; +} + + +cMenuSetupPage *cPluginTVTV::SetupMenu(void) +{ + // Return a setup menu in case the plugin supports one. + return new cMenuSetupTVTV; +} + +bool cPluginTVTV::SetupParse(const char *Name, const char *Value) +{ + // Parse your own setup parameters and store their values. + + if (!strcasecmp(Name, "TVTVServer")) TVTVConfig.tvtv_server = atoi(Value); + else if (!strcasecmp(Name, "UserName")) strcpy(TVTVConfig.username, Value); + else if (!strcasecmp(Name, "Password")) strcpy(TVTVConfig.password, Value); + else if (!strcasecmp(Name, "UseProxy")) TVTVConfig.useproxy = atoi(Value); + else if (!strcasecmp(Name, "HTTPProxy")) strcpy(TVTVConfig.httpproxy, Value); + else if (!strcasecmp(Name, "AutoUpdate")) TVTVConfig.autoupdate = atoi(Value); + else if (!strcasecmp(Name, "UpdateTime")) TVTVConfig.updatetime = atoi(Value); + else if (!strcasecmp(Name, "UseGenreInFName")) TVTVConfig.usegenre = atoi(Value); + else if (!strcasecmp(Name, "UseStationInFName")) TVTVConfig.usestation = atoi(Value); + else if (!strcasecmp(Name, "ShowInMainMenu")) TVTVConfig.show_in_mainmenu = atoi(Value); +// VPS was introduced with VDR 1.3.5 +#if VDRVERSNUM >= 10305 + else if (!strcasecmp(Name, "UseVps")) TVTVConfig.usevps = atoi(Value); +#endif + +#if VDRVERSNUM >= 10344 + else if (!strcasecmp(Name, "UseTVTVDescr")) TVTVConfig.usetvtvdescr = atoi(Value); +#endif + + else if (!strcasecmp(Name, "TVTVBugfix")) TVTVConfig.tvtv_bugfix = atoi(Value); + else if (!strcasecmp(Name, "TVTVBugfixHrs")) TVTVConfig.tvtv_bugfix_hrs = atoi(Value); + + else + return false; + return true; +} + +VDRPLUGINCREATOR(cPluginTVTV); // Don't touch this! + diff --git a/update.c b/update.c new file mode 100644 index 0000000..3019bb6 --- /dev/null +++ b/update.c @@ -0,0 +1,703 @@ +/* + * update.c: TVTV plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include "update.h" + + +cUpdate::cUpdate() +{ + active = false; + data.memory = NULL; + data.size = 0; + chanmap = new cChannelMap(); +} + +cUpdate::~cUpdate() +{ + if (active) { + active = false; + Cancel(3); + } + + if (data.memory) { + free(data.memory); + data.memory = NULL; + data.size = 0; + } +} + +void cUpdate::StartUpdate() +{ + if (!active) + Start(); + else { + active = false; + Cancel(3); + usleep(250); + Start(); + } +} + +int cUpdate::ReloadChannelMap() { + return chanmap->ReloadChannelMap(); +} + +void cUpdate::Action(void) +{ + dsyslog("TVTV: Timer Thread started (pid=%d)", getpid()); + active = true; + do { + MakeTimerUpdate(); + if (TVTVConfig.autoupdate && TVTVConfig.updatetime > 0) + for (long i = 0; active && i < TVTVConfig.updatetime * 60 * 2; i++) + usleep(500000); + } + while (active && TVTVConfig.autoupdate && TVTVConfig.updatetime > 0); + + active = false; + dsyslog("TVTV: Timer Thread ended (pid=%d)", getpid()); + Cancel(0); +} + + +void cUpdate::Get_Packed_String(char *sOut) +{ + char *s; + unsigned char signature[17]; + + asprintf(&s, "EPGSync%s%s", TVTVConfig.username, TVTVConfig.password); + + MD5_CTX ctx; + MD5Init(&ctx); + MD5Update(&ctx, (unsigned char *)s, strlen(s)); + MD5Final(signature, &ctx); + signature[16] = 0; + + char aStr[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + char aOut[30]; + int j = 0; + + aOut[16] = '\0'; + + for (int i = 0; i < 16; i+= 3) { + uint8_t x, y; + + x = signature[i]; + x >>= 2; + x = x & 0x3f; + aOut[j++] = aStr[x]; + + y = signature[i]; + y = y & 0x3; + y <<= 4; + + x = signature[i + 1]; + x >>= 4; + x = x & 0x0f; + x = x ^ y; + aOut[j++] = aStr[x]; + + if (i + 1 < 16) { + y = signature[i + 1]; + y = y & 0x0f; + y <<= 2; + + // 3 + x = signature[i + 2]; + x = x & 0xff; + x >>= 6; + x = x ^ y; + aOut[j++] = aStr[x]; + + // 4 + x = signature[i + 2]; + x &= 0x3f; + aOut[j++] = aStr[x]; + } + else { + aOut[j++] = (char) 0x3d; + aOut[j++] = (char) 0x3d; + } + aOut[j] = '\0'; + } + + strcpy(sOut, aOut); + free(s); +} + + +static size_t WriteMemoryCallback( void *ptr, size_t size, size_t nmemb, void *data) { + size_t realsize = size * nmemb; + struct MemoryStruct *mem = (struct MemoryStruct *)data; + + if (mem->memory) + mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1); + else + mem->memory = (char *)malloc(mem->size + realsize + 1); + + if (mem->memory) { + memcpy(&(mem->memory[mem->size]), ptr, realsize); + mem->size += realsize; + mem->memory[mem->size] = 0; + } + return realsize; +} + + +int cUpdate::DownloadCSVData(const char *url) { + CURL *curl_handle; + + // Initialize 'data' struct + if (data.memory) free(data.memory); + data.memory = NULL; + data.size = 0; + + if (curl_global_init(CURL_GLOBAL_ALL) != 0) { + esyslog("TVTV: Something went wrong with curl_global_init()"); + return -1; + } + curl_handle = curl_easy_init(); + if (curl_handle == NULL) { + esyslog("TVTV: Unable to get handle from curl_easy_init()"); + return -1; + } + curl_easy_setopt(curl_handle, CURLOPT_URL, url); // Specify URL to get + + if (TVTVConfig.useproxy) { + curl_easy_setopt(curl_handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); + curl_easy_setopt(curl_handle, CURLOPT_PROXY, TVTVConfig.httpproxy); // Specify HTTP proxy + } + + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); // Send all data to this function + curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&data); // Pass our 'data' struct to the callback function + curl_easy_setopt(curl_handle, CURLOPT_MAXFILESIZE, 1048576); // Set maximum file size to get (bytes) + curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1); // No progress meter + curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1); // No signaling + curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 30); // Set timeout to 30 seconds + curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, TVTV_USERAGENT); // Some servers don't like requests that are made without a user-agent field + + if (curl_easy_perform(curl_handle) != 0) { + curl_easy_cleanup(curl_handle); // Cleanup curl stuff + if (data.memory) { + free(data.memory); + data.memory = NULL; + data.size = 0; + } + esyslog("TVTV: Couldn't download the stream"); + return -1; + } + + curl_easy_cleanup(curl_handle); // Cleanup curl stuff + return data.size; +} + + +uint8_t cUpdate::toHex(const uint8_t &x) +{ + return x > 9 ? x + 55: x + 48; +} + +void cUpdate::URLEncode(const char *sIn, char *sOut) +{ + register char *pOutTmp = NULL; + char *pOutBuf = NULL; + register char *pInTmp = NULL; + char *pInBuf = (char *)sIn; + + //alloc out buffer + pOutBuf = sOut; + + if(pOutBuf) { + pInTmp = pInBuf; + pOutTmp = pOutBuf; + + // do encoding + while (*pInTmp) { + if(isalnum(*pInTmp)) + *pOutTmp++ = *pInTmp; + else + if(isspace(*pInTmp)) + *pOutTmp++ = '+'; + else { + *pOutTmp++ = '%'; + *pOutTmp++ = toHex(*pInTmp>>4); + *pOutTmp++ = toHex(*pInTmp%16); + } + pInTmp++; + } + *pOutTmp = '\0'; + } +} + + +bool cUpdate::MakeTimerUpdate(void) +{ + char *sEnCryptS = NULL; + char *sPackedString = NULL; + char *url = NULL; + + sPackedString = (char *)calloc(30, sizeof (char)); + sEnCryptS = (char *)calloc(100, sizeof (char)); + + Get_Packed_String(sPackedString); + dsyslog("TVTV: Packed String: %s", sPackedString); + URLEncode(sPackedString, sEnCryptS); + + asprintf(&url, "http://%s/cgi-bin/WebObjects/TVSync.woa/wa/getjobs?&serial=0&account=%s&product=35&target=%s&doctype=csv&access=%s", + TVTV_SERVERS[TVTVConfig.tvtv_server], TVTVConfig.username, TVTV_SERVERS[TVTVConfig.tvtv_server], sEnCryptS); + + isyslog("TVTV: Timer Update started"); + + int iFileSize = DownloadCSVData(url); + + if (iFileSize > 0) { + dsyslog("TVTV: Received %d Bytes", iFileSize); + /* process CSV file */ + ProcessImportedFile(data.memory); + isyslog("TVTV: Timer File processed"); + } + else { + esyslog("TVTV: Download Error"); + } + + // Clean up + if (data.memory) { + free(data.memory); + data.memory = NULL; + data.size = 0; + } + if (url) free(url); + if (sEnCryptS) free(sEnCryptS); + if (sPackedString) free(sPackedString); + + return true; +} + + +int cUpdate::calc_field_cnt(string *s) { + int n=0; + size_t p = 0; + + if ((s == NULL) || (s->empty())) return 0; + + p = s->find(',', 0); + while (p != string::npos) { + n++; + p = s->find(',', p+1); + } + n++; + return n; +} + +char *cUpdate::strip_str(char *s) { + char *m=NULL; + unsigned int i=0; + + if (s==NULL) return NULL; + + m=(char *)calloc(strlen(s)+1, sizeof(char)); + + for (i=0; i<strlen(s); i++) { + if (s[i] == '"') { + if (s[i+1] == '"') { + strncat(m, s+i, 1); + i++; + } + } else if ((s[i] == '\\')&&(s[i+1] == 'n')) { + strncat(m, "\n", 1); + i++; + } else { + strncat(m, s+i, 1); + } + } + return m; +} + + +char **cUpdate::split_csv(const char *job_line, int field_cnt) { + + char **arr=NULL; + char *sp=NULL, *ep=NULL; + char *s=NULL; + int i=0; + int n=0; + int fini=0; + + if ((job_line == NULL)||(field_cnt == 0)) { return NULL; } + + arr=(char **)calloc(field_cnt, sizeof(char *)); + sp=(char *)job_line; + + while ((n < field_cnt)&&(fini == 0)) { + if (*sp == '"') { + sp++; + ep=index(sp, '"'); + if (ep != NULL) { + while ( *(ep+1) == '"' ) { ep=index(ep+2, '"'); } + ep++; + } else { + ep=(char *)job_line + strlen(job_line); + fini=1; + } + } else { + ep=index(sp, ','); + if (ep == NULL) { + ep=(char *)job_line + strlen(job_line); + fini=1; + } + } + s=(char *)calloc(ep-sp+1, sizeof(char)); + strncpy(s, sp, ep-sp); + arr[n]=strip_str(s); + free(s); + + sp=ep+1; + n++; + + if ((n < field_cnt)&&(fini==1)) { + for(i=0; i<n; i++) free(arr[i]); + free(arr); + arr=NULL; + } + + } + return arr; +} + + +string *cUpdate::read_line_from_buffer(const char *buf, unsigned int *idx) { + string s; + + if (buf == NULL) return NULL; + + while ((buf[*idx] != 0)&&(buf[*idx] != '\n')) { + if (!iscntrl(buf[*idx])) s.append(1, buf[*idx]); + (*idx)++; + } + while ( (buf[*idx] != 0) && (iscntrl(buf[*idx]) )) (*idx)++; + return new string(s); +} + +void cUpdate::ProcessImportedFile(const char *sBuffer) +{ + char **fields=NULL; + char **tvtvjob=NULL; + int field_cnt=0; + unsigned int p=0; + size_t rp=0; + bool vps = false; + tChannelID vdrch; + bool timer_update=false; +#if VDRVERSNUM < 10336 + unsigned int max_desc_len=0; +#endif + + time_t tStartTime, tVpsTime, tEndTime; + struct tm tStart, tVps, tEnd; + int StartTZ, VpsTZ, EndTZ; + + cTimer *oTimer = NULL; + cTimer *ti = NULL; + cChannel *oTVTVChannel = NULL; + + map<string, string> tvtv_timer; + string *sLine=NULL; + string s; + + const string sTokenTvtvUid = "TVTV-UID: "; + + dsyslog("TVTV: Processing CSV data"); + + // skip header + do { + sLine = read_line_from_buffer(sBuffer, &p); + field_cnt = calc_field_cnt(sLine); + } while (( field_cnt < 10 ) && ( !sLine->empty() )); + fields=split_csv(sLine->c_str(), field_cnt); + dsyslog("TVTV: Found %d fields in CSV data", field_cnt); + + // read timer jobs and create timers + dsyslog("TVTV: Start reading timer jobs"); + sLine = read_line_from_buffer(sBuffer, &p); + while (!sLine->empty()) { + dsyslog("TVTV: Received '%s...'", sLine->substr(0,80).c_str()); + tvtvjob=split_csv(sLine->c_str(), field_cnt); + if (tvtvjob != NULL) { + for (int i=0; i<field_cnt; i++) { + tvtv_timer[fields[i]] = tvtvjob[i]; + free(tvtvjob[i]); + } + free(tvtvjob); + } + + // replace newline characters by '|' + rp = tvtv_timer[DEF_TVTV_SCHEDULE_DESC].find('\n',0 ); + while (rp != string::npos) { tvtv_timer[DEF_TVTV_SCHEDULE_DESC].replace(rp, 1, 1, '|'); rp = tvtv_timer[DEF_TVTV_SCHEDULE_DESC].find('\n',0 ); } + rp = tvtv_timer[DEF_TVTV_SCHEDULE_PERS].find('\n',0 ); + while (rp != string::npos) { tvtv_timer[DEF_TVTV_SCHEDULE_PERS].replace(rp, 1, 1, '|'); rp = tvtv_timer[DEF_TVTV_SCHEDULE_PERS].find('\n',0 ); } + + // Get ChannelID from channel map + vdrch=chanmap->GetChanID(atoi(tvtv_timer[DEF_TVTV_SCHEDULE_CHID].c_str())); + if (!(vdrch == tChannelID::InvalidID)) { + +#if VDRVERSNUM >= 10305 + oTVTVChannel = Channels.GetByChannelID(vdrch, true, true); +#else + oTVTVChannel = Channels.GetByChannelID(vdrch, true); +#endif + if (oTVTVChannel) { + + oTimer = new cTimer; + + // Calc Start and Stop Time + sscanf(tvtv_timer[DEF_TVTV_SCHEDULE_STM].c_str(), "%04d-%02d-%02d %02d:%02d:%02d %d", + &tStart.tm_year, &tStart.tm_mon, &tStart.tm_mday, + &tStart.tm_hour, &tStart.tm_min, &tStart.tm_sec, &StartTZ); + + sscanf(tvtv_timer[DEF_TVTV_SCHEDULE_VTM].c_str(), "%04d-%02d-%02d %02d:%02d:%02d %d", + &tVps.tm_year, &tVps.tm_mon, &tVps.tm_mday, + &tVps.tm_hour, &tVps.tm_min, &tVps.tm_sec, &VpsTZ); + + sscanf(tvtv_timer[DEF_TVTV_SCHEDULE_ETM].c_str(), "%04d-%02d-%02d %02d:%02d:%02d %d", + &tEnd.tm_year, &tEnd.tm_mon, &tEnd.tm_mday, + &tEnd.tm_hour, &tEnd.tm_min, &tEnd.tm_sec, &EndTZ); + + tStart.tm_year -= 1900; tStart.tm_mon -= 1; tStart.tm_isdst = -1; + tVps.tm_year -= 1900; tVps.tm_mon -= 1; tVps.tm_isdst = -1; + tEnd.tm_year -= 1900; tEnd.tm_mon -= 1; tEnd.tm_isdst = -1; + + tStartTime = timegm(&tStart); + tVpsTime = timegm(&tVps); + tEndTime = timegm(&tEnd); + +// VPS was introduced with VDR 1.3.5 +#if VDRVERSNUM >= 10305 + vps = Setup.UseVps && (tVpsTime != -1) && TVTVConfig.usevps; +#else + vps = false; +#endif + + tStartTime -= StartTZ*36; + tEndTime -= EndTZ*36; + if (vps) tVpsTime -= VpsTZ*36; + + tStartTime -= Setup.MarginStart * 60; + if (!vps) tEndTime += Setup.MarginStop * 60; + localtime_r(&tStartTime, &tStart); + localtime_r(&tVpsTime, &tVps); + localtime_r(&tEndTime, &tEnd); + + // Adding Genre and Station Name to File Name to make it more unique + if (TVTVConfig.usegenre && ! tvtv_timer[DEF_TVTV_SCHEDULE_NAT].empty()) + s = tvtv_timer[DEF_TVTV_SCHEDULE_NAT] + "~"; + else + s = ""; + + if (TVTVConfig.usestation) +#if VDRVERSNUM >= 10315 + s = s + oTVTVChannel->ShortName(true) + "~"; +#else + s = s + oTVTVChannel->Name() + "~"; +#endif + s += tvtv_timer[DEF_TVTV_SCHEDULE_TIT]; + + + // Colons should be replaced by '|' in title + rp = s.find(':',0 ); + while (rp != string::npos) { s.replace(rp, 1, 1, '|'); rp = s.find(':',0 ); } + + // create timer string + ostringstream oss(ostringstream::out); + oss.fill('0'); +#if VDRVERSNUM >= 10305 + oss << (tfActive|(vps?tfVps:tfNone)) << ":"; +#else + oss << "1:"; +#endif + oss << oTVTVChannel->GetChannelID().ToString() << ":"; + +// Starting with VDR 1.3.23 timer entries support a full date in ISO notation. +#if VDRVERSNUM >= 10323 + oss.width(4); oss << ((vps?(tVps.tm_year):(tStart.tm_year))+1900) << "-"; + oss.width(2); oss << ((vps?(tVps.tm_mon):(tStart.tm_mon))+1) << "-"; +#endif + oss.width(2); oss << (vps?(tVps.tm_mday):(tStart.tm_mday)) << ":"; + oss.width(4); oss << (vps?(tVps.tm_hour * 100 + tVps.tm_min):(tStart.tm_hour * 100 + tStart.tm_min)) << ":"; + oss.width(4); oss << tEnd.tm_hour * 100 + tEnd.tm_min << ":"; + oss << Setup.DefaultPriority << ":"; + oss << Setup.DefaultLifetime << ":"; + oss << s.c_str() << ":"; + + dsyslog("TVTV: Timer entry '%s'", oss.str().c_str()); + s=oss.str(); + +// Starting with VDR 1.3.44 the description within info.vdr is taken +// just from EPG. A description coming with a timer is added as a comment +// to info.vdr. This setup parameter decides whether to add this description +// as a comment or not. +#if VDRVERSNUM >= 10344 + if (TVTVConfig.usetvtvdescr) { +#endif + +// Recording summary changed in VDR 1.3.25 +#if VDRVERSNUM < 10325 + s += tvtv_timer[DEF_TVTV_SCHEDULE_TIT]; + if ((tvtv_timer[DEF_TVTV_SCHEDULE_PERS].length() > 0)||(tvtv_timer[DEF_TVTV_SCHEDULE_DESC].length() > 0)) s += "||"; +#endif + + if (tvtv_timer[DEF_TVTV_SCHEDULE_PERS].length() > 0) { + s += "Darsteller: " + tvtv_timer[DEF_TVTV_SCHEDULE_PERS]; + if (tvtv_timer[DEF_TVTV_SCHEDULE_DESC].length() > 0) s += "||" + tvtv_timer[DEF_TVTV_SCHEDULE_DESC]; + } else { + if (tvtv_timer[DEF_TVTV_SCHEDULE_DESC].length() > 0) s += tvtv_timer[DEF_TVTV_SCHEDULE_DESC]; + } + +// Length of timer entry is limited to less than 10240 characters. Keeping off another +// 15 to avoid problems with additional characters (like newline). +// This is not needed for VDR 1.3.36+ anymore! +#if VDRVERSNUM < 10336 + max_desc_len = MAXPARSEBUFFER - sTokenTvtvUid.length() - tvtv_timer[DEF_TVTV_SCHEDULE_UID].length() - 15; + if (s.length() > max_desc_len) { + dsyslog("TVTV: received description too long, cutted (%d -> %d)", s.length(), max_desc_len); + s.erase(max_desc_len); + } +#endif + +#if VDRVERSNUM >= 10344 + } +#endif + // Add Timer's UID to description to identify it later on + if (tvtv_timer[DEF_TVTV_SCHEDULE_UID].length() > 0) s += "||" + sTokenTvtvUid + tvtv_timer[DEF_TVTV_SCHEDULE_UID]; + + + if (oTimer->Parse(s.c_str())) { + cTimer *t = Timers.GetTimer(oTimer); + if (t) { // Timer exists + if (tvtv_timer[DEF_TVTV_SCHEDULE_ACT] == "delete") { + if (t->Recording()) { + isyslog("TVTV: timer %d recording, will be deleted after recording has ended (%s)", t->Index() + 1, t->File()); + } else { + isyslog("TVTV: timer %d deleted [%s/%s/%d/%04d-%04d/%s]", oTimer->Index() + 1, + tvtv_timer[DEF_TVTV_SCHEDULE_UID].c_str(), + tvtv_timer[DEF_TVTV_SCHEDULE_CHN].c_str(), + vps ? (tVps.tm_mday):(tStart.tm_mday), + vps ? (tVps.tm_hour * 100 + tVps.tm_min):(tStart.tm_hour * 100 + tStart.tm_min), + tEnd.tm_hour * 100 + tEnd.tm_min, + vps ? "VPS":"-"); + Timers.Del(t); + } + } else { + isyslog("TVTV: timer %d exist (%s)", t->Index() + 1, t->File()); + } + delete oTimer; + } else { // if (t) + + // try to figure out if timer needs to be updated + timer_update=false; + ti = Timers.First(); + while (ti != NULL) { +#if VDRVERSNUM >= 10344 + if (ti->Aux() != NULL) { + s=ti->Aux(); +#else + if (ti->Summary() != NULL) { + s=ti->Summary(); +#endif + if (s.find(sTokenTvtvUid + tvtv_timer[DEF_TVTV_SCHEDULE_UID], 0) != string::npos) { + timer_update=true; + break; + } else { + ti = Timers.Next(ti); + } + } else { + ti = Timers.Next(ti); + } + } + + if (timer_update) { // Timer exists + if (tvtv_timer[DEF_TVTV_SCHEDULE_ACT] == "rec") { + // avoid Timer updates if Timer is shifted exactly 1 or 2 hours earlier (TVTV Problem) + if (TVTVConfig.tvtv_bugfix && ((((ti->StartTime() - tStartTime) == TVTVConfig.tvtv_bugfix_hrs*3600) && + ((ti->StopTime() - tEndTime) == TVTVConfig.tvtv_bugfix_hrs*3600)) || + (vps && ((ti->StopTime() - tEndTime) == TVTVConfig.tvtv_bugfix_hrs*3600)) )) { + isyslog("TVTV: timer %d update rejected (%s) [%s/%s/%d/%04d-%04d/%s]", ti->Index() + 1, + ti->File(), + tvtv_timer[DEF_TVTV_SCHEDULE_UID].c_str(), + tvtv_timer[DEF_TVTV_SCHEDULE_CHN].c_str(), + vps ? (tVps.tm_mday):(tStart.tm_mday), + vps ? (tVps.tm_hour * 100 + tVps.tm_min):(tStart.tm_hour * 100 + tStart.tm_min), + tEnd.tm_hour * 100 + tEnd.tm_min, + vps ? "VPS":"-" + ); + } else { + if (ti->Recording()) { + isyslog("TVTV: timer %d recording, will be deleted after recording has ended (%s)", ti->Index() + 1, ti->File()); + } else { + Timers.Del(ti); + } + Timers.Add(oTimer); + isyslog("TVTV: timer %d updated (%s) [%s/%s/%d/%04d-%04d/%s]", oTimer->Index() + 1, + oTimer->File(), + tvtv_timer[DEF_TVTV_SCHEDULE_UID].c_str(), + tvtv_timer[DEF_TVTV_SCHEDULE_CHN].c_str(), + vps ? (tVps.tm_mday):(tStart.tm_mday), + vps ? (tVps.tm_hour * 100 + tVps.tm_min):(tStart.tm_hour * 100 + tStart.tm_min), + tEnd.tm_hour * 100 + tEnd.tm_min, + vps ? "VPS":"-" + ); + } + } else if (tvtv_timer[DEF_TVTV_SCHEDULE_ACT] == "delete") { + if (ti->Recording()) { + isyslog("TVTV: timer %d recording, will be deleted after recording has ended (%s)", ti->Index() + 1, ti->File()); + } else { + isyslog("TVTV: timer %d deleted [%s/%s/%d/%04d-%04d/%s]", oTimer->Index() + 1, + tvtv_timer[DEF_TVTV_SCHEDULE_UID].c_str(), + tvtv_timer[DEF_TVTV_SCHEDULE_CHN].c_str(), + vps ? (tVps.tm_mday):(tStart.tm_mday), + vps ? (tVps.tm_hour * 100 + tVps.tm_min):(tStart.tm_hour * 100 + tStart.tm_min), + tEnd.tm_hour * 100 + tEnd.tm_min, + vps ? "VPS":"-"); + Timers.Del(ti); + } + } + } else { // if (timer_update) + if (tvtv_timer[DEF_TVTV_SCHEDULE_ACT] == "rec") { + Timers.Add(oTimer); + isyslog("TVTV: timer %d added (%s) [%s/%s/%d/%04d-%04d/%s]", oTimer->Index() + 1, + oTimer->File(), + tvtv_timer[DEF_TVTV_SCHEDULE_UID].c_str(), + tvtv_timer[DEF_TVTV_SCHEDULE_CHN].c_str(), + vps ? (tVps.tm_mday):(tStart.tm_mday), + vps ? (tVps.tm_hour * 100 + tVps.tm_min):(tStart.tm_hour * 100 + tStart.tm_min), + tEnd.tm_hour * 100 + tEnd.tm_min, + vps ? "VPS":"-"); + } + } + + } + } else { + isyslog("TVTV: Timer Error: %s", s.c_str()); + } + + } else { // if (oTVTVChannel) + isyslog("TVTV: ChannelID <%s> for Channel <%s> was not found in channels.conf!", (const char *)vdrch.ToString(), tvtv_timer[DEF_TVTV_SCHEDULE_CHN].c_str()); + } + + } else { // if (!(vdrch == tChannelID::InvalidID)) + isyslog("TVTV: Channel <%s (ID: %d)> is not found!", tvtv_timer[DEF_TVTV_SCHEDULE_CHN].c_str(), atoi(tvtv_timer[DEF_TVTV_SCHEDULE_CHID].c_str())); + } + + // read next line + sLine = read_line_from_buffer(sBuffer, &p); + tvtv_timer.clear(); + + } // while (!sLine->empty()) + + Timers.Save(); +} + diff --git a/update.h b/update.h new file mode 100644 index 0000000..561fb9e --- /dev/null +++ b/update.h @@ -0,0 +1,82 @@ +/* + * update.h: TVTV plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#ifndef __UPDATE_H +#define __UPDATE_H + +#include <curl/curl.h> +#include <curl/types.h> +#include <curl/easy.h> + +#include <string> +#include <iostream> +#include <fstream> +#include <sstream> + +#include "i18n.h" +#include "config.h" +#include "channelmap.h" +#include "md5tools.h" + +using namespace std; + + +#define TVTV_USERAGENT "libcurl-agent/1.0" + +#define DEF_TVTV_SCHEDULE_UID "uid" +#define DEF_TVTV_SCHEDULE_CHN "channel" +#define DEF_TVTV_SCHEDULE_CHID "channelid" +#define DEF_TVTV_SCHEDULE_STM "starttime" +#define DEF_TVTV_SCHEDULE_VTM "vps" +#define DEF_TVTV_SCHEDULE_ETM "endtime" +#define DEF_TVTV_SCHEDULE_TIT "title" +#define DEF_TVTV_SCHEDULE_NAT "nature" +#define DEF_TVTV_SCHEDULE_DESC "description" +#define DEF_TVTV_SCHEDULE_PERS "persons" +#define DEF_TVTV_SCHEDULE_FRM "format" +#define DEF_TVTV_SCHEDULE_FSK "pg" +#define DEF_TVTV_SCHEDULE_ACT "action" + + +#define TVTVSRV_CNT 8 +static const char *TVTV_SERVERS[TVTVSRV_CNT] = {"www.tvtv.de", "www.tvtv.at", "www.tvtv.co.uk", "www.tvtv.fr", + "www.tvtv.it", "www.tvtv.ch", "www.tvtv.es", "www.tvtv.nl"}; + + +struct MemoryStruct { + char *memory; + size_t size; +}; + + +class cUpdate : public cThread { +private: + bool active; + struct MemoryStruct data; + cChannelMap *chanmap; + + uint8_t toHex(const uint8_t &x); + void URLEncode(const char *sIn, char *sOut); + void Get_Packed_String(char *sOut); + + void Action(void); + int DownloadCSVData(const char *url); + bool MakeTimerUpdate(void); + void ProcessImportedFile(const char *sBuffer); + + int calc_field_cnt(string *s); + char *strip_str(char *s); + char **split_csv(const char *job_line, int field_cnt); + string *read_line_from_buffer(const char *buf, unsigned int *idx); +public: + cUpdate(); + ~cUpdate(); + void StartUpdate(); + int ReloadChannelMap(); +}; + +#endif //__UPDATE_H |