mirror of
				https://projects.vdr-developer.org/git/vdr-plugin-scraper2vdr.git
				synced 2023-10-19 15:58:31 +00:00 
			
		
		
		
	initial commit
This commit is contained in:
		
							
								
								
									
										340
									
								
								COPYING
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										340
									
								
								COPYING
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,340 @@
 | 
			
		||||
		    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
		       Version 2, June 1991
 | 
			
		||||
 | 
			
		||||
 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
 | 
			
		||||
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
 Everyone is permitted to copy and distribute verbatim copies
 | 
			
		||||
 of this license document, but changing it is not allowed.
 | 
			
		||||
 | 
			
		||||
			    Preamble
 | 
			
		||||
 | 
			
		||||
  The licenses for most software are designed to take away your
 | 
			
		||||
freedom to share and change it.  By contrast, the GNU General Public
 | 
			
		||||
License is intended to guarantee your freedom to share and change free
 | 
			
		||||
software--to make sure the software is free for all its users.  This
 | 
			
		||||
General Public License applies to most of the Free Software
 | 
			
		||||
Foundation's software and to any other program whose authors commit to
 | 
			
		||||
using it.  (Some other Free Software Foundation software is covered by
 | 
			
		||||
the GNU Lesser General Public License instead.)  You can apply it to
 | 
			
		||||
your programs, too.
 | 
			
		||||
 | 
			
		||||
  When we speak of free software, we are referring to freedom, not
 | 
			
		||||
price.  Our General Public Licenses are designed to make sure that you
 | 
			
		||||
have the freedom to distribute copies of free software (and charge for
 | 
			
		||||
this service if you wish), that you receive source code or can get it
 | 
			
		||||
if you want it, that you can change the software or use pieces of it
 | 
			
		||||
in new free programs; and that you know you can do these things.
 | 
			
		||||
 | 
			
		||||
  To protect your rights, we need to make restrictions that forbid
 | 
			
		||||
anyone to deny you these rights or to ask you to surrender the rights.
 | 
			
		||||
These restrictions translate to certain responsibilities for you if you
 | 
			
		||||
distribute copies of the software, or if you modify it.
 | 
			
		||||
 | 
			
		||||
  For example, if you distribute copies of such a program, whether
 | 
			
		||||
gratis or for a fee, you must give the recipients all the rights that
 | 
			
		||||
you have.  You must make sure that they, too, receive or can get the
 | 
			
		||||
source code.  And you must show them these terms so they know their
 | 
			
		||||
rights.
 | 
			
		||||
 | 
			
		||||
  We protect your rights with two steps: (1) copyright the software, and
 | 
			
		||||
(2) offer you this license which gives you legal permission to copy,
 | 
			
		||||
distribute and/or modify the software.
 | 
			
		||||
 | 
			
		||||
  Also, for each author's protection and ours, we want to make certain
 | 
			
		||||
that everyone understands that there is no warranty for this free
 | 
			
		||||
software.  If the software is modified by someone else and passed on, we
 | 
			
		||||
want its recipients to know that what they have is not the original, so
 | 
			
		||||
that any problems introduced by others will not reflect on the original
 | 
			
		||||
authors' reputations.
 | 
			
		||||
 | 
			
		||||
  Finally, any free program is threatened constantly by software
 | 
			
		||||
patents.  We wish to avoid the danger that redistributors of a free
 | 
			
		||||
program will individually obtain patent licenses, in effect making the
 | 
			
		||||
program proprietary.  To prevent this, we have made it clear that any
 | 
			
		||||
patent must be licensed for everyone's free use or not licensed at all.
 | 
			
		||||
 | 
			
		||||
  The precise terms and conditions for copying, distribution and
 | 
			
		||||
modification follow.
 | 
			
		||||
 | 
			
		||||
		    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
			
		||||
 | 
			
		||||
  0. This License applies to any program or other work which contains
 | 
			
		||||
a notice placed by the copyright holder saying it may be distributed
 | 
			
		||||
under the terms of this General Public License.  The "Program", below,
 | 
			
		||||
refers to any such program or work, and a "work based on the Program"
 | 
			
		||||
means either the Program or any derivative work under copyright law:
 | 
			
		||||
that is to say, a work containing the Program or a portion of it,
 | 
			
		||||
either verbatim or with modifications and/or translated into another
 | 
			
		||||
language.  (Hereinafter, translation is included without limitation in
 | 
			
		||||
the term "modification".)  Each licensee is addressed as "you".
 | 
			
		||||
 | 
			
		||||
Activities other than copying, distribution and modification are not
 | 
			
		||||
covered by this License; they are outside its scope.  The act of
 | 
			
		||||
running the Program is not restricted, and the output from the Program
 | 
			
		||||
is covered only if its contents constitute a work based on the
 | 
			
		||||
Program (independent of having been made by running the Program).
 | 
			
		||||
Whether that is true depends on what the Program does.
 | 
			
		||||
 | 
			
		||||
  1. You may copy and distribute verbatim copies of the Program's
 | 
			
		||||
source code as you receive it, in any medium, provided that you
 | 
			
		||||
conspicuously and appropriately publish on each copy an appropriate
 | 
			
		||||
copyright notice and disclaimer of warranty; keep intact all the
 | 
			
		||||
notices that refer to this License and to the absence of any warranty;
 | 
			
		||||
and give any other recipients of the Program a copy of this License
 | 
			
		||||
along with the Program.
 | 
			
		||||
 | 
			
		||||
You may charge a fee for the physical act of transferring a copy, and
 | 
			
		||||
you may at your option offer warranty protection in exchange for a fee.
 | 
			
		||||
 | 
			
		||||
  2. You may modify your copy or copies of the Program or any portion
 | 
			
		||||
of it, thus forming a work based on the Program, and copy and
 | 
			
		||||
distribute such modifications or work under the terms of Section 1
 | 
			
		||||
above, provided that you also meet all of these conditions:
 | 
			
		||||
 | 
			
		||||
    a) You must cause the modified files to carry prominent notices
 | 
			
		||||
    stating that you changed the files and the date of any change.
 | 
			
		||||
 | 
			
		||||
    b) You must cause any work that you distribute or publish, that in
 | 
			
		||||
    whole or in part contains or is derived from the Program or any
 | 
			
		||||
    part thereof, to be licensed as a whole at no charge to all third
 | 
			
		||||
    parties under the terms of this License.
 | 
			
		||||
 | 
			
		||||
    c) If the modified program normally reads commands interactively
 | 
			
		||||
    when run, you must cause it, when started running for such
 | 
			
		||||
    interactive use in the most ordinary way, to print or display an
 | 
			
		||||
    announcement including an appropriate copyright notice and a
 | 
			
		||||
    notice that there is no warranty (or else, saying that you provide
 | 
			
		||||
    a warranty) and that users may redistribute the program under
 | 
			
		||||
    these conditions, and telling the user how to view a copy of this
 | 
			
		||||
    License.  (Exception: if the Program itself is interactive but
 | 
			
		||||
    does not normally print such an announcement, your work based on
 | 
			
		||||
    the Program is not required to print an announcement.)
 | 
			
		||||
 | 
			
		||||
These requirements apply to the modified work as a whole.  If
 | 
			
		||||
identifiable sections of that work are not derived from the Program,
 | 
			
		||||
and can be reasonably considered independent and separate works in
 | 
			
		||||
themselves, then this License, and its terms, do not apply to those
 | 
			
		||||
sections when you distribute them as separate works.  But when you
 | 
			
		||||
distribute the same sections as part of a whole which is a work based
 | 
			
		||||
on the Program, the distribution of the whole must be on the terms of
 | 
			
		||||
this License, whose permissions for other licensees extend to the
 | 
			
		||||
entire whole, and thus to each and every part regardless of who wrote it.
 | 
			
		||||
 | 
			
		||||
Thus, it is not the intent of this section to claim rights or contest
 | 
			
		||||
your rights to work written entirely by you; rather, the intent is to
 | 
			
		||||
exercise the right to control the distribution of derivative or
 | 
			
		||||
collective works based on the Program.
 | 
			
		||||
 | 
			
		||||
In addition, mere aggregation of another work not based on the Program
 | 
			
		||||
with the Program (or with a work based on the Program) on a volume of
 | 
			
		||||
a storage or distribution medium does not bring the other work under
 | 
			
		||||
the scope of this License.
 | 
			
		||||
 | 
			
		||||
  3. You may copy and distribute the Program (or a work based on it,
 | 
			
		||||
under Section 2) in object code or executable form under the terms of
 | 
			
		||||
Sections 1 and 2 above provided that you also do one of the following:
 | 
			
		||||
 | 
			
		||||
    a) Accompany it with the complete corresponding machine-readable
 | 
			
		||||
    source code, which must be distributed under the terms of Sections
 | 
			
		||||
    1 and 2 above on a medium customarily used for software interchange; or,
 | 
			
		||||
 | 
			
		||||
    b) Accompany it with a written offer, valid for at least three
 | 
			
		||||
    years, to give any third party, for a charge no more than your
 | 
			
		||||
    cost of physically performing source distribution, a complete
 | 
			
		||||
    machine-readable copy of the corresponding source code, to be
 | 
			
		||||
    distributed under the terms of Sections 1 and 2 above on a medium
 | 
			
		||||
    customarily used for software interchange; or,
 | 
			
		||||
 | 
			
		||||
    c) Accompany it with the information you received as to the offer
 | 
			
		||||
    to distribute corresponding source code.  (This alternative is
 | 
			
		||||
    allowed only for noncommercial distribution and only if you
 | 
			
		||||
    received the program in object code or executable form with such
 | 
			
		||||
    an offer, in accord with Subsection b above.)
 | 
			
		||||
 | 
			
		||||
The source code for a work means the preferred form of the work for
 | 
			
		||||
making modifications to it.  For an executable work, complete source
 | 
			
		||||
code means all the source code for all modules it contains, plus any
 | 
			
		||||
associated interface definition files, plus the scripts used to
 | 
			
		||||
control compilation and installation of the executable.  However, as a
 | 
			
		||||
special exception, the source code distributed need not include
 | 
			
		||||
anything that is normally distributed (in either source or binary
 | 
			
		||||
form) with the major components (compiler, kernel, and so on) of the
 | 
			
		||||
operating system on which the executable runs, unless that component
 | 
			
		||||
itself accompanies the executable.
 | 
			
		||||
 | 
			
		||||
If distribution of executable or object code is made by offering
 | 
			
		||||
access to copy from a designated place, then offering equivalent
 | 
			
		||||
access to copy the source code from the same place counts as
 | 
			
		||||
distribution of the source code, even though third parties are not
 | 
			
		||||
compelled to copy the source along with the object code.
 | 
			
		||||
 | 
			
		||||
  4. You may not copy, modify, sublicense, or distribute the Program
 | 
			
		||||
except as expressly provided under this License.  Any attempt
 | 
			
		||||
otherwise to copy, modify, sublicense or distribute the Program is
 | 
			
		||||
void, and will automatically terminate your rights under this License.
 | 
			
		||||
However, parties who have received copies, or rights, from you under
 | 
			
		||||
this License will not have their licenses terminated so long as such
 | 
			
		||||
parties remain in full compliance.
 | 
			
		||||
 | 
			
		||||
  5. You are not required to accept this License, since you have not
 | 
			
		||||
signed it.  However, nothing else grants you permission to modify or
 | 
			
		||||
distribute the Program or its derivative works.  These actions are
 | 
			
		||||
prohibited by law if you do not accept this License.  Therefore, by
 | 
			
		||||
modifying or distributing the Program (or any work based on the
 | 
			
		||||
Program), you indicate your acceptance of this License to do so, and
 | 
			
		||||
all its terms and conditions for copying, distributing or modifying
 | 
			
		||||
the Program or works based on it.
 | 
			
		||||
 | 
			
		||||
  6. Each time you redistribute the Program (or any work based on the
 | 
			
		||||
Program), the recipient automatically receives a license from the
 | 
			
		||||
original licensor to copy, distribute or modify the Program subject to
 | 
			
		||||
these terms and conditions.  You may not impose any further
 | 
			
		||||
restrictions on the recipients' exercise of the rights granted herein.
 | 
			
		||||
You are not responsible for enforcing compliance by third parties to
 | 
			
		||||
this License.
 | 
			
		||||
 | 
			
		||||
  7. If, as a consequence of a court judgment or allegation of patent
 | 
			
		||||
infringement or for any other reason (not limited to patent issues),
 | 
			
		||||
conditions are imposed on you (whether by court order, agreement or
 | 
			
		||||
otherwise) that contradict the conditions of this License, they do not
 | 
			
		||||
excuse you from the conditions of this License.  If you cannot
 | 
			
		||||
distribute so as to satisfy simultaneously your obligations under this
 | 
			
		||||
License and any other pertinent obligations, then as a consequence you
 | 
			
		||||
may not distribute the Program at all.  For example, if a patent
 | 
			
		||||
license would not permit royalty-free redistribution of the Program by
 | 
			
		||||
all those who receive copies directly or indirectly through you, then
 | 
			
		||||
the only way you could satisfy both it and this License would be to
 | 
			
		||||
refrain entirely from distribution of the Program.
 | 
			
		||||
 | 
			
		||||
If any portion of this section is held invalid or unenforceable under
 | 
			
		||||
any particular circumstance, the balance of the section is intended to
 | 
			
		||||
apply and the section as a whole is intended to apply in other
 | 
			
		||||
circumstances.
 | 
			
		||||
 | 
			
		||||
It is not the purpose of this section to induce you to infringe any
 | 
			
		||||
patents or other property right claims or to contest validity of any
 | 
			
		||||
such claims; this section has the sole purpose of protecting the
 | 
			
		||||
integrity of the free software distribution system, which is
 | 
			
		||||
implemented by public license practices.  Many people have made
 | 
			
		||||
generous contributions to the wide range of software distributed
 | 
			
		||||
through that system in reliance on consistent application of that
 | 
			
		||||
system; it is up to the author/donor to decide if he or she is willing
 | 
			
		||||
to distribute software through any other system and a licensee cannot
 | 
			
		||||
impose that choice.
 | 
			
		||||
 | 
			
		||||
This section is intended to make thoroughly clear what is believed to
 | 
			
		||||
be a consequence of the rest of this License.
 | 
			
		||||
 | 
			
		||||
  8. If the distribution and/or use of the Program is restricted in
 | 
			
		||||
certain countries either by patents or by copyrighted interfaces, the
 | 
			
		||||
original copyright holder who places the Program under this License
 | 
			
		||||
may add an explicit geographical distribution limitation excluding
 | 
			
		||||
those countries, so that distribution is permitted only in or among
 | 
			
		||||
countries not thus excluded.  In such case, this License incorporates
 | 
			
		||||
the limitation as if written in the body of this License.
 | 
			
		||||
 | 
			
		||||
  9. The Free Software Foundation may publish revised and/or new versions
 | 
			
		||||
of the General Public License from time to time.  Such new versions will
 | 
			
		||||
be similar in spirit to the present version, but may differ in detail to
 | 
			
		||||
address new problems or concerns.
 | 
			
		||||
 | 
			
		||||
Each version is given a distinguishing version number.  If the Program
 | 
			
		||||
specifies a version number of this License which applies to it and "any
 | 
			
		||||
later version", you have the option of following the terms and conditions
 | 
			
		||||
either of that version or of any later version published by the Free
 | 
			
		||||
Software Foundation.  If the Program does not specify a version number of
 | 
			
		||||
this License, you may choose any version ever published by the Free Software
 | 
			
		||||
Foundation.
 | 
			
		||||
 | 
			
		||||
  10. If you wish to incorporate parts of the Program into other free
 | 
			
		||||
programs whose distribution conditions are different, write to the author
 | 
			
		||||
to ask for permission.  For software which is copyrighted by the Free
 | 
			
		||||
Software Foundation, write to the Free Software Foundation; we sometimes
 | 
			
		||||
make exceptions for this.  Our decision will be guided by the two goals
 | 
			
		||||
of preserving the free status of all derivatives of our free software and
 | 
			
		||||
of promoting the sharing and reuse of software generally.
 | 
			
		||||
 | 
			
		||||
			    NO WARRANTY
 | 
			
		||||
 | 
			
		||||
  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 | 
			
		||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
 | 
			
		||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
 | 
			
		||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
 | 
			
		||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
 | 
			
		||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
 | 
			
		||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
 | 
			
		||||
REPAIR OR CORRECTION.
 | 
			
		||||
 | 
			
		||||
  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
 | 
			
		||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
 | 
			
		||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
 | 
			
		||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
 | 
			
		||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
 | 
			
		||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
 | 
			
		||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
 | 
			
		||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 | 
			
		||||
POSSIBILITY OF SUCH DAMAGES.
 | 
			
		||||
 | 
			
		||||
		     END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
	    How to Apply These Terms to Your New Programs
 | 
			
		||||
 | 
			
		||||
  If you develop a new program, and you want it to be of the greatest
 | 
			
		||||
possible use to the public, the best way to achieve this is to make it
 | 
			
		||||
free software which everyone can redistribute and change under these terms.
 | 
			
		||||
 | 
			
		||||
  To do so, attach the following notices to the program.  It is safest
 | 
			
		||||
to attach them to the start of each source file to most effectively
 | 
			
		||||
convey the exclusion of warranty; and each file should have at least
 | 
			
		||||
the "copyright" line and a pointer to where the full notice is found.
 | 
			
		||||
 | 
			
		||||
    <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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Also add information on how to contact you by electronic and paper mail.
 | 
			
		||||
 | 
			
		||||
If the program is interactive, make it output a short notice like this
 | 
			
		||||
when it starts in an interactive mode:
 | 
			
		||||
 | 
			
		||||
    Gnomovision version 69, Copyright (C) year name of author
 | 
			
		||||
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
 | 
			
		||||
    This is free software, and you are welcome to redistribute it
 | 
			
		||||
    under certain conditions; type `show c' for details.
 | 
			
		||||
 | 
			
		||||
The hypothetical commands `show w' and `show c' should show the appropriate
 | 
			
		||||
parts of the General Public License.  Of course, the commands you use may
 | 
			
		||||
be called something other than `show w' and `show c'; they could even be
 | 
			
		||||
mouse-clicks or menu items--whatever suits your program.
 | 
			
		||||
 | 
			
		||||
You should also get your employer (if you work as a programmer) or your
 | 
			
		||||
school, if any, to sign a "copyright disclaimer" for the program, if
 | 
			
		||||
necessary.  Here is a sample; alter the names:
 | 
			
		||||
 | 
			
		||||
  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
 | 
			
		||||
  `Gnomovision' (which makes passes at compilers) written by James Hacker.
 | 
			
		||||
 | 
			
		||||
  <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 Lesser General
 | 
			
		||||
Public License instead of this License.
 | 
			
		||||
							
								
								
									
										6
									
								
								HISTORY
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								HISTORY
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
VDR Plugin 'scraper2vdr' Revision History
 | 
			
		||||
-----------------------------------------
 | 
			
		||||
 | 
			
		||||
2014-03-02: Version 0.0.1
 | 
			
		||||
 | 
			
		||||
- Initial revision.
 | 
			
		||||
							
								
								
									
										132
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
#
 | 
			
		||||
# Makefile for a Video Disk Recorder plugin
 | 
			
		||||
#
 | 
			
		||||
# $Id$
 | 
			
		||||
 | 
			
		||||
# External image lib to use: imagemagick, graphicsmagick
 | 
			
		||||
IMAGELIB = imagemagick
 | 
			
		||||
 | 
			
		||||
PLUGIN = scraper2vdr
 | 
			
		||||
 | 
			
		||||
### The version number of this plugin (taken from the main source file):
 | 
			
		||||
 | 
			
		||||
VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).h | awk '{ print $$6 }' | sed -e 's/[";]//g')
 | 
			
		||||
 | 
			
		||||
### The directory environment:
 | 
			
		||||
 | 
			
		||||
# Use package data if installed...otherwise assume we're under the VDR source directory:
 | 
			
		||||
PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc))
 | 
			
		||||
LIBDIR = $(call PKGCFG,libdir)
 | 
			
		||||
LOCDIR = $(call PKGCFG,locdir)
 | 
			
		||||
PLGCFG = $(call PKGCFG,plgcfg)
 | 
			
		||||
#
 | 
			
		||||
TMPDIR ?= /tmp
 | 
			
		||||
 | 
			
		||||
### The compiler options:
 | 
			
		||||
 | 
			
		||||
export CFLAGS   = $(call PKGCFG,cflags)
 | 
			
		||||
export CXXFLAGS = $(call PKGCFG,cxxflags)
 | 
			
		||||
 | 
			
		||||
### The version number of VDR's plugin API:
 | 
			
		||||
 | 
			
		||||
APIVERSION = $(call PKGCFG,apiversion)
 | 
			
		||||
 | 
			
		||||
### Allow user defined options to overwrite defaults:
 | 
			
		||||
 | 
			
		||||
-include $(PLGCFG)
 | 
			
		||||
 | 
			
		||||
LIBS = -lmysqlclient_r -luuid
 | 
			
		||||
 | 
			
		||||
### The name of the distribution archive:
 | 
			
		||||
 | 
			
		||||
ARCHIVE = $(PLUGIN)-$(VERSION)
 | 
			
		||||
PACKAGE = vdr-$(ARCHIVE)
 | 
			
		||||
 | 
			
		||||
### The name of the shared object file:
 | 
			
		||||
 | 
			
		||||
SOFILE = libvdr-$(PLUGIN).so
 | 
			
		||||
 | 
			
		||||
### Includes and Defines (add further entries here):
 | 
			
		||||
 | 
			
		||||
INCLUDES +=
 | 
			
		||||
 | 
			
		||||
DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
 | 
			
		||||
DEFINES += -DVDR_PLUGIN -DUSEUUID
 | 
			
		||||
 | 
			
		||||
ifeq ($(IMAGELIB), imagemagick)
 | 
			
		||||
	INCLUDES += $(shell pkg-config --cflags Magick++)
 | 
			
		||||
	LIBS += $(shell pkg-config --libs Magick++)
 | 
			
		||||
else ifeq ($(IMAGELIB), graphicsmagick)
 | 
			
		||||
	INCLUDES += $(shell pkg-config --cflags GraphicsMagick++)
 | 
			
		||||
	LIBS += $(shell pkg-config --libs GraphicsMagick++)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
### The object files (add further files here):
 | 
			
		||||
 | 
			
		||||
OBJS = $(PLUGIN).o config.o setup.o update.o scrapmanager.o tvdbseries.o moviedbmovie.o tools.o lib/db.o lib/tabledef.o lib/common.o lib/config.o
 | 
			
		||||
 | 
			
		||||
### The main target:
 | 
			
		||||
 | 
			
		||||
all: $(SOFILE) i18n
 | 
			
		||||
 | 
			
		||||
### Implicit rules:
 | 
			
		||||
 | 
			
		||||
%.o: %.c
 | 
			
		||||
	$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
 | 
			
		||||
 | 
			
		||||
### Dependencies:
 | 
			
		||||
 | 
			
		||||
MAKEDEP = $(CXX) -MM -MG
 | 
			
		||||
DEPFILE = .dependencies
 | 
			
		||||
$(DEPFILE): Makefile
 | 
			
		||||
	@$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
 | 
			
		||||
 | 
			
		||||
-include $(DEPFILE)
 | 
			
		||||
 | 
			
		||||
### Internationalization (I18N):
 | 
			
		||||
 | 
			
		||||
PODIR     = po
 | 
			
		||||
I18Npo    = $(wildcard $(PODIR)/*.po)
 | 
			
		||||
I18Nmo    = $(addsuffix .mo, $(foreach file, $(I18Npo), $(basename $(file))))
 | 
			
		||||
I18Nmsgs  = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file))))))
 | 
			
		||||
I18Npot   = $(PODIR)/$(PLUGIN).pot
 | 
			
		||||
 | 
			
		||||
%.mo: %.po
 | 
			
		||||
	msgfmt -c -o $@ $<
 | 
			
		||||
 | 
			
		||||
$(I18Npot): $(wildcard *.c)
 | 
			
		||||
	xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
 | 
			
		||||
 | 
			
		||||
%.po: $(I18Npot)
 | 
			
		||||
	msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
 | 
			
		||||
	@touch $@
 | 
			
		||||
 | 
			
		||||
$(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
 | 
			
		||||
	install -D -m644 $< $@
 | 
			
		||||
 | 
			
		||||
.PHONY: i18n
 | 
			
		||||
i18n: $(I18Nmo) $(I18Npot)
 | 
			
		||||
 | 
			
		||||
install-i18n: $(I18Nmsgs)
 | 
			
		||||
 | 
			
		||||
### Targets:
 | 
			
		||||
 | 
			
		||||
$(SOFILE): $(OBJS)
 | 
			
		||||
	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@
 | 
			
		||||
 | 
			
		||||
install-lib: $(SOFILE)
 | 
			
		||||
	install -D -m644 $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
 | 
			
		||||
 | 
			
		||||
install: install-lib install-i18n
 | 
			
		||||
 | 
			
		||||
dist: $(I18Npo) 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 $(PODIR)/*.mo $(PODIR)/*.pot
 | 
			
		||||
	@-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~
 | 
			
		||||
							
								
								
									
										79
									
								
								README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								README
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
This is a "plugin" for the Video Disk Recorder (VDR).
 | 
			
		||||
 | 
			
		||||
Written by:                  Louis Braun <louis.braun@gmx.de>
 | 
			
		||||
 | 
			
		||||
Project's homepage:          http://projects.vdr-developer.org/projects/plg-scraper2vdr
 | 
			
		||||
 | 
			
		||||
Latest version available at: http://projects.vdr-developer.org/git/vdr-plugin-scraper2vdr.git/
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
See the file COPYING for more information.
 | 
			
		||||
 | 
			
		||||
Description 
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
scraper2vdr acts as client and provides scraped metadata for tvshows and
 | 
			
		||||
movies from epgd to other plugins via its service interface. The plugin 
 | 
			
		||||
cares about caching the images locally and also cleans up the images if
 | 
			
		||||
not longer needed. 
 | 
			
		||||
 | 
			
		||||
epgd itself uses the thetvdb.com API for collecting series metadata and
 | 
			
		||||
themoviedb.org API for movies. Check the websites of both services for
 | 
			
		||||
the terms of use.
 | 
			
		||||
 | 
			
		||||
Requirements
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
To run the plugin the following libaries have to be installed:
 | 
			
		||||
 
 | 
			
		||||
 - VDR 1.7.x     
 | 
			
		||||
 - libmysql >= 5.07
 | 
			
		||||
 - uuid-dev
 | 
			
		||||
 - imagemagick or graphicksmagick
 | 
			
		||||
 | 
			
		||||
Installation and configuration
 | 
			
		||||
------------------------------
 | 
			
		||||
 | 
			
		||||
Just install the plugin depending on your used distribution. During VDR
 | 
			
		||||
startup the following options can be set:
 | 
			
		||||
 | 
			
		||||
-i <IMAGEDIR>, --imagedir=<IMAGEDIR>  Set directory where images are stored
 | 
			
		||||
-m <MODE>, --mode=<MODE>   mode can be client or headless. 
 | 
			
		||||
 | 
			
		||||
Each running scraper2vdr Plugin reports his recordings to the epgd 
 | 
			
		||||
database, the epgd then checks these entries and tries to find
 | 
			
		||||
appropriate scraping information. epgd performs first a lookup for a
 | 
			
		||||
event in the database which belongs to the recording. If this fails, epgd
 | 
			
		||||
checks if another client has already reported this recording to the database.
 | 
			
		||||
After that, the scrapinfo file in the recording directory (if existing)
 | 
			
		||||
is checked. If nothing is successfull, a new scrap process for the name
 | 
			
		||||
of the recording is done. If in this case the length of the recording
 | 
			
		||||
is less than 70 minutes, a series recording is assumed, otherwise
 | 
			
		||||
the scraper searches for a movie.  
 | 
			
		||||
 | 
			
		||||
In client mode both live epg and recordings metadata is loaded from the 
 | 
			
		||||
database. In headless mode only recording metadata is loaded. This mode
 | 
			
		||||
is useful for headless VDRs so that recordings which are done from this
 | 
			
		||||
VDR during no other VDR client with running scraper2vdr Plugin is active
 | 
			
		||||
are not missed. The recording information is then written to the database 
 | 
			
		||||
in time before the related and already reliably scraped event entry is 
 | 
			
		||||
deleted from the database.
 | 
			
		||||
 | 
			
		||||
Service Interface
 | 
			
		||||
-----------------
 | 
			
		||||
 | 
			
		||||
Other Plugins can and should request information about meta data from 
 | 
			
		||||
scraper2vdr via a call to the provided service interface. 
 | 
			
		||||
 | 
			
		||||
First the service "GetEventType" which expects a pointer to a cEvent or 
 | 
			
		||||
a cRecording object as input variable has to be called. This call provides
 | 
			
		||||
the type of the event or recording (tSeries, tMovie, tNone) and the seriesId,
 | 
			
		||||
episodeId and movieId. If type is tSeries, movieId is 0 and vice versa.
 | 
			
		||||
With that then a second call to GetSeries or GetMovie with the appropriate IDs
 | 
			
		||||
provides all stored information for the series or movie in form of a cSeries
 | 
			
		||||
or cMovie object. 
 | 
			
		||||
 | 
			
		||||
For further information just check the self explanatory services.h file. 
 | 
			
		||||
							
								
								
									
										56
									
								
								config.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								config.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
#include "lib/common.h"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
cScraper2VdrConfig::cScraper2VdrConfig() {
 | 
			
		||||
    mainMenuEntry = 1;
 | 
			
		||||
    headless = false;
 | 
			
		||||
    uuid = "";
 | 
			
		||||
    imgDirSet = false;
 | 
			
		||||
    mysqlHost = "localhost";
 | 
			
		||||
    mysqlPort = 3306;
 | 
			
		||||
    mysqlDBName = "epg2vdr";
 | 
			
		||||
    mysqlDBUser = "epg2vdr";
 | 
			
		||||
    mysqlDBPass = "epg";
 | 
			
		||||
    recScrapInfoName = "scrapinfo";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cScraper2VdrConfig::~cScraper2VdrConfig() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cScraper2VdrConfig::SetUuid(cPlugin *plug) {
 | 
			
		||||
    if (uuid.size() == 0) {
 | 
			
		||||
        uuid = getUniqueId();
 | 
			
		||||
        plug->SetupStore("uuid", uuid.c_str());
 | 
			
		||||
    }
 | 
			
		||||
    tell(0, "epgd uuid: %s", uuid.c_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cScraper2VdrConfig::SetImageDir(cString dir) {
 | 
			
		||||
    imageDir = *dir;
 | 
			
		||||
    imgDirSet = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cScraper2VdrConfig::SetDefaultImageDir(void) {
 | 
			
		||||
    if (!imgDirSet) {
 | 
			
		||||
        imageDir = cPlugin::CacheDirectory(PLUGIN_NAME_I18N);
 | 
			
		||||
    }
 | 
			
		||||
    tell (0, "using image directory %s", imageDir.c_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cScraper2VdrConfig::SetMode(string mode) {
 | 
			
		||||
    if (!mode.compare("headless"))
 | 
			
		||||
        headless = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cScraper2VdrConfig::SetupParse(const char *Name, const char *Value) {
 | 
			
		||||
    if      (strcmp(Name, "uuid") == 0)               uuid = Value;
 | 
			
		||||
    else if (strcmp(Name, "mainMenuEntry") == 0)      mainMenuEntry = atoi(Value);
 | 
			
		||||
    else if (strcmp(Name, "mysqlHost") == 0)          mysqlHost = Value;
 | 
			
		||||
    else if (strcmp(Name, "mysqlPort") == 0)          mysqlPort = atoi(Value);
 | 
			
		||||
    else if (strcmp(Name, "mysqlDBName") == 0)        mysqlDBName = Value;
 | 
			
		||||
    else if (strcmp(Name, "mysqlDBUser") == 0)        mysqlDBUser = Value;
 | 
			
		||||
    else if (strcmp(Name, "mysqlDBPass") == 0)        mysqlDBPass = Value;
 | 
			
		||||
    else
 | 
			
		||||
        return false;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								config.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
#ifndef __SCRAPER2VDR_CONFIG_H
 | 
			
		||||
#define __SCRAPER2VDR_CONFIG_H
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vdr/plugin.h>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
class cScraper2VdrConfig {
 | 
			
		||||
    private:
 | 
			
		||||
    public:
 | 
			
		||||
        cScraper2VdrConfig();
 | 
			
		||||
        ~cScraper2VdrConfig();
 | 
			
		||||
        bool SetupParse(const char *Name, const char *Value);
 | 
			
		||||
        void SetUuid(cPlugin *plug);
 | 
			
		||||
        void SetImageDir(cString dir);
 | 
			
		||||
        void SetDefaultImageDir(void);
 | 
			
		||||
        void SetMode(string mode);
 | 
			
		||||
        int mainMenuEntry;
 | 
			
		||||
        bool headless;
 | 
			
		||||
        string uuid;
 | 
			
		||||
        bool imgDirSet;
 | 
			
		||||
        string imageDir;
 | 
			
		||||
        string mysqlHost;
 | 
			
		||||
        int mysqlPort;
 | 
			
		||||
        string mysqlDBName;
 | 
			
		||||
        string mysqlDBUser;
 | 
			
		||||
        string mysqlDBPass;
 | 
			
		||||
        string recScrapInfoName;
 | 
			
		||||
};
 | 
			
		||||
#endif //__SCRAPER2VDR_CONFIG_H
 | 
			
		||||
							
								
								
									
										7
									
								
								lib/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								lib/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
all: 
 | 
			
		||||
	g++ -ggdb -DPLGDIR='"."' test.c common.c config.c db.c tabledef.c -lrt -lz -lmysqlclient -o t
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -f *.o *.a *~ core
 | 
			
		||||
							
								
								
									
										812
									
								
								lib/common.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										812
									
								
								lib/common.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,812 @@
 | 
			
		||||
/*
 | 
			
		||||
 * common.c: 
 | 
			
		||||
 *
 | 
			
		||||
 * See the README file for copyright information and how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
#ifdef USEUUID
 | 
			
		||||
# include <uuid/uuid.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <zlib.h>
 | 
			
		||||
 | 
			
		||||
#ifdef USELIBARCHIVE
 | 
			
		||||
# include <archive.h>
 | 
			
		||||
# include <archive_entry.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef VDR_PLUGIN
 | 
			
		||||
# include <vdr/thread.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#ifdef VDR_PLUGIN
 | 
			
		||||
  cMutex logMutex;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Debug
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
void tell(int eloquence, const char* format, ...)
 | 
			
		||||
{
 | 
			
		||||
   if (EPG2VDRConfig.loglevel < eloquence)
 | 
			
		||||
      return ;
 | 
			
		||||
 | 
			
		||||
   const int sizeBuffer = 100000;
 | 
			
		||||
   char t[sizeBuffer+100]; *t = 0;
 | 
			
		||||
   va_list ap;
 | 
			
		||||
 | 
			
		||||
#ifdef VDR_PLUGIN
 | 
			
		||||
   cMutexLock lock(&logMutex);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   va_start(ap, format);
 | 
			
		||||
 | 
			
		||||
#ifdef VDR_PLUGIN
 | 
			
		||||
   snprintf(t, sizeBuffer, "scraper2vdr: ");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   vsnprintf(t+strlen(t), sizeBuffer-strlen(t), format, ap);
 | 
			
		||||
   
 | 
			
		||||
   if (EPG2VDRConfig.logstdout)
 | 
			
		||||
   {
 | 
			
		||||
      char buf[50+TB];
 | 
			
		||||
      time_t now;
 | 
			
		||||
      time(&now);
 | 
			
		||||
      strftime(buf, 50, "%y.%m.%d %H:%M:%S", localtime(&now));
 | 
			
		||||
      printf("%s %s\n", buf, t);
 | 
			
		||||
   }
 | 
			
		||||
   else
 | 
			
		||||
      syslog(LOG_ERR, "%s", t);
 | 
			
		||||
 | 
			
		||||
   va_end(ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Host ID
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
unsigned int getHostId()
 | 
			
		||||
{
 | 
			
		||||
   static unsigned int id = gethostid() & 0xFFFFFFFF;
 | 
			
		||||
   return id;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// String Operations
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
void toUpper(std::string& str)
 | 
			
		||||
{
 | 
			
		||||
   const char* s = str.c_str();
 | 
			
		||||
   int lenSrc = str.length();
 | 
			
		||||
 | 
			
		||||
   char* dest = (char*)malloc(lenSrc+TB); *dest = 0;
 | 
			
		||||
   char* d = dest;
 | 
			
		||||
 | 
			
		||||
   int csSrc;  // size of character
 | 
			
		||||
 | 
			
		||||
   for (int ps = 0; ps < lenSrc; ps += csSrc)
 | 
			
		||||
   {
 | 
			
		||||
      csSrc = max(mblen(&s[ps], lenSrc-ps), 1);
 | 
			
		||||
      
 | 
			
		||||
      if (csSrc == 1)
 | 
			
		||||
         *d++ = toupper(s[ps]);
 | 
			
		||||
      else if (csSrc == 2 && s[ps] == (char)0xc3 && s[ps+1] >= (char)0xa0)
 | 
			
		||||
      {
 | 
			
		||||
         *d++ = s[ps];
 | 
			
		||||
         *d++ = s[ps+1] - 32;
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
         for (int i = 0; i < csSrc; i++)
 | 
			
		||||
            *d++ = s[ps+i];
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   *d = 0;
 | 
			
		||||
 | 
			
		||||
   str = dest;
 | 
			
		||||
   free(dest);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void removeChars(std::string& str, const char* ignore)
 | 
			
		||||
{
 | 
			
		||||
   const char* s = str.c_str();
 | 
			
		||||
   int lenSrc = str.length();
 | 
			
		||||
   int lenIgn = strlen(ignore);
 | 
			
		||||
 | 
			
		||||
   char* dest = (char*)malloc(lenSrc+TB); *dest = 0;
 | 
			
		||||
   char* d = dest;
 | 
			
		||||
 | 
			
		||||
   int csSrc;  // size of character
 | 
			
		||||
   int csIgn;  // 
 | 
			
		||||
 | 
			
		||||
   for (int ps = 0; ps < lenSrc; ps += csSrc)
 | 
			
		||||
   {
 | 
			
		||||
      int skip = no;
 | 
			
		||||
 | 
			
		||||
      csSrc = max(mblen(&s[ps], lenSrc-ps), 1);
 | 
			
		||||
 | 
			
		||||
      for (int pi = 0; pi < lenIgn; pi += csIgn)
 | 
			
		||||
      {
 | 
			
		||||
         csIgn = max(mblen(&ignore[pi], lenIgn-pi), 1);
 | 
			
		||||
 | 
			
		||||
         if (csSrc == csIgn && strncmp(&s[ps], &ignore[pi], csSrc) == 0)
 | 
			
		||||
         {
 | 
			
		||||
            skip = yes;
 | 
			
		||||
            break;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (!skip)
 | 
			
		||||
      {
 | 
			
		||||
         for (int i = 0; i < csSrc; i++)
 | 
			
		||||
            *d++ = s[ps+i];
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   *d = 0;
 | 
			
		||||
 | 
			
		||||
   str = dest;
 | 
			
		||||
   free(dest);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void removeCharsExcept(std::string& str, const char* except)
 | 
			
		||||
{
 | 
			
		||||
   const char* s = str.c_str();
 | 
			
		||||
   int lenSrc = str.length();
 | 
			
		||||
   int lenIgn = strlen(except);
 | 
			
		||||
 | 
			
		||||
   char* dest = (char*)malloc(lenSrc+TB); *dest = 0;
 | 
			
		||||
   char* d = dest;
 | 
			
		||||
 | 
			
		||||
   int csSrc;  // size of character
 | 
			
		||||
   int csIgn;  // 
 | 
			
		||||
 | 
			
		||||
   for (int ps = 0; ps < lenSrc; ps += csSrc)
 | 
			
		||||
   {
 | 
			
		||||
      int skip = yes;
 | 
			
		||||
 | 
			
		||||
      csSrc = max(mblen(&s[ps], lenSrc-ps), 1);
 | 
			
		||||
 | 
			
		||||
      for (int pi = 0; pi < lenIgn; pi += csIgn)
 | 
			
		||||
      {
 | 
			
		||||
         csIgn = max(mblen(&except[pi], lenIgn-pi), 1);
 | 
			
		||||
 | 
			
		||||
         if (csSrc == csIgn && strncmp(&s[ps], &except[pi], csSrc) == 0)
 | 
			
		||||
         {
 | 
			
		||||
            skip = no;
 | 
			
		||||
            break;
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (!skip)
 | 
			
		||||
      {
 | 
			
		||||
         for (int i = 0; i < csSrc; i++)
 | 
			
		||||
            *d++ = s[ps+i];
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   *d = 0;
 | 
			
		||||
 | 
			
		||||
   str = dest;
 | 
			
		||||
   free(dest);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void removeWord(std::string& pattern, std::string word)
 | 
			
		||||
{
 | 
			
		||||
   size_t  pos;
 | 
			
		||||
 | 
			
		||||
   if ((pos = pattern.find(word)) != std::string::npos)
 | 
			
		||||
      pattern.swap(pattern.erase(pos, word.length()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// String Manipulation
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
void prepareCompressed(std::string& pattern)
 | 
			
		||||
{
 | 
			
		||||
   // const char* ignore = " (),.;:-_+*!#?=&%$<>§/'`´@~\"[]{}"; 
 | 
			
		||||
   const char* notignore = "ABCDEFGHIJKLMNOPQRSTUVWXYZßÖÄÜöäü0123456789"; 
 | 
			
		||||
 | 
			
		||||
   toUpper(pattern);
 | 
			
		||||
   removeWord(pattern, " TEIL ");
 | 
			
		||||
   removeWord(pattern, " FOLGE ");
 | 
			
		||||
   removeCharsExcept(pattern, notignore);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Left Trim
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
char* lTrim(char* buf)
 | 
			
		||||
{
 | 
			
		||||
   if (buf)
 | 
			
		||||
   {
 | 
			
		||||
      char *tp = buf;
 | 
			
		||||
 | 
			
		||||
      while (*tp && strchr("\n\r\t ",*tp)) 
 | 
			
		||||
         tp++;
 | 
			
		||||
 | 
			
		||||
      memmove(buf, tp, strlen(tp) +1);
 | 
			
		||||
   }
 | 
			
		||||
   
 | 
			
		||||
   return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//*************************************************************************
 | 
			
		||||
// Right Trim
 | 
			
		||||
//*************************************************************************
 | 
			
		||||
 | 
			
		||||
char* rTrim(char* buf)
 | 
			
		||||
{
 | 
			
		||||
   if (buf)
 | 
			
		||||
   {
 | 
			
		||||
      char *tp = buf + strlen(buf);
 | 
			
		||||
 | 
			
		||||
      while (tp >= buf && strchr("\n\r\t ",*tp)) 
 | 
			
		||||
         tp--;
 | 
			
		||||
 | 
			
		||||
      *(tp+1) = 0;
 | 
			
		||||
   }
 | 
			
		||||
   
 | 
			
		||||
   return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//*************************************************************************
 | 
			
		||||
// All Trim
 | 
			
		||||
//*************************************************************************
 | 
			
		||||
 | 
			
		||||
char* allTrim(char* buf)
 | 
			
		||||
{
 | 
			
		||||
   return lTrim(rTrim(buf));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Number to String
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
std::string num2Str(int num)
 | 
			
		||||
{
 | 
			
		||||
   char txt[16];
 | 
			
		||||
 | 
			
		||||
   snprintf(txt, sizeof(txt), "%d", num);
 | 
			
		||||
 | 
			
		||||
   return std::string(txt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Long to Pretty Time
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
std::string l2pTime(time_t t)
 | 
			
		||||
{
 | 
			
		||||
   char txt[30];
 | 
			
		||||
   tm* tmp = localtime(&t);
 | 
			
		||||
   
 | 
			
		||||
   strftime(txt, sizeof(txt), "%d.%m.%Y %T", tmp);
 | 
			
		||||
   
 | 
			
		||||
   return std::string(txt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// MS to Duration
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
std::string ms2Dur(uint64_t t)
 | 
			
		||||
{
 | 
			
		||||
   char txt[30];
 | 
			
		||||
   
 | 
			
		||||
   int s = t / 1000;
 | 
			
		||||
   int ms = t % 1000;
 | 
			
		||||
 | 
			
		||||
   snprintf(txt, sizeof(txt), "%d.%03d seconds", s, ms);
 | 
			
		||||
   
 | 
			
		||||
   return std::string(txt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Char to Char-String
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
const char* c2s(char c, char* buf)
 | 
			
		||||
{
 | 
			
		||||
   sprintf(buf, "%c", c);
 | 
			
		||||
 | 
			
		||||
   return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// TOOLS
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
int isEmpty(const char* str)
 | 
			
		||||
{
 | 
			
		||||
   return !str || !*str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char* sstrcpy(char* dest, const char* src, int max)
 | 
			
		||||
{
 | 
			
		||||
   if (!dest || !src)
 | 
			
		||||
      return 0;
 | 
			
		||||
 | 
			
		||||
   strncpy(dest, src, max);
 | 
			
		||||
   dest[max-1] = 0;
 | 
			
		||||
   
 | 
			
		||||
   return dest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int isLink(const char* path)
 | 
			
		||||
{
 | 
			
		||||
   struct stat sb;
 | 
			
		||||
 | 
			
		||||
   if (lstat(path, &sb) == 0)
 | 
			
		||||
      return S_ISLNK(sb.st_mode);
 | 
			
		||||
 | 
			
		||||
   tell(0, "Error: Detecting state for '%s' failed, error was '%m'", path);
 | 
			
		||||
 | 
			
		||||
   return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fileSize(const char* path)
 | 
			
		||||
{
 | 
			
		||||
   struct stat sb;
 | 
			
		||||
 | 
			
		||||
   if (lstat(path, &sb) == 0)
 | 
			
		||||
      return sb.st_size;
 | 
			
		||||
 | 
			
		||||
   tell(0, "Error: Detecting state for '%s' failed, error was '%m'", path);
 | 
			
		||||
 | 
			
		||||
   return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int fileExists(const char* path)
 | 
			
		||||
{
 | 
			
		||||
   return access(path, F_OK) == 0; 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int createLink(const char* link, const char* dest, int force)
 | 
			
		||||
{
 | 
			
		||||
   if (!fileExists(link) || force)
 | 
			
		||||
   {
 | 
			
		||||
      // may be the link exists and point to a wrong or already deleted destination ...
 | 
			
		||||
      //   .. therefore we delete the link at first
 | 
			
		||||
      
 | 
			
		||||
      unlink(link);
 | 
			
		||||
      
 | 
			
		||||
      if (symlink(dest, link) != 0)
 | 
			
		||||
      {
 | 
			
		||||
         tell(0, "Failed to create symlink '%s', error was '%m'", link);
 | 
			
		||||
         return fail;
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Remove File
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
int removeFile(const char* filename)
 | 
			
		||||
{
 | 
			
		||||
   int lnk = isLink(filename);
 | 
			
		||||
 | 
			
		||||
   if (unlink(filename) != 0)
 | 
			
		||||
   {
 | 
			
		||||
      tell(0, "Can't remove file '%s', '%m'", filename);
 | 
			
		||||
      
 | 
			
		||||
      return 1;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   tell(3, "Removed %s '%s'", lnk ? "link" : "file", filename);
 | 
			
		||||
   
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Check Dir
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
int chkDir(const char* path)
 | 
			
		||||
{
 | 
			
		||||
   struct stat fs;
 | 
			
		||||
   
 | 
			
		||||
   if (stat(path, &fs) != 0 || !S_ISDIR(fs.st_mode))
 | 
			
		||||
   {
 | 
			
		||||
      tell(0, "Creating directory '%s'", path);
 | 
			
		||||
      
 | 
			
		||||
      if (mkdir(path, ACCESSPERMS) == -1)
 | 
			
		||||
      {
 | 
			
		||||
         tell(0, "Can't create directory '%m'");
 | 
			
		||||
         return fail;
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef USELIBXML
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Load XSLT
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
xsltStylesheetPtr loadXSLT(const char* name, const char* path, int utf8)
 | 
			
		||||
{
 | 
			
		||||
   xsltStylesheetPtr stylesheet;
 | 
			
		||||
   char* xsltfile;
 | 
			
		||||
 | 
			
		||||
   asprintf(&xsltfile, "%s/%s-%s.xsl", path, name, utf8 ? "utf-8" : "iso-8859-1");
 | 
			
		||||
   
 | 
			
		||||
   if ((stylesheet = xsltParseStylesheetFile((const xmlChar*)xsltfile)) == 0)
 | 
			
		||||
      tell(0, "Error: Can't load xsltfile %s", xsltfile);
 | 
			
		||||
   else
 | 
			
		||||
      tell(0, "Info: Stylesheet '%s' loaded", xsltfile);
 | 
			
		||||
      
 | 
			
		||||
   free(xsltfile);
 | 
			
		||||
   return stylesheet;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Gnu Unzip
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
int gunzip(MemoryStruct* zippedData, MemoryStruct* unzippedData)
 | 
			
		||||
{
 | 
			
		||||
   const int growthStep = 1024;
 | 
			
		||||
 | 
			
		||||
   z_stream stream = {0,0,0,0,0,0,0,0,0,0,0,Z_NULL,Z_NULL,Z_NULL};
 | 
			
		||||
   unsigned int resultSize = 0;
 | 
			
		||||
   int res = 0;
 | 
			
		||||
 | 
			
		||||
   unzippedData->clear();
 | 
			
		||||
 | 
			
		||||
   // determining the size in this way is taken from the sources of the gzip utility.
 | 
			
		||||
 | 
			
		||||
   memcpy(&unzippedData->size, zippedData->memory + zippedData->size -4, 4); 
 | 
			
		||||
   unzippedData->memory = (char*)malloc(unzippedData->size);
 | 
			
		||||
 | 
			
		||||
   // zlib initialisation
 | 
			
		||||
 | 
			
		||||
   stream.avail_in  = zippedData->size;
 | 
			
		||||
   stream.next_in   = (Bytef*)zippedData->memory;
 | 
			
		||||
   stream.avail_out = unzippedData->size;
 | 
			
		||||
   stream.next_out  = (Bytef*)unzippedData->memory;
 | 
			
		||||
 | 
			
		||||
   // The '+ 32' tells zlib to process zlib&gzlib headers
 | 
			
		||||
 | 
			
		||||
   res = inflateInit2(&stream, MAX_WBITS + 32);
 | 
			
		||||
 | 
			
		||||
   if (res != Z_OK)
 | 
			
		||||
   {
 | 
			
		||||
      tellZipError(res, " during zlib initialisation", stream.msg);
 | 
			
		||||
      inflateEnd(&stream);
 | 
			
		||||
      return fail;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   // skip the header
 | 
			
		||||
 | 
			
		||||
   res = inflate(&stream, Z_BLOCK);
 | 
			
		||||
 | 
			
		||||
   if (res != Z_OK)
 | 
			
		||||
   {
 | 
			
		||||
      tellZipError(res, " while skipping the header", stream.msg);
 | 
			
		||||
      inflateEnd(&stream);
 | 
			
		||||
      return fail;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   while (res == Z_OK)
 | 
			
		||||
   {
 | 
			
		||||
      if (stream.avail_out == 0)
 | 
			
		||||
      {
 | 
			
		||||
         unzippedData->size += growthStep;
 | 
			
		||||
         unzippedData->memory = (char*)realloc(unzippedData->memory, unzippedData->size);
 | 
			
		||||
 | 
			
		||||
         // Set the stream pointers to the potentially changed buffer!
 | 
			
		||||
 | 
			
		||||
         stream.avail_out = resultSize - stream.total_out;
 | 
			
		||||
         stream.next_out  = (Bytef*)(unzippedData + stream.total_out);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      res = inflate(&stream, Z_SYNC_FLUSH);
 | 
			
		||||
      resultSize = stream.total_out;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   if (res != Z_STREAM_END)
 | 
			
		||||
   {
 | 
			
		||||
      tellZipError(res, " during inflating", stream.msg);
 | 
			
		||||
      inflateEnd(&stream);
 | 
			
		||||
      return fail;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   unzippedData->size = resultSize;
 | 
			
		||||
   inflateEnd(&stream);
 | 
			
		||||
 | 
			
		||||
   return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//*************************************************************************
 | 
			
		||||
// tellZipError
 | 
			
		||||
//*************************************************************************
 | 
			
		||||
 | 
			
		||||
void tellZipError(int errorCode, const char* op, const char* msg)
 | 
			
		||||
{
 | 
			
		||||
   if (!op)  op  = "";
 | 
			
		||||
   if (!msg) msg = "None";
 | 
			
		||||
 | 
			
		||||
   switch (errorCode)
 | 
			
		||||
   {
 | 
			
		||||
      case Z_OK:           return;
 | 
			
		||||
      case Z_STREAM_END:   return;
 | 
			
		||||
      case Z_MEM_ERROR:    tell(0, "Error: Not enough memory to unzip file%s!\n", op); return;
 | 
			
		||||
      case Z_BUF_ERROR:    tell(0, "Error: Couldn't unzip data due to output buffer size problem%s!\n", op); return;
 | 
			
		||||
      case Z_DATA_ERROR:   tell(0, "Error: Zipped input data corrupted%s! Details: %s\n", op, msg); return;
 | 
			
		||||
      case Z_STREAM_ERROR: tell(0, "Error: Invalid stream structure%s. Details: %s\n", op, msg); return;
 | 
			
		||||
      default:             tell(0, "Error: Couldn't unzip data for unknown reason (%6d)%s!\n", errorCode, op); return;
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//*************************************************************************
 | 
			
		||||
// Host Data
 | 
			
		||||
//*************************************************************************
 | 
			
		||||
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
#include <ifaddrs.h>
 | 
			
		||||
 | 
			
		||||
static struct utsname info;
 | 
			
		||||
 | 
			
		||||
const char* getHostName()
 | 
			
		||||
{
 | 
			
		||||
   // get info from kernel
 | 
			
		||||
 | 
			
		||||
   if (uname(&info) == -1)
 | 
			
		||||
      return "";
 | 
			
		||||
 | 
			
		||||
   return info.nodename;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char* getFirstIp()
 | 
			
		||||
{
 | 
			
		||||
   struct ifaddrs *ifaddr, *ifa;
 | 
			
		||||
   static char host[NI_MAXHOST] = "";
 | 
			
		||||
 | 
			
		||||
   if (getifaddrs(&ifaddr) == -1) 
 | 
			
		||||
   {
 | 
			
		||||
      tell(0, "getifaddrs() failed");
 | 
			
		||||
      return "";
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   // walk through linked interface list
 | 
			
		||||
 | 
			
		||||
   for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) 
 | 
			
		||||
   {
 | 
			
		||||
      if (!ifa->ifa_addr)
 | 
			
		||||
         continue;
 | 
			
		||||
      
 | 
			
		||||
      // For an AF_INET interfaces
 | 
			
		||||
 | 
			
		||||
      if (ifa->ifa_addr->sa_family == AF_INET) //  || ifa->ifa_addr->sa_family == AF_INET6) 
 | 
			
		||||
      {
 | 
			
		||||
         int res = getnameinfo(ifa->ifa_addr, 
 | 
			
		||||
                               (ifa->ifa_addr->sa_family == AF_INET) ? sizeof(struct sockaddr_in) :
 | 
			
		||||
                               sizeof(struct sockaddr_in6),
 | 
			
		||||
                               host, NI_MAXHOST, 0, 0, NI_NUMERICHOST);
 | 
			
		||||
 | 
			
		||||
         if (res)
 | 
			
		||||
         {
 | 
			
		||||
            tell(0, "getnameinfo() failed: %s", gai_strerror(res));
 | 
			
		||||
            return "";
 | 
			
		||||
         }
 | 
			
		||||
 | 
			
		||||
         // skip loopback interface
 | 
			
		||||
 | 
			
		||||
         if (strcmp(host, "127.0.0.1") == 0)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
         tell(5, "%-8s %-15s %s", ifa->ifa_name, host,
 | 
			
		||||
              ifa->ifa_addr->sa_family == AF_INET   ? " (AF_INET)" :
 | 
			
		||||
              ifa->ifa_addr->sa_family == AF_INET6  ? " (AF_INET6)" : "");
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   freeifaddrs(ifaddr);
 | 
			
		||||
 | 
			
		||||
   return host;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef USELIBARCHIVE
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// unzip <file> and get data of first content which name matches <filter>
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
int unzip(const char* file, const char* filter, char*& buffer, int& size, char* entryName)
 | 
			
		||||
{
 | 
			
		||||
   const int step = 1024*10;
 | 
			
		||||
 | 
			
		||||
   int bufSize = 0;
 | 
			
		||||
   int r;
 | 
			
		||||
   int res;
 | 
			
		||||
 | 
			
		||||
   struct archive_entry* entry;
 | 
			
		||||
   struct archive* a = archive_read_new();
 | 
			
		||||
 | 
			
		||||
   *entryName = 0;
 | 
			
		||||
   buffer = 0;
 | 
			
		||||
   size = 0;
 | 
			
		||||
 | 
			
		||||
   archive_read_support_filter_all(a);
 | 
			
		||||
   archive_read_support_format_all(a);
 | 
			
		||||
 | 
			
		||||
   r = archive_read_open_filename(a, file, 10204);
 | 
			
		||||
 | 
			
		||||
   if (r != ARCHIVE_OK)
 | 
			
		||||
   {
 | 
			
		||||
      tell(0, "Error: Open '%s' failed - %m", file);
 | 
			
		||||
      return 1;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   while (archive_read_next_header(a, &entry) == ARCHIVE_OK) 
 | 
			
		||||
   {
 | 
			
		||||
      strcpy(entryName, archive_entry_pathname(entry));
 | 
			
		||||
 | 
			
		||||
      if (strstr(entryName, filter))
 | 
			
		||||
      {
 | 
			
		||||
         bufSize = step;
 | 
			
		||||
         buffer = (char*)malloc(bufSize+1);
 | 
			
		||||
 | 
			
		||||
         while ((res = archive_read_data(a, buffer+size, step)) > 0)
 | 
			
		||||
         {
 | 
			
		||||
            size += res;
 | 
			
		||||
            bufSize += step;
 | 
			
		||||
 | 
			
		||||
            buffer = (char*)realloc(buffer, bufSize+1);
 | 
			
		||||
         }
 | 
			
		||||
         
 | 
			
		||||
         buffer[size] = 0;
 | 
			
		||||
 | 
			
		||||
         break;
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   r = archive_read_free(a);
 | 
			
		||||
 | 
			
		||||
   if (r != ARCHIVE_OK)
 | 
			
		||||
   {
 | 
			
		||||
      size = 0;
 | 
			
		||||
      free(buffer);      
 | 
			
		||||
      return fail;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   return size > 0 ? success : fail;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Class LogDuration
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
#ifdef VDR_PLUGIN
 | 
			
		||||
 | 
			
		||||
# include <vdr/plugin.h>
 | 
			
		||||
 | 
			
		||||
LogDuration::LogDuration(const char* aMessage, int aLogLevel)
 | 
			
		||||
{
 | 
			
		||||
   logLevel = aLogLevel;
 | 
			
		||||
   strcpy(message, aMessage);
 | 
			
		||||
   
 | 
			
		||||
   // at last !
 | 
			
		||||
 | 
			
		||||
   durationStart = cTimeMs::Now();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LogDuration::~LogDuration()
 | 
			
		||||
{
 | 
			
		||||
   tell(logLevel, "duration '%s' was (%dms)",
 | 
			
		||||
     message, cTimeMs::Now() - durationStart);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LogDuration::show(const char* label)
 | 
			
		||||
{
 | 
			
		||||
   tell(logLevel, "elapsed '%s' at '%s' was (%dms)",
 | 
			
		||||
        message, label, cTimeMs::Now() - durationStart);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Get Unique ID
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
#ifdef USEUUID
 | 
			
		||||
const char* getUniqueId()
 | 
			
		||||
{
 | 
			
		||||
   static char uuid[sizeUuid+TB] = "";
 | 
			
		||||
 | 
			
		||||
   uuid_t id;
 | 
			
		||||
   uuid_generate(id);
 | 
			
		||||
   uuid_unparse_upper(id, uuid);
 | 
			
		||||
 | 
			
		||||
   return uuid;
 | 
			
		||||
}
 | 
			
		||||
#endif // USEUUID
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Create MD5
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
#ifdef USEMD5
 | 
			
		||||
 | 
			
		||||
int createMd5(const char* buf, md5* md5)
 | 
			
		||||
{
 | 
			
		||||
   MD5_CTX c;
 | 
			
		||||
   unsigned char out[MD5_DIGEST_LENGTH];
 | 
			
		||||
 | 
			
		||||
   MD5_Init(&c);
 | 
			
		||||
   MD5_Update(&c, buf, strlen(buf));
 | 
			
		||||
   MD5_Final(out, &c);
 | 
			
		||||
 | 
			
		||||
   for (int n = 0; n < MD5_DIGEST_LENGTH; n++)
 | 
			
		||||
      sprintf(md5+2*n, "%02x", out[n]);
 | 
			
		||||
 | 
			
		||||
   md5[sizeMd5] = 0;
 | 
			
		||||
 | 
			
		||||
   return done;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int createMd5OfFile(const char* path, const char* name, md5* md5)
 | 
			
		||||
{
 | 
			
		||||
   FILE* f;
 | 
			
		||||
   char buffer[1000];
 | 
			
		||||
   int nread = 0;
 | 
			
		||||
   MD5_CTX c;
 | 
			
		||||
   unsigned char out[MD5_DIGEST_LENGTH];
 | 
			
		||||
   char* file = 0;
 | 
			
		||||
 | 
			
		||||
   asprintf(&file, "%s/%s", path, name);
 | 
			
		||||
   
 | 
			
		||||
   if (!(f = fopen(file, "r")))
 | 
			
		||||
   {
 | 
			
		||||
      tell(0, "Fatal: Can't access '%s'; %m", file);
 | 
			
		||||
      free(file);
 | 
			
		||||
      return fail;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   free(file);
 | 
			
		||||
 | 
			
		||||
   MD5_Init(&c);   
 | 
			
		||||
   
 | 
			
		||||
   while ((nread = fread(buffer, 1, 1000, f)) > 0)
 | 
			
		||||
      MD5_Update(&c, buffer, nread);
 | 
			
		||||
   
 | 
			
		||||
   fclose(f);
 | 
			
		||||
 | 
			
		||||
   MD5_Final(out, &c);
 | 
			
		||||
   
 | 
			
		||||
   for (int n = 0; n < MD5_DIGEST_LENGTH; n++)
 | 
			
		||||
      sprintf(md5+2*n, "%02x", out[n]);
 | 
			
		||||
 | 
			
		||||
   md5[sizeMd5] = 0;
 | 
			
		||||
 | 
			
		||||
   return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // USEMD5
 | 
			
		||||
							
								
								
									
										179
									
								
								lib/common.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								lib/common.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,179 @@
 | 
			
		||||
/*
 | 
			
		||||
 * common.h: EPG2VDR plugin for the Video Disk Recorder
 | 
			
		||||
 *
 | 
			
		||||
 * See the README file for copyright information and how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __COMMON_H
 | 
			
		||||
#define __COMMON_H
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>      // uint_64_t
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include <openssl/md5.h> // MD5_*
 | 
			
		||||
 | 
			
		||||
#ifdef VDR_PLUGIN
 | 
			
		||||
#  include <vdr/tools.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef USELIBXML
 | 
			
		||||
# include <libxslt/transform.h>
 | 
			
		||||
# include <libxslt/xsltutils.h>
 | 
			
		||||
# include <libexslt/exslt.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// 
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
#ifndef VDR_PLUGIN
 | 
			
		||||
  inline long min(long a, long b) { return a < b ? a : b; }
 | 
			
		||||
  inline long max(long a, long b) { return a > b ? a : b; }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
enum Misc
 | 
			
		||||
{
 | 
			
		||||
   success  = 0,
 | 
			
		||||
   done     = success,
 | 
			
		||||
   fail     = -1,
 | 
			
		||||
   na       = -1,
 | 
			
		||||
   ignore   = -2,
 | 
			
		||||
   all      = -3,
 | 
			
		||||
   abrt     = -4,
 | 
			
		||||
   yes      = 1,
 | 
			
		||||
   on       = 1,
 | 
			
		||||
   off      = 0,
 | 
			
		||||
   no       = 0,
 | 
			
		||||
   TB       = 1,
 | 
			
		||||
 | 
			
		||||
   sizeMd5 = 2 * MD5_DIGEST_LENGTH,
 | 
			
		||||
   sizeUuid = 36,
 | 
			
		||||
 | 
			
		||||
   tmeSecondsPerMinute = 60,
 | 
			
		||||
   tmeSecondsPerHour = tmeSecondsPerMinute * 60,
 | 
			
		||||
   tmeSecondsPerDay = 24 * tmeSecondsPerHour
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Tell
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
void tell(int eloquence, const char* format, ...);
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// MemoryStruct for curl callbacks
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
struct MemoryStruct
 | 
			
		||||
{
 | 
			
		||||
   MemoryStruct()   { memory = 0; clear(); }
 | 
			
		||||
   ~MemoryStruct()  { clear(); }
 | 
			
		||||
 | 
			
		||||
   // data
 | 
			
		||||
 | 
			
		||||
   char* memory;
 | 
			
		||||
   size_t size;
 | 
			
		||||
 | 
			
		||||
   // tag attribute
 | 
			
		||||
 | 
			
		||||
   char tag[100];           // the tag to be compared 
 | 
			
		||||
   char name[100];          // content name (filename)
 | 
			
		||||
   int headerOnly;
 | 
			
		||||
 | 
			
		||||
   int isEmpty() { return memory == 0; }
 | 
			
		||||
 | 
			
		||||
   void clear() 
 | 
			
		||||
   {
 | 
			
		||||
      free(memory);
 | 
			
		||||
      memory = 0;
 | 
			
		||||
      size = 0;
 | 
			
		||||
      *tag = 0;
 | 
			
		||||
      *name = 0;
 | 
			
		||||
      headerOnly = no;
 | 
			
		||||
   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Tools
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
unsigned int getHostId();
 | 
			
		||||
const char* getHostName();
 | 
			
		||||
const char* getFirstIp();
 | 
			
		||||
 | 
			
		||||
#ifdef USEUUID
 | 
			
		||||
  const char* getUniqueId();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void removeChars(std::string& str, const char* ignore);
 | 
			
		||||
void removeCharsExcept(std::string& str, const char* except);
 | 
			
		||||
void removeWord(std::string& pattern, std::string word);
 | 
			
		||||
void prepareCompressed(std::string& pattern);
 | 
			
		||||
 | 
			
		||||
char* rTrim(char* buf);
 | 
			
		||||
char* lTrim(char* buf);
 | 
			
		||||
char* allTrim(char* buf);
 | 
			
		||||
char* sstrcpy(char* dest, const char* src, int max);
 | 
			
		||||
std::string num2Str(int num);
 | 
			
		||||
std::string l2pTime(time_t t);
 | 
			
		||||
std::string ms2Dur(uint64_t t);
 | 
			
		||||
const char* c2s(char c, char* buf);
 | 
			
		||||
 | 
			
		||||
int fileExists(const char* path);
 | 
			
		||||
int fileSize(const char* path);
 | 
			
		||||
int createLink(const char* link, const char* dest, int force);
 | 
			
		||||
int isLink(const char* path);
 | 
			
		||||
int isEmpty(const char* str);
 | 
			
		||||
int removeFile(const char* filename);
 | 
			
		||||
int chkDir(const char* path);
 | 
			
		||||
 | 
			
		||||
#ifdef USELIBXML
 | 
			
		||||
  xsltStylesheetPtr loadXSLT(const char* name, const char* path, int utf8);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef USEMD5
 | 
			
		||||
  typedef char md5Buf[sizeMd5+TB];
 | 
			
		||||
  typedef char md5;
 | 
			
		||||
  int createMd5(const char* buf, md5* md5);
 | 
			
		||||
  int createMd5OfFile(const char* path, const char* name, md5* md5);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Zip
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
int gunzip(MemoryStruct* zippedData, MemoryStruct* unzippedData);
 | 
			
		||||
void tellZipError(int errorCode, const char* op, const char* msg);
 | 
			
		||||
 | 
			
		||||
#ifdef USELIBARCHIVE
 | 
			
		||||
int unzip(const char* file, const char* filter, char*& buffer, 
 | 
			
		||||
          int& size, char* entryName);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef VDR_PLUGIN
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Log Duration
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class LogDuration
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      LogDuration(const char* aMessage, int aLogLevel = 2);
 | 
			
		||||
      ~LogDuration();
 | 
			
		||||
 | 
			
		||||
      void show(const char* label = "");
 | 
			
		||||
 | 
			
		||||
   protected:
 | 
			
		||||
 | 
			
		||||
      char message[1000];
 | 
			
		||||
      uint64_t durationStart;
 | 
			
		||||
      int logLevel;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
#endif //___COMMON_H
 | 
			
		||||
							
								
								
									
										63
									
								
								lib/config.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								lib/config.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
/*
 | 
			
		||||
 * config.c:
 | 
			
		||||
 *
 | 
			
		||||
 * See the README file for copyright information and how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
cEPG2VDRConfig EPG2VDRConfig;
 | 
			
		||||
 | 
			
		||||
cEPG2VDRConfig::cEPG2VDRConfig(void) 
 | 
			
		||||
{
 | 
			
		||||
   mainmenuVisible = yes;
 | 
			
		||||
   mainmenuFullupdate = 0;
 | 
			
		||||
 | 
			
		||||
   useproxy = no;
 | 
			
		||||
   sstrcpy(httpproxy, "127.0.0.1:8000", sizeof(httpproxy));
 | 
			
		||||
   sstrcpy(username, "", sizeof(username));
 | 
			
		||||
   sstrcpy(password, "", sizeof(password));
 | 
			
		||||
 | 
			
		||||
   checkInitial = yes;
 | 
			
		||||
   updatetime = 6;        // hours
 | 
			
		||||
   days = 8;
 | 
			
		||||
   upddays = 2;
 | 
			
		||||
   storeXmlToFs = no;
 | 
			
		||||
   blacklist = no;
 | 
			
		||||
   masterMode = 0;
 | 
			
		||||
 | 
			
		||||
   getepgimages = yes;
 | 
			
		||||
   maximagesperevent = 1;
 | 
			
		||||
   epgImageSize = 2;
 | 
			
		||||
 | 
			
		||||
   seriesEnabled = yes;
 | 
			
		||||
   sstrcpy(seriesUrl, "eplists.constabel.net", sizeof(seriesUrl));
 | 
			
		||||
   seriesPort = 2006;
 | 
			
		||||
   storeSeriesToFs = no;
 | 
			
		||||
 | 
			
		||||
#ifdef VDR_PLUGIN
 | 
			
		||||
   activeOnEpgd = no;
 | 
			
		||||
   scheduleBoot = no;
 | 
			
		||||
#else
 | 
			
		||||
   sstrcpy(cachePath, "/var/cache/epgd", sizeof(cachePath));
 | 
			
		||||
   sstrcpy(pluginPath, PLGDIR, sizeof(pluginPath));
 | 
			
		||||
   sstrcpy(epgView, "eventsview.sql", sizeof(epgView));
 | 
			
		||||
   updateThreshold = 200;
 | 
			
		||||
   maintanance = no;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
   sstrcpy(dbHost, "localhost", sizeof(dbHost));
 | 
			
		||||
   dbPort = 3306;
 | 
			
		||||
   sstrcpy(dbName, "epg2vdr", sizeof(dbName));
 | 
			
		||||
   sstrcpy(dbUser, "epg2vdr", sizeof(dbUser));
 | 
			
		||||
   sstrcpy(dbPass, "epg", sizeof(dbPass));
 | 
			
		||||
 | 
			
		||||
   logstdout = no;
 | 
			
		||||
   loglevel = 1;
 | 
			
		||||
 | 
			
		||||
   uuid[0] = 0;
 | 
			
		||||
} 
 | 
			
		||||
							
								
								
									
										73
									
								
								lib/config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								lib/config.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
/*
 | 
			
		||||
 * config.h:
 | 
			
		||||
 *
 | 
			
		||||
 * See the README file for copyright information and how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: config.h,v 1.2 2012/10/26 08:44:13 wendel Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __EPG2VDR_CONFIG_H
 | 
			
		||||
#define __EPG2VDR_CONFIG_H
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Config
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
struct cEPG2VDRConfig
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
      
 | 
			
		||||
      cEPG2VDRConfig(void);
 | 
			
		||||
 | 
			
		||||
      int useproxy;      
 | 
			
		||||
      char httpproxy[256+TB];
 | 
			
		||||
      char username[100+TB];
 | 
			
		||||
      char password[100+TB];
 | 
			
		||||
 | 
			
		||||
      int checkInitial;
 | 
			
		||||
      int updatetime;
 | 
			
		||||
      int days;
 | 
			
		||||
      int upddays;
 | 
			
		||||
      int storeXmlToFs;
 | 
			
		||||
      int blacklist;         // to enable noepg feature
 | 
			
		||||
 | 
			
		||||
      int getepgimages;
 | 
			
		||||
      int maximagesperevent;
 | 
			
		||||
      int epgImageSize;
 | 
			
		||||
 | 
			
		||||
      int seriesEnabled;
 | 
			
		||||
      char seriesUrl[500+TB];
 | 
			
		||||
      int seriesPort;
 | 
			
		||||
      int storeSeriesToFs;
 | 
			
		||||
 | 
			
		||||
#ifdef VDR_PLUGIN
 | 
			
		||||
      int activeOnEpgd;
 | 
			
		||||
      int scheduleBoot;
 | 
			
		||||
#else
 | 
			
		||||
      char cachePath[256+TB];
 | 
			
		||||
      char pluginPath[256+TB];
 | 
			
		||||
      char epgView[100+TB];
 | 
			
		||||
      int updateThreshold;
 | 
			
		||||
      int maintanance;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
      char dbHost[100+TB];
 | 
			
		||||
      int dbPort;
 | 
			
		||||
      char dbName[100+TB];
 | 
			
		||||
      char dbUser[100+TB];
 | 
			
		||||
      char dbPass[100+TB];
 | 
			
		||||
 | 
			
		||||
      int logstdout;
 | 
			
		||||
      int loglevel;
 | 
			
		||||
 | 
			
		||||
      int mainmenuVisible;
 | 
			
		||||
      int mainmenuFullupdate;
 | 
			
		||||
      int masterMode;
 | 
			
		||||
      char uuid[sizeUuid+TB];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern cEPG2VDRConfig EPG2VDRConfig;
 | 
			
		||||
 | 
			
		||||
#endif // __EPG2VDR_CONFIG_H 
 | 
			
		||||
							
								
								
									
										856
									
								
								lib/tabledef.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										856
									
								
								lib/tabledef.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,856 @@
 | 
			
		||||
/*
 | 
			
		||||
 * tabledef.c
 | 
			
		||||
 *
 | 
			
		||||
 * See the README file for copyright information and how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "tabledef.h"
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// cEpgdState
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
const char* cEpgdState::states[] =
 | 
			
		||||
{
 | 
			
		||||
   "init",
 | 
			
		||||
   "standby",
 | 
			
		||||
   "stopped",
 | 
			
		||||
 | 
			
		||||
   "busy (events)",
 | 
			
		||||
   "busy (match)",
 | 
			
		||||
   "busy (images)",
 | 
			
		||||
   "busy (scraping)",
 | 
			
		||||
 | 
			
		||||
   0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const char* cEpgdState::toName(cEpgdState::State s)
 | 
			
		||||
{
 | 
			
		||||
   if (!isValid(s))
 | 
			
		||||
      return "unknown";
 | 
			
		||||
 | 
			
		||||
   return states[s];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cEpgdState::State cEpgdState::toState(const char* name)
 | 
			
		||||
{
 | 
			
		||||
   for (int i = 0; i < esCount; i++)
 | 
			
		||||
      if (strcmp(states[i], name) == 0)
 | 
			
		||||
         return (State)i;
 | 
			
		||||
 | 
			
		||||
   return esUnknown;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Event Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableEvents::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name               format     size  index               type
 | 
			
		||||
 | 
			
		||||
   // primary key
 | 
			
		||||
 | 
			
		||||
   { "eventid",          ffUInt,       0, fiEventId,          ftPrimary },
 | 
			
		||||
   { "channelid",        ffAscii,     50, fiChannelId,        ftPrimary },
 | 
			
		||||
 | 
			
		||||
   { "masterid",         ffUInt,       0, fiMasterId,         ftAutoinc },
 | 
			
		||||
   { "useid",            ffUInt,       0, fiUseId,            ftData },
 | 
			
		||||
 | 
			
		||||
   // meta                                                         
 | 
			
		||||
 | 
			
		||||
   { "source",           ffAscii,     10, fiSource,           ftMeta },
 | 
			
		||||
   { "fileref",          ffAscii,     50, fiFileRef,          ftMeta },
 | 
			
		||||
   { "inssp",            ffInt,       10, fiInsSp,            ftMeta },
 | 
			
		||||
   { "updsp",            ffInt,       10, fiUpdSp,            ftMeta },
 | 
			
		||||
   { "updflg",           ffAscii,      1, fiUpdFlg,           ftMeta },
 | 
			
		||||
   { "delflg",           ffAscii,      1, fiDelFlg,           ftMeta },
 | 
			
		||||
                                                                   
 | 
			
		||||
   // vdr event data                                               
 | 
			
		||||
                                                                   
 | 
			
		||||
   { "tableid",          ffInt,        2, fiTableId,          ftData },
 | 
			
		||||
   { "version",          ffInt,        3, fiVersion,          ftData },
 | 
			
		||||
   { "title",            ffAscii,    200, fiTitle,            ftData },
 | 
			
		||||
   { "comptitle",        ffAscii,    200, fiCompTitle,        ftData },
 | 
			
		||||
   { "shorttext",        ffAscii,    300, fiShortText,        ftData },
 | 
			
		||||
   { "compshorttext",    ffAscii,    300, fiCompShortText,    ftData },
 | 
			
		||||
   { "longdescription",  ffText,   25000, fiLongDescription,  ftData },
 | 
			
		||||
   { "starttime",        ffInt,       10, fiStartTime,        ftData },
 | 
			
		||||
   { "duration",         ffInt,        5, fiDuration,         ftData },
 | 
			
		||||
   { "parentalrating",   ffInt,        2, fiParentalRating,   ftData },
 | 
			
		||||
   { "vps",              ffInt,       10, fiVps,              ftData },
 | 
			
		||||
 | 
			
		||||
   { "description",      ffText,   50000, fiDescription,      ftCalc },
 | 
			
		||||
                                                                   
 | 
			
		||||
   // additional external data
 | 
			
		||||
                                                                   
 | 
			
		||||
   { "shortdescription", ffAscii,   3000, fiShortDescription, ftData },
 | 
			
		||||
   { "actor",            ffAscii,   3000, fiActor,            ftData },
 | 
			
		||||
   { "audio",            ffAscii,     50, fiAudio,            ftData },
 | 
			
		||||
   { "category",         ffAscii,     50, fiCategory,         ftData },
 | 
			
		||||
   { "country",          ffAscii,     50, fiCountry,          ftData },
 | 
			
		||||
   { "director",         ffAscii,    250, fiDirector,         ftData },
 | 
			
		||||
   { "flags",            ffAscii,    100, fiFlags,            ftData },
 | 
			
		||||
   { "genre",            ffAscii,    100, fiGenre,            ftData },
 | 
			
		||||
   { "info",             ffText,   10000, fiInfo,             ftData },
 | 
			
		||||
   { "music",            ffAscii,    250, fiMusic,            ftData },
 | 
			
		||||
   { "producer",         ffText,    1000, fiProducer,         ftData },
 | 
			
		||||
   { "screenplay",       ffAscii,    500, fiScreenplay,       ftData },
 | 
			
		||||
   { "shortreview",      ffAscii,    500, fiShortreview,      ftData },
 | 
			
		||||
   { "tipp",             ffAscii,    250, fiTipp,             ftData },
 | 
			
		||||
   { "topic",            ffAscii,    500, fiTopic,            ftData },
 | 
			
		||||
   { "year",             ffAscii,     10, fiYear,             ftData },
 | 
			
		||||
   { "rating",           ffAscii,    250, fiRating,           ftData },
 | 
			
		||||
   { "fsk",              ffAscii,      2, fiFsk,              ftData },
 | 
			
		||||
   { "movieid",          ffAscii,     20, fiMovieid,          ftData },
 | 
			
		||||
   { "moderator",        ffAscii,    250, fiModerator,        ftData },
 | 
			
		||||
   { "other",            ffText,    2000, fiOther,            ftData },
 | 
			
		||||
   { "guest",            ffText,    1000, fiGuest,            ftData },
 | 
			
		||||
   { "camera",           ffText,    1000, fiCamera,           ftData },
 | 
			
		||||
 | 
			
		||||
   { "extepnum",         ffInt,        4, fiExtEpNum,         ftData },
 | 
			
		||||
   { "imagecount",       ffInt,        2, fiImageCount,       ftData },
 | 
			
		||||
 | 
			
		||||
   // episodes (constable)
 | 
			
		||||
 | 
			
		||||
   { "episode",          ffAscii,    250, fiEpisode,          ftData },
 | 
			
		||||
   { "episodepart",      ffAscii,    250, fiEpisodePart,      ftData },
 | 
			
		||||
   { "episodelang",      ffAscii,      3, fiEpisodeLang,      ftData },
 | 
			
		||||
 | 
			
		||||
   // tv scraper
 | 
			
		||||
 | 
			
		||||
   { "scrseriesid",      ffInt,       11, fiScrSeriesId,      ftData },
 | 
			
		||||
   { "scrseriesepisode", ffInt,       11, fiScrSeriesEpisode, ftData },
 | 
			
		||||
   { "scrmovieid",       ffInt,       11, fiScrMovieId,       ftData },
 | 
			
		||||
   { "scrsp",            ffInt,       11, fiScrSp,            ftData },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef* cTableEvents::toField(const char* name)
 | 
			
		||||
{
 | 
			
		||||
   for (int i = 0; i < fiCount; i++)
 | 
			
		||||
      if (strcmp(fields[i].name, name) == 0)
 | 
			
		||||
         return &fields[i];
 | 
			
		||||
   
 | 
			
		||||
   tell(0, "Request for unexpected field '%s', ignoring", name);
 | 
			
		||||
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cDbService::IndexDef cTableEvents::indices[] =
 | 
			
		||||
{
 | 
			
		||||
   // index             fields  
 | 
			
		||||
 | 
			
		||||
   { "comptitle",          { fiCompTitle, na            }, 0 },
 | 
			
		||||
   { "source",             { fiSource, na               }, 0 },
 | 
			
		||||
   { "FilerefSource",      { fiFileRef, fiSource,    na }, 0 },
 | 
			
		||||
   { "channelid",          { fiChannelId, na            }, 0 },
 | 
			
		||||
   { "useid",              { fiUseId, na                }, 0 },
 | 
			
		||||
   { "useidchannelid",     { fiUseId, fiChannelId,   na }, 0 },
 | 
			
		||||
   { "updflgupdsp",        { fiUpdFlg, fiUpdSp,      na }, 0 },
 | 
			
		||||
   { "idxsourcechannelid", { fiSource, fiChannelId,  na }, 0 },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Components
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableComponents::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name               format     size  index          type
 | 
			
		||||
 | 
			
		||||
   { "eventid",          ffUInt,        0, fiEventId,     ftPrimary },
 | 
			
		||||
   { "channelid",        ffAscii,      50, fiChannelId,   ftPrimary },
 | 
			
		||||
   { "stream",           ffInt,         3, fiStream,      ftPrimary },
 | 
			
		||||
   { "type",             ffInt,         3, fiType,        ftPrimary },
 | 
			
		||||
   { "lang",             ffAscii,       8, fiLang,        ftPrimary },
 | 
			
		||||
   { "description",      ffAscii,     100, fiDescription, ftPrimary },
 | 
			
		||||
 | 
			
		||||
   { "inssp",            ffInt,         0, fiInsSp,       ftMeta },
 | 
			
		||||
   { "updsp",            ffInt,         0, fiUpdSp,       ftMeta },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// File References
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableFileRefs::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name               format     size  index          type
 | 
			
		||||
 | 
			
		||||
   { "name",             ffAscii,    100, fiName,        ftPrimary },
 | 
			
		||||
   { "source",           ffAscii,     10, fiSource,      ftPrimary },
 | 
			
		||||
 | 
			
		||||
   { "inssp",            ffInt,        0, fiInsSp,       ftMeta },
 | 
			
		||||
   { "updsp",            ffInt,        0, fiUpdSp,       ftMeta },
 | 
			
		||||
 | 
			
		||||
   { "extid",            ffAscii,     10, fiExternalId,  ftData },
 | 
			
		||||
   { "fileref",          ffAscii,    100, fiFileRef,     ftData },     // name + '-' + tag
 | 
			
		||||
   { "tag",              ffAscii,    100, fiTag,         ftData },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cDbService::IndexDef cTableFileRefs::indices[] =
 | 
			
		||||
{
 | 
			
		||||
   // index              fields             
 | 
			
		||||
 | 
			
		||||
   { "SourceFileref",  { fiSource, fiFileRef, na }, 0 },
 | 
			
		||||
   { "Fileref",        { fiFileRef, na           }, 0 },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Image Ref Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableImageRefs::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name               format     size index          type
 | 
			
		||||
 | 
			
		||||
   { "eventid",          ffUInt,       0, fiEventId,     ftPrimary },
 | 
			
		||||
   { "lfn",              ffInt,        0, fiLfn,         ftPrimary },
 | 
			
		||||
 | 
			
		||||
   { "inssp",            ffInt,        0, fiInsSp,       ftMeta   },
 | 
			
		||||
   { "updsp",            ffInt,        0, fiUpdSp,       ftMeta   },
 | 
			
		||||
   { "source",           ffAscii,     10, fiSource,      ftMeta },
 | 
			
		||||
 | 
			
		||||
   { "fileref",          ffAscii,    100, fiFileRef,     ftData },
 | 
			
		||||
   { "imagename",        ffAscii,    100, fiImgName,     ftData   },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cDbService::IndexDef cTableImageRefs::indices[] =
 | 
			
		||||
{
 | 
			
		||||
   // index     fields     
 | 
			
		||||
 | 
			
		||||
   { "lfn",   { fiLfn, na     }, 0 },
 | 
			
		||||
   { "name",  { fiImgName, na }, 0 },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Image Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableImages::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name               format     size index          type
 | 
			
		||||
 | 
			
		||||
   { "imagename",        ffAscii,    100, fiImgName,     ftPrimary },
 | 
			
		||||
 | 
			
		||||
   { "inssp",            ffInt,        0, fiInsSp,       ftMeta },
 | 
			
		||||
   { "updsp",            ffInt,        0, fiUpdSp,       ftMeta },
 | 
			
		||||
 
 | 
			
		||||
   { "image",            ffMlob,  200000, fiImage,       ftData },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Series Episode Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableEpisodes::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name               format    size  index           type
 | 
			
		||||
 | 
			
		||||
   // primary key 
 | 
			
		||||
 | 
			
		||||
   { "compname",          ffAscii,   100, fiCompName,     ftPrimary },   // episode name compressed
 | 
			
		||||
   { "comppartname",      ffAscii,   200, fiCompPartName, ftPrimary },   // part name compressed
 | 
			
		||||
   { "lang",              ffAscii,    10, fiLang,         ftPrimary }, 
 | 
			
		||||
 | 
			
		||||
   { "inssp",             ffInt,       0, fiInsSp,        ftMeta },
 | 
			
		||||
   { "updsp",             ffInt,       0, fiUpdSp,        ftMeta },
 | 
			
		||||
   { "link",              ffInt,       0, fiLink,         ftData },
 | 
			
		||||
 | 
			
		||||
   // episode data 
 | 
			
		||||
 | 
			
		||||
   { "shortname",         ffAscii,   100, fiShortName,    ftData },
 | 
			
		||||
   { "episodename",       ffAscii,   100, fiEpisodeName,  ftData },   // episode name
 | 
			
		||||
 | 
			
		||||
   // part data
 | 
			
		||||
 | 
			
		||||
   { "partname",          ffAscii,   300, fiPartName,     ftData },   // part name
 | 
			
		||||
   { "season",            ffInt,       0, fiSeason,       ftData },
 | 
			
		||||
   { "part",              ffInt,       0, fiPart,         ftData },
 | 
			
		||||
   { "parts",             ffInt,       0, fiParts,        ftData },
 | 
			
		||||
   { "number",            ffInt,       0, fiNumber,       ftData },
 | 
			
		||||
 | 
			
		||||
   { "extracol1",         ffAscii,   250, fiExtraCol1,    ftData },
 | 
			
		||||
   { "extracol2",         ffAscii,   250, fiExtraCol2,    ftData },
 | 
			
		||||
   { "extracol3",         ffAscii,   250, fiExtraCol3,    ftData },
 | 
			
		||||
 | 
			
		||||
   { "comment",           ffAscii,   250, fiComment,      ftData },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cDbService::IndexDef cTableEpisodes::indices[] =
 | 
			
		||||
{
 | 
			
		||||
   // index     fields
 | 
			
		||||
 | 
			
		||||
   { "updsp", { fiUpdSp, na }, 0 },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Channel Map Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableChannelMap::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name               format     size index           type
 | 
			
		||||
 | 
			
		||||
   { "extid",            ffAscii,    10, fiExternalId,   ftPrimary },
 | 
			
		||||
   { "channelid",        ffAscii,    50, fiChannelId,    ftPrimary },
 | 
			
		||||
   { "source",           ffAscii,    20, fiSource,       ftPrimary },
 | 
			
		||||
 | 
			
		||||
   { "channelname",      ffAscii,   100, fiChannelName,  ftData },
 | 
			
		||||
 | 
			
		||||
   { "vps",              ffInt,       0, fiVps,          ftData },
 | 
			
		||||
   { "merge",            ffInt,       0, fiMerge,        ftData },
 | 
			
		||||
   { "mergesp",          ffInt,       0, fiMergeSp,      ftData },
 | 
			
		||||
 | 
			
		||||
   { "inssp",            ffInt,       0, fiInsSp,        ftMeta },
 | 
			
		||||
   { "updsp",            ffInt,       0, fiUpdSp,        ftMeta },
 | 
			
		||||
   { "updflg",           ffAscii,     1, fiUpdFlg,       ftMeta },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cDbService::IndexDef cTableChannelMap::indices[] =
 | 
			
		||||
{
 | 
			
		||||
   // index           fields 
 | 
			
		||||
 | 
			
		||||
   { "sourceExtid",        { fiSource, fiExternalId, na }, 0 },
 | 
			
		||||
   { "source",             { fiSource, na               }, 0 },
 | 
			
		||||
   { "updflg",             { fiUpdFlg, na               }, 0 },
 | 
			
		||||
   { "idxsourcechannelid", { fiSource, fiChannelId,  na }, 0 },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// VDRs Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableVdrs::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name               format     size index           type
 | 
			
		||||
 | 
			
		||||
   { "uuid",             ffAscii,    40, fiUuid,         ftPrimary },
 | 
			
		||||
 | 
			
		||||
   { "inssp",            ffInt,       0, fiInsSp,        ftMeta },
 | 
			
		||||
   { "updsp",            ffInt,       0, fiUpdSp,        ftMeta },
 | 
			
		||||
 | 
			
		||||
   { "name",             ffAscii,   100, fiName,         ftData },
 | 
			
		||||
   { "version",          ffAscii,   100, fiVersion,      ftData },
 | 
			
		||||
   { "dbapi",            ffUInt,      0, fiDbApi,        ftData },
 | 
			
		||||
   { "lastupd",          ffInt,       0, fiLastUpdate,   ftData },
 | 
			
		||||
   { "nextupd",          ffInt,       0, fiNextUpdate,   ftData },
 | 
			
		||||
   { "state",            ffAscii,    20, fiState,        ftData },
 | 
			
		||||
   { "master",           ffAscii,     1, fiMaster,       ftData },
 | 
			
		||||
   { "ip",               ffAscii,    20, fiIp,           ftData },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Parameter Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableParameters::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name               format     size index           type
 | 
			
		||||
 | 
			
		||||
   { "owner",            ffAscii,    40, fiOwner,        ftPrimary },
 | 
			
		||||
   { "name",             ffAscii,    40, fiName,         ftPrimary },
 | 
			
		||||
 | 
			
		||||
   { "inssp",            ffInt,       0, fiInsSp,        ftMeta },
 | 
			
		||||
   { "updsp",            ffInt,       0, fiUpdSp,        ftMeta },
 | 
			
		||||
 | 
			
		||||
   { "value",            ffAscii,   100, fiValue,        ftData },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Analyse
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableAnalyse::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name               format     size  index            type
 | 
			
		||||
 | 
			
		||||
   { "channelid",        ffAscii,     50, fiChannelId,     ftPrimary },
 | 
			
		||||
   { "vdr_masterid",     ffUInt,       0, fiVdrMasterId,   ftData },
 | 
			
		||||
   { "vdr_eventid",      ffUInt,       0, fiVdrEventId,    ftPrimary },
 | 
			
		||||
 | 
			
		||||
   { "vdr_starttime",    ffInt,       10, fiVdrStartTime,  ftData },
 | 
			
		||||
   { "vdr_duration",     ffInt,        5, fiVdrDuration,   ftData },
 | 
			
		||||
   { "vdr_title",        ffAscii,    200, fiVdrTitle,      ftData },
 | 
			
		||||
   { "vdr_shorttext",    ffAscii,    300, fiVdrShortText,  ftData },
 | 
			
		||||
 | 
			
		||||
   { "ext_masterid",     ffUInt,       0, fiExtMasterId,   ftData },
 | 
			
		||||
   { "ext_eventid",      ffUInt,       0, fiExtEventId,    ftData },
 | 
			
		||||
   { "ext_starttime",    ffInt,       10, fiExtStartTime,  ftData },
 | 
			
		||||
   { "ext_duration",     ffInt,        5, fiExtDuration,   ftData },
 | 
			
		||||
   { "ext_title",        ffAscii,    200, fiExtTitle,      ftData },
 | 
			
		||||
   { "ext_shorttext",    ffAscii,    300, fiExtShortText,  ftData },
 | 
			
		||||
   { "ext_episode",      ffAscii,      1, fiExtEpisode,    ftData },
 | 
			
		||||
   { "ext_merge",        ffInt,       11, fiExtMerge,      ftData },
 | 
			
		||||
   { "ext_images",       ffAscii,      1, fiExiImages,     ftData },
 | 
			
		||||
 | 
			
		||||
   { "lvmin",            ffInt,        3, fiLvMin,         ftData },
 | 
			
		||||
   { "rank",             ffInt,        5, fiRank,          ftData },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cDbService::IndexDef cTableAnalyse::indices[] =
 | 
			
		||||
{
 | 
			
		||||
   // index            fields 
 | 
			
		||||
 | 
			
		||||
   { "vdr_masterid", { fiVdrMasterId, na }, 0 },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Snapshot
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableSnapshot::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name            format     size  index             type
 | 
			
		||||
 | 
			
		||||
   { "channelid",     ffAscii,     50, fiChannelId,      ftData },
 | 
			
		||||
   { "source",        ffAscii,     10, fiSource,         ftData },
 | 
			
		||||
 | 
			
		||||
   { "masterid",      ffUInt,       0, fiVdrMasterId,    ftData },
 | 
			
		||||
   { "eventid",       ffUInt,       0, fiEventId,        ftData },
 | 
			
		||||
   { "useid",         ffUInt,       0, fiUseId,          ftData },
 | 
			
		||||
 | 
			
		||||
   { "starttime",     ffInt,       10, fiStartTime,      ftData },
 | 
			
		||||
   { "duration",      ffInt,        5, fiDuration,       ftData },
 | 
			
		||||
   { "title",         ffAscii,    200, fiTitle,          ftData },
 | 
			
		||||
   { "comptitle",     ffAscii,    200, fiCompTitle,      ftData },
 | 
			
		||||
   { "shorttext",     ffAscii,    300, fiShortText,      ftData },
 | 
			
		||||
   { "compshorttext", ffAscii,    300, fiCompShortText,  ftData },
 | 
			
		||||
 | 
			
		||||
   { "updsp",         ffInt,       10, fiUpdsp,          ftData },
 | 
			
		||||
 | 
			
		||||
   { "episode",       ffAscii,      1, fiEpisode,        ftData },
 | 
			
		||||
   { "merge",         ffInt,        0, fiMerge,          ftData },
 | 
			
		||||
   { "images",        ffAscii,      1, fiImages,         ftData },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cDbService::IndexDef cTableSnapshot::indices[] =
 | 
			
		||||
{
 | 
			
		||||
   // index            fields 
 | 
			
		||||
 | 
			
		||||
   { "channelid",       { fiChannelId, na }, 0 },
 | 
			
		||||
   { "starttimeSource", { fiStartTime, fiSource, na }, 0 },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Series Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableSeries::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name                     format     size  index                  type
 | 
			
		||||
 | 
			
		||||
   // primary key
 | 
			
		||||
   { "series_id",              ffUInt,       0, fiSeriesId,            ftPrimary },
 | 
			
		||||
   //Data
 | 
			
		||||
   { "series_name",            ffAscii,    200, fiSeriesName,          ftData },
 | 
			
		||||
   { "series_last_scraped",    ffUInt,       0, fiSeriesLastScraped,   ftData },
 | 
			
		||||
   { "series_last_updated",    ffUInt,       0, fiSeriesLastUpdated,   ftData },
 | 
			
		||||
   { "series_overview",        ffText,   10000, fiSeriesOverview,      ftData },
 | 
			
		||||
   { "series_firstaired",      ffAscii,     50, fiSeriesFirstAired,    ftData },
 | 
			
		||||
   { "series_network",         ffAscii,    100, fiSeriesNetwork,       ftData },
 | 
			
		||||
   { "series_imdb_id",         ffAscii,     20, fiSeriesIMDBId,        ftData },
 | 
			
		||||
   { "series_genre",           ffAscii,    100, fiSeriesGenre,         ftData },
 | 
			
		||||
   { "series_rating",          ffFloat,     31, fiSeriesRating,        ftData },
 | 
			
		||||
   { "series_status",          ffAscii,     50, fiSeriesStatus,        ftData },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef* cTableSeries::toField(const char* name)
 | 
			
		||||
{
 | 
			
		||||
   for (int i = 0; i < fiCount; i++)
 | 
			
		||||
      if (strcmp(fields[i].name, name) == 0)
 | 
			
		||||
         return &fields[i];
 | 
			
		||||
   
 | 
			
		||||
   tell(0, "Request for unexpected field '%s', ignoring", name);
 | 
			
		||||
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cDbService::IndexDef cTableSeries::indices[] =
 | 
			
		||||
{
 | 
			
		||||
   // index             fields  
 | 
			
		||||
  
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// SeriesEpisode Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableSeriesEpisode::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name                        format     size  index                  type
 | 
			
		||||
 | 
			
		||||
   // primary key
 | 
			
		||||
   { "episode_id",                  ffUInt,       0, fiEpisodeId,           ftPrimary },
 | 
			
		||||
   //Data
 | 
			
		||||
   { "episode_number",              ffUInt,       0, fiEpisodeNumber,       ftData },
 | 
			
		||||
   { "season_number",               ffUInt,       0, fiSeasonNumber,        ftData },
 | 
			
		||||
   { "episode_name",                ffAscii,    300, fiEpisodeName,         ftData },
 | 
			
		||||
   { "episode_overview",            ffText,   10000, fiEpisodeOverview,     ftData },
 | 
			
		||||
   { "episode_firstaired",          ffAscii,     20, fiEpisodeFirstAired,   ftData },
 | 
			
		||||
   { "episode_gueststars",          ffAscii,   1000, fiEpisodeGuestStars,   ftData },
 | 
			
		||||
   { "episode_rating",              ffFloat,     31, fiEpisodeRating,       ftData },
 | 
			
		||||
   { "episode_last_updated",        ffUInt,       0, fiEpisodeLastUpdated,  ftData },
 | 
			
		||||
   { "series_id",                   ffUInt,       0, fiSeriesId,            ftData },
 | 
			
		||||
   
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef* cTableSeriesEpisode::toField(const char* name)
 | 
			
		||||
{
 | 
			
		||||
   for (int i = 0; i < fiCount; i++)
 | 
			
		||||
      if (strcmp(fields[i].name, name) == 0)
 | 
			
		||||
         return &fields[i];
 | 
			
		||||
   
 | 
			
		||||
   tell(0, "Request for unexpected field '%s', ignoring", name);
 | 
			
		||||
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cDbService::IndexDef cTableSeriesEpisode::indices[] =
 | 
			
		||||
{
 | 
			
		||||
   // index               fields  
 | 
			
		||||
   { "series_id",         { fiSeriesId, na }, 0 },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// SeriesMedia Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableSeriesMedia::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name                        format     size  index                    type
 | 
			
		||||
 | 
			
		||||
   // primary key
 | 
			
		||||
   { "series_id",                  ffUInt,       0, fiSeriesId,             ftPrimary },
 | 
			
		||||
   { "season_number",              ffUInt,       0, fiSeasonNumber,         ftPrimary },
 | 
			
		||||
   { "episode_id",                 ffUInt,       0, fiEpisodeId,            ftPrimary },
 | 
			
		||||
   { "actor_id",                   ffUInt,       0, fiActorId,              ftPrimary },
 | 
			
		||||
   { "media_type",                 ffUInt,       0, fiMediaType,            ftPrimary },
 | 
			
		||||
   //Data
 | 
			
		||||
   { "media_url",                  ffAscii,    100, fiMediaUrl,             ftData },
 | 
			
		||||
   { "media_width",                ffUInt,       0, fiMediaWidth,           ftData },
 | 
			
		||||
   { "media_height",               ffUInt,       0, fiMediaHeight,          ftData },
 | 
			
		||||
   { "media_rating",               ffFloat,     31, fiMediaRating,          ftData },
 | 
			
		||||
   { "media_content",              ffMlob, 1000000, fiMediaContent,         ftData },
 | 
			
		||||
   
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef* cTableSeriesMedia::toField(const char* name)
 | 
			
		||||
{
 | 
			
		||||
   for (int i = 0; i < fiCount; i++)
 | 
			
		||||
      if (strcmp(fields[i].name, name) == 0)
 | 
			
		||||
         return &fields[i];
 | 
			
		||||
   
 | 
			
		||||
   tell(0, "Request for unexpected field '%s', ignoring", name);
 | 
			
		||||
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cDbService::IndexDef cTableSeriesMedia::indices[] =
 | 
			
		||||
{
 | 
			
		||||
   // index               fields  
 | 
			
		||||
   { "series_id",         { fiSeriesId, na }, 0 },
 | 
			
		||||
   { "season_number",     { fiSeasonNumber, na }, 0 },
 | 
			
		||||
   { "episode_id",        { fiEpisodeId, na }, 0 },
 | 
			
		||||
   { "actor_id",          { fiActorId, na }, 0 },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// SeriesActor Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableSeriesActor::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name                        format     size  index                    type
 | 
			
		||||
 | 
			
		||||
   // primary key
 | 
			
		||||
   { "actor_id",                  ffUInt,       0, fiActorId,              ftPrimary },
 | 
			
		||||
   //Data
 | 
			
		||||
   { "actor_name",                ffAscii,    100, fiActorName,            ftData },
 | 
			
		||||
   { "actor_role",                ffAscii,    500, fiActorRole,            ftData },
 | 
			
		||||
   { "actor_sortorder",           ffUInt,       0, fiSortOrder,            ftData },
 | 
			
		||||
   
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef* cTableSeriesActor::toField(const char* name)
 | 
			
		||||
{
 | 
			
		||||
   for (int i = 0; i < fiCount; i++)
 | 
			
		||||
      if (strcmp(fields[i].name, name) == 0)
 | 
			
		||||
         return &fields[i];
 | 
			
		||||
   
 | 
			
		||||
   tell(0, "Request for unexpected field '%s', ignoring", name);
 | 
			
		||||
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cDbService::IndexDef cTableSeriesActor::indices[] =
 | 
			
		||||
{
 | 
			
		||||
   // index               fields  
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Movie Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableMovies::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name                        format     size  index                    type
 | 
			
		||||
 | 
			
		||||
   // primary key
 | 
			
		||||
   { "movie_id",                   ffUInt,       0, fiMovieId,              ftPrimary },
 | 
			
		||||
   //Data
 | 
			
		||||
   { "movie_title",                ffAscii,    300, fiTitle,                ftData },
 | 
			
		||||
   { "movie_original_title",       ffAscii,    300, fiOriginalTitle,        ftData },
 | 
			
		||||
   { "movie_tagline",              ffAscii,   1000, fiTagline,              ftData },
 | 
			
		||||
   { "movie_overview",             ffText,    5000, fiOverview,             ftData },
 | 
			
		||||
   { "movie_adult",                ffUInt,       0, fiIsAdult,              ftData },
 | 
			
		||||
   { "movie_collection_id",        ffUInt,       0, fiCollectionId,         ftData },
 | 
			
		||||
   { "movie_collection_name",      ffAscii,    300, fiCollectionName,       ftData },
 | 
			
		||||
   { "movie_budget",               ffUInt,       0, fiBudget,               ftData },
 | 
			
		||||
   { "movie_revenue",              ffUInt,       0, fiRevenue,              ftData },
 | 
			
		||||
   { "movie_genres",               ffAscii,    500, fiGenres,               ftData },
 | 
			
		||||
   { "movie_homepage",             ffAscii,    300, fiHomepage,             ftData },
 | 
			
		||||
   { "movie_release_date",         ffAscii,     20, fiReleaaseDate,         ftData },
 | 
			
		||||
   { "movie_runtime",              ffUInt,       0, fiRuntime,              ftData },
 | 
			
		||||
   { "movie_popularity",           ffFloat,     31, fiPopularity,           ftData },
 | 
			
		||||
   { "movie_vote_average",         ffFloat,     31, fiVoteAverage,          ftData },
 | 
			
		||||
   
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef* cTableMovies::toField(const char* name)
 | 
			
		||||
{
 | 
			
		||||
   for (int i = 0; i < fiCount; i++)
 | 
			
		||||
      if (strcmp(fields[i].name, name) == 0)
 | 
			
		||||
         return &fields[i];
 | 
			
		||||
   
 | 
			
		||||
   tell(0, "Request for unexpected field '%s', ignoring", name);
 | 
			
		||||
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cDbService::IndexDef cTableMovies::indices[] =
 | 
			
		||||
{
 | 
			
		||||
   // index               fields  
 | 
			
		||||
   { "movie_id",         { fiMovieId, na }, 0 },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// MovieActor Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableMovieActor::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name                        format     size  index                    type
 | 
			
		||||
 | 
			
		||||
   // primary key
 | 
			
		||||
   { "actor_id",                   ffUInt,       0, fiActorId,              ftPrimary },
 | 
			
		||||
   //Data
 | 
			
		||||
   { "actor_name",                 ffAscii,    300, fiActorName,            ftData },
 | 
			
		||||
   
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef* cTableMovieActor::toField(const char* name)
 | 
			
		||||
{
 | 
			
		||||
   for (int i = 0; i < fiCount; i++)
 | 
			
		||||
      if (strcmp(fields[i].name, name) == 0)
 | 
			
		||||
         return &fields[i];
 | 
			
		||||
   
 | 
			
		||||
   tell(0, "Request for unexpected field '%s', ignoring", name);
 | 
			
		||||
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cDbService::IndexDef cTableMovieActor::indices[] =
 | 
			
		||||
{
 | 
			
		||||
   // index               fields  
 | 
			
		||||
   { "actor_id",         { fiActorId, na }, 0 },
 | 
			
		||||
   
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// MovieActors Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableMovieActors::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name                        format     size  index                    type
 | 
			
		||||
 | 
			
		||||
   // primary key
 | 
			
		||||
   { "movie_id",                   ffUInt,       0, fiMovieId,              ftPrimary },
 | 
			
		||||
   { "actor_id",                   ffUInt,       0, fiActorId,              ftPrimary },
 | 
			
		||||
   //Data
 | 
			
		||||
   { "actor_role",                 ffAscii,    300, fiRole,                 ftData },
 | 
			
		||||
   
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef* cTableMovieActors::toField(const char* name)
 | 
			
		||||
{
 | 
			
		||||
   for (int i = 0; i < fiCount; i++)
 | 
			
		||||
      if (strcmp(fields[i].name, name) == 0)
 | 
			
		||||
         return &fields[i];
 | 
			
		||||
   
 | 
			
		||||
   tell(0, "Request for unexpected field '%s', ignoring", name);
 | 
			
		||||
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cDbService::IndexDef cTableMovieActors::indices[] =
 | 
			
		||||
{
 | 
			
		||||
   // index               fields  
 | 
			
		||||
   { "movie_id",         { fiMovieId, na }, 0 },
 | 
			
		||||
   { "actor_id",         { fiActorId, na }, 0 },
 | 
			
		||||
   
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// cTableMovieMedia Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableMovieMedia::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name                        format     size  index                    type
 | 
			
		||||
 | 
			
		||||
   // primary key
 | 
			
		||||
   { "movie_id",                   ffUInt,       0, fiMovieId,              ftPrimary },
 | 
			
		||||
   { "actor_id",                   ffUInt,       0, fiActorId,              ftPrimary },
 | 
			
		||||
   { "media_type",                 ffUInt,       0, fiMediaType,            ftPrimary },
 | 
			
		||||
   //Data
 | 
			
		||||
   { "media_url",                  ffAscii,    100, fiMediaUrl,             ftData },
 | 
			
		||||
   { "media_width",                ffUInt,       0, fiMediaWidth,           ftData },
 | 
			
		||||
   { "media_height",               ffUInt,       0, fiMediaHeight,          ftData },
 | 
			
		||||
   { "media_content",              ffMlob, 1000000, fiMediaContent,         ftData },
 | 
			
		||||
   
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef* cTableMovieMedia::toField(const char* name)
 | 
			
		||||
{
 | 
			
		||||
   for (int i = 0; i < fiCount; i++)
 | 
			
		||||
      if (strcmp(fields[i].name, name) == 0)
 | 
			
		||||
         return &fields[i];
 | 
			
		||||
   
 | 
			
		||||
   tell(0, "Request for unexpected field '%s', ignoring", name);
 | 
			
		||||
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cDbService::IndexDef cTableMovieMedia::indices[] =
 | 
			
		||||
{
 | 
			
		||||
   // index               fields  
 | 
			
		||||
   { "movie_id",          { fiMovieId, na }, 0 },
 | 
			
		||||
   { "actor_id",          { fiActorId, na }, 0 },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// cTableRecordings Fields
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef cTableRecordings::fields[] =
 | 
			
		||||
{
 | 
			
		||||
   // name                        format     size  index                    type
 | 
			
		||||
 | 
			
		||||
   // primary key
 | 
			
		||||
   { "uuid",                       ffAscii,     40, fiUuid,                 ftPrimary },
 | 
			
		||||
   { "rec_path",                   ffAscii,    200, fiRecPath,              ftPrimary },
 | 
			
		||||
   { "rec_start",                  ffUInt,       0, fiRecStart,             ftPrimary },
 | 
			
		||||
   
 | 
			
		||||
   //Data
 | 
			
		||||
   { "event_id",                   ffUInt,       0, fiEventId,              ftData },
 | 
			
		||||
   { "channel_id",                 ffAscii,     50, fiChannelId,            ftData },
 | 
			
		||||
   { "scrapinfo_movie_id",         ffUInt,       0, fiScrapInfoMovieId,     ftData },
 | 
			
		||||
   { "scrapinfo_series_id",        ffUInt,       0, fiScrapInfoSeriesId,    ftData },
 | 
			
		||||
   { "scrapinfo_episode_id",       ffUInt,       0, fiScrapInfoEpisodeId,   ftData },
 | 
			
		||||
   { "scrap_new",                  ffUInt,       0, fiScrapNew,             ftData },
 | 
			
		||||
   { "rec_title",                  ffAscii,    200, fiRecTitle,             ftData },
 | 
			
		||||
   { "rec_subtitle",               ffAscii,    500, fiRecSubTitle,          ftData },
 | 
			
		||||
   { "rec_duration",               ffUInt,       0, fiRecDuration,          ftData },
 | 
			
		||||
   { "movie_id",                   ffUInt,       0, fiMovieId,              ftData },
 | 
			
		||||
   { "series_id",                  ffUInt,       0, fiSeriesId,             ftData },
 | 
			
		||||
   { "episode_id",                 ffUInt,       0, fiEpisodeId,            ftData },
 | 
			
		||||
   
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cDbService::FieldDef* cTableRecordings::toField(const char* name)
 | 
			
		||||
{
 | 
			
		||||
   for (int i = 0; i < fiCount; i++)
 | 
			
		||||
      if (strcmp(fields[i].name, name) == 0)
 | 
			
		||||
         return &fields[i];
 | 
			
		||||
   
 | 
			
		||||
   tell(0, "Request for unexpected field '%s', ignoring", name);
 | 
			
		||||
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cDbService::IndexDef cTableRecordings::indices[] =
 | 
			
		||||
{
 | 
			
		||||
   // index                   fields  
 | 
			
		||||
   { "uuid",                  { fiUuid, na }, 0 },
 | 
			
		||||
   { "rec_path",              { fiRecPath, na }, 0 },
 | 
			
		||||
   { "rec_start",             { fiRecStart, na }, 0 },
 | 
			
		||||
 | 
			
		||||
   { 0 }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										832
									
								
								lib/tabledef.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										832
									
								
								lib/tabledef.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,832 @@
 | 
			
		||||
/*
 | 
			
		||||
 * tabledef.h
 | 
			
		||||
 *
 | 
			
		||||
 * See the README file for copyright information and how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __TABLEDEF_H
 | 
			
		||||
#define __TABLEDEF_H
 | 
			
		||||
 | 
			
		||||
#include "db.h"
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// cEpgdState
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cEpgdState
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      enum State
 | 
			
		||||
      {
 | 
			
		||||
         esUnknown = na,
 | 
			
		||||
 | 
			
		||||
         esInit,
 | 
			
		||||
         esStandby,
 | 
			
		||||
         esStopped,
 | 
			
		||||
 | 
			
		||||
         esBusy,
 | 
			
		||||
         esBusyEvents = esBusy,
 | 
			
		||||
         esBusyMatch,
 | 
			
		||||
 | 
			
		||||
         esBusyImages,
 | 
			
		||||
 | 
			
		||||
         esBusyScraping,
 | 
			
		||||
 | 
			
		||||
         esCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static const char* toName(State s);
 | 
			
		||||
      static State toState(const char* name);
 | 
			
		||||
      static int isValid(State s) { return s > esUnknown && s < esCount; }
 | 
			
		||||
 | 
			
		||||
      static const char* states[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef cEpgdState Es;
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// cUpdateState
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cUpdateState
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      enum State
 | 
			
		||||
      {
 | 
			
		||||
         // add to VDRs EPG
 | 
			
		||||
         
 | 
			
		||||
         usActive      = 'A',
 | 
			
		||||
         usLink        = 'L',
 | 
			
		||||
         usPassthrough = 'P',
 | 
			
		||||
         
 | 
			
		||||
         // remove from VDRs EPG
 | 
			
		||||
         
 | 
			
		||||
         usChanged     = 'C',
 | 
			
		||||
         usDelete      = 'D', 
 | 
			
		||||
         usRemove      = 'R',
 | 
			
		||||
         
 | 
			
		||||
         // don't care for VDRs EPG
 | 
			
		||||
         
 | 
			
		||||
         usInactive    = 'I',
 | 
			
		||||
         usTarget      = 'T'
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      // get lists for SQL 'in' statements
 | 
			
		||||
 | 
			
		||||
      static const char* getDeletable()      { return "'A','L','P','R','I'"; }
 | 
			
		||||
      static const char* getNeeded()         { return "'A','L','P','C','D','R'"; }
 | 
			
		||||
 | 
			
		||||
      // checks fpr c++ code
 | 
			
		||||
 | 
			
		||||
      static int isNeeded(char c)            { return strchr("ALPCDR", c) != 0; }
 | 
			
		||||
      static int isRemove(char c)            { return strchr("CDR", c) != 0; }
 | 
			
		||||
      
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef cUpdateState Us;
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableFileRef
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableFileRefs : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableFileRefs(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields, indices) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "fileref"; }
 | 
			
		||||
      
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiName,
 | 
			
		||||
         fiSource,
 | 
			
		||||
 | 
			
		||||
         fiInsSp,
 | 
			
		||||
         fiUpdSp,
 | 
			
		||||
 | 
			
		||||
         fiExternalId,
 | 
			
		||||
         fiFileRef,
 | 
			
		||||
         fiTag,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
      static IndexDef indices[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableImageRef
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableImageRefs : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableImageRefs(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields, indices) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "imagerefs"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiEventId,
 | 
			
		||||
         fiLfn,
 | 
			
		||||
 | 
			
		||||
         fiInsSp,
 | 
			
		||||
         fiUpdSp,
 | 
			
		||||
         fiSource,
 | 
			
		||||
         fiFileRef,
 | 
			
		||||
 | 
			
		||||
         fiImgName,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
      static IndexDef indices[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableImage
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableImages : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableImages(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "images"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiImgName,
 | 
			
		||||
 | 
			
		||||
         fiInsSp,
 | 
			
		||||
         fiUpdSp,
 | 
			
		||||
         fiImage,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableEvent
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableEvents : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableEvents(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields, indices) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "events"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiEventId,
 | 
			
		||||
         fiChannelId,
 | 
			
		||||
 | 
			
		||||
         fiMasterId,
 | 
			
		||||
         fiUseId,
 | 
			
		||||
 | 
			
		||||
         fiSource,
 | 
			
		||||
         fiFileRef,
 | 
			
		||||
         fiInsSp,
 | 
			
		||||
         fiUpdSp,
 | 
			
		||||
         fiUpdFlg,           // update flag
 | 
			
		||||
         fiDelFlg,           // deletion flag
 | 
			
		||||
 | 
			
		||||
         fiTableId,
 | 
			
		||||
         fiVersion,
 | 
			
		||||
         fiTitle,
 | 
			
		||||
         fiCompTitle,        // compressed (without whitespace and special characters)
 | 
			
		||||
         fiShortText,
 | 
			
		||||
         fiCompShortText,    // compressed (without whitespace and special characters)
 | 
			
		||||
         fiLongDescription,
 | 
			
		||||
         fiStartTime,
 | 
			
		||||
         fiDuration,
 | 
			
		||||
         fiParentalRating,
 | 
			
		||||
         fiVps,
 | 
			
		||||
         fiDescription,      // view field, not stored!
 | 
			
		||||
 | 
			
		||||
         fiShortDescription,
 | 
			
		||||
         fiActor,
 | 
			
		||||
         fiAudio,
 | 
			
		||||
         fiCategory,
 | 
			
		||||
         fiCountry,
 | 
			
		||||
         fiDirector,
 | 
			
		||||
         fiFlags,
 | 
			
		||||
         fiGenre,
 | 
			
		||||
         fiInfo,
 | 
			
		||||
         fiMusic,
 | 
			
		||||
         fiProducer,
 | 
			
		||||
         fiScreenplay,
 | 
			
		||||
         fiShortreview,
 | 
			
		||||
         fiTipp,
 | 
			
		||||
         fiTopic,
 | 
			
		||||
         fiYear,
 | 
			
		||||
         fiRating,
 | 
			
		||||
         fiFsk,
 | 
			
		||||
         fiMovieid,
 | 
			
		||||
         fiModerator,
 | 
			
		||||
         fiOther,
 | 
			
		||||
         fiGuest,
 | 
			
		||||
         fiCamera,
 | 
			
		||||
 | 
			
		||||
         fiExtEpNum,
 | 
			
		||||
         fiImageCount,
 | 
			
		||||
 | 
			
		||||
         fiEpisode,
 | 
			
		||||
         fiEpisodePart,
 | 
			
		||||
         fiEpisodeLang,
 | 
			
		||||
 | 
			
		||||
         fiScrSeriesId,
 | 
			
		||||
         fiScrSeriesEpisode,
 | 
			
		||||
         fiScrMovieId,
 | 
			
		||||
         fiScrSp,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef* toField(const char* name);      
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
      static IndexDef indices[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableComponent
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableComponents : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableComponents(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "components"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiEventId,
 | 
			
		||||
         fiChannelId,
 | 
			
		||||
         fiStream,
 | 
			
		||||
         fiType,
 | 
			
		||||
         fiLang,
 | 
			
		||||
         fiDescription,
 | 
			
		||||
 | 
			
		||||
         fiInsSp,
 | 
			
		||||
         fiUpdSp
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableEpisode
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableEpisodes : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableEpisodes(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields, indices) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "episodes"; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         // primary key 
 | 
			
		||||
 | 
			
		||||
         fiCompName,      // compressed name (without whitespace and special characters)
 | 
			
		||||
         fiCompPartName,  //      "      "       "
 | 
			
		||||
         fiLang,          // "de", "en", ...
 | 
			
		||||
 | 
			
		||||
         fiInsSp,
 | 
			
		||||
         fiUpdSp,
 | 
			
		||||
         fiLink,
 | 
			
		||||
 | 
			
		||||
         // episode data 
 | 
			
		||||
 | 
			
		||||
         fiShortName,
 | 
			
		||||
         fiEpisodeName,   // episode name (fielname without path and suffix)
 | 
			
		||||
 | 
			
		||||
         // part data
 | 
			
		||||
 | 
			
		||||
         fiPartName,      // part name
 | 
			
		||||
         fiSeason,
 | 
			
		||||
         fiPart,
 | 
			
		||||
         fiParts,
 | 
			
		||||
         fiNumber,
 | 
			
		||||
 | 
			
		||||
         fiExtraCol1,
 | 
			
		||||
         fiExtraCol2,
 | 
			
		||||
         fiExtraCol3,
 | 
			
		||||
         fiComment,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
      static IndexDef indices[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableChannelMap
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableChannelMap : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableChannelMap(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields, indices) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "channelmap"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiExternalId,   // 
 | 
			
		||||
         fiChannelId,    // 
 | 
			
		||||
         fiSource,
 | 
			
		||||
 | 
			
		||||
         fiChannelName,
 | 
			
		||||
 | 
			
		||||
         fiVps,
 | 
			
		||||
         fiMerge,
 | 
			
		||||
         fiMergeSp,
 | 
			
		||||
 | 
			
		||||
         fiInsSp,
 | 
			
		||||
         fiUpdSp,
 | 
			
		||||
         fiUpdFlg,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
      static IndexDef indices[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableVdr
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableVdrs : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableVdrs(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "vdrs"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiUuid,
 | 
			
		||||
 | 
			
		||||
         fiInsSp,
 | 
			
		||||
         fiUpdSp,
 | 
			
		||||
 | 
			
		||||
         fiName,
 | 
			
		||||
         fiVersion,
 | 
			
		||||
         fiDbApi,
 | 
			
		||||
         fiLastUpdate,
 | 
			
		||||
         fiNextUpdate,
 | 
			
		||||
         fiState,
 | 
			
		||||
         fiMaster,
 | 
			
		||||
         fiIp,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableParameters
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableParameters : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableParameters(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "parameters"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiOwner,
 | 
			
		||||
         fiName,
 | 
			
		||||
 | 
			
		||||
         fiInsSp,
 | 
			
		||||
         fiUpdSp,
 | 
			
		||||
 | 
			
		||||
         fiValue,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// cTableAnalyse
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableAnalyse : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableAnalyse(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields, indices) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "analyse"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiChannelId,   
 | 
			
		||||
         fiVdrMasterId, 
 | 
			
		||||
         fiVdrEventId,  
 | 
			
		||||
 | 
			
		||||
         fiVdrStartTime,
 | 
			
		||||
         fiVdrDuration, 
 | 
			
		||||
         fiVdrTitle,    
 | 
			
		||||
         fiVdrShortText,
 | 
			
		||||
         
 | 
			
		||||
         fiExtMasterId, 
 | 
			
		||||
         fiExtEventId,  
 | 
			
		||||
         fiExtStartTime,
 | 
			
		||||
         fiExtDuration, 
 | 
			
		||||
         fiExtTitle,    
 | 
			
		||||
         fiExtShortText,
 | 
			
		||||
         fiExtEpisode,
 | 
			
		||||
         fiExtMerge,
 | 
			
		||||
         fiExiImages,
 | 
			
		||||
 | 
			
		||||
         fiLvMin,
 | 
			
		||||
         fiRank,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
      static IndexDef indices[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// cTableSnapshot
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableSnapshot : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableSnapshot(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields, indices) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "snapshot"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiChannelId,    
 | 
			
		||||
         fiSource,
 | 
			
		||||
         fiVdrMasterId,  
 | 
			
		||||
         fiEventId,      
 | 
			
		||||
         fiUseId,        
 | 
			
		||||
         fiStartTime,    
 | 
			
		||||
         fiDuration,     
 | 
			
		||||
         fiTitle,        
 | 
			
		||||
         fiCompTitle,    
 | 
			
		||||
         fiShortText,
 | 
			
		||||
         fiCompShortText,
 | 
			
		||||
         fiUpdsp,
 | 
			
		||||
         fiEpisode,
 | 
			
		||||
         fiMerge,
 | 
			
		||||
         fiImages,
 | 
			
		||||
         
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
      static IndexDef indices[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableSeries
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableSeries : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableSeries(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields, indices) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "series"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiSeriesId,
 | 
			
		||||
 | 
			
		||||
         fiSeriesName,
 | 
			
		||||
         fiSeriesLastScraped,
 | 
			
		||||
         fiSeriesLastUpdated,
 | 
			
		||||
         fiSeriesOverview,
 | 
			
		||||
         fiSeriesFirstAired,
 | 
			
		||||
         fiSeriesNetwork,
 | 
			
		||||
         fiSeriesIMDBId,
 | 
			
		||||
         fiSeriesGenre,
 | 
			
		||||
         fiSeriesRating,
 | 
			
		||||
         fiSeriesStatus,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef* toField(const char* name);      
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
      static IndexDef indices[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableSeriesEpisode
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableSeriesEpisode : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableSeriesEpisode(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields, indices) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "series_episode"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiEpisodeId,
 | 
			
		||||
 | 
			
		||||
         fiEpisodeNumber,
 | 
			
		||||
         fiSeasonNumber,
 | 
			
		||||
         fiEpisodeName,
 | 
			
		||||
         fiEpisodeOverview,
 | 
			
		||||
         fiEpisodeFirstAired,
 | 
			
		||||
         fiEpisodeGuestStars,
 | 
			
		||||
         fiEpisodeRating,
 | 
			
		||||
         fiEpisodeLastUpdated,
 | 
			
		||||
         fiSeriesId,   
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef* toField(const char* name);      
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
      static IndexDef indices[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableSeriesMedia
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableSeriesMedia : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableSeriesMedia(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields, indices) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "series_media"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiSeriesId,
 | 
			
		||||
         fiSeasonNumber,
 | 
			
		||||
         fiEpisodeId,
 | 
			
		||||
         fiActorId,
 | 
			
		||||
         fiMediaType,
 | 
			
		||||
 | 
			
		||||
         fiMediaUrl,
 | 
			
		||||
         fiMediaWidth,
 | 
			
		||||
         fiMediaHeight,
 | 
			
		||||
         fiMediaRating,
 | 
			
		||||
         fiMediaContent,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef* toField(const char* name);      
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
      static IndexDef indices[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableSeriesActor
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableSeriesActor : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableSeriesActor(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields, indices) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "series_actor"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiActorId,
 | 
			
		||||
 | 
			
		||||
         fiActorName,
 | 
			
		||||
         fiActorRole,
 | 
			
		||||
         fiSortOrder,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef* toField(const char* name);      
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
      static IndexDef indices[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableMovies
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableMovies : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableMovies(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields, indices) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "movie"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiMovieId,
 | 
			
		||||
 | 
			
		||||
         fiTitle,
 | 
			
		||||
         fiOriginalTitle,
 | 
			
		||||
         fiTagline,
 | 
			
		||||
         fiOverview,
 | 
			
		||||
         fiIsAdult,
 | 
			
		||||
         fiCollectionId,
 | 
			
		||||
         fiCollectionName,
 | 
			
		||||
         fiBudget,
 | 
			
		||||
         fiRevenue,
 | 
			
		||||
         fiGenres,
 | 
			
		||||
         fiHomepage,
 | 
			
		||||
         fiReleaaseDate,
 | 
			
		||||
         fiRuntime,
 | 
			
		||||
         fiPopularity,
 | 
			
		||||
         fiVoteAverage,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef* toField(const char* name);      
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
      static IndexDef indices[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableMovieActor
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableMovieActor : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableMovieActor(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields, indices) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "movie_actor"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiActorId,
 | 
			
		||||
 | 
			
		||||
         fiActorName,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef* toField(const char* name);      
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
      static IndexDef indices[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableMovieActors
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableMovieActors : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableMovieActors(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields, indices) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "movie_actors"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiMovieId,
 | 
			
		||||
         fiActorId,
 | 
			
		||||
 | 
			
		||||
         fiRole,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef* toField(const char* name);      
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
      static IndexDef indices[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableMovieMedia
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableMovieMedia : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableMovieMedia(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields, indices) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "movie_media"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiMovieId,
 | 
			
		||||
         fiActorId,
 | 
			
		||||
         fiMediaType,
 | 
			
		||||
 | 
			
		||||
         fiMediaUrl,
 | 
			
		||||
         fiMediaWidth,
 | 
			
		||||
         fiMediaHeight,
 | 
			
		||||
         fiMediaContent,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef* toField(const char* name);      
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
      static IndexDef indices[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// class cTableRecordings
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cTableRecordings : public cDbTable
 | 
			
		||||
{
 | 
			
		||||
   public:
 | 
			
		||||
 | 
			
		||||
      cTableRecordings(cDbConnection* aConnection)
 | 
			
		||||
         : cDbTable(aConnection, fields, indices) { }
 | 
			
		||||
 | 
			
		||||
      virtual const char* TableName()    { return "recordings"; }
 | 
			
		||||
 | 
			
		||||
      enum FieldIndex
 | 
			
		||||
      {
 | 
			
		||||
         fiUuid,
 | 
			
		||||
         fiRecPath,
 | 
			
		||||
         fiRecStart,
 | 
			
		||||
 | 
			
		||||
         fiEventId,
 | 
			
		||||
         fiChannelId,
 | 
			
		||||
         fiScrapInfoMovieId,
 | 
			
		||||
         fiScrapInfoSeriesId,
 | 
			
		||||
         fiScrapInfoEpisodeId,
 | 
			
		||||
         fiScrapNew,
 | 
			
		||||
         fiRecTitle,
 | 
			
		||||
         fiRecSubTitle,
 | 
			
		||||
         fiRecDuration,
 | 
			
		||||
         fiMovieId,
 | 
			
		||||
         fiSeriesId,
 | 
			
		||||
         fiEpisodeId,
 | 
			
		||||
 | 
			
		||||
         fiCount
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      static FieldDef* toField(const char* name);      
 | 
			
		||||
      static FieldDef fields[];
 | 
			
		||||
      static IndexDef indices[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif //__TABLEDEF_H
 | 
			
		||||
							
								
								
									
										130
									
								
								moviedbmovie.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								moviedbmovie.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
#define __STL_CONFIG_H
 | 
			
		||||
#include "lib/common.h"
 | 
			
		||||
#include "moviedbmovie.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
cMovieDbMovie::cMovieDbMovie(void) {
 | 
			
		||||
    title = "";
 | 
			
		||||
    originalTitle = "";
 | 
			
		||||
    tagline = "";
 | 
			
		||||
    overview = "";
 | 
			
		||||
    adult = false;
 | 
			
		||||
    collectionID = 0;
 | 
			
		||||
    collectionName = "";
 | 
			
		||||
    budget = 0;
 | 
			
		||||
    revenue = 0;
 | 
			
		||||
    genres = "";
 | 
			
		||||
    homepage = "";
 | 
			
		||||
    imdbid = "";
 | 
			
		||||
    releaseDate = "";
 | 
			
		||||
    runtime = 0;
 | 
			
		||||
    popularity = 0.0;
 | 
			
		||||
    voteAverage = 0.0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cMovieDbMovie::~cMovieDbMovie() {
 | 
			
		||||
    for (map<int, cMovieActor*>::iterator it = actors.begin(); it != actors.end(); it++) {
 | 
			
		||||
        cMovieActor *a = (cMovieActor*)it->second;
 | 
			
		||||
        delete a;
 | 
			
		||||
    }
 | 
			
		||||
    for (map<int, cMovieMedia*>::iterator it = medias.begin(); it != medias.end(); it++) {
 | 
			
		||||
        cMovieMedia *m = (cMovieMedia*)it->second;
 | 
			
		||||
        delete m;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cMovieDbMovie::InsertMedia(cMovieMedia *media) {
 | 
			
		||||
    medias.insert(pair<int, cMovieMedia*>(media->mediaType, media));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cMovieDbMovie::InsertActor(cMovieActor *actor) {
 | 
			
		||||
    cMovieMedia *m = new cMovieMedia();
 | 
			
		||||
    actor->actorThumb = m;
 | 
			
		||||
    actors.insert(pair<int, cMovieActor*>(actor->id, actor));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vector<int> cMovieDbMovie::GetActorIDs(void) {
 | 
			
		||||
    vector<int> IDs;
 | 
			
		||||
    for (map<int, cMovieActor*>::iterator it = actors.begin(); it != actors.end(); it++) {
 | 
			
		||||
        cMovieActor *a = it->second;
 | 
			
		||||
        IDs.push_back(a->id);
 | 
			
		||||
    }
 | 
			
		||||
    return IDs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cMovieDbMovie::SetActorThumbSize(int actorId, int imgWidth, int imgHeight) {
 | 
			
		||||
    map<int, cMovieActor*>::iterator hit = actors.find(actorId);
 | 
			
		||||
    if (hit != actors.end()) {
 | 
			
		||||
        cMovieActor *a = hit->second;
 | 
			
		||||
        if (!a->actorThumb)
 | 
			
		||||
            return;
 | 
			
		||||
        cMovieMedia *thumb = a->actorThumb;
 | 
			
		||||
        thumb->width = imgWidth;
 | 
			
		||||
        thumb->height = imgHeight;
 | 
			
		||||
        thumb->mediaType = mmActorThumb;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cMovieDbMovie::SetActorPath(int actorId, string path) {
 | 
			
		||||
    map<int, cMovieActor*>::iterator hit = actors.find(actorId);
 | 
			
		||||
    if (hit != actors.end()) {
 | 
			
		||||
        cMovieActor *a = hit->second;
 | 
			
		||||
        if (!a->actorThumb)
 | 
			
		||||
            return;
 | 
			
		||||
        a->actorThumb->path = path;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cMovieDbMovie::GetMedia(mediaMovies mediatype, cTvMedia *p) {
 | 
			
		||||
    map<int, cMovieMedia*>::iterator hit = medias.find(mediatype);
 | 
			
		||||
    if (hit == medias.end())
 | 
			
		||||
        return false;
 | 
			
		||||
    cMovieMedia *pStored = hit->second;
 | 
			
		||||
    p->path = pStored->path;
 | 
			
		||||
    p->width = pStored->width;
 | 
			
		||||
    p->height = pStored->height;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cMovieDbMovie::GetActors(vector<cActor> *a) {
 | 
			
		||||
    for (map<int, cMovieActor*>::iterator it = actors.begin(); it != actors.end(); it++) {
 | 
			
		||||
        cMovieActor *aStored = it->second;
 | 
			
		||||
        cActor act;
 | 
			
		||||
        act.name = aStored->name;
 | 
			
		||||
        act.role = aStored->role;
 | 
			
		||||
        if (aStored->actorThumb) {
 | 
			
		||||
            act.actorThumb.width = aStored->actorThumb->width;
 | 
			
		||||
            act.actorThumb.height = aStored->actorThumb->height;
 | 
			
		||||
            act.actorThumb.path = aStored->actorThumb->path;
 | 
			
		||||
        }
 | 
			
		||||
        a->push_back(act);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cMovieDbMovie::Dump(void) {
 | 
			
		||||
    tell(0, "--------------------------- Movie Info ----------------------------------");
 | 
			
		||||
    tell(0, "title %s, ID: %d", title.c_str(), id);
 | 
			
		||||
    tell(0, "Orig. Title: %s", originalTitle.c_str());
 | 
			
		||||
    tell(0, "Tagline: %s", tagline.c_str());
 | 
			
		||||
    tell(0, "Overview: %s", overview.c_str());
 | 
			
		||||
    tell(0, "Collection: %s", collectionName.c_str());
 | 
			
		||||
    tell(0, "Genre: %s", genres.c_str());
 | 
			
		||||
    tell(0, "Popularity: %f", popularity);
 | 
			
		||||
    tell(0, "--------------------------- Actors ----------------------------------");
 | 
			
		||||
    for (map<int, cMovieActor*>::iterator it = actors.begin(); it != actors.end(); it++) {
 | 
			
		||||
        cMovieActor *a = it->second;
 | 
			
		||||
        tell(0, "Actor %d, Name: %s, Role %s", a->id, a->name.c_str(), a->role.c_str());
 | 
			
		||||
        if (a->actorThumb) {
 | 
			
		||||
            tell(0, "thmbWidth %d, thmbHeight %d", a->actorThumb->width, a->actorThumb->height);
 | 
			
		||||
            tell(0, "Path %s", a->actorThumb->path.c_str());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    tell(0, "--------------------------- Media ----------------------------------");
 | 
			
		||||
    for (map<int, cMovieMedia*>::iterator it = medias.begin(); it != medias.end(); it++) {
 | 
			
		||||
        cMovieMedia *m = it->second;
 | 
			
		||||
        tell(0, "Media %d", m->mediaType);
 | 
			
		||||
        tell(0, "width %d, height %d", m->width, m->height);
 | 
			
		||||
        tell(0, "Path %s", m->path.c_str());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										98
									
								
								moviedbmovie.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								moviedbmovie.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
#ifndef __TVSCRAPER_MOVIEDBMOVIE_H
 | 
			
		||||
#define __TVSCRAPER_MOVIEDBMOVIE_H
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <set>
 | 
			
		||||
#include <utility>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include "services.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
enum mediaMovies {
 | 
			
		||||
     mmPoster,
 | 
			
		||||
     mmFanart,
 | 
			
		||||
     mmCollectionPoster,
 | 
			
		||||
     mmCollectionFanart,
 | 
			
		||||
     mmActorThumb,
 | 
			
		||||
     mmPosterThumb,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// --- cMovieMedia -------------------------------------------------------------
 | 
			
		||||
class cMovieMedia {
 | 
			
		||||
public:
 | 
			
		||||
    cMovieMedia(void) {
 | 
			
		||||
        path = "";
 | 
			
		||||
        mediaType = mmPoster;
 | 
			
		||||
        width = 0;
 | 
			
		||||
        height = 0;
 | 
			
		||||
    };
 | 
			
		||||
    ~cMovieMedia(void) {
 | 
			
		||||
    };
 | 
			
		||||
    string path;
 | 
			
		||||
    int mediaType;
 | 
			
		||||
    int width;
 | 
			
		||||
    int height;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// --- cMovieActor -------------------------------------------------------------
 | 
			
		||||
class cMovieActor {
 | 
			
		||||
public:
 | 
			
		||||
    cMovieActor(void) {
 | 
			
		||||
        id = 0;
 | 
			
		||||
        name = "";
 | 
			
		||||
        role = "";
 | 
			
		||||
        actorThumb = NULL;
 | 
			
		||||
    };
 | 
			
		||||
    ~cMovieActor(void) {
 | 
			
		||||
        if (actorThumb)
 | 
			
		||||
            delete actorThumb;
 | 
			
		||||
    };
 | 
			
		||||
    int id;
 | 
			
		||||
    string name;
 | 
			
		||||
    string role;
 | 
			
		||||
    cMovieMedia *actorThumb;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// --- cMovieDbMovie -------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
class cMovieDbMovie {
 | 
			
		||||
private:
 | 
			
		||||
    map<int, cMovieActor*> actors;
 | 
			
		||||
    map<int, cMovieMedia*> medias;
 | 
			
		||||
public:
 | 
			
		||||
    cMovieDbMovie(void);
 | 
			
		||||
    virtual ~cMovieDbMovie(void);
 | 
			
		||||
    int id;
 | 
			
		||||
    string title;
 | 
			
		||||
    string originalTitle;
 | 
			
		||||
    string tagline;    
 | 
			
		||||
    string overview;
 | 
			
		||||
    bool adult;
 | 
			
		||||
    int collectionID;
 | 
			
		||||
    string collectionName;
 | 
			
		||||
    int budget;
 | 
			
		||||
    int revenue;
 | 
			
		||||
    string genres;
 | 
			
		||||
    string homepage;
 | 
			
		||||
    string imdbid;
 | 
			
		||||
    string releaseDate;
 | 
			
		||||
    int runtime;
 | 
			
		||||
    float popularity;
 | 
			
		||||
    float voteAverage;
 | 
			
		||||
    void InsertActor(cMovieActor *actor);
 | 
			
		||||
    void InsertMedia(cMovieMedia *media);
 | 
			
		||||
    vector<int> GetActorIDs(void);
 | 
			
		||||
    void SetActorThumbSize(int actorId, int imgWidth, int imgHeight);
 | 
			
		||||
    void SetActorPath(int actorId, string path);
 | 
			
		||||
    //Getter for Serivice Calls
 | 
			
		||||
    bool GetMedia(mediaMovies mediatype, cTvMedia *p);
 | 
			
		||||
    void GetActors(vector<cActor> *a);
 | 
			
		||||
    void Dump();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif //__TVSCRAPER_TVDBSERIES_H
 | 
			
		||||
							
								
								
									
										65
									
								
								po/de_DE.po
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								po/de_DE.po
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 | 
			
		||||
# This file is distributed under the same license as the PACKAGE package.
 | 
			
		||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
 | 
			
		||||
#
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: vdr-scraper2vdr 0.0.1\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: <see README>\n"
 | 
			
		||||
"POT-Creation-Date: 2014-03-30 14:37+0200\n"
 | 
			
		||||
"PO-Revision-Date: 2014-03-30 18:30+0100\n"
 | 
			
		||||
"Last-Translator: 3PO\n"
 | 
			
		||||
"Language-Team: German <vdr@linuxtv.org>\n"
 | 
			
		||||
"Language: de\n"
 | 
			
		||||
"MIME-Version: 1.0\n"
 | 
			
		||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
			
		||||
"Content-Transfer-Encoding: 8bit\n"
 | 
			
		||||
 | 
			
		||||
msgid "Update Scraper Information from Database"
 | 
			
		||||
msgstr "Filme und Serien aus Datenbank aktualisieren"
 | 
			
		||||
 | 
			
		||||
msgid "Update Scraper Recordings Information from Database"
 | 
			
		||||
msgstr "Aufnahmen aus Datenbank aktualisieren"
 | 
			
		||||
 | 
			
		||||
msgid "Scan for new recordings in video directory"
 | 
			
		||||
msgstr "Videoverzeichnis nach neuen Aufnahmen scannen"
 | 
			
		||||
 | 
			
		||||
msgid "Scan for new or updated scrapinfo files"
 | 
			
		||||
msgstr "Nach neuen oder geänderten scrapinfo Dateien suchen"
 | 
			
		||||
 | 
			
		||||
msgid "Cleanup Recordings in Database"
 | 
			
		||||
msgstr "Aufnahmen in Datenbank bereinigen"
 | 
			
		||||
 | 
			
		||||
msgid "Updating Scraper EPG Information from Database"
 | 
			
		||||
msgstr "Filme und Serien werden aus Datenbank aktualisieren"
 | 
			
		||||
 | 
			
		||||
msgid "Updating Scraper Recordings Information from Database"
 | 
			
		||||
msgstr "Aufnahmen werden aus Datenbank aktualisieren"
 | 
			
		||||
 | 
			
		||||
msgid "Scanning for new recordings in video directory"
 | 
			
		||||
msgstr "Scanne Videoverzeichnis nach neuen Aufnahmen"
 | 
			
		||||
 | 
			
		||||
msgid "Scanning for new or updated scrapinfo files"
 | 
			
		||||
msgstr "Suche nach neuen oder geänderten scrapinfo Dateien"
 | 
			
		||||
 | 
			
		||||
msgid "Cleaning up Recordings in Database"
 | 
			
		||||
msgstr "Bereinige Aufnahmen in Datenbank"
 | 
			
		||||
 | 
			
		||||
msgid "Show Main Menu Entry"
 | 
			
		||||
msgstr "Hauptmenüeintrag anzeigen"
 | 
			
		||||
 | 
			
		||||
msgid "MySQL Host"
 | 
			
		||||
msgstr "MySQL Host"
 | 
			
		||||
 | 
			
		||||
msgid "MySQL Port"
 | 
			
		||||
msgstr "MySQL Port"
 | 
			
		||||
 | 
			
		||||
msgid "MySQL Database Name"
 | 
			
		||||
msgstr "MySQL Datenbannk Name"
 | 
			
		||||
 | 
			
		||||
msgid "MySQL User"
 | 
			
		||||
msgstr "MySQL Benutzer"
 | 
			
		||||
 | 
			
		||||
msgid "MySQL Password"
 | 
			
		||||
msgstr "MySQL Passwort"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										249
									
								
								scraper2vdr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								scraper2vdr.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,249 @@
 | 
			
		||||
/*
 | 
			
		||||
 * scraper2vdr.c: A plugin for the Video Disk Recorder
 | 
			
		||||
 *
 | 
			
		||||
 * See the README file for copyright information and how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id$
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "scraper2vdr.h"
 | 
			
		||||
 | 
			
		||||
#if defined (APIVERSNUM) && (APIVERSNUM < 10600)
 | 
			
		||||
# error VDR API versions < 1.6.0 are not supported !
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Plugin Main Menu
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cScraper2VdrPluginMenu : public cOsdMenu {
 | 
			
		||||
    public:
 | 
			
		||||
        cScraper2VdrPluginMenu(const char* title, cUpdate *update);
 | 
			
		||||
        virtual ~cScraper2VdrPluginMenu() { };
 | 
			
		||||
        virtual eOSState ProcessKey(eKeys key);
 | 
			
		||||
    protected:
 | 
			
		||||
        cUpdate *update;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cScraper2VdrPluginMenu::cScraper2VdrPluginMenu(const char* title, cUpdate *update) : cOsdMenu(title) {
 | 
			
		||||
    this->update = update;
 | 
			
		||||
    Clear();
 | 
			
		||||
    cOsdMenu::Add(new cOsdItem(tr("Update Scraper Information from Database")));
 | 
			
		||||
    cOsdMenu::Add(new cOsdItem(tr("Update Scraper Recordings Information from Database")));
 | 
			
		||||
    cOsdMenu::Add(new cOsdItem(tr("Scan for new recordings in video directory")));
 | 
			
		||||
    cOsdMenu::Add(new cOsdItem(tr("Scan for new or updated scrapinfo files")));
 | 
			
		||||
    cOsdMenu::Add(new cOsdItem(tr("Cleanup Recordings in Database")));
 | 
			
		||||
    SetHelp(0, 0, 0,0);
 | 
			
		||||
    Display();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Process Key
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
eOSState cScraper2VdrPluginMenu::ProcessKey(eKeys key) {
 | 
			
		||||
   eOSState state = cOsdMenu::ProcessKey(key);
 | 
			
		||||
 | 
			
		||||
    if (state != osUnknown)
 | 
			
		||||
        return state;
 | 
			
		||||
 | 
			
		||||
    switch (key) {
 | 
			
		||||
        case kOk: {
 | 
			
		||||
            if (Current() == 0) {
 | 
			
		||||
                Skins.Message(mtInfo, tr("Updating Scraper EPG Information from Database"));
 | 
			
		||||
                update->ForceUpdate();
 | 
			
		||||
            } else if (Current() == 1) {
 | 
			
		||||
                Skins.Message(mtInfo, tr("Updating Scraper Recordings Information from Database"));
 | 
			
		||||
                update->ForceRecordingUpdate();
 | 
			
		||||
            } else if (Current() == 2) {
 | 
			
		||||
                Skins.Message(mtInfo, tr("Scanning for new recordings in video directory"));
 | 
			
		||||
                update->ForceVideoDirUpdate();
 | 
			
		||||
            } else if (Current() == 3) {
 | 
			
		||||
                Skins.Message(mtInfo, tr("Scanning for new or updated scrapinfo files"));
 | 
			
		||||
                update->ForceScrapInfoUpdate();
 | 
			
		||||
            } else if (Current() == 4) {
 | 
			
		||||
                Skins.Message(mtInfo, tr("Cleaning up Recordings in Database"));
 | 
			
		||||
                update->TriggerCleanRecordingsDB();
 | 
			
		||||
            }
 | 
			
		||||
            return osEnd;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
    return state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// cPluginScraper2vdr
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
cPluginScraper2vdr::cPluginScraper2vdr(void) {
 | 
			
		||||
    cDbConnection::init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cPluginScraper2vdr::~cPluginScraper2vdr() {
 | 
			
		||||
    delete update;
 | 
			
		||||
    delete scrapManager;
 | 
			
		||||
    cDbConnection::exit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *cPluginScraper2vdr::CommandLineHelp(void) {
 | 
			
		||||
    return
 | 
			
		||||
      "  -i <IMAGEDIR>, --imagedir=<IMAGEDIR> Set directory where images are stored\n"
 | 
			
		||||
      "  -m <MODE>, --mode=<MODE> mode can be client or headless, see README\n";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cPluginScraper2vdr::ProcessArgs(int argc, char *argv[]) {
 | 
			
		||||
    static const struct option long_options[] = {
 | 
			
		||||
        { "imagedir", required_argument, NULL, 'i' },
 | 
			
		||||
        { "mode", required_argument, NULL, 'm' },
 | 
			
		||||
        { 0, 0, 0, 0 }
 | 
			
		||||
    };
 | 
			
		||||
    int c;
 | 
			
		||||
    while ((c = getopt_long(argc, argv, "i:m:", long_options, NULL)) != -1) {
 | 
			
		||||
        switch (c) {
 | 
			
		||||
            case 'i':
 | 
			
		||||
                config.SetImageDir(optarg);
 | 
			
		||||
                break;
 | 
			
		||||
            case 'm':
 | 
			
		||||
                config.SetMode(optarg);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cPluginScraper2vdr::Initialize(void) {
 | 
			
		||||
    config.SetUuid(this);
 | 
			
		||||
    config.SetDefaultImageDir();
 | 
			
		||||
    scrapManager = new cScrapManager();
 | 
			
		||||
    update = new cUpdate(scrapManager);
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cPluginScraper2vdr::Start(void) {
 | 
			
		||||
    update->Start();
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cPluginScraper2vdr::Stop(void) {
 | 
			
		||||
    update->Stop();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cPluginScraper2vdr::Housekeeping(void) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cPluginScraper2vdr::MainThreadHook(void) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cString cPluginScraper2vdr::Active(void) {
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
time_t cPluginScraper2vdr::WakeupTime(void) {
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cOsdObject *cPluginScraper2vdr::MainMenuAction(void) {
 | 
			
		||||
    if (config.mainMenuEntry == 1)
 | 
			
		||||
        return new cScraper2VdrPluginMenu("Scraper2Vdr", update);
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cMenuSetupPage *cPluginScraper2vdr::SetupMenu(void) {
 | 
			
		||||
    return new cScraper2VdrSetup(update);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cPluginScraper2vdr::SetupParse(const char *Name, const char *Value) {
 | 
			
		||||
    return config.SetupParse(Name, Value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cPluginScraper2vdr::Service(const char *Id, void *Data) {
 | 
			
		||||
    if (Data == NULL)
 | 
			
		||||
        return false;
 | 
			
		||||
    if (strcmp(Id, "GetEventType") == 0) {
 | 
			
		||||
        ScraperGetEventType* call = (ScraperGetEventType*) Data;
 | 
			
		||||
        if (!call->event && !call->recording)
 | 
			
		||||
            return false;
 | 
			
		||||
        return scrapManager->GetEventType(call);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (strcmp(Id, "GetSeries") == 0) {
 | 
			
		||||
        cSeries* call = (cSeries*) Data;
 | 
			
		||||
        if (call->seriesId == 0)
 | 
			
		||||
            return false;
 | 
			
		||||
        return scrapManager->GetSeries(call);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (strcmp(Id, "GetMovie") == 0) {
 | 
			
		||||
        cMovie* call = (cMovie*) Data;
 | 
			
		||||
        if (call->movieId == 0)
 | 
			
		||||
            return false;
 | 
			
		||||
        return scrapManager->GetMovie(call);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (strcmp(Id, "GetPosterBanner") == 0) {
 | 
			
		||||
        ScraperGetPosterBanner* call = (ScraperGetPosterBanner*) Data;
 | 
			
		||||
        if (!call->event)
 | 
			
		||||
            return false;
 | 
			
		||||
        return scrapManager->GetPosterBanner(call);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (strcmp(Id, "GetPoster") == 0) {
 | 
			
		||||
        ScraperGetPoster* call = (ScraperGetPoster*) Data;
 | 
			
		||||
        if (!call->event && !call->recording)
 | 
			
		||||
            return false;
 | 
			
		||||
        return scrapManager->GetPoster(call);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (strcmp(Id, "GetPosterThumb") == 0) {
 | 
			
		||||
        ScraperGetPosterThumb* call = (ScraperGetPosterThumb*) Data;
 | 
			
		||||
        if (!call->event && !call->recording)
 | 
			
		||||
            return false;
 | 
			
		||||
        return scrapManager->GetPosterThumb(call);  
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char **cPluginScraper2vdr::SVDRPHelpPages(void) {
 | 
			
		||||
    static const char *HelpPages[] = {
 | 
			
		||||
      "UPDT\n"
 | 
			
		||||
      "    Load all series and movies for events from database.",
 | 
			
		||||
      "UPDR\n"
 | 
			
		||||
      "    Load recordings from database.",
 | 
			
		||||
      "SCVD\n"
 | 
			
		||||
      "    Trigger scan fornew recordings in video directory.",
 | 
			
		||||
      "SCSI\n"
 | 
			
		||||
      "    Trigger scan for scrapinfo files in video directory.",
 | 
			
		||||
      "CRDB\n"
 | 
			
		||||
      "    Trigger cleanup of recordings database.",
 | 
			
		||||
      0
 | 
			
		||||
    };
 | 
			
		||||
    return HelpPages;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cString cPluginScraper2vdr::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode) {
 | 
			
		||||
    if (strcasecmp(Command, "UPDT") == 0) {
 | 
			
		||||
        update->ForceUpdate();
 | 
			
		||||
        return "SCRAPER2VDR full update from database forced.";
 | 
			
		||||
    } else if (strcasecmp(Command, "UPDR") == 0) {
 | 
			
		||||
        update->ForceRecordingUpdate();
 | 
			
		||||
        return "SCRAPER2VDR scanning of recordings in database triggered.";
 | 
			
		||||
    } else if (strcasecmp(Command, "SCVD") == 0) {
 | 
			
		||||
        update->ForceVideoDirUpdate();
 | 
			
		||||
        return "SCRAPER2VDR scan for new recordings in video dir triggered.";
 | 
			
		||||
    } else if (strcasecmp(Command, "SCSI") == 0) {
 | 
			
		||||
        update->ForceScrapInfoUpdate();
 | 
			
		||||
        return "SCRAPER2VDR scan for new or updated scrapinfo files triggered.";
 | 
			
		||||
    } else if (strcasecmp(Command, "CRDB") == 0) {
 | 
			
		||||
        update->TriggerCleanRecordingsDB();
 | 
			
		||||
        return "SCRAPER2VDR cleanup of recording DB triggered.";
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VDRPLUGINCREATOR(cPluginScraper2vdr); // Don't touch this!
 | 
			
		||||
							
								
								
									
										57
									
								
								scraper2vdr.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								scraper2vdr.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
#ifndef __SCRAPER2VDR_H
 | 
			
		||||
#define __SCRAPER2VDR_H
 | 
			
		||||
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <vdr/plugin.h>
 | 
			
		||||
#include "lib/common.h"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "setup.h"
 | 
			
		||||
#include "scrapmanager.h"
 | 
			
		||||
#include "update.h"
 | 
			
		||||
#include "services.h"
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Constants
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
static const char *VERSION        = "0.0.1";
 | 
			
		||||
static const char *DESCRIPTION    = "'scraper2vdr' plugin";
 | 
			
		||||
static const char *MAINMENUENTRY  = "Scraper2Vdr";
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// Globals
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
cScraper2VdrConfig config;
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
// cPluginScraper2vdr
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
 | 
			
		||||
class cPluginScraper2vdr : public cPlugin {
 | 
			
		||||
private:
 | 
			
		||||
    cScrapManager *scrapManager;
 | 
			
		||||
    cUpdate *update;
 | 
			
		||||
public:
 | 
			
		||||
    cPluginScraper2vdr(void);
 | 
			
		||||
    virtual ~cPluginScraper2vdr();
 | 
			
		||||
    virtual const char *Version(void) { return VERSION; }
 | 
			
		||||
    virtual const char *Description(void) { return DESCRIPTION; }
 | 
			
		||||
    virtual const char *CommandLineHelp(void);
 | 
			
		||||
    virtual bool ProcessArgs(int argc, char *argv[]);
 | 
			
		||||
    virtual bool Initialize(void);
 | 
			
		||||
    virtual bool Start(void);
 | 
			
		||||
    virtual void Stop(void);
 | 
			
		||||
    virtual void Housekeeping(void);
 | 
			
		||||
    virtual void MainThreadHook(void);
 | 
			
		||||
    virtual cString Active(void);
 | 
			
		||||
    virtual time_t WakeupTime(void);
 | 
			
		||||
    virtual const char *MainMenuEntry(void) { return (config.mainMenuEntry)?MAINMENUENTRY:NULL; }
 | 
			
		||||
    virtual cOsdObject *MainMenuAction(void);
 | 
			
		||||
    virtual cMenuSetupPage *SetupMenu(void);
 | 
			
		||||
    virtual bool SetupParse(const char *Name, const char *Value);
 | 
			
		||||
    virtual bool Service(const char *Id, void *Data = NULL);
 | 
			
		||||
    virtual const char **SVDRPHelpPages(void);
 | 
			
		||||
    virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
#endif // __SCRAPER2VDR_H
 | 
			
		||||
							
								
								
									
										503
									
								
								scrapmanager.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										503
									
								
								scrapmanager.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,503 @@
 | 
			
		||||
#define __STL_CONFIG_H
 | 
			
		||||
#include <vdr/recording.h>
 | 
			
		||||
#include "tools.h"
 | 
			
		||||
#include "scrapmanager.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
bool operator<(const sEventsKey& l, const sEventsKey& r) {
 | 
			
		||||
     if (l.eventId != r.eventId)
 | 
			
		||||
        return (l.eventId < r.eventId);
 | 
			
		||||
     int comp = l.channelId.compare(r.channelId);
 | 
			
		||||
     if (comp < 0)
 | 
			
		||||
        return true;
 | 
			
		||||
     return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool operator<(const sRecordingsKey& l, const sRecordingsKey& r) {
 | 
			
		||||
     if (l.recStart != r.recStart)
 | 
			
		||||
        return (l.recStart < r.recStart);
 | 
			
		||||
     int comp = l.recPath.compare(r.recPath);
 | 
			
		||||
     if (comp < 0)
 | 
			
		||||
        return true;
 | 
			
		||||
     return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cScrapManager::cScrapManager(void) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cScrapManager::~cScrapManager(void) {
 | 
			
		||||
    for (map<int, cTVDBSeries*>::iterator it = series.begin(); it != series.end(); it++) {
 | 
			
		||||
        cTVDBSeries *s = (cTVDBSeries*)it->second;
 | 
			
		||||
        delete s;
 | 
			
		||||
    }
 | 
			
		||||
    series.clear();
 | 
			
		||||
    for (map<int, cMovieDbMovie*>::iterator it = movies.begin(); it != movies.end(); it++) {
 | 
			
		||||
        cMovieDbMovie *m = (cMovieDbMovie*)it->second;
 | 
			
		||||
        delete m;
 | 
			
		||||
    }
 | 
			
		||||
    movies.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cScrapManager::InitIterator(bool isRec) {
 | 
			
		||||
	if (!isRec)
 | 
			
		||||
		eventsIterator = events.begin();
 | 
			
		||||
	else
 | 
			
		||||
		recIterator = recordings.begin();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sEventsValue cScrapManager::GetEventInformation(int eventId, string channelId) {
 | 
			
		||||
	sEventsKey k;
 | 
			
		||||
	k.eventId = eventId;
 | 
			
		||||
	k.channelId = channelId;
 | 
			
		||||
	sEventsValue emptyVal;
 | 
			
		||||
	emptyVal.seriesId = 0;
 | 
			
		||||
	emptyVal.episodeId = 0;
 | 
			
		||||
	emptyVal.movieId = 0;
 | 
			
		||||
	emptyVal.isNew = false;
 | 
			
		||||
	map<sEventsKey, sEventsValue>::iterator hit = events.find(k);
 | 
			
		||||
	if (hit != events.end())
 | 
			
		||||
		return hit->second;
 | 
			
		||||
	return emptyVal;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void cScrapManager::AddEvent(int eventId, string channelId, int seriesId, int episodeId, int movieId) {
 | 
			
		||||
	sEventsKey k;
 | 
			
		||||
	k.eventId = eventId;
 | 
			
		||||
	k.channelId = channelId;
 | 
			
		||||
	sEventsValue v;
 | 
			
		||||
	v.seriesId = seriesId;
 | 
			
		||||
	v.episodeId = episodeId;
 | 
			
		||||
	v.movieId = movieId;
 | 
			
		||||
	v.isNew = true;
 | 
			
		||||
	events.insert(pair<sEventsKey, sEventsValue>(k, v));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cScrapManager::GetNextSeries(bool isRec, int &seriesId, int &episodeId) {
 | 
			
		||||
	bool next = false;
 | 
			
		||||
	if (!isRec) {
 | 
			
		||||
		while (eventsIterator != events.end()) {
 | 
			
		||||
			next = true;
 | 
			
		||||
			sEventsValue ev = eventsIterator->second;
 | 
			
		||||
			if (ev.isNew && (ev.seriesId > 0)) {
 | 
			
		||||
				seriesId = ev.seriesId;
 | 
			
		||||
				episodeId = ev.episodeId;
 | 
			
		||||
				eventsIterator->second.isNew = false;
 | 
			
		||||
				eventsIterator++;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			eventsIterator++;
 | 
			
		||||
			next = false;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		while (recIterator != recordings.end()) {
 | 
			
		||||
			next = true;
 | 
			
		||||
			sEventsValue ev = recIterator->second;
 | 
			
		||||
			if (ev.isNew && (ev.seriesId > 0)) {
 | 
			
		||||
				seriesId = ev.seriesId;
 | 
			
		||||
				episodeId = ev.episodeId;
 | 
			
		||||
				recIterator->second.isNew = false;
 | 
			
		||||
				recIterator++;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			recIterator++;
 | 
			
		||||
			next = false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	return next;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cScrapManager::GetNextMovie(bool isRec, int &movieId) {
 | 
			
		||||
	bool next = false;
 | 
			
		||||
	if (!isRec) {
 | 
			
		||||
		while (eventsIterator != events.end()) {
 | 
			
		||||
			next = true;
 | 
			
		||||
			sEventsValue ev = eventsIterator->second;
 | 
			
		||||
			if (ev.isNew && (ev.movieId > 0)) {
 | 
			
		||||
				movieId = ev.movieId;
 | 
			
		||||
				eventsIterator->second.isNew = false;
 | 
			
		||||
				eventsIterator++;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			eventsIterator++;
 | 
			
		||||
			next = false;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		while (recIterator != recordings.end()) {
 | 
			
		||||
			next = true;
 | 
			
		||||
			sEventsValue ev = recIterator->second;
 | 
			
		||||
			if (ev.isNew && (ev.movieId > 0)) {
 | 
			
		||||
				movieId = ev.movieId;
 | 
			
		||||
				recIterator->second.isNew = false;
 | 
			
		||||
				recIterator++;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			recIterator++;
 | 
			
		||||
			next = false;
 | 
			
		||||
		}		
 | 
			
		||||
	}
 | 
			
		||||
	return next;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cTVDBSeries *cScrapManager::GetSeries(int seriesId) {
 | 
			
		||||
	map<int, cTVDBSeries*>::iterator hit = series.find(seriesId);
 | 
			
		||||
	if (hit == series.end())
 | 
			
		||||
		return NULL;
 | 
			
		||||
	return hit->second;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cMovieDbMovie *cScrapManager::GetMovie(int movieId) {
 | 
			
		||||
	map<int, cMovieDbMovie*>::iterator hit = movies.find(movieId);
 | 
			
		||||
	if (hit == movies.end())
 | 
			
		||||
		return NULL;
 | 
			
		||||
	return hit->second;	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cTVDBSeries *cScrapManager::AddSeries(cTableSeries* tSeries) {
 | 
			
		||||
	cTVDBSeries *s = new cTVDBSeries();
 | 
			
		||||
	s->id = tSeries->getIntValue(cTableSeries::fiSeriesId);
 | 
			
		||||
    s->name = tSeries->getStrValue(cTableSeries::fiSeriesName);
 | 
			
		||||
    s->overview = tSeries->getStrValue(cTableSeries::fiSeriesOverview);
 | 
			
		||||
    s->firstAired = tSeries->getStrValue(cTableSeries::fiSeriesFirstAired);
 | 
			
		||||
    s->network = tSeries->getStrValue(cTableSeries::fiSeriesNetwork);
 | 
			
		||||
    string genre = replaceString(tSeries->getStrValue(cTableSeries::fiSeriesGenre), "|", ", ");
 | 
			
		||||
    s->genre = genre;
 | 
			
		||||
    s->rating = tSeries->getFloatValue(cTableSeries::fiSeriesRating);
 | 
			
		||||
    s->status = tSeries->getStrValue(cTableSeries::fiSeriesStatus);
 | 
			
		||||
    series.insert(pair<int, cTVDBSeries*>(tSeries->getIntValue(cTableSeries::fiSeriesId), s));
 | 
			
		||||
    return s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cMovieDbMovie *cScrapManager::AddMovie(cTableMovies* tMovies) {
 | 
			
		||||
	cMovieDbMovie *m = new cMovieDbMovie();
 | 
			
		||||
	m->id = tMovies->getIntValue(cTableMovies::fiMovieId);
 | 
			
		||||
	m->title = tMovies->getStrValue(cTableMovies::fiTitle);
 | 
			
		||||
    m->originalTitle = tMovies->getStrValue(cTableMovies::fiOriginalTitle);
 | 
			
		||||
    m->tagline = tMovies->getStrValue(cTableMovies::fiTagline);
 | 
			
		||||
    m->overview = tMovies->getStrValue(cTableMovies::fiOverview);
 | 
			
		||||
    m->adult = tMovies->getIntValue(cTableMovies::fiIsAdult);
 | 
			
		||||
    m->collectionName = tMovies->getStrValue(cTableMovies::fiCollectionName);
 | 
			
		||||
    m->budget = tMovies->getIntValue(cTableMovies::fiBudget);
 | 
			
		||||
    m->revenue = tMovies->getIntValue(cTableMovies::fiRevenue);
 | 
			
		||||
    string genre = replaceString(tMovies->getStrValue(cTableMovies::fiGenres), "|", ",");
 | 
			
		||||
    m->genres = genre;
 | 
			
		||||
    m->homepage = tMovies->getStrValue(cTableMovies::fiHomepage);
 | 
			
		||||
    m->releaseDate = tMovies->getStrValue(cTableMovies::fiReleaaseDate);
 | 
			
		||||
    m->runtime = tMovies->getIntValue(cTableMovies::fiRuntime);
 | 
			
		||||
    m->popularity = tMovies->getFloatValue(cTableMovies::fiPopularity);
 | 
			
		||||
    m->voteAverage = tMovies->getFloatValue(cTableMovies::fiVoteAverage);
 | 
			
		||||
    movies.insert(pair<int, cMovieDbMovie*>(tMovies->getIntValue(cTableMovies::fiMovieId), m));
 | 
			
		||||
    return m;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cScrapManager::AddSeriesEpisode(cTVDBSeries *series, cTableSeriesEpisode* tEpisodes) {
 | 
			
		||||
	cTVDBEpisode *e = new cTVDBEpisode();
 | 
			
		||||
	e->id = tEpisodes->getIntValue(cTableSeriesEpisode::fiEpisodeId);
 | 
			
		||||
	e->name = tEpisodes->getStrValue(cTableSeriesEpisode::fiEpisodeName);
 | 
			
		||||
    e->number =  tEpisodes->getIntValue(cTableSeriesEpisode::fiEpisodeNumber);
 | 
			
		||||
    e->season = tEpisodes->getIntValue(cTableSeriesEpisode::fiSeasonNumber);
 | 
			
		||||
    e->overview = tEpisodes->getStrValue(cTableSeriesEpisode::fiEpisodeOverview);
 | 
			
		||||
    e->firstAired = tEpisodes->getStrValue(cTableSeriesEpisode::fiEpisodeFirstAired);
 | 
			
		||||
    string guestStars = replaceString(tEpisodes->getStrValue(cTableSeriesEpisode::fiEpisodeGuestStars), "|", ", ");
 | 
			
		||||
    e->guestStars = guestStars;
 | 
			
		||||
    e->rating = tEpisodes->getFloatValue(cTableSeriesEpisode::fiEpisodeRating);
 | 
			
		||||
    series->InsertEpisode(e);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cScrapManager::AddSeriesActor(cTVDBSeries *series, cTableSeriesActor* tActors) {
 | 
			
		||||
	cTVDBActor *a = new cTVDBActor();
 | 
			
		||||
	a->id = tActors->getIntValue(cTableSeriesActor::fiActorId);
 | 
			
		||||
	a->name = tActors->getStrValue(cTableSeriesActor::fiActorName);
 | 
			
		||||
    a->role =  tActors->getStrValue(cTableSeriesActor::fiActorRole);
 | 
			
		||||
    series->InsertActor(a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cScrapManager::AddMovieMedia(cMovieDbMovie *movie, cTableMovieMedia* tMovieMedia, string path) {
 | 
			
		||||
	cMovieMedia *m = new cMovieMedia();
 | 
			
		||||
	m->mediaType = tMovieMedia->getIntValue(cTableMovieMedia::fiMediaType);
 | 
			
		||||
	m->width = tMovieMedia->getIntValue(cTableMovieMedia::fiMediaWidth);
 | 
			
		||||
	m->height = tMovieMedia->getIntValue(cTableMovieMedia::fiMediaHeight);
 | 
			
		||||
    m->path = path;
 | 
			
		||||
    movie->InsertMedia(m);	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void cScrapManager::AddMovieActor(cMovieDbMovie *movie, cTableMovieActor* tActor, string role) {
 | 
			
		||||
	cMovieActor *a = new cMovieActor();
 | 
			
		||||
	a->id = tActor->getIntValue(cTableMovieActor::fiActorId);
 | 
			
		||||
	a->name = tActor->getStrValue(cTableMovieActor::fiActorName);
 | 
			
		||||
    a->role =  role;
 | 
			
		||||
    movie->InsertActor(a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cScrapManager::AddRecording(int recStart, string recPath, int seriesId, int episodeId, int movieId) {
 | 
			
		||||
	sRecordingsKey k;
 | 
			
		||||
	k.recStart = recStart;
 | 
			
		||||
	k.recPath = recPath;
 | 
			
		||||
	//check if recording already exists
 | 
			
		||||
	map<sRecordingsKey, sEventsValue>::iterator hit = recordings.find(k);
 | 
			
		||||
	if (hit != recordings.end()) {
 | 
			
		||||
		sEventsValue v = hit->second;
 | 
			
		||||
		if ((v.seriesId == seriesId) && (v.episodeId == episodeId) && (v.movieId == movieId))
 | 
			
		||||
			return false;
 | 
			
		||||
		else
 | 
			
		||||
			recordings.erase(hit);
 | 
			
		||||
	}
 | 
			
		||||
	sEventsValue v;
 | 
			
		||||
	v.seriesId = seriesId;
 | 
			
		||||
	v.episodeId = episodeId;
 | 
			
		||||
	v.movieId = movieId;
 | 
			
		||||
	v.isNew = true;
 | 
			
		||||
	recordings.insert(pair<sRecordingsKey, sEventsValue>(k, v));	
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cScrapManager::RecordingExists(int recStart, string recPath) {
 | 
			
		||||
	sRecordingsKey k;
 | 
			
		||||
	k.recStart = recStart;
 | 
			
		||||
	k.recPath = recPath;
 | 
			
		||||
	map<sRecordingsKey, sEventsValue>::iterator hit = recordings.find(k);
 | 
			
		||||
	if (hit != recordings.end())
 | 
			
		||||
		return true;
 | 
			
		||||
	return false;	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cScrapManager::SeriesInUse(int seriesId) {
 | 
			
		||||
	map<int, cTVDBSeries*>::iterator hit = series.find(seriesId);
 | 
			
		||||
	if (hit != series.end())
 | 
			
		||||
		return true;
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cScrapManager::MovieInUse(int movieId) {
 | 
			
		||||
	map<int, cMovieDbMovie*>::iterator hit = movies.find(movieId);
 | 
			
		||||
	if (hit != movies.end())
 | 
			
		||||
		return true;
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cScrapManager::DumpSeries(int num) {
 | 
			
		||||
	int i=0;
 | 
			
		||||
	tell(0, "Dumping first %d series", num);
 | 
			
		||||
	for (map<int, cTVDBSeries*>::iterator it = series.begin(); it != series.end(); it++) {
 | 
			
		||||
		cTVDBSeries *s = it->second;
 | 
			
		||||
		s->Dump();
 | 
			
		||||
		if (i == num)
 | 
			
		||||
			break;
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cScrapManager::DumpMovies(int num) {
 | 
			
		||||
	int i=0;
 | 
			
		||||
	tell(0, "Dumping first %d movies", num);
 | 
			
		||||
	for (map<int, cMovieDbMovie*>::iterator it = movies.begin(); it != movies.end(); it++) {
 | 
			
		||||
		cMovieDbMovie *m = it->second;
 | 
			
		||||
		m->Dump();
 | 
			
		||||
		if (i == num)
 | 
			
		||||
			break;
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cScrapManager::DumpRecordings(int num) {
 | 
			
		||||
	tell(0, "Dumping first %d recordings", num);
 | 
			
		||||
	for (map<sRecordingsKey, sEventsValue>::iterator it = recordings.begin(); it != recordings.end(); it++) {
 | 
			
		||||
		sRecordingsKey key = it->first;
 | 
			
		||||
		sEventsValue val = it->second;
 | 
			
		||||
		tell(0, "recStart %d, recPath %s, seriesId %d, episodeId %d, movieId %d", key.recStart, key.recPath.c_str(), val.seriesId, val.episodeId, val.movieId);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cScrapManager::GetEventType(ScraperGetEventType *call) {
 | 
			
		||||
	sEventsValue v;
 | 
			
		||||
	if (call->event) {
 | 
			
		||||
		sEventsKey k;
 | 
			
		||||
		k.eventId = call->event->EventID();
 | 
			
		||||
		k.channelId = *(call->event->ChannelID().ToString());
 | 
			
		||||
		map<sEventsKey, sEventsValue>::iterator hit = events.find(k);
 | 
			
		||||
		if (hit == events.end())
 | 
			
		||||
			return false;
 | 
			
		||||
		v = hit->second;
 | 
			
		||||
	} else if (call->recording) {
 | 
			
		||||
		sRecordingsKey k;
 | 
			
		||||
		k.recStart = call->recording->Start();
 | 
			
		||||
        k.recPath = call->recording->FileName();
 | 
			
		||||
		map<sRecordingsKey, sEventsValue>::iterator hit = recordings.find(k);
 | 
			
		||||
		if (hit == recordings.end())
 | 
			
		||||
			return false;
 | 
			
		||||
		v = hit->second;
 | 
			
		||||
	}
 | 
			
		||||
	if (v.seriesId > 0) {
 | 
			
		||||
		call->type = tSeries;
 | 
			
		||||
	} else if (v.movieId > 0) {
 | 
			
		||||
		call->type = tMovie;
 | 
			
		||||
	} else {
 | 
			
		||||
		call->type = tNone;
 | 
			
		||||
		return false;			
 | 
			
		||||
	}
 | 
			
		||||
	call->seriesId = v.seriesId;
 | 
			
		||||
	call->episodeId = v.episodeId;
 | 
			
		||||
	call->movieId = v.movieId;
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cScrapManager::GetSeries(cSeries *s) {
 | 
			
		||||
    map<int, cTVDBSeries*>::iterator hit = series.find(s->seriesId);
 | 
			
		||||
    if (hit == series.end())
 | 
			
		||||
        return false;
 | 
			
		||||
    cTVDBSeries *sStored = hit->second;
 | 
			
		||||
    s->name = sStored->name;
 | 
			
		||||
	s->overview = sStored->overview;
 | 
			
		||||
    s->firstAired = sStored->firstAired;
 | 
			
		||||
    s->network = sStored->network;
 | 
			
		||||
    s->genre = sStored->genre;
 | 
			
		||||
    s->rating = sStored->rating;
 | 
			
		||||
    s->status = sStored->status;
 | 
			
		||||
    //Episode
 | 
			
		||||
    if (s->episodeId > 0) {
 | 
			
		||||
    	sStored->GetEpisode(s->episodeId, &s->episode);
 | 
			
		||||
	    sStored->GetSeasonPoster(s->episodeId, &s->seasonPoster);    
 | 
			
		||||
    }
 | 
			
		||||
    //Media
 | 
			
		||||
    sStored->GetPosters(&s->posters);
 | 
			
		||||
    sStored->GetBanners(&s->banners);
 | 
			
		||||
    sStored->GetFanart(&s->fanarts);
 | 
			
		||||
    //Actors
 | 
			
		||||
    sStored->GetActors(&s->actors);
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cScrapManager::GetMovie(cMovie *m) {
 | 
			
		||||
    map<int, cMovieDbMovie*>::iterator hit = movies.find(m->movieId);
 | 
			
		||||
    if (hit == movies.end())
 | 
			
		||||
        return false;
 | 
			
		||||
    cMovieDbMovie *mStored = hit->second;
 | 
			
		||||
    m->title = mStored->title;
 | 
			
		||||
    m->originalTitle = mStored->originalTitle;
 | 
			
		||||
    m->tagline = mStored->tagline;    
 | 
			
		||||
    m->overview = mStored->overview;
 | 
			
		||||
    m->adult = mStored->adult;
 | 
			
		||||
    m->collectionName = mStored->collectionName;
 | 
			
		||||
    m->budget = mStored->budget;
 | 
			
		||||
    m->revenue = mStored->revenue;
 | 
			
		||||
    m->genres = mStored->genres;
 | 
			
		||||
    m->homepage = mStored->homepage;
 | 
			
		||||
    m->releaseDate = mStored->releaseDate;
 | 
			
		||||
    m->runtime = mStored->runtime;
 | 
			
		||||
    m->popularity = mStored->popularity;
 | 
			
		||||
    m->voteAverage = mStored->voteAverage;
 | 
			
		||||
    //Media
 | 
			
		||||
	mStored->GetMedia(mmPoster, &m->poster);
 | 
			
		||||
	mStored->GetMedia(mmFanart, &m->fanart);
 | 
			
		||||
	mStored->GetMedia(mmCollectionPoster, &m->collectionPoster);
 | 
			
		||||
	mStored->GetMedia(mmCollectionFanart, &m->collectionFanart);
 | 
			
		||||
	//Actors
 | 
			
		||||
    mStored->GetActors(&m->actors);
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cScrapManager::GetPosterBanner(ScraperGetPosterBanner *call) {
 | 
			
		||||
	sEventsKey k;
 | 
			
		||||
	k.eventId = call->event->EventID();
 | 
			
		||||
	k.channelId = *(call->event->ChannelID().ToString());
 | 
			
		||||
	map<sEventsKey, sEventsValue>::iterator hit = events.find(k);
 | 
			
		||||
	if (hit == events.end())
 | 
			
		||||
		return false;
 | 
			
		||||
	sEventsValue v = hit->second;
 | 
			
		||||
	if (v.seriesId > 0) {
 | 
			
		||||
		call->type = tSeries;
 | 
			
		||||
		map<int, cTVDBSeries*>::iterator hitSeries = series.find(v.seriesId);
 | 
			
		||||
		if (hitSeries == series.end())
 | 
			
		||||
			return false;
 | 
			
		||||
		cTVDBSeries *s = hitSeries->second;
 | 
			
		||||
		bool found = s->GetRandomBanner(&call->banner);
 | 
			
		||||
		if (v.episodeId > 0) {
 | 
			
		||||
			s->GetSeasonPoster(v.episodeId, &call->poster);
 | 
			
		||||
		}
 | 
			
		||||
		return found;
 | 
			
		||||
	} else if (v.movieId > 0) {
 | 
			
		||||
		call->type = tMovie;
 | 
			
		||||
		map<int, cMovieDbMovie*>::iterator hitMovies = movies.find(v.movieId);
 | 
			
		||||
		if (hitMovies == movies.end())
 | 
			
		||||
			return false;
 | 
			
		||||
		cMovieDbMovie *m = hitMovies->second;
 | 
			
		||||
		return m->GetMedia(mmPoster, &call->poster);
 | 
			
		||||
	} else {
 | 
			
		||||
		call->type = tNone;
 | 
			
		||||
	}
 | 
			
		||||
	return false;			
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cScrapManager::GetPoster(ScraperGetPoster *call) {
 | 
			
		||||
    sEventsValue v;
 | 
			
		||||
    if (call->event) {
 | 
			
		||||
    	sEventsKey k;
 | 
			
		||||
        k.eventId = call->event->EventID();
 | 
			
		||||
        k.channelId = *(call->event->ChannelID().ToString());
 | 
			
		||||
        map<sEventsKey, sEventsValue>::iterator hit = events.find(k);
 | 
			
		||||
        if (hit == events.end())
 | 
			
		||||
            return false;
 | 
			
		||||
        v = hit->second;
 | 
			
		||||
    } else if (call->recording) {
 | 
			
		||||
		sRecordingsKey k;
 | 
			
		||||
		k.recStart = call->recording->Start();
 | 
			
		||||
        k.recPath = call->recording->FileName();
 | 
			
		||||
		map<sRecordingsKey, sEventsValue>::iterator hit = recordings.find(k);
 | 
			
		||||
        if (hit == recordings.end())
 | 
			
		||||
            return false;
 | 
			
		||||
        v = hit->second;
 | 
			
		||||
    }
 | 
			
		||||
    if (v.seriesId > 0) {
 | 
			
		||||
        map<int, cTVDBSeries*>::iterator hitSeries = series.find(v.seriesId);
 | 
			
		||||
        if (hitSeries == series.end())
 | 
			
		||||
            return false;
 | 
			
		||||
        cTVDBSeries *s = hitSeries->second;
 | 
			
		||||
        return s->GetPoster(&call->poster);
 | 
			
		||||
    } else if (v.movieId > 0) {
 | 
			
		||||
        map<int, cMovieDbMovie*>::iterator hitMovies = movies.find(v.movieId);
 | 
			
		||||
        if (hitMovies == movies.end())
 | 
			
		||||
            return false;
 | 
			
		||||
        cMovieDbMovie *m = hitMovies->second;
 | 
			
		||||
        return m->GetMedia(mmPoster, &call->poster);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cScrapManager::GetPosterThumb(ScraperGetPosterThumb *call) {
 | 
			
		||||
    sEventsValue v;
 | 
			
		||||
    if (call->event) {
 | 
			
		||||
	    sEventsKey k;
 | 
			
		||||
        k.eventId = call->event->EventID();
 | 
			
		||||
        k.channelId = *(call->event->ChannelID().ToString());
 | 
			
		||||
        map<sEventsKey, sEventsValue>::iterator hit = events.find(k);
 | 
			
		||||
        if (hit == events.end())
 | 
			
		||||
            return false;
 | 
			
		||||
        v = hit->second;
 | 
			
		||||
    } else if (call->recording) {
 | 
			
		||||
		sRecordingsKey k;
 | 
			
		||||
		k.recStart = call->recording->Start();
 | 
			
		||||
        k.recPath = call->recording->FileName();
 | 
			
		||||
		map<sRecordingsKey, sEventsValue>::iterator hit = recordings.find(k);
 | 
			
		||||
        if (hit == recordings.end())
 | 
			
		||||
            return false;
 | 
			
		||||
        v = hit->second;
 | 
			
		||||
    }
 | 
			
		||||
    if (v.seriesId > 0) {
 | 
			
		||||
        map<int, cTVDBSeries*>::iterator hitSeries = series.find(v.seriesId);
 | 
			
		||||
        if (hitSeries == series.end())
 | 
			
		||||
            return false;
 | 
			
		||||
        cTVDBSeries *s = hitSeries->second;
 | 
			
		||||
        return s->GetPosterThumb(&call->poster);
 | 
			
		||||
    } else if (v.movieId > 0) {
 | 
			
		||||
        map<int, cMovieDbMovie*>::iterator hitMovies = movies.find(v.movieId);
 | 
			
		||||
        if (hitMovies == movies.end())
 | 
			
		||||
            return false;
 | 
			
		||||
        cMovieDbMovie *m = hitMovies->second;
 | 
			
		||||
        return m->GetMedia(mmPosterThumb, &call->poster);
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										81
									
								
								scrapmanager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								scrapmanager.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
#ifndef __SCRAPMANAGER_H
 | 
			
		||||
#define __SCRAPMANAGER_H
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <set>
 | 
			
		||||
#include <utility>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#include "lib/common.h"
 | 
			
		||||
#include "lib/db.h"
 | 
			
		||||
#include "lib/tabledef.h"
 | 
			
		||||
 | 
			
		||||
#include "services.h"
 | 
			
		||||
#include "tvdbseries.h"
 | 
			
		||||
#include "moviedbmovie.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
struct sEventsKey {
 | 
			
		||||
    int eventId;
 | 
			
		||||
    string channelId;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct sEventsValue {
 | 
			
		||||
    int seriesId;
 | 
			
		||||
    int episodeId;
 | 
			
		||||
    int movieId;
 | 
			
		||||
    bool isNew;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct sRecordingsKey {
 | 
			
		||||
    int recStart;
 | 
			
		||||
    string recPath;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class cScrapManager  {
 | 
			
		||||
    private:
 | 
			
		||||
        map<sEventsKey, sEventsValue> events;
 | 
			
		||||
        map<sEventsKey, sEventsValue>::iterator eventsIterator;
 | 
			
		||||
        map<sRecordingsKey, sEventsValue> recordings;
 | 
			
		||||
        map<sRecordingsKey, sEventsValue>::iterator recIterator;
 | 
			
		||||
        map<int, cTVDBSeries*> series;
 | 
			
		||||
        map<int, cMovieDbMovie*> movies;
 | 
			
		||||
    public:
 | 
			
		||||
        cScrapManager(void);
 | 
			
		||||
        virtual ~cScrapManager(void);
 | 
			
		||||
        //Series and Movies Handling
 | 
			
		||||
        void AddEvent(int eventId, string channelId, int seriesId, int episodeId, int movieId);
 | 
			
		||||
        void InitIterator(bool isRec);
 | 
			
		||||
        int GetNumSeries(void) { return series.size(); };
 | 
			
		||||
        int GetNumMovies(void) { return movies.size(); };
 | 
			
		||||
        sEventsValue GetEventInformation(int eventId, string channelId);
 | 
			
		||||
        bool GetNextSeries(bool isRec, int &seriesId, int &episodeId);
 | 
			
		||||
        bool GetNextMovie(bool isRec, int &movieId);
 | 
			
		||||
        cTVDBSeries *GetSeries(int seriesId);
 | 
			
		||||
        cMovieDbMovie *GetMovie(int movieId);
 | 
			
		||||
        cTVDBSeries *AddSeries(cTableSeries* tSeries);
 | 
			
		||||
        cMovieDbMovie *AddMovie(cTableMovies* tMovies);
 | 
			
		||||
        void AddSeriesEpisode(cTVDBSeries *series, cTableSeriesEpisode* tEpisodes);
 | 
			
		||||
        void AddSeriesActor(cTVDBSeries *series, cTableSeriesActor* tActors);
 | 
			
		||||
        void AddMovieActor(cMovieDbMovie *movie, cTableMovieActor* tActor, string role);
 | 
			
		||||
        void AddMovieMedia(cMovieDbMovie *movie, cTableMovieMedia* tMovieMedia, string path);
 | 
			
		||||
        //Recording Handling
 | 
			
		||||
        bool AddRecording(int recStart, string recPath, int seriesId, int episodeId, int movieId);
 | 
			
		||||
        bool RecordingExists(int recStart, string recPath);
 | 
			
		||||
        bool SeriesInUse(int seriesId);
 | 
			
		||||
        bool MovieInUse(int movieId);
 | 
			
		||||
        //Debug
 | 
			
		||||
        void DumpSeries(int num);
 | 
			
		||||
        void DumpMovies(int num);
 | 
			
		||||
        void DumpRecordings(int num);
 | 
			
		||||
        //Service Calls
 | 
			
		||||
        bool GetEventType(ScraperGetEventType *call);
 | 
			
		||||
        bool GetSeries(cSeries *series);
 | 
			
		||||
        bool GetMovie(cMovie *movie);
 | 
			
		||||
        bool GetPosterBanner(ScraperGetPosterBanner *call);
 | 
			
		||||
        bool GetPoster(ScraperGetPoster *call);
 | 
			
		||||
        bool GetPosterThumb(ScraperGetPosterThumb *call);
 | 
			
		||||
};
 | 
			
		||||
#endif //__SCRAPMANAGER_H
 | 
			
		||||
							
								
								
									
										194
									
								
								services.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								services.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,194 @@
 | 
			
		||||
#ifndef __SCRAPER2VDRSERVICES_H
 | 
			
		||||
#define __SCRAPER2VDRSERVICES_H
 | 
			
		||||
 | 
			
		||||
#include <vdr/epg.h>
 | 
			
		||||
#include <vdr/recording.h>
 | 
			
		||||
 | 
			
		||||
enum tvType {
 | 
			
		||||
    tSeries,
 | 
			
		||||
    tMovie,
 | 
			
		||||
    tNone,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
* Helper Structures
 | 
			
		||||
*********************************************************************/
 | 
			
		||||
class cTvMedia {
 | 
			
		||||
public:
 | 
			
		||||
	cTvMedia(void) {
 | 
			
		||||
		path = "";
 | 
			
		||||
		width = height = 0;
 | 
			
		||||
	};
 | 
			
		||||
    std::string path;
 | 
			
		||||
    int width;
 | 
			
		||||
    int height;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class cEpisode {
 | 
			
		||||
public:
 | 
			
		||||
    cEpisode(void) {
 | 
			
		||||
        number = 0;
 | 
			
		||||
        season = 0;
 | 
			
		||||
        name = "";
 | 
			
		||||
        firstAired = "";
 | 
			
		||||
        guestStars = "";
 | 
			
		||||
        overview = "";
 | 
			
		||||
        rating = 0.0;
 | 
			
		||||
    };
 | 
			
		||||
    int number;
 | 
			
		||||
    int season;
 | 
			
		||||
    std::string name;
 | 
			
		||||
    std::string firstAired;
 | 
			
		||||
    std::string guestStars;
 | 
			
		||||
    std::string overview;
 | 
			
		||||
    float rating;
 | 
			
		||||
    cTvMedia episodeImage;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class cActor {
 | 
			
		||||
public:
 | 
			
		||||
    cActor(void) {
 | 
			
		||||
        name = "";
 | 
			
		||||
        role = "";
 | 
			
		||||
    };
 | 
			
		||||
    std::string name;
 | 
			
		||||
    std::string role;
 | 
			
		||||
    cTvMedia actorThumb;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*********************************************************************
 | 
			
		||||
* Data Structures for Service Calls
 | 
			
		||||
*********************************************************************/
 | 
			
		||||
 | 
			
		||||
// Data structure for service "GetEventType"
 | 
			
		||||
class ScraperGetEventType {
 | 
			
		||||
public:
 | 
			
		||||
	ScraperGetEventType(void) {
 | 
			
		||||
		event = NULL;
 | 
			
		||||
        recording = NULL;
 | 
			
		||||
		type = tNone;
 | 
			
		||||
		movieId = 0;
 | 
			
		||||
		seriesId = 0;
 | 
			
		||||
		episodeId = 0;
 | 
			
		||||
	};
 | 
			
		||||
// in
 | 
			
		||||
    const cEvent *event;             // check type for this event 
 | 
			
		||||
    const cRecording *recording;     // or for this recording
 | 
			
		||||
//out
 | 
			
		||||
    tvType type;                	 //typeSeries or typeMovie
 | 
			
		||||
    int movieId;
 | 
			
		||||
    int seriesId;
 | 
			
		||||
    int episodeId;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//Data structure for full series and episode information
 | 
			
		||||
class cMovie {
 | 
			
		||||
public:
 | 
			
		||||
    cMovie(void) {
 | 
			
		||||
        title = "";
 | 
			
		||||
        originalTitle = "";
 | 
			
		||||
        tagline = "";    
 | 
			
		||||
        overview = "";
 | 
			
		||||
        adult = false;
 | 
			
		||||
        collectionName = "";
 | 
			
		||||
        budget = 0;
 | 
			
		||||
        revenue = 0;
 | 
			
		||||
        genres = "";
 | 
			
		||||
        homepage = "";
 | 
			
		||||
        releaseDate = "";
 | 
			
		||||
        runtime = 0;
 | 
			
		||||
        popularity = 0.0;
 | 
			
		||||
        voteAverage = 0.0;
 | 
			
		||||
    };
 | 
			
		||||
//IN
 | 
			
		||||
    int movieId;                    // movieId fetched from ScraperGetEventType
 | 
			
		||||
//OUT    
 | 
			
		||||
    std::string title;
 | 
			
		||||
    std::string originalTitle;
 | 
			
		||||
    std::string tagline;    
 | 
			
		||||
    std::string overview;
 | 
			
		||||
    bool adult;
 | 
			
		||||
    std::string collectionName;
 | 
			
		||||
    int budget;
 | 
			
		||||
    int revenue;
 | 
			
		||||
    std::string genres;
 | 
			
		||||
    std::string homepage;
 | 
			
		||||
    std::string releaseDate;
 | 
			
		||||
    int runtime;
 | 
			
		||||
    float popularity;
 | 
			
		||||
    float voteAverage;
 | 
			
		||||
    cTvMedia poster;
 | 
			
		||||
    cTvMedia fanart;
 | 
			
		||||
    cTvMedia collectionPoster;
 | 
			
		||||
    cTvMedia collectionFanart;
 | 
			
		||||
    std::vector<cActor> actors;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//Data structure for full series and episode information
 | 
			
		||||
class cSeries {
 | 
			
		||||
public:
 | 
			
		||||
    cSeries(void) {
 | 
			
		||||
        seriesId = 0;
 | 
			
		||||
        episodeId = 0;
 | 
			
		||||
        name = "";
 | 
			
		||||
        overview = "";
 | 
			
		||||
        firstAired = "";
 | 
			
		||||
        network = "";
 | 
			
		||||
        genre = "";
 | 
			
		||||
        rating = 0.0;
 | 
			
		||||
        status = "";
 | 
			
		||||
    };
 | 
			
		||||
//IN
 | 
			
		||||
    int seriesId;                   // seriesId fetched from ScraperGetEventType
 | 
			
		||||
    int episodeId;                  // episodeId fetched from ScraperGetEventType
 | 
			
		||||
//OUT
 | 
			
		||||
    std::string name;
 | 
			
		||||
    std::string overview;
 | 
			
		||||
    std::string firstAired;
 | 
			
		||||
    std::string network;
 | 
			
		||||
    std::string genre;
 | 
			
		||||
    float rating;
 | 
			
		||||
    std::string status;
 | 
			
		||||
    cEpisode episode;
 | 
			
		||||
    std::vector<cActor> actors;
 | 
			
		||||
    std::vector<cTvMedia> posters;
 | 
			
		||||
    std::vector<cTvMedia> banners;
 | 
			
		||||
    std::vector<cTvMedia> fanarts;
 | 
			
		||||
    cTvMedia seasonPoster;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Data structure for service "GetPosterBanner"
 | 
			
		||||
class ScraperGetPosterBanner {
 | 
			
		||||
public:
 | 
			
		||||
	ScraperGetPosterBanner(void) {
 | 
			
		||||
		type = tNone;
 | 
			
		||||
	};
 | 
			
		||||
// in
 | 
			
		||||
    const cEvent *event;             // check type for this event 
 | 
			
		||||
//out
 | 
			
		||||
    tvType type;                	 //typeSeries or typeMovie
 | 
			
		||||
    cTvMedia poster;
 | 
			
		||||
    cTvMedia banner;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Data structure for service "GetPoster"
 | 
			
		||||
class ScraperGetPoster {
 | 
			
		||||
public:
 | 
			
		||||
// in
 | 
			
		||||
    const cEvent *event;             // check type for this event
 | 
			
		||||
    const cRecording *recording;     // or for this recording
 | 
			
		||||
//out
 | 
			
		||||
    cTvMedia poster;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Data structure for service "GetPosterThumb"
 | 
			
		||||
class ScraperGetPosterThumb {
 | 
			
		||||
public:
 | 
			
		||||
// in
 | 
			
		||||
    const cEvent *event;             // check type for this event
 | 
			
		||||
    const cRecording *recording;     // or for this recording
 | 
			
		||||
//out
 | 
			
		||||
    cTvMedia poster;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif //__SCRAPER2VDRSERVICES_H
 | 
			
		||||
							
								
								
									
										78
									
								
								setup.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								setup.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
#include "setup.h"
 | 
			
		||||
 | 
			
		||||
extern cScraper2VdrConfig config;
 | 
			
		||||
 | 
			
		||||
cScraper2VdrSetup::cScraper2VdrSetup(cUpdate *update) {
 | 
			
		||||
    this->update = update;
 | 
			
		||||
    tmpConfig = config;
 | 
			
		||||
    strn0cpy(host, tmpConfig.mysqlHost.c_str(), sizeof(host));
 | 
			
		||||
    strn0cpy(dbname, tmpConfig.mysqlDBName.c_str(), sizeof(dbname));
 | 
			
		||||
    strn0cpy(user, tmpConfig.mysqlDBUser.c_str(), sizeof(user));
 | 
			
		||||
    strn0cpy(password, tmpConfig.mysqlDBPass.c_str(), sizeof(password));
 | 
			
		||||
    Setup();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cScraper2VdrSetup::~cScraper2VdrSetup() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void cScraper2VdrSetup::Setup(void) {
 | 
			
		||||
    int currentItem = Current();
 | 
			
		||||
    Clear();
 | 
			
		||||
    
 | 
			
		||||
    Add(new cMenuEditBoolItem(tr("Show Main Menu Entry"), &tmpConfig.mainMenuEntry));
 | 
			
		||||
    Add(new cMenuEditStrItem(tr("MySQL Host"), host, sizeof(host), tr(FileNameChars)));
 | 
			
		||||
    Add(new cMenuEditIntItem(tr("MySQL Port"), &tmpConfig.mysqlPort, 1, 99999));
 | 
			
		||||
    Add(new cMenuEditStrItem(tr("MySQL Database Name"), dbname, sizeof(dbname), tr(FileNameChars)));
 | 
			
		||||
    Add(new cMenuEditStrItem(tr("MySQL User"), user, sizeof(user), tr(FileNameChars)));
 | 
			
		||||
    Add(new cMenuEditStrItem(tr("MySQL Password"), password, sizeof(password), tr(FileNameChars)));
 | 
			
		||||
 | 
			
		||||
    Add(new cOsdItem(tr("Update Scraper Information from Database")));
 | 
			
		||||
    Add(new cOsdItem(tr("Update Scraper Recordings Information from Database")));
 | 
			
		||||
    Add(new cOsdItem(tr("Scan for new recordings in video directory")));
 | 
			
		||||
    Add(new cOsdItem(tr("Scan for new or updated scrapinfo files")));
 | 
			
		||||
    Add(new cOsdItem(tr("Cleanup Recordings in Database")));
 | 
			
		||||
 | 
			
		||||
    SetCurrent(Get(currentItem));
 | 
			
		||||
    Display();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eOSState cScraper2VdrSetup::ProcessKey(eKeys Key) {
 | 
			
		||||
    bool hadSubMenu = HasSubMenu();   
 | 
			
		||||
    eOSState state = cMenuSetupPage::ProcessKey(Key);
 | 
			
		||||
    if (Key == kOk) {
 | 
			
		||||
        tmpConfig.mysqlHost = host;
 | 
			
		||||
        tmpConfig.mysqlDBName = dbname;
 | 
			
		||||
        tmpConfig.mysqlDBUser = user;
 | 
			
		||||
        tmpConfig.mysqlDBPass = password;
 | 
			
		||||
        Store();
 | 
			
		||||
        if (Current() == 6) {
 | 
			
		||||
            Skins.Message(mtInfo, tr("Updating Scraper EPG Information from Database"));
 | 
			
		||||
            update->ForceUpdate();
 | 
			
		||||
        } else if (Current() == 7) {
 | 
			
		||||
            Skins.Message(mtInfo, tr("Updating Scraper Recordings Information from Database"));
 | 
			
		||||
            update->ForceRecordingUpdate();
 | 
			
		||||
        } else if (Current() == 8) {
 | 
			
		||||
            Skins.Message(mtInfo, tr("Scanning for new recordings in video directory"));
 | 
			
		||||
            update->ForceVideoDirUpdate();
 | 
			
		||||
        } else if (Current() == 9) {
 | 
			
		||||
            Skins.Message(mtInfo, tr("Scanning for new or updated scrapinfo files"));
 | 
			
		||||
            update->ForceScrapInfoUpdate();
 | 
			
		||||
        } else if (Current() == 10) {
 | 
			
		||||
            Skins.Message(mtInfo, tr("Cleaning up Recordings in Database"));
 | 
			
		||||
            update->TriggerCleanRecordingsDB();
 | 
			
		||||
        }
 | 
			
		||||
        return osEnd;
 | 
			
		||||
    }
 | 
			
		||||
    return state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cScraper2VdrSetup::Store(void) {
 | 
			
		||||
    config = tmpConfig;
 | 
			
		||||
    SetupStore("mainMenuEntry", tmpConfig.mainMenuEntry);
 | 
			
		||||
    SetupStore("mysqlHost", tmpConfig.mysqlHost.c_str());
 | 
			
		||||
    SetupStore("mysqlPort", tmpConfig.mysqlPort);
 | 
			
		||||
    SetupStore("mysqlDBName", tmpConfig.mysqlDBName.c_str());
 | 
			
		||||
    SetupStore("mysqlDBUser", tmpConfig.mysqlDBUser.c_str());
 | 
			
		||||
    SetupStore("mysqlDBPass", tmpConfig.mysqlDBPass.c_str());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								setup.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								setup.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
#ifndef __SCRAPER2VDR_SETUP_H
 | 
			
		||||
#define __SCRAPER2VDR_SETUP_H
 | 
			
		||||
 | 
			
		||||
#include <vdr/menuitems.h>
 | 
			
		||||
#include "update.h"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
class cScraper2VdrSetup : public cMenuSetupPage {
 | 
			
		||||
    public:
 | 
			
		||||
        cScraper2VdrSetup(cUpdate *update);
 | 
			
		||||
        virtual ~cScraper2VdrSetup();       
 | 
			
		||||
    private:
 | 
			
		||||
        cUpdate *update;
 | 
			
		||||
        cScraper2VdrConfig tmpConfig;
 | 
			
		||||
        char host[256];
 | 
			
		||||
        char dbname[256];
 | 
			
		||||
        char user[256];
 | 
			
		||||
        char password[256];
 | 
			
		||||
        void Setup(void);
 | 
			
		||||
    protected:
 | 
			
		||||
        virtual eOSState ProcessKey(eKeys Key);
 | 
			
		||||
        virtual void Store(void);
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
#endif //__SCRAPER2VDR_SETUP_H
 | 
			
		||||
							
								
								
									
										170
									
								
								tools.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								tools.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,170 @@
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/vfs.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <algorithm> 
 | 
			
		||||
#include <functional> 
 | 
			
		||||
#include <cctype>
 | 
			
		||||
#include <locale>
 | 
			
		||||
#include <Magick++.h>
 | 
			
		||||
#include <vdr/plugin.h>
 | 
			
		||||
#include "lib/common.h"
 | 
			
		||||
#include "tools.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace Magick;
 | 
			
		||||
 | 
			
		||||
bool CreateDirectory(string dir) {
 | 
			
		||||
    mkdir(dir.c_str(), 0775);
 | 
			
		||||
    //check if successfull
 | 
			
		||||
    DIR *pDir;
 | 
			
		||||
    bool exists = false;
 | 
			
		||||
    pDir = opendir(dir.c_str());
 | 
			
		||||
    if (pDir != NULL) {
 | 
			
		||||
        exists = true;    
 | 
			
		||||
        closedir(pDir);
 | 
			
		||||
    }
 | 
			
		||||
    return exists;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool FileExists(string filename, bool isImage) {
 | 
			
		||||
    ifstream ifile(filename.c_str());
 | 
			
		||||
    if (ifile) {
 | 
			
		||||
        //a valid image should be larger then 500 bytes
 | 
			
		||||
        ifile.seekg (0, ifile.end);
 | 
			
		||||
        int length = ifile.tellg();
 | 
			
		||||
        int minimumLength = isImage ? 500 : 1;
 | 
			
		||||
        if (length > minimumLength)
 | 
			
		||||
            return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CheckDirExists(const char* dirName) {
 | 
			
		||||
    struct statfs statfsbuf;
 | 
			
		||||
    if (statfs(dirName,&statfsbuf)==-1) return false;
 | 
			
		||||
    if ((statfsbuf.f_type!=0x01021994) && (statfsbuf.f_type!=0x28cd3d45)) return false;
 | 
			
		||||
    if (access(dirName,R_OK|W_OK)==-1) return false;
 | 
			
		||||
    return true;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DeleteFile(string filename) {
 | 
			
		||||
    remove(filename.c_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DeleteDirectory(string dirname) {
 | 
			
		||||
    DIR *dir;
 | 
			
		||||
    struct dirent *entry;
 | 
			
		||||
    if ((dir = opendir (dirname.c_str())) != NULL) {
 | 
			
		||||
        while ((entry = readdir (dir)) != NULL) {
 | 
			
		||||
            string file = entry->d_name;
 | 
			
		||||
            if (!file.compare("."))
 | 
			
		||||
                continue;
 | 
			
		||||
            if (!file.compare(".."))
 | 
			
		||||
                continue;
 | 
			
		||||
            string delFile = dirname + "/" + file;
 | 
			
		||||
            DeleteFile(delFile);
 | 
			
		||||
        }
 | 
			
		||||
        closedir (dir);
 | 
			
		||||
    }
 | 
			
		||||
    rmdir(dirname.c_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
string TwoFoldersHigher(string folder) {
 | 
			
		||||
    unsigned found = folder.find_last_of("/");
 | 
			
		||||
    if (found != string::npos) {
 | 
			
		||||
        string firstDirRemoved = folder.substr(0,found);
 | 
			
		||||
        unsigned found2 = firstDirRemoved.find_last_of("/");
 | 
			
		||||
        if (found2 != string::npos) {
 | 
			
		||||
            return firstDirRemoved.substr(0,found2);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return "";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// trim from start
 | 
			
		||||
string <rim(string &s) {
 | 
			
		||||
    s.erase(s.begin(), find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(isspace))));
 | 
			
		||||
    return s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// trim from end
 | 
			
		||||
string &rtrim(string &s) {
 | 
			
		||||
    s.erase(find_if(s.rbegin(), s.rend(), not1(ptr_fun<int, int>(isspace))).base(), s.end());
 | 
			
		||||
    return s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// trim from both ends
 | 
			
		||||
string &trim(string &s) {
 | 
			
		||||
    return ltrim(rtrim(s));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void toLower(string &s) {
 | 
			
		||||
    transform(s.begin(), s.end(), s.begin(), ::tolower);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool isNumber(const string& s) {
 | 
			
		||||
    string::const_iterator it = s.begin();
 | 
			
		||||
    while (it != s.end() && isdigit(*it)) ++it;
 | 
			
		||||
    return !s.empty() && it == s.end();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
string replaceString(string content, string search, string repl) {
 | 
			
		||||
    size_t pos = 0;
 | 
			
		||||
    while((pos = content.find(search, pos)) != std::string::npos) {
 | 
			
		||||
        if (pos > 3 && pos < content.size() - 2) {
 | 
			
		||||
            content.replace(pos, search.length(), repl);
 | 
			
		||||
        } else {
 | 
			
		||||
            content.replace(pos, search.length(), "");            
 | 
			
		||||
        }
 | 
			
		||||
        pos += repl.length();
 | 
			
		||||
    }
 | 
			
		||||
    return content;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/****************************************************************************************
 | 
			
		||||
*            SPLTSTRING
 | 
			
		||||
****************************************************************************************/
 | 
			
		||||
// split: receives a char delimiter; returns a vector of strings
 | 
			
		||||
// By default ignores repeated delimiters, unless argument rep == 1.
 | 
			
		||||
vector<string>& splitstring::split(char delim, int rep) {
 | 
			
		||||
    if (!flds.empty()) flds.clear();  // empty vector if necessary
 | 
			
		||||
    string work = data();
 | 
			
		||||
    string buf = "";
 | 
			
		||||
    int i = 0;
 | 
			
		||||
    while (i < work.length()) {
 | 
			
		||||
        if (work[i] != delim)
 | 
			
		||||
            buf += work[i];
 | 
			
		||||
        else if (rep == 1) {
 | 
			
		||||
            flds.push_back(buf);
 | 
			
		||||
            buf = "";
 | 
			
		||||
        } else if (buf.length() > 0) {
 | 
			
		||||
            flds.push_back(buf);
 | 
			
		||||
            buf = "";
 | 
			
		||||
        }
 | 
			
		||||
        i++;
 | 
			
		||||
    }
 | 
			
		||||
    if (!buf.empty())
 | 
			
		||||
        flds.push_back(buf);
 | 
			
		||||
    return flds;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CreateThumbnail(string sourcePath, string destPath, int origWidth, int origHeight, int shrinkFactor) {
 | 
			
		||||
    if (sourcePath.size() < 5 || destPath.size() < 5 || shrinkFactor < 2)
 | 
			
		||||
        return;
 | 
			
		||||
    
 | 
			
		||||
    int thumbWidth = origWidth / shrinkFactor;
 | 
			
		||||
    int thumbHeight = origHeight / shrinkFactor;
 | 
			
		||||
 | 
			
		||||
    InitializeMagick(NULL);
 | 
			
		||||
    Image buffer;
 | 
			
		||||
    try {
 | 
			
		||||
        buffer.read(sourcePath.c_str());
 | 
			
		||||
        buffer.sample(Geometry(thumbWidth, thumbHeight)); 
 | 
			
		||||
        buffer.write(destPath.c_str());
 | 
			
		||||
    } catch( ... ) {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								tools.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								tools.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
//Filesystem Functions
 | 
			
		||||
bool CreateDirectory(string dir);
 | 
			
		||||
bool FileExists(string filename, bool isImage = true); 
 | 
			
		||||
bool CheckDirExists(const char* dirName);
 | 
			
		||||
void DeleteFile(string filename);
 | 
			
		||||
void DeleteDirectory(string dirname);
 | 
			
		||||
string TwoFoldersHigher(string folder);
 | 
			
		||||
 | 
			
		||||
//String Functions
 | 
			
		||||
string <rim(string &s);
 | 
			
		||||
string &rtrim(string &s);
 | 
			
		||||
string &trim(string &s);
 | 
			
		||||
void toLower(string &s);
 | 
			
		||||
bool isNumber(const string& s);
 | 
			
		||||
string replaceString(string content, string search, string repl);
 | 
			
		||||
 | 
			
		||||
class splitstring : public string {
 | 
			
		||||
    vector<string> flds;
 | 
			
		||||
public:
 | 
			
		||||
    splitstring(const char *s) : string(s) { };
 | 
			
		||||
    vector<string>& split(char delim, int rep=0);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//Image Functions
 | 
			
		||||
void CreateThumbnail(string sourcePath, string destPath, int origWidth, int origHeight, int shrinkFactor);
 | 
			
		||||
							
								
								
									
										289
									
								
								tvdbseries.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										289
									
								
								tvdbseries.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,289 @@
 | 
			
		||||
#define __STL_CONFIG_H
 | 
			
		||||
#include "lib/common.h"
 | 
			
		||||
#include "tvdbseries.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
cTVDBSeries::cTVDBSeries(void) {
 | 
			
		||||
    id = 0;
 | 
			
		||||
    name = "";
 | 
			
		||||
    overview = "";
 | 
			
		||||
    firstAired = "";
 | 
			
		||||
    network = "";
 | 
			
		||||
    genre = "";
 | 
			
		||||
    rating = 0.0;
 | 
			
		||||
    status = "";
 | 
			
		||||
    posterThumb = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cTVDBSeries::~cTVDBSeries() {
 | 
			
		||||
    for (map<int, cTVDBActor*>::iterator it = actors.begin(); it != actors.end(); it++) {
 | 
			
		||||
        cTVDBActor *a = (cTVDBActor*)it->second;
 | 
			
		||||
        delete a;
 | 
			
		||||
    }
 | 
			
		||||
    for (map<int, cTVDBEpisode*>::iterator it = episodes.begin(); it != episodes.end(); it++) {
 | 
			
		||||
        cTVDBEpisode *e = (cTVDBEpisode*)it->second;
 | 
			
		||||
        delete e;
 | 
			
		||||
    }
 | 
			
		||||
    for (vector<cTVDBMedia*>::iterator it = posters.begin(); it != posters.end(); it++) {
 | 
			
		||||
        cTVDBMedia *p = *it;
 | 
			
		||||
        delete p;
 | 
			
		||||
    }
 | 
			
		||||
    for (vector<cTVDBMedia*>::iterator it = banners.begin(); it != banners.end(); it++) {
 | 
			
		||||
        cTVDBMedia *b = *it;
 | 
			
		||||
        delete b;
 | 
			
		||||
    }
 | 
			
		||||
    for (vector<cTVDBMedia*>::iterator it = fanart.begin(); it != fanart.end(); it++) {
 | 
			
		||||
        cTVDBMedia *f = *it;
 | 
			
		||||
        delete f;
 | 
			
		||||
    }
 | 
			
		||||
    for (map<int, cTVDBMedia*>::iterator it = seasonPosters.begin(); it != seasonPosters.end(); it++) {
 | 
			
		||||
        cTVDBMedia *s = (cTVDBMedia*)it->second;
 | 
			
		||||
        delete s;
 | 
			
		||||
    }
 | 
			
		||||
    for (map<int, cTVDBMedia*>::iterator it = seasonPosterThumbs.begin(); it != seasonPosterThumbs.end(); it++) {
 | 
			
		||||
        cTVDBMedia *s = (cTVDBMedia*)it->second;
 | 
			
		||||
        delete s;
 | 
			
		||||
    }
 | 
			
		||||
    if (posterThumb)
 | 
			
		||||
        delete posterThumb;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cTVDBSeries::InsertEpisode(cTVDBEpisode *episode) {
 | 
			
		||||
    map<int, cTVDBEpisode*>::iterator hit = episodes.find(episode->id);
 | 
			
		||||
    if (hit != episodes.end())
 | 
			
		||||
        delete episode;
 | 
			
		||||
    else
 | 
			
		||||
        episodes.insert(pair<int, cTVDBEpisode*>(episode->id, episode));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cTVDBSeries::InsertEpisodeImage(int episodeId, int width, int height, string path) {
 | 
			
		||||
    map<int, cTVDBEpisode*>::iterator hit = episodes.find(episodeId);
 | 
			
		||||
    if (hit != episodes.end()) {
 | 
			
		||||
        cTVDBEpisode *e = hit->second;
 | 
			
		||||
        cTVDBMedia *m = new cTVDBMedia();
 | 
			
		||||
        m->width = width;
 | 
			
		||||
        m->height = height;
 | 
			
		||||
        m->path = path;
 | 
			
		||||
        m->mediaType = msEpisodePic;
 | 
			
		||||
        e->episodeImage = m;
 | 
			
		||||
    }    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cTVDBSeries::InsertActor(cTVDBActor *actor) {
 | 
			
		||||
    actors.insert(pair<int, cTVDBActor*>(actor->id, actor));    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cTVDBSeries::InsertActorThumb(int actorId, int imgWidth, int imgHeight, string path) {
 | 
			
		||||
    map<int, cTVDBActor*>::iterator hit = actors.find(actorId);
 | 
			
		||||
    if (hit != actors.end()) {
 | 
			
		||||
        cTVDBActor *a = hit->second;
 | 
			
		||||
        cTVDBMedia *m = new cTVDBMedia();
 | 
			
		||||
        m->width = imgWidth;
 | 
			
		||||
        m->height = imgHeight;
 | 
			
		||||
        m->path = path;
 | 
			
		||||
        m->mediaType = msActorThumb;
 | 
			
		||||
        a->actorThumb = m;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cTVDBSeries::InsertMedia(int mediaType, int imgWidth, int imgHeight, string path, int season) {
 | 
			
		||||
    cTVDBMedia *media = new cTVDBMedia();
 | 
			
		||||
    media->width = imgWidth;
 | 
			
		||||
    media->height = imgHeight;
 | 
			
		||||
    media->path = path;
 | 
			
		||||
    media->mediaType = mediaType;
 | 
			
		||||
    switch (mediaType) {
 | 
			
		||||
        case msPoster1:
 | 
			
		||||
        case msPoster2:
 | 
			
		||||
        case msPoster3:
 | 
			
		||||
            posters.push_back(media);
 | 
			
		||||
            break;
 | 
			
		||||
        case msFanart1:
 | 
			
		||||
        case msFanart2:
 | 
			
		||||
        case msFanart3:
 | 
			
		||||
            fanart.push_back(media);
 | 
			
		||||
            break;
 | 
			
		||||
        case msBanner1:
 | 
			
		||||
        case msBanner2:
 | 
			
		||||
        case msBanner3:
 | 
			
		||||
            banners.push_back(media);
 | 
			
		||||
        case msSeasonPoster:
 | 
			
		||||
            seasonPosters.insert(pair<int, cTVDBMedia*>(season, media));
 | 
			
		||||
            break;
 | 
			
		||||
        case msPosterThumb:
 | 
			
		||||
            posterThumb = media;
 | 
			
		||||
            break;
 | 
			
		||||
        case msSeasonPosterThumb:
 | 
			
		||||
            seasonPosterThumbs.insert(pair<int, cTVDBMedia*>(season, media));
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
        break;
 | 
			
		||||
    }   
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cTVDBSeries::GetEpisode(int episodeId, cEpisode *e) {
 | 
			
		||||
    map<int, cTVDBEpisode*>::iterator hit = episodes.find(episodeId);
 | 
			
		||||
    if (hit == episodes.end())
 | 
			
		||||
        return;
 | 
			
		||||
    cTVDBEpisode *eStored = hit->second;
 | 
			
		||||
    e->number = eStored->number;
 | 
			
		||||
    e->season = eStored->season;
 | 
			
		||||
    e->name = eStored->name;
 | 
			
		||||
    e->firstAired = eStored->firstAired;
 | 
			
		||||
    e->guestStars = eStored->guestStars;
 | 
			
		||||
    e->overview = eStored->overview;
 | 
			
		||||
    e->rating = eStored->rating;
 | 
			
		||||
    if (eStored->episodeImage) {
 | 
			
		||||
        e->episodeImage.path = eStored->episodeImage->path;
 | 
			
		||||
        e->episodeImage.width = eStored->episodeImage->width;
 | 
			
		||||
        e->episodeImage.height = eStored->episodeImage->height;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cTVDBSeries::GetPosters(vector<cTvMedia> *p) {
 | 
			
		||||
    for (vector<cTVDBMedia*>::iterator it = posters.begin(); it != posters.end(); it++) {
 | 
			
		||||
        cTVDBMedia *mStored = *it;
 | 
			
		||||
        cTvMedia m;
 | 
			
		||||
        m.path = mStored->path;        
 | 
			
		||||
        m.width = mStored->width;
 | 
			
		||||
        m.height = mStored->height;
 | 
			
		||||
        p->push_back(m);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cTVDBSeries::GetPoster(cTvMedia *p) {
 | 
			
		||||
    if (posters.size() > 0) {
 | 
			
		||||
        p->path = posters[0]->path;
 | 
			
		||||
        p->width = posters[0]->width;
 | 
			
		||||
        p->height = posters[0]->height;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cTVDBSeries::GetPosterThumb(cTvMedia *p) {
 | 
			
		||||
    if (posterThumb) {
 | 
			
		||||
        p->path = posterThumb->path;
 | 
			
		||||
        p->width = posterThumb->width;
 | 
			
		||||
        p->height = posterThumb->height;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cTVDBSeries::GetBanners(vector<cTvMedia> *b) {
 | 
			
		||||
    for (vector<cTVDBMedia*>::iterator it = banners.begin(); it != banners.end(); it++) {
 | 
			
		||||
        cTVDBMedia *bStored = *it;
 | 
			
		||||
        cTvMedia m;
 | 
			
		||||
        m.path = bStored->path;        
 | 
			
		||||
        m.width = bStored->width;
 | 
			
		||||
        m.height = bStored->height;
 | 
			
		||||
        b->push_back(m);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cTVDBSeries::GetRandomBanner(cTvMedia *b) {
 | 
			
		||||
    int numBanners = banners.size();
 | 
			
		||||
    if (numBanners == 0)
 | 
			
		||||
        return false;
 | 
			
		||||
    srand((unsigned)time(NULL));
 | 
			
		||||
    int banner = rand()%numBanners;
 | 
			
		||||
    cTVDBMedia *bStored = banners[banner];
 | 
			
		||||
    b->path = bStored->path;
 | 
			
		||||
    b->width = bStored->width;
 | 
			
		||||
    b->height = bStored->height;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cTVDBSeries::GetFanart(vector<cTvMedia> *f) {
 | 
			
		||||
    for (vector<cTVDBMedia*>::iterator it = fanart.begin(); it != fanart.end(); it++) {
 | 
			
		||||
        cTVDBMedia *fStored = *it;
 | 
			
		||||
        cTvMedia m;
 | 
			
		||||
        m.path = fStored->path;        
 | 
			
		||||
        m.width = fStored->width;
 | 
			
		||||
        m.height = fStored->height;
 | 
			
		||||
        f->push_back(m);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cTVDBSeries::GetSeasonPoster(int episodeId, cTvMedia *sp) {
 | 
			
		||||
    map<int, cTVDBEpisode*>::iterator hit = episodes.find(episodeId);
 | 
			
		||||
    if (hit == episodes.end())
 | 
			
		||||
        return;
 | 
			
		||||
    cTVDBEpisode *e = hit->second;
 | 
			
		||||
    map<int, cTVDBMedia*>::iterator hit2 = seasonPosters.find(e->season);
 | 
			
		||||
    if (hit2 == seasonPosters.end())
 | 
			
		||||
        return;
 | 
			
		||||
    cTVDBMedia *spStored = hit2->second;
 | 
			
		||||
    sp->width = spStored->width;
 | 
			
		||||
    sp->height = spStored->height;
 | 
			
		||||
    sp->path = spStored->path;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cTVDBSeries::GetActors(vector<cActor> *a) {
 | 
			
		||||
    for (map<int, cTVDBActor*>::iterator it = actors.begin(); it != actors.end(); it++) {
 | 
			
		||||
        cTVDBActor *aStored = it->second;
 | 
			
		||||
        cActor act;
 | 
			
		||||
        act.name = aStored->name;
 | 
			
		||||
        act.role = aStored->role;
 | 
			
		||||
        if (aStored->actorThumb) {
 | 
			
		||||
            act.actorThumb.width = aStored->actorThumb->width;
 | 
			
		||||
            act.actorThumb.height = aStored->actorThumb->height;
 | 
			
		||||
            act.actorThumb.path = aStored->actorThumb->path;
 | 
			
		||||
        }
 | 
			
		||||
        a->push_back(act);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cTVDBSeries::Dump(void) {
 | 
			
		||||
    tell(0, "--------------------------- Series Info ----------------------------------");
 | 
			
		||||
    tell(0, "series %s, ID: %d", name.c_str(), id);
 | 
			
		||||
    tell(0, "Overview: %s", overview.c_str());
 | 
			
		||||
    tell(0, "FirstAired: %s", firstAired.c_str());
 | 
			
		||||
    tell(0, "Network: %s", network.c_str());
 | 
			
		||||
    tell(0, "Status: %s", status.c_str());
 | 
			
		||||
    tell(0, "Genre: %s", genre.c_str());
 | 
			
		||||
    tell(0, "Rating: %f", rating);
 | 
			
		||||
    tell(0, "--------------------------- Media ----------------------------------");
 | 
			
		||||
    for (vector<cTVDBMedia*>::iterator it = posters.begin(); it != posters.end(); it++) {
 | 
			
		||||
        cTVDBMedia *m = *it;
 | 
			
		||||
        tell(0, "Poster %d, Path: %s", m->mediaType, m->path.c_str());
 | 
			
		||||
        tell(0, "width %d, height %d", m->width, m->height);
 | 
			
		||||
    }
 | 
			
		||||
    for (vector<cTVDBMedia*>::iterator it = banners.begin(); it != banners.end(); it++) {
 | 
			
		||||
        cTVDBMedia *m = *it;
 | 
			
		||||
        tell(0, "Banner %d, Path: %s", m->mediaType, m->path.c_str());
 | 
			
		||||
        tell(0, "width %d, height %d", m->width, m->height);
 | 
			
		||||
    }
 | 
			
		||||
    for (vector<cTVDBMedia*>::iterator it = fanart.begin(); it != fanart.end(); it++) {
 | 
			
		||||
        cTVDBMedia *m = *it;
 | 
			
		||||
        tell(0, "Fanart %d, Path: %s", m->mediaType, m->path.c_str());
 | 
			
		||||
        tell(0, "width %d, height %d", m->width, m->height);
 | 
			
		||||
    }
 | 
			
		||||
    tell(0, "--------------------------- Episodes ----------------------------------");
 | 
			
		||||
    for (map<int, cTVDBEpisode*>::iterator it = episodes.begin(); it != episodes.end(); it++) {
 | 
			
		||||
        cTVDBEpisode *e = it->second;
 | 
			
		||||
        tell(0, "Episode %d, Name: %s", e->id, e->name.c_str());
 | 
			
		||||
        if (e->episodeImage) {
 | 
			
		||||
            tell(0, "Episode Image: %d x %d, Path: %s", e->episodeImage->width, e->episodeImage->height, e->episodeImage->path.c_str());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    tell(0, "--------------------------- Season Posters ----------------------------------");
 | 
			
		||||
    for (map<int, cTVDBMedia*>::iterator it = seasonPosters.begin(); it != seasonPosters.end(); it++) {
 | 
			
		||||
        int season = it->first;
 | 
			
		||||
        cTVDBMedia *m = it->second;
 | 
			
		||||
        tell(0, "Season %d, %d x %d, Path: %s", season, m->width, m->height, m->path.c_str());
 | 
			
		||||
    }
 | 
			
		||||
    tell(0, "--------------------------- Actors ----------------------------------");
 | 
			
		||||
    for (map<int, cTVDBActor*>::iterator it = actors.begin(); it != actors.end(); it++) {
 | 
			
		||||
        cTVDBActor *a = it->second;
 | 
			
		||||
        tell(0, "Actor %d, Name: %s, Role %s", a->id, a->name.c_str(), a->role.c_str());
 | 
			
		||||
        if (a->actorThumb) {
 | 
			
		||||
            tell(0, "Thumb: %d x %d, Path: %s", a->actorThumb->width, a->actorThumb->height, a->actorThumb->path.c_str());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (posterThumb) {
 | 
			
		||||
        tell(0, "posterThumb path %s, width %d, height %d", posterThumb->path.c_str(), posterThumb->width, posterThumb->height);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										143
									
								
								tvdbseries.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								tvdbseries.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,143 @@
 | 
			
		||||
#ifndef __TVSCRAPER_TVDBSERIES_H
 | 
			
		||||
#define __TVSCRAPER_TVDBSERIES_H
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <set>
 | 
			
		||||
#include <utility>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include "services.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
enum mediaSeries {
 | 
			
		||||
    msBanner1,
 | 
			
		||||
    msBanner2,
 | 
			
		||||
    msBanner3,
 | 
			
		||||
    msPoster1,
 | 
			
		||||
    msPoster2,
 | 
			
		||||
    msPoster3,
 | 
			
		||||
    msSeasonPoster,
 | 
			
		||||
    msFanart1,
 | 
			
		||||
    msFanart2,
 | 
			
		||||
    msFanart3,
 | 
			
		||||
    msEpisodePic,
 | 
			
		||||
    msActorThumb,
 | 
			
		||||
    msPosterThumb,
 | 
			
		||||
    msSeasonPosterThumb,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// --- cTVDBMedia -------------------------------------------------------------
 | 
			
		||||
class cTVDBMedia {
 | 
			
		||||
public:
 | 
			
		||||
    cTVDBMedia(void) {
 | 
			
		||||
        path = "";
 | 
			
		||||
        mediaType = msBanner1;
 | 
			
		||||
        width = 0;
 | 
			
		||||
        height = 0;
 | 
			
		||||
    };
 | 
			
		||||
    ~cTVDBMedia(void) {
 | 
			
		||||
    };
 | 
			
		||||
    string path;
 | 
			
		||||
    int mediaType;
 | 
			
		||||
    int width;
 | 
			
		||||
    int height;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// --- cTVDBEpisode -------------------------------------------------------------
 | 
			
		||||
class cTVDBEpisode {
 | 
			
		||||
public:
 | 
			
		||||
    cTVDBEpisode(void) {
 | 
			
		||||
        id = 0;
 | 
			
		||||
        number = 0;
 | 
			
		||||
        season = 0;
 | 
			
		||||
        name = "";
 | 
			
		||||
        firstAired = "";
 | 
			
		||||
        guestStars = "";
 | 
			
		||||
        overview = "";
 | 
			
		||||
        rating = 0.0;
 | 
			
		||||
        episodeImage = NULL;
 | 
			
		||||
    };
 | 
			
		||||
    ~cTVDBEpisode(void) {
 | 
			
		||||
        if (episodeImage)
 | 
			
		||||
            delete episodeImage;
 | 
			
		||||
    };
 | 
			
		||||
    int id;
 | 
			
		||||
    int number;
 | 
			
		||||
    int season;
 | 
			
		||||
    string name;
 | 
			
		||||
    string firstAired;
 | 
			
		||||
    string guestStars;
 | 
			
		||||
    string overview;
 | 
			
		||||
    float rating;
 | 
			
		||||
    cTVDBMedia *episodeImage;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// --- cTVDBActor -------------------------------------------------------------
 | 
			
		||||
class cTVDBActor {
 | 
			
		||||
public:
 | 
			
		||||
    cTVDBActor(void) {
 | 
			
		||||
        id = 0;
 | 
			
		||||
        name = "";
 | 
			
		||||
        role = "";
 | 
			
		||||
        thumbWidth = 0;
 | 
			
		||||
        thumbHeight = 0;
 | 
			
		||||
        actorThumb = NULL;
 | 
			
		||||
    };
 | 
			
		||||
    ~cTVDBActor(void) {
 | 
			
		||||
        if (actorThumb)
 | 
			
		||||
            delete actorThumb;
 | 
			
		||||
    };
 | 
			
		||||
    int id;
 | 
			
		||||
    string name;
 | 
			
		||||
    string role;
 | 
			
		||||
    int thumbWidth;
 | 
			
		||||
    int thumbHeight;
 | 
			
		||||
    cTVDBMedia *actorThumb;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// --- cTVDBSeries -------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
class cTVDBSeries {
 | 
			
		||||
private:
 | 
			
		||||
    map<int, cTVDBEpisode*> episodes;
 | 
			
		||||
    map<int, cTVDBActor*> actors;
 | 
			
		||||
    vector<cTVDBMedia*> posters;
 | 
			
		||||
    vector<cTVDBMedia*> banners;
 | 
			
		||||
    vector<cTVDBMedia*> fanart;
 | 
			
		||||
    map<int, cTVDBMedia*> seasonPosters;
 | 
			
		||||
    map<int, cTVDBMedia*> seasonPosterThumbs;
 | 
			
		||||
    cTVDBMedia *posterThumb;
 | 
			
		||||
public:
 | 
			
		||||
    cTVDBSeries(void);
 | 
			
		||||
    virtual ~cTVDBSeries(void);
 | 
			
		||||
    int id;
 | 
			
		||||
    string name;
 | 
			
		||||
    string overview;
 | 
			
		||||
    string firstAired;
 | 
			
		||||
    string network;
 | 
			
		||||
    string genre;
 | 
			
		||||
    float rating;
 | 
			
		||||
    string status;
 | 
			
		||||
    void InsertEpisode(cTVDBEpisode *episode);
 | 
			
		||||
    void InsertEpisodeImage(int episodeId, int width, int height, string path);
 | 
			
		||||
    void InsertActor(cTVDBActor *actor);
 | 
			
		||||
    void InsertActorThumb(int actorId, int imgWidth, int imgHeight, string path);
 | 
			
		||||
    void InsertMedia(int mediaType, int imgWidth, int imgHeight, string path, int season = 0);
 | 
			
		||||
    //Getter for Serivice Calls
 | 
			
		||||
    void GetEpisode(int episodeId, cEpisode *e);
 | 
			
		||||
    void GetPosters(vector<cTvMedia> *p);
 | 
			
		||||
    bool GetPoster(cTvMedia *p);
 | 
			
		||||
    bool GetPosterThumb(cTvMedia *p);
 | 
			
		||||
    void GetBanners(vector<cTvMedia> *b);
 | 
			
		||||
    bool GetRandomBanner(cTvMedia *b);
 | 
			
		||||
    void GetFanart(vector<cTvMedia> *f);
 | 
			
		||||
    void GetSeasonPoster(int episodeId, cTvMedia *sp);
 | 
			
		||||
    void GetActors(vector<cActor> *a);
 | 
			
		||||
    void Dump(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif //__TVSCRAPER_TVDBSERIES_H
 | 
			
		||||
							
								
								
									
										87
									
								
								update.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								update.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
#ifndef __UPDATE_H
 | 
			
		||||
#define __UPDATE_H
 | 
			
		||||
 | 
			
		||||
#include <mysql/mysql.h>
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
#include <vdr/thread.h>
 | 
			
		||||
#include "lib/common.h"
 | 
			
		||||
#include "lib/db.h"
 | 
			
		||||
#include "lib/tabledef.h"
 | 
			
		||||
#include "scrapmanager.h"
 | 
			
		||||
 | 
			
		||||
#define EPGDNAME "epgd"
 | 
			
		||||
 | 
			
		||||
class cUpdate : public cThread  {
 | 
			
		||||
    private:
 | 
			
		||||
        cScrapManager *scrapManager;
 | 
			
		||||
        string imgPathSeries;
 | 
			
		||||
        string imgPathMovies;
 | 
			
		||||
        bool withutf8;
 | 
			
		||||
        bool loopActive;
 | 
			
		||||
        cDbConnection* connection;
 | 
			
		||||
        cTableVdrs* vdrDb;
 | 
			
		||||
        cTableEvents* tEvents;
 | 
			
		||||
        cTableSeries* tSeries;
 | 
			
		||||
        cTableSeriesEpisode* tEpisodes;
 | 
			
		||||
        cTableSeriesMedia* tSeriesMedia;
 | 
			
		||||
        cTableSeriesActor* tSeriesActors;
 | 
			
		||||
        cTableMovies* tMovies;
 | 
			
		||||
        cTableMovieActor* tMovieActor;
 | 
			
		||||
        cTableMovieActors* tMovieActors;
 | 
			
		||||
        cTableMovieMedia* tMovieMedia;
 | 
			
		||||
        cTableRecordings* tRecordings;
 | 
			
		||||
        int lastScrap;
 | 
			
		||||
        cCondVar waitCondition;
 | 
			
		||||
        cMutex mutex;
 | 
			
		||||
        bool forceUpdate;
 | 
			
		||||
        bool forceRecordingUpdate;
 | 
			
		||||
        bool forceVideoDirUpdate;
 | 
			
		||||
        bool forceScrapInfoUpdate;
 | 
			
		||||
        bool forceCleanupRecordingDb;
 | 
			
		||||
        int exitDb();
 | 
			
		||||
        int dbConnected(int force = no) { return connection && (!force || connection->check() == success); };
 | 
			
		||||
        int CheckConnection(int& timeout);
 | 
			
		||||
        bool CheckEpgdBusy(void);
 | 
			
		||||
        void Action(void);
 | 
			
		||||
        int ReadScrapedEvents(void);
 | 
			
		||||
        //SERIES
 | 
			
		||||
        int ReadSeries(bool isRec);
 | 
			
		||||
        void ReadEpisode(int episodeId, cTVDBSeries *series, string path);
 | 
			
		||||
        void LoadEpisodeImage(cTVDBSeries *series, int episodeId, string path);
 | 
			
		||||
        void LoadSeasonPoster(cTVDBSeries *series, int season, string path);
 | 
			
		||||
        void ReadSeriesActors(cTVDBSeries *series, string path);
 | 
			
		||||
        void LoadSeriesMedia(cTVDBSeries *series, string path);
 | 
			
		||||
        string LoadMediaSeries(int seriesId, int mediaType, string path, int width, int height);
 | 
			
		||||
        void LoadSeriesActorThumb(cTVDBSeries *series, int actorId, string path);
 | 
			
		||||
        //MOVIES
 | 
			
		||||
        int ReadMovies(bool isRec);
 | 
			
		||||
        void ReadMovieActors(cMovieDbMovie *movie);
 | 
			
		||||
        void LoadMovieActorThumbs(cMovieDbMovie *movie);
 | 
			
		||||
        void LoadMovieMedia(cMovieDbMovie *movie, string moviePath);
 | 
			
		||||
        string LoadMediaMovie(int movieId, int mediaType, string path, int width, int height);
 | 
			
		||||
        //RECORDINGS
 | 
			
		||||
        int ReadRecordings(void);
 | 
			
		||||
        int ScanVideoDir(void);
 | 
			
		||||
        int ScanVideoDirScrapInfo(void);
 | 
			
		||||
        bool LoadRecording(int eventId, string recName);
 | 
			
		||||
        bool ScrapInfoChanged(int scrapInfoMovieID, int scrapInfoSeriesID, int scrapInfoEpisodeID);
 | 
			
		||||
        void ReadScrapInfo(string recDir, int &scrapInfoMovieID, int &scrapInfoSeriesID, int &scrapInfoEpisodeID);
 | 
			
		||||
        //CLEANUP
 | 
			
		||||
        int CleanupSeries(void);
 | 
			
		||||
        int CleanupMovies(void);
 | 
			
		||||
        int CleanupRecordings(void);
 | 
			
		||||
    public:
 | 
			
		||||
        cUpdate(cScrapManager *manager);
 | 
			
		||||
        virtual ~cUpdate(void);
 | 
			
		||||
        int initDb();
 | 
			
		||||
        void Stop(void);
 | 
			
		||||
        void ForceUpdate(void);
 | 
			
		||||
        void ForceRecordingUpdate(void);
 | 
			
		||||
        void ForceVideoDirUpdate(void);
 | 
			
		||||
        void ForceScrapInfoUpdate(void);
 | 
			
		||||
        void TriggerCleanRecordingsDB(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//***************************************************************************
 | 
			
		||||
#endif //__UPDATE_H
 | 
			
		||||
		Reference in New Issue
	
	Block a user