feat: add videodb media index with Docker stack
- Add videodb PHP/MySQL media collection manager (Blu-ray, DVD, CD) - Dockerfile: PHP 8.1 + Apache with GD/mysqli/exif extensions - docker-compose.yml: app on port 6761 + MySQL 8.0 with health checks - docker-entrypoint.sh: auto-generates config.inc.php from env vars, waits for MySQL, initializes DB schema idempotently - init-db.php: CLI schema installer using app's own prefix_query() logic - Persistent volumes for DB, cache, and cover images Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
47
docker-compose.yml
Normal file
47
docker-compose.yml
Normal file
@@ -0,0 +1,47 @@
|
||||
services:
|
||||
|
||||
app:
|
||||
build:
|
||||
context: ./videodb
|
||||
container_name: videodb_app
|
||||
ports:
|
||||
- "6761:80"
|
||||
environment:
|
||||
DB_HOST: db
|
||||
DB_USER: videodb
|
||||
DB_PASSWORD: videodb_secret
|
||||
DB_NAME: videodb
|
||||
DB_PREFIX: videodb_
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
# Persist cover images and cached thumbnails across rebuilds
|
||||
- videodb_cache:/var/www/html/cache
|
||||
- videodb_images:/var/www/html/images
|
||||
restart: unless-stopped
|
||||
|
||||
db:
|
||||
image: mysql:8.0
|
||||
container_name: videodb_db
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: root_secret
|
||||
MYSQL_DATABASE: videodb
|
||||
MYSQL_USER: videodb
|
||||
MYSQL_PASSWORD: videodb_secret
|
||||
volumes:
|
||||
- videodb_db:/var/lib/mysql
|
||||
# MySQL 8 defaults to caching_sha2_password; keep native auth for broad client compat
|
||||
command: --default-authentication-plugin=mysql_native_password
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "videodb", "-pvideodb_secret"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
start_period: 30s
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
videodb_db:
|
||||
videodb_cache:
|
||||
videodb_images:
|
||||
7
videodb/.gitignore
vendored
Normal file
7
videodb/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# Files to be ignored by git
|
||||
config.inc.php
|
||||
cache
|
||||
# ignore logfiles
|
||||
*.log
|
||||
**/Thumbs.db
|
||||
.idea
|
||||
39
videodb/.htaccess
Normal file
39
videodb/.htaccess
Normal file
@@ -0,0 +1,39 @@
|
||||
#
|
||||
# Apache access control
|
||||
#
|
||||
# @author Andreas Goetz <cpuidle@gmx.de>
|
||||
# $Id: .htaccess,v 1.2 2008/04/29 13:32:48 andig2 Exp $
|
||||
#
|
||||
|
||||
# Don't show directory listings for URLs which map to a directory.
|
||||
Options -Indexes
|
||||
|
||||
# go directly to index.php
|
||||
DirectoryIndex index.php
|
||||
|
||||
# make sure Apache doesn't set default charset on it's own (bug 1943523)
|
||||
AddDefaultCharset utf-8
|
||||
|
||||
# PHP 4, Apache 1.
|
||||
<IfModule mod_php4.c>
|
||||
php_value default_charset utf-8
|
||||
</IfModule>
|
||||
|
||||
# PHP 4, Apache 2.
|
||||
<IfModule sapi_apache2.c>
|
||||
php_value default_charset utf-8
|
||||
</IfModule>
|
||||
|
||||
# PHP 5, Apache 1 and 2.
|
||||
<IfModule mod_php5.c>
|
||||
php_value default_charset utf-8
|
||||
</IfModule>
|
||||
|
||||
# enable compression
|
||||
<IfModule mod_deflate_DISABLED.c>
|
||||
# Deflate zum zippen
|
||||
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/javascript text/css
|
||||
BrowserMatch ^Mozilla/4 gzip-only-text/html
|
||||
BrowserMatch ^Mozilla/4.0[678] no-gzip
|
||||
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
|
||||
</IfModule>
|
||||
51
videodb/Dockerfile
Normal file
51
videodb/Dockerfile
Normal file
@@ -0,0 +1,51 @@
|
||||
FROM php:8.1-apache
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libpng-dev \
|
||||
libjpeg-dev \
|
||||
libfreetype6-dev \
|
||||
default-mysql-client \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install PHP extensions needed by videoDB
|
||||
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
|
||||
&& docker-php-ext-install -j$(nproc) \
|
||||
gd \
|
||||
mysqli \
|
||||
exif \
|
||||
mbstring
|
||||
|
||||
# Enable Apache mod_rewrite for .htaccess
|
||||
RUN a2enmod rewrite
|
||||
|
||||
# Allow .htaccess overrides in document root
|
||||
RUN sed -i '/<Directory \/var\/www\/>/,/<\/Directory>/ s/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf
|
||||
|
||||
# Set working directory to document root
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# Copy application (including vendor which is committed to the repo)
|
||||
COPY . .
|
||||
|
||||
# Create cache directories and set permissions
|
||||
RUN mkdir -p \
|
||||
cache/smarty \
|
||||
cache/imdb \
|
||||
cache/img \
|
||||
cache/thumbs \
|
||||
cache/javascript \
|
||||
cache/local \
|
||||
&& chown -R www-data:www-data \
|
||||
cache \
|
||||
images
|
||||
|
||||
# Copy entrypoint and db-init scripts
|
||||
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
||||
COPY init-db.php /usr/local/bin/init-db.php
|
||||
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
ENTRYPOINT ["docker-entrypoint.sh"]
|
||||
CMD ["apache2-foreground"]
|
||||
34
videodb/README.md
Normal file
34
videodb/README.md
Normal file
@@ -0,0 +1,34 @@
|
||||
videoDB
|
||||
=======
|
||||
|
||||
VideoDB is a PHP-based web application to manage a personal video collection. Multiple video types are supported, ranging from VHS tapes and DVDs to Blu-ray discs and DivX files on hard-disc. Even video games are supported.
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
### Browse
|
||||
|
||||
You can use videoDB to manage your video and CD collection, be it DVD, BluRay or plain Files:
|
||||
|
||||

|
||||
|
||||
### View
|
||||
|
||||

|
||||
|
||||
### Edit
|
||||
All data is editable in nice layed out forms:
|
||||
|
||||

|
||||
|
||||
### IMDB
|
||||
|
||||
New movies are easily added directly from IMDB or other sources:
|
||||
|
||||

|
||||
|
||||
### Config
|
||||
|
||||
videoDB is also highly customizable- almost every aspect can be changed from template selection to detailed customization:
|
||||
|
||||

|
||||
111
videodb/borrow.php
Normal file
111
videodb/borrow.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* Borrow Manager
|
||||
*
|
||||
* Handles lending of disks
|
||||
*
|
||||
* @package videoDB
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @version $Id: borrow.php,v 2.21 2013/03/10 16:20:10 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './core/output.php';
|
||||
|
||||
// check for localnet
|
||||
localnet_or_die();
|
||||
|
||||
// permission check
|
||||
permission_or_die(PERM_WRITE, PERM_ANY);
|
||||
|
||||
/**
|
||||
* input
|
||||
*/
|
||||
$diskid = req_string('diskid');
|
||||
$return = req_string('return');
|
||||
$who = req_string('who');
|
||||
|
||||
// borrowmanagement for single disk
|
||||
$editable = false;
|
||||
$dt = null;
|
||||
if (!empty($diskid))
|
||||
{
|
||||
if (check_permission(PERM_WRITE, get_owner_id($diskid,true)))
|
||||
{
|
||||
$editable = true;
|
||||
if ($return) {
|
||||
$SQL = "DELETE FROM ".TBL_LENT." WHERE diskid = '".escapeSQL($diskid)."'";
|
||||
runSQL($SQL);
|
||||
}
|
||||
if (!empty($who)) {
|
||||
$SQL = "INSERT INTO ".TBL_LENT." SET who = '".escapeSQL($who)."', diskid = '".escapeSQL($diskid)."'";
|
||||
runSQL($SQL);
|
||||
}
|
||||
|
||||
$SQL = "SELECT who, DATE_FORMAT(dt,'%d.%m.%Y') AS dt
|
||||
FROM ".TBL_LENT."
|
||||
WHERE diskid = '".escapeSQL($diskid)."'";
|
||||
$result = runSQL($SQL);
|
||||
|
||||
if (isset($result[0]['who']))
|
||||
{ $who = $result[0]['who']; }
|
||||
if (isset($result[0]['dt']))
|
||||
{ $dt = $result[0]['dt']; }
|
||||
}
|
||||
}
|
||||
|
||||
$WHERES = '';
|
||||
$JOINS = '';
|
||||
|
||||
if ($config['multiuser'])
|
||||
{
|
||||
// get owner from session- or use current user
|
||||
session_default_owner();
|
||||
// build html select box
|
||||
$all = $lang['filter_any'];
|
||||
$smarty->assign('owners', out_owners(array($all => $all), PERM_READ));
|
||||
$smarty->assign('owner', $owner);
|
||||
|
||||
// if we don't have read all permissions, limit visibility using cross-user permissions
|
||||
if (!check_permission(PERM_READ))
|
||||
{
|
||||
$JOINS = ' LEFT JOIN '.TBL_PERMISSIONS.' ON '.TBL_DATA.'.owner_id = '.TBL_PERMISSIONS.'.to_uid';
|
||||
$WHERES .= ' AND '.TBL_PERMISSIONS.'.from_uid = '.get_current_user_id().' AND '.TBL_PERMISSIONS.'.permissions & '.PERM_READ.' != 0';
|
||||
}
|
||||
|
||||
// further limit to single owner
|
||||
if ($owner != $all) $WHERES .= " AND ".TBL_USERS.".name = '".escapeSQL($owner)."'";
|
||||
}
|
||||
|
||||
// overview on lent disks
|
||||
$SQL = "SELECT who, DATE_FORMAT(dt,'%d.%m.%Y') as dt, ".TBL_LENT.".diskid,
|
||||
CASE WHEN subtitle = '' THEN title ELSE CONCAT(title,' - ',subtitle) END AS title,
|
||||
".TBL_DATA.".id, COUNT(".TBL_LENT.".diskid) AS count, ".TBL_USERS.".name AS owner
|
||||
FROM ".TBL_LENT.", ".TBL_DATA."
|
||||
LEFT JOIN ".TBL_USERS." ON owner_id = ".TBL_USERS.".id
|
||||
$JOINS
|
||||
WHERE ".TBL_LENT.".diskid = ".TBL_DATA.".diskid
|
||||
$WHERES
|
||||
GROUP BY ".TBL_LENT.".diskid, ".TBL_DATA.".id
|
||||
ORDER BY who, ".TBL_LENT.".diskid";
|
||||
$result = runSQL($SQL);
|
||||
|
||||
// check permissions
|
||||
for($i=0; $i < count($result); $i++)
|
||||
{
|
||||
$result[$i]['editable'] = check_permission(PERM_WRITE, get_userid($result[$i]['owner']));
|
||||
}
|
||||
|
||||
// prepare templates
|
||||
tpl_page();
|
||||
|
||||
$smarty->assign('diskid', $diskid);
|
||||
$smarty->assign('who', $who);
|
||||
$smarty->assign('dt', $dt);
|
||||
$smarty->assign('editable', $editable);
|
||||
$smarty->assign('borrowlist', $result);
|
||||
|
||||
// display templates
|
||||
tpl_display('borrow.tpl');
|
||||
|
||||
|
||||
80
videodb/borrowask.php
Normal file
80
videodb/borrowask.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* Ask to borrow form
|
||||
*
|
||||
* Allows to request a movie
|
||||
*
|
||||
* @package videoDB
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @version $Id: borrowask.php,v 2.13 2008/06/15 13:58:13 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
|
||||
// Auth-Checks
|
||||
$user_id = get_current_user_id();
|
||||
$user = get_username($user_id);
|
||||
|
||||
if (empty($user))
|
||||
{
|
||||
errorpage('Access denied','You don\'t have enough permissions to access this
|
||||
page try to <a href="login.php">login</a> first. (This feature is not
|
||||
available in Single User Mode)');
|
||||
}
|
||||
|
||||
/**
|
||||
* input
|
||||
*/
|
||||
$id = req_int('id');
|
||||
$diskid = req_string('diskid');
|
||||
|
||||
if (empty($id) || empty($diskid))
|
||||
{
|
||||
errorpage('Error', 'No Ids given');
|
||||
}
|
||||
|
||||
$owner = get_owner($diskid, true);
|
||||
$result = runSQL('SELECT email FROM '.TBL_USERS." WHERE name = '".escapeSQL($owner)."'");
|
||||
$owner_email = $result[0]['email'];
|
||||
$result = runSQL('SELECT email FROM '.TBL_USERS." WHERE id = '".escapeSQL($user_id)."'");
|
||||
$user_email = $result[0]['email'];
|
||||
$result = runSQL('SELECT title FROM '.TBL_DATA." WHERE id = '".escapeSQL($id)."'");
|
||||
$title = $result[0]['title'];
|
||||
|
||||
$mail = $lang['msg_borrowaskmail'];
|
||||
$subject = $lang['msg_borrowasksubject'];
|
||||
$url = 'http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['SCRIPT_NAME']).'/show.php?id='.$id;
|
||||
|
||||
// replace place holders
|
||||
$mail = str_replace('%id%', $id, $mail);
|
||||
$mail = str_replace('%diskid%', $diskid, $mail);
|
||||
$mail = str_replace('%owner%', $owner, $mail);
|
||||
$mail = str_replace('%ownermail%', $owner_email, $mail);
|
||||
$mail = str_replace('%user%', $user, $mail);
|
||||
$mail = str_replace('%usermail%', $user_email, $mail);
|
||||
$mail = str_replace('%title%', $title, $mail);
|
||||
$mail = str_replace('%url%', $url, $mail);
|
||||
|
||||
$subject = str_replace('%id%', $id, $subject);
|
||||
$subject = str_replace('%diskid%', $diskid, $subject);
|
||||
$subject = str_replace('%owner%', $owner, $subject);
|
||||
$subject = str_replace('%ownermail%', $owner_email, $subject);
|
||||
$subject = str_replace('%user%', $user, $subject);
|
||||
$subject = str_replace('%usermail%', $user_email, $subject);
|
||||
$subject = str_replace('%title%', $title, $subject);
|
||||
$subject = str_replace('%url%', $url, $subject);
|
||||
|
||||
|
||||
// prepare templates
|
||||
tpl_page();
|
||||
|
||||
/*
|
||||
$smarty->assign('success', @mail($owner_email, $subject, $mail));
|
||||
Fix for https://sourceforge.net/tracker/?func=detail&atid=586362&aid=1570618&group_id=88349
|
||||
*/
|
||||
$smarty->assign('success', @mail($owner_email, $subject, $mail, "From: $user <$user_email>\r\nReply-To: $user_email\r\n"));
|
||||
|
||||
// display templates
|
||||
smarty_display('borrowask.tpl');
|
||||
|
||||
|
||||
18
videodb/composer.json
Normal file
18
videodb/composer.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "andig/videodb",
|
||||
"type": "project",
|
||||
"require": {
|
||||
"guzzlehttp/guzzle": "^6.3",
|
||||
"smarty/smarty": "^3.1",
|
||||
"pear/ole": "^v1.0.0RC8",
|
||||
"pear/spreadsheet_excel_writer": "^v0.9.7",
|
||||
"setasign/fpdf": "^1.8",
|
||||
"james-heinrich/phpthumb": "v1.7.19"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "andig",
|
||||
"email": "cpuidle@gmx.de"
|
||||
}
|
||||
]
|
||||
}
|
||||
1256
videodb/composer.lock
generated
Normal file
1256
videodb/composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
357
videodb/config.sample.php
Normal file
357
videodb/config.sample.php
Normal file
@@ -0,0 +1,357 @@
|
||||
<?php
|
||||
/**
|
||||
* Global configuration file
|
||||
*
|
||||
* In here you can set the database connection settings and a
|
||||
* few other configuration options that are not accessible
|
||||
* through the setup/profile pages. Copy this file to config.inc.php
|
||||
* and view and fill each item as required. Database configuration
|
||||
* is the most important part, all other parts are only needed
|
||||
* when needed ;-)
|
||||
*
|
||||
* @package Setup
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: config.sample.php,v 1.10 2012/06/14 17:17:36 andig2 Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Database configuration
|
||||
*/
|
||||
|
||||
/**
|
||||
* the hostname of your database server
|
||||
* @default 'localhost'
|
||||
*/
|
||||
$config['db_server'] = 'localhost';
|
||||
|
||||
/**
|
||||
* the username of your database server
|
||||
* @default 'videodb'
|
||||
*/
|
||||
$config['db_user'] = 'videodb';
|
||||
|
||||
/**
|
||||
* the password for above user
|
||||
* @default ''
|
||||
*/
|
||||
$config['db_password'] = '';
|
||||
|
||||
/**
|
||||
* the name of the database
|
||||
* @default 'videodb'
|
||||
*/
|
||||
$config['db_database'] = 'videodb';
|
||||
|
||||
/**
|
||||
* an optional prefix for the tables (for use in hosting environments)
|
||||
* can be empty
|
||||
* @default: 'videodb_'
|
||||
*/
|
||||
$config['db_prefix'] = 'videodb_';
|
||||
|
||||
/**
|
||||
* Offline flag, set to 1 to take videoDB offline
|
||||
* @default 0
|
||||
*/
|
||||
$config['offline'] = 0;
|
||||
|
||||
/**
|
||||
* Debug options, set to 1 to enable debug logs
|
||||
* Usually leave this at 0 (to keep videoDB fast)
|
||||
* @default 0
|
||||
*/
|
||||
$config['debug'] = 0;
|
||||
|
||||
/**
|
||||
* HttpClient logging, is for debugging only
|
||||
* Usually leave this at 0 (to keep videoDB fast)
|
||||
* @default 0
|
||||
*/
|
||||
$config['httpclientlog'] = 0;
|
||||
|
||||
/**
|
||||
* Boxee box configuration
|
||||
* If you still have and use one of these you can enter
|
||||
* the hostname and port used. If not, leave as-is
|
||||
* @default ''
|
||||
*/
|
||||
$config['boxeeHost'] = '';
|
||||
/**
|
||||
* @default 9090
|
||||
*/
|
||||
$config['boxeePort'] = 9090;
|
||||
|
||||
/**
|
||||
* Cache configuration
|
||||
* This setting determines how long to keep remote assets locally
|
||||
* After this many seconds they are considered stale and will be
|
||||
* fetched again for a fresh copy. You can set this to 0, but you
|
||||
* probably want to keep this at the default or higher.
|
||||
* @default 604800 (one week, 7*24*60*60)
|
||||
*/
|
||||
$config['IMDBage'] = 604800;
|
||||
|
||||
/**
|
||||
* Hierarchical cache folders, used to distribute the cached files
|
||||
* over multiple folders instead of one, prevents hitting filesystem
|
||||
* limits in due time. Set to 1 to enable, 0 to disable
|
||||
* @default 1
|
||||
*/
|
||||
$config['hierarchical'] = 1;
|
||||
|
||||
/**
|
||||
* Pruning means automatically cleaning the cache folders, removing
|
||||
* old/stale files. Set to 1 to enable, 0 to disable
|
||||
* @default 1
|
||||
*/
|
||||
$config['cache_pruning'] = 1;
|
||||
|
||||
/**
|
||||
* Enable use of HTTP 304 headers for unmodified content to save bandwidth
|
||||
* Set to 1 to enable, 0 to disable
|
||||
* @default 0
|
||||
*/
|
||||
$config['http_caching'] = 0;
|
||||
|
||||
/**
|
||||
* Defaults for external data lookup when editing entries
|
||||
* Set to 0 to ignore external data
|
||||
* Set to 1 to lookup missing data
|
||||
* Set to 2 to overwrite all entered data with the external version
|
||||
* @default 0
|
||||
*/
|
||||
$config['lookupdefault_edit'] = 0;
|
||||
|
||||
/**
|
||||
* Defaults for external data lookup when adding entries
|
||||
* Set to 0 to ignore external data
|
||||
* Set to 1 to lookup missing data
|
||||
* Set to 2 to overwrite all entered data with the external version
|
||||
* @default 2
|
||||
*/
|
||||
$config['lookupdefault_new'] = 2;
|
||||
|
||||
/**
|
||||
* Amount of digits which are automatically generated as DiskID
|
||||
* if "Automatic DiskID" is enabled in the configuration tab
|
||||
* @default 4
|
||||
*/
|
||||
$config['diskid_digits'] = 4;
|
||||
|
||||
/**
|
||||
* Thumbnail configuration
|
||||
*
|
||||
* If you're running videodb over a low bandwidth connection with many users or want to enhance
|
||||
* image quality by applying smooth scaling, use the following settings to control the behavior.
|
||||
*
|
||||
* Define when thumbnails are created and which jpeg quality to use:
|
||||
* -1 : no scaling - use of thumbnails is disabled
|
||||
* 0 : reduce only - create thumbnails when requested image dimensions are smaller than original image
|
||||
* 1 : always scale - create thumbnails for all images (applies aliasing when scaling)
|
||||
*
|
||||
* or define a positive integer to check filesize - thumbnail is created when existing file is bigger
|
||||
* than the specified value in bytes
|
||||
* @default 1
|
||||
*/
|
||||
$config['thumbnail_level'] = 1;
|
||||
|
||||
/**
|
||||
* Control the quality setting when generating jpeg images
|
||||
* Is a range from 0 to 100, where 0 is the lowest quality with smallest filesize
|
||||
* and 100 is the best quality with largest filesize. Industry standard setting is 70
|
||||
* @default 80
|
||||
*/
|
||||
$config['thumbnail_quality'] = 80;
|
||||
|
||||
/**
|
||||
* Export settings
|
||||
*/
|
||||
|
||||
/**
|
||||
* XML Import/Export
|
||||
* Set to 1 to enable XML data im/export, set to 0 to disable
|
||||
* @note import is currently broken
|
||||
* @default 0
|
||||
*/
|
||||
$config['xml'] = 0;
|
||||
|
||||
/**
|
||||
*XML export thumbnail URLs
|
||||
* Set to 1 to enable, set to 0 to disable
|
||||
* @default 0
|
||||
*/
|
||||
$config['xml_thumbnails'] = 0;
|
||||
|
||||
/**
|
||||
* RSS Feed
|
||||
* Set to 1 to enable RSS Feed, set to 0 to disable
|
||||
* @default 1
|
||||
*/
|
||||
$config['rss'] = 1;
|
||||
|
||||
/**
|
||||
* PDF Export
|
||||
* set to 1 to enable PDF data export, set to 0 to disable
|
||||
* @default 1
|
||||
*/
|
||||
$config['pdf'] = 1;
|
||||
|
||||
/**
|
||||
* Here you can set the fonts used for title. Available fonts:
|
||||
* - Arial
|
||||
* - Courier
|
||||
* - Helvetica
|
||||
* - Symbol
|
||||
* - Times
|
||||
* - ZapfDingBats
|
||||
* @default 'Arial'
|
||||
*/
|
||||
$config['pdf_font_title'] = 'Arial';
|
||||
|
||||
/**
|
||||
* Here you can set the fonts used for plot. Available fonts:
|
||||
* - Arial
|
||||
* - Courier
|
||||
* - Helvetica
|
||||
* - Symbol
|
||||
* - Times
|
||||
* - ZapfDingBats
|
||||
* @default 'Times'
|
||||
*/
|
||||
$config['pdf_font_plot'] = 'Times';
|
||||
|
||||
/**
|
||||
* Overall font size. Title will be this size and the plot will be one point smaller.
|
||||
* @default 10
|
||||
*/
|
||||
$config['pdf_font_size'] = 10;
|
||||
|
||||
/**
|
||||
* Maximum "rescale" width for images
|
||||
* @default 95
|
||||
*/
|
||||
$config['pdf_image_max_width'] = 95;
|
||||
|
||||
/**
|
||||
* Maximum "rescale" height for images
|
||||
* @default 135
|
||||
*/
|
||||
$config['pdf_image_max_height'] = 135;
|
||||
|
||||
/**
|
||||
* Set the width of the mediatype icon
|
||||
* @default 8
|
||||
*/
|
||||
$config['pdf_image_media_width'] = 8;
|
||||
|
||||
/**
|
||||
* Total Page width
|
||||
* @default 210
|
||||
*/
|
||||
$config['pdf_page_width'] = 210;
|
||||
|
||||
/**
|
||||
* Maximum plot text length
|
||||
* @default 500
|
||||
*/
|
||||
$config['pdf_text_length'] = 500;
|
||||
|
||||
/**
|
||||
* Margins between fields
|
||||
* @default 5
|
||||
*/
|
||||
$config['pdf_margin'] = 5;
|
||||
|
||||
/**
|
||||
* Left margin
|
||||
* @default 5
|
||||
*/
|
||||
$config['pdf_left_margin'] = 5;
|
||||
|
||||
/**
|
||||
* Right margin
|
||||
* @default 5
|
||||
*/
|
||||
$config['pdf_right_margin'] = 5;
|
||||
|
||||
/**
|
||||
* Image height and width on generated PDF
|
||||
* @default 24
|
||||
*/
|
||||
$config['pdf_image_height'] = 24;
|
||||
|
||||
/**
|
||||
* Image width on generated PDF, do not change
|
||||
* @default <calculated-value>
|
||||
*/
|
||||
$config['pdf_image_width'] = intval(($config['pdf_image_max_width'] / $config['pdf_image_max_height']) * $config['pdf_image_height']);
|
||||
|
||||
/**
|
||||
* XLS Export, set to 1 to enable Excel data export, 0 to disable
|
||||
* @default 1
|
||||
*/
|
||||
$config['xls'] = 1;
|
||||
|
||||
/**
|
||||
* Name of the Excel sheet and headline for printing
|
||||
* @default 'VideoDB'
|
||||
*/
|
||||
$config['xls_sheet_title'] = 'VideoDB';
|
||||
|
||||
/**
|
||||
* Filename for the output file without xls extension!
|
||||
* @default 'VideoDB'
|
||||
*/
|
||||
$config['xls_output_filename'] = 'VideoDB';
|
||||
|
||||
/**
|
||||
* Show column headlines in the first row (1=Yes;0=No)
|
||||
* @default 1
|
||||
*/
|
||||
$config['xls_show_headline'] = 1;
|
||||
|
||||
/**
|
||||
* Set background color of unseen movie titles to yellow? (1=Yes;0=No)
|
||||
* @default 1
|
||||
*/
|
||||
$config['xls_mark_unseen'] = 1;
|
||||
|
||||
/**
|
||||
* Set background color of borrowed movies to red? (1=Yes;0=No)
|
||||
* @default 1
|
||||
*/
|
||||
$config['xls_mark_lent'] = 1;
|
||||
|
||||
/**
|
||||
* Build your own list, where you define which fields you want and in
|
||||
* which order they should appear, separated by comma.
|
||||
*
|
||||
* Supported fields are:
|
||||
* title diskid language mediatype runtime year
|
||||
* custom1 custom2 custom3 custom4 owner lent
|
||||
* insertdate genres plot
|
||||
*
|
||||
* The length of the plot is limited to 253 characters!!!
|
||||
*
|
||||
* It's possible to use those fields also as an Excel note. For example if you want
|
||||
* to see the title of the movie, followed by the diskid and the running time. As a
|
||||
* note you want to see the plot next to the title and the owner next to the diskid.
|
||||
* For this example the xls_extra_fields list would look like this:
|
||||
*
|
||||
* $config['xls_extra_fields'] = 'title (plot), diskid (owner), runtime';
|
||||
* @default 'title (plot), diskid, genres, language, mediatype, runtime, year, custom1, custom2, custom3, custom4, insertdate, owner, lent'
|
||||
*/
|
||||
$config['xls_extra_fields'] = 'title (plot), diskid, genres, language, mediatype, runtime, year, custom1, custom2, custom3, custom4, insertdate, owner, lent';
|
||||
|
||||
/**
|
||||
* To get access to FSK18 rated movies in the german dvdb engine you
|
||||
* have to enter your dvdb user id and password. If you don't have a
|
||||
* user you can go to http://www.dvdb.de and click on 'Neu registrieren'.
|
||||
* Don't forget to enter the identification card id to get FSK18 access!
|
||||
* @default ''
|
||||
* @deprecated The dvdb.de website does not appear to exist anymore
|
||||
*/
|
||||
$config['dvdb_user'] = '';
|
||||
$config['dvdb_password'] = '';
|
||||
|
||||
91
videodb/contrib.php
Normal file
91
videodb/contrib.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* Contrib tools index
|
||||
*
|
||||
* @package videoDB
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @version $Id: contrib.php,v 1.3 2005/05/26 12:24:15 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
|
||||
// check for localnet
|
||||
localnet_or_die();
|
||||
|
||||
// multiuser permission check
|
||||
permission_or_die(PERM_WRITE);
|
||||
|
||||
/**
|
||||
* Sort multi-dimensional arrays
|
||||
* (thanks to phpdotnet)
|
||||
*/
|
||||
function multidimsort($array_in, $column)
|
||||
{
|
||||
$multiarray = array_column($array_in, $column);
|
||||
$array_out = array();
|
||||
|
||||
asort($multiarray);
|
||||
|
||||
// traverse new array of index values and add the corresponding element of the input array to the correct position in the output array
|
||||
foreach ($multiarray as $key => $val)
|
||||
{
|
||||
$array_out[] = $array_in[$key];
|
||||
}
|
||||
|
||||
// return the output array which is all nicely sorted by the index you wanted!
|
||||
return $array_out;
|
||||
}
|
||||
|
||||
|
||||
// dynamic contrib loader
|
||||
$files = array();
|
||||
$dirpath = './contrib';
|
||||
|
||||
if ($dh = opendir($dirpath))
|
||||
{
|
||||
while (($filename = readdir($dh)) !== false)
|
||||
{
|
||||
$access = '';
|
||||
if (!preg_match('/.*\.php$/', $filename)) continue;
|
||||
if ($filename == 'index.php') continue;
|
||||
|
||||
$info = array('contrib/'.$filename);
|
||||
$file = $dirpath.'/'.$filename;
|
||||
$content = file_get_contents($file);
|
||||
|
||||
// title
|
||||
if (preg_match('/<TITLE.*?>(.+?)</msi', $content, $title))
|
||||
{
|
||||
$info[1] = $title[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
$info[1] = preg_replace('/\.php$/', '', $filename);
|
||||
}
|
||||
|
||||
// access
|
||||
if (preg_match('/^.*?\*[\t ]+@meta[\t ]+ACCESS:(.*?)\n/i', $content, $access))
|
||||
{
|
||||
$info[2] = trim($access[1]);
|
||||
}
|
||||
|
||||
// add to list of access rights are valid
|
||||
if (empty($info[2]) || check_permission($info[2]))
|
||||
{
|
||||
$files[] = $info;
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
|
||||
// sort by title
|
||||
$files = multidimsort($files, 1);
|
||||
|
||||
// prepare templates
|
||||
tpl_page();
|
||||
$smarty->assign('files', $files);
|
||||
|
||||
// display templates
|
||||
tpl_display('contrib.tpl');
|
||||
|
||||
?>
|
||||
141
videodb/contrib/add_recommended_movies.php
Normal file
141
videodb/contrib/add_recommended_movies.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
* Add recommended movies via IMDB
|
||||
*
|
||||
* @package Contrib
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: add_recommended_movies.php,v 1.8 2014/02/25 21:22:00 kec2 Exp $
|
||||
*/
|
||||
|
||||
// move out of contrib for includes
|
||||
chdir('..');
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './engines/engines.php';
|
||||
|
||||
// since we don't need session functionality, use this as workaround
|
||||
// for php bug #22526 session_start/popen hang
|
||||
session_write_close();
|
||||
|
||||
?>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Find Movie Recommendations</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="description" content="VideoDB" />
|
||||
|
||||
<style>
|
||||
.green { color:green }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<?
|
||||
|
||||
error_reporting(E_ALL ^ E_NOTICE);
|
||||
|
||||
if ($submit)
|
||||
{
|
||||
// validate form data
|
||||
$required_rating = (is_numeric($required_rating)) ? (float) $required_rating : '';
|
||||
$required_year = (is_numeric($required_year)) ? (int) $required_year : '';
|
||||
|
||||
// get list of all videos
|
||||
$SQL = 'SELECT * FROM '.TBL_DATA;
|
||||
if (empty($wishlist)) $SQL .= ' WHERE mediatype != '.MEDIA_WISHLIST;
|
||||
$result = runSQL($SQL);
|
||||
|
||||
foreach ($result as $video)
|
||||
{
|
||||
if (empty($video['imdbID'])) continue;
|
||||
$engine = strtoupper(engineGetEngine($video['imdbID']));
|
||||
echo "Fetching recommendations for <b>{$video['title']}</b> ($engine Id {$video['imdbID']})<br/>";
|
||||
|
||||
$data = engineGetRecommendations($video['imdbID'], $required_rating, $required_year, 'imdb');
|
||||
if (!empty($CLIENTERROR))
|
||||
{
|
||||
echo $CLIENTERROR."<br/>";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (empty($data))
|
||||
{
|
||||
// sometimes there are no recommendations for a movie. This is true for Underworld: imdbId 0320691
|
||||
echo "No recommendations for {$video['title']}.<br/><br/>";
|
||||
continue;
|
||||
}
|
||||
|
||||
echo '<table border="1">';
|
||||
echo " <tr>";
|
||||
echo " <th>Title</th> <th>Year</th> <th>Rating</th> <th>Id</th>";
|
||||
echo " </tr>";
|
||||
|
||||
foreach ($data as $recommended)
|
||||
{
|
||||
$available = (count(runSQL("SELECT * FROM ".TBL_DATA." WHERE imdbID like '%".$recommended['id']."'")) > 0);
|
||||
|
||||
if (!$available)
|
||||
{
|
||||
$recommended['title'] = '<a class="green" href="../edit.php?save=1&mediatype='.MEDIA_WISHLIST.'&lookup=1&imdbID='.$recommended['id'].
|
||||
'&title='.urlencode($recommended['title']).'" target="_blank">'.$recommended['title'].' <img src="../images/add.gif" border="0"/></a>';
|
||||
}
|
||||
|
||||
echo "<tr>";
|
||||
echo "<td align=left width=\"65%\">{$recommended['title']}</td>";
|
||||
echo "<td align=right width=\"10%\">{$recommended['year']}</td>";
|
||||
echo "<td align=right width=\"10%\">{$recommended['rating']}</td>";
|
||||
echo "<td align=right width=\"15%\">{$recommended['id']}</td>";
|
||||
echo "</tr>";
|
||||
|
||||
if ($download && !$available) engineGetData($recommended['id']);
|
||||
}
|
||||
echo "</table>";
|
||||
echo "<br/>";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
?>
|
||||
<form action="<?php echo $_SERVER['PHP_SELF']?>">
|
||||
<table>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
Limit to movies to no earlier then
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="required_year" id="required_year" value="1980" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr valign="top">
|
||||
<td>
|
||||
At least require this rating
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="required_rating" id="required_rating" value="7.0" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<label for="wishlist">
|
||||
<input type="checkbox" name="wishlist" id="wishlist" value="1" />
|
||||
Include wishlist
|
||||
</label>
|
||||
<br />
|
||||
|
||||
<label for="download">
|
||||
<input type="checkbox" name="download" id="download" value="1" />
|
||||
Download recommendations if movie is not in videoDB
|
||||
</label>
|
||||
<br />
|
||||
|
||||
<input type="submit" name="submit" value="Search" />
|
||||
</form>
|
||||
<?
|
||||
}
|
||||
?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
202
videodb/contrib/borrowByBarcode.php
Normal file
202
videodb/contrib/borrowByBarcode.php
Normal file
@@ -0,0 +1,202 @@
|
||||
<?php
|
||||
/**
|
||||
* Borrow / return movie via barcode
|
||||
*
|
||||
* (c) 2005 GPL'd
|
||||
*
|
||||
* @package Contrib
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
*
|
||||
*/
|
||||
chdir('..');
|
||||
require_once './core/session.php';
|
||||
require_once './core/functions.php';
|
||||
require_once './core/genres.php';
|
||||
require_once './core/custom.php';
|
||||
require_once './core/security.php';
|
||||
|
||||
|
||||
// check for localnet
|
||||
localnet_or_die();
|
||||
|
||||
// multiuser permission check
|
||||
permission_or_die(PERM_WRITE, $_COOKIE['VDBuserid']);
|
||||
|
||||
$SELECT = 'SELECT opt FROM '.TBL_CONFIG." WHERE LOWER(opt) LIKE 'custom_type' AND value = 'barcode'";
|
||||
$result = runSQL($SELECT);
|
||||
if (count($result)>0) $customFieldName = preg_replace('/type/','',$result[0]['opt']);
|
||||
|
||||
if (count($result) == 0) {
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<title>Borrow / return movie via barcode</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body>Please select &qt;barcode&qt; as a custom field in the &qt;configuration&qt; tab.</body>
|
||||
</html>
|
||||
<?
|
||||
} elseif (isset($_GET['process']) && $_GET['process'] != "") {
|
||||
$notFound=-1;
|
||||
|
||||
if ($_GET['process'] == "BORROW") {
|
||||
|
||||
$who = escapeSQL(trim($_GET['borrowText']));
|
||||
$barcode = trim($_GET['barcode']);
|
||||
|
||||
if ($who == '') {
|
||||
$notFound=2;
|
||||
} elseif ($barcode == '' || preg_match('/[^0-9]+/',$barcode)) {
|
||||
$notFound=1;
|
||||
} else {
|
||||
$result = runSQL('SELECT diskid, '.$customFieldName.' AS barcode
|
||||
FROM '.TBL_DATA.'
|
||||
LEFT JOIN '.TBL_USERS.'
|
||||
ON '.TBL_DATA.'.owner_id = '.TBL_USERS.'.id
|
||||
WHERE '.TBL_USERS.".name = '".escapeSQL($_COOKIE['VDBusername'])."'".'
|
||||
AND '.TBL_DATA.'.'.$customFieldName." LIKE '%".$barcode."'");
|
||||
|
||||
foreach($result as $row)
|
||||
{
|
||||
// missing zeros at the beginning?
|
||||
if (($lenDiff = strlen($row['barcode'])-strlen($barcode))>0) {
|
||||
// If there is a rotten apple - just skip
|
||||
if (preg_match('/[^0]+/',substr($row['barcode'],0,$lenDiff))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$DELETE = 'DELETE FROM '.TBL_LENT.' WHERE diskid = '.escapeSQL($row['diskid']);
|
||||
$INSERT = 'INSERT '.TBL_LENT." SET who = '".escapeSQL($who)."', diskid = '".escapeSQL($row['diskid'])."'";
|
||||
runSQL($DELETE,false);
|
||||
runSQL($INSERT);
|
||||
$specialJsCode = "parent.mainFrame.location.href='../borrow.php';";
|
||||
$notFound=0;
|
||||
}
|
||||
}
|
||||
} else if ($_GET['process'] == "RETURN") {
|
||||
|
||||
$barcode = trim($_GET['barcode']);
|
||||
|
||||
if ($barcode == '' || preg_match('/[^0-9]+/',$barcode)) {
|
||||
$notFound=1;
|
||||
} else {
|
||||
|
||||
$result = runSQL('SELECT diskid, '.$customFieldName.' AS barcode
|
||||
FROM '.TBL_DATA.'
|
||||
LEFT JOIN '.TBL_USERS.'
|
||||
ON '.TBL_DATA.'.owner_id = '.TBL_USERS.'.id
|
||||
WHERE '.TBL_USERS.".name = '".escapeSQL($_COOKIE['VDBusername'])."'".'
|
||||
AND '.TBL_DATA.'.'.$customFieldName." LIKE '%".$barcode."'");
|
||||
|
||||
foreach($result as $row)
|
||||
{
|
||||
// missing zeros at the beginning?
|
||||
if (($lenDiff = strlen($row['barcode'])-strlen($barcode))>0) {
|
||||
// If there is a rotten apple - just skip
|
||||
if (preg_match('/[^0]+/',substr($row['barcode'],0,$lenDiff))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$DELETE = 'DELETE FROM '.TBL_LENT.' WHERE diskid = '.escapeSQL($row['diskid']);
|
||||
runSQL($DELETE);
|
||||
$specialJsCode = "parent.mainFrame.location.href='../borrow.php';";
|
||||
$notFound=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Borrow / return movie via barcode</title>
|
||||
<link rel="stylesheet" href="../<?php echo $config['style'] ?>" type="text/css" />
|
||||
<script language="JavaScript">
|
||||
<!--
|
||||
function changed() {
|
||||
if (document.barcodeForm.process.value == "BORROW") {
|
||||
document.getElementsByName('borrowTextDesc')[0].style.display='';
|
||||
document.barcodeForm.barcode.focus();
|
||||
document.barcodeForm.barcode.select();
|
||||
} else { // RETURN
|
||||
document.getElementsByName('borrowTextDesc')[0].style.display='none;';
|
||||
document.barcodeForm.barcode.focus();
|
||||
document.barcodeForm.barcode.select();
|
||||
}
|
||||
}
|
||||
|
||||
function bgmonitor(field) {
|
||||
if (field.defaultValue != field.value) {
|
||||
document.barcodeForm.barcode.style.backgroundColor='';
|
||||
document.barcodeForm.borrowText.style.backgroundColor='';
|
||||
}
|
||||
}
|
||||
//-->
|
||||
</script>
|
||||
</head>
|
||||
<body class="tablemenu" >
|
||||
<TABLE width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<TR>
|
||||
<TD align="left" valign="top" class="logo" style="font-size:16px;font-style:normal;float:left;">
|
||||
<form name="barcodeForm" method="get" action="<?php echo $_SERVER['PHP_SELF']?>">
|
||||
<select name="process" onChange="changed();">
|
||||
<option value="BORROW" <?php if ($process=="BORROW" || $process=="LOAD") {?>selected<?php }?>>borrow</option>
|
||||
<option value="RETURN" <?php if ($process=="RETURN") {?>selected<?php }?>>return</option>
|
||||
</select>
|
||||
barcode:
|
||||
<?php
|
||||
if ($notFound == 1) $textFieldStyleB='style="background-color:red;"';
|
||||
elseif ($notFound == 2) $textFieldStyleT='style="background-color:red;"';
|
||||
elseif ($notFound == 0) {
|
||||
$textFieldStyleB='style="background-color:green;"';
|
||||
$textFieldStyleT='style="background-color:green;"';
|
||||
}
|
||||
?>
|
||||
<input type="text" <?php echo $textFieldStyleB ?> name="barcode" size="20" onkeydown="bgmonitor(this);" value="<?php echo $barcode ?>">
|
||||
<span name="borrowTextDesc">
|
||||
to:
|
||||
<input type="text" <?php echo $textFieldStyleT ?> name="borrowText" size="20" onkeydown="bgmonitor(this);" value="<?php echo $borrowText ?>">
|
||||
</span>
|
||||
<input type="submit" name="submit" value="OK">
|
||||
</form>
|
||||
<script language="JavaScript">
|
||||
<!--
|
||||
changed();
|
||||
<?php if ($notFound != 2) { ?>
|
||||
document.barcodeForm.barcode.focus();
|
||||
document.barcodeForm.barcode.select();
|
||||
<?php } else { ?>
|
||||
document.barcodeForm.borrowText.focus();
|
||||
document.barcodeForm.borrowText.select();
|
||||
<?php } ?>
|
||||
<?php echo $specialJsCode ?>
|
||||
//-->
|
||||
</script>
|
||||
</TD>
|
||||
<TD align="right" valign="top" width="14"><a href="javascript:parent.location.href='../index.php';"><img src="../images/close.gif" width="14" height="14" alt="" border="0" /></a></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</body>
|
||||
</html>
|
||||
<?
|
||||
} else { // Frameset
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<title>Borrow / return movie via barcode</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
|
||||
<frameset name="fs1" rows="25,*" frameborder="NO" border="0" framespacing="0">
|
||||
<frame name="topFrame" scrolling="NO" noresize src="<?php echo $_SERVER['PHP_SELF']?>?process=LOAD">
|
||||
<frame name="mainFrame" src="../borrow.php">
|
||||
</frameset>
|
||||
|
||||
<noframes>
|
||||
<body>Please use a browser which supports frames!</body>
|
||||
</noframes>
|
||||
</html>
|
||||
<?
|
||||
}
|
||||
?>
|
||||
194
videodb/contrib/clean_unused_images.php
Normal file
194
videodb/contrib/clean_unused_images.php
Normal file
@@ -0,0 +1,194 @@
|
||||
<?php
|
||||
/**
|
||||
* Cleanup utility to remove unused images from cache folders
|
||||
*
|
||||
* @package Contrib
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @modified Constantinos Neophytou <jaguarcy@gmail.com>
|
||||
*/
|
||||
|
||||
// move out of contrib for includes
|
||||
chdir('..');
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './core/setup.core.php';
|
||||
|
||||
?>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Cleanup Image Cache</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="description" content="VideoDB" />
|
||||
<!--
|
||||
<link rel="stylesheet" href="../templates/modern/compact.css" type="text/css" />
|
||||
-->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<?php
|
||||
|
||||
error_reporting(E_ALL ^ E_NOTICE);
|
||||
|
||||
// get list of all used images
|
||||
//$SQL = "SELECT imgurl FROM videodata UNION SELECT imgurl FROM actors";
|
||||
//$result = runSQL($SQL);
|
||||
|
||||
$coverSQL = "SELECT imgurl FROM ".TBL_DATA;
|
||||
$actorSQL = "SELECT imgurl FROM ".TBL_ACTORS;
|
||||
$coverResult = runSQL($coverSQL);
|
||||
$actorResult = runSQL($actorSQL);
|
||||
|
||||
#dump($coverResult);
|
||||
|
||||
// find covers in cache
|
||||
foreach ($coverResult as $val)
|
||||
{
|
||||
$url = $val['imgurl'];
|
||||
if (preg_match("/\.(jpe?g|gif|png)$/i", $url, $matches))
|
||||
{
|
||||
// get the cache file name, honor manually uploaded files
|
||||
if (preg_match('#^cache#i', $url))
|
||||
$cache_file = $url;
|
||||
else
|
||||
cache_file_exists($url, $cache_file, CACHE_IMG, $matches[1]);
|
||||
|
||||
$covers[] = $cache_file;
|
||||
$images[] = $cache_file;
|
||||
}
|
||||
}
|
||||
|
||||
// find actor images in cache
|
||||
foreach ($actorResult as $val)
|
||||
{
|
||||
$url = $val['imgurl'];
|
||||
if (preg_match("/\.(jpe?g|gif|png)$/i", $url, $matches))
|
||||
{
|
||||
// get the cache file name, honor manually uploaded files
|
||||
if (preg_match('#^cache#i', $url))
|
||||
$cache_file = $url;
|
||||
else
|
||||
cache_file_exists($url, $cache_file, CACHE_IMG, $matches[1]);
|
||||
|
||||
$actors[] = $cache_file;
|
||||
$images[] = $cache_file;
|
||||
}
|
||||
}
|
||||
|
||||
$size = 0;
|
||||
$coverSize = 0;
|
||||
$actorSize = 0;
|
||||
$unused = 0;
|
||||
$coverNum = 0;
|
||||
$actorNum = 0;
|
||||
|
||||
/**
|
||||
* Check cache folder for expired entries
|
||||
*
|
||||
* @author Andreas Goetz
|
||||
* @param string $dir cache folder
|
||||
* @param boolean $all return list of all files (or outdated files)
|
||||
* @return array $total, $expired, $files sum and list of total and expired files
|
||||
*/
|
||||
function analyzeCacheFolder($dir, $all = false)
|
||||
{
|
||||
global $config;
|
||||
|
||||
$files = array();
|
||||
|
||||
if ($handle = opendir($dir))
|
||||
{
|
||||
// read cache directory (note syntax, according to docs!)
|
||||
while (false !== ($file = readdir($handle)))
|
||||
{
|
||||
// prevent deletion of hidden files (*nix) or directory references (Windows)
|
||||
if (preg_match("/^\./", $file)) continue;
|
||||
$cfile = "$dir/$file";
|
||||
|
||||
// file found?
|
||||
if (!is_dir($cfile))
|
||||
{
|
||||
$total += filesize($cfile);
|
||||
if ($all || !(time()-filemtime($cfile) < $config['IMDBage']))
|
||||
{
|
||||
$expired += filesize($cfile);
|
||||
$files[] = $cfile;
|
||||
}
|
||||
}
|
||||
|
||||
// or hierarchical cache directories?
|
||||
elseif ($config['hierarchical'])
|
||||
{
|
||||
// one-char directory name?
|
||||
if (preg_match("/^\w$/", $file))
|
||||
{
|
||||
list($atotal, $aexpired, $afiles) = analyzeCacheFolder($cfile, $all);
|
||||
$total += $atotal;
|
||||
$expired += $aexpired;
|
||||
$files = array_merge($files, $afiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
|
||||
return array($total, $expired, $files);
|
||||
}
|
||||
|
||||
// get list of all images currently in cache
|
||||
list($total, $foo, $files) = analyzeCacheFolder('cache/img', true);
|
||||
|
||||
if ($submit) dump('Deleting:');
|
||||
|
||||
// loop over cache files
|
||||
foreach ($files as $file)
|
||||
{
|
||||
if (!in_array($file, $images))
|
||||
{
|
||||
$size += filesize($file);
|
||||
$unused++;
|
||||
|
||||
if ($submit)
|
||||
{
|
||||
unlink($file);
|
||||
dump($file);
|
||||
}
|
||||
}
|
||||
elseif (in_array($file, $covers))
|
||||
{
|
||||
$coverSize += filesize($file);
|
||||
$coverNum++;
|
||||
}
|
||||
elseif (in_array($file, $actors))
|
||||
{
|
||||
$actorSize += filesize($file);
|
||||
$actorNum++;
|
||||
}
|
||||
}
|
||||
|
||||
echo sprintf("
|
||||
$coverNum out of %d files with a size of %.2fMB are used for covers<br/>
|
||||
$actorNum out of %d files with a size of %.2fMB are used for headshots<br/>
|
||||
$unused out of %d files with a size of %.2fMB are currently unused<br/>",
|
||||
count($files), $coverSize/(1024*1024),
|
||||
count($files), $actorSize/(1024*1024),
|
||||
count($files), $size/(1024*1024));
|
||||
|
||||
if ($unused)
|
||||
{
|
||||
if ($submit)
|
||||
{
|
||||
echo "$unused files with a size of ".round($size/(1024*1024),2)."Mb have been deleted<br/>";
|
||||
}
|
||||
?>
|
||||
<form action=<?php echo $PHP_SELF?>>
|
||||
<input type="submit" name="submit" value="Delete" />
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
67
videodb/contrib/convertOwnerlessMovies.php
Normal file
67
videodb/contrib/convertOwnerlessMovies.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* transfer ownerless to moves to one user
|
||||
*
|
||||
* @package Contrib
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
*
|
||||
* @meta ACCESS:PERM_ADMIN
|
||||
*/
|
||||
|
||||
// move out of contrib for includes
|
||||
chdir('..');
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './core/output.php';
|
||||
|
||||
// check for localnet
|
||||
localnet_or_die();
|
||||
|
||||
// multiuser permission check
|
||||
permission_or_die(PERM_ADMIN);
|
||||
|
||||
$owners = out_owners(null, 0, true);
|
||||
|
||||
if (empty($owner_id)) $owner_id = $_COOKIE['VDBuserid'];
|
||||
|
||||
if ($convert)
|
||||
{
|
||||
runSQL("UPDATE ".TBL_DATA."
|
||||
SET owner_id = ".$owner_id."
|
||||
WHERE owner_id = 0");
|
||||
// show the saved movie
|
||||
header('Location: ../index.php');
|
||||
exit();
|
||||
}
|
||||
else
|
||||
{
|
||||
?>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Transfer ownerless movies to a user</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<form action="<?php echo $_SERVER['PHP_SELF']?>">
|
||||
<h3>Do you realy want to convert all ownerless movies to be owned by <SELECT name='owner_id'>
|
||||
<?
|
||||
|
||||
foreach (array_keys($owners) as $owner)
|
||||
{
|
||||
if ($owner == $owner_id) $selected = "selected";
|
||||
else $selected = "";
|
||||
print "<OPTION $selected value='$owner'>".$owners[$owner]."</OPTION>\n";
|
||||
}
|
||||
?></SELECT> ?</h3>
|
||||
|
||||
<input type="submit" name="convert" value="Convert" />
|
||||
</form>
|
||||
<?
|
||||
}
|
||||
?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
135
videodb/contrib/count_actors.php
Normal file
135
videodb/contrib/count_actors.php
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
/**
|
||||
* Produce a count of all actors in the database
|
||||
*
|
||||
* Code structure based on add_recommended_movies.php by Andreas Goetz
|
||||
*
|
||||
* @package Contrib
|
||||
* @author Constantinos Neophytou <jaguarcy@gmail.com>
|
||||
* @version $Id: count_actors.php,v 1.4 2007/09/08 09:17:16 andig2 Exp $
|
||||
*/
|
||||
|
||||
// move out of contrib for includes
|
||||
chdir('..');
|
||||
|
||||
require_once './core/functions.php';
|
||||
?>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>List actor counts</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="description" content="VideoDB" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<?
|
||||
|
||||
if ($submit)
|
||||
{
|
||||
// validate form data
|
||||
$maxcount = (is_numeric($maxcount)) ? (int) $maxcount : 0;
|
||||
|
||||
// Build query - ignore duplicate imdbID fields
|
||||
$query = 'SELECT DISTINCT `imdbID`, `director`, `actors` FROM '.TBL_DATA;
|
||||
if (empty($wishlist)) $query .= ' WHERE mediatype != '.MEDIA_WISHLIST;
|
||||
|
||||
$result = runSQL($query);
|
||||
|
||||
$includeDirectors = !empty($director);
|
||||
|
||||
$actors = array(); // Actor array
|
||||
|
||||
// If we are counting the directors separately than the actors, create the array
|
||||
if (empty($notseparate) && $includeDirectors) {
|
||||
$directors = array();
|
||||
$displayDirectorCount = true;
|
||||
} else {
|
||||
// Otherwise, use the actor array for directors as well.
|
||||
$directors = &$actors;
|
||||
$displayDirectorCount = false;
|
||||
}
|
||||
|
||||
|
||||
foreach ($result as $row)
|
||||
{
|
||||
$cast = split("\r?\n", $row['actors']);
|
||||
|
||||
// Counting actors
|
||||
foreach ($cast as $actor) {
|
||||
$actorary = split('::', $actor);
|
||||
if (!isset($actors[$actorary[0]])) {
|
||||
// Use actor name as array index so all counts are attributed to the same name
|
||||
$actors[$actorary[0]] = 0;
|
||||
}
|
||||
$actors[$actorary[0]]++;
|
||||
}
|
||||
|
||||
// Director count
|
||||
if ($includeDirectors) {
|
||||
if (!isset($directors[$row['director']])) {
|
||||
$directors[$row['director']] = 0;
|
||||
}
|
||||
$directors[$row['director']]++;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort array by actor appearances in reverse order (high to low)
|
||||
arsort($actors);
|
||||
|
||||
$i = 1;
|
||||
foreach ($actors as $key=>$val)
|
||||
{
|
||||
if ($val > $maxcount)
|
||||
{
|
||||
// Build name search url
|
||||
$url = "../search.php?q=%22" . htmlentities(urlencode($key)) . "%22&isname=Y";
|
||||
|
||||
// Text for director counts
|
||||
$dirText = '';
|
||||
if ($displayDirectorCount && $directors[$key]) {
|
||||
$dirText = ", " . $directors[$key] . " director entries";
|
||||
}
|
||||
|
||||
echo "$i - <a href='$url'>$key</a>: $val actor entries" . $dirText . "<br />";
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
?>
|
||||
<form action="<?php echo $_SERVER['PHP_SELF']?>">
|
||||
|
||||
<label for="maxcount">
|
||||
Only show names with more than
|
||||
<input type="text" name="maxcount" id="maxcount" value="3" size="2" maxlength="2" />
|
||||
actor entries
|
||||
</label>
|
||||
<br />
|
||||
<label for="director">
|
||||
<input type="checkbox" name="director" id="director" value="1" checked />
|
||||
Count director entries (will appear next to the actor entries, will not be sorted)
|
||||
</label>
|
||||
<br />
|
||||
<label for="notseparate">
|
||||
<input type="checkbox" name="notseparate" id="notseparate" value="1" />
|
||||
Count director entries as "actor" (i.e. don't separate them)
|
||||
</label>
|
||||
<br />
|
||||
<label for="wishlist">
|
||||
<input type="checkbox" name="wishlist" id="wishlist" value="1" />
|
||||
Include wishlist
|
||||
</label>
|
||||
<br />
|
||||
<br />
|
||||
<input type="submit" name="submit" value="List" />
|
||||
</form>
|
||||
<br />
|
||||
<small>Note: Duplicate movie entries (determined by imdbID) will not be counted.</small>
|
||||
<?
|
||||
}
|
||||
?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
102
videodb/contrib/decode_entities.php
Normal file
102
videodb/contrib/decode_entities.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/**
|
||||
* Convert HTML entities to plain text
|
||||
*
|
||||
* @package Contrib
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: decode_entities.php,v 1.6 2008/01/23 09:06:25 andig2 Exp $
|
||||
* @meta ACCESS:PERM_ADMIN
|
||||
*/
|
||||
|
||||
// move out of contrib for includes
|
||||
chdir('..');
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './engines/engines.php';
|
||||
|
||||
?>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Decode HTML Entities</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="description" content="VideoDB" />
|
||||
<!--
|
||||
<link rel="stylesheet" href="../templates/modern/compact.css" type="text/css" />
|
||||
-->
|
||||
<style>
|
||||
.green { color:green }
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<?
|
||||
|
||||
error_reporting(E_ALL ^ E_NOTICE);
|
||||
|
||||
if (!$submit) echo "<h2>Warning- be sure to backup your data before submitting the cleanup request!</h2>";
|
||||
|
||||
$SQL = 'SELECT * FROM '.TBL_DATA;
|
||||
$result = runSQL($SQL);
|
||||
|
||||
$count = 0;
|
||||
foreach ($result as $video)
|
||||
{
|
||||
$SQL = '';
|
||||
|
||||
$keys = array();
|
||||
|
||||
foreach ($video as $key => $value)
|
||||
{
|
||||
if ($key == 'id') continue;
|
||||
|
||||
$new = html_clean_utf8($value);
|
||||
if ($new != $value)
|
||||
{
|
||||
$keys[] = $key;
|
||||
|
||||
if ($SQL) $SQL .= ', ';
|
||||
$SQL .= "$key = '".escapeSQL($new)."'";
|
||||
}
|
||||
}
|
||||
|
||||
if ($SQL)
|
||||
{
|
||||
$count++;
|
||||
echo (($submit) ? 'Converting: ' : '<b>Conversion needed:</b> ').$video['title']."<br/>\n";
|
||||
|
||||
// actually perform the conversion?
|
||||
if ($submit)
|
||||
{
|
||||
$SQL = "UPDATE ".TBL_DATA." SET $SQL WHERE id = ".$video['id'];
|
||||
runSQL($SQL);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($keys as $key)
|
||||
{
|
||||
echo $key.': '.htmlentities($video[$key])."<br/>\n";
|
||||
}
|
||||
echo "<br/>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$action = ($submit) ? 'Converted' : 'Analyzed';
|
||||
echo "$action $count of ".count($result)." movies.<br/>\n";
|
||||
|
||||
if (empty($submit))
|
||||
{
|
||||
?>
|
||||
<form action="<?php echo $_SERVER['PHP_SELF']?>">
|
||||
<input type="submit" name="submit" value="Convert" />
|
||||
</form>
|
||||
<?
|
||||
}
|
||||
?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
142
videodb/contrib/direxport.pl
Normal file
142
videodb/contrib/direxport.pl
Normal file
@@ -0,0 +1,142 @@
|
||||
#!/usr/bin/perl
|
||||
use DBI;
|
||||
|
||||
#DB-Connection
|
||||
$db_server = "localhost";
|
||||
$db_user = "www";
|
||||
$db_password = "leech";
|
||||
$db_database = "VideoDB";
|
||||
|
||||
#output directory
|
||||
$outdir = '/ftp/moviez/VideoDB/';
|
||||
|
||||
#imgcache
|
||||
$imgcache = 'http://xerxes/videodb/imgcache';
|
||||
|
||||
#showurl
|
||||
$showurl = 'http://xerxes/videodb/show.php';
|
||||
|
||||
#lynx
|
||||
$lynx = '/usr/bin/lynx';
|
||||
|
||||
###############################################################################
|
||||
#okay lets go
|
||||
|
||||
#delete old stuff
|
||||
system("rm -rf $outdir/*");
|
||||
|
||||
#connect
|
||||
$dbh = DBI->connect("dbi:mysql:$db_database:$db_server",$db_user,$db_password) || die("Can't connect");
|
||||
|
||||
#unseen nontv
|
||||
$out = "$outdir/unseen";
|
||||
mkdir($out) unless(-e $out);
|
||||
$SELECT = "SELECT id, title , subtitle
|
||||
FROM videodata
|
||||
WHERE seen = 0
|
||||
AND istv = 0";
|
||||
$result = $dbh->selectall_arrayref($SELECT);
|
||||
$row=0;
|
||||
while (defined($result->[$row][0])){
|
||||
&show($result->[$row][0],$result->[$row][1],$result->[$row][2],$out);
|
||||
$row++;
|
||||
}
|
||||
|
||||
#unseen nontv
|
||||
$out = "$outdir/unseen/tv";
|
||||
mkdir($out) unless(-e $out);
|
||||
$SELECT = "SELECT id, title , subtitle
|
||||
FROM videodata
|
||||
WHERE seen = 0
|
||||
AND istv = 1";
|
||||
$result = $dbh->selectall_arrayref($SELECT);
|
||||
$row=0;
|
||||
while (defined($result->[$row][0])){
|
||||
&show($result->[$row][0],$result->[$row][1],$result->[$row][2],$out);
|
||||
$row++;
|
||||
}
|
||||
|
||||
#seen nontv
|
||||
$out = "$outdir/seen";
|
||||
mkdir($out) unless(-e $out);
|
||||
$SELECT = "SELECT id, title , subtitle
|
||||
FROM videodata
|
||||
WHERE seen = 1
|
||||
AND istv = 0";
|
||||
$result = $dbh->selectall_arrayref($SELECT);
|
||||
$row=0;
|
||||
while (defined($result->[$row][0])){
|
||||
&show($result->[$row][0],$result->[$row][1],$result->[$row][2],$out);
|
||||
$row++;
|
||||
}
|
||||
|
||||
#unseen tv
|
||||
$out = "$outdir/seen/tv";
|
||||
mkdir($out) unless(-e $out);
|
||||
$SELECT = "SELECT id, title , subtitle
|
||||
FROM videodata
|
||||
WHERE seen = 1
|
||||
AND istv = 1";
|
||||
$result = $dbh->selectall_arrayref($SELECT);
|
||||
$row=0;
|
||||
while (defined($result->[$row][0])){
|
||||
&show($result->[$row][0],$result->[$row][1],$result->[$row][2],$out);
|
||||
$row++;
|
||||
}
|
||||
|
||||
#all nontv
|
||||
$out = "$outdir";
|
||||
mkdir($out) unless(-e $out);
|
||||
$SELECT = "SELECT id, title , subtitle
|
||||
FROM videodata
|
||||
WHERE istv = 0";
|
||||
$result = $dbh->selectall_arrayref($SELECT);
|
||||
$row=0;
|
||||
while (defined($result->[$row][0])){
|
||||
&show($result->[$row][0],$result->[$row][1],$result->[$row][2],$out);
|
||||
$row++;
|
||||
}
|
||||
|
||||
#all tv
|
||||
$out = "$outdir/tv";
|
||||
mkdir($out) unless(-e $out);
|
||||
$SELECT = "SELECT id, title , subtitle
|
||||
FROM videodata
|
||||
WHERE istv = 1";
|
||||
$result = $dbh->selectall_arrayref($SELECT);
|
||||
$row=0;
|
||||
while (defined($result->[$row][0])){
|
||||
&show($result->[$row][0],$result->[$row][1],$result->[$row][2],$out);
|
||||
$row++;
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
sub show($$$$){
|
||||
my $id = $_[0];
|
||||
my $title = $_[1];
|
||||
my $subtitle = $_[2];
|
||||
my $out = $_[3];
|
||||
print '.';
|
||||
|
||||
my $name;
|
||||
if ($subtitle ne ''){
|
||||
$name = "$title - $subtitle.html";
|
||||
}else{
|
||||
$name = "$title.html";
|
||||
}
|
||||
|
||||
my $output = `$lynx --dump --source '$showurl?id=$id'`;
|
||||
# print "$lynx --dump '$showurl?id=$id'\n";
|
||||
|
||||
|
||||
$output =~ m/<!-- content begin -->(.*)<!-- content end -->/is;
|
||||
$output = $1;
|
||||
$output =~ s/SRC="imgcache/SRC="$imgcache/is;
|
||||
|
||||
$output =~ s/<span CLASS="show_title">(.*?)<\/span>/<H1>$1/is;
|
||||
$output =~ s/<span CLASS="show_subtitle">(.*?)<\/span>/$1<\/H1>/is;
|
||||
|
||||
open (FILE,">$out/$name") || die("file open '$out/$name' failed");
|
||||
print FILE $output;
|
||||
close FILE;
|
||||
}
|
||||
314
videodb/contrib/dvdadd.pl
Normal file
314
videodb/contrib/dvdadd.pl
Normal file
@@ -0,0 +1,314 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
#program version
|
||||
my $VERSION="0.1.0";
|
||||
|
||||
# Path to your lsdvd binary (http://acidrip.thirtythreeandathird.net/lsdvd.html)
|
||||
$lsdvd = '/usr/bin/lsdvd';
|
||||
|
||||
# DVD drive to use (reads it from commandline)
|
||||
$device = $ARGV[ 0 ];
|
||||
$device = "/dev/cdrom" unless (defined($device));
|
||||
|
||||
# if you use the multiuser feature you may want to give an
|
||||
# owner of the movies to add here - if you don't need it just
|
||||
# set it to a blank string. It has to be a number for videoDB 2.x
|
||||
$owner = 3;
|
||||
|
||||
# if you want to define what mediatype you are going to add (7=dvd-r 1=dvd)
|
||||
$mediatype = 7;
|
||||
|
||||
# Database stuff
|
||||
$driver = "mysql";
|
||||
$database = "VideoDB";
|
||||
$hostname = "localhost";
|
||||
$user = "www";
|
||||
$password = "leech";
|
||||
|
||||
################################################################################
|
||||
use DBI;
|
||||
use Data::Dumper;
|
||||
|
||||
#Connect to database
|
||||
$dsn = "DBI:$driver:database=$database;host=$hostname";
|
||||
$dbh = DBI->connect($dsn, $user, $password);
|
||||
|
||||
#quote this only once:
|
||||
$owner = $dbh->quote($owner);
|
||||
|
||||
#prepare language codes
|
||||
%lc = preparelc();
|
||||
|
||||
#work
|
||||
&readlsdvd();
|
||||
|
||||
#disconnect
|
||||
$dbh->disconnect();
|
||||
|
||||
#
|
||||
###############################################################################
|
||||
sub readlsdvd($)
|
||||
{
|
||||
my $output = `$lsdvd -t 1 -a -s -v -p $device`;
|
||||
if ($output eq '')
|
||||
{
|
||||
print STDERR "running lsdvd failed - check pathnames\n";
|
||||
exit 1;
|
||||
}
|
||||
eval($output);
|
||||
|
||||
# prepare for inserts
|
||||
my $title = $dbh->quote($lsdvd{ title });
|
||||
my $video_width = $dbh->quote($lsdvd{ track }[ 0 ]{ width });
|
||||
my $video_height = $dbh->quote($lsdvd{ track }[ 0 ]{ height });
|
||||
my $runtime = $dbh->quote(sprintf("%d", $lsdvd{ track }[ 0 ]{ 'length' } / 60));
|
||||
|
||||
# get languages... first is default, the next are written to custom1 and custom2 respectively (add custom3 and four if you want 4 languages
|
||||
my $language1 = $dbh->quote($lc{ $lsdvd{ track }[ 0 ]{ audio }[ 0 ]{ langcode } });
|
||||
my $language2 = $dbh->quote($lc{ $lsdvd{ track }[ 0 ]{ audio }[ 1 ]{ langcode } });
|
||||
my $language3 = $dbh->quote($lc{ $lsdvd{ track }[ 0 ]{ audio }[ 2 ]{ langcode } });
|
||||
|
||||
# reads if PAL or NTSC and how many channels the audio has
|
||||
my $audio_codec = $dbh->quote($lsdvd{ track }[ 0 ]{ audio }[ 0 ]{ format } . ' ' . $lsdvd{ track }[ 0 ]{ audio }[ 0 ]{ channels } . ' channels');
|
||||
|
||||
# video codec is either PAL or NTSC ... Aspectratio is 16x9 or 4x3
|
||||
my $video_codec = $dbh->quote($lsdvd{ track }[ 0 ]{ format });
|
||||
my $aspectratio = $dbh->quote($lsdvd{ track }[ 0 ]{ aspect });
|
||||
|
||||
# just for those who want to use pixels instead of Aspectratio
|
||||
my $videowidth = $dbh->quote($lsdvd{ track }[ 0 ]{ width });
|
||||
my $videoheight = $dbh->quote($lsdvd{ track }[ 0 ]{ height });
|
||||
|
||||
# Get subtitles prepared... based on GPL code from acidrip-0.12
|
||||
my $this_track = 0;
|
||||
my $subtitle = "Subtitles: ";
|
||||
|
||||
foreach my $this_subp (@{ $lsdvd{ track }[ 0 ]->{ 'subp' } })
|
||||
{
|
||||
my $subp_ix = $this_subp->{ 'ix' };
|
||||
my $label = $subp_ix . " " . $this_subp->{ 'language' };
|
||||
$label .= "\: " . $this_subp->{ 'content' } if $this_subp->{ 'content' } ne "Undefined";
|
||||
$subtitle = $subtitle . $label . "\, ";
|
||||
}
|
||||
|
||||
# Detect aspect ratio and put into video width and height... comment if you prefer pixel count
|
||||
|
||||
if ($aspectratio = "16/9")
|
||||
{
|
||||
$video_width = "16";
|
||||
$video_height = "9";
|
||||
}
|
||||
elsif ($aspectratio = "4/3")
|
||||
{
|
||||
$video_width = "4";
|
||||
$video_height = "3";
|
||||
}
|
||||
|
||||
# insert... remove both custom1 and custom2 if you use them for something else or change them to
|
||||
# something different
|
||||
#
|
||||
# video_width can be replaced with $videowidth and video_height with $videoheight to achieve pixel
|
||||
# count like width = 720, height = 576
|
||||
|
||||
my $INSERT = "INSERT INTO videodata
|
||||
SET title = $title,
|
||||
video_width = $video_width,
|
||||
video_height = $video_height,
|
||||
video_codec = $video_codec,
|
||||
mediatype = $mediatype,
|
||||
created = NOW(),
|
||||
runtime = $runtime,
|
||||
language = $language1,
|
||||
custom1 = $language2,
|
||||
custom2 = $language3,
|
||||
audio_codec = $audio_codec,
|
||||
comment = '$subtitle',
|
||||
owner_id = $owner";
|
||||
|
||||
# comment if you are testing the script... this writes to the database
|
||||
$dbh->do($INSERT);
|
||||
|
||||
#print $INSERT;
|
||||
}
|
||||
|
||||
sub preparelc()
|
||||
{
|
||||
my %lc;
|
||||
$lc{ 'aa' } = 'afar';
|
||||
$lc{ 'ab' } = 'abkhazian';
|
||||
$lc{ 'af' } = 'afrikaans';
|
||||
$lc{ 'am' } = 'amharic';
|
||||
$lc{ 'ar' } = 'arabic';
|
||||
$lc{ 'as' } = 'assamese';
|
||||
$lc{ 'ay' } = 'aymara';
|
||||
$lc{ 'az' } = 'azerbaijani';
|
||||
$lc{ 'ba' } = 'bashkir';
|
||||
$lc{ 'be' } = 'byelorussian';
|
||||
$lc{ 'bg' } = 'bulgarian';
|
||||
$lc{ 'bh' } = 'bihari';
|
||||
$lc{ 'bi' } = 'bislama';
|
||||
$lc{ 'bn' } = 'bengali';
|
||||
$lc{ 'bo' } = 'tibetan';
|
||||
$lc{ 'br' } = 'breton';
|
||||
$lc{ 'ca' } = 'catalan';
|
||||
$lc{ 'co' } = 'corsican';
|
||||
$lc{ 'cs' } = 'czech';
|
||||
$lc{ 'cy' } = 'welsh';
|
||||
$lc{ 'da' } = 'danish';
|
||||
$lc{ 'de' } = 'german';
|
||||
$lc{ 'dz' } = 'bhutani';
|
||||
$lc{ 'el' } = 'greek';
|
||||
$lc{ 'en' } = 'english';
|
||||
$lc{ 'eo' } = 'esperanto';
|
||||
$lc{ 'es' } = 'spanish';
|
||||
$lc{ 'et' } = 'estonian';
|
||||
$lc{ 'eu' } = 'basque';
|
||||
$lc{ 'fa' } = 'persian';
|
||||
$lc{ 'fi' } = 'finnish';
|
||||
$lc{ 'fj' } = 'fiji';
|
||||
$lc{ 'fo' } = 'faroese';
|
||||
$lc{ 'fr' } = 'french';
|
||||
$lc{ 'fy' } = 'frisian';
|
||||
$lc{ 'ga' } = 'irish';
|
||||
$lc{ 'gd' } = 'gaelic';
|
||||
$lc{ 'gl' } = 'galician';
|
||||
$lc{ 'gn' } = 'guarani';
|
||||
$lc{ 'gu' } = 'gujarati';
|
||||
$lc{ 'ha' } = 'hausa';
|
||||
$lc{ 'he' } = 'hebrew';
|
||||
$lc{ 'hi' } = 'hindi';
|
||||
$lc{ 'hr' } = 'croatian';
|
||||
$lc{ 'hu' } = 'hungarian';
|
||||
$lc{ 'hy' } = 'armenian';
|
||||
$lc{ 'ia' } = 'interlingua';
|
||||
$lc{ 'id' } = 'indonesian';
|
||||
$lc{ 'ie' } = 'interlingue';
|
||||
$lc{ 'ik' } = 'inupiak';
|
||||
$lc{ 'is' } = 'icelandic';
|
||||
$lc{ 'it' } = 'italian';
|
||||
$lc{ 'iu' } = 'inuktitut';
|
||||
$lc{ 'ja' } = 'japanese';
|
||||
$lc{ 'jw' } = 'javanese';
|
||||
$lc{ 'ka' } = 'georgian';
|
||||
$lc{ 'kk' } = 'kazakh';
|
||||
$lc{ 'kl' } = 'greenlandic';
|
||||
$lc{ 'km' } = 'cambodian';
|
||||
$lc{ 'kn' } = 'kannada';
|
||||
$lc{ 'ko' } = 'korean';
|
||||
$lc{ 'ks' } = 'kashmiri';
|
||||
$lc{ 'ku' } = 'kurdish';
|
||||
$lc{ 'ky' } = 'kirghiz';
|
||||
$lc{ 'la' } = 'latin';
|
||||
$lc{ 'ln' } = 'lingala';
|
||||
$lc{ 'lo' } = 'laothian';
|
||||
$lc{ 'lt' } = 'lithuanian';
|
||||
$lc{ 'lv' } = 'latvian';
|
||||
$lc{ 'mg' } = 'malagasy';
|
||||
$lc{ 'mi' } = 'maori';
|
||||
$lc{ 'mk' } = 'macedonian';
|
||||
$lc{ 'ml' } = 'malayalam';
|
||||
$lc{ 'mn' } = 'mongolian';
|
||||
$lc{ 'mo' } = 'moldavian';
|
||||
$lc{ 'mr' } = 'marathi';
|
||||
$lc{ 'ms' } = 'malay';
|
||||
$lc{ 'mt' } = 'maltese';
|
||||
$lc{ 'my' } = 'burmese';
|
||||
$lc{ 'na' } = 'nauru';
|
||||
$lc{ 'ne' } = 'nepali';
|
||||
$lc{ 'nl' } = 'dutch';
|
||||
$lc{ 'no' } = 'norwegian';
|
||||
$lc{ 'oc' } = 'occitan';
|
||||
$lc{ 'om' } = 'oromo';
|
||||
$lc{ 'or' } = 'oriya';
|
||||
$lc{ 'pa' } = 'punjabi';
|
||||
$lc{ 'pl' } = 'polish';
|
||||
$lc{ 'ps' } = 'pashto';
|
||||
$lc{ 'pt' } = 'portuguese';
|
||||
$lc{ 'qu' } = 'quechua';
|
||||
$lc{ 'rm' } = 'rhaeto-romance';
|
||||
$lc{ 'rn' } = 'kirundi';
|
||||
$lc{ 'ro' } = 'romanian';
|
||||
$lc{ 'ru' } = 'russian';
|
||||
$lc{ 'rw' } = 'kinyarwanda';
|
||||
$lc{ 'sa' } = 'sanskrit';
|
||||
$lc{ 'sd' } = 'sindhi';
|
||||
$lc{ 'sg' } = 'sangho';
|
||||
$lc{ 'sh' } = 'serbo-croatian';
|
||||
$lc{ 'si' } = 'sinhalese';
|
||||
$lc{ 'sk' } = 'slovak';
|
||||
$lc{ 'sl' } = 'slovenian';
|
||||
$lc{ 'sm' } = 'samoan';
|
||||
$lc{ 'sn' } = 'shona';
|
||||
$lc{ 'so' } = 'somali';
|
||||
$lc{ 'sq' } = 'albanian';
|
||||
$lc{ 'sr' } = 'serbian';
|
||||
$lc{ 'ss' } = 'siswati';
|
||||
$lc{ 'st' } = 'sesotho';
|
||||
$lc{ 'su' } = 'sundanese';
|
||||
$lc{ 'sv' } = 'swedish';
|
||||
$lc{ 'sw' } = 'swahili';
|
||||
$lc{ 'ta' } = 'tamil';
|
||||
$lc{ 'te' } = 'telugu';
|
||||
$lc{ 'tg' } = 'tajik';
|
||||
$lc{ 'th' } = 'thai';
|
||||
$lc{ 'ti' } = 'tigrinya';
|
||||
$lc{ 'tk' } = 'turkmen';
|
||||
$lc{ 'tl' } = 'tagalog';
|
||||
$lc{ 'tn' } = 'setswana';
|
||||
$lc{ 'to' } = 'tonga';
|
||||
$lc{ 'tr' } = 'turkish';
|
||||
$lc{ 'ts' } = 'tsonga';
|
||||
$lc{ 'tt' } = 'tatar';
|
||||
$lc{ 'tw' } = 'twi';
|
||||
$lc{ 'ug' } = 'uighur';
|
||||
$lc{ 'uk' } = 'ukrainian';
|
||||
$lc{ 'ur' } = 'urdu';
|
||||
$lc{ 'uz' } = 'uzbek';
|
||||
$lc{ 'vi' } = 'vietnamese';
|
||||
$lc{ 'vo' } = 'volapuk';
|
||||
$lc{ 'wo' } = 'wolof';
|
||||
$lc{ 'xh' } = 'xhosa';
|
||||
$lc{ 'yi' } = 'yiddish';
|
||||
$lc{ 'yo' } = 'yoruba';
|
||||
$lc{ 'za' } = 'zhuang';
|
||||
$lc{ 'zh' } = 'chinese';
|
||||
$lc{ 'zu' } = 'zulu';
|
||||
|
||||
return %lc;
|
||||
}
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
dvdadd - reads DVD Video Data and writes it to videoDB
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
reads DVD Video Data and writes it to videoDB
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
reads DVD Video Data and writes it to videoDB using Perl and lsdvd. Linux or Unix is required, not tested on MS Windows.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
videoDB http://videodb.sf.net
|
||||
lsdvd 0.10 http://acidrip.thirtythreeandathird.net/lsdvd.html
|
||||
perl http://perl.org
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Elkin Fricke, videoDB DevTeam.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
VideoDB is released under the GNU General Public License (GPL)
|
||||
See COPYING for more Info
|
||||
|
||||
VideoDB comes with the Smarty Template Engine
|
||||
Smarty is released under the GNU Lesser General Public License (LGPL)
|
||||
See COPYING.lib in the smarty directory for more Info
|
||||
|
||||
=cut
|
||||
|
||||
152
videodb/contrib/fetch_imdb_all.php
Normal file
152
videodb/contrib/fetch_imdb_all.php
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
/**
|
||||
* Refresh whole IMDB info (rund from command line)
|
||||
*
|
||||
* This script should be executed from command line
|
||||
* Look for the NOTE: comments to change behavior
|
||||
* The script should be placed under videodb/contrib and run as "php fetch_imdb_all.php"
|
||||
*
|
||||
* @package Contrib
|
||||
* @author Alex Mondshain <alex_mond@yahoo.com>
|
||||
*/
|
||||
|
||||
chdir('..');
|
||||
require_once './engines/engines.php';
|
||||
require_once './core/functions.php';
|
||||
require_once './core/genres.php';
|
||||
require_once './core/custom.php';
|
||||
require_once './core/edit.core.php';
|
||||
|
||||
//Id is imdb id
|
||||
//lookup is either 1 (add missing) or 2 (overwrite)
|
||||
function FetchSaveMovie($id,$lookup)
|
||||
{
|
||||
$debug = 0;
|
||||
|
||||
$video = runSQL('SELECT * FROM '.TBL_DATA.' WHERE id = '.$id);
|
||||
// get fields (according to list) from db to be saved later
|
||||
|
||||
if ($debug){
|
||||
echo "\n=================== Video DB Data ============================\n";
|
||||
print_r( $video[0]);
|
||||
echo "\n=================== Video DB Data ============================\n";
|
||||
}
|
||||
|
||||
$imdbID = $video[0]['imdbID'];
|
||||
echo "Movie/imdb -- ".$video[0]['title']."/".$video[0]['imdbID']."\n";
|
||||
|
||||
|
||||
if (empty($imdbID)) {
|
||||
echo "No imdbID\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($engine)) $engine = engineGetEngine($imdbID);
|
||||
|
||||
if ($debug) {
|
||||
echo "IMDBID = $imdbID, engine = $engine\n";
|
||||
}
|
||||
|
||||
$imdbdata = engineGetData($imdbID, $engine);
|
||||
# removed due to performance issues of is_utf8
|
||||
// fix erroneous IMDB encoding issues
|
||||
if (!is_utf8($imdbdata)) {
|
||||
echo "Applying encoding fix\n";
|
||||
$imdbdata = fix_utf8($imdbdata);
|
||||
}
|
||||
|
||||
if (empty($imdbdata[title])) {
|
||||
echo "Fetch failed , try again...\n";
|
||||
$imdbdata = engineGetData($imdbID, $engine);
|
||||
}
|
||||
|
||||
if (empty($imdbdata[title])) {
|
||||
echo "Fetch failed again , next movie";
|
||||
return;
|
||||
}
|
||||
|
||||
if ($debug) {
|
||||
echo "\n=================== IMDB Data ============================\n";
|
||||
print_r($imdbdata);
|
||||
echo "\n=================== IMDB Data ============================\n";
|
||||
}
|
||||
|
||||
if (!empty($imdbdata[title])) {
|
||||
//
|
||||
// NOTE: comment out any of the following lines if you do not want them updated
|
||||
//
|
||||
$video[0][title]=$imdbdata[title];
|
||||
$video[0][subtitle]=$imdbdata[subtitle];
|
||||
$video[0][year]=$imdbdata[year];
|
||||
$video[0][imgurl]=$imdbdata[coverurl];
|
||||
$video[0][runtime]=$imdbdata[runtime];
|
||||
$video[0][director]=$imdbdata[director];
|
||||
$video[0][rating]=$imdbdata[rating];
|
||||
$video[0][country]=$imdbdata[country];
|
||||
$video[0][language]=$imdbdata[language];
|
||||
$video[0][actors]=$imdbdata[cast];
|
||||
$video[0][plot]=$imdbdata[plot];
|
||||
}
|
||||
|
||||
if (count($genres) == 0 || ($lookup > 1))
|
||||
{
|
||||
$genres = array();
|
||||
$gnames = $imdbdata['genres'];
|
||||
if (isset($gnames))
|
||||
{
|
||||
foreach ($gnames as $gname)
|
||||
{
|
||||
// check if genre is found- otherwise fail silently
|
||||
if (is_numeric($genre = getGenreId($gname))) {
|
||||
$genres[] = $genre;
|
||||
} else {
|
||||
echo "MISSING GENRE $gname\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// custom filds , not working for now
|
||||
for ($i=1; $i<=4; $i++)
|
||||
{
|
||||
$custom = 'custom'.$i;
|
||||
$type = $config[$custom.'type'];
|
||||
if (!empty($type))
|
||||
{
|
||||
// copy imdb data into corresponding custom field
|
||||
$video[0][$custom]=$imdbdata[$type];
|
||||
echo "CUSTOM $custom $type = $imdbdata[$type]\n";
|
||||
}
|
||||
}
|
||||
|
||||
// -------- SAVE
|
||||
|
||||
$SETS = prepareSQL($video[0]);
|
||||
|
||||
if ($debug) {
|
||||
echo "\n=================== Final Data ============================\n";
|
||||
echo "SETS = $SETS \n";
|
||||
echo "\n=================== Final Data ============================\n";
|
||||
}
|
||||
|
||||
$id = updateDB($SETS, $id);
|
||||
|
||||
// save genres
|
||||
setItemGenres($id, $genres);
|
||||
|
||||
// set seen for currently logged in user
|
||||
set_userseen($id, $seen);
|
||||
}
|
||||
|
||||
// NOTE: Edit this line if you want to update specific set of files by adding WHERE statment
|
||||
$allids = runSQL('SELECT id FROM '.TBL_DATA);
|
||||
|
||||
foreach ($allids as $id) {
|
||||
#if ($id['id'] <= 2113) continue;
|
||||
echo "Updating ID:".$id['id']."\n";
|
||||
FetchSaveMovie($id['id'],3);
|
||||
}
|
||||
// for testing
|
||||
// FetchSaveMovie(1,3);
|
||||
|
||||
?>
|
||||
7
videodb/contrib/index.html
Normal file
7
videodb/contrib/index.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; URL=../contrib.php">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
116
videodb/contrib/langcheck.php
Normal file
116
videodb/contrib/langcheck.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/**
|
||||
* Language Checker
|
||||
*
|
||||
* Checks languagefiles for completeness
|
||||
*
|
||||
* @package Contrib
|
||||
* @version $Id: langcheck.php,v 1.7 2013/03/10 17:08:36 andig2 Exp $
|
||||
*/
|
||||
|
||||
$LANGDIR = '../language';
|
||||
$base_lang = 'en';
|
||||
#include($LANGDIR.'/'.$base_lang.'_withtooltips.php');
|
||||
$tooltip_lang = array(); # $lang
|
||||
unset($lang);
|
||||
include($LANGDIR.'/en.php');
|
||||
|
||||
error_reporting(E_WARNING);
|
||||
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<title>Translation statistics</title>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
|
||||
function printlang($missing, $code, $type)
|
||||
{
|
||||
$c = count($missing);
|
||||
print '<b>'.$code.'</b> ';
|
||||
|
||||
if ($c)
|
||||
{
|
||||
print $c.' translations '.$type;
|
||||
print '<br /><br />';
|
||||
|
||||
foreach($missing as $key)
|
||||
{
|
||||
print $key.'<br />';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
print 'complete';
|
||||
}
|
||||
print '<br /><hr noshade="noshade" size="1" />';
|
||||
}
|
||||
|
||||
function getlangs(&$tooltipLangs)
|
||||
{
|
||||
global $LANGDIR;
|
||||
|
||||
if ($dh = opendir($LANGDIR))
|
||||
{
|
||||
while (($file = readdir($dh)) !== false)
|
||||
{
|
||||
if(preg_match("/(.*)\.php$/",$file,$matches))
|
||||
{
|
||||
$langs[]=$matches[1];
|
||||
if(substr($file, -16) == "withtooltips.php")
|
||||
{
|
||||
$tooltipLangs[] = $matches[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
else
|
||||
{
|
||||
print "could not open language directory $LANGDIR";
|
||||
exit;
|
||||
}
|
||||
|
||||
return $langs;
|
||||
}
|
||||
|
||||
function loadlang($code)
|
||||
{
|
||||
global $LANGDIR;
|
||||
|
||||
include($LANGDIR.'/'.$code.'.php');
|
||||
return $lang;
|
||||
}
|
||||
|
||||
|
||||
foreach(getlangs($tooltipLangs) as $code) if ($base_lang !== $code)
|
||||
{
|
||||
$foreign = loadlang($code);
|
||||
|
||||
$missing = array();
|
||||
$identical = array();
|
||||
|
||||
$useLang = $lang;
|
||||
|
||||
foreach (array_keys($useLang) as $key)
|
||||
{
|
||||
if(empty($foreign[$key]))
|
||||
{
|
||||
$missing[]=$key;
|
||||
}
|
||||
|
||||
if ($useLang[$key] == $foreign[$key])
|
||||
{
|
||||
$identical[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
printlang($missing, $code, 'missing');
|
||||
|
||||
if ($_GET['copycheck']) printlang($identical, $code, 'identical');
|
||||
}
|
||||
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
97
videodb/contrib/lookup_barcode.php
Normal file
97
videodb/contrib/lookup_barcode.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* Add a DVD/Video to VideoDB via the barcode on the box
|
||||
* (c) 2004 GPL'd
|
||||
*
|
||||
* @package Contrib
|
||||
* @author Andrew Pritchard <videodb@teppic.homeip.net>
|
||||
* @version $Id: lookup_barcode.php,v 1.4 2007/09/08 09:17:16 andig2 Exp $
|
||||
*/
|
||||
|
||||
chdir('..');
|
||||
require_once('./core/functions.php');
|
||||
|
||||
$notFound = 0;
|
||||
if (isset($_GET['barcode']))
|
||||
{
|
||||
// Base URL for the search
|
||||
$url = 'http://s1.amazon.co.uk/exec/varzea/sdp/sai-condition/';
|
||||
|
||||
// Add our post options and get the data
|
||||
$post = 'sdp-sai-asin='.$_GET['barcode'];
|
||||
$amazon_data = httpClient ($url, 0, $post);
|
||||
|
||||
// If it succeeds....
|
||||
if ($amazon_data['success'] == 1)
|
||||
{
|
||||
if (preg_match("/<b class=\"sans\">(.*)<\/b>/", $amazon_data['data'], $matches))
|
||||
{
|
||||
if ($matches[1] == 'Identify the exact item you&//039;re selling')
|
||||
{
|
||||
$notFound = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$media_type = 1;
|
||||
$title = urlencode($matches[1]);
|
||||
if (preg_match("/http:\/\/www.amazon.co.uk\/exec\/obidos\/ASIN\/(.*)\//", $amazon_data, $matches))
|
||||
{
|
||||
$asin_number = "ASIN: $matches[1]";
|
||||
}
|
||||
else
|
||||
{
|
||||
$asin_number = 'ASIN not found';
|
||||
}
|
||||
if (preg_match("/alt=\"VHS\"/", $amazon_data['data'], $matches))
|
||||
{
|
||||
$media_type = 6;
|
||||
}
|
||||
header("Location: ../edit.php?save=1&lookup=1&title=$title&diskid={$_GET['barcode']}&mediatype=$media_type&subtitle=$asin_number");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$notFound = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Print the error message
|
||||
print "Failed to download:<br>\n";
|
||||
print $amazon_data['error'];
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Add movie by Amazon-UK barcode</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Add movie by Amazon-UK barcode</h1>
|
||||
|
||||
<form name="addbarcode" method="get" action="<?php echo $_SERVER['PHP_SELF']?>">
|
||||
<input type="text" name="barcode" size="20">
|
||||
<input type="submit" name="submit" value="Submit">
|
||||
<input type="reset" name="reset" value="Reset">
|
||||
</form>
|
||||
<script language="JavaScript">
|
||||
<!--
|
||||
document.addbarcode.barcode.focus();
|
||||
//-->
|
||||
</script>
|
||||
|
||||
<?php
|
||||
if ($notFound == 1)
|
||||
{
|
||||
print "Sorry - your barcode wasn't found at Amazon<br>\n";
|
||||
//print_r($amazon_data);
|
||||
}
|
||||
elseif ($notFound == 2)
|
||||
{
|
||||
print "No data returned!<br>\n";
|
||||
print_r($amazon_data);
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
265
videodb/contrib/mass_add.php
Normal file
265
videodb/contrib/mass_add.php
Normal file
@@ -0,0 +1,265 @@
|
||||
<?php
|
||||
/**
|
||||
* mass_add.php
|
||||
*
|
||||
* Form for batch importing entries based on imdb id's.
|
||||
*
|
||||
* Changelog:
|
||||
* vv0.000000.1e-100000000 Initial version by Branko Kokanovic
|
||||
* v0.2 seen attribute now stored in userseen table - Alrik Bronsema
|
||||
*
|
||||
* @todo Optional check for duplicate entries.
|
||||
*
|
||||
* @package Contrib
|
||||
* @author Branko Kokanovic
|
||||
* @author Alrik Bronsema <alrikb@gmail.com>
|
||||
* @version $Id: mass_add.php,v 1.2 2007/07/27 10:09:07 andig2 Exp $
|
||||
*/
|
||||
|
||||
chdir('..');
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './core/genres.php';
|
||||
require_once './core/custom.php';
|
||||
require_once './core/security.php';
|
||||
?>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Mass IMDB movie add</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<?php
|
||||
|
||||
//slightly modified VideoDB function that does pretty much the same thing
|
||||
function InsertMovie($imdb_id,&$ret_title,$seen,$mediatype){
|
||||
|
||||
$imdb_set_fields = array('md5','title','subtitle','language','diskid','mediatype','comment','disklabel',
|
||||
'imdbID','year','imgurl','director','actors','runtime','country','plot','filename',
|
||||
'filesize','filedate','audio_codec','video_codec','video_width','video_height','istv',
|
||||
'custom1','custom2','custom3','custom4');
|
||||
|
||||
//fetching all the data
|
||||
$imdbdata=engineGetData($imdb_id);
|
||||
if ($imdbdata['title']=='') return 0;
|
||||
//sorting needed things
|
||||
|
||||
//genres--------------------------
|
||||
$genres = array();
|
||||
$gnames = $imdbdata['genres'];
|
||||
if (isset($gnames))
|
||||
{
|
||||
foreach ($gnames as $gname)
|
||||
{
|
||||
// check if genre is found- otherwise fail silently
|
||||
if (is_numeric($genre = getGenreId($gname)))
|
||||
{
|
||||
$genres[] = $genre;
|
||||
}
|
||||
}
|
||||
}
|
||||
//--------------------------------
|
||||
|
||||
//actors
|
||||
$actors = $imdbdata['cast'];
|
||||
|
||||
//movie owner---------------------
|
||||
if (check_permission(PERM_WRITE, $_COOKIE['VDBuserid'])){
|
||||
$owner_id = $_COOKIE['VDBuserid'];
|
||||
}else{
|
||||
$owner_id=0;
|
||||
}
|
||||
//--------------------------------
|
||||
|
||||
//cover
|
||||
$imgurl = $imdbdata['coverurl'];
|
||||
|
||||
// lookup all other fields
|
||||
foreach (array_keys($imdbdata) as $name){
|
||||
if (in_array($name, array('coverurl', 'genres', 'cast', 'id'))) continue;
|
||||
$$name = $imdbdata[$name];
|
||||
}
|
||||
|
||||
//year
|
||||
if (empty($year)) $year = '0000';
|
||||
|
||||
// set owner
|
||||
if (!empty($owner_id))
|
||||
$SETS = 'owner_id = '.escapeSQL($owner_id);
|
||||
|
||||
$imdbID=$imdb_id;
|
||||
// update all fields according to list
|
||||
foreach ($imdb_set_fields as $name){
|
||||
// sanitize input
|
||||
$$name = removeEvilTags($$name);
|
||||
|
||||
// make sure no formatting contained in basic data
|
||||
if (in_array($name, array('title', 'subtitle'))){
|
||||
$$name = trim(strip_tags($$name));
|
||||
|
||||
// string leading articles?
|
||||
if ($config['removearticles']){
|
||||
foreach ($articles as $article){
|
||||
if (preg_match("/^$article+/i", $$name)){
|
||||
$$name = trim(preg_replace("/(^$article)(.+)/i", "$2, $1", $$name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$SET = "$name = '".escapeSQL($$name)."'";
|
||||
|
||||
if (empty($$name)){
|
||||
if (in_array($name, $db_null_fields))
|
||||
$SET = "$name = NULL";
|
||||
elseif (in_array($name, $db_zero_fields))
|
||||
$SET = "$name = 0";
|
||||
}
|
||||
|
||||
if ($SETS) $SETS .= ', ';
|
||||
$SETS .= $SET;
|
||||
}
|
||||
|
||||
//inserting into database--------------------
|
||||
$INSERT = 'INSERT INTO '.TBL_DATA.' SET '.$SETS.', created = NOW()';
|
||||
//print_r($INSERT);
|
||||
//echo "<br><br>";
|
||||
$id = runSQL($INSERT);
|
||||
// save genres
|
||||
setItemGenres($id, $genres);
|
||||
//-------------------------------------------
|
||||
|
||||
// insert userseen data
|
||||
$INSERTSEEN = 'INSERT INTO `userseen` (`video_id`, `user_id`) VALUES ('.$id.','.$owner_id.')';
|
||||
runSQL($INSERTSEEN);
|
||||
$ret_title=$title;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((isset($_POST['Submit'])) && (is_uploaded_file($_FILES['id_list']['tmp_name']))){
|
||||
//lets set time limit of we can
|
||||
set_time_limit(30000);
|
||||
$filename = $_FILES['id_list']['tmp_name'];
|
||||
echo "File uploaded. Starting fetching and inserting into database...<br>";
|
||||
ob_flush();
|
||||
flush();
|
||||
//get seen field from form
|
||||
$seen=isset($_POST['seen'])?1:0;
|
||||
//get mediatype id from form
|
||||
$mediatype=$_POST['mediatype'];
|
||||
$lines=file($filename);
|
||||
//iterate for all lines in uploaded file
|
||||
foreach( $lines as $line){
|
||||
//trim \n from end of line
|
||||
$line=rtrim($line);
|
||||
//if line is empty, go to the next line
|
||||
if ($line=="") continue;
|
||||
//if we import by title, first get id from best matcing title
|
||||
if ($_POST['import_type']=='title'){
|
||||
$all=engineSearch($line);
|
||||
$id=$all[0][id];
|
||||
}
|
||||
else{
|
||||
$id=$line;
|
||||
}
|
||||
if (strpos($id,"imdb:")===false){
|
||||
$id="imdb:".$id;
|
||||
}
|
||||
//try to insert movie
|
||||
if (InsertMovie($id,&$title,$seen,$mediatype)==1){
|
||||
echo "<a href=\"http://www.imdb.com/title/tt".substr($id,-7)."/\">$title</a> inserted ";
|
||||
if ($_POST['import_type']=='title'){
|
||||
echo "(additional info - title form file was $line)";
|
||||
}
|
||||
echo "<br>";
|
||||
}
|
||||
else{ //ops, error
|
||||
echo "Error while inserting ID - ".$id." (additional info - ";
|
||||
if ($_POST['import_type']=='title')
|
||||
echo "title from file was $line) <br>";
|
||||
else{
|
||||
echo "id from file was $line) <br>";
|
||||
}
|
||||
}
|
||||
ob_flush();
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<h1>Mass IMDB movie add v0.2</h1><br>
|
||||
Ok, here is the thing:<br>
|
||||
|
||||
1. Browse for file with movie data (imdb ids or titles), hit Submit and pray:)
|
||||
<br>
|
||||
2. Script will try to set time limit, but this also depends from PHP configuration, so if script stops before all movies has been entered, check for PHP config.
|
||||
<br>
|
||||
3. File you need to browse is in form - one line per movie. So, if you want to import imdb ids, it should be something like:
|
||||
<br>
|
||||
<center>
|
||||
0088247
|
||||
<br>
|
||||
0088248
|
||||
<br>
|
||||
or
|
||||
<br>
|
||||
imdb:0088247
|
||||
<br>
|
||||
imdb:0088248
|
||||
<br>
|
||||
</center>
|
||||
and for titles:
|
||||
<br>
|
||||
<center>
|
||||
terminator
|
||||
<br>
|
||||
terrible joe moran
|
||||
<br>
|
||||
</center>
|
||||
In second case (import by titles), first matching title will be imported.
|
||||
<br>
|
||||
4. You must be logged to VideoDB as user who has write access (i.e. you can add movies on your own). All imported movies will be assigned to you. If you don't have write access or you are not logged, owner id will be 0.
|
||||
<br>
|
||||
5. Backup your data, make sure nothing can be lost, no responsibility, blah, blah...you already know it all.
|
||||
<br>
|
||||
<br>
|
||||
<form action="" method="post" enctype="multipart/form-data" name="form" id="form">
|
||||
<input name="import_type" type="radio" value="id" checked="checked" /> Import by ids
|
||||
<br>
|
||||
<input name="import_type" type="radio" value="title" /> Import by titles
|
||||
<br>
|
||||
<input type="checkbox" name="seen" value="1" /> Set all movies as seen
|
||||
<br>
|
||||
Media type:
|
||||
<select name="mediatype">
|
||||
<?php
|
||||
$first=false;
|
||||
$ret=runSQL("SELECT * FROM mediatypes");
|
||||
foreach($ret as $mediatype){
|
||||
if ($first==false){
|
||||
$first=true;
|
||||
echo "<option value=\"$mediatype[id]\" selected=\"selected\">$mediatype[name]</option>";
|
||||
}
|
||||
else{
|
||||
echo "<option value=\"$mediatype[id]\">$mediatype[name]</option>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<br>
|
||||
Import list:<input type="file" name="id_list" />
|
||||
<br>
|
||||
<input type="submit" name="Submit" value="Mass add" />
|
||||
</form>
|
||||
<br>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
||||
30
videodb/contrib/mklist.pl
Normal file
30
videodb/contrib/mklist.pl
Normal file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use DBI;
|
||||
|
||||
$db_server = "localhost";
|
||||
$db_user = "www";
|
||||
$db_password = "leech";
|
||||
$db_database = "VideoDB";
|
||||
|
||||
$dbh = DBI->connect("dbi:mysql:$db_database:$db_server",$db_user,$db_password) || die("Can't connect");
|
||||
|
||||
|
||||
$SELECT = "SELECT filename, filesize, diskid
|
||||
FROM videodata
|
||||
ORDER BY filename";
|
||||
|
||||
$result = $dbh->selectall_arrayref($SELECT);
|
||||
|
||||
print "DiskID\tSize\t\tFilename\n";
|
||||
print "-"x74;
|
||||
print "\n";
|
||||
|
||||
$row=0;
|
||||
while (defined($result->[$row][0])){
|
||||
printf("%s\t",$result->[$row][2]);
|
||||
printf("%3.2f MB\t",($result->[$row][1]/(1024*1024)));
|
||||
printf("%s\n",$result->[$row][0]);
|
||||
|
||||
$row++;
|
||||
}
|
||||
276
videodb/contrib/refetchAllInfos.php
Normal file
276
videodb/contrib/refetchAllInfos.php
Normal file
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
/**
|
||||
* Refetch and overwrite all movie information by according engine
|
||||
*
|
||||
* (c) 2005 GPL'd
|
||||
*
|
||||
* @package Contrib
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @meta ACCESS:PERM_ADMIN
|
||||
*/
|
||||
|
||||
chdir('..');
|
||||
require_once './core/functions.php';
|
||||
require_once './core/custom.php';
|
||||
require_once './core/security.php';
|
||||
require_once './engines/engines.php';
|
||||
require_once './core/compatibility.php';
|
||||
|
||||
// check for localnet
|
||||
localnet_or_die();
|
||||
|
||||
// multiuser permission check
|
||||
permission_or_die(PERM_WRITE);
|
||||
|
||||
|
||||
/**
|
||||
* Fetch a list of all editable video fields (keys)
|
||||
* and assign 1 (value) if they should be preselected else 0
|
||||
*/
|
||||
function getFields()
|
||||
{
|
||||
$edit_file = file_get_contents('./core/edit.core.php');
|
||||
$edit_file = preg_replace("/\n/",'',$edit_file);
|
||||
|
||||
|
||||
if (preg_match('/\$imdb_set_fields\s*=\s*array\s*\((.*?)\)/', $edit_file, $fieldslist) &&
|
||||
preg_match('/\$imdb_overwrite_fields.*?array\s*\((.*?)\)/', $edit_file, $overwritelist))
|
||||
{
|
||||
$fields = array_map('trim', split(',', preg_replace("/'/", '', $fieldslist[1])));
|
||||
$overwrites = array_map('trim', split(',', preg_replace("/'/", '', $overwritelist[1])));
|
||||
|
||||
$ret = array();
|
||||
foreach ($fields as $field)
|
||||
{
|
||||
$value = (in_array($field, $overwrites)) ? 1 : 0;
|
||||
if (preg_match('/custom/', $field)) $value = 0;
|
||||
$ret = array_merge ($ret, array($field => $value));
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!check_permission(PERM_ADMIN)) {
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<title>Refetch all external engine information</title>
|
||||
<meta http-equiv="refresh" content="0; URL=../index.php">
|
||||
<META http-equiv="Content-Style-Type" content="text/html">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (isset($submit) && $submit == "Yes")
|
||||
{
|
||||
$contribUrl = "http://".$_SERVER['SERVER_NAME'].":".$_SERVER['SERVER_PORT']
|
||||
.substr($_SERVER['PHP_SELF'],0,strrpos ( $_SERVER['PHP_SELF'], '/' ));
|
||||
$baseUrl = substr($contribUrl,0,strrpos ($contribUrl, '/'));
|
||||
|
||||
// get list movies in DB
|
||||
$SQL = 'SELECT * FROM '.TBL_DATA;
|
||||
if ($user != '0') $SQL .= ' WHERE owner_id = '.$user;
|
||||
$result = runSQL($SQL);
|
||||
|
||||
$CLIENTERRORS = array();
|
||||
$CLIENTOKS = array();
|
||||
$diskid = 0;
|
||||
|
||||
foreach ($result as $video)
|
||||
{
|
||||
$diskid++;
|
||||
// Filter movies of unselected Users.
|
||||
// if ($user != '0' && $video['owner_id'] != $user) continue;
|
||||
|
||||
// Filter movies of unselected Engines
|
||||
if ($selectedengine != 'all' && engineGetEngine($video['imdbID']) != $selectedengine) continue;
|
||||
|
||||
// new DiskID ?
|
||||
if (isset($resetDI) && $resetDI == "true")
|
||||
{
|
||||
$didigits = $GLOBALS['config']['diskid_digits'];
|
||||
if (empty($didigits)) $didigits = 4;
|
||||
$newId=sprintf('%0'.$didigits.'d',$diskid);
|
||||
|
||||
// make sure lent table is changed too
|
||||
$SELECT = "SELECT diskid FROM ".TBL_DATA." WHERE id = ".$video['id'];
|
||||
$oldDiskId = runSQL($SELECT);
|
||||
$UPDATE = "UPDATE ".TBL_LENT." SET diskid = 'TMP".$newId."' WHERE diskid = '".$oldDiskId[0]['diskid']."'";
|
||||
runSQL($UPDATE);
|
||||
|
||||
$UPDATE = "UPDATE ".TBL_DATA." SET diskid = '".$newId."' WHERE id = ".$video['id'];
|
||||
runSQL($UPDATE);
|
||||
}
|
||||
|
||||
// cannot refetch without external id
|
||||
if (empty($video['imdbID'])) continue;
|
||||
|
||||
set_time_limit(300); // raise per movie execution timeout limit if safe_mode is not set in php.ini
|
||||
|
||||
$id = $video['id'];
|
||||
$imdbID = $video['imdbID'];
|
||||
$engine = engineGetEngine($video['imdbID']);
|
||||
|
||||
$fieldlist = "";
|
||||
foreach (array_keys($_POST) as $param)
|
||||
{
|
||||
if (preg_match('/^(update_.*)/',$param,$fieldname))
|
||||
{
|
||||
$fieldlist .= "&".$fieldname[1]."=1";
|
||||
}
|
||||
}
|
||||
$url = $baseUrl."/edit.php?id=".$id."&engine=".$engine."&save=1&lookup=".$lookup.$fieldlist;
|
||||
$resp = httpClient($url, false, array('cookies' => $_COOKIE, 'no_proxy' => true, 'no_redirect' => true));
|
||||
if (!$resp['success'])
|
||||
{
|
||||
$CLIENTERRORS[] = $video['title']." (".$video['diskid']."/".engineGetEngine($video['imdbID'])."): ".$resp['error'];
|
||||
}
|
||||
else $CLIENTOKS[] = $video['title']." (".$video['diskid']."/".engineGetEngine($video['imdbID']).")";
|
||||
}
|
||||
|
||||
if (isset($resetDI) && $resetDI == "true")
|
||||
{
|
||||
// fix lent table after upper temp. changes
|
||||
$SELECT = "SELECT diskid FROM ".TBL_LENT." WHERE diskid like 'TMP%'";
|
||||
$lentResult = runSQL($SELECT);
|
||||
foreach ($lentResult as $lentRow)
|
||||
{
|
||||
$diskid = preg_replace('/^TMP/','',$lentRow['diskid']);
|
||||
$UPDATE = "UPDATE ".TBL_LENT." SET diskid = '".$diskid."' WHERE diskid = 'TMP".$diskid."'";
|
||||
runSQL($UPDATE);
|
||||
}
|
||||
}
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<title>Refetch all external engine information</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Report</h1><p>
|
||||
<h2>ERROR:</h2><p>
|
||||
<?php foreach ($CLIENTERRORS as $error) { ?>
|
||||
<?php echo $error ?>
|
||||
<br>
|
||||
<?php } ?>
|
||||
|
||||
<h2>SUCCESS:</h2><p>
|
||||
<?php foreach ($CLIENTOKS as $ok) { ?>
|
||||
<?php echo $ok ?>
|
||||
<br>
|
||||
<?php } ?>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
}
|
||||
elseif (isset($submit) && $submit == "LOAD")
|
||||
{
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<title>Refetch all external engine information</title>
|
||||
<link rel="stylesheet" href="../<?php echo $config['style'] ?>" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body style="font-size: 16px">
|
||||
|
||||
<form method="post" action="<?php echo $_SERVER['PHP_SELF']?>" target="mainFrame" onSubmit="alert('This may take a LONG time (dependent on movie count and connection speed)!!!');">
|
||||
|
||||
<div>
|
||||
<div style="float:right">
|
||||
<a href="javascript:parent.location.href='../index.php';"><img src="../images/close.gif" width="14" height="14" alt="" border="0" /></a>
|
||||
</div>
|
||||
|
||||
Refetch and overwrite selected fields of movies for this User:
|
||||
<select name="user">
|
||||
<option value="0" selected="selected">All Users</option>
|
||||
<?php
|
||||
$SQL = 'SELECT name, id FROM '.TBL_USERS;
|
||||
$result = runSQL($SQL);
|
||||
foreach ($result as $user)
|
||||
{
|
||||
print '<option value="'.$user['id'].'">'.$user['name']."</option>\n";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Update fields only for movies fetched by this engine:
|
||||
<select name="selectedengine">
|
||||
<option value="all" selected="selected">All Engines</option>
|
||||
<?php
|
||||
global $config;
|
||||
foreach ($config['engines'] as $engine => $meta)
|
||||
{
|
||||
print '<option value="'.$engine.'">'.$meta['name']."</option>\n";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Data Lookup:
|
||||
<label for="lookup1"><input type="radio" name="lookup" id="lookup1" value="5" checked = "checked" />add missing</label>
|
||||
<label for="lookup2"><input type="radio" name="lookup" id="lookup2" value="6" />overwrite</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<table><tr>
|
||||
<?
|
||||
$fields_in_a_row = 6;
|
||||
$fields = getFields();
|
||||
$keys = array_keys($fields);
|
||||
$field_amount = count($keys);
|
||||
for($i = 0; $i < $field_amount; $i++)
|
||||
{
|
||||
$checked = ($fields[$keys[$i]] == 1) ? "checked" : "";
|
||||
if ($i % $fields_in_a_row == 0 && $i != 0) print "</TR><TR>";
|
||||
print '<TD nowrap="nowrap"><input type="checkbox" name="update_'.$keys[$i].'" value="1" '.$checked.' />'.$keys[$i].'</TD>';
|
||||
}
|
||||
for ($i = 0; $i < ($fields_in_a_row - ($field_amount % $fields_in_a_row)); $i++) {
|
||||
print '<TD> </TD>';
|
||||
}
|
||||
?>
|
||||
</tr></table>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
reset DiskIDs FOR ALL MOVIES AND ALL USERS?<input type="checkbox" name="resetDI" value="true" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Are you shure to know what you are doing?
|
||||
<input type="submit" name="submit" value="Yes">
|
||||
<input type="button" value="No" onClick="parent.location.href='../index.php';">
|
||||
</div>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<title>Refetch all external engine information</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
|
||||
<frameset name="fs1" rows="260,*" frameborder="NO" border="0" framespacing="0">
|
||||
<frame name="topFrame" scrolling="NO" noresize src="<?php echo $_SERVER['PHP_SELF']?>?submit=LOAD">
|
||||
<frame name="mainFrame" src="">
|
||||
</frameset>
|
||||
|
||||
<noframes>
|
||||
<body>Please use a browser which supports frames!</body>
|
||||
</noframes>
|
||||
</html>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
54
videodb/contrib/setGenre.pl
Normal file
54
videodb/contrib/setGenre.pl
Normal file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# Set title
|
||||
$TITLE="South Park";
|
||||
|
||||
# Set genres (see list below for ids)
|
||||
@GENRES=(4,3);
|
||||
|
||||
# 1 Action
|
||||
# 2 Adventure
|
||||
# 3 Animation
|
||||
# 4 Comedy
|
||||
# 5 Crime
|
||||
# 6 Documentary
|
||||
# 7 Drama
|
||||
# 8 Family
|
||||
# 9 Fantasy
|
||||
# 10 Film-Noir
|
||||
# 11 Horror
|
||||
# 12 Musical
|
||||
# 13 Mystery
|
||||
# 14 Romance
|
||||
# 15 Sci-Fi
|
||||
# 16 Short
|
||||
# 17 Thriller
|
||||
# 18 War
|
||||
# 19 Western
|
||||
|
||||
$db_server = "localhost";
|
||||
$db_user = "www";
|
||||
$db_password = "leech";
|
||||
$db_database = "VideoDB";
|
||||
|
||||
######################################################################
|
||||
use DBI;
|
||||
$dbh = DBI->connect("dbi:mysql:$db_database:$db_server",$db_user,$db_password) || die("Can't connect");
|
||||
|
||||
$SELECT = "SELECT id from videodata
|
||||
WHERE title LIKE '$TITLE'";
|
||||
$idr = $dbh->selectall_arrayref($SELECT);
|
||||
|
||||
$row=0;
|
||||
while (defined($idr->[$row][0])){
|
||||
my $id = $idr->[$row][0];
|
||||
|
||||
#clear existing genres:
|
||||
$dbh->do("DELETE FROM videogenre WHERE id = $id");
|
||||
|
||||
#insert new genres
|
||||
foreach my $gid (@GENRES){
|
||||
$dbh->do("INSERT INTO videogenre SET id = $id, gid = $gid");
|
||||
}
|
||||
$row++;
|
||||
}
|
||||
7
videodb/contrib/setOwner.sql
Normal file
7
videodb/contrib/setOwner.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
# This SQL statement changes the owner of all unowned movies be sure to change
|
||||
# NEWOWNER to the name of the user who should own the movies.
|
||||
|
||||
UPDATE videodata
|
||||
SET owner = 'NEWOWNER'
|
||||
WHERE owner IS NULL
|
||||
OR owner = '';
|
||||
177
videodb/contrib/utf_migration.php
Normal file
177
videodb/contrib/utf_migration.php
Normal file
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
/**
|
||||
* UTF-8 Migration Utility
|
||||
*
|
||||
* @package Contrib
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* $Id: utf_migration.php,v 1.2 2008/01/06 12:30:00 andig2 Exp $
|
||||
*/
|
||||
|
||||
chdir('..');
|
||||
require_once './core/functions.php';
|
||||
require_once './core/encoding.php';
|
||||
|
||||
?>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Migrate database contents to UTF-8</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=<?=$targetencoding?>" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<b>
|
||||
Attention: Be sure to perform a backup before running the encoding migration!
|
||||
</b>
|
||||
|
||||
<h2>1. Choose source and target encoding</h2>
|
||||
|
||||
<form action="<?=$PHP_SELF?>">
|
||||
|
||||
<div>
|
||||
Source encoding:
|
||||
<select name="sourceencoding">
|
||||
<option value="iso-8859-1" <? if($sourceencoding=='iso-8859-1'|| empty($sourceencoding)) echo 'selected="selected"' ?>>iso-8859-1</option>
|
||||
<option value="iso-8859-7" <? if($sourceencoding=='iso-8859-7') echo 'selected="selected"' ?>>iso-8859-7</option>
|
||||
<option value="iso-8859-9" <? if($sourceencoding=='iso-8859-9') echo 'selected="selected"' ?>>iso-8859-9</option>
|
||||
<option value="windows-1251" <? if($sourceencoding=='windows-1251') echo 'selected="selected"' ?>>windows-1251</option>
|
||||
<option value="koi8-r" <? if($sourceencoding=='koi8-r') echo 'selected="selected"' ?>>koi8-r</option>
|
||||
<option value="utf-8" <? if($sourceencoding=='utf-8') echo 'selected="selected"' ?>>utf-8</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Target encoding:
|
||||
<select name="targetencoding">
|
||||
<option value="iso-8859-1" <? if($sourceencoding=='iso-8859-1') echo 'selected="selected"' ?>>iso-8859-1</option>
|
||||
<option value="iso-8859-7" <? if($targetencoding=='iso-8859-7') echo 'selected="selected"' ?>>iso-8859-7</option>
|
||||
<option value="iso-8859-9" <? if($targetencoding=='iso-8859-9') echo 'selected="selected"' ?>>iso-8859-9</option>
|
||||
<option value="windows-1251" <? if($targetencoding=='windows-1251') echo 'selected="selected"' ?>>windows-1251</option>
|
||||
<option value="koi8-r" <? if($targetencoding=='koi8-r') echo 'selected="selected"' ?>>koi8-r</option>
|
||||
<option value="utf-8" <? if($targetencoding=='utf-8' || empty($targetencoding)) echo 'selected="selected"' ?>>utf-8</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Simulate only: <input type="checkbox" name="simulate" checked="checked" />
|
||||
</div>
|
||||
|
||||
<input type="submit" value="Submit" />
|
||||
|
||||
</form>
|
||||
|
||||
<?
|
||||
|
||||
/**
|
||||
* SQL function
|
||||
*/
|
||||
function sql_native($sql_string)
|
||||
{
|
||||
global $config, $db_native;
|
||||
|
||||
if (!is_resource($db_native))
|
||||
{
|
||||
$db_native = mysqli_pconnect($config['db_server'], $config['db_user'], $config['db_password'], $config['db_database']);
|
||||
if (mysqli_connect_error())
|
||||
errorpage('DB Connection Error',
|
||||
"<p>Edit the database settings in <code>".CONFIG_FILE."</code>.</p>
|
||||
<p>Alternatively, consider running the <a href='install.php'>installation script</a>.</p>");
|
||||
}
|
||||
|
||||
$res = mysqli_query($db_native, $sql_string);
|
||||
|
||||
// mysqli_db_query returns either positive result ressource or true/false for an insert/update statement
|
||||
if ($res === false)
|
||||
{
|
||||
// report DB Problem
|
||||
errorpage('Database Problem', mysqli_error($db_native)."\n<br />\n".$sql_string);
|
||||
}
|
||||
elseif ($res === true)
|
||||
{
|
||||
// on insert, return id of created record
|
||||
$result = mysqli_insert_id($db_native);
|
||||
}
|
||||
else
|
||||
{
|
||||
// return associative result array
|
||||
$result = array();
|
||||
|
||||
for ($i=0; $i<mysqli_num_rows($res); $i++)
|
||||
{
|
||||
$result[] = mysqli_fetch_assoc($res);
|
||||
}
|
||||
mysqli_free_result($res);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function db_encode($s)
|
||||
{
|
||||
global $db_native;
|
||||
|
||||
if (is_numeric($s)) return $s;
|
||||
elseif (empty($s)) return 'NULL';
|
||||
else return "'".mysqli_escape_string($db_native, $s)."'";
|
||||
}
|
||||
|
||||
$db_encodings = array('iso-8859-1'=>'latin1', 'iso-8859-7'=>'latin7', 'iso-8859-9'=>'latin9', 'windows-1251'=>'cp1251', 'koi8-r'=>'koi8r', 'utf-8'=>'utf8');
|
||||
$tables = array(TBL_DATA, TBL_ACTORS);
|
||||
|
||||
extract($_REQUEST);
|
||||
|
||||
$db_sourceencoding = $db_encodings[$sourceencoding];
|
||||
$db_targetencoding = $db_encodings[$targetencoding];
|
||||
|
||||
if ($sourceencoding && $targetencoding && ($sourceencoding != $targetencoding))
|
||||
{
|
||||
# if (!preg_match('/^(\w\d)+$/', $sourceencoding)) die ('Security violation');
|
||||
# if (!preg_match('/^(\w\d)+$/', $targetencoding)) die ('Security violation');
|
||||
|
||||
?>
|
||||
|
||||
<h2>2. Validate data correctness and execute</h2>
|
||||
|
||||
<?
|
||||
dump("Converting from $sourceencoding to $targetencoding");
|
||||
|
||||
sql_native("SET NAMES '".$db_targetencoding."'");
|
||||
|
||||
foreach ($tables as $table)
|
||||
{
|
||||
dump("Table: ".$table);
|
||||
|
||||
$res = sql_native('SELECT * FROM '.$table);
|
||||
dump("Items: ".count($res)."<br/>");
|
||||
|
||||
$enc = iconv_array($sourceencoding, $targetencoding, $res);
|
||||
|
||||
for ($i=0; $i<count($enc); $i++)
|
||||
{
|
||||
$row = $enc[$i];
|
||||
|
||||
// check if encoding really changed
|
||||
if (join(array_values($row)) == join(array_values($res[$i]))) continue;
|
||||
|
||||
$id = $row['id'];
|
||||
if (!$id) die("No ID found");
|
||||
unset($row['id']);
|
||||
|
||||
$SQL = '';
|
||||
foreach ($row as $key=>$val)
|
||||
{
|
||||
if ($SQL) $SQL .= ', ';
|
||||
$SQL .= $key.'='.db_encode($val);
|
||||
}
|
||||
$SQL = "UPDATE $table SET ".$SQL." WHERE id=".$id;
|
||||
dump($SQL);
|
||||
|
||||
if (!$simulate) sql_native($SQL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
70
videodb/contrib/vdb_wiki.sh
Normal file
70
videodb/contrib/vdb_wiki.sh
Normal file
@@ -0,0 +1,70 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Extract documentation from wiki to include in release package
|
||||
#
|
||||
# @package Release
|
||||
# @author Andreas Gohr <a.gohr@web.de>
|
||||
# @author Andreas Goetz <cpuidle@gmx.de>
|
||||
# @link http://www.splitbrain.org/dokuwiki/vdb:videodb
|
||||
# @version $Id: vdb_wiki.sh,v 1.1 2004/08/11 10:09:13 andig2 Exp $
|
||||
#
|
||||
|
||||
# remove existing doku
|
||||
rm -f *.html
|
||||
|
||||
# get doku from dokuwiki
|
||||
wget --level 2 -r -np -nc -nd -E -k -A 'vdb*' -R '*\?*' http://www.splitbrain.org/dokuwiki/vdb:videodb
|
||||
|
||||
# delete files
|
||||
for x in `ls *@*`
|
||||
do
|
||||
rm $x
|
||||
done
|
||||
|
||||
# fix filenames
|
||||
for x in `ls *%3A*`
|
||||
do
|
||||
mv $x `echo $x|tr -s %3A _`
|
||||
done
|
||||
|
||||
#cp ../Copy\ of\ vdb/* .
|
||||
|
||||
# fix html
|
||||
for x in `ls *.html`
|
||||
do
|
||||
# move to tempfile
|
||||
cp $x $x.tmp
|
||||
|
||||
# add new header
|
||||
cat >$x <<EOF
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="vdb_videodb.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
EOF
|
||||
|
||||
# add fixed content
|
||||
cat $x.tmp | \
|
||||
perl -e '$foo=join("",<>);
|
||||
$foo=~s/vdb(:|%3A)/vdb_/gs;
|
||||
$foo=~m/<!-- wikipage start -->(.*)<!-- foocache/s;
|
||||
print $1' \
|
||||
>> $x
|
||||
|
||||
|
||||
# add new footer
|
||||
cat >>$x <<EOF
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
# remove tempfile
|
||||
rm -f $x.tmp
|
||||
done
|
||||
|
||||
422
videodb/contrib/videoadd.php
Normal file
422
videodb/contrib/videoadd.php
Normal file
@@ -0,0 +1,422 @@
|
||||
<?php
|
||||
/**
|
||||
* Add movies on a file system to the DB
|
||||
*
|
||||
* Pre-requsisions:
|
||||
* mplayer:
|
||||
* Test if installed with this command: mplayer -v
|
||||
* If not installed use this command (Ubuntu) to install: sudo apt install mplayer
|
||||
*
|
||||
* Please change following variables
|
||||
*
|
||||
* movie_dirs -- list of directories to search for a new files
|
||||
* update_missing -- if set to TRUE, the movie with a file in DB but not on a disk will be set as wanted
|
||||
* update_moved -- if set to TRUE, if file was moved to a different location on a disk, the location in a DB will be updated to a new path
|
||||
* clean_file_name -- is a substring in a name of the file you want to be removed when setting movie name
|
||||
* skip_folders -- a list of subfolders to be skipped
|
||||
*
|
||||
* @package pages
|
||||
* @author Alexander Mondshain <alex_mond@yahoo.com>
|
||||
* @author Alexander Mondshain <klaus_edwin@hotmail.com>
|
||||
* @version $Id: videoadd.php,v 1.3 2018/09/23 13:02:11 kec2 Exp $
|
||||
*/
|
||||
chdir('..');
|
||||
|
||||
require './core/functions.php';
|
||||
|
||||
// Movies on the file system.
|
||||
// File name is key and full path is value.
|
||||
$moviesFS = array();
|
||||
// duplicate file on file system.
|
||||
// File name is key and full path is value.
|
||||
$doubles = array();
|
||||
|
||||
// NOTE : as a minimum change the following movie_dirs variable to point to a movie directory $movieDirs = array("/moviedir1","/moviedir2);
|
||||
$movieDirs = array();
|
||||
$movieExts = '(avi|mpg|bin|mpeg|ogm|bin|mkv|m2ts|iso)';
|
||||
$cleanFileName = '(.avi|.mkv|.iso|.m2ts|XVID|XviD|XViD|Xvid|CD1)';
|
||||
$skipFolders = '/^\.|^CVS|^lost|^photos|^music|^staff/';
|
||||
|
||||
// NOTE:update_missing, update missing files and associeted movies as wanted
|
||||
// NOTE:update_moved. update moved files with a new file location
|
||||
$update_missing = false;
|
||||
$update_moved = false;
|
||||
|
||||
/**
|
||||
* Check if MPlayer is installed.
|
||||
*
|
||||
* @return boolean True if it is installed.
|
||||
*/
|
||||
function isMPlayerInstalled()
|
||||
{
|
||||
$out = null;
|
||||
$ret = - 1;
|
||||
@exec("mplayer -v", $out, $ret);
|
||||
return $ret == '0';
|
||||
}
|
||||
|
||||
/**
|
||||
* If a movies consits of multiple file then all but one will be removed.
|
||||
* fx. Thor_CD1.avi, Thor_CD2.avi and Thor_CD3.avi => Thor_CD1.avi.
|
||||
*/
|
||||
function removeCDNumbers($moviesFS)
|
||||
{
|
||||
foreach ($moviesFS as $movie) {
|
||||
$filePathParts = preg_split("/\//", $movie);
|
||||
$fileName = end($filePathParts);
|
||||
|
||||
if (preg_match("/CD2/i", $movie)) {
|
||||
unset($moviesFS[$fileName]);
|
||||
} else if (preg_match("/CD3/i", $movie)) {
|
||||
unset($moviesFS[$fileName]);
|
||||
} else if (preg_match("/CD4/i", $movie)) {
|
||||
unset($moviesFS[$fileName]);
|
||||
}
|
||||
}
|
||||
return $moviesFS;
|
||||
}
|
||||
|
||||
function getFileSizeLinux($file)
|
||||
{
|
||||
$out = null;
|
||||
$ret = - 1;
|
||||
@exec("stat -c %s \"$file\"", $out, $ret);
|
||||
if ($ret != '0') {
|
||||
return FALSE;
|
||||
} else {
|
||||
return ($out[0]);
|
||||
}
|
||||
}
|
||||
|
||||
function getFileTimeLinux($file)
|
||||
{
|
||||
$out = null;
|
||||
$ret = - 1;
|
||||
@exec("stat -c %Y \"$file\"", $out, $ret);
|
||||
if ($ret != '0') {
|
||||
return FALSE;
|
||||
} else {
|
||||
return ($out[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get all movie files requrcily starting from \$dir.
|
||||
*
|
||||
* @param String $dir
|
||||
* The starting point.
|
||||
* @param String $ext
|
||||
* Files with these file extensions are or included in the result.
|
||||
* @param String $skip
|
||||
* Directories to skip.
|
||||
*/
|
||||
function recurseDir($dir, $ext, $skip)
|
||||
{
|
||||
// echo "In DIR $dir<br>";
|
||||
global $moviesFS, $doubles;
|
||||
if ($dh = opendir($dir)) {
|
||||
while ($file = readdir($dh)) {
|
||||
// Exclude all dot file, CVS and lost+found directories
|
||||
if (preg_match($skip, $file)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the file is a movie, we add it to the list
|
||||
if (preg_match("/\.$ext$/", $file)) {
|
||||
if (isset($moviesFS[$file])) {
|
||||
array_push($doubles, $moviesFS[$file]);
|
||||
array_push($doubles, "$dir/$file");
|
||||
} else {
|
||||
$moviesFS[$file] = "$dir/$file";
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a directory we search it
|
||||
if (is_dir("$dir/$file")) {
|
||||
recurseDir("$dir/$file", $ext, $skip);
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get combined file size of a movies with multiple files.
|
||||
* fx. Thor_CD1.avi (100k), Thor_CD2.avi (200k) and Thor_CD3.avi (150k) => 450k.
|
||||
*
|
||||
* @param string $filePath
|
||||
* Path to the first file.
|
||||
* @return integer The size of the file(s).
|
||||
*/
|
||||
function getFileSize($filePath)
|
||||
{
|
||||
$fileSize = getFileSizeLinux($filePath);
|
||||
|
||||
if (preg_match("/CD1/i", $filePath)) {
|
||||
$newfile = preg_replace("/(CD)(\d)/i", '${1}2', $filePath);
|
||||
$fileSize += getFileSizeLinux($newfile);
|
||||
|
||||
$newfile = preg_replace("/(CD)(\d)/i", '${1}3', $filePath);
|
||||
$fileSize += getFileSizeLinux($newfile);
|
||||
|
||||
$newfile = preg_replace("/(CD)(\d)/i", '${1}4', $filePath);
|
||||
$fileSize += getFileSizeLinux($newfile);
|
||||
}
|
||||
|
||||
return $fileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get metadata of a movie.
|
||||
* Data include video codec, audio codec, video width and video height.
|
||||
* MPlayer is used to retrive these data.
|
||||
*
|
||||
* @param String $filePath
|
||||
* File path to the movie.
|
||||
* @return array An assosiative array with keys: videoCodec, audioCodec, videoHeight and videoWidth.
|
||||
*/
|
||||
function getMetadata($filePath)
|
||||
{
|
||||
$metadata = array();
|
||||
$command = "mplayer -vo null -ao null -frames 3 -identify \"$filePath\"";
|
||||
// echo "command: ".$command."<br>";
|
||||
$output = array();
|
||||
$return_var = 0;
|
||||
|
||||
$match = array();
|
||||
exec($command, $output, $return_var);
|
||||
// parse mplayer output
|
||||
foreach ($output as $line) {
|
||||
trim($line);
|
||||
|
||||
if (preg_match("/ID_VIDEO_CODEC=(.*)/", $line, $match)) {
|
||||
$videoCodec = strtolower($match[1]);
|
||||
switch ($videoCodec) {
|
||||
case 'ffh264':
|
||||
$metadata['videoCodec'] = 'H.264';
|
||||
break;
|
||||
case 'ffvc1':
|
||||
$metadata['videoCodec'] = 'VC1';
|
||||
break;
|
||||
case '0x10000001':
|
||||
$metadata['videoCodec'] = 'MPEG1';
|
||||
break;
|
||||
case 'ffmpeg2':
|
||||
$metadata['videoCodec'] = 'MPEG2';
|
||||
break;
|
||||
case '0x10000002':
|
||||
$metadata['videoCodec'] = 'MPEG2';
|
||||
break;
|
||||
case 'mpg4':
|
||||
$metadata['videoCodec'] = 'MPEG4';
|
||||
break;
|
||||
case 'div3':
|
||||
$metadata['videoCodec'] = 'DivX3';
|
||||
break;
|
||||
case 'div4':
|
||||
$metadata['videoCodec'] = 'DivX4';
|
||||
break;
|
||||
case 'divx':
|
||||
$metadata['videoCodec'] = 'DivX4';
|
||||
break;
|
||||
case 'dx50':
|
||||
$metadata['videoCodec'] = 'DivX5';
|
||||
break;
|
||||
case 'xvid':
|
||||
$metadata['videoCodec'] = 'XviD';
|
||||
break;
|
||||
default:
|
||||
$metadata['videoCodec'] = 'Unknown';
|
||||
echo 'Unknown Video Codec: ' . $match[1] . '<br>';
|
||||
}
|
||||
} else if (preg_match("/ID_AUDIO_CODEC=(.*)/", $line, $match)) {
|
||||
$audioCodec = strtolower($match[1]);
|
||||
switch ($audioCodec) {
|
||||
case 'fftruehd':
|
||||
$metadata['audioCodec'] = 'Dolby TrueHD';
|
||||
break;
|
||||
case 'ffdca':
|
||||
$metadata['audioCodec'] = 'DTS-HD Master Audio';
|
||||
break;
|
||||
case 'ffac3':
|
||||
$metadata['audioCodec'] = 'AC-3';
|
||||
break;
|
||||
case 'a52':
|
||||
$metadata['audioCodec'] = 'AC3';
|
||||
break;
|
||||
case 'pcm':
|
||||
$metadata['audioCodec'] = 'Uncompressed PCM';
|
||||
break;
|
||||
case 'dvdpcm':
|
||||
$metadata['audioCodec'] = 'Uncompressed DVD/VOB LPCM';
|
||||
break;
|
||||
case 'mad':
|
||||
$metadata['audioCodec'] = 'MP3';
|
||||
break;
|
||||
case 'mp3':
|
||||
$metadata['audioCodec'] = 'MP3';
|
||||
break;
|
||||
case 'ffvorbis':
|
||||
$metadata['audioCodec'] = 'Vorbis';
|
||||
break;
|
||||
case 'ffwmav1':
|
||||
$metadata['audioCodec'] = 'WMA1';
|
||||
break;
|
||||
case 'ffwmav2':
|
||||
$metadata['audioCodec'] = 'WMA2';
|
||||
break;
|
||||
default:
|
||||
$metadata['audioCodec'] = 'Unknown';
|
||||
echo 'Unknown Audio Codec: ' . $match[1] . '<br>';
|
||||
}
|
||||
} else if (preg_match("/ID_VIDEO_WIDTH=(.*)/", $line, $match)) {
|
||||
$metadata['videoWidth'] = $match[1];
|
||||
} else if (preg_match("/ID_VIDEO_HEIGHT=(.*)/", $line, $match)) {
|
||||
$metadata['videoHeight'] = $match[1];
|
||||
}
|
||||
}
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
?>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Add and move files</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="description" content="VideoDB" />
|
||||
<link rel="stylesheet" href="../<?php echo $config['style'] ?>"
|
||||
type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
|
||||
if (!isMPlayerInstalled()) {
|
||||
echo '<h1 style="color:red;">mplayer is not installed! Please install it.</h1><br>';
|
||||
exit();
|
||||
}
|
||||
|
||||
if (count($movieDirs) == 0) {
|
||||
echo '<h1 style="color:red;">PLEASE edit the script and set at least one folder in \$movie_dirs variable </h1><br>';
|
||||
exit();
|
||||
}
|
||||
|
||||
// get all files. Result is in $moviesFS and $doubles;
|
||||
foreach ($movieDirs as $dir) {
|
||||
recurseDir($dir, $movieExts, $skipFolders);
|
||||
}
|
||||
|
||||
// Get all movies that are not on the whishlist (50) or inserted by this tool (51)
|
||||
$SELECT = 'SELECT id, filename FROM ' . TBL_DATA . ' WHERE mediatype < 50 ORDER BY filename';
|
||||
$rows = runSQL($SELECT);
|
||||
|
||||
echo '<h3>Scanning...</h3>';
|
||||
echo '<b>Total movie files found on disk:</b> ' . sizeof($moviesFS) . '<br>';
|
||||
echo '<b>Total movie files found in DB:</b> ' . count($rows) . '<br><br>';
|
||||
echo '<h3>Comparing results.</h3>';
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$filePathParts = preg_split("/\//", $row['filename']);
|
||||
$fileName = end($filePathParts);
|
||||
$id = $row['id'];
|
||||
|
||||
// The path does not match the path found in the database
|
||||
if ($moviesFS[$fileName] != $row['filename']) {
|
||||
if (! isset($moviesFS[$fileName])) {
|
||||
echo "<b>MISSING</b> - <a href='../show.php?id={$id}'>{$fileName}</a><br>";
|
||||
if ($update_missing) {
|
||||
$UPDATE = "UPDATE " . TBL_DATA . " SET mediatype='" . MEDIA_WISHLIST . "' WHERE id='{$id}'";
|
||||
runSQL($UPDATE);
|
||||
}
|
||||
} else {
|
||||
echo "<b>MOVED</b> - <a href='../show.php?id={$id}'>{$fileName}</a><br>";
|
||||
if ($update_moved) {
|
||||
$UPDATE = "UPDATE " . TBL_DATA . " SET filename='" . escapeSQL($moviesFS[$fileName]) . "' WHERE id='{$id}'";
|
||||
runSQL($UPDATE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unset($moviesFS[$fileName]);
|
||||
}
|
||||
}
|
||||
|
||||
echo '<br><b>New files found:</b> ' . sizeof($moviesFS) . '<br>';
|
||||
asort($moviesFS);
|
||||
$moviesFS = removeCDNumbers($moviesFS);
|
||||
echo '<b>New files found with no CD[2-3-4]:</b> ' . sizeof($moviesFS) . '<br>';
|
||||
|
||||
// remove all movies added last time and not updated with real information
|
||||
// mediatype 51 indicates that the movie was inserted/modified by this tool.
|
||||
$UPDATE = "DELETE FROM " . TBL_DATA . " WHERE mediatype='51'";
|
||||
runSQL($UPDATE);
|
||||
|
||||
echo '<h3>Data on movies to add.</h3>';
|
||||
echo "<table class='collapse'>
|
||||
<tr>
|
||||
<th>File Name</th>
|
||||
<th>Title</th>
|
||||
<th>File Size</th>
|
||||
<th>Audio Codec</th>
|
||||
<th>Video Codec</th>
|
||||
<th>Video Width</th>
|
||||
<th>Video Height</th>
|
||||
<th>File Date</th>
|
||||
</tr>";
|
||||
|
||||
$currentUserId = get_current_user_id();
|
||||
|
||||
foreach ($moviesFS as $movie) {
|
||||
$filePathParts = preg_split("/\//", $movie);
|
||||
$fileName = end($filePathParts);
|
||||
$title = preg_replace($cleanFileName, '', $fileName);
|
||||
$title = str_replace('_', ' ', $title);
|
||||
|
||||
$filePath = $moviesFS[end($filePathParts)];
|
||||
$fileSize = (int) getFileSize($filePath);
|
||||
$fileDate = getFileTimeLinux($filePath);
|
||||
|
||||
$metadata = getMetadata($filePath);
|
||||
$audioCodec = $metadata['audioCodec'];
|
||||
$videoCodec = $metadata['videoCodec'];
|
||||
$videoWidth = (int) $metadata['videoWidth'];
|
||||
$videoHeight = (int) $metadata['videoHeight'];
|
||||
|
||||
echo "<tr>
|
||||
<td>$filePath</td>
|
||||
<td>$title</td>
|
||||
<td>$fileSize</td>
|
||||
<td>$audioCodec</td>
|
||||
<td>$videoCodec</td>
|
||||
<td>$videoWidth</td>
|
||||
<td>$videoHeight</td>
|
||||
<td>$fileDate</td>
|
||||
</tr>";
|
||||
|
||||
$UPDATE = "INSERT " . TBL_DATA . " SET filename='" . escapeSQL($filePath) . "',
|
||||
mediatype = 51,
|
||||
title = '$title',
|
||||
filesize = $fileSize,
|
||||
audio_codec = '$audioCodec',
|
||||
video_codec = '$videoCodec',
|
||||
video_width = $videoWidth,
|
||||
video_height = $videoHeight,
|
||||
owner_id = $currentUserId,
|
||||
filedate = FROM_UNIXTIME($fileDate)";
|
||||
|
||||
runSQL($UPDATE);
|
||||
}
|
||||
echo '</table>';
|
||||
|
||||
$SELECT = "SELECT id, title FROM " . TBL_DATA . " WHERE mediatype='51' ORDER BY title";
|
||||
$rows = runSQL($SELECT);
|
||||
|
||||
echo '<br><br><h3><New movies added (click to edit):</h3>';
|
||||
foreach ($rows as $row) {
|
||||
echo "<a href='../edit.php?id={$row['id']}'>{$row['title']}</a><br>";
|
||||
}
|
||||
|
||||
?>
|
||||
<h3>All Done</h3>
|
||||
</body>
|
||||
</html>
|
||||
324
videodb/contrib/videoadd.pl
Normal file
324
videodb/contrib/videoadd.pl
Normal file
@@ -0,0 +1,324 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
##
|
||||
# Add video files from local disc
|
||||
#
|
||||
# @package videoDB
|
||||
# @author Andreas Gohr <a.gohr@web.de>
|
||||
#
|
||||
# TODO check paths for correctness
|
||||
##
|
||||
|
||||
# path to md4sum
|
||||
# Get it from http://www-tet.ee.tu-berlin.de/solyga/linux/
|
||||
#
|
||||
# If you don't want md4 sums (time consuming) set it to a
|
||||
# blank string
|
||||
$md4sum = ''; #/usr/local/bin/md4sum';
|
||||
|
||||
# If you want md4 sums: in which custom field should it be
|
||||
# stored? In VideoDB it should have 'ed2k' as type
|
||||
#$md4field = 'custom2';
|
||||
|
||||
# If you want a download link to the file: in which custom
|
||||
# field should it be stored? In VideoDB it should have
|
||||
# 'url' as type
|
||||
#$urlfield = 'custom1';
|
||||
|
||||
# path to the eject tool,
|
||||
#found this not real useful when you can rub the script to process a directory,
|
||||
#but if you going to us a cdrom you un comment it it.
|
||||
#$eject = '/usr/bin/eject';
|
||||
|
||||
# path to mplayer (only version 0.90 was tested, 1.0rc1 works too)
|
||||
$mplayer = '/usr/bin/mplayer';
|
||||
|
||||
# cdrom to use (reads it from commandline)
|
||||
$device = $ARGV[ 0 ];
|
||||
# alter "/writer" to the directory you have videos in to process.
|
||||
$device = "/writer" unless (defined($device));
|
||||
|
||||
# do the mount ?
|
||||
$do_mount = 0;
|
||||
|
||||
# remove articles
|
||||
$remove_article = 1;
|
||||
|
||||
# if you use the multiuser feature you may want to give an
|
||||
# owner of the movies to add here - if you don't need it just
|
||||
# set it to a blank string
|
||||
$owner_id = 1;
|
||||
|
||||
# allowed suffixes
|
||||
$suffix_re = 'avi|ogm|ogg|bin|mpe?g|ra?m|mov|asf|wmv|mp4|mkv';
|
||||
|
||||
# Database stuff
|
||||
$driver = "mysql";
|
||||
$database = "VideoDB";
|
||||
$prefix = ""; // enter your DB prefix like videodb. in here
|
||||
$hostname = "server";
|
||||
$user = "www";
|
||||
$password = "leech";
|
||||
|
||||
################################################################################
|
||||
use DBI;
|
||||
|
||||
#Connect to database
|
||||
$dsn = "DBI:$driver:database=$database;host=$hostname";
|
||||
$dbh = DBI->connect($dsn, $user, $password);
|
||||
|
||||
#quote this only once:
|
||||
$owner = $dbh->quote($owner);
|
||||
|
||||
if (-f $device)
|
||||
{
|
||||
$plain = $device;
|
||||
$plain =~ s#.*/([^/]+)$#\1#i;
|
||||
add($device,$plain);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
# mount
|
||||
($do_mount) && system("$eject -t $device");
|
||||
($do_mount) && system("mount $device");
|
||||
|
||||
#work
|
||||
&readfiles($device);
|
||||
|
||||
#umount
|
||||
($do_mount) && system("umount $device");
|
||||
($do_mount) && system("$eject $device");
|
||||
}
|
||||
|
||||
#disconnect
|
||||
$dbh->disconnect();
|
||||
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
sub readfiles($)
|
||||
{
|
||||
my $path = $_[ 0 ];
|
||||
|
||||
opendir(ROOT, $path);
|
||||
my @files = readdir(ROOT);
|
||||
closedir(ROOT);
|
||||
|
||||
my ($file, $ffile);
|
||||
foreach $file (@files)
|
||||
{
|
||||
$ffile = "$path/$file";
|
||||
|
||||
next if ($file =~ /^\.|\.\.$/); #skip upper dirs
|
||||
if (-d $ffile)
|
||||
{
|
||||
readfiles($ffile);
|
||||
}
|
||||
|
||||
if ($ffile =~ /\.($suffix_re)$/i)
|
||||
{
|
||||
&add($ffile, $file); #add it
|
||||
print STDERR "$ffile\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub add($$)
|
||||
{
|
||||
my $ffile = $_[ 0 ]; #full path
|
||||
my $file = $_[ 1 ]; #file only
|
||||
|
||||
# get filestatistics
|
||||
my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat($ffile);
|
||||
|
||||
# get md4
|
||||
my $md4;
|
||||
if ($md4sum ne '')
|
||||
{
|
||||
$md4 = `$md4sum "$ffile"`;
|
||||
$md4 =~ s/\s.*$//;
|
||||
}
|
||||
|
||||
# get videoinfos
|
||||
my ($audio_codec, $video_codec, $video_width, $video_height, $runtime);
|
||||
print qq($mplayer -identify -ao null -vo null -frames 0 "$ffile" 2>/dev/null);
|
||||
my @out = `$mplayer -identify -ao null -vo null -frames 0 "$ffile" 2>/dev/null` if ($mplayer);
|
||||
foreach my $line (@out)
|
||||
{
|
||||
next unless ($line =~ m/^ID_/);
|
||||
chomp($line);
|
||||
if ($line =~ m/^ID_VIDEO_FORMAT=(.*)/)
|
||||
{
|
||||
$video_codec = $1;
|
||||
$video_codec = 'MPEG1' if ($video_codec eq '0x10000001');
|
||||
$video_codec = 'MPEG2' if ($video_codec eq '0x10000002');
|
||||
$video_codec = 'MPEG4' if ($video_codec eq 'MPG4');
|
||||
#FIXME id's of other mpegs??
|
||||
$video_codec = 'DivX3' if ($video_codec eq 'DIV3');
|
||||
$video_codec = 'DivX3' if ($video_codec eq 'div3');
|
||||
$video_codec = 'DivX4' if ($video_codec eq 'DIV4');
|
||||
$video_codec = 'DivX4' if ($video_codec eq 'DIVX');
|
||||
$video_codec = 'DivX4' if ($video_codec eq 'divx');
|
||||
$video_codec = 'DivX5' if ($video_codec eq 'DX50');
|
||||
$video_codec = 'XviD' if ($video_codec eq 'XVID');
|
||||
#FIXME aliases of other codecs?
|
||||
#Add more 20/1/2015 by LinuxHam couple extra codecs to help get data needed
|
||||
$video_codec = 'H264' if ($video_codec eq 'ffh264');
|
||||
$video_codec = 'avc1' if ($video_codec eq 'ffh264');
|
||||
$video_codec = 'MP4V' if ($video_codec eq 'ffodivx');
|
||||
}
|
||||
elsif ($line =~ m/^ID_VIDEO_WIDTH=(.*)/)
|
||||
{
|
||||
$video_width = $1;
|
||||
}
|
||||
elsif ($line =~ m/^ID_VIDEO_HEIGHT=(.*)/)
|
||||
{
|
||||
$video_height = $1;
|
||||
}
|
||||
elsif ($line =~ m/^ID_AUDIO_CODEC=(.*)/)
|
||||
{
|
||||
$audio_codec = $1;
|
||||
$audio_codec = 'MP3' if ($audio_codec eq 'mad');
|
||||
$audio_codec = 'MP3' if ($audio_codec eq 'mp3');
|
||||
$audio_codec = 'AC3' if ($audio_codec eq 'a52');
|
||||
$audio_codec = 'Vorbis' if ($audio_codec eq 'ffvorbis');
|
||||
$audio_codec = 'PCM' if ($audio_codec eq 'pcm');
|
||||
$audio_codec = 'WMA2' if ($audio_codec eq 'ffwmav2');
|
||||
$audio_codec = 'WMA1' if ($audio_codec eq 'ffwmav1'); # just a guess, needs confirmation
|
||||
#Add more 20/1/2015 by LinuxHam, couple extra codecs to help get data needed
|
||||
$audio_codec = '8192' if ($audio_codec eq 'ffac3');
|
||||
$audio_codec = 'MP4A' if ($audio_codec eq 'ffaac');
|
||||
$audio_codec = '85' if ($audio_codec eq 'ffmp3float');
|
||||
}
|
||||
elsif ($line =~ m/^ID_LENGTH=(.*)/)
|
||||
{
|
||||
$runtime = $1;
|
||||
$runtime = sprintf("%d", $runtime / 60);
|
||||
}
|
||||
}
|
||||
|
||||
# get titles
|
||||
my ($lang, $title, $subtitle, $istv) = &guessnames($file);
|
||||
|
||||
# prepare for inserts
|
||||
$file = $dbh->quote($file);
|
||||
$size = $dbh->quote($size);
|
||||
$audio_codec = $dbh->quote($audio_codec);
|
||||
$video_codec = $dbh->quote($video_codec);
|
||||
$video_width = $dbh->quote($video_width);
|
||||
$video_height = $dbh->quote($video_height);
|
||||
$runtime = $dbh->quote($runtime);
|
||||
$lang = $dbh->quote($lang);
|
||||
$title = $dbh->quote($title);
|
||||
$subtitle = $dbh->quote($subtitle);
|
||||
$md4 = $dbh->quote($md4);
|
||||
$ffile = $dbh->quote($ffile);
|
||||
|
||||
# insert
|
||||
$INSERT = "INSERT INTO ".$prefix."videodata
|
||||
SET filename = $file,
|
||||
filesize = $size,
|
||||
audio_codec = $audio_codec,
|
||||
video_codec = $video_codec,
|
||||
video_width = $video_width,
|
||||
video_height = $video_height,
|
||||
language = $lang,
|
||||
title = $title,
|
||||
subtitle = $subtitle,
|
||||
runtime = $runtime,
|
||||
mediatype = 4,
|
||||
istv = $istv,
|
||||
filedate = FROM_UNIXTIME($mtime),
|
||||
created = NOW(),
|
||||
owner_id = $owner_id";
|
||||
if ($md4sum ne '')
|
||||
{
|
||||
$INSERT .= ", $md4field = $md4";
|
||||
}
|
||||
|
||||
if ($urlfield ne '')
|
||||
{
|
||||
$INSERT .= ", $urlfield = $ffile";
|
||||
}
|
||||
$dbh->do($INSERT);
|
||||
|
||||
#print "$file \n$title - $subtitle\n\n";
|
||||
}
|
||||
|
||||
sub guessnames($)
|
||||
{
|
||||
my $episode = "";
|
||||
my $istv = 0;
|
||||
|
||||
my $file = $_[ 0 ]; #file only
|
||||
|
||||
# try to get language
|
||||
# backdrafts: es matches german word, de probably some french stuff
|
||||
my $lang = "";
|
||||
$lang = "german" if ($file =~ m/\b(german|deutsch|ger|de)\b/i);
|
||||
$lang = "english" if ($file =~ m/\b(english|eng|en)\b/i);
|
||||
$lang = "french" if ($file =~ m/\b(french|français|fra|fr)\b/i);
|
||||
$lang = "spanish" if ($file =~ m/\b(spanish|español|es)\b/i);
|
||||
|
||||
# remove add. info
|
||||
$file =~ s/\(.*\)//;
|
||||
|
||||
#remove common trash and suffixes
|
||||
$file =~ s/(\[[^\]]\]|bin|cd\d|dvd\d|divx|xvid|[ms]?vcd|dvdscr|dvdrip|shareconnector|eselfilme)//gi;
|
||||
$file =~ s/\.($suffix_re)$//gi;
|
||||
|
||||
# get episode Number
|
||||
if ($file =~ s/(s\d+e\d+)/-/i)
|
||||
{
|
||||
$episode = $1;
|
||||
}
|
||||
elsif ($file =~ s/(\d+x\d+)/-/i)
|
||||
{
|
||||
$episode = $1;
|
||||
}
|
||||
|
||||
# change dots to underscores
|
||||
$file =~ s/\./_/g;
|
||||
|
||||
# change underscores to spaces
|
||||
$file =~ s/_/ /g;
|
||||
|
||||
# split title and subtitle and cleanup
|
||||
my @parts = split ("-", $file, 2);
|
||||
my $title = $parts[ 0 ];
|
||||
my $subtitle = $parts[ 1 ];
|
||||
$title =~ s/^[\s-]*//g;
|
||||
$title =~ s/[\s-]*$//g;
|
||||
$subtitle =~ s/^[\s-]*//g;
|
||||
$subtitle =~ s/[\s-]*$//g;
|
||||
|
||||
if ($episode)
|
||||
{
|
||||
$subtitle = "[$episode] $subtitle";
|
||||
$istv = 1;
|
||||
}
|
||||
|
||||
if ($remove_article)
|
||||
{
|
||||
unless ($title =~ s/^(for the)\b(.*)$/$2, $1/i)
|
||||
{
|
||||
unless ($title =~ s/^(for a)\b(.*)$/$2, $1/i)
|
||||
{
|
||||
unless ($title =~ s/^(for)\b(.*)$/$2, $1/i)
|
||||
{
|
||||
unless ($title =~ s/^(the)\b(.*)$/$2, $1/i)
|
||||
{
|
||||
unless ($title =~ s/^(a)\b(.*)$/$2, $1/i)
|
||||
{
|
||||
($title =~ s/^(der|die|das)\b(.*)$/$2, $1/i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chomp ($title);
|
||||
|
||||
return ($lang, $title, $subtitle, $istv);
|
||||
}
|
||||
56
videodb/core/VariableStream.class.php
Normal file
56
videodb/core/VariableStream.class.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* VariableStream class
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: VariableStream.class.php,v 1.4 2004/10/30 11:48:36 andig2 Exp $
|
||||
*/
|
||||
|
||||
// stream wrappers require php > 4.3
|
||||
if (version_compare(phpversion(), '4.3') < 0)
|
||||
{
|
||||
errorpage('PHP version mismatch',
|
||||
'At least PHP version 4.3.0 is required to run the VariableStream, please check the documentation!');
|
||||
}
|
||||
|
||||
/**
|
||||
* VariableStream allows XML reading from variables
|
||||
* @package Core
|
||||
*/
|
||||
class VariableStream
|
||||
{
|
||||
var $position;
|
||||
var $varname;
|
||||
var $context;
|
||||
|
||||
function stream_open($path, $mode, $options, &$opened_path) {
|
||||
$url = parse_url($path);
|
||||
$this->varname = $url['host'];
|
||||
$this->position = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
function stream_read($count) {
|
||||
$ret = substr($GLOBALS[$this->varname], $this->position, $count);
|
||||
$this->position += strlen($ret);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function stream_eof() {
|
||||
return $this->position >= strlen($GLOBALS[$this->varname]);
|
||||
}
|
||||
|
||||
function stream_stat() {
|
||||
return array('size' => strlen($GLOBALS[$this->varname]));
|
||||
}
|
||||
|
||||
function url_stat() {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
// register stream type to allow use in xml->load
|
||||
stream_wrapper_register('var', 'VariableStream');
|
||||
|
||||
?>
|
||||
196
videodb/core/cache.php
Normal file
196
videodb/core/cache.php
Normal file
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
/**
|
||||
* File caching functions
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: cache.php,v 1.11 2013/04/26 15:09:35 andig2 Exp $
|
||||
*/
|
||||
|
||||
// define cache folder
|
||||
if (!defined('CACHE')) define('CACHE', 'cache');
|
||||
|
||||
/**
|
||||
* Get the hashed filename
|
||||
*
|
||||
* @param string url of the item
|
||||
* @param string $cache_folder name ob the sub-cache to adress
|
||||
* @param string ext file extension of the cache file
|
||||
*/
|
||||
function cache_get_filename($url, $cache_folder, $ext = '')
|
||||
{
|
||||
$hash = md5($url) . (($ext) ? '.'.$ext : '');
|
||||
$cache_file = cache_get_folder($cache_folder, $hash) . $hash;
|
||||
|
||||
return $cache_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of the cache folder
|
||||
*
|
||||
* @TODO decouple from global config options
|
||||
*
|
||||
* @param string $cache_folder name ob the sub-cache to adress
|
||||
* @param string $cache_filename name of the item to be cached for use with hierarchical caches
|
||||
* @return string cache folder path including trailing /
|
||||
*/
|
||||
function cache_get_folder($cache_folder, $cache_filename = '')
|
||||
{
|
||||
global $config;
|
||||
|
||||
$cache_folder = CACHE.'/' .
|
||||
(($cache_folder) ? $cache_folder.'/' : '');
|
||||
|
||||
if ($cache_filename)
|
||||
$cache_folder .= substr($cache_filename, 0, @(int)$config['hierarchical']).'/';
|
||||
|
||||
return $cache_folder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup a single cache folder
|
||||
*
|
||||
* @param string $cache_folder path to cache folder
|
||||
* @param int $cache_max_age maximum age of cached items in seconds
|
||||
* @param bool $force_prune force cache pruning even if not due according to schedule
|
||||
*/
|
||||
function cache_prune_folder($cache_folder, $cache_max_age, $force_prune = false, $simulate = false, $pattern = '*')
|
||||
{
|
||||
if (!preg_match('#/$#', $cache_folder)) $cache_folder .= '/';
|
||||
$stamp = $cache_folder.'cache_last_purge';
|
||||
$cache_mtime = @filemtime($stamp); // get time the cache was last purged (once a day)
|
||||
|
||||
// if cache was last purged a day or more ago
|
||||
if ($force_prune || ((time() - $cache_mtime) > ($cache_max_age / 24))) # 86400)
|
||||
{
|
||||
foreach (glob($cache_folder.$pattern, GLOB_NOSORT) as $file)
|
||||
{
|
||||
// avoid hidden files and directories
|
||||
if (is_file($file) &! preg_match("/^\./", $file) && time() - filemtime($file) > $cache_max_age)
|
||||
{
|
||||
if ($simulate)
|
||||
$files[] = $file; // add to list of potentially purged files
|
||||
else
|
||||
@unlink($file); // purge cache
|
||||
}
|
||||
}
|
||||
|
||||
if ($simulate) return $files;
|
||||
|
||||
@touch($stamp); // mark purge as having occurred
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup a cache folder hierarchy
|
||||
*
|
||||
* @TODO decouple from global config options
|
||||
*
|
||||
* @param string $cache_folder path to cache folder
|
||||
* @param int $cache_max_age maximum age of cached items in seconds
|
||||
* @param bool $force_prune force cache pruning even if not due according to schedule
|
||||
*/
|
||||
function cache_prune_folders($cache_folder, $cache_max_age, $force_prune = false, $simulate = false, $pattern = '*', $levels = 0)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// root folder
|
||||
cache_prune_folder($cache_folder, $cache_max_age, $force_prune, $simulate, $pattern, $levels);
|
||||
|
||||
// descent hierarchy
|
||||
if ($levels > 0)
|
||||
{
|
||||
if (!isset($error))
|
||||
{
|
||||
$error = '';
|
||||
}
|
||||
for ($i=0; $i<16; $i++)
|
||||
$error .= cache_prune_folders($cache_folder.dechex($i).'/', $cache_max_age, $force_prune, $simulate, $pattern, $levels-1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create cache folders
|
||||
*
|
||||
* Check individual cache folder for existance, check if folder is writable and create folder if it doesn't exist
|
||||
*/
|
||||
function cache_create_folders($dir, $levels = 0)
|
||||
{
|
||||
$error = '';
|
||||
if (!is_dir($dir))
|
||||
{
|
||||
if (!@mkdir($dir, 0700)) $error = 'Directory <code>'.$dir.'</code> does not exist.<br/>';
|
||||
}
|
||||
elseif (!is_writable($dir))
|
||||
{
|
||||
$error = 'Directory <code>'.$dir.'</code> is not writable.<br/>';
|
||||
}
|
||||
|
||||
// check hierarchical folders
|
||||
if (empty($error) && ($levels > 0))
|
||||
{
|
||||
for ($i=0; $i<16; $i++)
|
||||
$error .= cache_create_folders($dir.'/'.dechex($i), $levels-1);
|
||||
}
|
||||
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify existance of cached file for given url/ extension
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string url of the item
|
||||
* @param string ext file extension of the cache file
|
||||
* @param string file result: URL to the cached image if exists
|
||||
* @return bool result of check
|
||||
*/
|
||||
function cache_file_exists($url, &$cache_file, $cache_folder, $ext = '')
|
||||
{
|
||||
$cache_file = cache_get_filename($url, $cache_folder, $ext);
|
||||
// Small performance fix
|
||||
$result = file_exists($cache_file) && filesize($cache_file);
|
||||
# $result = filesize($cache_file) > 0;
|
||||
|
||||
return($result);
|
||||
}
|
||||
|
||||
function cache_get($url, $cache_folder, $cache_max_age, $serialize = false)
|
||||
{
|
||||
$data = false;
|
||||
|
||||
if ($cache_max_age > 0)
|
||||
{
|
||||
if (cache_file_exists($url, $cache_file, $cache_folder))
|
||||
{
|
||||
if (time() - filemtime($cache_file) < $cache_max_age)
|
||||
{
|
||||
$data = file_get_contents($cache_file);
|
||||
if (($data !== false) && $serialize) $data = unserialize($data);
|
||||
}
|
||||
// TODO Check if outdated cache files should really be auto-deleted
|
||||
else @unlink($cache_file);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
function cache_put($url, $data, $cache_folder, $cache_max_age, $serialize = false)
|
||||
{
|
||||
// only put file to cache if caching is enabled
|
||||
if ($cache_max_age > 0)
|
||||
{
|
||||
// get the cache file name
|
||||
$cache_file = cache_get_filename($url, $cache_folder);
|
||||
|
||||
// commit to disk
|
||||
if ($serialize) $data = serialize($data);
|
||||
file_put_contents($cache_file, $data);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
312
videodb/core/compatibility.php
Normal file
312
videodb/core/compatibility.php
Normal file
@@ -0,0 +1,312 @@
|
||||
<?php
|
||||
/**
|
||||
* Compatibility functions
|
||||
*
|
||||
* Borrowed simplified functions from PEAR module PHP_Compat
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @link http://pear.php.net PEAR
|
||||
* @version $Id: compatibility.php,v 1.15 2013/03/13 16:38:19 andig2 Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements file_get_contents introduced in v4.3.0
|
||||
*/
|
||||
if (!function_exists('file_get_contents'))
|
||||
{
|
||||
function file_get_contents($filename)
|
||||
{
|
||||
$fh = @fopen($filename, 'rb');
|
||||
if (!$fh) return false;
|
||||
$content = fread($fh, filesize($filename));
|
||||
fclose($fh);
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements file_put_contents introduced in v5.0.0
|
||||
*/
|
||||
if (!function_exists('file_put_contents'))
|
||||
{
|
||||
function file_put_contents($filename, $content)
|
||||
{
|
||||
$fh = @fopen($filename, 'wb');
|
||||
if (!$fh) return false;
|
||||
if (!fwrite($fh, $content, strlen($content))) return false;
|
||||
fclose($fh);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements html_entity_decode introduced in v4.3.0
|
||||
* @author <martin@swertcw.com>
|
||||
* @param string $string HTML encoded string
|
||||
* @return string HTML decoded string
|
||||
*/
|
||||
if (!function_exists('html_entity_decode'))
|
||||
{
|
||||
function html_entity_decode($string)
|
||||
{
|
||||
// replace numeric entities
|
||||
$string = preg_replace('~&#x([0-9a-f]+);~ei', 'chr(hexdec("\\1"))', $string);
|
||||
$string = preg_replace('~&#([0-9]+);~e', 'chr(\\1)', $string);
|
||||
// replace literal entities
|
||||
$trans_tbl = get_html_translation_table(HTML_ENTITIES);
|
||||
$trans_tbl = array_flip($trans_tbl);
|
||||
return strtr($string, $trans_tbl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements http_build_query introduced in v5.0.0
|
||||
*/
|
||||
if (!function_exists('http_build_query'))
|
||||
{
|
||||
function http_build_query ($formdata, $numeric_prefix = null)
|
||||
{
|
||||
// Check we have an array to work with
|
||||
if (!is_array($formdata)) {
|
||||
return $formdata;
|
||||
}
|
||||
|
||||
// Start building the query
|
||||
$tmp = array ();
|
||||
foreach ($formdata as $key => $val)
|
||||
{
|
||||
array_push($tmp, urlencode($key).'='.urlencode($val));
|
||||
}
|
||||
|
||||
return implode('&', $tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Multibyte-aware character case conversion
|
||||
*
|
||||
* @author tedemo <tedemo@free.fr>
|
||||
*/
|
||||
if (!function_exists('mb_convert_case'))
|
||||
{
|
||||
function mb_convert_case($str)
|
||||
{
|
||||
return ucwords(strtolower($str));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* iconv alternatives
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
if (!function_exists('iconv'))
|
||||
{
|
||||
function iconv($source_encoding, $target_encoding, $str)
|
||||
{
|
||||
// remove transliteration- only available in native iconv
|
||||
$source_encoding = preg_replace('#^(.+?)(//.*)#', '\\1', $source_encoding);
|
||||
$target_encoding = preg_replace('#^(.+?)(//.*)#', '\\1', $target_encoding);
|
||||
|
||||
if (function_exists('mb_convert_encoding'))
|
||||
return mb_convert_encoding($str, $target_encoding, $source_encoding);
|
||||
elseif (function_exists('recode_string'))
|
||||
return recode_string($source_encoding.'..'.$target_encoding, $str);
|
||||
else
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements json_encode introduced in v5.2.0
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
if (!function_exists('json_encode'))
|
||||
{
|
||||
function json_encode($data)
|
||||
{
|
||||
require_once('./lib/json.php');
|
||||
$json = new Services_JSON();
|
||||
return($json->encode($data));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements json_decode introduced in v5.2.0
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
if (!function_exists('json_decode'))
|
||||
{
|
||||
function json_decode($data)
|
||||
{
|
||||
require_once('./lib/json.php');
|
||||
$json = new Services_JSON();
|
||||
return($json->decode($data));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements json_decode introduced in v5.0.0
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
if (!function_exists('http_build_query'))
|
||||
{
|
||||
function http_build_query($formdata, $numeric_prefix = null, $key = null)
|
||||
{
|
||||
$res = array();
|
||||
foreach ((array)$formdata as $k=>$v)
|
||||
{
|
||||
$tmp_key = urlencode(is_int($k) ? $numeric_prefix.$k : $k);
|
||||
if ($key) $tmp_key = $key.'['.$tmp_key.']';
|
||||
|
||||
if ( is_array($v) || is_object($v) ) {
|
||||
$res[] = http_build_query($v, null /* or $numeric_prefix if you want to add numeric_prefix to all indexes in array*/, $tmp_key);
|
||||
} else {
|
||||
$res[] = $tmp_key."=".urlencode($v);
|
||||
}
|
||||
}
|
||||
$separator = ini_get('arg_separator.output');
|
||||
return implode($separator, $res);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick image type detection
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
if (!function_exists('exif_imagetype'))
|
||||
{
|
||||
function exif_imagetype($filename)
|
||||
{
|
||||
if ((list($width, $height, $type, $attr) = getimagesize($filename )) !== false ) {
|
||||
return $type;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ease PHP 5.3.0 requirement on Windows
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
if (!function_exists('linkinfo'))
|
||||
{
|
||||
function linkinfo($path)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Polyfill for PHP 4 - PHP 7
|
||||
* introduced in PHP 8
|
||||
*/
|
||||
if (!function_exists('str_contains'))
|
||||
{
|
||||
function str_contains(string $haystack, string $needle): bool
|
||||
{
|
||||
return strpos($haystack, $needle) !== false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This file is part of the array_column library
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* @copyright Copyright (c) 2013 Ben Ramsey <http://benramsey.com>
|
||||
* @license http://opensource.org/licenses/MIT MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the values from a single column of the input array, identified by
|
||||
* the $columnKey.
|
||||
*
|
||||
* Optionally, you may provide an $indexKey to index the values in the returned
|
||||
* array by the values from the $indexKey column in the input array.
|
||||
*
|
||||
* @param array $input A multi-dimensional array (record set) from which to pull
|
||||
* a column of values.
|
||||
* @param mixed $columnKey The column of values to return. This value may be the
|
||||
* integer key of the column you wish to retrieve, or it
|
||||
* may be the string key name for an associative array.
|
||||
* @param mixed $indexKey (Optional.) The column to use as the index/keys for
|
||||
* the returned array. This value may be the integer key
|
||||
* of the column, or it may be the string key name.
|
||||
* @return array
|
||||
*/
|
||||
if (!function_exists('array_column'))
|
||||
{
|
||||
function array_column($input = null, $columnKey = null, $indexKey = null)
|
||||
{
|
||||
// Using func_get_args() in order to check for proper number of
|
||||
// parameters and trigger errors exactly as the built-in array_column()
|
||||
// does in PHP 5.5.
|
||||
$params = func_get_args();
|
||||
if (!isset($params[0])) {
|
||||
trigger_error('array_column() expects at least 2 parameters, 0 given', E_USER_WARNING);
|
||||
return null;
|
||||
} elseif (!isset($params[1])) {
|
||||
trigger_error('array_column() expects at least 2 parameters, 1 given', E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
if (!is_array($params[0])) {
|
||||
trigger_error('array_column() expects parameter 1 to be array, ' . gettype($params[0]) . ' given', E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
if (!is_int($params[1])
|
||||
&& !is_string($params[1])
|
||||
&& !(is_object($params[1]) && method_exists($params[1], '__toString'))
|
||||
) {
|
||||
trigger_error('array_column(): The column key should be either a string or an integer', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
if (isset($params[2])
|
||||
&& !is_int($params[2])
|
||||
&& !is_string($params[2])
|
||||
&& !(is_object($params[2]) && method_exists($params[2], '__toString'))
|
||||
) {
|
||||
trigger_error('array_column(): The index key should be either a string or an integer', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
$paramsInput = $params[0];
|
||||
$paramsColumnKey = (string) $params[1];
|
||||
$paramsIndexKey = (isset($params[2]) ? (string) $params[2] : null);
|
||||
$resultArray = array();
|
||||
foreach ($paramsInput as $row) {
|
||||
$key = $value = null;
|
||||
$keySet = $valueSet = false;
|
||||
if ($paramsIndexKey !== null && array_key_exists($paramsIndexKey, $row)) {
|
||||
$keySet = true;
|
||||
$key = $row[$paramsIndexKey];
|
||||
}
|
||||
if (is_array($row) && array_key_exists($paramsColumnKey, $row)) {
|
||||
$valueSet = true;
|
||||
$value = $row[$paramsColumnKey];
|
||||
}
|
||||
if ($valueSet) {
|
||||
if ($keySet) {
|
||||
$resultArray[$key] = $value;
|
||||
} else {
|
||||
$resultArray[] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $resultArray;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
76
videodb/core/constants.php
Normal file
76
videodb/core/constants.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* Constants
|
||||
*
|
||||
* Contains global constants for table names
|
||||
* Must only be loaded after config.inc.php
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: constants.php,v 1.65 2013/04/25 15:00:32 andig2 Exp $
|
||||
*/
|
||||
|
||||
// Config file
|
||||
define('CONFIG_FILE', './config.inc.php');
|
||||
define('VERSION', '4.1.0');
|
||||
|
||||
define('LOG_FILE', 'debug.log');
|
||||
|
||||
// User Permission bit masks
|
||||
define('PERM_ADMIN', 1);
|
||||
define('PERM_READ', 2);
|
||||
define('PERM_WRITE', 4);
|
||||
define('PERM_ADULT', 8);
|
||||
define('PERM_ALL', -1); // used to check for "all" permissions only
|
||||
define('PERM_ANY', -2); // used to check for exististance of any cross-user permission
|
||||
|
||||
// Cache folders
|
||||
define('CACHE_IMG', 'img');
|
||||
define('CACHE_HTML', 'imdb');
|
||||
define('CACHE_THUMBS', 'thumbs');
|
||||
define('CACHE_LOCAL', 'local'); // local images for covers and actors
|
||||
|
||||
// Table names
|
||||
define('TBL_DATA', $config['db_prefix'].'videodata');
|
||||
|
||||
define('TBL_CONFIG', $config['db_prefix'].'config');
|
||||
define('TBL_USERCONFIG', $config['db_prefix'].'userconfig');
|
||||
|
||||
define('TBL_USERS', $config['db_prefix'].'users');
|
||||
define('TBL_USERSEEN', $config['db_prefix'].'userseen');
|
||||
define('TBL_PERMISSIONS', $config['db_prefix'].'permissions');
|
||||
|
||||
define('TBL_ACTORS', $config['db_prefix'].'actors');
|
||||
define('TBL_GENRES', $config['db_prefix'].'genres');
|
||||
|
||||
define('TBL_VIDEOGENRE', $config['db_prefix'].'videogenre');
|
||||
define('TBL_MEDIATYPES', $config['db_prefix'].'mediatypes');
|
||||
|
||||
define('TBL_LENT', $config['db_prefix'].'lent');
|
||||
|
||||
define('TBL_CACHE', $config['db_prefix'].'cache');
|
||||
|
||||
// Wishlist
|
||||
define('MEDIA_WISHLIST', 50);
|
||||
|
||||
// Amazon associates token
|
||||
define('AMAZON_ASSOCIATE', 'cpuidle-20');
|
||||
|
||||
// Database character set - only valid values are UTF8, LATIN1 (legacy only) or empty
|
||||
define('DB_CHARSET', 'UTF8');
|
||||
// Database sort order - if empty sorting is defined by language file or db standard.
|
||||
// use UTF8_GENERAL_CI or other valid MySQL collation to override
|
||||
define('DB_COLLATION', '');
|
||||
|
||||
// Required database version
|
||||
define('DB_REQUIRED', 41);
|
||||
|
||||
/**
|
||||
* These used to be defined inside config.sample and therefore config.inc
|
||||
* Removed the need for them inside config.* but since their definition can still
|
||||
* be inside config.inc prefixed here with a check
|
||||
*/
|
||||
if (!defined('TUMB_NO_SCALE')) define('TUMB_NO_SCALE', -1); // no scaling - use of thumbnails is disabled
|
||||
if (!defined('TUMB_REDUCE_ONLY')) define('TUMB_REDUCE_ONLY', 0); // reduce only - create thumbnails when requested image dimensions are smaller than original image
|
||||
if (!defined('TUMB_SCALE')) define('TUMB_SCALE', 1); // always scale - create thumbnails for all images (applies aliasing when scaling)
|
||||
|
||||
492
videodb/core/custom.php
Normal file
492
videodb/core/custom.php
Normal file
@@ -0,0 +1,492 @@
|
||||
<?php
|
||||
/**
|
||||
* Custom handlers
|
||||
*
|
||||
* Defines functions for displaying custom fields.
|
||||
* To add your own type define input and output functions for it here. These
|
||||
* functions will be called in show.php (output) and edit.php (input). You can
|
||||
* get other values from these files by global'ing them into your function. See
|
||||
* ed2k as an example.
|
||||
*
|
||||
* @todo Check if this can be moved to Smarty plugins
|
||||
*
|
||||
* @package Custom
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @version $Id: custom.php,v 1.16 2008/10/03 14:18:04 andig2 Exp $
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Hint:
|
||||
|
||||
$cn
|
||||
holds the name of the custom field (eg. 'custom2') use this as the name for
|
||||
the input formfield
|
||||
|
||||
$cv
|
||||
holds the current value of that field if any. When you want to use it as
|
||||
value in a formfield quote it with the formvar() function!
|
||||
|
||||
When you add new types send them to me. I will include them here.
|
||||
*/
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* This array contains all available types - be sure to add your type if
|
||||
you ad a new one */
|
||||
$allcustomtypes=array('',
|
||||
'text',
|
||||
'url',
|
||||
'ed2k',
|
||||
'language',
|
||||
'orgtitle',
|
||||
'movix',
|
||||
'mpaa',
|
||||
'bbfc',
|
||||
'fsk',
|
||||
'barcode',
|
||||
'kijkwijzer'
|
||||
);
|
||||
|
||||
/**
|
||||
* Assigns custom field names and values to input object
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param hashref $video Reference to video hash structure
|
||||
* @param string $inout Either in or out, determines type of control
|
||||
* returned (html input control or rendered output)
|
||||
*/
|
||||
function customfields(&$video, $inout)
|
||||
{
|
||||
global $config;
|
||||
|
||||
$inout_function = ($inout == 'in') ? '_input' : '_output';
|
||||
for ($i=1; $i < 5; $i++)
|
||||
{
|
||||
if (!empty($config['custom'.$i]))
|
||||
{
|
||||
$video['custom'.$i.'name'] = $config['custom'.$i];
|
||||
$run = 'custom_'.$config['custom'.$i.'type'].$inout_function;
|
||||
$custom_value = null;
|
||||
if (array_key_exists('custom'.$i, $video))
|
||||
{
|
||||
$custom_value = $video['custom'.$i];
|
||||
}
|
||||
$video['custom'.$i.$inout] = $run('custom'.$i,$custom_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type:
|
||||
*
|
||||
* Standardinputhandler for custom fields -> just calls text type
|
||||
*/
|
||||
function custom__input($cn,$cv)
|
||||
{
|
||||
return custom_text_input($cn,$cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type:
|
||||
*
|
||||
* Standardoutputhandler for custom fields -> just calls text type
|
||||
*/
|
||||
function custom__output($cn,$cv)
|
||||
{
|
||||
return custom_text_output($cn,$cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: text
|
||||
*
|
||||
* Standardinputhandler for custom fields
|
||||
*/
|
||||
function custom_text_input($cn,$cv)
|
||||
{
|
||||
return '<input type="text" size="45" maxlength="255" name="'.$cn.'" id="'.$cn.'" value="'.formvar($cv).'" />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: text
|
||||
*
|
||||
* Standardouputhandler for custom fields
|
||||
*/
|
||||
function custom_text_output($cn,$cv)
|
||||
{
|
||||
return $cv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: url
|
||||
*
|
||||
* Stores an URL in a custom file and shows a clickable link.
|
||||
*/
|
||||
function custom_url_input($cn,$cv)
|
||||
{
|
||||
return '<input type="text" size="45" maxlength="255" name="'.$cn.'" id="'.$cn.'" value="'.formvar($cv).'" />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: url
|
||||
*
|
||||
* Stores an URL in a custom file and shows a clickable link.
|
||||
*/
|
||||
function custom_url_output($cn,$cv)
|
||||
{
|
||||
if (!empty($cv))
|
||||
{
|
||||
return '<a href="'.$cv.'">[ Link ]</a>';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: ed2k
|
||||
*
|
||||
* Stores the MD4 sum of the File in a custom file and shows a clickable ed2k
|
||||
* Link for the eDonkey2000 client tools.
|
||||
*/
|
||||
function custom_ed2k_input($cn,$cv)
|
||||
{
|
||||
return '<input type="text" size="40" maxlength="255" name="'.$cn.'" id="'.$cn.'" value="'.formvar($cv).'" /> (MD4)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: ed2k
|
||||
*
|
||||
* Stores the MD4 sum of the File in a custom file and shows a clickable ed2k
|
||||
* Link for the eDonkey2000 client tools.
|
||||
*/
|
||||
function custom_ed2k_output($cn,$cv)
|
||||
{
|
||||
global $video;
|
||||
|
||||
if (!empty($video[0]['filesize']) && !empty($video[0]['filename']) && !empty($cv)) {
|
||||
return '<a href="ed2k://|file|'.$video[0]['filename'].'|'.$video[0]['filesize'].'|'.$cv.'|">[ Add to eDonkey ]</a>';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: language
|
||||
*
|
||||
* Language Selection with Quickselectionbuttons configured in
|
||||
* $config['languages']
|
||||
*/
|
||||
function custom_language_input($cn,$cv)
|
||||
{
|
||||
global $config;
|
||||
|
||||
$output = '';
|
||||
$output .= '<input type="text" size="15" maxlength="255" name="'.$cn.'" id="'.$cn.'" value="'.formvar($cv).'" /> ';
|
||||
foreach ($config['languages'] as $flag)
|
||||
{
|
||||
$output .= '<a href="#" title="set to '.$flag.'" onclick="document.edi.'.$cn.'.value=\''.$flag.'\'">';
|
||||
$output .= '<img src="'.img('flags/'.$flag.'.gif').'" border="0" alt="'.formvar($cv).'" /></a> ';
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: language
|
||||
*
|
||||
* Language Selection with Quickselectionbuttons configured in
|
||||
* $config[languages]
|
||||
*/
|
||||
function custom_language_output($cn,$cv)
|
||||
{
|
||||
return custom_text_output($cn,$cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: FSK
|
||||
*
|
||||
* Allows you to set the FSK Rating of a movie.
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
*/
|
||||
function custom_fsk_input($cn,$cv)
|
||||
{
|
||||
return custom_text_input($cn,$cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: FSK
|
||||
*
|
||||
* Allows you to display the FSK Rating.
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
*/
|
||||
function custom_fsk_output($cn,$cv)
|
||||
{
|
||||
$allfsktypes = array('0','6','12','16','18');
|
||||
if (!in_array ($cv, $allfsktypes))
|
||||
{
|
||||
return custom_text_output($cn,$cv);
|
||||
}
|
||||
|
||||
return '<a href="search.php?q='.$cv.'&fields='.$cn.'"><img border="0" src="'.img('r_'.$cv.'.gif').'" width="50" height="50" /></a>';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Custom Type: Barcode
|
||||
*
|
||||
* Allows you to input the Barcode of a movie.
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
*/
|
||||
function custom_barcode_input($cn,$cv)
|
||||
{
|
||||
return custom_text_input($cn,$cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: Barcode
|
||||
*
|
||||
* Allows you to display Barcode.
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
*/
|
||||
function custom_barcode_output($cn,$cv)
|
||||
{
|
||||
return custom_text_output($cn,$cv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Custom Type: Originaltitle
|
||||
*
|
||||
* Holds the Original title of an movie
|
||||
*
|
||||
* @author Stephan Zalewski <stephan-01@gmx.de>
|
||||
*/
|
||||
function custom_orgtitle_input($cn,$cv)
|
||||
{
|
||||
global $config;
|
||||
global $imdbdata;
|
||||
global $id;
|
||||
|
||||
if (empty($cv)|| $config['lookupdefault_edit'] > 0 || $config['lookupdefault_new'] > 0)
|
||||
{
|
||||
if (!empty($imdbdata['title'])) {$cv .= ' - '.$imdbdata['title'];}
|
||||
if (!empty($imdbdata['subtitle'])) {$cv .= ' - '.$imdbdata['subtitle'];}
|
||||
|
||||
// we need to save our self here!
|
||||
if (!empty($id) && $cv != '')
|
||||
{
|
||||
$qcv = escapeSQL($cv);
|
||||
$UPDATE = "UPDATE ".TBL_DATA." SET $cn = '$qcv' WHERE id = $id";
|
||||
runSQL($UPDATE);
|
||||
}
|
||||
}
|
||||
return custom_text_input($cn,$cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: Originaltitle
|
||||
*
|
||||
* Holds the Original title of an movie
|
||||
*
|
||||
* @author Stephan Zalewski <stephan-01@gmx.de>
|
||||
*/
|
||||
function custom_orgtitle_output($cn,$cv)
|
||||
{
|
||||
return custom_text_output($cn,$cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: Movix
|
||||
*
|
||||
* Allows you to indicate if a movie is stored in a cd/dvd
|
||||
* with movix (http://movix.sourceforge.net/)
|
||||
*
|
||||
* @author Antonio Giungato <antonio_giungato@libero.it>
|
||||
*/
|
||||
|
||||
function custom_movix_input($cn,$cv)
|
||||
{
|
||||
$output ='<select name="'.$cn.'">
|
||||
<option selected value=""></option>
|
||||
<option value="eMovix">eMovix</option>
|
||||
<option value="Movix">Movix</option>
|
||||
<option value="Movix²">Movix²</option>
|
||||
</select>';
|
||||
return $output;
|
||||
}
|
||||
|
||||
function custom_movix_output($cn,$cv)
|
||||
{
|
||||
return custom_text_output($cn,$cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: MPAA
|
||||
*
|
||||
* Show the MPAA rating of a movie
|
||||
*
|
||||
* @author Tim M. Sanders <tsanders@thesanders.org>
|
||||
*/
|
||||
function custom_mpaa_input($cn,$cv)
|
||||
{
|
||||
global $config;
|
||||
global $imdbdata;
|
||||
global $id;
|
||||
|
||||
if (empty($cv)|| $config['lookupdefault_edit'] > 0 || $config['lookupdefault_new'] > 0)
|
||||
{
|
||||
if (!empty($imdbdata['mpaa'])) {$cv .= $imdbdata['mpaa'];}
|
||||
|
||||
//we need to save our self here!
|
||||
if(!empty($id) && $cv != '')
|
||||
{
|
||||
$qcv = escapeSQL($cv);
|
||||
$UPDATE = "UPDATE ".TBL_DATA." SET $cn = '$qcv' WHERE id = $id";
|
||||
runSQL($UPDATE);
|
||||
}
|
||||
}
|
||||
$output = '<input type="text" size="50" maxlength="255" name="'.$cn.'" id="'.$cn.'" value="'.formvar($cv).'" /> ';
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: MPAA
|
||||
*
|
||||
* Show the MPAA rating of a movie
|
||||
*
|
||||
* @author Tim M. Sanders <tsanders@thesanders.org>
|
||||
*/
|
||||
function custom_mpaa_output($cn,$cv)
|
||||
{
|
||||
global $imdbdata;
|
||||
global $id;
|
||||
|
||||
$ratings = array('R' => 'mpaa-R.gif',
|
||||
'NC-17' => 'mpaa-NC-17.gif',
|
||||
'PG-13' => 'mpaa-PG-13.gif',
|
||||
'PG' => 'mpaa-PG.gif',
|
||||
'G' => 'mpaa-G.gif');
|
||||
|
||||
$output = custom_text_output($cn,$cv);
|
||||
foreach ($ratings as $rating => $image)
|
||||
{
|
||||
if (strstr($output, $rating))
|
||||
{
|
||||
$output .= '<br/><img src="'.img($image).'" alt="'.$rating.'"/>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: BBFC
|
||||
*
|
||||
* Show the BBFC rating of a movie
|
||||
* Based on the MPAA ratings above
|
||||
*
|
||||
* @author Colin Ogilvie <csogilvie@users.sourceforge.net>
|
||||
*/
|
||||
function custom_bbfc_input($cn,$cv)
|
||||
{
|
||||
global $config;
|
||||
global $imdbdata;
|
||||
global $id;
|
||||
|
||||
if (empty($cv)|| $config['lookupdefault_edit'] > 0 || $config['lookupdefault_new'] > 0)
|
||||
{
|
||||
$cv = $imdbdata['bbfc'];
|
||||
if (!empty($imdbdata['bbfc'])) $cv .= $imdbdata['bbfc'];
|
||||
|
||||
//we need to save our self here!
|
||||
if(!empty($id) && $cv != '')
|
||||
{
|
||||
$qcv = escapeSQL($cv);
|
||||
$UPDATE = "UPDATE ".TBL_DATA." SET $cn = '$qcv' WHERE id = $id";
|
||||
runSQL($UPDATE);
|
||||
}
|
||||
}
|
||||
$output = '<input type="text" size="10" maxlength="4" name="'.$cn.'" id="'.$cn.'" value="'.formvar($cv).'" />';
|
||||
$output .= " <a href='#' onclick='document.edi.".$cn.".value=\"U\"'>U</a>";
|
||||
$output .= " <a href='#' onclick='document.edi.".$cn.".value=\"12\"'>12</a>";
|
||||
$output .= " <a href='#' onclick='document.edi.".$cn.".value=\"12A\"'>12A</a>";
|
||||
$output .= " <a href='#' onclick='document.edi.".$cn.".value=\"15\"'>15</a>";
|
||||
$output .= " <a href='#' onclick='document.edi.".$cn.".value=\"18\"'>18</a>";
|
||||
$output .= " <a href='#' onclick='document.edi.".$cn.".value=\"PG\"'>PG</a>";
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Type: BBFC
|
||||
*
|
||||
* Show the BBFC rating of a movie
|
||||
* Based on the MPAA ratings above
|
||||
*
|
||||
* @author Colin Ogilvie <csogilvie@users.sourceforge.net>
|
||||
*/
|
||||
function custom_bbfc_output($cn,$cv)
|
||||
{
|
||||
global $imdbdata;
|
||||
global $id;
|
||||
|
||||
$ratings = array('PG' => 'bbfc-PG.gif',
|
||||
'12A' => 'bbfc-12A.gif',
|
||||
'12' => 'bbfc-12.gif',
|
||||
'15' => 'bbfc-15.gif',
|
||||
'18' => 'bbfc-18.gif',
|
||||
'U' => 'bbfc-U.gif');
|
||||
|
||||
$output = custom_text_output($cn,$cv);
|
||||
foreach ($ratings as $rating => $image)
|
||||
{
|
||||
if (strstr($output, (string) $rating))
|
||||
{
|
||||
$output = '<img src="'.img($image).'" alt="'.$rating.'"/>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
function custom_kijkwijzer_kijkwijzerdata () {
|
||||
return [
|
||||
'AL' => [1, 'Alle leeftijden', 'kijkwijzer/al.png', ''],
|
||||
'06' => [2, '6 jaar', 'kijkwijzer/6.png', ''],
|
||||
'09' => [4, '9 jaar', 'kijkwijzer/9.png', ''],
|
||||
'12' => [8, '12 jaar', 'kijkwijzer/12.png', ''],
|
||||
'14' => [16, '14 jaar', 'kijkwijzer/14.png', ''],
|
||||
'16' => [32, '16 jaar', 'kijkwijzer/16.png', ''],
|
||||
'18' => [64, '18 jaar', 'kijkwijzer/18.png', ''],
|
||||
'AN' => [128, 'Angst', 'kijkwijzer/angst.png', ''],
|
||||
'DI' => [256, 'Discriminatie', 'kijkwijzer/discriminatie.png', ''],
|
||||
'DA' => [512, 'Roken, alcohol en drugs', 'kijkwijzer/drugs-en-alcohol.png', ''],
|
||||
'GE' => [1024, 'Geweld', 'kijkwijzer/geweld.png', ''],
|
||||
'SE' => [2048, 'Seks', 'kijkwijzer/seks.png', ''],
|
||||
'TA' => [4096, 'Grof taalgebruik', 'kijkwijzer/taal.png', '']
|
||||
];
|
||||
}
|
||||
|
||||
function custom_kijkwijzer_input ($cn, $cv) {
|
||||
$kijkwijzer = custom_kijkwijzer_kijkwijzerdata();
|
||||
$output = '<input type="text" size="10" maxlength="4" name="'.$cn.'" id="'.$cn.'" value="'.formvar($cv).'" />';
|
||||
foreach ($kijkwijzer as $val => $cfg) {
|
||||
$output .= " <a href='#' onclick='document.edi.".$cn.".value+=\"".$val." \"' title='".$cfg[1]."'><img src=\"".img($cfg[2])."\" alt=\"Kijkwijzer: ".$cfg[1]."\" data-desc=\"".$cfg[3]."\" width=\"32\" /></a>";
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
function custom_kijkwijzer_output ($cn, $cv, $sm = false) {
|
||||
$kijkwijzer = custom_kijkwijzer_kijkwijzerdata();
|
||||
$rv = '';
|
||||
$cv = explode(' ', trim($cv));
|
||||
foreach ($cv as $i) {
|
||||
if (isset($kijkwijzer[$i])) {
|
||||
$rv .= '<img src="' . img($kijkwijzer[$i][2]) . '" alt="Kijkwijzer: ' . $kijkwijzer[$i][1] . '" title="' . $kijkwijzer[$i][1] . '" width="' . ($sm ? 24 : 48) . '" />';
|
||||
}
|
||||
}
|
||||
return $rv;
|
||||
}
|
||||
|
||||
263
videodb/core/edit.core.php
Normal file
263
videodb/core/edit.core.php
Normal file
@@ -0,0 +1,263 @@
|
||||
<?php
|
||||
/**
|
||||
* Edit functions. Split into separate file for reuse.
|
||||
*
|
||||
* @package videoDB
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @version $Id: edit.core.php,v 1.9 2009/12/05 13:56:04 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/security.php';
|
||||
|
||||
// list of fields to be read/written from/to html form
|
||||
$imdb_set_fields = array('md5','title','subtitle','language','diskid','mediatype','comment','disklabel',
|
||||
'imdbID','year','imgurl','director','actors','runtime','country','plot','filename',
|
||||
'filesize','filedate','audio_codec','video_codec','video_width','video_height','istv',
|
||||
'rating', 'custom1','custom2','custom3','custom4');
|
||||
|
||||
// list of fields to be overwritten by refetchAllInfos-Script
|
||||
$imdb_overwrite_fields = array('comment','disklabel','imdbID','year','director','actors','runtime','country','plot',
|
||||
'rating','custom1','custom2','custom3','custom4');
|
||||
|
||||
// special fields for SQL statements
|
||||
$db_null_fields = array('runtime', 'filesize', 'filedate', 'video_width', 'video_height');
|
||||
$db_zero_fields = array('istv', 'year');
|
||||
|
||||
/**
|
||||
* Obtain new disk id
|
||||
*
|
||||
* @return string Generated disk id
|
||||
*/
|
||||
function getDiskId()
|
||||
{
|
||||
global $config;
|
||||
|
||||
/*
|
||||
* change this if you have some fancy naming style
|
||||
*/
|
||||
|
||||
// how many digits have to be used for DiskId?
|
||||
$digits = ($config['diskid_digits']) ? $config['diskid_digits'] : 4;
|
||||
|
||||
/*
|
||||
* Old way automatic DiskID was generated: result was "highest ID + 1"
|
||||
*
|
||||
$NEXTUSERID = "SELECT LPAD(TRIM(LEADING '0' FROM MAX(LPAD(TRIM(LEADING '0' FROM diskid), 10, '0'))) + 1, ".
|
||||
$digits.", '0') AS max FROM ".TBL_DATA.' WHERE diskid NOT REGEXP "[^0-9]"';
|
||||
$result = runSQL($NEXTUSERID);
|
||||
return $result[0]['max'];
|
||||
*/
|
||||
|
||||
// get all DiskIds ordered from DB
|
||||
$SQL = "SELECT LPAD(TRIM(LEADING '0' FROM diskid), 10, '0') AS id
|
||||
FROM ".TBL_DATA.'
|
||||
WHERE diskid NOT REGEXP "[^0-9]" AND
|
||||
owner_id = '.get_current_user_id().'
|
||||
ORDER BY id';
|
||||
// sql looks strange but fixes problems with users who change their
|
||||
// diskid_digits while they have already movies in their DB.
|
||||
// added owner_id as fix for https://github.com/andig/videodb/issues/6
|
||||
$results = runSQL($SQL);
|
||||
|
||||
// find first 'free' diskId
|
||||
$lastid = 0;
|
||||
foreach ($results as $result)
|
||||
{
|
||||
$thisid = preg_replace('/^0+/','',$result['id']);
|
||||
if ($lastid + 1 < $thisid) break;
|
||||
$lastid = $thisid;
|
||||
}
|
||||
|
||||
// return the found id
|
||||
return str_pad($lastid + 1, $digits, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip leading articles
|
||||
*
|
||||
* @param string $field Input field to be stripped
|
||||
* @return string Input with articles rearranged to end of string
|
||||
*/
|
||||
function removeArticles($field)
|
||||
{
|
||||
$articles = array('the ', 'la ', 'a ', 'der ', 'die ', 'das ', 'des ', 'dem ', 'den ',
|
||||
'ein ', 'eine ', 'eines ', 'le ', 'el ', "l'", 'il ', 'les ', 'i ',
|
||||
'o ', 'un ', 'los ', 'de ', 'an ', 'una ', 'las ', 'gli ', 'het ',
|
||||
'lo ', 'os ', 'az ', 'ha-', 'een ', 'det ', 'oi ', 'ang ', 'ta ',
|
||||
'al-', 'uno ', "un'", 'ett ', 'mga ', 'Ï ', 'Ç ', 'els ', 'Ôï ', 'Ïé ');
|
||||
|
||||
foreach ($articles as $article)
|
||||
{
|
||||
if (preg_match("/^$article+/i", $field))
|
||||
{
|
||||
$field = trim(preg_replace("/(^$article)(.+)/i", "$2, $1", $field));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare item for display based on input data
|
||||
*/
|
||||
function echoInput($data)
|
||||
{
|
||||
global $imdb_set_fields;
|
||||
|
||||
// error no owner specified
|
||||
$video = array();
|
||||
|
||||
// select all fields according to list, plus id
|
||||
foreach ($imdb_set_fields as $name)
|
||||
{
|
||||
$video[0][$name] = $data[$name];
|
||||
}
|
||||
|
||||
return $video;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare update SQL
|
||||
*
|
||||
* @param array $data key/value pairs of data
|
||||
* @returns string result SQL, suitable for INSERT/UPDATE
|
||||
*/
|
||||
function prepareSQL($data, $setonly = false)
|
||||
{
|
||||
global $config, $imdb_set_fields, $db_null_fields, $db_zero_fields;
|
||||
|
||||
// get global variables into local scope
|
||||
extract($data);
|
||||
|
||||
// Fix for Bugreport [1122052] Automatic DiskID generation problem
|
||||
if ($config['autoid'] && !empty($diskid) && ($diskid == $autoid))
|
||||
{
|
||||
// in case DiskID is already used in meanwhile
|
||||
// -> update to new DiskId
|
||||
$diskid = getDiskId();
|
||||
}
|
||||
|
||||
// set default mediatype
|
||||
if (empty($mediatype)) $mediatype = $config['mediadefault'];
|
||||
|
||||
// set owner
|
||||
if (is_numeric($owner_id)) $SQL = 'owner_id = '.$owner_id;
|
||||
|
||||
// rating up to 10
|
||||
$rating = min($rating, 10);
|
||||
|
||||
// update all fields according to list
|
||||
foreach ($imdb_set_fields as $name)
|
||||
{
|
||||
if ($setonly && !isset($$name)) continue;
|
||||
|
||||
// sanitize input
|
||||
$$name = removeEvilTags($$name);
|
||||
if (!is_null($$name))
|
||||
{
|
||||
$$name = html_entity_decode($$name);
|
||||
}
|
||||
|
||||
// make sure no formatting contained in basic data
|
||||
if (in_array($name, array('title', 'subtitle')))
|
||||
{
|
||||
$$name = trim(strip_tags($$name));
|
||||
|
||||
// string leading articles?
|
||||
if ($config['removearticles'])
|
||||
{
|
||||
$$name = removeArticles($$name);
|
||||
}
|
||||
}
|
||||
|
||||
$SET = "$name = '".escapeSQL($$name)."'";
|
||||
|
||||
// special null/zero handling
|
||||
if (empty($$name))
|
||||
{
|
||||
if (in_array($name, $db_null_fields))
|
||||
$SET = "$name = NULL";
|
||||
elseif (in_array($name, $db_zero_fields))
|
||||
$SET = "$name = 0";
|
||||
}
|
||||
|
||||
if ($SQL) $SQL .= ', ';
|
||||
$SQL .= $SET;
|
||||
}
|
||||
|
||||
return $SQL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $SQL set fields
|
||||
* @param int $id id of item to update, insert if empty
|
||||
* @param boolean $touch true specifies to update created data of item
|
||||
*/
|
||||
function updateDB($SQL, $id, $touch=false)
|
||||
{
|
||||
if ($id)
|
||||
{
|
||||
// update existing record
|
||||
if ($touch)
|
||||
{
|
||||
// if the disk was on the wishlist and is now available, make sure it appears under 'new'
|
||||
$SQL .= ', created = NOW()';
|
||||
}
|
||||
|
||||
$SQL = 'UPDATE '.TBL_DATA.' SET '.$SQL.' WHERE id = '.$id;
|
||||
runSQL($SQL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// insert new record
|
||||
$SQL = 'INSERT INTO '.TBL_DATA.' SET '.$SQL.', created = NOW()';
|
||||
$id = runSQL($SQL);
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process HTTP file upload
|
||||
*/
|
||||
function processUpload($id, $file, $mime, $name)
|
||||
{
|
||||
if (!(isset($_FILES['coverupload']) && is_uploaded_file($_FILES['coverupload']['tmp_name'])))
|
||||
return;
|
||||
|
||||
// determine file extension
|
||||
if (preg_match('=image/jpe?g=i', $mime))
|
||||
{
|
||||
$ext = 'jpg';
|
||||
}
|
||||
elseif (preg_match('=image/(gif|png)=i', $mime, $m))
|
||||
{
|
||||
$ext = $m[1];
|
||||
}
|
||||
elseif (preg_match('=application/octet-stream=i', $mime))
|
||||
{
|
||||
if (preg_match("/\.(jpe?g|gif|png)$/i", $name, $m))
|
||||
{
|
||||
$ext = $m[1];
|
||||
}
|
||||
}
|
||||
|
||||
// move to cache and update db
|
||||
if (!empty($ext))
|
||||
{
|
||||
$coverfile = 'cache/img/'.$id.'.'.$ext;
|
||||
if (move_uploaded_file($file, $coverfile))
|
||||
{
|
||||
// fix permission issues
|
||||
chmod($coverfile, 0644);
|
||||
|
||||
$sql = "UPDATE ".TBL_DATA." SET imgurl='$coverfile' WHERE id=$id";
|
||||
runSQL($sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
282
videodb/core/encoding.php
Normal file
282
videodb/core/encoding.php
Normal file
@@ -0,0 +1,282 @@
|
||||
<?php
|
||||
/**
|
||||
* Encoding functions
|
||||
*
|
||||
* Contains HTML and Unicode conversion functions
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: encoding.php,v 1.6 2013/03/10 16:25:35 andig2 Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check if string contains unicode characters
|
||||
*/
|
||||
function is_utf8($str)
|
||||
{
|
||||
// array handling
|
||||
if (is_array($str)) {
|
||||
foreach($str as $k => $v) {
|
||||
$res = is_utf8($v);
|
||||
if (!$res) return(false);
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
// From http://w3.org/International/questions/qa-forms-utf-8.html
|
||||
return preg_match('%^(?:
|
||||
[\x09\x0A\x0D\x20-\x7E] # ASCII
|
||||
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|
||||
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
|
||||
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
|
||||
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
|
||||
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
|
||||
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
|
||||
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
|
||||
)*$%xs', $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author "Sebasti<74>n Grignoli" <grignoli@framework2.com.ar>
|
||||
* @package Encoding
|
||||
* @version 1.1
|
||||
* @link http://www.framework2.com.ar/dzone/forceUTF8-es/
|
||||
* @example http://www.framework2.com.ar/dzone/forceUTF8-es/
|
||||
*/
|
||||
function fix_utf8($text)
|
||||
{
|
||||
$utf8ToWin1252 = array(
|
||||
"\xe2\x82\xac" => "\x80",
|
||||
|
||||
"\xe2\x80\x9a" => "\x82",
|
||||
"\xc6\x92" => "\x83",
|
||||
"\xe2\x80\x9e" => "\x84",
|
||||
"\xe2\x80\xa6" => "\x85",
|
||||
"\xe2\x80\xa0" => "\x86",
|
||||
"\xe2\x80\xa1" => "\x87",
|
||||
"\xcb\x86" => "\x88",
|
||||
"\xe2\x80\xb0" => "\x89",
|
||||
"\xc5\xa0" => "\x8a",
|
||||
"\xe2\x80\xb9" => "\x8b",
|
||||
"\xc5\x92" => "\x8c",
|
||||
|
||||
"\xc5\xbd" => "\x8e",
|
||||
|
||||
|
||||
"\xe2\x80\x98" => "\x91",
|
||||
"\xe2\x80\x99" => "\x92",
|
||||
"\xe2\x80\x9c" => "\x93",
|
||||
"\xe2\x80\x9d" => "\x94",
|
||||
"\xe2\x80\xa2" => "\x95",
|
||||
"\xe2\x80\x93" => "\x96",
|
||||
"\xe2\x80\x94" => "\x97",
|
||||
"\xcb\x9c" => "\x98",
|
||||
"\xe2\x84\xa2" => "\x99",
|
||||
"\xc5\xa1" => "\x9a",
|
||||
"\xe2\x80\xba" => "\x9b",
|
||||
"\xc5\x93" => "\x9c",
|
||||
|
||||
"\xc5\xbe" => "\x9e",
|
||||
"\xc5\xb8" => "\x9f"
|
||||
);
|
||||
|
||||
if (is_array($text)) {
|
||||
foreach($text as $k => $v) {
|
||||
$text[$k] = fix_utf8($v);
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
$last = "";
|
||||
while ($last <> $text) {
|
||||
$last = $text;
|
||||
$text = utf8_encode(utf8_decode(str_replace(array_keys($utf8ToWin1252), array_values($utf8ToWin1252), $text)));
|
||||
}
|
||||
$text = utf8_encode(utf8_decode(str_replace(array_keys($utf8ToWin1252), array_values($utf8ToWin1252), $text)));
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode string is utf-8. Typically used for later URL encoding of the string
|
||||
*/
|
||||
function utf8_smart_decode($str)
|
||||
{
|
||||
return (is_utf8($str)) ? utf8_decode($str) : $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like html_entity_decode() but also supports numeric entities.
|
||||
* Output encoding is ISO-8852-1.
|
||||
*
|
||||
* @author www.php.net
|
||||
* @param string $string html entity loaded string
|
||||
* @return string html entity free string
|
||||
*/
|
||||
function html_entity_decode_all($string)
|
||||
{
|
||||
// replace numeric entities
|
||||
$string = preg_replace_callback('~&#x([0-9a-f]+);~i', '_callback_chr_hexdec', $string);
|
||||
$string = preg_replace_callback('~&#([0-9]+);~', '_callback_chr', $string);
|
||||
# utf8 version commented out
|
||||
# $string = preg_replace_callback('~&#x([0-9a-f]+);~i', '_callback_code2utf_hexdec', $string);
|
||||
# $string = preg_replace_callback('~&#([0-9]+);~', '_callback_code2utf', $string);
|
||||
|
||||
// replace literal entities
|
||||
$trans_tbl = get_html_translation_table(HTML_ENTITIES);
|
||||
$trans_tbl = array_flip($trans_tbl);
|
||||
# utf8 version commented out
|
||||
# foreach (get_html_translation_table(HTML_ENTITIES) as $val=>$key) $trans_tbl[$key] = utf8_encode($val);
|
||||
|
||||
return strtr($string, $trans_tbl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like html_entity_decode() but also supports numeric entities.
|
||||
* Output encoding is UTF-8.
|
||||
*
|
||||
* @author www.php.net
|
||||
* @param string $string html entity loaded string
|
||||
* @return string html entity free string
|
||||
*/
|
||||
function html_entity_decode_all_utf8($string)
|
||||
{
|
||||
// replace numeric entities
|
||||
# non-utf8 version commented out
|
||||
# $string = preg_replace_callback('~&#x([0-9a-f]+);~i', '_callback_chr_hexdec', $string);
|
||||
# $string = preg_replace_callback('~&#([0-9]+);~', '_callback_chr', $string);
|
||||
$string = preg_replace_callback('~&#x([0-9a-f]+);~i', '_callback_code2utf_hexdec', $string);
|
||||
$string = preg_replace_callback('~&#([0-9]+);~', '_callback_code2utf', $string);
|
||||
|
||||
// replace literal entities
|
||||
# non-utf8 version commented out
|
||||
# $trans_tbl = get_html_translation_table(HTML_ENTITIES);
|
||||
# $trans_tbl = array_flip($trans_tbl);
|
||||
foreach (get_html_translation_table(HTML_ENTITIES) as $val=>$key) $trans_tbl[$key] = utf8_encode($val);
|
||||
|
||||
return strtr($string, $trans_tbl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the utf-8 encoding corresponding to the unicode character value
|
||||
* @author from php.net, courtesy - romans@void.lv
|
||||
*/
|
||||
function code2utf($num)
|
||||
{
|
||||
if ($num < 128) return chr($num);
|
||||
if ($num < 2048) return chr(($num >> 6) + 192) . chr(($num & 63) + 128);
|
||||
if ($num < 65536) return chr(($num >> 12) + 224) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
|
||||
if ($num < 2097152) return chr(($num >> 18) + 240) . chr((($num >> 12) & 63) + 128) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean HTML entities and replace special spaces
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string $string html entity loaded string
|
||||
* @return string html entity free string
|
||||
*/
|
||||
function html_clean($str)
|
||||
{
|
||||
return trim(str_replace(chr(160), ' ', html_entity_decode_all($str)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean HTML entities, tags and replace special spaces
|
||||
* Output encoding is UTF-8.
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string $str html entity loaded string
|
||||
* @return string html entity free string
|
||||
*/
|
||||
function html_clean_utf8($str)
|
||||
{
|
||||
# this replacement breaks unicode enitity encoding as A0 might occor as part of any character
|
||||
# $str = str_replace(chr(160), ' ', $str);
|
||||
$str = html_entity_decode_all_utf8(strip_tags($str));
|
||||
return trim($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chance character set encoding for hierarchical array
|
||||
*
|
||||
* @param mixed $data string or hierarchical array to convert
|
||||
* @return mixed data in target encoding
|
||||
*/
|
||||
function iconv_array($source_encoding, $target_encoding, $data)
|
||||
{
|
||||
if (is_array($data))
|
||||
{
|
||||
// recursive call for array conversion
|
||||
foreach ($data as $key => $val)
|
||||
{
|
||||
$data[$key] = iconv_array($source_encoding, $target_encoding, $val);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// finally convert string value
|
||||
$data_saved = $data; // save data for output on error page if signalled
|
||||
$data = iconv($source_encoding, $target_encoding."//TRANSLIT", (string)$data);
|
||||
if ($data === FALSE)
|
||||
{
|
||||
errorpage('Character set conversion error', "Error converting from $source_encoding to $target_encoding. <br> String <br> $data_saved");
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert HTML to plain text for some common entities
|
||||
*/
|
||||
function html_to_text($str)
|
||||
{
|
||||
// create list items
|
||||
$str = preg_replace("#<li.*?>#i", "\n-", $str);
|
||||
|
||||
// de-html line breaks
|
||||
$str = preg_replace('#<(br|p).*?>#i', "\n", $str);
|
||||
|
||||
// avoid double line breaks
|
||||
$str = preg_replace("#\n+#", "\n", $str);
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that there is only one match from a preg_replace_callback and return it
|
||||
*/
|
||||
function _get_only_match_from_callback($matches) {
|
||||
assert(sizeof($matches) === 2);
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* apply chr on the only match of a preg_replace_callback
|
||||
*/
|
||||
function _callback_chr($matches) {
|
||||
return chr(_get_only_match_from_callback($matches));
|
||||
}
|
||||
|
||||
/**
|
||||
* apply hexdec and chr on the only match of a preg_replace_callback
|
||||
*/
|
||||
function _callback_chr_hexdec($matches) {
|
||||
return chr(hexdec(_get_only_match_from_callback($matches)));
|
||||
}
|
||||
|
||||
/**
|
||||
* apply code2utf on the only match of a preg_replace_callback
|
||||
*/
|
||||
function _callback_code2utf($matches) {
|
||||
return code2utf(_get_only_match_from_callback($matches));
|
||||
}
|
||||
|
||||
/**
|
||||
* apply hexdec and code2utf on the only match of a preg_replace_callback
|
||||
*/
|
||||
function _callback_code2utf_hexdec($matches) {
|
||||
return code2utf(hexdec(_get_only_match_from_callback($matches)));
|
||||
}
|
||||
?>
|
||||
81
videodb/core/export.core.php
Normal file
81
videodb/core/export.core.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
* Export functions. Returns standardized data for export.
|
||||
*
|
||||
* @package videoDB
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @version $Id: export.core.php,v 1.8 2013/03/15 16:42:46 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/genres.php';
|
||||
|
||||
function listExports($link, $omit = array('rss'))
|
||||
{
|
||||
global $config;
|
||||
|
||||
$exports = array('xls' => 'Microsoft Excel',
|
||||
'pdf' => 'Adobe PDF',
|
||||
'xml' => 'XML',
|
||||
'rss' => 'RSS Feed');
|
||||
|
||||
$res = array();
|
||||
foreach ($exports as $export => $title)
|
||||
{
|
||||
if ($config[$export] &! in_array($export, $omit))
|
||||
$res[] = array('type' => $export, 'title' => $title, 'link' => $link);
|
||||
}
|
||||
return($res);
|
||||
}
|
||||
|
||||
function exportData($WHERE)
|
||||
{
|
||||
$SQL = 'SELECT '.TBL_DATA.'.*,
|
||||
'.TBL_USERS.'.name AS owner,
|
||||
'.TBL_MEDIATYPES.'.name AS mediatype,
|
||||
'.TBL_LENT.'.who AS lentto,
|
||||
CASE WHEN '.TBL_USERSEEN.'.video_id IS NULL THEN 0 ELSE 1 END AS seen
|
||||
FROM '.TBL_DATA.'
|
||||
LEFT JOIN '.TBL_USERS.' ON '.TBL_DATA.'.owner_id = '.TBL_USERS.'.id
|
||||
LEFT JOIN '.TBL_USERSEEN.' ON '.TBL_DATA.'.id = '.TBL_USERSEEN.'.video_id AND '.TBL_USERSEEN.'.user_id = '.get_current_user_id().'
|
||||
LEFT JOIN '.TBL_LENT.' ON '.TBL_DATA.'.diskid = '.TBL_LENT.'.diskid
|
||||
LEFT JOIN '.TBL_MEDIATYPES.' ON mediatype = '.TBL_MEDIATYPES.'.id '.
|
||||
$WHERE;
|
||||
|
||||
$result = runSQL($SQL);
|
||||
|
||||
// do adultcheck
|
||||
if (is_array($result))
|
||||
{
|
||||
$result = array_filter($result, function($video) {return adultcheck($video["id"]);});
|
||||
}
|
||||
|
||||
// genres
|
||||
for($i=0; $i<count($result); $i++)
|
||||
{
|
||||
$result[$i]['genres'] = getItemGenres($result[$i]['id'], true);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit string length while honoring word breaks
|
||||
*
|
||||
* @param string string to trim
|
||||
* @param int target length
|
||||
* @result string trimmed string
|
||||
*/
|
||||
function leftString($plot, $text_length)
|
||||
{
|
||||
if (strlen($plot) > $text_length+3)
|
||||
{
|
||||
$plot = substr($plot, 0, $text_length);
|
||||
$space = strrpos($plot, ' ');
|
||||
if ($space) $plot = substr($plot, 0, $space);
|
||||
$plot .= '...';
|
||||
}
|
||||
return $plot;
|
||||
}
|
||||
|
||||
?>
|
||||
279
videodb/core/functions.core.php
Normal file
279
videodb/core/functions.core.php
Normal file
@@ -0,0 +1,279 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* General functions
|
||||
*
|
||||
* Contains globally available tool functions. It is included in every
|
||||
* page and sets up some defaults like error reporting, environment
|
||||
* setups and config loading
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @version $Id: functions.core.php,v 1.1 2013/04/26 15:08:30 andig2 Exp $
|
||||
*/
|
||||
|
||||
if (!function_exists('errorpage')) {
|
||||
function errorpage($title = 'An error occured', $body = '', $stacktrace = false) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output debug info
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param mixed $var Variable to dump
|
||||
* @param bool $ret Return result instead of outputting
|
||||
* @param bool $plain Indicate that \n separator is used
|
||||
*/
|
||||
function dump($var, $ret = false, $plain = false)
|
||||
{
|
||||
global $argv;
|
||||
if (isset($argv) && is_array($argv) && count($argv) > 0) $plain = true;
|
||||
|
||||
if (is_array($var) || is_object($var))
|
||||
$var = print_r($var, 1);
|
||||
else if (is_bool($var))
|
||||
$var = ($var) ? 'TRUE' : 'FALSE';
|
||||
|
||||
$var .= (is_array($argv)&&count($argv) > 0 || $plain) ? "\n" : "<br/>\n";
|
||||
|
||||
if ($ret) return $var;
|
||||
echo $var;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write variable to file
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $filename Filename to dump to
|
||||
* @param var $var Variable to dump
|
||||
*/
|
||||
function file_append($filename, $var, $append = true)
|
||||
{
|
||||
$log = fopen($filename, $append ? 'a' : 'w');
|
||||
fwrite($log, dump($var, true, true));
|
||||
fclose($log);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to debug log
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param mixed $var Variable to dump
|
||||
*/
|
||||
function dlog($var)
|
||||
{
|
||||
file_append(LOG_FILE, $var);
|
||||
}
|
||||
|
||||
/**
|
||||
* safe formoutputter
|
||||
*
|
||||
* @param string $name The input string
|
||||
* @return string The cleaned string
|
||||
*/
|
||||
function formvar($name)
|
||||
{
|
||||
if (!is_null($name))
|
||||
{
|
||||
return htmlspecialchars($name);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get high resolution time
|
||||
*
|
||||
* @return integer current time in microseconds
|
||||
*/
|
||||
function getmicrotime()
|
||||
{
|
||||
list($usec, $sec) = explode(' ', microtime());
|
||||
return ((float)$usec + (float)$sec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return mysqli db connection object
|
||||
*
|
||||
* @return mysqli database handle
|
||||
*/
|
||||
function getConnection()
|
||||
{
|
||||
global $config, $dbh;
|
||||
|
||||
$dbh = mysqli_connect('p:'.$config['db_server'], $config['db_user'], $config['db_password'], $config['db_database']);
|
||||
if (mysqli_connect_error())
|
||||
errorpage('DB Connection Error',
|
||||
"<p>Edit the database settings in <code>".CONFIG_FILE."</code>.</p>
|
||||
<p>Alternatively, consider running the <a href='install.php'>installation script</a>.</p>");
|
||||
|
||||
if (DB_CHARSET)
|
||||
{
|
||||
if (mysqli_set_charset($dbh, DB_CHARSET) === false)
|
||||
errorpage('DB Link Error', 'Couldn\'t set encoding to '.DB_CHARSET);
|
||||
}
|
||||
|
||||
return($dbh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape SQL string according to current DB charset settings
|
||||
*
|
||||
* @param string $sql_string SQL string to escape
|
||||
* @return string escaped string
|
||||
*/
|
||||
function escapeSQL($sql_string)
|
||||
{
|
||||
global $dbh;
|
||||
|
||||
if (!is_null($sql_string))
|
||||
{
|
||||
if (!is_resource($dbh)) $dbh = getConnection();
|
||||
|
||||
return(mysqli_real_escape_string($dbh, $sql_string));
|
||||
}
|
||||
|
||||
return ("");
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL wrapper for all Database accesses
|
||||
*
|
||||
* @param string $sql_string The SQL-Statement to execute
|
||||
* @return mixed either the resultset as an array with hashes or the insertid
|
||||
*/
|
||||
function runSQL($sql_string, $verify = true)
|
||||
{
|
||||
global $config, $dbh, $SQLtrace;
|
||||
|
||||
if ($config['debug'])
|
||||
{
|
||||
dlog("\n".$_SERVER['REQUEST_URI']);
|
||||
if (function_exists('xdebug_get_function_stack')) dlog(join(' -> ', array_column(xdebug_get_function_stack(), 'function')));
|
||||
dlog($sql_string);
|
||||
$timestamp = getmicrotime();
|
||||
}
|
||||
|
||||
if (!is_resource($dbh)) $dbh = getConnection();
|
||||
$res = mysqli_query($dbh, $sql_string);
|
||||
|
||||
// mysqli_db_query returns either positive result ressource or true/false for an insert/update statement
|
||||
if ($res === false)
|
||||
{
|
||||
$result = false;
|
||||
if ($verify)
|
||||
{
|
||||
// report DB Problem
|
||||
errorpage('Database Problem', mysqli_error($dbh)."\n<br />\n".$sql_string, true);
|
||||
}
|
||||
}
|
||||
elseif ($res === true)
|
||||
{
|
||||
// on insert, return id of created record
|
||||
$result = mysqli_insert_id($dbh);
|
||||
}
|
||||
else
|
||||
{
|
||||
// return associative result array
|
||||
$result = array();
|
||||
|
||||
for ($i=0; $i<mysqli_num_rows($res); $i++)
|
||||
{
|
||||
$result[] = mysqli_fetch_assoc($res);
|
||||
}
|
||||
mysqli_free_result($res);
|
||||
}
|
||||
|
||||
if ($config['debug'])
|
||||
{
|
||||
$timestamp = getmicrotime() - $timestamp;
|
||||
dlog('Time: '.$timestamp);
|
||||
// collect all SQL info for debugging
|
||||
$SQLtrace[] = array('sql' => $sql_string, 'time' => $timestamp);
|
||||
}
|
||||
|
||||
# mysqli_close($dbh);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the page is accessed from within the local net.
|
||||
*
|
||||
* @return bool true if localnet
|
||||
*/
|
||||
function localnet()
|
||||
{
|
||||
global $config;
|
||||
return (preg_match('/'.$config['localnet'].'/', $_SERVER['REMOTE_ADDR']));
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the page is accessed from within the local net.
|
||||
* If not, displays a simple error page and exits
|
||||
*/
|
||||
function localnet_or_die()
|
||||
{
|
||||
if (!localnet()) errorpage('Forbidden', 'You are not allowed to access this page');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set connection encoding according to config file or language specification
|
||||
*/
|
||||
function db_set_encoding()
|
||||
{
|
||||
global $config, $lang;
|
||||
|
||||
// set connection character set and collation
|
||||
if (DB_CHARSET)
|
||||
{
|
||||
$sql = "SET NAMES '".DB_CHARSET."'";
|
||||
$collation = ($lang['collation']) ? DB_CHARSET.'_'.$lang['collation'] : DB_COLLATION;
|
||||
if ($collation) $sql .= " COLLATE '".$collation."'";
|
||||
|
||||
runSQL($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to new location
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string $dest Redirect destination
|
||||
* @todo Read somewhere that according to RFC redirects need to specify full URI
|
||||
*/
|
||||
function redirect($dest)
|
||||
{
|
||||
header('Location: '.$dest);
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an array of associative arrays (e.g. a database query result) to an associative key=>value array
|
||||
*
|
||||
* Sample: array_associate( 0=>(a=>1a, b=1b) 1=>(a=>2a, b=>2b), "a", "b" ) gives 1a=>1b, 2a=>2b
|
||||
*
|
||||
* If $value is false, the whole array is associated instead of a specific value
|
||||
*
|
||||
* Sample: array_associate( 0=>(a=>1a, b=1b) 1=>(a=>2a, b=>2b), "a", false ) gives 1a=>(b=>1b), 2a=>(b=>2b
|
||||
*
|
||||
* TODO Check if this can be replaced by PHP5.5 array_column() function
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param $ary SQL result array
|
||||
* @param $key key index name
|
||||
* @param $value value index name
|
||||
* @return array resulting associative array
|
||||
*/
|
||||
function array_associate($ary, $columnKey, $value = false)
|
||||
{
|
||||
$res = array();
|
||||
foreach ($ary as $row)
|
||||
{
|
||||
$res[$row[$columnKey]] = ($value) ? $row[$value] : $row;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
?>
|
||||
1095
videodb/core/functions.php
Normal file
1095
videodb/core/functions.php
Normal file
File diff suppressed because it is too large
Load Diff
137
videodb/core/genres.php
Normal file
137
videodb/core/genres.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/**
|
||||
* Genre functions
|
||||
*
|
||||
* Contains functions for working with video genres
|
||||
* moved from functions.php to genres.php
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @version $Id: genres.php,v 1.14 2008/01/29 10:59:52 veal Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Map movie genres to versions existing in db
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param array $genres A list of input genres
|
||||
* @return array The mapped genres result array
|
||||
*/
|
||||
function mapGenres($genres)
|
||||
{
|
||||
global $dbgenres;
|
||||
|
||||
// load genres from DB once
|
||||
if (empty($dbgenres))
|
||||
{
|
||||
$dbgenres = array();
|
||||
foreach (runSQL('SELECT id, name FROM '.TBL_GENRES.' ORDER BY name') as $row)
|
||||
{
|
||||
$dbgenres[] = $row['name'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($genres as $in_genre)
|
||||
{
|
||||
$mapped_genre = '';
|
||||
$mapped_percent = 0;
|
||||
|
||||
$in_genre = trim($in_genre);
|
||||
|
||||
// direct match?
|
||||
if (in_array($in_genre, $dbgenres))
|
||||
{
|
||||
$gens[] = $in_genre;
|
||||
}
|
||||
else
|
||||
{
|
||||
// possible approximate match
|
||||
foreach ($dbgenres as $genre_name)
|
||||
{
|
||||
// calculate similiarity and find best match
|
||||
$chars = similar_text($in_genre, $genre_name, $percent);
|
||||
if ($percent >= 50)
|
||||
{
|
||||
if (stristr($in_genre, $genre_name)) $percent += 10;
|
||||
if ($percent > $mapped_percent)
|
||||
{
|
||||
$mapped_genre = $genre_name;
|
||||
$mapped_percent = $percent;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($mapped_genre) $gens[] = $mapped_genre;
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique($gens);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the genreID for a given name from the 'genres' table
|
||||
*
|
||||
* @todo check if this can be moved to edit.php
|
||||
* @param string $name the name of the genre
|
||||
* @return integer $genre the genre id
|
||||
*/
|
||||
function getGenreId($name)
|
||||
{
|
||||
$name = escapeSQL($name);
|
||||
$result = runSQL("SELECT id FROM ".TBL_GENRES." WHERE LCASE(name) = LCASE('".$name."')");
|
||||
return $result[0]['id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve genre ids/ genres of a video
|
||||
*
|
||||
* @param integer $id ID of the video
|
||||
* @param boolean $names include genre names in output
|
||||
* @return array genre id's OR
|
||||
* @return array associative array of genre ids and names
|
||||
*/
|
||||
function getItemGenres($id, $names = false)
|
||||
{
|
||||
$genres = array();
|
||||
if (empty($id)) return $genres;
|
||||
|
||||
$SELECT = 'SELECT genres.id, genres.name
|
||||
FROM '.TBL_GENRES.' AS genres, '.TBL_VIDEOGENRE.' AS videogenre
|
||||
WHERE genres.id = videogenre.genre_id
|
||||
AND videogenre.video_id = '.$id;
|
||||
$result = runSQL($SELECT);
|
||||
|
||||
if ($names) return $result;
|
||||
|
||||
foreach ($result as $row)
|
||||
{
|
||||
$genres[] = $row['id'];
|
||||
}
|
||||
|
||||
return $genres;
|
||||
}
|
||||
|
||||
/**
|
||||
* save genres for a movie
|
||||
*
|
||||
* @todo check if this can be moved to edit.php
|
||||
* @param integer $id ID of the video
|
||||
* @param array $genres genre IDs
|
||||
*/
|
||||
function setItemGenres($id, $genres)
|
||||
{
|
||||
// Delete all genres for id
|
||||
runSQL('DELETE FROM '.TBL_VIDEOGENRE.' WHERE video_id = '.$id);
|
||||
|
||||
if (count($genres))
|
||||
{
|
||||
$genres = array_unique($genres);
|
||||
|
||||
foreach($genres as $genre)
|
||||
{
|
||||
runSQL('INSERT INTO '.TBL_VIDEOGENRE.' SET video_id = '.$id.', genre_id = '.$genre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
111
videodb/core/httpcache.php
Normal file
111
videodb/core/httpcache.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* HTTP caching functions
|
||||
*
|
||||
* Enable use of HTTP 304 headers for unmodified content to save bandwidth
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @version $Id: httpcache.php,v 1.5 2010/11/05 10:38:47 andig2 Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Start output buffering
|
||||
*/
|
||||
function httpCacheCaptureStart()
|
||||
{
|
||||
ob_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop output buffering
|
||||
*
|
||||
* @param string MD5 hash of content
|
||||
*/
|
||||
function httpCacheCaptureEnd()
|
||||
{
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last modified data for given etag
|
||||
* Checks session for known etag and timestamp
|
||||
*/
|
||||
function httpCacheCheckTag($template, $etag)
|
||||
{
|
||||
if ($etag != $_SESSION['vdb'][$template]['etag'])
|
||||
{
|
||||
$lastmod = time();
|
||||
$_SESSION['vdb'][$template]['etag'] = $etag;
|
||||
$_SESSION['vdb'][$template]['time'] = $lastmod;
|
||||
}
|
||||
else
|
||||
{
|
||||
$lastmod = $_SESSION['vdb'][$template]['time'];
|
||||
}
|
||||
return($lastmod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Output 304 Not Modified header
|
||||
* Require browser to re-check on next request
|
||||
*/
|
||||
function httpCacheHeaders($etag, $expires)
|
||||
{
|
||||
header(php_sapi_name() == 'cgi' ? 'Status: 304 Not Modified' : 'HTTP/1.x 304 Not Modified');
|
||||
header("ETag: {$etag}");
|
||||
header("Cache-Control: private, max-age={$expires}, pre-check=0, post-check=0");
|
||||
header("Content-Length: 0");
|
||||
|
||||
header("Content-Type: !invalid");
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if output was modified since last request
|
||||
* If unmodifed, output 304 Not Modified header
|
||||
* Otherwise add additional ETag and LastModified headers
|
||||
*/
|
||||
function httpCacheOutput($template, $content)
|
||||
{
|
||||
$etag = '"'.md5($content).'"';
|
||||
|
||||
// check if 'sending' is necessary (using cache functions)
|
||||
$sendbody = true;
|
||||
$expires = 0;
|
||||
|
||||
$lastmod = httpCacheCheckTag($template, $etag);
|
||||
|
||||
// check 'If-Modified-Since' header
|
||||
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && gmdate('D, d M Y H:i:s', $lastmod)." GMT" == trim($_SERVER['HTTP_IF_MODIFIED_SINCE']))
|
||||
{
|
||||
httpCacheHeaders($etag, $expires);
|
||||
}
|
||||
|
||||
// check 'If-None-Match' header (ETag)
|
||||
if ($sendbody && isset($_SERVER['HTTP_IF_NONE_MATCH']))
|
||||
{
|
||||
$inm = explode(',', $_SERVER['HTTP_IF_NONE_MATCH']);
|
||||
foreach ($inm as $i)
|
||||
{
|
||||
if (trim($i) != $etag) continue;
|
||||
httpCacheHeaders($etag, $expires);
|
||||
}
|
||||
}
|
||||
|
||||
// send with caching headers (enable cache for one day)
|
||||
$exp_gmt = gmdate('D, d M Y H:i:s', time() + $expires).' GMT';
|
||||
$mod_gmt = gmdate('D, d M Y H:i:s', $lastmod).' GMT';
|
||||
header("Expires: {$exp_gmt}");
|
||||
header("Last-Modified: {$mod_gmt}");
|
||||
header("Cache-Control: private, max-age={$expires}, pre-check=0, post-check=0");
|
||||
header("Pragma: !invalid");
|
||||
header("ETag: {$etag}");
|
||||
|
||||
echo $content;
|
||||
}
|
||||
|
||||
?>
|
||||
246
videodb/core/httpclient.php
Normal file
246
videodb/core/httpclient.php
Normal file
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
/**
|
||||
* HTTP client functions
|
||||
*
|
||||
* @todo Encapsulate httpClient and Cache as separate classes
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @version $Id: httpclient.php,v 1.21 2013/04/26 15:09:35 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once 'core/cache.php';
|
||||
require_once 'vendor/autoload.php';
|
||||
|
||||
use GuzzleHttp\Psr7 as Psr7;
|
||||
|
||||
/**
|
||||
* Reads a saved HTTP response from a cachefile.
|
||||
* If caching is globally disabled ($config['IMDBage'] <= 0), file is not loaded.
|
||||
*
|
||||
* @param string $url URL of the cached response
|
||||
* @return mixed HTTP Response, false on errors
|
||||
*/
|
||||
function getHTTPcache($url)
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (@$config['cache_pruning'])
|
||||
{
|
||||
$cache_file = cache_get_filename($url, CACHE_HTML);
|
||||
cache_prune_folder(dirname($cache_file).'/', $config['IMDBage']);
|
||||
}
|
||||
|
||||
return cache_get($url, CACHE_HTML, $config['IMDBage'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a HTTP resonse to a cachefile
|
||||
* If caching is globally disabled ($config['IMDBage'] <= 0), file is not saved.
|
||||
*
|
||||
* @param string $url URL of the response
|
||||
* @param mixed $resp HTTP Response
|
||||
*/
|
||||
function putHTTPcache($url, $data)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// for debugging purposes track there the request originated
|
||||
$data['source'] = $url;
|
||||
|
||||
cache_put($url, $data, CACHE_HTML, $config['IMDBage'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract source encoding from HTML code or HTTP header otherwise
|
||||
*/
|
||||
function get_response_encoding($response)
|
||||
{
|
||||
$header = $encoding = null;
|
||||
|
||||
// response array from cache
|
||||
if (is_array($response)) {
|
||||
if (isset($response['header']['Content-Type'])) {
|
||||
$header = $response['header']['Content-Type'];
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Psr response
|
||||
$header = $response->getHeader('Content-Type');
|
||||
}
|
||||
|
||||
if ($header) {
|
||||
$parsed = Psr7\parse_header($header);
|
||||
if (array_key_exists('charset', $parsed[0]))
|
||||
{
|
||||
$encoding = strtolower($parsed[0]['charset']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$encoding)
|
||||
{
|
||||
$encoding = 'iso-8859-1';
|
||||
}
|
||||
|
||||
return $encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP Client
|
||||
*
|
||||
* Returns the raw data from the given URL, uses proxy when configured
|
||||
* and follows redirects
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string $url URL to fetch
|
||||
* @param bool $cache use caching? defaults to false
|
||||
* @param string $post POST data, if nonempty POST is used instead of GET
|
||||
* @param integer $timeout Timeout in seconds defaults to 15
|
||||
* @return mixed HTTP response
|
||||
*/
|
||||
function httpClient($url, $cache = false, $para = null, $reload = false)
|
||||
{
|
||||
static $referer = 'https://www.imdb.com/search/';
|
||||
global $config;
|
||||
$client = new GuzzleHttp\Client();
|
||||
|
||||
$requestConfig = [];
|
||||
$headers = ''; // additional HTTP headers, used for post data
|
||||
|
||||
if (!empty($para) && array_key_exists('cookies', $para) && $para['cookies'])
|
||||
{
|
||||
$jar = new GuzzleHttp\Cookie\CookieJar();
|
||||
$requestConfig += ['cookies' => $jar];
|
||||
}
|
||||
|
||||
$method = 'GET';
|
||||
|
||||
$post = isset($para['post']) ? $para['post'] : '';
|
||||
if ($post)
|
||||
{
|
||||
$method = 'POST';
|
||||
$requestConfig += ['headers' => ['Content-Type' => 'application/x-www-form-urlencoded']];
|
||||
$requestConfig += ['body' => $post];
|
||||
}
|
||||
|
||||
// get data from cache?
|
||||
if ($cache &! $reload)
|
||||
{
|
||||
$resp = getHTTPcache($url.$post);
|
||||
if ($resp !== false)
|
||||
{
|
||||
$resp['cached'] = true;
|
||||
return $resp;
|
||||
}
|
||||
}
|
||||
|
||||
// proxy setup
|
||||
if (!empty($config['proxy_host']) && !$para['no_proxy'])
|
||||
{
|
||||
$server = $config['proxy_host'];
|
||||
if (!($port = @$config['proxy_port']))
|
||||
{
|
||||
$port = 8080;
|
||||
}
|
||||
$requestConfig += ['proxy' => sprintf('tcp://%s:%d', $server, $port)];
|
||||
}
|
||||
|
||||
// additional request headers
|
||||
if (!empty($para) && array_key_exists('header', $para) && $para['header'])
|
||||
{
|
||||
$requestConfig += ['headers' => $para['header']];
|
||||
}
|
||||
|
||||
if (empty($requestConfig['headers']['Accept'])) $requestConfig['headers']['Accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
|
||||
if (empty($requestConfig['headers']['Accept-Language'])) $requestConfig['headers']['Accept-Language'] = ((isset($config['acclangbrowser']) && $config['acclangbrowser']) ? filter_input(INPUT_SERVER, 'HTTP_ACCEPT_LANGUAGE') : 'en-US;q=0.7,en;q=0.3');
|
||||
if (empty($requestConfig['headers']['DNT'])) $requestConfig['headers']['DNT'] = '1';
|
||||
if (empty($requestConfig['headers']['User-Agent'])) $requestConfig['headers']['User-Agent'] = filter_input(INPUT_SERVER, 'HTTP_USER_AGENT');
|
||||
if (empty($requestConfig['headers']['Referer'])) $requestConfig['headers']['Referer'] = $referer;
|
||||
|
||||
$resp = $client->request($method, $url, $requestConfig);
|
||||
|
||||
$response['error'] = '';
|
||||
$response['url'] = $url;
|
||||
$response['success'] = false;
|
||||
$response['encoding'] = get_response_encoding($resp);
|
||||
$response['header'] = $resp->getHeaders();
|
||||
$response['data'] = (string) $resp->getBody();
|
||||
|
||||
if ($config['debug']) echoHeaders($response['header'])."<p>";
|
||||
if ($config['debug']) echo "data:<br>".htmlspecialchars($response['data'])."<p>";
|
||||
|
||||
|
||||
// log response
|
||||
if ($config['httpclientlog'])
|
||||
{
|
||||
$log = fopen('httpClient.log', 'a');
|
||||
fwrite($log, headers_to_string($response['header']));
|
||||
fclose($log);
|
||||
}
|
||||
|
||||
// verify status code
|
||||
if ($resp->getStatusCode() != 200)
|
||||
{
|
||||
$response['error'] = 'Server returned wrong status: ' . $resp->getStatusCode();
|
||||
$response['error'] .= " Reason: " . $resp->getReasonPhrase();
|
||||
return $response;
|
||||
}
|
||||
|
||||
$response['success'] = true;
|
||||
// @todo i'm not sure on the side-effects of setting the previous requested URL as referer
|
||||
// for the next, so disabled for now. might be something to investigate...
|
||||
//$referer = $url;
|
||||
|
||||
// commit successful request to cache
|
||||
if ($cache)
|
||||
{
|
||||
putHTTPcache($url.$post, $response);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print all header info using echo
|
||||
* @param response Object homepage Psr7\Response
|
||||
*/
|
||||
function echoHeaders($headers)
|
||||
{
|
||||
foreach ($headers as $name => $values) {
|
||||
echo $name . ': ' . implode(', ', $values) . "<br>";
|
||||
}
|
||||
}
|
||||
|
||||
function headers_to_string($headers)
|
||||
{
|
||||
$result = '';
|
||||
foreach ($headers as $name => $values) {
|
||||
$result .= $name . ': ' . implode(', ', $values) . "\n";
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads an URL to the given local file
|
||||
*
|
||||
* @param string $url URL to download
|
||||
* @param string $local Full path to save to
|
||||
* @return bool true on succes else false
|
||||
*/
|
||||
function download($url, $local)
|
||||
{
|
||||
$resp = httpClient($url);
|
||||
|
||||
if (!$resp['success'])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return(@file_put_contents($local, $resp['data']) !== false);
|
||||
}
|
||||
|
||||
?>
|
||||
68
videodb/core/ids.php
Normal file
68
videodb/core/ids.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* IDS setup
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: ids.php,v 1.2 2010/02/01 22:38:42 andig2 Exp $
|
||||
*/
|
||||
|
||||
// set the include path properly for PHPIDS
|
||||
set_include_path(
|
||||
get_include_path()
|
||||
. PATH_SEPARATOR
|
||||
. './lib/'
|
||||
);
|
||||
|
||||
if (!session_id()) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
require_once 'IDS/Init.php';
|
||||
|
||||
try {
|
||||
$init = IDS_Init::init(dirname(__FILE__) . '/../lib/IDS/Config/Config.ini');
|
||||
$init->config['General']['base_path'] = dirname(__FILE__) . '/../lib/IDS/';
|
||||
$init->config['General']['use_base_path'] = true;
|
||||
$init->config['Caching']['caching'] = 'file';
|
||||
|
||||
$request = array(
|
||||
'GET' => $_GET,
|
||||
'POST' => $_POST,
|
||||
'COOKIE' => $_COOKIE
|
||||
);
|
||||
|
||||
$ids = new IDS_Monitor($request, $init);
|
||||
|
||||
$result = $ids->run();
|
||||
if (!$result->isEmpty() && $result->getImpact() > 50)
|
||||
{
|
||||
require_once 'IDS/Log/Database.php';
|
||||
require_once 'IDS/Log/Composite.php';
|
||||
$compositeLog = new IDS_Log_Composite();
|
||||
$compositeLog->addLogger(
|
||||
IDS_Log_Database::getInstance($init)
|
||||
);
|
||||
$compositeLog->execute($result);
|
||||
|
||||
$hta = @file_get_contents('.htaccess');
|
||||
if (preg_match('/(.+?)^(allow from all.*)/ms', $hta, $m))
|
||||
{
|
||||
$addr = $_SERVER['REMOTE_ADDR'];
|
||||
|
||||
// block whole subnet
|
||||
$addr = implode('.', array_slice(explode('.', $addr), 0, 3));
|
||||
|
||||
$hta = $m[1] . 'deny from '.$addr."\n" . $m[2];
|
||||
@file_put_contents('.htaccess', $hta);
|
||||
}
|
||||
|
||||
header("HTTP/1.0 403 Forbidden");
|
||||
die('Your IP has been blocked.<br/>To find out why visit <a href="http://sourceforge.net/mailarchive/forum.php?forum_name=videodb-devel">http://sourceforge.net/mailarchive/forum.php?forum_name=videodb-devel</a>');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
//this shouldn't happen and if it does you don't want the notification public.
|
||||
}
|
||||
|
||||
?>
|
||||
326
videodb/core/install.core.php
Normal file
326
videodb/core/install.core.php
Normal file
@@ -0,0 +1,326 @@
|
||||
<?php
|
||||
/**
|
||||
* Installer functions
|
||||
*
|
||||
* Create database, tables and config file
|
||||
*
|
||||
* @package Setup
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: install.core.php,v 1.11 2010/02/18 15:15:37 andig2 Exp $
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Build formatted message string for html output
|
||||
*
|
||||
* @param string $msg Message to print
|
||||
* @param string $color Color code for <div> tag
|
||||
* @param boolean $print If true, output directly, else append to message string
|
||||
*/
|
||||
function showmessage($msg, $color, $print = false)
|
||||
{
|
||||
global $message;
|
||||
|
||||
if ($msg) $msg = "<span style='color: $color'>$msg</span><br/><br/>\n";
|
||||
if ($print)
|
||||
{
|
||||
// print directly
|
||||
echo $msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
// return
|
||||
$message .= $msg;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare formatted error message for output
|
||||
*
|
||||
* @param string $msg Message to print
|
||||
* @param boolean $print If true, output directly, else append to message string
|
||||
*/
|
||||
function error($msg, $print = false)
|
||||
{
|
||||
showmessage($msg, 'red', $print);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare formatted warning message for output
|
||||
*
|
||||
* @param string $msg Message to print
|
||||
* @param boolean $print If true, output directly, else append to message string
|
||||
*/
|
||||
function warn($msg, $print = false)
|
||||
{
|
||||
showmessage($msg, 'orange', $print);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare formatted info message for output
|
||||
*
|
||||
* @param string $msg Message to print
|
||||
* @param boolean $print If true, output directly, else append to message string
|
||||
*/
|
||||
function info($msg, $print = false)
|
||||
{
|
||||
showmessage($msg, 'green', $print);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recursively delete files from directory
|
||||
* used for Smarty cache cleanup during installation
|
||||
*
|
||||
* @param string $dir Directory name
|
||||
* @param boolean $recursive Recurse into subfolders
|
||||
*/
|
||||
function delete_files($dir, $recursive = false)
|
||||
{
|
||||
if ($dh = @opendir($dir))
|
||||
{
|
||||
while (($file = readdir($dh)) !== false)
|
||||
{
|
||||
// next if . or ..
|
||||
if (preg_match("/^\.\.?$/", $file)) continue;
|
||||
|
||||
// recursion?
|
||||
if (is_dir("$dir/$file"))
|
||||
{
|
||||
if ($recursive) delete_files("$dir/$file", $recursive);
|
||||
}
|
||||
else
|
||||
{
|
||||
// delete file
|
||||
unlink("$dir/$file");
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
|
||||
if ($recursive) rmdir($dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse config file and replace settings according
|
||||
* to associate array parameter
|
||||
*
|
||||
* @param array new parameter values
|
||||
*/
|
||||
function parse_config($vars)
|
||||
{
|
||||
$raw = null;
|
||||
|
||||
if ($file = @file_get_contents(CONFIG_FILE)) {
|
||||
$raw = explode("\n", $file);
|
||||
|
||||
for ($i = 0; $i < count($raw); $i++)
|
||||
{
|
||||
foreach ($vars as $name => $val)
|
||||
{
|
||||
if (preg_match("/^(.*?'$name'.*?=\s*)(.*?)(\s*;.*?)$/", $raw[$i], $matches))
|
||||
{
|
||||
# quoted?
|
||||
if (preg_match("/^[\"'].*[\"']$/", $matches[2])) $val = "'$val'";
|
||||
$matches[2] = $val;
|
||||
$raw[$i] = join('', array_slice($matches,1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fallback if config file is empty or invalid
|
||||
if (count($raw) < 4)
|
||||
{
|
||||
$raw = array('<?php');
|
||||
foreach ($vars as $name => $val)
|
||||
{
|
||||
$line = "\$config['$name'] = ";
|
||||
$line .= (is_numeric($val)) ? "$val;" : "'$val';";
|
||||
$raw[] = $line;
|
||||
}
|
||||
$raw[] = '?>';
|
||||
}
|
||||
|
||||
return join("\n", $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse database upgrade SQL file and
|
||||
* build associate array of upgrade sql steps per version
|
||||
*
|
||||
* @return array associative array of upgrade steps
|
||||
*/
|
||||
function parse_upgrades($upgrade_file)
|
||||
{
|
||||
$cfg = file_get_contents($upgrade_file);
|
||||
$raw = preg_split('/# changes in DB version /i', $cfg);
|
||||
|
||||
// loop through list of db upgrades split by comments
|
||||
foreach ($raw as $str)
|
||||
{
|
||||
// upgrade version comment found?
|
||||
if (preg_match('/(\d+)\s*#\s*(.+)/s', $str, $m))
|
||||
{
|
||||
$key = $m[1];
|
||||
$str = $m[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (empty($upgrades['3']))
|
||||
{
|
||||
// this is the first supported version
|
||||
$key = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
// unexpected first db upgrade version found
|
||||
trigger_error('Could not parse <a href="'.$upgrade_file.'">'.$upgrade_file.'</a>, please fix!', E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
$upgrades["$key"] = $str;
|
||||
}
|
||||
return $upgrades;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function for adding prefix to table name in FROM clauses- extended to include sub queries
|
||||
*
|
||||
* $match[2] is table
|
||||
*/
|
||||
function sql_add_prefix($match)
|
||||
{
|
||||
global $db_prefix;
|
||||
|
||||
$match[2] = preg_replace('/(\'?\w+\'?)(\s*\w*)(,?)/', "`$db_prefix$1`$2$3", $match[2]);
|
||||
return join(array_slice($match, 1, 3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix table names with table name prefix
|
||||
* This will only work for simple queries with known structure (createtables.sql, updatedb.sql)
|
||||
*
|
||||
* @param string SQL command
|
||||
* @return string SQL command with new table names
|
||||
*/
|
||||
function prefix_query($query)
|
||||
{
|
||||
global $db_prefix;
|
||||
|
||||
$query = preg_replace('/((CREATE|ALTER)\s+TABLE\s+(IF\s+NOT\s+EXISTS\s+)?)`?(\w+)`?/', "$1`$db_prefix$4`", $query);
|
||||
$query = preg_replace('/((INSERT(\s+IGNORE)?|REPLACE)\s+INTO\s+)`?(\w+)`?/', "$1`$db_prefix$4`", $query);
|
||||
|
||||
$query = preg_replace('/(DROP\s+TABLE\s+(IF\s+EXISTS\s+)?)`?(\w+)`?(;?)/', "$1`$db_prefix$3`$4", $query);
|
||||
// changed to allow only replace if sql update to row
|
||||
$query = preg_replace('/(UPDATE\s+)`?(\w+)`?(\s+SET\s+)`?/', "$1`$db_prefix$2`$3", $query);
|
||||
|
||||
// FROM matches at beginning of string or subquery opened by left bracket
|
||||
$query = preg_replace_callback( "/(\s+FROM\s+)(.*?)((\s+WHERE|ORDER|LEFT|RIGHT|OUTER|JOIN)|\)|$)/msi", 'sql_add_prefix', $query);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run multiple comma-separated queries
|
||||
*
|
||||
* @todo Split SQL queries more cleverly (currently not needed)
|
||||
*
|
||||
* @param string SQL commands
|
||||
* @param ressource database handle
|
||||
* @return mixed result array or false
|
||||
*/
|
||||
function runSQL($sql, $dbh, $verify = false)
|
||||
{
|
||||
$result = true;
|
||||
foreach (explode(';', $sql) as $query)
|
||||
{
|
||||
$query = trim($query);
|
||||
if (empty($query)) continue;
|
||||
|
||||
$query = prefix_query($query);
|
||||
$result = mysqli_query($dbh, $query);
|
||||
|
||||
// error running SQL?
|
||||
if ($result === false)
|
||||
{
|
||||
$sql = $query;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// error running SQL?
|
||||
if ($result === false)
|
||||
{
|
||||
if ($verify)
|
||||
{
|
||||
error("Error in SQL statement:<br/>".
|
||||
"<code>$sql</code><br/>".mysqli_error($dbh));
|
||||
}
|
||||
}
|
||||
|
||||
// result set returned?
|
||||
elseif ($result !== true)
|
||||
{
|
||||
$res = array();
|
||||
|
||||
for ($i=0; $i < mysqli_num_rows($result); $i++)
|
||||
{
|
||||
$res[] = mysqli_fetch_assoc($result);
|
||||
}
|
||||
mysqli_free_result($result);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run all upgrade scripts passed as array step by step
|
||||
*
|
||||
* @param array $upgrade_steps Associative array of upgrade sql steps
|
||||
*/
|
||||
function db_upgrade($upgrade_steps)
|
||||
{
|
||||
global $dbh, $version;
|
||||
global $step;
|
||||
|
||||
foreach ($upgrade_steps as $ver => $sql)
|
||||
{
|
||||
#info("Upgrading to database version: $ver");
|
||||
$sql = preg_replace('/#.*\n/m','',$sql);
|
||||
|
||||
if (runSQL($sql, $dbh) === false)
|
||||
{
|
||||
error('Error upgrading database, try full install instead of upgrade:<br/>'.mysqli_error($dbh).
|
||||
'<br/><br/><pre>'.$sql.'</pre>');
|
||||
return false;
|
||||
}
|
||||
|
||||
// perform additional upgrade steps
|
||||
$upgrade_file = "./install/upgrade_v$ver.php";
|
||||
if (file_exists($upgrade_file))
|
||||
{
|
||||
$result = include_once($upgrade_file);
|
||||
if (!$result) return($false);
|
||||
}
|
||||
|
||||
// add DB version information- this will make the separate update statement in upgrade.sql obsolete
|
||||
runSQL("REPLACE INTO config (opt,value) VALUES ('dbversion', ".$ver.");", $dbh);
|
||||
# runSQL("update config set value=25 where opt='dbversion'");
|
||||
|
||||
$version = $ver;
|
||||
}
|
||||
|
||||
// perform generic upgrade validation
|
||||
$upgrade_file = "./install/upgrade.php";
|
||||
if (file_exists($upgrade_file))
|
||||
{
|
||||
$result = include_once($upgrade_file);
|
||||
if (!$result) return($false);
|
||||
}
|
||||
|
||||
return $version;
|
||||
}
|
||||
|
||||
?>
|
||||
278
videodb/core/output.php
Normal file
278
videodb/core/output.php
Normal file
@@ -0,0 +1,278 @@
|
||||
<?php
|
||||
/**
|
||||
* Output functions
|
||||
*
|
||||
* Functions for HTML output generation (Not templates!)
|
||||
*
|
||||
* @todo Check if this can be moved to smarty plugins
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: output.php,v 1.29 2013/04/19 07:55:58 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
|
||||
/**
|
||||
* Return list of valid genres from db
|
||||
*/
|
||||
function getGenres()
|
||||
{
|
||||
$SELECT = 'SELECT id, name
|
||||
FROM '.TBL_GENRES.'
|
||||
ORDER BY name';
|
||||
$result = runSQL($SELECT);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display genre checkboxes
|
||||
*
|
||||
* @param array $selected selected genre IDs
|
||||
* @return string HTML for genre checkboxes
|
||||
*/
|
||||
function out_genres($selected)
|
||||
{
|
||||
global $config;
|
||||
|
||||
$result = getGenres();
|
||||
$out = '<table class="genreselect"><tr>';
|
||||
|
||||
// get list of adult genres
|
||||
$adultgenres = array();
|
||||
if ($config['multiuser'] && !check_permission(PERM_ADULT))
|
||||
{
|
||||
$adultgenres = get_adult_genres();
|
||||
}
|
||||
|
||||
$row = 0;
|
||||
foreach ($result as $res)
|
||||
{
|
||||
// don't show adult genres if no permissions
|
||||
if (in_array($res['id'], $adultgenres)) continue;
|
||||
|
||||
$out .= '<td nowrap="nowrap">';
|
||||
$out .= '<input type="checkbox" name="genres[]" id="genreid'.$res['id'].'" value="'.$res['id'].'"';
|
||||
if (@in_array ($res['id'], $selected))
|
||||
{
|
||||
$out .= ' checked="checked"';
|
||||
}
|
||||
$out .= '/>';
|
||||
$out .= '<label for="genreid'.$res['id'].'">'.$res['name'].'</label>';
|
||||
$out .= '</td>';
|
||||
if ((++$row % 5) == 0)
|
||||
{
|
||||
$out .= '</tr><tr>';
|
||||
}
|
||||
}
|
||||
$out .= '</tr></table>';
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate genres array for use with genre checkboxes
|
||||
*
|
||||
* @param array $selected selected genre IDs
|
||||
* @return string HTML for genre checkboxes
|
||||
*/
|
||||
function out_genres2($item_genres = null)
|
||||
{
|
||||
global $config;
|
||||
// get detailed genres
|
||||
$all_genres = getGenres();
|
||||
$adultgenres = array();
|
||||
if ($config['multiuser'] && !check_permission(PERM_ADULT)) {
|
||||
$adultgenres = get_adult_genres();
|
||||
}
|
||||
|
||||
$genres = array();
|
||||
foreach ($all_genres as $gen) {
|
||||
// don't show adult genres if no permissions
|
||||
if (in_array($gen['id'], $adultgenres)) continue;
|
||||
|
||||
// selected?
|
||||
if ($item_genres) $gen['checked'] = (@in_array($gen['id'], $item_genres)) ? 1 : 0;
|
||||
|
||||
$genres[] = $gen;
|
||||
}
|
||||
|
||||
return($genres);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display selectbox with available Mediatypes
|
||||
*
|
||||
* @todo is this still used? can it be replaced by template code?
|
||||
* @author <rob@robvonk.com>
|
||||
* @return string HTML of selectbox
|
||||
*/
|
||||
function out_mediatypes($prefix = null)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// select mediatypes
|
||||
$SELECT = 'SELECT id, name
|
||||
FROM '.TBL_MEDIATYPES.'
|
||||
ORDER BY name';
|
||||
$result = runSQL($SELECT);
|
||||
|
||||
// build associative array
|
||||
# array('0' => '') +
|
||||
$mediatypes = is_array($prefix) ? $prefix : array();
|
||||
$mediatypes = $mediatypes + array_associate($result, 'id', 'name');
|
||||
|
||||
return $mediatypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* All available language flags for config screen
|
||||
*
|
||||
* @param array $flags selected flags
|
||||
* @return string HTML of Languageflags
|
||||
*/
|
||||
function out_languageflags($flags)
|
||||
{
|
||||
global $config;
|
||||
|
||||
$out = '';
|
||||
$count = 1;
|
||||
|
||||
if (($dh = @opendir('./'.$config['templatedir'].'images/flags')) || ($dh = opendir('./images/flags')))
|
||||
{
|
||||
while (($file = readdir($dh)) !== false)
|
||||
{
|
||||
if (preg_match("/(.*)\.gif$/", $file, $matches))
|
||||
{
|
||||
$CHECK= (in_array($matches[1], $flags)) ? 'checked="checked"' : '';
|
||||
$out .= '<input type="checkbox" name="languages[]" '.$CHECK.' id="flag_'.$matches[1].'" value="'.$matches[1].'" />';
|
||||
$out .= '<label for="flag_'.$matches[1].'">';
|
||||
$out .= '<img src="'.img('flags/'.$matches[1].'.gif').'" width="30" height="15" alt="'.ucwords($matches[1]).'" title="'.ucwords($matches[1]).'" />';
|
||||
$out .= '</label> ';
|
||||
if ($count++%4 == 0) $out.='<br />';
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of owners names/ids with valid permissions for use in edit/index/search templates
|
||||
*
|
||||
* @author <cpuidle@gmx.de>
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $prefix Predefined additional Array entries
|
||||
* @param string $permission Honor permissions for selectbox
|
||||
* @return array Array with keys=ownernames and values=ownerids
|
||||
*/
|
||||
function out_owners($prefix = null, $permission = false, $keyIsId = false)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// all permissions available if admin
|
||||
if (check_permission(PERM_ADMIN)) $permission = false;
|
||||
|
||||
// hide guest if he/she can't login
|
||||
$WHERES = ($config['denyguest']) ? " AND B.id != ".$config['guestid'] : '';
|
||||
|
||||
// select user ids- if permissions are required and no all access given, this is done against xrefs
|
||||
if ($permission && !check_permission($permission))
|
||||
{
|
||||
// xref permissions
|
||||
// TODO use cached permission table instead
|
||||
$SELECT = 'SELECT DISTINCT(B.name) AS name, B.id
|
||||
FROM '.TBL_PERMISSIONS.' A, '.TBL_USERS.' B
|
||||
WHERE A.to_uid = B.id
|
||||
AND A.from_uid = '.get_current_user_id().'
|
||||
AND (A.permissions & '.$permission.') = '.$permission.$WHERES.'
|
||||
ORDER BY name';
|
||||
}
|
||||
else
|
||||
{
|
||||
// all users +/- guest
|
||||
$SELECT = 'SELECT B.id, B.name
|
||||
FROM '.TBL_USERS.' B
|
||||
WHERE 1=1 '.$WHERES.'
|
||||
ORDER BY B.name';
|
||||
}
|
||||
$result = runSQL($SELECT);
|
||||
|
||||
$key = ($keyIsId) ? 'id' : 'name';
|
||||
|
||||
// build associative array
|
||||
$owners = is_array($prefix) ? $prefix : array();
|
||||
$owners = $owners + array_unique(array_associate($result, $key, 'name'));
|
||||
|
||||
return $owners;
|
||||
}
|
||||
|
||||
/**
|
||||
* MySQL-compatible list of owner ids with required access permission
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
function get_owner_ids($permission)
|
||||
{
|
||||
foreach($_SESSION['vdb']['permissions']['to_uid'] as $to_uid => $perm)
|
||||
{
|
||||
if ($permission & $perm) $ids[] = $to_uid;
|
||||
}
|
||||
|
||||
return (count($ids)) ? join(',', $ids) : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Present a size (in bytes) as a human-readable value
|
||||
*
|
||||
* @author http://php.net
|
||||
*
|
||||
* @param int $size size (in bytes)
|
||||
* @param int $precision number of digits after the decimal point
|
||||
* @return string
|
||||
*/
|
||||
function sizetostring($size, $precision = 0)
|
||||
{
|
||||
$sizes = array('YB', 'ZB', 'EB', 'PB', 'TB', 'GB', 'MB', 'kB', 'B');
|
||||
$total = count($sizes);
|
||||
|
||||
while($total-- && $size > 1024) $size /= 1024;
|
||||
return round($size, $precision).$sizes[$total];
|
||||
}
|
||||
|
||||
// @todo unused
|
||||
function img_avg_color($filename, $format=0)
|
||||
{
|
||||
// networked file
|
||||
if (preg_match('/^http/i', $imgurl)) return(FALSE);
|
||||
|
||||
// not a valid image
|
||||
if (!list($width, $height) = @getimagesize($filename)) return(FALSE);
|
||||
|
||||
// resample
|
||||
switch (exif_imagetype($filename)) {
|
||||
case 2:
|
||||
$img = imagecreatefromjpeg($filename);
|
||||
break;
|
||||
case 3:
|
||||
$img = imagecreatefrompng($filename);
|
||||
break;
|
||||
case 1:
|
||||
$img = imagecreatefromgif($filename);
|
||||
break;
|
||||
}
|
||||
|
||||
$tmp = imagecreatetruecolor(1, 1);
|
||||
if (!imagecopyresampled($tmp, $img, 0, 0, 0, 0, 1, 1, $width, $height)) return(FALSE);
|
||||
|
||||
$rgb = imagecolorat($tmp, 0, 0);
|
||||
$r = dechex($rgb >> 16);
|
||||
$g = dechex($rgb >> 8 & 0xFF);
|
||||
$b = dechex($rgb & 0xFF);
|
||||
|
||||
return('#'.$r.$g.$b);
|
||||
}
|
||||
|
||||
?>
|
||||
457
videodb/core/pdf.php
Normal file
457
videodb/core/pdf.php
Normal file
@@ -0,0 +1,457 @@
|
||||
<?php
|
||||
/**
|
||||
* PDF Export functions
|
||||
*
|
||||
* Allows exporting movies to PDF
|
||||
* Requires FPDF libaray (http://www.fpdf.org)
|
||||
*
|
||||
* @package Core
|
||||
* @link http://www.fpdf.org
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @version $Id: pdf.php,v 1.36 2013/03/15 16:42:46 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './core/cache.php';
|
||||
require_once './core/export.core.php';
|
||||
require_once './engines/engines.php';
|
||||
require_once './core/VariableStream.class.php';
|
||||
|
||||
define('FPDF', './vendor/setasign/fpdf');
|
||||
define('FPDF_FONTPATH', FPDF.'/font/');
|
||||
|
||||
require_once FPDF.'/fpdf.php';
|
||||
require_once './lib/fpdf2file/fpdf2file.php';
|
||||
|
||||
/**
|
||||
* Copied from FPDF tutorial 3
|
||||
* enhanced with memory image creation for gif->png conversion
|
||||
*
|
||||
* @link http://www.fpdf.org/?go=script&id=45
|
||||
*/
|
||||
class PDF extends FPDF2File
|
||||
{
|
||||
var $B;
|
||||
var $I;
|
||||
var $U;
|
||||
var $HREF;
|
||||
var $GDCount = 0;
|
||||
var $Scale = 0; // dont rescale images
|
||||
|
||||
function FPDF2File($orientation='P', $unit='mm', $format='A4')
|
||||
{
|
||||
//Call parent constructor
|
||||
$this->FPDF($orientation,$unit,$format);
|
||||
//Initialization
|
||||
$this->B=0;
|
||||
$this->I=0;
|
||||
$this->U=0;
|
||||
$this->HREF='';
|
||||
}
|
||||
|
||||
function GDImage($file, $x, $y, $im, $w=0, $h=0, $link='', $type='png')
|
||||
{
|
||||
// ouput the GD image $im
|
||||
ob_start();
|
||||
$func = 'image'.$type; // image creation function according to type
|
||||
$func($im);
|
||||
$data = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
// create file-unique variable name to not duplicate images for pdf
|
||||
$file = (empty($file)) ? $this->GDCount++ : preg_replace('/[\s\/\.]/', '_', $file);
|
||||
$name = 'pdf_image_'.$file;
|
||||
$GLOBALS[$name] = $data;
|
||||
|
||||
// call Image using in-memory PNG file
|
||||
parent::Image('var://'.$name, $x, $y, $w, $h, $type, $link);
|
||||
}
|
||||
|
||||
function Image($file, $x=null, $y=null, $w=0, $h=0, $ext='', $link='')
|
||||
{
|
||||
global $config;
|
||||
|
||||
$image_types = array(1 => 'gif', 2 => 'jpg', 3 => 'png', 6 => 'bmp');
|
||||
|
||||
list($width, $height, $ext, $attr) = getimagesize($file);
|
||||
$ext = $image_types[$ext];
|
||||
|
||||
// find image loading function
|
||||
switch($ext)
|
||||
{
|
||||
case 'jpg': $func = 'jpeg'; break;
|
||||
case 'bmp': $func = 'wbmp'; break;
|
||||
default: $func = $ext;
|
||||
}
|
||||
$func = 'imagecreatefrom'.$func;
|
||||
|
||||
// check if loading functions exists (especially for gif support)
|
||||
$im = (function_exists($func)) ? $func($file) : imagecreatetruecolor(1,1);
|
||||
|
||||
// scaling requested?
|
||||
if ($this->Scale)
|
||||
{
|
||||
$this->max_width = round($this->Scale * $config['pdf_image_max_width']);
|
||||
$this->max_height = round($this->Scale * $config['pdf_image_max_height']);
|
||||
|
||||
$scale = min($this->max_width/$width, $this->max_height/$height);
|
||||
$thumb_x = round($width * $scale);
|
||||
$thumb_y = round($height * $scale);
|
||||
}
|
||||
|
||||
// scaling requied?
|
||||
if (($this->Scale) && (($thumb_x != $width) || ($thumb_y != $height)))
|
||||
{
|
||||
// create white truecolor image (in case original is transparent)
|
||||
$target = imagecreatetruecolor($thumb_x, $thumb_y);
|
||||
$white = imagecolorallocate($target, 255, 255, 255);
|
||||
imagefilledrectangle($target, 0, 0, $thumb_x, $thumb_y, $white);
|
||||
imagecopyresampled($target, $im, 0,0, 0,0, $thumb_x,$thumb_y, $width,$height);
|
||||
$this->GDImage($file, $x, $y, $target, $w, $h, $link, 'jpeg'); // change to png if you receive acrobat errors
|
||||
imagedestroy($target);
|
||||
}
|
||||
elseif ($ext == 'gif') {
|
||||
// pdf doesn't support interlaced images
|
||||
if (imageinterlace($im))
|
||||
{
|
||||
// claim non-interlaced image
|
||||
imageinterlace($im, false);
|
||||
}
|
||||
|
||||
$this->GDImage($file, $x, $y, $im, $w, $h, $link);
|
||||
}
|
||||
else {
|
||||
parent::Image($file, $x, $y, $w, $h, $ext, $link);
|
||||
}
|
||||
|
||||
imagedestroy($im);
|
||||
}
|
||||
|
||||
function VerifyFont($font, $mode = '')
|
||||
{
|
||||
$default_fonts = array('Arial', 'Courier', 'Helvetica', 'Times');
|
||||
|
||||
if (!in_array($font, $default_fonts))
|
||||
{
|
||||
if ($mode)
|
||||
$this->AddFont($font, 'B', strtolower($font).'b.php');
|
||||
else
|
||||
$this->AddFont($font);
|
||||
}
|
||||
}
|
||||
|
||||
function WriteHTML($html)
|
||||
{
|
||||
global $config;
|
||||
|
||||
//HTML parser
|
||||
$html = str_replace("\n",' ',$html);
|
||||
$a = preg_split('/<(.*)>/U',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
|
||||
foreach($a as $i=>$e)
|
||||
{
|
||||
if($i%2==0)
|
||||
{
|
||||
//Text
|
||||
if($this->HREF)
|
||||
$this->PutLink($this->HREF,$e);
|
||||
else
|
||||
$this->Write((int)$config['pdf_font_size'] / 2.5, $e);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Tag
|
||||
if($e[0]=='/')
|
||||
$this->CloseTag(strtoupper(substr($e,1)));
|
||||
else
|
||||
{
|
||||
//Extract attributes
|
||||
$a2=explode(' ',$e);
|
||||
$tag=strtoupper(array_shift($a2));
|
||||
$attr=array();
|
||||
foreach($a2 as $v)
|
||||
if(ereg('^([^=]*)=["\']?([^"\']*)["\']?$',$v,$a3))
|
||||
$attr[strtoupper($a3[1])]=$a3[2];
|
||||
$this->OpenTag($tag,$attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function OpenTag($tag, $attr)
|
||||
{
|
||||
global $config;
|
||||
|
||||
//Opening tag
|
||||
if($tag=='B' or $tag=='I' or $tag=='U')
|
||||
$this->SetStyle($tag,true);
|
||||
if($tag=='A')
|
||||
$this->HREF=$attr['HREF'];
|
||||
if($tag=='BR')
|
||||
$this->Ln((int)$config['pdf_font_size'] / 2);
|
||||
}
|
||||
|
||||
function CloseTag($tag)
|
||||
{
|
||||
//Closing tag
|
||||
if($tag=='B' or $tag=='I' or $tag=='U')
|
||||
$this->SetStyle($tag,false);
|
||||
if($tag=='A')
|
||||
$this->HREF='';
|
||||
}
|
||||
|
||||
function SetStyle($tag, $enable)
|
||||
{
|
||||
//Modify style and select corresponding font
|
||||
$this->$tag+=($enable ? 1 : -1);
|
||||
$style='';
|
||||
foreach(array('B','I','U') as $s)
|
||||
if($this->$s>0)
|
||||
$style.=$s;
|
||||
$this->SetFont('',$style);
|
||||
}
|
||||
|
||||
function PutLink($URL, $txt)
|
||||
{
|
||||
global $config;
|
||||
|
||||
//Put a hyperlink
|
||||
$this->SetTextColor(0,0,255);
|
||||
$this->SetStyle('U',true);
|
||||
$this->Write((int)$config['pdf_font_size'] / 2, $txt, $URL);
|
||||
$this->SetStyle('U',false);
|
||||
$this->SetTextColor(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Olivier <oliver@fpdf.org>
|
||||
* @license Freeware
|
||||
*/
|
||||
function WordWrap(&$text, $maxwidth)
|
||||
{
|
||||
$text = trim($text);
|
||||
if ($text==='')
|
||||
return 0;
|
||||
$space = $this->GetStringWidth(' ');
|
||||
$lines = explode("\n", $text);
|
||||
$text = '';
|
||||
$count = 0;
|
||||
|
||||
foreach ($lines as $line)
|
||||
{
|
||||
$words = preg_split('/ +/', $line);
|
||||
$width = 0;
|
||||
|
||||
foreach ($words as $word)
|
||||
{
|
||||
$wordwidth = $this->GetStringWidth($word);
|
||||
if ($width + $wordwidth <= $maxwidth)
|
||||
{
|
||||
$width += $wordwidth + $space;
|
||||
$text .= $word.' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$width = $wordwidth + $space;
|
||||
$text = rtrim($text)."\n".$word.' ';
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
$text = rtrim($text)."\n";
|
||||
$count++;
|
||||
}
|
||||
$text = rtrim($text);
|
||||
return $count;
|
||||
}
|
||||
|
||||
function SaveFile($filename)
|
||||
{
|
||||
FPDF::Output('D', 'videoDB.pdf', $isUTF8=false);
|
||||
readfile($filename);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return image name for representing the media type
|
||||
*/
|
||||
function getMediaImage($mediatype)
|
||||
{
|
||||
if (preg_match("/^(DVD([+-]R)?|DivX|CD|VCD|SVCD|VHS|BLU-RAY|AVCHD|HDD|HD-DVD)/i", $mediatype, $matches))
|
||||
{
|
||||
$type_image = strtolower($matches[1]).'.png';
|
||||
}
|
||||
else $type_image = '';
|
||||
|
||||
return $type_image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export PDF document
|
||||
*
|
||||
* @param string $where WHERE clause for SQL statement
|
||||
*/
|
||||
function pdfexport($WHERE)
|
||||
{
|
||||
global $config;
|
||||
|
||||
$ypos = $config['pdf_font_size']; // Match the font size for proper vertical offset
|
||||
$page_width = $config['pdf_page_width'];
|
||||
$margin = $config['pdf_margin'];
|
||||
$left_margin = $config['pdf_left_margin'];
|
||||
$right_margin = $config['pdf_right_margin'];
|
||||
$mediaimg_width = $config['pdf_image_media_width'];
|
||||
$font_size = $config['pdf_font_size'];
|
||||
|
||||
$image_height = $config['pdf_image_height'];
|
||||
$image_width = $config['pdf_image_width'];
|
||||
|
||||
$font_title = $config['pdf_font_title'];
|
||||
$font_plot = $config['pdf_font_plot'];
|
||||
|
||||
$text_length = $config['pdf_text_length'];
|
||||
|
||||
$tempfolder = cache_get_folder('');
|
||||
if ($config['cache_pruning']) cache_prune_folder($tempfolder, 3600, false, false, 'videodb*.pdf');
|
||||
$filename = $tempfolder.'videodb'.date('His',time()).'.pdf';
|
||||
|
||||
// setup pdf class
|
||||
$pdf = new PDF();
|
||||
$pdf->Open($filename);
|
||||
$pdf->VerifyFont($font_title);
|
||||
$pdf->VerifyFont($font_title, 'B');
|
||||
$pdf->VerifyFont($font_plot);
|
||||
$pdf->AddPage();
|
||||
$pdf->SetRightMargin($right_margin);
|
||||
|
||||
// add downscaling
|
||||
if (array_key_exists('pdf_scale', $config) && $config['pdf_scale'])
|
||||
{
|
||||
$pdf->Scale = $config['pdf_scale'];
|
||||
$pdf->max_width = $config['pdf_image_max_width'];
|
||||
$pdf->max_height= $config['pdf_image_max_height'];
|
||||
}
|
||||
|
||||
// get data
|
||||
$result = iconv_array('utf-8', 'iso-8859-1', exportData($WHERE));
|
||||
|
||||
$tech = array();
|
||||
|
||||
foreach ($result as $row)
|
||||
{
|
||||
set_time_limit(300); // rise per movie execution timeout limit if safe_mode is not set in php.ini
|
||||
|
||||
$title = $row['title'];
|
||||
if ($row['subtitle']) $title .= ' - '.$row['subtitle'];
|
||||
if ($row['diskid'] || $row['mediatype'])
|
||||
{
|
||||
$title .= ' [';
|
||||
if ($row['mediatype']) $title .= $row['mediatype'] . ', ';
|
||||
if ($row['diskid']) $title .= $row['diskid'];
|
||||
$title = preg_replace('/, $/', '', $title) . ']';
|
||||
}
|
||||
|
||||
// get drilldown url for image
|
||||
$imdb = $row['imdbID'];
|
||||
$link = ($imdb) ? engineGetContentUrl($imdb, engineGetEngine($imdb)) : '';
|
||||
|
||||
// title
|
||||
$pdf->SetFont($font_title, 'B', $font_size);
|
||||
$pdf->SetXY($left_margin + $image_width + $margin, $ypos);
|
||||
$pdf->Cell(0, 0, $title, 0,1, 'L',0,$link);
|
||||
|
||||
// [muddle] technical details
|
||||
unset($tech['Y']);
|
||||
if ($row['year']) {
|
||||
$tech['Y'] = "Year: ".$row['year'];
|
||||
}
|
||||
|
||||
unset($tech['V']);
|
||||
if ($row['video_width'] and $row['video_height'])
|
||||
{
|
||||
$vw = $row['video_width'];
|
||||
$vh = $row['video_height'];
|
||||
$tech['V'] = "Video: ";
|
||||
|
||||
if ($vw>1920) {
|
||||
$tech['V'] .= "UHD ".$vw."x".$vh;
|
||||
} elseif ($vw>1280) {
|
||||
$tech['V'] .= "HD 1080p";
|
||||
} elseif ($vw==1280 or $vh==720) {
|
||||
$tech['V'] .= "HD 720p";
|
||||
} elseif ($vw==720 or $vw==704) {
|
||||
$tech['V'] .= "SD ";
|
||||
if ($vh==480) {
|
||||
$tech['V'] .= "NTSC";
|
||||
} elseif ($vh==576) {
|
||||
$tech['V'] .= "PAL";
|
||||
} else {
|
||||
$tech['V'] .= $vw."x".$vh;
|
||||
}
|
||||
} else {
|
||||
$tech['V'] .= "LORES ".$vw."x".$vh;
|
||||
}
|
||||
}
|
||||
|
||||
unset($tech['A']);
|
||||
if ($row['audio_codec']) {
|
||||
$tech['A'] = "Audio: ".$row['audio_codec'];
|
||||
}
|
||||
|
||||
unset($tech['D']);
|
||||
if ($row['created']) {
|
||||
$tech['D'] = "Date: ".$row['created'];
|
||||
}
|
||||
|
||||
$techinfo = implode(", ", $tech);
|
||||
|
||||
$pdf->SetFont($font_title, 'B', $font_size-3);
|
||||
$pdf->SetXY($left_margin + $image_width + $margin, $ypos+ 4);
|
||||
$pdf->Cell(0, 0, $techinfo, 0,1, 'L',0);
|
||||
|
||||
// plot
|
||||
$plot = leftString($row['plot'], $text_length);
|
||||
$pdf->SetFont($font_plot, '', $font_size-1);
|
||||
$pdf->SetXY($left_margin + $image_width + $margin, $ypos+3 +3);
|
||||
$pdf->SetLeftMargin($left_margin + $image_width + $margin);
|
||||
$pdf->WriteHTML($plot);
|
||||
|
||||
// image
|
||||
$file = getThumbnail($row['imgurl']);
|
||||
if (preg_match('/^img.php/', $file)) $file = img();
|
||||
|
||||
// image file present?
|
||||
if ($file)
|
||||
{
|
||||
$pdf->Image($file, $left_margin, $ypos-2, $image_width, $image_height, '', $link);
|
||||
}
|
||||
|
||||
// add mediatype image
|
||||
if ($type_image = getMediaImage($row['mediatype']))
|
||||
{
|
||||
$pdf->Image('./images/media/'.$type_image, $page_width - $mediaimg_width - $right_margin, $ypos - 2, $mediaimg_width, 0, '', '');
|
||||
}
|
||||
|
||||
// new position
|
||||
$ypos += $margin;
|
||||
if ($file or $plot)
|
||||
{
|
||||
$ypos += max($image_height, $font_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
$ypos += $font_size;
|
||||
}
|
||||
|
||||
if ($ypos > 250)
|
||||
{
|
||||
$ypos = $config['pdf_font_size'];
|
||||
$pdf->AddPage();
|
||||
}
|
||||
}
|
||||
|
||||
$pdf->SaveFile($filename);
|
||||
|
||||
// get rid of temp file
|
||||
@unlink($filename);
|
||||
}
|
||||
|
||||
?>
|
||||
182
videodb/core/queryparser.php
Normal file
182
videodb/core/queryparser.php
Normal file
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
/**
|
||||
* Searchquerystring Parser
|
||||
*
|
||||
* Parses a search query into it's tokens kann detect + - AND OR NOT Operators
|
||||
* and Phrases.
|
||||
*
|
||||
* @todo remove german errorstrings, maybe handle umlauts and stuff...
|
||||
*
|
||||
* @package Search
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @version $Id: queryparser.php,v 1.9 2007/12/19 18:42:11 andig2 Exp $
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Querystringparser
|
||||
*
|
||||
* Parses a querystring into a datastructure
|
||||
*
|
||||
* @param string $query Querystring
|
||||
* @param string &$errors Stringreference to write errors back
|
||||
* @return array parsed querytokens
|
||||
*/
|
||||
function queryparser($query, &$errors)
|
||||
{
|
||||
$query = trim($query);
|
||||
/*
|
||||
// filter forbidden characters
|
||||
if (preg_match('/[^\w \.\(\)"\'*]/',$query))
|
||||
{
|
||||
$errors .= "Nicht erlaubte Zeichen wurden ignoriert\n";
|
||||
$query = preg_replace('/[^\w \.\(\)"\'*]/','',$query);
|
||||
}
|
||||
*/
|
||||
|
||||
$ops = array();
|
||||
$struct = array();
|
||||
$tokens = tokenizer($query);
|
||||
|
||||
// look through tokens
|
||||
while ($current = array_shift($tokens))
|
||||
{
|
||||
if (preg_match('/^(AND|OR|NOT)$/i', $current))
|
||||
{
|
||||
// token is operator
|
||||
$ops[] = strtoupper($current);
|
||||
}
|
||||
else
|
||||
{
|
||||
// token is searchword
|
||||
if (!count($ops))
|
||||
{
|
||||
// empty operator counts as AND
|
||||
$ops[] = 'AND';
|
||||
}
|
||||
|
||||
// clean invalid operators
|
||||
$cleanops = cleanoperators($ops, $errors);
|
||||
|
||||
// check wildcards
|
||||
$wild = '';
|
||||
if (substr($current,0,1) == '*') $wild .= 'l';
|
||||
if (substr($current, -1) == '*') $wild .= 'r';
|
||||
|
||||
$current = str_replace('*', '', $current);
|
||||
$struct[] = array('ops' => $cleanops,
|
||||
'token' => $current,
|
||||
'wildcard' => $wild);
|
||||
$ops = array();
|
||||
}
|
||||
}
|
||||
return $struct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Querystring tokenizer
|
||||
*
|
||||
* Parse string into array of tokens.
|
||||
* Honors literal expressions enclosed by "",
|
||||
* converts +/- to AND and NOT
|
||||
*
|
||||
* @param string Querystring
|
||||
* @return array All tokens of the Strings
|
||||
*/
|
||||
function tokenizer($qstring)
|
||||
{
|
||||
// replace +/- with AND and NOT
|
||||
$qstring = ' '.$qstring; // for following regexps
|
||||
$qstring = preg_replace('/(\s)-(\S)/', '\1NOT \2', $qstring);
|
||||
$qstring = preg_replace('/(\s)\+(\S)/', '\1AND \2', $qstring);
|
||||
$qstring = trim($qstring);
|
||||
|
||||
$tokens = array();
|
||||
$current = '';
|
||||
$sep = '\s';
|
||||
|
||||
for ($i=0; $i < strlen($qstring); $i++)
|
||||
{
|
||||
$char = $qstring[$i];
|
||||
|
||||
// match current separator?
|
||||
if (preg_match("/$sep/", $char))
|
||||
{
|
||||
$current = trim($current);
|
||||
if (!empty($current) AND ((str_replace('*', '', $current)) != ''))
|
||||
{
|
||||
// add non-empty token
|
||||
$tokens[] = $current;
|
||||
}
|
||||
$current = '';
|
||||
$sep = '\s';
|
||||
}
|
||||
|
||||
// begin literal expression?
|
||||
elseif ($char == '"')
|
||||
{
|
||||
$sep = '"';
|
||||
}
|
||||
|
||||
// normal token character
|
||||
else
|
||||
{
|
||||
$current .= $char;
|
||||
}
|
||||
}
|
||||
|
||||
// add remaining token
|
||||
$current = trim($current);
|
||||
if (!empty($current) AND ((str_replace('*','',$current))!=''))
|
||||
{
|
||||
$tokens[] = $current;
|
||||
}
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Operator cleaning
|
||||
*
|
||||
* removes illogical operator combinations...
|
||||
*
|
||||
* @param array Operators
|
||||
* @param string Stringreference to write errors back
|
||||
* @return string cleaned Operators
|
||||
*/
|
||||
function cleanoperators($ops, &$errors)
|
||||
{
|
||||
$newops = array();
|
||||
|
||||
// make unique
|
||||
$ops = array_unique($ops);
|
||||
|
||||
// sort
|
||||
if (in_array('AND', $ops)) $newops[] = 'AND';
|
||||
if (in_array('OR', $ops)) $newops[] = 'OR';
|
||||
if (in_array('NOT', $ops)) $newops[] = 'NOT';
|
||||
|
||||
// join
|
||||
$opstr = join(' ', $newops);
|
||||
|
||||
// clean unnormal conditions
|
||||
if (strstr($opstr, 'AND OR'))
|
||||
{
|
||||
$errors .= "Die logische Verknüpfung 'AND OR' ist nicht erlaubt und wurde in 'OR' umgewandelt.\n";
|
||||
$opstr = str_replace('AND OR', 'OR', $opstr);
|
||||
}
|
||||
if (strstr($opstr, 'OR NOT'))
|
||||
{
|
||||
$errors .= "Die logische Verknüpfung 'OR NOT' ist nicht erlaubt und wurde in 'AND' umgewandelt.\n";
|
||||
$opstr = str_replace('OR NOT', 'AND', $opstr);
|
||||
}
|
||||
if ($opstr == 'NOT')
|
||||
{
|
||||
$opstr = 'AND NOT';
|
||||
}
|
||||
|
||||
return $opstr;
|
||||
}
|
||||
|
||||
|
||||
59
videodb/core/security.php
Normal file
59
videodb/core/security.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* Security functions
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @author tREXX <www.trexx.ch>
|
||||
* @version $Id: security.php,v 1.2 2008/01/05 13:50:58 andig2 Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allow these tags
|
||||
*/
|
||||
$allowedTags = '<h1><h2><h3><h4><b><strong><i><a><ol><ul><li><pre><hr><blockquote>';
|
||||
|
||||
/**
|
||||
* Disallow these attributes/prefix within a tag
|
||||
*/
|
||||
$stripAttrib = 'javascript:|onclick|ondblclick|onmousedown|onmouseup|onmouseover|'.
|
||||
'onmousemove|onmouseout|onkeypress|onkeydown|onkeyup';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @param string
|
||||
* @desc Strip forbidden attributes from a tag
|
||||
*/
|
||||
function removeEvilAttributes($tagSource)
|
||||
{
|
||||
global $stripAttrib;
|
||||
return stripslashes(preg_replace("/$stripAttrib/i", 'forbidden', $tagSource));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @param string
|
||||
* @desc Strip forbidden attributes from an array of matches for an expression like (<)(.*?)(>)
|
||||
*/
|
||||
function _callbackRemoveEvilAttributes($matches)
|
||||
{
|
||||
return $matches[1] . removeEvilAttributes($matches[2]) . $matches[3];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @param string
|
||||
* @desc Strip forbidden tags and delegate tag-source check to removeEvilAttributes()
|
||||
*/
|
||||
function removeEvilTags($source)
|
||||
{
|
||||
global $allowedTags;
|
||||
if (!is_null($source))
|
||||
{
|
||||
$source = strip_tags($source, $allowedTags);
|
||||
return preg_replace_callback('/(<)(.*?)(>)/i', "_callbackRemoveEvilAttributes", $source);
|
||||
}
|
||||
return $source;
|
||||
}
|
||||
|
||||
?>
|
||||
69
videodb/core/session.php
Normal file
69
videodb/core/session.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* Session functions
|
||||
*
|
||||
* Moved all session functions into one file,
|
||||
* include this where session starting might be required
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: session.php,v 1.13 2008/02/28 20:01:17 andig2 Exp $
|
||||
*/
|
||||
|
||||
// start session
|
||||
session_start();
|
||||
|
||||
/**
|
||||
* Get session value or specified default
|
||||
*/
|
||||
function session_get($varname, $default=null)
|
||||
{
|
||||
if (isset($_SESSION['vdb'][$varname]))
|
||||
{
|
||||
return $_SESSION['vdb'][$varname];
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set session value or specified default
|
||||
*/
|
||||
function session_set($varname, $value)
|
||||
{
|
||||
$_SESSION['vdb'][$varname] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upsert session value with current value of global variable or specified default
|
||||
*/
|
||||
function session_default($varname, $default=null)
|
||||
{
|
||||
global $$varname;
|
||||
|
||||
if (!isset($$varname))
|
||||
{
|
||||
$$varname = (isset($_SESSION['vdb'][$varname])) ? $_SESSION['vdb'][$varname] : $default;
|
||||
}
|
||||
$_SESSION['vdb'][$varname] = $$varname;
|
||||
}
|
||||
|
||||
/**
|
||||
* get session_default for owner
|
||||
*
|
||||
* basically this only executes the extra query when the global $owner is not set and also
|
||||
* not available in session data. only then we need the hasAny check. if the global is set
|
||||
* or the global is not set but the session is then session_default() will fix both those
|
||||
* cases. put into a single function because it gets called from multiple files.
|
||||
*/
|
||||
function session_default_owner()
|
||||
{
|
||||
global $owner, $lang;
|
||||
if (!isset($owner) && !isset($_SESSION['vdb']['owner'])) {
|
||||
$hasAny = runSQL('SELECT COUNT(*) AS num FROM '.TBL_DATA.' WHERE '.TBL_DATA.'.owner_id = ' . get_current_user_id());
|
||||
$hasAny = ($hasAny && isset($hasAny[0]['num']) && $hasAny[0]['num'] > 0);
|
||||
$default = ($hasAny ? get_username(get_current_user_id()) : $lang['filter_any']);
|
||||
return session_default('owner', $default);
|
||||
}
|
||||
return session_default('owner');
|
||||
}
|
||||
|
||||
356
videodb/core/setup.core.php
Normal file
356
videodb/core/setup.core.php
Normal file
@@ -0,0 +1,356 @@
|
||||
<?php
|
||||
/**
|
||||
* Functions for config options
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @version $Id: setup.core.php,v 1.12 2013/03/16 10:10:07 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './core/custom.php';
|
||||
require_once './core/output.php';
|
||||
|
||||
$SETUP_GLOBAL = array('language', 'autoid', 'mediadefault', 'langdefault', 'acclangbrowser',
|
||||
'filterdefault', 'showtv', 'orderallbydisk', 'removearticles',
|
||||
'localnet', 'IMDBage', 'thumbnail',
|
||||
'castcolumns', 'template', 'languageflags', 'custom1',
|
||||
'custom2', 'custom3', 'custom4', 'custom1type',
|
||||
'custom2type', 'custom3type', 'custom4type', 'enginedefault',
|
||||
'proxy_host', 'proxy_port', 'actorpics', 'thumbAge', 'listcolumns',
|
||||
'shownew', 'imdbBrowser', 'multiuser', 'denyguest', 'adultgenres',
|
||||
'pageno', 'showtools', 'showcasttoggle', 'browse_include_title');
|
||||
|
||||
$SETUP_QUICK = array('template');
|
||||
|
||||
$SETUP_USER = array('language', 'mediadefault', 'langdefault', 'acclangbrowser', 'filterdefault',
|
||||
'showtv', 'orderallbydisk', 'template', 'languageflags',
|
||||
'listcolumns', 'castcolumns', 'shownew', 'pageno', 'removearticles',
|
||||
'showcasttoggle', 'browse_include_title');
|
||||
|
||||
/**
|
||||
* Build config options array
|
||||
*
|
||||
* @param boolean $isprofile Determines if user-specific options are to be displayed
|
||||
*
|
||||
* @return array associative array of config options
|
||||
*/
|
||||
function setup_mkOptions($isprofile = false)
|
||||
{
|
||||
global $config, $lang;
|
||||
|
||||
// built list of setup options
|
||||
$setup = array();
|
||||
|
||||
// isprofile, name, type (text|boolean|dropdown|special|link), data, set, helphl, helptxt
|
||||
$setup[] = setup_addSection('opt_general');
|
||||
$setup[] = setup_addOption($isprofile, 'language', 'dropdown', setup_getLanguages(), null, $lang['help_langn'], $lang['help_lang']);
|
||||
$option = setup_addOption($isprofile, 'template', 'dropdown', setup_getTemplates($thumbs));
|
||||
$option['thumbs'] = $thumbs;
|
||||
$setup[] = $option;
|
||||
|
||||
$setup[] = setup_addOption($isprofile, 'listcolumns', 'text');
|
||||
$setup[] = setup_addOption($isprofile, 'castcolumns', 'text');
|
||||
|
||||
$setup[] = setup_addOption($isprofile, 'autoid', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'orderallbydisk', 'boolean');
|
||||
|
||||
$setup[] = setup_addOption($isprofile, 'mediadefault', 'dropdown', setup_getMediatypes());
|
||||
$setup[] = setup_addOption($isprofile, 'langdefault', 'text');
|
||||
$setup[] = setup_addOption($isprofile, 'acclangbrowser', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'filterdefault', 'dropdown', array('all'=>$lang['radio_all'], 'unseen'=>$lang['radio_unseen'], 'new'=>$lang['radio_new'], 'wanted'=>$lang['radio_wanted']));
|
||||
$setup[] = setup_addOption($isprofile, 'showtv', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'shownew', 'text');
|
||||
$setup[] = setup_addOption($isprofile, 'pageno', 'text');
|
||||
$setup[] = setup_addOption($isprofile, 'languageflags', 'special', out_languageflags($config['languages']));
|
||||
$setup[] = setup_addOption($isprofile, 'removearticles', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'adultgenres', 'multi', setup_getGenres(), @explode('::', $config['adultgenres']));
|
||||
$setup[] = setup_addOption($isprofile, 'showtools', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'showcasttoggle', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'browse_include_title', 'dropdown', array('none' => $lang['none'], 'top' => $lang['top'], 'bottom' => $lang['bottom'], 'both' => $lang['both']));
|
||||
|
||||
if (!$isprofile) $setup[] = setup_addSection('opt_custom');
|
||||
$setup[] = setup_addOption($isprofile, 'custom', 'special', setup_mkCustoms(), 'custom', $lang['help_customn'], $lang['help_custom']);
|
||||
|
||||
if (!$isprofile) $setup[] = setup_addSection('opt_engines');
|
||||
$setup[] = setup_addOption($isprofile, 'enginedefault', 'dropdown', setup_getEngines($config['engines']), null , $lang['help_defaultenginen'], $lang['help_defaultengine']);
|
||||
|
||||
foreach ($config['engines'] as $engine => $meta)
|
||||
{
|
||||
$title = $meta['name'];
|
||||
if (array_key_exists($engine,$config['engine'])) {$enabled = $config['engine'][$engine];} else {$enabled = null;}
|
||||
$helptext = sprintf($lang['help_engine'], $title);
|
||||
if (array_key_exists('help_engine' . $engine, $lang)) {$helptext .= ' ' . $lang['help_engine' . $engine];}
|
||||
if (!array_key_exists('stable', $meta) || $meta['stable'] == 0) {$helptext .= ' ' . $lang['help_engexperimental'];}
|
||||
|
||||
$setup[] = setup_addOption($isprofile, 'engine'.$engine, 'boolean', null, $enabled, $title, $helptext);
|
||||
|
||||
// add engine-specific options
|
||||
if (array_key_exists('config', $meta) && is_array($meta['config']))
|
||||
{
|
||||
foreach ($meta['config'] as $setting)
|
||||
{
|
||||
// NOTE: check setup_additionalSettings if you change the option naming
|
||||
if (is_array($setting['values']))
|
||||
$setup[] = setup_addOption($isprofile, $engine.$setting['opt'],
|
||||
'dropdown', $setting['values'], null, $setting['name'], $setting['desc']);
|
||||
else
|
||||
$setup[] = setup_addOption($isprofile, $engine.$setting['opt'],
|
||||
'text', null, null, $setting['name'], $setting['desc']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$isprofile) {$setup[] = setup_addSection('opt_security');}
|
||||
$setup[] = setup_addOption($isprofile, 'localnet', 'text');
|
||||
$setup[] = setup_addOption($isprofile, 'multiuser', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'denyguest', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'usermanager', 'link', 'users.php', 'usermanager');
|
||||
$setup[] = setup_addOption($isprofile, 'proxy_host', 'text');
|
||||
$setup[] = setup_addOption($isprofile, 'proxy_port', 'text');
|
||||
|
||||
if (!$isprofile) {$setup[] = setup_addSection('opt_caching');}
|
||||
$setup[] = setup_addOption($isprofile, 'thumbnail', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'imdbBrowser', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'IMDBage', 'text');
|
||||
$setup[] = setup_addOption($isprofile, 'actorpics', 'boolean');
|
||||
$setup[] = setup_addOption($isprofile, 'thumbAge', 'text');
|
||||
|
||||
// clean empty entries
|
||||
for ($i = count($setup); $i > 0; $i--)
|
||||
{
|
||||
if (empty($setup[$i]['name']) && empty($setup[$i]['group'])) unset($setup[$i]);
|
||||
}
|
||||
|
||||
return $setup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add engine-specific config options for saving
|
||||
*/
|
||||
function setup_additionalSettings()
|
||||
{
|
||||
global $config, $SETUP_GLOBAL;
|
||||
|
||||
foreach ($config['engines'] as $engine => $meta)
|
||||
{
|
||||
// add engine-specific options
|
||||
if (array_key_exists('config', $meta) && is_array($meta['config']))
|
||||
{
|
||||
foreach ($meta['config'] as $setting)
|
||||
{
|
||||
$SETUP_GLOBAL[] = $engine.$setting['opt'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new section to the config options array
|
||||
*
|
||||
* @param array $setup The config array
|
||||
* @param string $section Name of the new section
|
||||
*/
|
||||
function setup_addSection($section)
|
||||
{
|
||||
$option['group'] = $section;
|
||||
return $option;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an entry for the config option array
|
||||
*
|
||||
* returns NULL on global options if $isprofile is true
|
||||
* so global options will not be added to user profile settings
|
||||
*
|
||||
* @param array $setup The config array
|
||||
* @param boolean $isprofile Do we prepare a profile array?
|
||||
* @param string $name Name of the config option
|
||||
* @param string $type Type of option (text|boolean|dropdown|special|link)
|
||||
* @param string $data Current value of this option
|
||||
* @param string $set Default value of this option
|
||||
* @param string $hl Help text headline
|
||||
* @param string $help Help text
|
||||
*/
|
||||
function setup_addOption($isprofile, $name, $type,
|
||||
$data='', $set=NULL, $hl=NULL, $help=NULL)
|
||||
{
|
||||
global $config, $lang;
|
||||
global $SETUP_USER;
|
||||
|
||||
// user-specific setting?
|
||||
$isuser = in_array($name, $SETUP_USER);
|
||||
|
||||
if ($isprofile and !$isuser) return;
|
||||
|
||||
$option['isuser'] = $isuser;
|
||||
$option['name'] = $name;
|
||||
$option['type'] = $type;
|
||||
$option['data'] = $data;
|
||||
|
||||
$option['set'] = ($set) ? $set : $config[$name];
|
||||
$option['hl'] = ($hl) ? $hl : $lang['help_'.$name.'n'];
|
||||
$option['help'] = ($help) ? $help : $lang['help_'.$name];
|
||||
|
||||
return $option;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find available languages
|
||||
*/
|
||||
function setup_getLanguages()
|
||||
{
|
||||
if ($dh = opendir('language'))
|
||||
{
|
||||
while (($file = readdir($dh)) !== false)
|
||||
{
|
||||
if (preg_match("/(.*)\.php$/", $file, $matches))
|
||||
{
|
||||
$languages[$matches[1]] = $matches[1];
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
return $languages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find available templates/styles
|
||||
* Extended to search for template screenshots
|
||||
*
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
*/
|
||||
function setup_getTemplates(&$screenshots)
|
||||
{
|
||||
$screenshots = array();
|
||||
|
||||
if ($dh = @opendir('templates'))
|
||||
{
|
||||
while (($file = readdir($dh)) !== false)
|
||||
{
|
||||
if (preg_match("/^\./", $file)) continue;
|
||||
if (is_dir('templates/'.$file))
|
||||
{
|
||||
$template = 'templates/'.$file;
|
||||
if ($dh2 = opendir($template))
|
||||
{
|
||||
$style_name = '';
|
||||
|
||||
while (($style = readdir($dh2)) !== false)
|
||||
{
|
||||
if (preg_match("/(.*)\.css$/", $style, $matches))
|
||||
{
|
||||
$thumb = $template.'/screenshot_'.$matches[1].'.jpg';
|
||||
if (file_exists($thumb))
|
||||
{
|
||||
$screenshots[] = array('name' => "$file::".$matches[1], 'img' => $thumb);
|
||||
}
|
||||
elseif (empty($style_name))
|
||||
{
|
||||
// remember first style found
|
||||
$style_name = $matches[1];
|
||||
}
|
||||
$templates[$file.'::'.$matches[1]] = $file.' ('.$matches[1].')';
|
||||
}
|
||||
}
|
||||
closedir($dh2);
|
||||
|
||||
if ($style_name)
|
||||
{
|
||||
$thumb = $template.'/screenshot.jpg';
|
||||
if (file_exists($thumb))
|
||||
{
|
||||
$screenshots[] = array('name' => "$file::$style_name", 'img' => $thumb);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
return $templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mediatypes
|
||||
*/
|
||||
function setup_getMediatypes()
|
||||
{
|
||||
$SELECT = 'SELECT id, name
|
||||
FROM '.TBL_MEDIATYPES.'
|
||||
ORDER BY name';
|
||||
$result = runSQL($SELECT);
|
||||
|
||||
return array_associate($result, 'id', 'name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Genres
|
||||
*/
|
||||
function setup_getGenres()
|
||||
{
|
||||
$SELECT = 'SELECT id, name
|
||||
FROM '.TBL_GENRES.'
|
||||
ORDER BY name';
|
||||
$result = runSQL($SELECT);
|
||||
|
||||
return array_associate($result, 'id', 'name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of engines for default engine selection
|
||||
*/
|
||||
function setup_getEngines($engines_ary)
|
||||
{
|
||||
$engines = array();
|
||||
|
||||
foreach ($engines_ary as $engine => $meta)
|
||||
{
|
||||
if (engine_get_capability($engine, 'movie')) $engines[$engine] = $meta['name'];
|
||||
}
|
||||
|
||||
return $engines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare customfields
|
||||
*/
|
||||
function setup_mkCustoms()
|
||||
{
|
||||
global $config;
|
||||
global $allcustomtypes;
|
||||
|
||||
$setup_custom = '';
|
||||
|
||||
for ($i=1; $i<5; $i++)
|
||||
{
|
||||
$setup_custom .= $i.'. <input type="text" size="20" name="custom'.$i.'" id="custom'.$i.'" value="'.formvar($config['custom'.$i]).'"/>';
|
||||
$setup_custom .= '<select name="custom'.$i.'type">';
|
||||
|
||||
foreach($allcustomtypes as $ctype)
|
||||
{
|
||||
$selected = ($ctype == $config['custom'.$i.'type']) ? ' selected="selected"' : '';
|
||||
$setup_custom .= '<option value="'.$ctype.'"'.$selected.'>'.$ctype.'</option>';
|
||||
}
|
||||
$setup_custom .= '</select>';
|
||||
$setup_custom .= "<br />\n";
|
||||
}
|
||||
|
||||
return $setup_custom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update session variables with configuration values
|
||||
*
|
||||
* @author Andreas Goetz
|
||||
*/
|
||||
function update_session()
|
||||
{
|
||||
global $listcolumns, $showtv;
|
||||
|
||||
if ($listcolumns) $_SESSION['vdb']['listcolumns'] = $listcolumns;
|
||||
if ($showtv) $_SESSION['vdb']['showtv'] = $showtv;
|
||||
}
|
||||
|
||||
612
videodb/core/template.php
Normal file
612
videodb/core/template.php
Normal file
@@ -0,0 +1,612 @@
|
||||
<?php
|
||||
/**
|
||||
* Template functions
|
||||
*
|
||||
* These functions prepare the data for assignment to the template engine
|
||||
*
|
||||
* @todo replace additional assignments of config options by using $config
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @version $Id: template.php,v 1.70 2013/03/21 16:27:57 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/session.php';
|
||||
require_once './core/output.php';
|
||||
require_once './core/genres.php';
|
||||
require_once './core/functions.php';
|
||||
require_once './engines/engines.php';
|
||||
|
||||
/**
|
||||
* Display template with standard header and footer
|
||||
*/
|
||||
function tpl_display_show($template, $flush = true)
|
||||
{
|
||||
smarty_display('header.tpl');
|
||||
|
||||
if ($flush) flush();
|
||||
smarty_display($template);
|
||||
smarty_display('footer.tpl');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display page using templates
|
||||
* If page content is unmodified, return HTTP 304 Not modified
|
||||
*
|
||||
* @param string $template Template name for main content
|
||||
*/
|
||||
function tpl_display($template)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// caching enabled?
|
||||
if ($config['http_caching'])
|
||||
{
|
||||
require_once('./core/httpcache.php');
|
||||
httpCacheCaptureStart();
|
||||
}
|
||||
|
||||
tpl_display_show($template, !$config['http_caching']);
|
||||
|
||||
if ($config['http_caching'])
|
||||
{
|
||||
httpCacheOutput($template, httpCacheCaptureEnd());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare standard page templates
|
||||
*/
|
||||
function tpl_page($help = '', $title = '')
|
||||
{
|
||||
tpl_language();
|
||||
tpl_header($help, $title);
|
||||
tpl_footer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns language strings and config options to the smarty engine
|
||||
*/
|
||||
function tpl_language()
|
||||
{
|
||||
global $smarty, $lang, $config;
|
||||
|
||||
$smarty->assign('lang', $lang);
|
||||
$smarty->assign('config', $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the header urls to the smarty engine
|
||||
*
|
||||
* @param string $help The helpfile to display (optional, without extension)
|
||||
* @param string $title The text to add to html <title> tag (optional, will be html-encoded)
|
||||
*/
|
||||
function tpl_header($help = '', $title = '')
|
||||
{
|
||||
global $smarty, $lang, $config;
|
||||
global $id, $diskid;
|
||||
|
||||
// viewing is only availble if autorized or public access
|
||||
if (auth_check(false))
|
||||
{
|
||||
$header['browse'] = 'index.php';
|
||||
if (check_permission(PERM_READ, PERM_ANY))
|
||||
{
|
||||
$header['random'] = 'show.php';
|
||||
$header['search'] = 'search.php';
|
||||
}
|
||||
$header['stats'] = 'stats.php';
|
||||
if ($config['imdbBrowser']) $header['trace'] = 'trace.php';
|
||||
$header['help'] = 'help.php';
|
||||
if ($help) $header['help'] .= '?page='.$help.'.html';
|
||||
}
|
||||
|
||||
// editing is only available in local network
|
||||
if (localnet())
|
||||
{
|
||||
if (check_permission(PERM_WRITE, PERM_ANY))
|
||||
{
|
||||
$header['new'] = 'edit.php';
|
||||
if ($config['showtools']) $header['contrib'] = 'contrib.php';
|
||||
}
|
||||
if (check_permission(PERM_ADMIN)) $header['setup'] = 'setup.php';
|
||||
|
||||
// edit or show?
|
||||
if ($id)
|
||||
{
|
||||
if (check_videopermission(PERM_WRITE, $id)) $header['edit'] = 'edit.php?id='.$id;
|
||||
if (!preg_match('/show.php$/', $_SERVER['PHP_SELF']))
|
||||
{
|
||||
$header['view'] = 'show.php?id='.$id;
|
||||
}
|
||||
if (check_videopermission(PERM_WRITE, $id)) $header['del'] = 'delete.php?id='.$id;
|
||||
}
|
||||
if (check_permission(PERM_WRITE, PERM_ANY))
|
||||
{
|
||||
$header['borrow'] = 'borrow.php';
|
||||
if (isset($diskid)) $header['borrow'] .= '?diskid='.$diskid;
|
||||
}
|
||||
}
|
||||
|
||||
// multiuser settings
|
||||
if ($config['multiuser'])
|
||||
{
|
||||
$header['login'] = 'login.php';
|
||||
|
||||
// logged in?
|
||||
if (!empty($_COOKIE['VDBusername']) && $_COOKIE['VDBuserid'] != $config['guestid'])
|
||||
{
|
||||
$header['profile'] = 'profile.php';
|
||||
$smarty->assign('loggedin', $_COOKIE['VDBusername']);
|
||||
}
|
||||
else
|
||||
{
|
||||
// make sure anonymous users don't get access to trace for security reasons
|
||||
unset($header['trace']);
|
||||
}
|
||||
|
||||
if (check_permission(PERM_ADMIN)) $header['users'] = 'users.php';
|
||||
}
|
||||
|
||||
// determine active tab
|
||||
if (preg_match('/(\w+)\.php/', $_SERVER['PHP_SELF'], $m))
|
||||
{
|
||||
$tab = strtolower($m[1]);
|
||||
switch ($tab)
|
||||
{
|
||||
case 'show':
|
||||
$header['request_uri'] = $_SERVER['REQUEST_URI'];
|
||||
case 'edit':
|
||||
if (!empty($id)) $header['active'] = $tab;
|
||||
// uncomment this if you want the 'Browse' tab to remember last visited movie
|
||||
// { ... $smarty->assign('browseid', $_REQUEST['id']); }
|
||||
else $header['active'] = ($tab == 'show') ? 'random' : 'new';
|
||||
break;
|
||||
default:
|
||||
/* legacy version
|
||||
$translate = array('index' => 'browse', 'users' => 'setup', 'permissions' => 'setup', 'delete' => 'show');
|
||||
*/
|
||||
$translate = array('index' => 'browse', 'permissions' => 'users', 'delete' => 'show');
|
||||
if (in_array($tab, array_keys($translate)))
|
||||
{
|
||||
$tab = $translate[$tab];
|
||||
}
|
||||
$header['active'] = $tab;
|
||||
}
|
||||
}
|
||||
|
||||
// breadcrumbs
|
||||
$breadcrumbs = session_get('breadcrumbs', array());
|
||||
$smarty->assign('breadcrumbs', $breadcrumbs);
|
||||
|
||||
if (!is_null($title))
|
||||
{
|
||||
$smarty->assign('title', htmlspecialchars($title));
|
||||
}
|
||||
else
|
||||
{
|
||||
$smarty->assign('title', "");
|
||||
}
|
||||
$smarty->assign('header', $header);
|
||||
$smarty->assign('style', $config['style']);
|
||||
$smarty->assign('langcode', $config['language']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the filter options to the smarty engine
|
||||
*/
|
||||
function tpl_filters($filter, $showtv)
|
||||
{
|
||||
global $smarty, $lang;
|
||||
global $filter_expr;
|
||||
global $owner, $mediatype;
|
||||
global $config;
|
||||
|
||||
// build filter array
|
||||
foreach ($filter_expr as $flt => $regex)
|
||||
{
|
||||
$filters[$flt] = ($flt == "NUM") ? "#" : $flt;
|
||||
}
|
||||
$filters['all'] = $lang['radio_all'];
|
||||
$filters['unseen'] = $lang['radio_unseen'];
|
||||
$filters['new'] = $lang['radio_new'];
|
||||
/*
|
||||
# removed as of 4.0 in favour of media type filter
|
||||
$filters['wanted'] = $lang['radio_wanted'];
|
||||
*/
|
||||
$smarty->assign('filters', $filters);
|
||||
$smarty->assign('filter', $filter);
|
||||
$smarty->assign('showtv', $showtv);
|
||||
|
||||
// create owner selectbox
|
||||
$smarty->assign('owners', out_owners(array($lang['filter_any'] => $lang['filter_any']), PERM_READ));
|
||||
if (!$owner) $owner = $lang['filter_any']; //!! default owner hack
|
||||
$smarty->assign('owner', $owner);
|
||||
|
||||
// create mediatype selectbox
|
||||
$smarty->assign('mediafilter', out_mediatypes(array(-2 => $lang['filter_any'], -1 => $lang['filter_available'])));
|
||||
if (!$mediatype) $mediatype = session_get('mediafilter'); //!! default media type hack
|
||||
$smarty->assign('mediatype', $mediatype);
|
||||
|
||||
// create sorting selectbox
|
||||
// Sorting is disabled when ordering by diskid is enabled
|
||||
if(!$config['orderallbydisk']) {
|
||||
$smarty->assign('order_options', array(-1 => $lang['title'], 1 => $lang['rating'], 2 => $lang['date']));
|
||||
if(!isset($order)) $order = session_get('order');
|
||||
$smarty->assign('order', $order);
|
||||
}
|
||||
|
||||
|
||||
// enable dynamic columns in list view
|
||||
$smarty->assign('listcolumns', session_get('listcolumns'));
|
||||
}
|
||||
|
||||
function adultcheck_for_video($video)
|
||||
{
|
||||
return adultcheck($video["id"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the searchresults/browselist to the smarty engine
|
||||
*
|
||||
* @param array indexed array containing the item data
|
||||
*/
|
||||
function tpl_list($list)
|
||||
{
|
||||
global $smarty, $config;
|
||||
global $listcolumns;
|
||||
if(!$list)
|
||||
{
|
||||
$smarty->assign('totalresults', 0);
|
||||
return;
|
||||
}
|
||||
for ($i=0; $i < count($list); $i++)
|
||||
{
|
||||
// setup imgurls
|
||||
$list[$i]['imgurl'] = ($config['thumbnail']) ? getThumbnail($list[$i]['imgurl']) : '';
|
||||
|
||||
// check for flagfile
|
||||
$languages = $list[$i]['language'];
|
||||
$flagfile = img('flags/'.$languages.'.gif');
|
||||
if (file_exists($flagfile))
|
||||
{
|
||||
// one langage
|
||||
$list[$i]['flagfile'][$languages] = $flagfile;
|
||||
$list[$i]['language'] = array($list[$i]['language']);
|
||||
}
|
||||
else
|
||||
{
|
||||
// multiple languages
|
||||
$langary = preg_split('/,\s*/', $languages);
|
||||
$list[$i]['language'] = $langary;
|
||||
|
||||
// assign them all
|
||||
foreach ($langary as $languagepart)
|
||||
{
|
||||
$flagfile = img('flags/'.$languagepart.'.gif');
|
||||
if (file_exists($flagfile))
|
||||
{
|
||||
$list[$i]['flagfile'][$languagepart] = $flagfile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// is this file editable?
|
||||
if (localnet())
|
||||
{
|
||||
$list[$i]['editable'] = ($config['multiuser']) ?
|
||||
check_permission(PERM_WRITE, $list[$i]['owner_id']) : true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$list[$i]['editable'] = false;
|
||||
}
|
||||
/*
|
||||
uncomment this to allow display of rating in the 'Browse' tab
|
||||
require_once 'custom.php';
|
||||
customfields($list[$i], 'out');
|
||||
*/
|
||||
}
|
||||
|
||||
// do adultcheck
|
||||
if (is_array($list))
|
||||
{
|
||||
$list = array_filter($list, "adultcheck_for_video");
|
||||
}
|
||||
|
||||
// enable dynamic columns in list view
|
||||
$smarty->assign('listcolumns', session_get('listcolumns'));
|
||||
$smarty->assign('list', $list);
|
||||
|
||||
// show total number of movies in footer
|
||||
$smarty->assign('totalresults', count($list));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns debug infos and version to the smarty engine
|
||||
*/
|
||||
function tpl_footer()
|
||||
{
|
||||
global $smarty, $config, $SQLtrace;
|
||||
|
||||
if ($config['debug'])
|
||||
{
|
||||
$out = $config;
|
||||
$out['db_password'] = '***';
|
||||
$session = $_SESSION['vdb'];
|
||||
$session['db_password'] = '***';
|
||||
|
||||
ob_start();
|
||||
print '<pre>';
|
||||
dump($SQLtrace);
|
||||
dump($out);
|
||||
dump($session);
|
||||
print '</pre>';
|
||||
# phpinfo();
|
||||
$debug = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
$smarty->assign('DEBUG', $debug);
|
||||
}
|
||||
$smarty->assign('version', VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function combines multiple actor thumbnail queries into single SQL query
|
||||
*/
|
||||
function get_actor_thumbnails_batched(&$actors)
|
||||
{
|
||||
if (!count($actors)) return;
|
||||
|
||||
$ids = "'".join("','", array_map('escapeSQL', array_column($actors, 'id')))."'";
|
||||
|
||||
$SQL = 'SELECT actorid, name, imgurl, UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(checked) AS cacheage
|
||||
FROM '.TBL_ACTORS.' WHERE actorid IN ('.$ids.')';
|
||||
$result = runSQL($SQL);
|
||||
|
||||
$result = array_associate($result, 'actorid');
|
||||
|
||||
// loop over actors from full-text field
|
||||
foreach ($actors as $idx => $actor)
|
||||
{
|
||||
// check for actor thumbnail
|
||||
$batch_result = null;
|
||||
if (array_key_exists($actor['id'], $result))
|
||||
{
|
||||
$batch_result = $result[$actor['id']];
|
||||
}
|
||||
|
||||
if ($batch_result)
|
||||
{
|
||||
$actors[$idx]['imgurl'] = get_actor_image_from_cache($batch_result, $actor['name'], $actor['id']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$actors[$idx]['imgurl'] = getActorThumbnail($actor['name'], $actor['id'], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert textbox/db presentation into actors array
|
||||
*/
|
||||
function split_cast_array(&$actor, $key)
|
||||
{
|
||||
$ary = explode('::', $actor);
|
||||
|
||||
$actor = array();
|
||||
$actor['name'] = $ary[0];
|
||||
$actor['id'] = $ary[2];
|
||||
$actor['roles'] = preg_split('[^</]', $ary[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts plain cast data into array of actors with thumbnails
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
function prepare_cast($cast)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// convert text represenatation into array
|
||||
$actors = array_filter(preg_split("/\r?\n/", trim($cast)));
|
||||
|
||||
// reformat roles
|
||||
$actors = preg_replace('/\((.*?)\)/', '<small>($1)</small>', $actors);
|
||||
|
||||
array_walk($actors, 'split_cast_array');
|
||||
|
||||
// check for actor thumbnails
|
||||
if ($config['actorpics']) get_actor_thumbnails_batched($actors);
|
||||
|
||||
// loop over actors from full-text field
|
||||
foreach ($actors as $idx => $actor)
|
||||
{
|
||||
$actors[$idx]['imdburl'] = engineGetActorUrl($actor['name'], $actor['id'], engineGetActorEngine($actor['id']));
|
||||
|
||||
// check for actor thumbnail
|
||||
# if ($config['actorpics']) $actor['imgurl'] = getActorThumbnail($actor['name'], $actor['id']);
|
||||
}
|
||||
|
||||
return $actors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the videoinfos to the smarty engine
|
||||
*
|
||||
* @param array associative array containing the item data
|
||||
*/
|
||||
function tpl_show($video)
|
||||
{
|
||||
global $smarty, $config;
|
||||
|
||||
// imageurl
|
||||
$video['imgurl'] = getThumbnail($video['imgurl'], $video['title']);
|
||||
|
||||
// make soft linebreaks:
|
||||
$video['filename'] = preg_replace('/(_|\.|-)/', '$1<wbr />', $video['filename']);
|
||||
|
||||
// split comma-separated countries, prevent empty array
|
||||
$video['country'] = preg_split('/,\s*/', $video['country'], -1, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
// split comma-separated multiple languages, prevent empty array
|
||||
$video['language'] = preg_split('/,\s*/', $video['language'], -1, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
// humanreadable filesize:
|
||||
$video['filesize'] = round($video['filesize']/(1024*1024), 2);
|
||||
|
||||
// break plot and comment
|
||||
$video['plot'] = nl2br($video['plot']);
|
||||
$video['comment'] = nl2br($video['comment']);
|
||||
|
||||
// cast
|
||||
$smarty->assign('cast_toggle', $config['showcasttoggle']);
|
||||
$show_cast = true;
|
||||
if ($config['showcasttoggle'])
|
||||
{
|
||||
$show_cast = (isset($_GET['show_cast']) && $_GET['show_cast'] == '1');
|
||||
}
|
||||
$smarty->assign('show_cast', $show_cast);
|
||||
$video['cast'] = [];
|
||||
if ($show_cast)
|
||||
{
|
||||
$video['cast'] = prepare_cast($video['actors']);
|
||||
}
|
||||
|
||||
// prepare the custom fields
|
||||
customfields($video, 'out');
|
||||
|
||||
// hide owner if not using multi-user
|
||||
if (!$config['multiuser']) unset($video['owner']);
|
||||
|
||||
// get drilldown url for image
|
||||
if ($video['imdbID'])
|
||||
{
|
||||
require_once './engines/engines.php';
|
||||
$smarty->assign('link', engineGetContentUrl($video['imdbID'], engineGetEngine($video['imdbID'])));
|
||||
}
|
||||
|
||||
// add episodes information
|
||||
if (array_key_exists('episodes', $video) && is_array($video['episodes']))
|
||||
{
|
||||
// allow multiple columns
|
||||
$smarty->assign('listcolumns', session_get('listcolumns'));
|
||||
}
|
||||
|
||||
$smarty->assign('castcolumns', $config['castcolumns']);
|
||||
$smarty->assign('video', $video);
|
||||
|
||||
// get genre ids and names
|
||||
$smarty->assign('genres', getItemGenres($video['id'], true));
|
||||
|
||||
// make engines available
|
||||
$smarty->assign('engines', $config['engine']);
|
||||
|
||||
// allow XML export
|
||||
foreach (array('xls','pdf','xml') as $export)
|
||||
{
|
||||
if ($config[$export]) $smarty->assign($export, 'show.php?id='.$video['id'].'&');
|
||||
}
|
||||
// new-style way of exporting
|
||||
// $smarty->assign('exports', listExports('show.php?id='.$video['id'].'&'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the videoinfos to the smarty engine
|
||||
*/
|
||||
function tpl_edit($video)
|
||||
{
|
||||
global $smarty, $config, $lang;
|
||||
|
||||
// create a form ready quoted version for each value
|
||||
foreach (array_keys($video) as $key)
|
||||
{
|
||||
$video['q_'.$key] = formvar($video[$key]);
|
||||
}
|
||||
|
||||
// use custom function for language
|
||||
$video['f_language'] = custom_language_input('language', $video['language']);
|
||||
|
||||
// create mediatype selectbox
|
||||
$smarty->assign('mediatypes', out_mediatypes());
|
||||
if (!isset($video['mediatype'])) $video['mediatype'] = $config['mediadefault'];
|
||||
|
||||
// prepare the custom fields
|
||||
customfields($video, 'in');
|
||||
|
||||
if ($config['multiuser'])
|
||||
{
|
||||
$smarty->assign('owners', out_owners(array('0' => ''), (check_permission(PERM_ADMIN)) ? false : PERM_WRITE, true));
|
||||
}
|
||||
|
||||
// item genres
|
||||
if (array_key_exists('id', $video))
|
||||
{
|
||||
$item_genres = getItemGenres($video['id']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$item_genres = array();
|
||||
}
|
||||
// new-style
|
||||
$smarty->assign('genres', out_genres2($item_genres));
|
||||
#dlog(out_genres2($item_genres));
|
||||
#dlog($item_genres);
|
||||
// classic
|
||||
$smarty->assign('genreselect', out_genres($item_genres));
|
||||
|
||||
// assign data
|
||||
$smarty->assign('video', $video);
|
||||
|
||||
// get drilldown url for visit link
|
||||
if (array_key_exists('imdbID', $video))
|
||||
{
|
||||
require_once './engines/engines.php';
|
||||
$engine = engineGetEngine($video['imdbID']);
|
||||
$smarty->assign('link', engineGetContentUrl($video['imdbID'], $engine));
|
||||
$smarty->assign('engine', $engine);
|
||||
}
|
||||
|
||||
/*
|
||||
// populate autocomplete boxes
|
||||
$smarty->assign('audio_codecs', array_column(runSQL('SELECT DISTINCT audio_codec FROM '.TBL_DATA.' WHERE audio_codec IS NOT NULL'), 'audio_codec'));
|
||||
$smarty->assign('video_codecs', array_column(runSQL('SELECT DISTINCT video_codec FROM '.TBL_DATA.' WHERE video_codec IS NOT NULL'), 'video_codec'));
|
||||
*/
|
||||
$smarty->assign('lookup', array('0' => $lang['radio_look_ignore'],
|
||||
'1' => $lang['radio_look_lookup'],
|
||||
'2' => $lang['radio_look_overwrite']));
|
||||
|
||||
// needed for ajax image lookup
|
||||
$smarty->assign('engines', $config['engines']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare lookup template
|
||||
*/
|
||||
function tpl_lookup($find, $engine, $searchtype)
|
||||
{
|
||||
global $smarty, $config;
|
||||
|
||||
$find = trim($find);
|
||||
$smarty->assign('find', $find);
|
||||
$smarty->assign('q_find', formvar($find));
|
||||
|
||||
$smarty->assign('engine', $engine);
|
||||
|
||||
$tpl = array();
|
||||
foreach (engine_get_capable_engines($searchtype) as $eng => $enabled)
|
||||
{
|
||||
// url- make sure this is non-unicode
|
||||
$tpl[$eng]['url'] = 'lookup.php?find='.urlencode(utf8_smart_decode($find)).'&engine='.$eng.'&searchtype='.$searchtype;
|
||||
|
||||
// title
|
||||
$tpl[$eng]['name'] = $config['engines'][$eng]['name'];
|
||||
}
|
||||
|
||||
$smarty->assign('engines', $tpl);
|
||||
}
|
||||
|
||||
?>
|
||||
459
videodb/core/xls.php
Normal file
459
videodb/core/xls.php
Normal file
@@ -0,0 +1,459 @@
|
||||
<?php
|
||||
/**
|
||||
* XLS Export functions
|
||||
*
|
||||
* Allows exporting movies to an Excel list
|
||||
* Requires Spreadsheet_Excel_Writer libaray (http://pear.php.net)
|
||||
*
|
||||
* @package Core
|
||||
* @link http://pear.php.net/package/Spreadsheet_Excel_Writer
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @version $Id: xls.php,v 1.8 2008/01/05 13:50:29 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './core/export.core.php';
|
||||
require_once './engines/engines.php';
|
||||
|
||||
#error_reporting(E_ALL^E_NOTICE);
|
||||
require_once 'vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* Export PDF document
|
||||
*
|
||||
* @param string $where WHERE clause for SQL statement
|
||||
*/
|
||||
function xlsexport($WHERE)
|
||||
{
|
||||
global $config, $lang;
|
||||
|
||||
$text_length = 256-3;
|
||||
|
||||
// videodb context dir
|
||||
$context_dir = preg_replace('/^(.*)\/.*?$/','\\1',$_SERVER["SCRIPT_FILENAME"]);
|
||||
|
||||
// array of temp files wich have to be deleted if workbook is closed
|
||||
$del_list = array();
|
||||
|
||||
// make shure we have list with extra fields, even if empty
|
||||
$extra_fields = array_map('trim', explode(",", $config['xls_extra_fields']));
|
||||
|
||||
// Creating a workbook
|
||||
$workbook = new Spreadsheet_Excel_Writer();
|
||||
$workbook->setCustomColor(12, 192,192,192); // Headline
|
||||
$workbook->setCustomColor(13, 255,255,200); // Seen
|
||||
$workbook->setCustomColor(14, 255,220,220); // Lent
|
||||
//$workbook->setCustomColor(15, 0,0,0); // Test
|
||||
|
||||
// sending HTTP headers
|
||||
$outputFilename = ($config['xls_output_filename']) ? $config['xls_output_filename'] : 'VideoDB';
|
||||
$workbook->send($outputFilename.'.xls');
|
||||
|
||||
// Creating a worksheet
|
||||
$sheetTitle = ($config['xls_sheet_title']) ? $config['xls_sheet_title'] : 'VideoDB';
|
||||
$worksheet =& $workbook->addWorksheet($sheetTitle);
|
||||
|
||||
// format templates
|
||||
$alignLeftFormatNormal =& $workbook->addFormat();
|
||||
$alignLeftFormatLent =& $workbook->addFormat(array('Pattern' => 1));
|
||||
$alignLeftFormatLent -> setFGColor(14);
|
||||
$alignRightFormatNormal =& $workbook->addFormat(array('Align' => 'right'));
|
||||
$alignRightFormatLent =& $workbook->addFormat(array('Align' => 'right', 'Pattern' => 1));
|
||||
$alignRightFormatLent -> setFgColor(14);
|
||||
$alignCenterFormatNormal =& $workbook->addFormat(array('Align' => 'center'));
|
||||
$alignCenterFormatLent =& $workbook->addFormat(array('Align' => 'center', 'Pattern' => 1));
|
||||
$alignCenterFormatLent -> setFgColor(14);
|
||||
$titleFormatNormal =& $workbook->addFormat(array('Bold' => 1));
|
||||
$titleFormatUnseen =& $workbook->addFormat(array('Bold' => 1, 'Pattern' => 1));
|
||||
$titleFormatUnseen -> setFgColor(13);
|
||||
$titleFormatLent =& $workbook->addFormat(array('Bold' => 1, 'Pattern' => 1));
|
||||
$titleFormatLent -> setFgColor(14);
|
||||
|
||||
$plotFormatNormal =& $workbook->addFormat(array('Align' => 'top'));
|
||||
$plotFormatNormal -> setTextWrap();
|
||||
$plotFormatLent =& $workbook->addFormat(array('Align' => 'top','Pattern' => 1));
|
||||
$plotFormatLent -> setTextWrap();
|
||||
$plotFormatLent -> setFgColor(14);
|
||||
|
||||
$headlineFormat =& $workbook->addFormat(array('Bold' => 1, 'Align' => 'center', 'Pattern' => 1));
|
||||
$headlineFormat ->setFgColor(12);
|
||||
|
||||
$rowindex = 0;
|
||||
$columnindex = 0;
|
||||
|
||||
if ($config['xls_show_headline'])
|
||||
{
|
||||
$worksheet->setRow(0, 30);
|
||||
$rowindex++;
|
||||
}
|
||||
|
||||
// get data (see http://pear.php.net/bugs/bug.php?id=1572)
|
||||
$result = iconv_array('utf-8', 'iso-8859-1', exportData($WHERE));
|
||||
|
||||
foreach ($result as $row)
|
||||
{
|
||||
$columnindex = 0;
|
||||
set_time_limit(300); // rise per movie execution timeout limit if safe_mode is not set in php.ini
|
||||
|
||||
if (!empty($row['lentto']) && $config['xls_mark_lent']) {
|
||||
$alignLeftFormat = $alignLeftFormatLent;
|
||||
$alignCenterFormat = $alignLeftFormatLent;
|
||||
$alignRightFormat = $alignLeftFormatLent;
|
||||
}
|
||||
else
|
||||
{
|
||||
$alignLeftFormat = $alignLeftFormatNormal;
|
||||
$alignCenterFormat = $alignLeftFormatNormal;
|
||||
$alignRightFormat = $alignLeftFormatNormal;
|
||||
}
|
||||
$worksheet->setRow($rowindex, 15, $alignLeftFormat);
|
||||
|
||||
foreach ($extra_fields as $field)
|
||||
{
|
||||
$isNote = false;
|
||||
$walks = 1;
|
||||
if (preg_match('/(.+)\((.+)\)/',$field,$matches))
|
||||
{
|
||||
$field = trim($matches[1]);
|
||||
$note = trim($matches[2]);
|
||||
$walks = 2;
|
||||
}
|
||||
|
||||
for ($walk = 0;$walk < $walks; $walk++)
|
||||
{
|
||||
if ($walk == 1)
|
||||
{
|
||||
$isNote = true;
|
||||
$field = $note;
|
||||
$columnindex--;
|
||||
}
|
||||
|
||||
// title
|
||||
if ($field == "title")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['title'], $headlineFormat);
|
||||
|
||||
$title = $row['title'];
|
||||
if ($row['subtitle']) $title .= ' - '.$row['subtitle'];
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['title'].":\n".html_entity_decode($title));
|
||||
else {
|
||||
if ($row['seen'] == '0' && $config['xls_mark_unseen']) $format = $titleFormatUnseen;
|
||||
elseif (!empty($row['lentto']) && $config['xls_mark_lent']) $format = $titleFormatLent;
|
||||
else $format = $titleFormatNormal;
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 50);
|
||||
$imdb = $row['imdbID'];
|
||||
$link = ($imdb) ? engineGetContentUrl($imdb, engineGetEngine($imdb)) : '';
|
||||
if($link <> '') $worksheet->writeUrl($rowindex, $columnindex, $link, html_entity_decode($title), $format);
|
||||
else $worksheet->writeString($rowindex, $columnindex, leftString(html_entity_decode($row['title']),$text_length), $format);
|
||||
}
|
||||
$columnindex++;
|
||||
}
|
||||
|
||||
// plot
|
||||
elseif ($field == "plot")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['plot'], $headlineFormat);
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, leftString(html_entity_decode($row['plot']),$text_length));
|
||||
else
|
||||
{
|
||||
if (!empty($row['lentto']) && $config['xls_mark_lent']) $format = $plotFormatLent;
|
||||
else $format = $plotFormatNormal;
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 50);
|
||||
$worksheet->writeString($rowindex, $columnindex++, leftString(html_entity_decode($row['plot']),$text_length), $format);
|
||||
}
|
||||
}
|
||||
|
||||
// DiskId
|
||||
elseif ($field == "diskid")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['diskid'], $headlineFormat);
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['diskid'].":\n".html_entity_decode($row['diskid']));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 7);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row['diskid']), $alignCenterFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// add language
|
||||
elseif ($field == "language")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['language'], $headlineFormat);
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['language'].":\n".html_entity_decode($row['language']));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 30);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row['language']), $alignLeftFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// add mediatype
|
||||
elseif ($field == "mediatype")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['mediatype'], $headlineFormat);
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['mediatype'].":\n".html_entity_decode($row['mediatype']));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 7);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row['mediatype']), $alignLeftFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// genres
|
||||
elseif ($field == "genres")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['genres'], $headlineFormat);
|
||||
|
||||
if (count($row['genres']))
|
||||
{
|
||||
$output_genres = array();
|
||||
foreach ($row['genres'] as $genre)
|
||||
{
|
||||
$output_genres[]= html_entity_decode($genre['name']);
|
||||
}
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['genres'].":\n".join(", ", $output_genres));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 20);
|
||||
$worksheet->writeString($rowindex, $columnindex, join(", ", $output_genres), $alignCenterFormat);
|
||||
}
|
||||
}
|
||||
$columnindex++;
|
||||
}
|
||||
|
||||
// runtime
|
||||
elseif ($field == "runtime")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['runtime'], $headlineFormat);
|
||||
|
||||
if ($row['runtime'])
|
||||
{
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['runtime'].":\n".html_entity_decode($row['runtime']).' min');
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 7);
|
||||
$worksheet->writeString($rowindex, $columnindex, html_entity_decode($row['runtime']).' min', $alignRightFormat);
|
||||
}
|
||||
}
|
||||
$columnindex++;
|
||||
}
|
||||
|
||||
// year
|
||||
elseif ($field == "year")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['year'], $headlineFormat);
|
||||
|
||||
if ($row['year'] != '0000')
|
||||
{
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['year'].":\n".html_entity_decode($row['year']));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 7);
|
||||
$worksheet->writeNumber($rowindex, $columnindex, html_entity_decode($row['year']), $alignCenterFormat);
|
||||
}
|
||||
}
|
||||
$columnindex++;
|
||||
}
|
||||
|
||||
// owner
|
||||
elseif ($field == "owner")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['owner'], $headlineFormat);
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['owner'].":\n".html_entity_decode($row['owner']));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 15);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row['owner']), $alignCenterFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// lent
|
||||
elseif ($field == "lent")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['lentto'], $headlineFormat);
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['lentto'].":\n".html_entity_decode($row['lentto']));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 15);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row['lentto']), $alignCenterFormat);
|
||||
}
|
||||
}
|
||||
// seen
|
||||
elseif ($field == "seen")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['seen'], $headlineFormat);
|
||||
|
||||
if ($isNote) {
|
||||
if ($row['seen'] == 1) $worksheet->writeNote($rowindex, $columnindex++, html_entity_decode($lang['seen']));
|
||||
else $columnindex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 2);
|
||||
if ($row['seen'] == 1) $worksheet->writeString($rowindex, $columnindex++, "X", $alignCenterFormat); else $columnindex++;
|
||||
}
|
||||
}
|
||||
// insertdate
|
||||
elseif ($field == "insertdate")
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $lang['date'], $headlineFormat);
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $lang['date'].":\n".html_entity_decode(preg_replace('/^([0-9]{4}\-[0-9]{2}\-[0-9]{2}).*/','$1',$row['created'])));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 10);
|
||||
$worksheet->write($rowindex, $columnindex++, html_entity_decode(preg_replace('/^([0-9]{4}\-[0-9]{2}\-[0-9]{2}).*/','$1',$row['created'])), $alignCenterFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// custom fields
|
||||
elseif(preg_match("/^custom[0-4]$/",$field))
|
||||
{
|
||||
// headline
|
||||
if ($config['xls_show_headline'] && $rowindex == 1 && !$isNote)
|
||||
$worksheet->writeString( 0, $columnindex, $config[$field], $headlineFormat);
|
||||
|
||||
//$row[$field] = html_entity_decode($row[$field]);
|
||||
|
||||
switch ($config[$field.'type'])
|
||||
{
|
||||
case 'ed2k':
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $config[$field].":\n".html_entity_decode($row[$field]));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 12);
|
||||
$worksheet->writeUrl($rowindex, $columnindex++, html_entity_decode($row[$field]), 'ED2K-Link', $alignCenterFormat);
|
||||
}
|
||||
break;
|
||||
case 'language':
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $config[$field].":\n".html_entity_decode($row[$field]));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 30);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row[$field]), $alignLeftFormat);
|
||||
}
|
||||
break;
|
||||
case 'rating':
|
||||
if ($row[$field]) $rating = html_entity_decode($row[$field]).'/10'; else $rating = "";
|
||||
if ($isNote)
|
||||
{
|
||||
if ($row[$field]) $worksheet->writeNote($rowindex, $columnindex, $config[$field].":\n".$rating);
|
||||
$columnindex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 7);
|
||||
if ($row[$field]) $worksheet->writeString($rowindex, $columnindex, $rating,$alignCenterFormat);
|
||||
$columnindex++;
|
||||
}
|
||||
break;
|
||||
case 'fsk':
|
||||
if (preg_match("/[0-9]+/",$row[$field]) && !preg_match("/[^0-9]+/",$row[$field]))
|
||||
{
|
||||
$fskstr = 'FSK'.html_entity_decode($row[$field]);
|
||||
}
|
||||
else $fskstr = html_entity_decode($row[$field]);
|
||||
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $config[$field].":\n".$fskstr);
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 7);
|
||||
$worksheet->writeString($rowindex, $columnindex++, $fskstr, $alignCenterFormat);
|
||||
}
|
||||
break;
|
||||
case 'barcode':
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $config[$field].":\n".html_entity_decode($row[$field]));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 15);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row[$field]), $alignCenterFormat);
|
||||
}
|
||||
break;
|
||||
case 'orgtitle':
|
||||
if ($isNote)
|
||||
{
|
||||
if (!empty($row[$field])) $worksheet->writeNote($rowindex, $columnindex, $config[$field]. ":\n".html_entity_decode($row[$field]));
|
||||
$columnindex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 50);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row[$field]), $alignLeftFormat);
|
||||
}
|
||||
break;
|
||||
case 'movix':
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $config[$field].":\n ".html_entity_decode($row[$field]));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 7);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row[$field]), $alignCenterFormat);
|
||||
}
|
||||
break;
|
||||
case 'mpaa':
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $config[$field].":\n".html_entity_decode($row[$field]), $alignCenterFormat);
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 12);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row[$field]), $alignCenterFormat);
|
||||
}
|
||||
break;
|
||||
case 'bbfc':
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $config[$field].":\n".html_entity_decode($row[$field]));
|
||||
else
|
||||
{
|
||||
if ($rowindex == 1) $worksheet->setColumn($columnindex, $columnindex, 7);
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row[$field]), $alignCenterFormat);
|
||||
}
|
||||
break;
|
||||
default: // unknown
|
||||
if ($isNote) $worksheet->writeNote($rowindex, $columnindex++, $config[$field].":\n".html_entity_decode($row[$field]));
|
||||
else
|
||||
{
|
||||
$worksheet->writeString($rowindex, $columnindex++, html_entity_decode($row[$field]), $alignLeftFormat);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} //End of walk
|
||||
|
||||
}
|
||||
$rowindex++;
|
||||
}
|
||||
// Let's send the file
|
||||
$workbook->close();
|
||||
}
|
||||
?>
|
||||
107
videodb/core/xml.core.php
Normal file
107
videodb/core/xml.core.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* XML support functions
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @version $Id: xml.core.php,v 1.8 2013/04/26 15:09:35 andig2 Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* See http://feedvalidator.org/docs/error/InvalidRFC2822Date.html
|
||||
*/
|
||||
$GLOBALS['rss_timestamp_format'] = 'D, j M Y H:i:s O';
|
||||
|
||||
/**
|
||||
* Encodes HTML entities into XML character entities
|
||||
* this avoids problems with unknown entities in XML
|
||||
*
|
||||
* @param string $string HTML string to encode
|
||||
* @return string encoded string containing XML character entities
|
||||
*/
|
||||
function encode_character_entities($string)
|
||||
{
|
||||
return strtr($string, get_html_translation_table(HTML_SPECIALCHARS));
|
||||
# return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an XML tag
|
||||
*
|
||||
* @param string $tag XML tag name
|
||||
* @param string $value value for XML tag
|
||||
* @param boolean $encode require encoding of tag value
|
||||
* @return string XML tag
|
||||
*/
|
||||
function createTag($tag, $value, $encode = true)
|
||||
{
|
||||
if ($encode) $value = encode_character_entities($value);
|
||||
return "<$tag>".$value."</$tag>\n";
|
||||
}
|
||||
|
||||
function createContainer($tag, $value = '')
|
||||
{
|
||||
return createTag($tag, $value, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert MySQL Date to RSS timestamp
|
||||
*
|
||||
* @return string RFC 2822 Date (http://feedvalidator.org/docs/error/InvalidRFC2822Date.html)
|
||||
*/
|
||||
function rss_timestamp($timestamp)
|
||||
{
|
||||
global $rss_timestamp_format;
|
||||
|
||||
// Lets sort this nasty timestamp nonsense out ;D
|
||||
$y = substr($timestamp, 0, 4);
|
||||
$m = substr($timestamp, 5, 2);
|
||||
$d = substr($timestamp, 8, 2);
|
||||
$h = substr($timestamp, 11, 2);
|
||||
$min = substr($timestamp, 14, 2);
|
||||
$s = substr($timestamp, 17, 2);
|
||||
|
||||
$timestamp = mktime($h, $min, $s, $m, $d, $y);
|
||||
|
||||
return date($rss_timestamp_format, $timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load XML into SimpleXML object
|
||||
* Fixes potential encoding issue
|
||||
*/
|
||||
function load_xml($data)
|
||||
{
|
||||
$xml = simplexml_load_string($data, $root = 'SimpleXMLElement', LIBXML_NOCDATA);
|
||||
|
||||
// character encoding warning- hack
|
||||
if ($xml === false)
|
||||
{
|
||||
$error = error_get_last();
|
||||
# dump($error);
|
||||
|
||||
// this is nasty- sometimes simplexml_load_string fails but doesn't raise an error
|
||||
if (preg_match('/simplexml_load_string/i', $error['message']))
|
||||
{
|
||||
$xml = simplexml_load_string(utf8_encode($data), $root, LIBXML_NOCDATA);
|
||||
}
|
||||
}
|
||||
|
||||
return $xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenate string-converted xml entities
|
||||
*/
|
||||
function xml_join($items, $str = "\n")
|
||||
{
|
||||
foreach ($items as $item)
|
||||
{
|
||||
if ($data) $data .= $str;
|
||||
$data .= (string) $item;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
?>
|
||||
186
videodb/core/xml.php
Normal file
186
videodb/core/xml.php
Normal file
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
/**
|
||||
* XML export functions
|
||||
*
|
||||
* Lets you browse through your movie collection
|
||||
*
|
||||
* @package Core
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
* @author Kokanovic Branko <branko.kokanovic@gmail.com>
|
||||
* @version $Id: xml.php,v 1.34 2013/03/10 16:25:35 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './core/export.core.php';
|
||||
require_once './core/xml.core.php';
|
||||
|
||||
/**
|
||||
* Export XML data
|
||||
*
|
||||
* @param string $where WHERE clause for SQL statement
|
||||
*/
|
||||
function xmlexport($WHERE)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// get data
|
||||
$result = exportData($WHERE);
|
||||
|
||||
// do adultcheck
|
||||
// this may not be needed as same check is done in exportData in previous statement
|
||||
if (is_array($result))
|
||||
{
|
||||
$result = array_filter($result, function($video) {return adultcheck($video["id"]);});
|
||||
}
|
||||
|
||||
$xml = '';
|
||||
|
||||
// loop over items
|
||||
foreach ($result as $item)
|
||||
{
|
||||
$xml_item = '';
|
||||
|
||||
// loop over attributes
|
||||
foreach ($item as $key => $value)
|
||||
{
|
||||
if (!empty($value))
|
||||
{
|
||||
if (($key != 'owner_id') && ($key != 'actors') && ($key != 'genres'))
|
||||
{
|
||||
$tag = strtolower($key);
|
||||
$xml_item .= createTag($tag, trim(html_entity_decode_all($value)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this is a hack for exporting thumbnail URLs
|
||||
if ($item['imgurl'] && $config['xml_thumbnails'])
|
||||
{
|
||||
$thumb = getThumbnail($item['imgurl']);
|
||||
if (preg_match('/cache/', $thumb))
|
||||
$xml_item .= createTag('thumbnail', trim($thumb));
|
||||
}
|
||||
|
||||
// genres
|
||||
if (count($item['genres']))
|
||||
{
|
||||
$xml_genres = '';
|
||||
foreach ($item['genres'] as $genre)
|
||||
{
|
||||
$xml_genres .= createTag('genre', $genre['name']);
|
||||
}
|
||||
$xml_item .= createContainer('genres', $xml_genres);
|
||||
}
|
||||
|
||||
// actors
|
||||
$actors = explode ("\n",$item['actors']);
|
||||
if (count($actors))
|
||||
{
|
||||
$xml_actors = '';
|
||||
foreach ($actors as $actor)
|
||||
{
|
||||
$xml_actor_data = '';
|
||||
$actor_data = explode("::",$actor);
|
||||
if (array_key_exists('1', $actor_data))
|
||||
{
|
||||
$xml_actor_data .= createTag('name', $actor_data[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$xml_actor_data .= createTag('name', '');
|
||||
}
|
||||
if (array_key_exists('1', $actor_data))
|
||||
{
|
||||
$xml_actor_data .= createTag('role', $actor_data[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$xml_actor_data .= createTag('role', '');
|
||||
}
|
||||
if (array_key_exists('2', $actor_data))
|
||||
{
|
||||
$xml_actor_data .= createTag('imdbid', $actor_data[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$xml_actor_data .= createTag('imdbid', '');
|
||||
}
|
||||
$xml_actors .= createContainer('actor', $xml_actor_data);
|
||||
}
|
||||
$xml_item .= createContainer('actors', $xml_actors);
|
||||
}
|
||||
$xml .= createContainer('item', $xml_item);
|
||||
}
|
||||
|
||||
$xml = '<?xml version="1.0" encoding="utf-8"?>'.
|
||||
"\n".createContainer('catalog', $xml);
|
||||
|
||||
// header('Content-type: text/xml');
|
||||
$mime = (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')) ? 'application/force-download' : 'application/octet-stream';
|
||||
header('Content-type: '.$mime);
|
||||
header('Content-length: '.strlen($xml));
|
||||
header('Content-disposition: attachment; filename=videoDB.xml');
|
||||
|
||||
echo $xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update RSS File
|
||||
*
|
||||
* @author Mike Clark <mike.clark@cinven.com>
|
||||
*/
|
||||
function rssexport($WHERE)
|
||||
{
|
||||
global $config, $rss_timestamp_format, $filter;
|
||||
|
||||
// make sure server doesn't specify something else
|
||||
header('Content-type: text/xml; charset=utf-8');
|
||||
|
||||
if ($filter)
|
||||
{
|
||||
$result = exportData($WHERE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// get the latest items from the DB according to config setting
|
||||
$SQL = 'SELECT id, title, plot, created
|
||||
FROM '.TBL_DATA.'
|
||||
ORDER BY created DESC LIMIT '.$config['shownew'];
|
||||
$result = runSQL($SQL);
|
||||
}
|
||||
|
||||
// script root
|
||||
$base = 'http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']);
|
||||
|
||||
// setup the RSS Feed
|
||||
$rssfeed = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
|
||||
$rssfeed .= '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">';
|
||||
$rssfeed .= '<channel>';
|
||||
$rssfeed .= '<atom:link href="'.$base.'/index.php?export=rss" rel="self" type="application/rss+xml" />';
|
||||
$rssfeed .= createTag('title', 'VideoDB');
|
||||
$rssfeed .= createTag('link', $base.'/index.php?export=rss');
|
||||
$rssfeed .= createTag('description', 'New items posted on VideoDB');
|
||||
$rssfeed .= createTag('language', 'en-us');
|
||||
$rssfeed .= createTag('lastBuildDate', date($rss_timestamp_format));
|
||||
|
||||
// build the <item></item> section of the Feed
|
||||
foreach ($result as $item)
|
||||
{
|
||||
$xml_item = createTag('title', $item['title']);
|
||||
$xml_item .= createTag('link', $base.'/show.php?id='.$item['id']);
|
||||
$xml_item .= createTag('description', $item['plot']);
|
||||
$xml_item .= createTag('guid', $base.'/show.php?id='.$item['id']);
|
||||
$xml_item .= createTag('pubDate', rss_timestamp($item['created']));
|
||||
|
||||
$rssfeed .= createTag('item', $xml_item, false);
|
||||
}
|
||||
$rssfeed .= '</channel>';
|
||||
$rssfeed .= '</rss>';
|
||||
|
||||
header('Content-type: text/xml');
|
||||
# header('Content-length: '.rssfeed($xml));
|
||||
# header('Content-disposition: filename=rss.xml');
|
||||
echo $rssfeed;
|
||||
}
|
||||
|
||||
?>
|
||||
78
videodb/delete.php
Normal file
78
videodb/delete.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* Delete a video
|
||||
*
|
||||
* Handles the deletion of a video
|
||||
*
|
||||
* @package videoDB
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @version $Id: delete.php,v 2.22 2013/03/10 16:20:31 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
|
||||
/**
|
||||
* input
|
||||
*/
|
||||
$id = req_int('id');
|
||||
$redirect = req_int('redirect');
|
||||
|
||||
/**
|
||||
* Remove image from cache
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
function removeCacheFile($url)
|
||||
{
|
||||
// get extension
|
||||
if (preg_match("/\.(jpe?g|gif|png)$/i", $url, $matches))
|
||||
{
|
||||
// check if file exists
|
||||
if (cache_file_exists($url, $cache_file, CACHE_IMG, $matches[1]))
|
||||
{
|
||||
@unlink($cache_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for localnet
|
||||
localnet_or_die();
|
||||
|
||||
// @todo check if post, fail if not?
|
||||
|
||||
// multiuser permission check
|
||||
permission_or_die(PERM_WRITE, get_owner_id($id));
|
||||
|
||||
/*
|
||||
// remove old cover image from cache
|
||||
$SQL = 'SELECT imgurl FROM '.TBL_DATA.' WHERE id = '.$id;
|
||||
$res = runSQL($SQL);
|
||||
if (count($res))
|
||||
{
|
||||
removeCacheFile($res[0]['imgurl']);
|
||||
}
|
||||
*/
|
||||
|
||||
// remove actual data
|
||||
runSQL('DELETE FROM '.TBL_DATA.' WHERE id = '.$id);
|
||||
runSQL('DELETE FROM '.TBL_VIDEOGENRE.' WHERE video_id = '.$id);
|
||||
|
||||
// clear smarty cache for this item
|
||||
#!! this does not work- at least not with Smarty3
|
||||
#$smarty->cache->clear($id);
|
||||
|
||||
// goto index instead of delete template
|
||||
if ($redirect)
|
||||
{
|
||||
header("Location: index.php?deleteid=$id");
|
||||
exit;
|
||||
}
|
||||
|
||||
// prepare templates
|
||||
tpl_page();
|
||||
|
||||
// display templates
|
||||
$smarty->assign('delete_meta', '<meta http-equiv="refresh"; content="1; url='.session_get('listview', 'index.php').'?'.strip_tags(SID).'">');
|
||||
tpl_display('delete.tpl');
|
||||
|
||||
|
||||
731
videodb/doc/CHANGES
Normal file
731
videodb/doc/CHANGES
Normal file
@@ -0,0 +1,731 @@
|
||||
# Version History
|
||||
|
||||
## videoDB Rel. 4.0
|
||||
|
||||
### 13.03.13
|
||||
- Created nexgen template based on Foundation CSS library
|
||||
- Added Foundation4 library
|
||||
- Upgraded to Smarty 3.1.10
|
||||
- Released videoDB 4.0pre
|
||||
|
||||
### 04.03.12
|
||||
- Upgraded to Smarty 3.1.8
|
||||
- Various PHP 5.4 compatibility fixes (Andreas Götz)
|
||||
|
||||
## videoDB Rel. 3.0
|
||||
|
||||
### 13.02.11 (3.1)
|
||||
- Loads of engine fixes, especially but not limited to IMDB
|
||||
- All bundled libraries upgraded
|
||||
|
||||
### 01.04.10
|
||||
- Various PHP 5.3 compatibility fixes (Andreas Götz)
|
||||
- Enhanced PDF output (Muddle)
|
||||
- Upgraded to Smarty 3 (Andreas Götz)
|
||||
|
||||
### 19.01.10
|
||||
- Added support for mod_fastcgi Basic authentication (Muddle)
|
||||
|
||||
### 25.03.09
|
||||
- Replaced outdated amazon engine with new Amazon Web Service (Andreas Götz)
|
||||
- Replaced partically broken google images engine with new google REST api (Andreas Götz)
|
||||
|
||||
### 05.03.09
|
||||
- Released v3.0.3
|
||||
|
||||
### 25.02.09
|
||||
- Fixed dvdb engine (Chinamann)
|
||||
- Fixed ofdb engine (Chinamann)
|
||||
- Fixed test classes for dvdb and dvdpalace engines (Chinamann)
|
||||
- Added test class for ofdb engine (Chinamann)
|
||||
- Fixed allocine engine and test (Martin Vauchel & Andreas Götz)
|
||||
- Fixed various character encoding issues (Andreas Götz)
|
||||
- Rewrote basic authentication code- should now provide seamless integration (Andreas Götz)
|
||||
|
||||
### 21.08.08
|
||||
- Fixed dvdb engine (Chinamann)
|
||||
- Fixed add_dvdb_barcode contrib (Chinamann)
|
||||
- Fixed OFDB engine (Chinamann)
|
||||
|
||||
### 20.01.08 (3.0a1)
|
||||
- Upgraded database schema to utf8- you can now have videos of various languages in one db
|
||||
- Revamped elegant template to support AJAX
|
||||
- Out-of-the-box thumbnail generation for better image quality and performance
|
||||
- Out-of-the-box support for PDF export
|
||||
- Various performance fixes
|
||||
- Added cantonese (Hong Kong) flag
|
||||
|
||||
### 03.12.07 (pre v3.0)
|
||||
- Added bundled fpdf and phpthumb libraries (Andreas Götz)
|
||||
|
||||
## videoDB Rel. 2.0
|
||||
|
||||
### 01.12.07
|
||||
- Fixed IMDB engine (Andreas Götz)
|
||||
- Upgraded xajax library to 0.5 (Andreas Götz)
|
||||
- Improved setup screen by calculating cache size in background (Andreas Götz)
|
||||
- Fixed various test cases (Andreas Götz)
|
||||
|
||||
### 08.09.07
|
||||
- Fixed PHP short tags (Andreas Götz)
|
||||
- Moved Smarty to /libs folder (Andreas Götz)
|
||||
|
||||
### 18.08.07
|
||||
- Fixed tv.com engine (Victor)
|
||||
- Fixed allocine.fr engine (tedemo)
|
||||
|
||||
### 10.08.07
|
||||
- Added support for youTube trailers (youtube developer key required)
|
||||
- More engine test cases (Sebastien)
|
||||
|
||||
### 15.07.07
|
||||
- Released videoDB 2.3.0
|
||||
- Upgraded Smarty to 2.6.18 (Andreas Götz)
|
||||
- Zillions of engine fixes
|
||||
- Added automated test cases for engines (Andreas Götz)
|
||||
|
||||
### 06.02.07
|
||||
- Completely rewritten OFDB engine (beta state) (Chinamann)
|
||||
|
||||
### 05.02.07
|
||||
- Fixed less privileged users can't use random, search, borrow and new/edit views even if the should (Chinamann)
|
||||
|
||||
### 17.01.07
|
||||
- Fixed security hole in show.php which enabled users to see movies they don't have access to (Chinamann)
|
||||
- Bugfix in stats.php: Don't count movies which are on the wishlist (Chinamann)
|
||||
|
||||
### 16.01.07
|
||||
- Fixed dvdb engine and improved fetching performance (Chinamann)
|
||||
- Fixed dvdpalace engine (Chinamann)
|
||||
- Fixed JavaScript error in elegant.css (Chinamann)
|
||||
- Added session status restore in httpClient (Chinamann)
|
||||
|
||||
### 11.11.06
|
||||
- Added template screenshots for selected templates (Andreas Götz)
|
||||
- Fixed an installer issue when upgrading (Andreas Götz)
|
||||
- Fixed [ 1596452 ] displaying movie takes a long time (Andreas Götz)
|
||||
|
||||
### 10.10.06
|
||||
- Upgraded Smarty to 2.6.14 (Andreas Götz)
|
||||
|
||||
### 04.10.06
|
||||
- Updated dvdfr engine (Seb)
|
||||
- Updated release scripts for new SF CVS settings (Andreas Götz)
|
||||
|
||||
### 03.10.06
|
||||
- Fixed IMDB cast issue (Andreas Götz)
|
||||
- Fixed include security issue Secunia advisory SA22184 (Andreas Götz)
|
||||
|
||||
### 05.07.06
|
||||
- Updated google image search engine according to google website updates (Andreas Götz)
|
||||
|
||||
### 28.03.06
|
||||
- added Aka search for IMDB (Andreas Götz)
|
||||
- split xml.tpl from header scripts for advanced and jeckyl template (Andreas Götz)
|
||||
|
||||
### 25.01.06
|
||||
- upgraded Smarty to 2.6.12 (Andreas Götz)
|
||||
|
||||
### 27.12.05
|
||||
- upgraded Smarty to 2.6.11 (Andreas Götz)
|
||||
|
||||
### 27.09.05
|
||||
- added dvdb user login support to acess FSK18 movies (Chinamann)
|
||||
|
||||
### 23.09.05
|
||||
- added favicons by Paul Leclair (Andreas Götz)
|
||||
- added previous/next navigation to show template (Andreas Götz)
|
||||
- added new auto DiskId calculation. Now: "next free" before: "highest+1" (Chinamann)
|
||||
- fixed external search (Chinamann)
|
||||
- added convert_engines contrib to switch between dvdpalace and dvdb engine (Chinamann)
|
||||
- added user and engine filter to refetchAllInfos contrib (Chinamann)
|
||||
- added imdbID prefix history functions to dvdb and dvdpalace engine (Chinamann)
|
||||
- fixed dvdb engine to avoid bad results if httpClient sends "Request Timeout" (Chinamann)
|
||||
|
||||
### 21.09.05
|
||||
- added DVDB.de engine (Chinamann)
|
||||
- changed barcode based adding contrib to use DVDB.de engine (Chinamann)
|
||||
- changed LableWriter Export to use DVDB.de engine (Chinamann)
|
||||
- added UTF8 support to httpClient (Chinamann)
|
||||
- added imdb-id-prefix also to imdb and changed it in dvdpalace engine (Chinamann)
|
||||
|
||||
### 01.09.05
|
||||
- PDF title formatting fix (Justin Pasher)
|
||||
- Excel export (Chinamann)
|
||||
- added Amazon.com engine (Andreas Götz)
|
||||
- added more IMDB genres (Andreas Götz)
|
||||
- added HTTP caching support (Andreas Götz)
|
||||
- upgraded Smarty to latest 2.6.10 (Andreas Götz)
|
||||
|
||||
### 31.07.05
|
||||
- Image max width/height values (pdf config file) (Justin Pasher)
|
||||
- Image width/height values (in the generated PDF) (pdf config file) (Justin Pasher)
|
||||
- Overall font size (pdf config file) (Justin Pasher)
|
||||
- Display mediatype next to diskid in the title for the movies (Justin Pasher)
|
||||
- Search form now display "Video Codec" in the "Search Fields" box (Justin Pasher)
|
||||
|
||||
### 15.06.05
|
||||
- fixed db prefix problems in create- and upgradescripts (Chinamann)
|
||||
- fixed "database not empty" problem even if different prefix is selected (Chinamann)
|
||||
- fixed bug [ 1199833 ] Database prefix not added when MySQL database is not empty (Chinamann)
|
||||
|
||||
### 24.05.05
|
||||
- added user to user permissions (Chinamann)
|
||||
- updated dvdpalace engine (Chinamann)
|
||||
- fixed bug [ 1122052 ] Automatic DiskID generation problem (Chinamann)
|
||||
|
||||
### 01.04.05
|
||||
- upgraded Smarty to latest 2.6.8 (Andreas Götz)
|
||||
|
||||
### 23.02.05
|
||||
- added engine config options (Andreas Götz)
|
||||
- added prelimenary improved episodes support (Andreas Götz)
|
||||
- added add_tv_episodes
|
||||
|
||||
### 10.02.05
|
||||
- added support for common table prefix for hosting environments (Andreas Götz)
|
||||
- added content drilldown to DvdInside engine (Andreas Götz)
|
||||
- added support for regrouping of articles (Andreas Götz)
|
||||
- added default values for list- and castcolumns to createtables.sql (Andreas Götz)
|
||||
- upgraded Smarty to latest 2.6.7 (Andreas Götz)
|
||||
- moved some language flags to images/flags/additional (Andreas Götz)
|
||||
|
||||
### 25.01.05
|
||||
- added HTTP basic auth support for use by RSS feed readers (Andreas Götz)
|
||||
- disabled IMDB browser access for anonymous users for security reasons
|
||||
- added new language flags (Constantinos Neophytou)
|
||||
|
||||
### 21.01.05
|
||||
- added langcheck tooltips update (Constantinos Neophytou)
|
||||
- added greek language files (Constantinos Neophytou)
|
||||
- applied multi-language patch (Constantinos Neophytou)
|
||||
|
||||
### 17.01.05
|
||||
- added https patch (Andreas Götz, thanks to Robert Hendricks)
|
||||
- added removal of html tags in title and subtitle (Andreas Götz)
|
||||
|
||||
### 05.01.05
|
||||
- security fix for javascript attacks (Andreas Götz, thanks to Holger van Lengerich)
|
||||
|
||||
### 28.12.04
|
||||
- fixed phpthumb code sometimes generating duplicate thumbnails
|
||||
- fixed custom fields not being copied from IMDB
|
||||
|
||||
### 24.12.04
|
||||
- added cache-less mode to avoid caching of IMDB queries (Andreas Götz)
|
||||
- various template fixes (bug 1084553, etc)
|
||||
- added swedish translations (Nisse Hellberg)
|
||||
- several security fixes (Andreas Götz, Steve Kemp)
|
||||
|
||||
### 15.11.04
|
||||
- even more PDF export fixes (Andreas Götz)
|
||||
|
||||
### 05.11.04
|
||||
- PDF export fixes
|
||||
- removed 'Adult' genres for users without permissions (Andreas Götz)
|
||||
- added default adult genre to the setup SQL (Andreas Götz)
|
||||
|
||||
### 27.10.04
|
||||
- added PDF export (Andreas Götz)
|
||||
- added advanced template (Elkin)
|
||||
|
||||
### 15.10.04
|
||||
- added thumbnail scaling using phpThumb for saving bandwidth (Andreas Götz)
|
||||
|
||||
### 20.09.04
|
||||
- moved javascripts to separate files for re-use (Andreas Götz)
|
||||
- moved xml headers to separate template file for re-use (Andreas Götz)
|
||||
- added xml import/export (Andreas Götz)
|
||||
- separated search field names in templates from physical columns names (Andreas Götz)
|
||||
- upgraded smarty to 2.6.5 (Andreas Götz)
|
||||
- added custom smarty function html_checkbox to get rid of the {if $video.seen}{else}{/if} (Andreas Götz)
|
||||
- added tool to decode html entities into ANSI characters (contrib/decode_entities.php)
|
||||
- fixed user dropdown (Mike Clark)
|
||||
|
||||
### 10.09.04
|
||||
- added hierarchical language files (Idea by Elkin)
|
||||
- added tool for finding recommendations (contrib/add_recommended_movies.php)
|
||||
- added owner dropdown for multiuser mode (PimpGoblin)
|
||||
|
||||
### 24.08.2004
|
||||
- added support for google image lookup (edit.tpl)
|
||||
- allowed to store engine as id prefix (experimental: imdb:081547)
|
||||
- upgraded search functionality to search any external site
|
||||
- added tool to remove orphans from image cache (contrib/clean_unused_images.php)
|
||||
- updated delete functionality to remove cover of deleted movie
|
||||
|
||||
### 16.08.2004
|
||||
- updated to allow drilldown on individual countries (if separated by ,)
|
||||
- major overhaul of installer (Andreas Götz)
|
||||
|
||||
### 15.08.2004
|
||||
- major overhaul of internal database structure
|
||||
- improved developer documentation
|
||||
|
||||
### 01.08.2004
|
||||
- Added indian language flag
|
||||
- small updates to the manual
|
||||
|
||||
### 03.07.2004
|
||||
- Not working search IMDB button fixed in default template
|
||||
|
||||
### 29.06.2004
|
||||
- Bugfix for PHP installation with missing '.' in include_path
|
||||
|
||||
### 28.06.2004
|
||||
- Bugfix for SQL error on user insert (Kris Senden)
|
||||
|
||||
### 27.06.2004
|
||||
- install.php (Andreas Götz)
|
||||
- upgrade accross multiple versions at once
|
||||
- jumps directly into upgrade step
|
||||
|
||||
### 21.06.2004
|
||||
- french update by Cyril Duveau
|
||||
- bugfix for german language file
|
||||
|
||||
### 19.06.2004
|
||||
- fixed support for admin to change owner
|
||||
- added per user seen value (statistics not updated yet)
|
||||
- bugfix for default lookup.tpl (no engine support yet)
|
||||
|
||||
### 11.06.2004
|
||||
- added amazon webservice (experimental) (Andreas Götz)
|
||||
- added compact.css (Andreas Götz)
|
||||
- modified imdboverwrite to be more flexible (Andreas Götz)
|
||||
|
||||
### 09.06.2004
|
||||
- small bugfix for contrib/tvtome.php
|
||||
- added access keys to default template
|
||||
|
||||
### 05.06.2004
|
||||
- Andreas Götz:
|
||||
- upgraded smarty 2.5 to 2.6.3 to ensure php5 compatibility
|
||||
- modified html_image to allow max_width and max_height parameters for
|
||||
modern template
|
||||
- Andreas Gohr:
|
||||
- fixed permission problems when logging out and in within the same
|
||||
browser session
|
||||
- added profile support to modern template
|
||||
- fetching gueststars in contrib/tvtome.php
|
||||
|
||||
### 03.06.2004
|
||||
- added <title> support for speaking html page titles (Andreas Götz)
|
||||
|
||||
### 01.06.2004
|
||||
- added installer support to write configuration back to
|
||||
config.inc.php (Andreas Götz)
|
||||
|
||||
### 28.05.2004
|
||||
- Various changes by Andreas Götz
|
||||
- added httpClient support for gzip-encoding
|
||||
- added httpClient support to remember redirects
|
||||
- reformatted error messages and added links to install.php
|
||||
- added preliminary multi-engine support
|
||||
- added improved video copy support
|
||||
- added referer patch by Mike Clark
|
||||
|
||||
### 16.05.2004
|
||||
- added user profiles
|
||||
|
||||
### 13.05.2004
|
||||
- bugfix for names containing quotes
|
||||
- bugfix for modern template CSS by Justin Pasher
|
||||
|
||||
### 10.05.2004
|
||||
- swedish language file by Nisse added
|
||||
- spanish update by Elkin Fricke
|
||||
- bugfix for tvtome.php by Elkin Fricke
|
||||
|
||||
### 09.05.2004
|
||||
- Multiuser Bug on deletion fixed by Stephan Hesmer
|
||||
- added a index.html (thx to Merle Reine)
|
||||
- added dvdadd.pl to contrib (based upon sample script by Elkin
|
||||
Fricke)
|
||||
- Request to Borrow Feature added some time in between ;-)
|
||||
- multiple minor changes and fixes by Andreas Götz and some
|
||||
others including some fixes on the IMDB integration
|
||||
|
||||
### 04.02.2004
|
||||
- language updates
|
||||
|
||||
### 29.12.2003
|
||||
- videoadd.pl supports the owner field
|
||||
- default template now uses the full screen width
|
||||
|
||||
### 21.12.2003
|
||||
- minor code cleanup
|
||||
- manual additions
|
||||
- use of security mechanisms for tvtome.php
|
||||
- all images are tried in the template directory first
|
||||
- VideoDB now checks for a loaded mysql PHP extension
|
||||
- videoadd.pl now sets the created timestamp
|
||||
- the # filter now matches foreign characters and special
|
||||
chars, too (thx to Justin Lim)
|
||||
- Now all fields from the videodata table are selected for list
|
||||
views (index and search) - more freedom for template designers
|
||||
|
||||
### 19.12.2003
|
||||
- bugfix for russian language file by Eugene Surov
|
||||
- Optional adult check for certain genres
|
||||
|
||||
### 29.11.2003
|
||||
- bugfix for IMDB Problem (thx to Andreas Götz and others)
|
||||
- more effective session init (Andreas Götz)
|
||||
|
||||
### 05.11.2003
|
||||
- no edit links on missing permissions in modern template
|
||||
- admin can change owner (thx to Mike Clark)
|
||||
|
||||
### 02.11.2003
|
||||
- small doc updates
|
||||
|
||||
### 26.10.2003
|
||||
- New custom type for MPAA ratings by Tim M. Sanders
|
||||
- bulgarian language update by drJekyll
|
||||
- polish update by Maciej Witkowiak
|
||||
|
||||
### 25.10.2003
|
||||
- french language update by Cyril Duveau
|
||||
- minor tweaks for modern template
|
||||
|
||||
### 23.10.2003
|
||||
- dutch language update by Kees de Bruin
|
||||
- german language updated
|
||||
|
||||
### 21.10.2003
|
||||
- small update for french language by Daniel Caujolle-Bert
|
||||
|
||||
### 19.10.2003
|
||||
- added new cutom type 'movix' by Antonio Giungato
|
||||
- added new default style 'metal'
|
||||
|
||||
### 15.10.2003
|
||||
- new Multiplayer code based on many code contributions by Mike
|
||||
Clark and some by "weber"
|
||||
|
||||
### 03.10.2003
|
||||
- added new stylesheet for the default template by Joakim Sandén
|
||||
|
||||
### 21.09.2003
|
||||
- spanish update by Elkin Fricke
|
||||
- DB versioning
|
||||
|
||||
### 17.09.2003
|
||||
- Added missing <?xml ?> header
|
||||
|
||||
### 16.09.2003
|
||||
- Dutch update by Kees de Bruin
|
||||
|
||||
### 15.09.2003
|
||||
- Manual and Helpbrowser added
|
||||
- random view does no longer show wishlist items
|
||||
- French update by Cyril Duveau
|
||||
- Bulgarian Update by drJekyll
|
||||
- movies are only marked as new when added not when changed anymore
|
||||
|
||||
### 14.09.2003
|
||||
- Portuguese update by Tiago Fonseca, Brasilian Portuguese
|
||||
by Marcus Leandro
|
||||
|
||||
### 08.09.2003
|
||||
- Italian update by Antonio Giungato
|
||||
|
||||
### 07.09.2003
|
||||
- language checker added to the contrib directory
|
||||
|
||||
### 04.09.2003
|
||||
- all IMDB functions now use the new link formats
|
||||
- imdbData now returns a hash
|
||||
|
||||
### 30.08.2003
|
||||
- bugfix for new imdb link format by Charles Morgan
|
||||
|
||||
### 29.08.2003
|
||||
- french update by Cyril Duveau
|
||||
- patch to enable upload from an URL in Konquerer by Stephan Zalewski
|
||||
- Userdefinable config table (by Stephan Zalewski)
|
||||
- Brazillian portuguese Language by Marcus Leandro added
|
||||
|
||||
### 27.08.2003
|
||||
- custom type for original title by Stephan Zalewski
|
||||
- better cachedirectory checks
|
||||
|
||||
### 26.08.2003
|
||||
- POST support for HTTP client by Andreas Götz
|
||||
- IMDB-Browser by Andreas Götz
|
||||
|
||||
### 25.08.2003
|
||||
- bulgarian language update by drJekyll
|
||||
|
||||
### 23.08.2003
|
||||
- spanish update by Elkin Fricke
|
||||
- bugfix for HTTP caching on windows
|
||||
- lots of comments added its now possible to generate a API doc with phpDocumentor
|
||||
|
||||
### 21.08.2003
|
||||
- small wishlist bugfix by Andreas Götz
|
||||
- Number of shown movies in new filter is cutomizable now (Patch by Stephan Zalewski)
|
||||
- improvements to the year statistic
|
||||
|
||||
### 18.08.2003
|
||||
- minor template tweaks (default)
|
||||
- updated spanish translation by Elkin Fricke
|
||||
- idea for year statistic implemented not finished yet
|
||||
|
||||
### 17.08.2003
|
||||
- setup.php uses REPLACE now
|
||||
- merged multi template with default
|
||||
- new template by Andreas Götz: modern
|
||||
- Fixed bug with interfering environment variables (Thanks to
|
||||
Raymond Scholz pointing that out)
|
||||
- nocover image is now a transparent gif - Templates can use
|
||||
their own.
|
||||
- Added a new rating custom type which uses the IMDB rating as
|
||||
a default
|
||||
- Search now works with ' in queries (Fixes Ed O'Neill)
|
||||
- Fixed error when selecting random on an empty database
|
||||
- New Mediatype 'wanted' for building a wishlist of movies (Idea by
|
||||
Andreas Götz)
|
||||
- Cover-Upload by Stephan Zalewski
|
||||
- some template tuning
|
||||
|
||||
### 11.08.2003
|
||||
- bugfix by Harald Leithner for mediadefault in setup.php
|
||||
- bulgarian update by drJekyll
|
||||
- minor template fixes
|
||||
|
||||
### 10.08.2003
|
||||
- Enhancement of the imdbActor function
|
||||
- Updated french language by Cyril Duveau
|
||||
- local files in the cover field now work again
|
||||
- setup.tpl is now independent from the available setup options
|
||||
- changed the random function again please send me a mail if it
|
||||
isn't random enough
|
||||
|
||||
### 09.08.2003
|
||||
- New template (multi) and some minor codechanges (Andreas Götz)
|
||||
- Fix for missing director and country fields in show.php
|
||||
- Not found actorthumbnails are retried after specified age
|
||||
|
||||
### 07.08.2003
|
||||
- Patches by Andreas Götz:
|
||||
- fix for chunked encoding which makes http/1.1 possible
|
||||
- enhanced imdbActor function
|
||||
- bugfix for IMDB caching function
|
||||
- Bulgarian language update by drJekyll
|
||||
|
||||
### 05.08.2003
|
||||
- Spanish language updates by Elkin Fricke
|
||||
|
||||
### 03.08.2003
|
||||
- IMDB cache reimplemented
|
||||
- small fix for imdbActors by Andreas Götz
|
||||
- Translation update for russian language by Konstantin Boudnik
|
||||
|
||||
### 31.07.2003
|
||||
- Dutch translation updated by Kees de Bruin
|
||||
|
||||
### 30.07.2003
|
||||
- update for the portuguese languagefile by Nuno Nunes
|
||||
- Some updates to the new proxy enabled download function
|
||||
- Experimental support for actor fotos by Andreas Götz
|
||||
|
||||
### 29.07.2003
|
||||
- Bulgarian languagefile by drJekyll added
|
||||
- spanish language update by ctRl
|
||||
- Proxy support by Andreas Götz
|
||||
|
||||
### 28.07.2003
|
||||
- Bugfix for the ID assigning problem which made adding new videos impossible (sorry folks)
|
||||
- image cacheing is now handled seperately by img.php
|
||||
|
||||
### 26.07.2003
|
||||
- Small fix by Andreas Götz for autoDiskID calculation
|
||||
|
||||
### 20-25.07.2003
|
||||
- Everything is better now! :-) I like to call it Version 2
|
||||
- Templates with Smarty
|
||||
- Webbased, database stored config
|
||||
- SQL function now returns associative arrays
|
||||
- much code cleanup
|
||||
- display bug in Linux Opera fixed
|
||||
- a TODO file was added
|
||||
- Style by drJeckyll added
|
||||
|
||||
### 20.07.2003
|
||||
- Patch by Andreas Götz to fix the genre links in show.php
|
||||
- The TV-Episode switch is now stored in the session (Patch by Thomas Zajik)
|
||||
|
||||
### 17.07.2003
|
||||
- Now checkboxlabels are clickable (patch by Kjetil Thuen)
|
||||
|
||||
### 16.07.2003
|
||||
- Fixed the random function to produce more random values
|
||||
|
||||
### 15.07.2003
|
||||
- Unavailable movies are now shown in red on the browsing view (Thanks to Alexandre Thomas for the idea)
|
||||
- The french translation was corrected by Alexandre Thomas
|
||||
|
||||
### 14.07.2003
|
||||
- Added russian language file by Konstantin Boudnik
|
||||
- bugfix for orderallbydiskid
|
||||
|
||||
### 05.07.2003
|
||||
- Incorporated lots of changes by Nicola Asuni (www.tecnick.com
|
||||
info@tecnick.com)
|
||||
- The output is in XHTML 1.0 Transitional
|
||||
- some PHP bugs has been removed
|
||||
- code cleanup
|
||||
- directory hierachy was redesigned
|
||||
- Added portuguese languagefile by Nuno Nunes
|
||||
- The style can be changed from the config file
|
||||
|
||||
### 21.06.2003
|
||||
- changed error_reporting to show fatal errors and parse errors this
|
||||
should make debugging of custom function easier
|
||||
|
||||
### 20.06.2003
|
||||
- added polish language file by Maciej Witkowiak
|
||||
- charsetencoding is now set with the languagefile
|
||||
- czech and polish flags added
|
||||
|
||||
### 19.06.2003
|
||||
- You can now define your own input/output functions for the custom fields. see custom.php
|
||||
- videoadd.pl now uses mplayer for getting video informations, it can create md4 sums for edonkey links, too (thx to Frank Schubert for the idea)
|
||||
- The recursion bug in videoadd now really is fixed
|
||||
|
||||
### 12.06.2003
|
||||
- added missing top.gif
|
||||
|
||||
### 09.06.2003
|
||||
- some more language flags and a new config option for language quick select buttons were added
|
||||
- cosmetic changes
|
||||
- infinite recursion fixed in videoadd.pl
|
||||
|
||||
### 01.06.2003
|
||||
- Cast is displayed in multiple columns now (Idea by Andreas Götz)
|
||||
- videoadd.pl now scans recursivly for files - this should work with (S)VCDs can anyone confirm that?
|
||||
|
||||
### 30.05.2003
|
||||
- fixed a small bug in the IMDB cast parser
|
||||
|
||||
### 28.05.2003
|
||||
- Updated the README a little bit
|
||||
|
||||
### 25.05.2003
|
||||
- back to top link on every page
|
||||
- Patches by Andreas Götz
|
||||
- addslashes for delete JavaScript (fixes problems with "Charlie's Angels")
|
||||
- The filtersetting is now saved in a session
|
||||
|
||||
### 24.05.2003
|
||||
- added french language file by Cyril Duveau
|
||||
- disabled error_reporting in nondebugmode
|
||||
|
||||
### 09.05.2003
|
||||
- Patches by Andreas Götz
|
||||
- bug fix for the new Cast IMDB parser (bad HREFs removed)
|
||||
- you can set a default language for new movies
|
||||
- thumbnails when browsing - sweet :-)
|
||||
|
||||
### 22.04.2003
|
||||
- added patches by Raymond Scholz:
|
||||
- little bug on custom fields fixed
|
||||
- IMDB parser now gets the runtime right on movies >999 min
|
||||
- The cast is now fetched from the extended credits page
|
||||
|
||||
### 17.04.2003
|
||||
- videoadd.pl now always sets the mediatype to CD-R and a bug in the titelguesser was fixed
|
||||
|
||||
### 23.03.2003
|
||||
- more statistics
|
||||
|
||||
### 18.03.2003
|
||||
- Dutch translation by Kees de Bruin added
|
||||
- IMDB parser now splits Title from Subtitle at " - " instead of "-" (patch by Kees de Bruin)
|
||||
|
||||
### 17.03.2003
|
||||
- added some JavaScript to enable the IMDB lookup by default when the IMBD-ID is changed
|
||||
- added an option to let IMDB lookups replace existing data
|
||||
|
||||
### 16.03.2003
|
||||
- various patches by "unknown":
|
||||
- saving new items without a genre with no errors from functions.php line 87
|
||||
- stop imdb lookup when searching on empty title/subtitle (window still shows but it is faster as it does nothing)
|
||||
- stop imdb lookup when selected checkbox "lookup missing data from imdb" and there is no imdb item value before clicking save
|
||||
- option to show listing entries sorted by diskid
|
||||
- allow editing seen option from inside edit screen
|
||||
- show total hours seen (watched) in statistics
|
||||
- added "Adult" genre
|
||||
- IMDB caching now works on redirects, too
|
||||
|
||||
### 15.03.2003
|
||||
- added spanish translation contributed by "Orko"
|
||||
|
||||
### 06.03.2003
|
||||
- linked the categories from the statistics page to the search
|
||||
|
||||
### 02.03.2003
|
||||
- applied some Patches by Cameron W. Johnston to add support for
|
||||
various writable DVD formats
|
||||
|
||||
### 04.02.2003
|
||||
- fixed a problem with duplicate keys on genre inserts
|
||||
|
||||
### 02.02.2003
|
||||
- The default filter can be set in the config (thx to Dale Blount)
|
||||
- removed the useless 'Edit' and 'View' link on the respective pages (thx to Stephen Tomkinson)
|
||||
- only nonempty fields are shown in the movie view (thx to Stephen Tomkinson)
|
||||
- Category names are linked to the search (thx to Stephen again)
|
||||
- empty years default to 0000 instead 2002 now
|
||||
- Version tag added
|
||||
|
||||
### 30.01.2003
|
||||
- Useragent of IMDB grabber is now IE and IMDB queries are now cached locally (thx to Marc Schoenefeld and Andreas Götz)
|
||||
|
||||
### 25.01.2003
|
||||
- new Perl script direxport.pl added
|
||||
- splitbrain link at the bottom now links directly to the videodb page
|
||||
|
||||
### 24.01.2003
|
||||
- fixed another small bugs in the IMDBgrabber and added a new search.gif (again: all the fame goes to Antonio :-))
|
||||
|
||||
### 23.01.2003
|
||||
- made search DISTINCT (thx to Antonio Giungato)
|
||||
- IMDBfetcher now grabs 'Runtime: USA: 110 min' correctly (thx to Antonio again)
|
||||
- added mediatype dropdown (thx to Rob Vonk)
|
||||
- added custom fields
|
||||
- limit edit to localnet only (thx to Jens Oberender)
|
||||
|
||||
### 20.01.2003
|
||||
- "column 'comment' specified twice" error removed (ARGG! STUPID ME!)
|
||||
- languages with no flag available don't result in a broken image anymore
|
||||
|
||||
### 19.01.2003
|
||||
- started a changefile ;-)
|
||||
- you may add a comment to each movie (currently 255 chars - mail me if that is a problem)
|
||||
- "lent tofred" solved
|
||||
- diskid '0' is possible now
|
||||
- actors and director is linked to the search (works pretty well)
|
||||
- changed the link color
|
||||
- borrow manager links to the first movie on disk
|
||||
- magic quote problems hopfully solved forever
|
||||
|
||||
### 16.01.2003
|
||||
- better borrowmanager, various smaller bugfixes and improvements
|
||||
|
||||
### 12.01.2003
|
||||
- It now works with register_globals=off.
|
||||
- Title and subtilefetching added.
|
||||
- Problems with gpc_magicquotes solved.
|
||||
|
||||
### 11.01.2003
|
||||
- Much better IMDB Search :-)
|
||||
|
||||
### 06.01.2003 17:00
|
||||
- Fixed a typo in the english language file
|
||||
- Grabbing the plot and image URL from IMDB now works again.
|
||||
|
||||
### 06.01.2003
|
||||
- Thanks to Marcel Spitau <marcel at spitau dot de> VideoDB now supports multiple languages. Currently english and german is available. But adding your own language is easy. If you do so please send in your language file!
|
||||
340
videodb/doc/COPYING
Normal file
340
videodb/doc/COPYING
Normal file
@@ -0,0 +1,340 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
1
videodb/doc/INSTALL
Normal file
1
videodb/doc/INSTALL
Normal file
@@ -0,0 +1 @@
|
||||
See README
|
||||
66
videodb/doc/README
Normal file
66
videodb/doc/README
Normal file
@@ -0,0 +1,66 @@
|
||||
INSTALL
|
||||
|
||||
- Be sure to have a recent PHP version! At least 5.3 with GD library is required
|
||||
- copy all files in a directory somewhere below your webserver root
|
||||
|
||||
Do one of these steps:
|
||||
|
||||
- point your browser the install.php and follow the instructions
|
||||
|
||||
or (not recommended since v2.0)
|
||||
|
||||
- create a MySQL-Database using the table definitions in install/install.sql
|
||||
- edit the config.inc.php to match your database
|
||||
|
||||
- point your browser to your new VideoDB and add some movies
|
||||
- customize everything in the config screen
|
||||
|
||||
UPDATING FROM A PRIOR VERSION
|
||||
|
||||
- extract the new videoDB archive into the same folder as your old installation
|
||||
- open videoDB- the system will recognize that upgrade is required and start install.php
|
||||
|
||||
or
|
||||
|
||||
- manually point your browser to install.php
|
||||
|
||||
- follow the instructions
|
||||
|
||||
or (not recommended since v2.0)
|
||||
|
||||
- run doc/updatedb.sql over your existing database with the -f option to
|
||||
force mysql to ignore errors. This *should* not delete any of your data.
|
||||
e.g.
|
||||
mysql -p -f VideoDB < doc/updatedb.sql
|
||||
|
||||
- check out new config options in the config screen
|
||||
|
||||
CUSTOMIZING
|
||||
|
||||
- You can define up to four custom fields in the config screen
|
||||
- You can add input and output functions for them in custom.php
|
||||
- You can add additional stylesheets by dropping them into the template
|
||||
directory (e.g. templates/default/)
|
||||
- You can create your own templates by putting them into their own
|
||||
directory in templates/
|
||||
- Whenever you do anything of the above please send it to me
|
||||
|
||||
PROBLEMS/FEEDBACK
|
||||
|
||||
- Use the mailinglist to contact the developers at
|
||||
http://lists.sourceforge.net/mailman/listinfo/videodb-devel
|
||||
|
||||
THANKS
|
||||
|
||||
- all the people mentioned in the CHANGELOG
|
||||
- all th people who made the wonderful free software this project is
|
||||
based on (e.g. Developers of PHP, Smarty, Apache, MySQL, Linux)
|
||||
|
||||
LICENSE
|
||||
|
||||
VideoDB is released under the GNU General Public License (GPL)
|
||||
See COPYING for more Info
|
||||
|
||||
VideoDB comes with the Smarty Template Engine
|
||||
Smarty is released under the GNU Lesser General Public License (LGPL)
|
||||
See COPYING.lib in the smarty directory for more Info
|
||||
30
videodb/doc/TODO
Normal file
30
videodb/doc/TODO
Normal file
@@ -0,0 +1,30 @@
|
||||
Here are some things that still have to be done. I add my thoughts
|
||||
|
||||
about them, too. So you have an idea how likely you will see them
|
||||
|
||||
in the next version.
|
||||
|
||||
If you want to do some of them *please* do so! I'm drowning in work.
|
||||
|
||||
|
||||
|
||||
This file is always slightly out of date - to have full insight in
|
||||
|
||||
the ongoing development process join the mailing list!
|
||||
|
||||
|
||||
|
||||
* Template-Creation HOWTO
|
||||
|
||||
- which variables are available in which template and so on
|
||||
|
||||
|
||||
|
||||
* Update/Add language files
|
||||
|
||||
- Yes please do so! You may even correct my bad english!
|
||||
|
||||
|
||||
|
||||
* Export-Function
|
||||
|
||||
1
videodb/doc/VERSION
Normal file
1
videodb/doc/VERSION
Normal file
@@ -0,0 +1 @@
|
||||
4_0_0
|
||||
5
videodb/doc/development/README.txt
Normal file
5
videodb/doc/development/README.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
The database design was modeled with FabForce DBModeler
|
||||
|
||||
To work with this model download from http://www.fabforce.net/downloads.php
|
||||
|
||||
cpuidle@gmx.de
|
||||
BIN
videodb/doc/development/datamodel.png
Normal file
BIN
videodb/doc/development/datamodel.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
803
videodb/doc/development/videoDB Data Model v2.xml
Normal file
803
videodb/doc/development/videoDB Data Model v2.xml
Normal file
@@ -0,0 +1,803 @@
|
||||
<?xml version="1.0" standalone="yes" ?>
|
||||
<DBMODEL Version="4.0">
|
||||
<SETTINGS>
|
||||
<GLOBALSETTINGS ModelName="videoDB v2" IDModel="3" IDVersion="4" VersionStr="1.0.0.1" Comments="" UseVersionHistroy="1" AutoIncVersion="1" DatabaseType="MySQL" ZoomFac="91.00" XPos="151" YPos="310" DefaultDataType="5" DefaultTablePrefix="0" DefSaveDBConn="dbdesigner" DefSyncDBConn="videodb_localhost" DefQueryDBConn="" Printer="" HPageCount="4.0" PageAspectRatio="1.440892512336408" PageOrientation="1" PageFormat="A4 (210x297 mm, 8.26x11.7 inches)" SelectedPages="" UsePositionGrid="1" PositionGridX="20" PositionGridY="20" TableNameInRefs="0" DefaultTableType="0" ActivateRefDefForNewRelations="1" FKPrefix="" FKPostfix="" CreateFKRefDefIndex="0" DBQuoteCharacter="`" CreateSQLforLinkedObjects="0" DefModelFont="Tahoma" CanvasWidth="4096" CanvasHeight="2842" />
|
||||
<DATATYPEGROUPS>
|
||||
<DATATYPEGROUP Name="Numeric Types" Icon="1" />
|
||||
<DATATYPEGROUP Name="Date and Time Types" Icon="2" />
|
||||
<DATATYPEGROUP Name="String Types" Icon="3" />
|
||||
<DATATYPEGROUP Name="Blob and Text Types" Icon="4" />
|
||||
<DATATYPEGROUP Name="User defined Types" Icon="5" />
|
||||
<DATATYPEGROUP Name="Geographic Types" Icon="6" />
|
||||
</DATATYPEGROUPS>
|
||||
<DATATYPES>
|
||||
<DATATYPE ID="1" IDGroup="0" TypeName="TINYINT" Description="A very small integer. The signed range is -128 to 127. The unsigned range is 0 to 255." ParamCount="1" OptionCount="2" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="length" />
|
||||
</PARAMS>
|
||||
<OPTIONS>
|
||||
<OPTION Name="UNSIGNED" Default="1" />
|
||||
<OPTION Name="ZEROFILL" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="2" IDGroup="0" TypeName="SMALLINT" Description="A small integer. The signed range is -32768 to 32767. The unsigned range is 0 to 65535." ParamCount="1" OptionCount="2" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="length" />
|
||||
</PARAMS>
|
||||
<OPTIONS>
|
||||
<OPTION Name="UNSIGNED" Default="1" />
|
||||
<OPTION Name="ZEROFILL" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="3" IDGroup="0" TypeName="MEDIUMINT" Description="A medium-size integer. The signed range is -8388608 to 8388607. The unsigned range is 0 to 16777215." ParamCount="1" OptionCount="2" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="length" />
|
||||
</PARAMS>
|
||||
<OPTIONS>
|
||||
<OPTION Name="UNSIGNED" Default="1" />
|
||||
<OPTION Name="ZEROFILL" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="4" IDGroup="0" TypeName="INT" Description="A normal-size integer. The signed range is -2147483648 to 2147483647. The unsigned range is 0 to 4294967295." ParamCount="1" OptionCount="2" ParamRequired="0" EditParamsAsString="0" SynonymGroup="1" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="length" />
|
||||
</PARAMS>
|
||||
<OPTIONS>
|
||||
<OPTION Name="UNSIGNED" Default="0" />
|
||||
<OPTION Name="ZEROFILL" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="5" IDGroup="0" TypeName="INTEGER" Description="A normal-size integer. The signed range is -2147483648 to 2147483647. The unsigned range is 0 to 4294967295." ParamCount="1" OptionCount="2" ParamRequired="0" EditParamsAsString="0" SynonymGroup="1" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="length" />
|
||||
</PARAMS>
|
||||
<OPTIONS>
|
||||
<OPTION Name="UNSIGNED" Default="1" />
|
||||
<OPTION Name="ZEROFILL" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="6" IDGroup="0" TypeName="BIGINT" Description="A large integer. The signed range is -9223372036854775808 to 9223372036854775807. The unsigned range is 0 to 18446744073709551615." ParamCount="1" OptionCount="2" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="length" />
|
||||
</PARAMS>
|
||||
<OPTIONS>
|
||||
<OPTION Name="UNSIGNED" Default="0" />
|
||||
<OPTION Name="ZEROFILL" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="7" IDGroup="0" TypeName="FLOAT" Description="A small (single-precision) floating-point number. Cannot be unsigned. Allowable values are -3.402823466E+38 to -1.175494351E-38, 0, and 1.175494351E-38 to 3.402823466E+38." ParamCount="1" OptionCount="1" ParamRequired="1" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="precision" />
|
||||
</PARAMS>
|
||||
<OPTIONS>
|
||||
<OPTION Name="ZEROFILL" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="8" IDGroup="0" TypeName="FLOAT" Description="A small (single-precision) floating-point number. Cannot be unsigned. Allowable values are -3.402823466E+38 to -1.175494351E-38, 0, and 1.175494351E-38 to 3.402823466E+38." ParamCount="2" OptionCount="1" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="length" />
|
||||
<PARAM Name="decimals" />
|
||||
</PARAMS>
|
||||
<OPTIONS>
|
||||
<OPTION Name="ZEROFILL" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="9" IDGroup="0" TypeName="DOUBLE" Description="A normal-size (double-precision) floating-point number. Cannot be unsigned. Allowable values are -1.7976931348623157E+308 to -2.2250738585072014E-308, 0, and 2.2250738585072014E-308 to 1.7976931348623157E+308." ParamCount="2" OptionCount="1" ParamRequired="0" EditParamsAsString="0" SynonymGroup="2" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="length" />
|
||||
<PARAM Name="decimals" />
|
||||
</PARAMS>
|
||||
<OPTIONS>
|
||||
<OPTION Name="ZEROFILL" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="10" IDGroup="0" TypeName="DOUBLE PRECISION" Description="This is a synonym for DOUBLE." ParamCount="2" OptionCount="1" ParamRequired="0" EditParamsAsString="0" SynonymGroup="2" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="length" />
|
||||
<PARAM Name="decimals" />
|
||||
</PARAMS>
|
||||
<OPTIONS>
|
||||
<OPTION Name="ZEROFILL" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="11" IDGroup="0" TypeName="REAL" Description="This is a synonym for DOUBLE." ParamCount="2" OptionCount="1" ParamRequired="0" EditParamsAsString="0" SynonymGroup="2" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="length" />
|
||||
<PARAM Name="decimals" />
|
||||
</PARAMS>
|
||||
<OPTIONS>
|
||||
<OPTION Name="ZEROFILL" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="12" IDGroup="0" TypeName="DECIMAL" Description="An unpacked floating-point number. Cannot be unsigned. Behaves like a CHAR column." ParamCount="2" OptionCount="1" ParamRequired="0" EditParamsAsString="0" SynonymGroup="3" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="length" />
|
||||
<PARAM Name="decimals" />
|
||||
</PARAMS>
|
||||
<OPTIONS>
|
||||
<OPTION Name="ZEROFILL" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="13" IDGroup="0" TypeName="NUMERIC" Description="This is a synonym for DECIMAL." ParamCount="2" OptionCount="1" ParamRequired="1" EditParamsAsString="0" SynonymGroup="3" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="length" />
|
||||
<PARAM Name="decimals" />
|
||||
</PARAMS>
|
||||
<OPTIONS>
|
||||
<OPTION Name="ZEROFILL" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="14" IDGroup="1" TypeName="DATE" Description="A date. The supported range is \a1000-01-01\a to \a9999-12-31\a." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="15" IDGroup="1" TypeName="DATETIME" Description="A date and time combination. The supported range is \a1000-01-01 00:00:00\a to \a9999-12-31 23:59:59\a." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="16" IDGroup="1" TypeName="TIMESTAMP" Description="A timestamp. The range is \a1970-01-01 00:00:00\a to sometime in the year 2037. The length can be 14 (or missing), 12, 10, 8, 6, 4, or 2 representing YYYYMMDDHHMMSS, ... , YYYYMMDD, ... , YY formats." ParamCount="1" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="length" />
|
||||
</PARAMS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="17" IDGroup="1" TypeName="TIME" Description="A time. The range is \a-838:59:59\a to \a838:59:59\a." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="18" IDGroup="1" TypeName="YEAR" Description="A year in 2- or 4-digit format (default is 4-digit)." ParamCount="1" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="length" />
|
||||
</PARAMS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="19" IDGroup="2" TypeName="CHAR" Description="A fixed-length string (1 to 255 characters) that is always right-padded with spaces to the specified length when stored. values are sorted and compared in case-insensitive fashion according to the default character set unless the BINARY keyword is given." ParamCount="1" OptionCount="1" ParamRequired="1" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="length" />
|
||||
</PARAMS>
|
||||
<OPTIONS>
|
||||
<OPTION Name="BINARY" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="20" IDGroup="2" TypeName="VARCHAR" Description="A variable-length string (1 to 255 characters). Values are sorted and compared in case-sensitive fashion unless the BINARY keyword is given." ParamCount="1" OptionCount="1" ParamRequired="1" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="length" />
|
||||
</PARAMS>
|
||||
<OPTIONS>
|
||||
<OPTION Name="BINARY" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="21" IDGroup="2" TypeName="BIT" Description="This is a synonym for CHAR(1)." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="22" IDGroup="2" TypeName="BOOL" Description="This is a synonym for CHAR(1)." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="23" IDGroup="3" TypeName="TINYBLOB" Description="A column maximum length of 255 (2^8 - 1) characters. Values are sorted and compared in case-sensitive fashion." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="24" IDGroup="3" TypeName="BLOB" Description="A column maximum length of 65535 (2^16 - 1) characters. Values are sorted and compared in case-sensitive fashion." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="25" IDGroup="3" TypeName="MEDIUMBLOB" Description="A column maximum length of 16777215 (2^24 - 1) characters. Values are sorted and compared in case-sensitive fashion." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="26" IDGroup="3" TypeName="LONGBLOB" Description="A column maximum length of 4294967295 (2^32 - 1) characters. Values are sorted and compared in case-sensitive fashion." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="27" IDGroup="3" TypeName="TINYTEXT" Description="A column maximum length of 255 (2^8 - 1) characters." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="28" IDGroup="3" TypeName="TEXT" Description="A column maximum length of 65535 (2^16 - 1) characters." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="29" IDGroup="3" TypeName="MEDIUMTEXT" Description="A column maximum length of 16777215 (2^24 - 1) characters." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="30" IDGroup="3" TypeName="LONGTEXT" Description="A column maximum length of 4294967295 (2^32 - 1) characters." ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="31" IDGroup="3" TypeName="ENUM" Description="An enumeration. A string object that can have only one value, chosen from the list of values." ParamCount="1" OptionCount="0" ParamRequired="1" EditParamsAsString="1" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="values" />
|
||||
</PARAMS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="32" IDGroup="3" TypeName="SET" Description="A set. A string object that can have zero or more values, each of which must be chosen from the list of values." ParamCount="1" OptionCount="0" ParamRequired="1" EditParamsAsString="1" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<PARAMS>
|
||||
<PARAM Name="values" />
|
||||
</PARAMS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="33" IDGroup="4" TypeName="Varchar(20)" Description="" ParamCount="0" OptionCount="1" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<OPTIONS>
|
||||
<OPTION Name="BINARY" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="34" IDGroup="4" TypeName="Varchar(45)" Description="" ParamCount="0" OptionCount="1" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<OPTIONS>
|
||||
<OPTION Name="BINARY" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="35" IDGroup="4" TypeName="Varchar(255)" Description="" ParamCount="0" OptionCount="1" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
<OPTIONS>
|
||||
<OPTION Name="BINARY" Default="0" />
|
||||
</OPTIONS>
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="36" IDGroup="5" TypeName="GEOMETRY" Description="Geographic Datatype" ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="38" IDGroup="5" TypeName="LINESTRING" Description="Geographic Datatype" ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="39" IDGroup="5" TypeName="POLYGON" Description="Geographic Datatype" ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="40" IDGroup="5" TypeName="MULTIPOINT" Description="Geographic Datatype" ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="41" IDGroup="5" TypeName="MULTILINESTRING" Description="Geographic Datatype" ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="42" IDGroup="5" TypeName="MULTIPOLYGON" Description="Geographic Datatype" ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
<DATATYPE ID="43" IDGroup="5" TypeName="GEOMETRYCOLLECTION" Description="Geographic Datatype" ParamCount="0" OptionCount="0" ParamRequired="0" EditParamsAsString="0" SynonymGroup="0" PhysicalMapping="0" PhysicalTypeName="" >
|
||||
</DATATYPE>
|
||||
</DATATYPES>
|
||||
<COMMON_DATATYPES>
|
||||
<COMMON_DATATYPE ID="5" />
|
||||
<COMMON_DATATYPE ID="8" />
|
||||
<COMMON_DATATYPE ID="20" />
|
||||
<COMMON_DATATYPE ID="15" />
|
||||
<COMMON_DATATYPE ID="22" />
|
||||
<COMMON_DATATYPE ID="28" />
|
||||
<COMMON_DATATYPE ID="26" />
|
||||
<COMMON_DATATYPE ID="33" />
|
||||
<COMMON_DATATYPE ID="34" />
|
||||
<COMMON_DATATYPE ID="35" />
|
||||
</COMMON_DATATYPES>
|
||||
<TABLEPREFIXES>
|
||||
<TABLEPREFIX Name="Default (no prefix)" />
|
||||
</TABLEPREFIXES>
|
||||
<REGIONCOLORS>
|
||||
<REGIONCOLOR Color="Red=#FFEEEC" />
|
||||
<REGIONCOLOR Color="Yellow=#FEFDED" />
|
||||
<REGIONCOLOR Color="Green=#EAFFE5" />
|
||||
<REGIONCOLOR Color="Cyan=#ECFDFF" />
|
||||
<REGIONCOLOR Color="Blue=#F0F1FE" />
|
||||
<REGIONCOLOR Color="Magenta=#FFEBFA" />
|
||||
</REGIONCOLORS>
|
||||
<POSITIONMARKERS>
|
||||
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
|
||||
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
|
||||
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
|
||||
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
|
||||
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
|
||||
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
|
||||
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
|
||||
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
|
||||
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
|
||||
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
|
||||
<POSITIONMARKER ZoomFac="-1.0" X="0" Y="0" />
|
||||
</POSITIONMARKERS>
|
||||
</SETTINGS>
|
||||
<METADATA>
|
||||
<REGIONS>
|
||||
<REGION ID="1368" RegionName="Actors" XPos="680" YPos="20" Width="320" Height="220" RegionColor="5" TablePrefix="0" TableType="0" OverwriteTablePrefix="0" OverwriteTableType="0" Comments="" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="23" />
|
||||
<REGION ID="1366" RegionName="Attributes" XPos="320" YPos="260" Width="680" Height="260" RegionColor="3" TablePrefix="0" TableType="0" OverwriteTablePrefix="0" OverwriteTableType="0" Comments="" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="21" />
|
||||
<REGION ID="1357" RegionName="User" XPos="320" YPos="540" Width="300" Height="380" RegionColor="2" TablePrefix="0" TableType="0" OverwriteTablePrefix="0" OverwriteTableType="0" Comments="" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="20" />
|
||||
<REGION ID="1341" RegionName="Configuration" XPos="680" YPos="540" Width="320" Height="380" RegionColor="0" TablePrefix="0" TableType="0" OverwriteTablePrefix="0" OverwriteTableType="0" Comments="" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="16" />
|
||||
<REGION ID="1342" RegionName="Base data" XPos="20" YPos="20" Width="280" Height="900" RegionColor="1" TablePrefix="0" TableType="0" OverwriteTablePrefix="0" OverwriteTableType="0" Comments="" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="17" />
|
||||
<REGION ID="1367" RegionName="Borrow" XPos="320" YPos="20" Width="300" Height="220" RegionColor="4" TablePrefix="0" TableType="0" OverwriteTablePrefix="0" OverwriteTableType="0" Comments="" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="22" />
|
||||
</REGIONS>
|
||||
<TABLES>
|
||||
<TABLE ID="1216" Tablename="actors" PrevTableName="" XPos="740" YPos="60" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="2" >
|
||||
<COLUMNS>
|
||||
<COLUMN ID="1228" ColName="name" PrevColName="" Pos="2" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1229" ColName="actorid" PrevColName="" Pos="3" idDatatype="20" DatatypeParams="(15)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1230" ColName="imgurl" PrevColName="" Pos="4" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1231" ColName="checked" PrevColName="" Pos="5" idDatatype="16" DatatypeParams="(14)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
</COLUMNS>
|
||||
<INDICES>
|
||||
<INDEX ID="1232" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1228" LengthParam="0" />
|
||||
<INDEXCOLUMN idColumn="1229" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
<INDEX ID="1234" IndexName="actorid" IndexKind="1" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1229" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
</INDICES>
|
||||
</TABLE>
|
||||
<TABLE ID="1217" Tablename="config" PrevTableName="" XPos="760" YPos="600" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="" TableOptions="" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="3" >
|
||||
<COLUMNS>
|
||||
<COLUMN ID="1235" ColName="opt" PrevColName="" Pos="1" idDatatype="20" DatatypeParams="(50)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1236" ColName="value" PrevColName="" Pos="2" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
</COLUMNS>
|
||||
<INDICES>
|
||||
<INDEX ID="1237" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1235" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
</INDICES>
|
||||
</TABLE>
|
||||
<TABLE ID="1218" Tablename="genres" PrevTableName="" XPos="660" YPos="300" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="" TableOptions="" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="4" >
|
||||
<COLUMNS>
|
||||
<COLUMN ID="1238" ColName="id" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(10)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="1" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1239" ColName="name" PrevColName="" Pos="2" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
</COLUMNS>
|
||||
<RELATIONS_START>
|
||||
<RELATION_START ID="1345" />
|
||||
</RELATIONS_START>
|
||||
<INDICES>
|
||||
<INDEX ID="1240" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1238" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
</INDICES>
|
||||
</TABLE>
|
||||
<TABLE ID="1219" Tablename="lent" PrevTableName="" XPos="380" YPos="60" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="5" >
|
||||
<COLUMNS>
|
||||
<COLUMN ID="1241" ColName="diskid" PrevColName="" Pos="1" idDatatype="20" DatatypeParams="(15)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1243" ColName="who" PrevColName="" Pos="3" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1244" ColName="dt" PrevColName="" Pos="4" idDatatype="16" DatatypeParams="(14)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
</COLUMNS>
|
||||
<RELATIONS_START>
|
||||
<RELATION_START ID="1369" />
|
||||
</RELATIONS_START>
|
||||
<INDICES>
|
||||
<INDEX ID="1245" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1241" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
</INDICES>
|
||||
</TABLE>
|
||||
<TABLE ID="1220" Tablename="mediatypes" PrevTableName="" XPos="360" YPos="420" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="6" >
|
||||
<COLUMNS>
|
||||
<COLUMN ID="1359" ColName="id" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(10))" Width="-1" Prec="-1" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="1" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1247" ColName="name" PrevColName="" Pos="2" idDatatype="20" DatatypeParams="(15)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
</COLUMNS>
|
||||
<RELATIONS_START>
|
||||
<RELATION_START ID="1365" />
|
||||
</RELATIONS_START>
|
||||
<INDICES>
|
||||
<INDEX ID="1360" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1359" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
</INDICES>
|
||||
</TABLE>
|
||||
<TABLE ID="1221" Tablename="userconfig" PrevTableName="" XPos="760" YPos="740" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="" TableOptions="" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="7" >
|
||||
<COLUMNS>
|
||||
<COLUMN ID="1249" ColName="user_id" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1250" ColName="opt" PrevColName="" Pos="2" idDatatype="20" DatatypeParams="(50)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1251" ColName="value" PrevColName="" Pos="3" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
</COLUMNS>
|
||||
<RELATIONS_END>
|
||||
<RELATION_END ID="1339" />
|
||||
</RELATIONS_END>
|
||||
<INDICES>
|
||||
<INDEX ID="1252" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1249" LengthParam="0" />
|
||||
<INDEXCOLUMN idColumn="1250" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
</INDICES>
|
||||
</TABLE>
|
||||
<TABLE ID="1222" Tablename="users" PrevTableName="" XPos="360" YPos="700" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="" TableOptions="" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="8" >
|
||||
<COLUMNS>
|
||||
<COLUMN ID="1253" ColName="id" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1254" ColName="name" PrevColName="" Pos="2" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1255" ColName="passwd" PrevColName="" Pos="3" idDatatype="20" DatatypeParams="(100)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1256" ColName="cookiecode" PrevColName="" Pos="4" idDatatype="20" DatatypeParams="(100)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1257" ColName="permissions" PrevColName="" Pos="5" idDatatype="5" DatatypeParams="(10)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="1" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1258" ColName="timestamp" PrevColName="" Pos="6" idDatatype="16" DatatypeParams="(14)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1259" ColName="email" PrevColName="" Pos="7" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
</COLUMNS>
|
||||
<RELATIONS_START>
|
||||
<RELATION_START ID="1330" />
|
||||
<RELATION_START ID="1339" />
|
||||
</RELATIONS_START>
|
||||
<INDICES>
|
||||
<INDEX ID="1260" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1253" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
<INDEX ID="1261" IndexName="name" IndexKind="1" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1254" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
</INDICES>
|
||||
</TABLE>
|
||||
<TABLE ID="1224" Tablename="videodata" PrevTableName="" XPos="40" YPos="60" TableType="0" TablePrefix="0" nmTable="0" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="10" >
|
||||
<COLUMNS>
|
||||
<COLUMN ID="1265" ColName="id" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(10)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="1" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1266" ColName="md5" PrevColName="" Pos="2" idDatatype="20" DatatypeParams="(32)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1267" ColName="title" PrevColName="" Pos="3" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1268" ColName="subtitle" PrevColName="" Pos="4" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1269" ColName="language" PrevColName="" Pos="5" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1270" ColName="diskid" PrevColName="" Pos="6" idDatatype="20" DatatypeParams="(15)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1271" ColName="comment" PrevColName="" Pos="7" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1272" ColName="disklabel" PrevColName="" Pos="8" idDatatype="20" DatatypeParams="(32)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1273" ColName="imdbID" PrevColName="" Pos="9" idDatatype="20" DatatypeParams="(15)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1274" ColName="year" PrevColName="" Pos="10" idDatatype="18" DatatypeParams="(4)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1275" ColName="imgurl" PrevColName="" Pos="11" idDatatype="27" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1276" ColName="director" PrevColName="" Pos="12" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1277" ColName="actors" PrevColName="" Pos="13" idDatatype="28" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1278" ColName="runtime" PrevColName="" Pos="14" idDatatype="5" DatatypeParams="(10)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="1" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1279" ColName="country" PrevColName="" Pos="15" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1280" ColName="plot" PrevColName="" Pos="16" idDatatype="28" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1281" ColName="filename" PrevColName="" Pos="17" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1282" ColName="filesize" PrevColName="" Pos="18" idDatatype="5" DatatypeParams="(16)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="1" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1283" ColName="filedate" PrevColName="" Pos="19" idDatatype="15" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1284" ColName="audio_codec" PrevColName="" Pos="20" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1285" ColName="video_codec" PrevColName="" Pos="21" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1286" ColName="video_width" PrevColName="" Pos="22" idDatatype="5" DatatypeParams="(10)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="1" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1287" ColName="video_height" PrevColName="" Pos="23" idDatatype="5" DatatypeParams="(10)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="1" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1288" ColName="istv" PrevColName="" Pos="24" idDatatype="1" DatatypeParams="(1)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="1" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1290" ColName="seen" PrevColName="" Pos="26" idDatatype="1" DatatypeParams="(1)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="1" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1291" ColName="mediatype" PrevColName="" Pos="27" idDatatype="5" DatatypeParams="(10))" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="1" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1292" ColName="custom1" PrevColName="" Pos="28" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1293" ColName="custom2" PrevColName="" Pos="29" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1294" ColName="custom3" PrevColName="" Pos="30" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1295" ColName="custom4" PrevColName="" Pos="31" idDatatype="20" DatatypeParams="(255)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1289" ColName="lastupdate" PrevColName="" Pos="25" idDatatype="16" DatatypeParams="(14)" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1296" ColName="created" PrevColName="" Pos="32" idDatatype="15" DatatypeParams="" Width="0" Prec="0" PrimaryKey="0" NotNull="0" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1297" ColName="owner_id" PrevColName="" Pos="33" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="0" NotNull="1" AutoInc="0" IsForeignKey="0" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
</COLUMNS>
|
||||
<RELATIONS_START>
|
||||
<RELATION_START ID="1329" />
|
||||
<RELATION_START ID="1344" />
|
||||
</RELATIONS_START>
|
||||
<RELATIONS_END>
|
||||
<RELATION_END ID="1365" />
|
||||
<RELATION_END ID="1369" />
|
||||
</RELATIONS_END>
|
||||
<INDICES>
|
||||
<INDEX ID="1298" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1265" LengthParam="0" />
|
||||
<INDEXCOLUMN idColumn="1270" LengthParam="0" />
|
||||
<INDEXCOLUMN idColumn="1291" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
<INDEX ID="1299" IndexName="seen" IndexKind="1" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1290" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
<INDEX ID="1300" IndexName="title_idx" IndexKind="1" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1267" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
<INDEX ID="1301" IndexName="diskid_idx" IndexKind="1" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1270" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
<INDEX ID="1302" IndexName="mediatype" IndexKind="1" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1291" LengthParam="0" />
|
||||
<INDEXCOLUMN idColumn="1288" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
<INDEX ID="1303" IndexName="actors_idx" IndexKind="1" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1277" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
<INDEX ID="1304" IndexName="comment" IndexKind="1" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1271" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
</INDICES>
|
||||
</TABLE>
|
||||
<TABLE ID="1328" Tablename="userseen" PrevTableName="videodata_has_users" XPos="360" YPos="580" TableType="0" TablePrefix="0" nmTable="1" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="13" >
|
||||
<COLUMNS>
|
||||
<COLUMN ID="1336" ColName="video_id" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(10)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="1" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1337" ColName="user_id" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(11)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1370" ColName="diskid" PrevColName="" Pos="1" idDatatype="20" DatatypeParams="(15)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
</COLUMNS>
|
||||
<RELATIONS_END>
|
||||
<RELATION_END ID="1329" />
|
||||
<RELATION_END ID="1330" />
|
||||
</RELATIONS_END>
|
||||
<INDICES>
|
||||
<INDEX ID="1332" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1336" LengthParam="0" />
|
||||
<INDEXCOLUMN idColumn="1337" LengthParam="0" />
|
||||
<INDEXCOLUMN idColumn="1370" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
</INDICES>
|
||||
</TABLE>
|
||||
<TABLE ID="1343" Tablename="videogenre" PrevTableName="videodata_has_genres" XPos="360" YPos="300" TableType="0" TablePrefix="0" nmTable="1" Temporary="0" UseStandardInserts="0" StandardInserts="\n" TableOptions="DelayKeyTblUpdates=0\nPackKeys=0\nRowChecksum=0\nRowFormat=0\nUseRaid=0\nRaidType=0\n" Comments="" Collapsed="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="18" >
|
||||
<COLUMNS>
|
||||
<COLUMN ID="1352" ColName="genre_id" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(10)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="1" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1354" ColName="video_id" PrevColName="" Pos="1" idDatatype="5" DatatypeParams="(10)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="1" />
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
<COLUMN ID="1371" ColName="diskid" PrevColName="" Pos="1" idDatatype="20" DatatypeParams="(15)" Width="0" Prec="0" PrimaryKey="1" NotNull="1" AutoInc="0" IsForeignKey="1" DefaultValue="" Comments="">
|
||||
<OPTIONSELECTED>
|
||||
<OPTIONSELECT Value="0" />
|
||||
</OPTIONSELECTED>
|
||||
</COLUMN>
|
||||
</COLUMNS>
|
||||
<RELATIONS_END>
|
||||
<RELATION_END ID="1344" />
|
||||
<RELATION_END ID="1345" />
|
||||
</RELATIONS_END>
|
||||
<INDICES>
|
||||
<INDEX ID="1347" IndexName="PRIMARY" IndexKind="0" FKRefDef_Obj_id="-1">
|
||||
<INDEXCOLUMNS>
|
||||
<INDEXCOLUMN idColumn="1352" LengthParam="0" />
|
||||
<INDEXCOLUMN idColumn="1354" LengthParam="0" />
|
||||
<INDEXCOLUMN idColumn="1371" LengthParam="0" />
|
||||
</INDEXCOLUMNS>
|
||||
</INDEX>
|
||||
</INDICES>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
<RELATIONS>
|
||||
<RELATION ID="1329" RelationName="was seen by" Kind="1" SrcTable="1224" DestTable="1328" FKFields="id=video_id\ndiskid=diskid\nmediatype=mediatype\n" FKFieldsComments="\n\n\n" relDirection="2" MidOffset="-21" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="0" CaptionOffsetY="0" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="14" />
|
||||
<RELATION ID="1330" RelationName="has seen" Kind="1" SrcTable="1222" DestTable="1328" FKFields="id=user_id\n" FKFieldsComments="\n" relDirection="1" MidOffset="10" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="0" CaptionOffsetY="0" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="15" />
|
||||
<RELATION ID="1339" RelationName="has config options" Kind="2" SrcTable="1222" DestTable="1221" FKFields="id=user_id\n" FKFieldsComments="\n" relDirection="2" MidOffset="0" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="0" CaptionOffsetY="0" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="15" />
|
||||
<RELATION ID="1344" RelationName="is of genres" Kind="1" SrcTable="1224" DestTable="1343" FKFields="id=video_id\ndiskid=diskid\nmediatype=mediatype\n" FKFieldsComments="\n\n\n" relDirection="2" MidOffset="-20" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="0" CaptionOffsetY="0" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="19" />
|
||||
<RELATION ID="1345" RelationName="genres are used by" Kind="1" SrcTable="1218" DestTable="1343" FKFields="id=genre_id\n" FKFieldsComments="\n" relDirection="4" MidOffset="0" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="0" CaptionOffsetY="0" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="20" />
|
||||
<RELATION ID="1365" RelationName="has type" Kind="0" SrcTable="1220" DestTable="1224" FKFields="id=mediatype\n" FKFieldsComments="\n" relDirection="4" MidOffset="-12" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="0" CaptionOffsetY="0" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="21" />
|
||||
<RELATION ID="1369" RelationName="is lent by" Kind="0" SrcTable="1219" DestTable="1224" FKFields="diskid=diskid\n" FKFieldsComments="\n" relDirection="4" MidOffset="-32" OptionalStart="0" OptionalEnd="0" CaptionOffsetX="0" CaptionOffsetY="0" StartIntervalOffsetX="0" StartIntervalOffsetY="0" EndIntervalOffsetX="0" EndIntervalOffsetY="0" CreateRefDef="1" Invisible="0" RefDef="Matching=0\nOnDelete=3\nOnUpdate=3\n" Comments="" FKRefDefIndex_Obj_id="-1" Splitted="0" IsLinkedObject="0" IDLinkedModel="-1" Obj_id_Linked="-1" OrderPos="24" />
|
||||
</RELATIONS>
|
||||
<NOTES>
|
||||
</NOTES>
|
||||
<IMAGES>
|
||||
</IMAGES>
|
||||
</METADATA>
|
||||
<PLUGINDATA>
|
||||
<PLUGINDATARECORDS>
|
||||
</PLUGINDATARECORDS>
|
||||
</PLUGINDATA>
|
||||
<QUERYDATA>
|
||||
<QUERYRECORDS>
|
||||
</QUERYRECORDS>
|
||||
</QUERYDATA>
|
||||
<LINKEDMODELS>
|
||||
</LINKEDMODELS>
|
||||
</DBMODEL>
|
||||
36
videodb/doc/manual/browse.html
Normal file
36
videodb/doc/manual/browse.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="index.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
|
||||
<h1>Usage</h1>
|
||||
|
||||
<h2>Browsing the Database</h2>
|
||||
|
||||
<p>The browse view allows you to list the content of your database by applying filters to the available data. On the top of the screen you'll find a row of radio buttons to list the available titles sorted by the first letter of the title.<br /> This means if you select the <code>DEF</code> filter only movies beginning with a D, E or F are shown in the list.</p>
|
||||
|
||||
<p>When adding movies it is a good practice to move common words like <code>the</code> or <code>a</code> to the end of the title to have the sorting make more sense.</p>
|
||||
|
||||
<p>Example: <code>A Clockwork Orange</code> becomes <code>Clockwork Orange, A</code>
|
||||
|
||||
<p>VideoDB treats TV episodes special, which means they are not shown by default. To show them, <code>show TV episodes</code> must be enabled. You can change this behavior in the <a href="configview.html">configuration</a>.</p>
|
||||
|
||||
<p>When selecting the <code>all</code> filter all movies are shown - please note that this can take some time if you have a very large database!<br />
|
||||
Usually the list is always sorted lexically, you may change the sort order of the <code>all</code> filter to sort by the <code>DiskID</code> in the <a href="configview.html">configuration</a>.</p>
|
||||
|
||||
<p>The <code>unseen</code> filter just shows you the movies that are not marked as seen yet by you.</p>
|
||||
|
||||
<p>When using the <code>new</code> filter only the 15 newest additions to your database are shown. You can change the number of shown files here in the <a href="configview.html">configuration</a>.
|
||||
|
||||
<a name="wishlist"></a>
|
||||
<p>The last filter is the <code>Wishlist</code>. Movies shown here are not yet owned by you and will not show up in any of the other views (not even with the <code>all</code> filter). To add a movie to your wishlist just add like every other movie but set its mediatype to <code>wanted</code>.</p>
|
||||
|
||||
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
59
videodb/doc/manual/configview.html
Normal file
59
videodb/doc/manual/configview.html
Normal file
@@ -0,0 +1,59 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="index.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
|
||||
<h1>Usage</h1>
|
||||
|
||||
<h2>The Configuration Screen</h2>
|
||||
|
||||
<h3>The Cache Control Bar</h3>
|
||||
|
||||
<h3>Changing the configuration</h3>
|
||||
|
||||
<h3>The custom types</h3>
|
||||
|
||||
<p>There are the following customtypes available:</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>text</td>
|
||||
<td>This is a simple textfield nothing special about it</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>url</td>
|
||||
<td>This shows a clickable link in the show view</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ed2k</td>
|
||||
<td>You may enter a MD4 sum and a clickable eDonkey link will be generated from this field, the filesize and the filename</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>language</td>
|
||||
<td>This is another language field. It will display the same languageflags for quickentry as the standard one.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>rating</td>
|
||||
<td>You can rate a movie with this field. It can be filled from IMDB.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>orgtitle</td>
|
||||
<td>This is the same as the standard title field, it gets filled from IMDB. This is useful if you store translated title of the movie in the title field.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>movix</td>
|
||||
<td>If you use <a href="http://movix.sourceforge.net/" target="_blank">Movix</a> on your CDs you can choose the version with this field.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>mpaa</td>
|
||||
<td>This field can hold the movie rating of the Motion Picture Association of Amerika. It gets filled from the IMDB.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
57
videodb/doc/manual/contrib.html
Normal file
57
videodb/doc/manual/contrib.html
Normal file
@@ -0,0 +1,57 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="index.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
|
||||
<h1>Additional Scripts</h1>
|
||||
|
||||
<h2>General</h2>
|
||||
|
||||
<p>VideoDB comes with some additional Scripts to do certain tasks, using them is completely optional and not needed for a functional VideoDB. All these files are stored in the <code>contrib</code> directory.<br />
|
||||
Some of them are written in Perl and you have to edit them to match your database auth options. Some knowledge of Perl and SQL may be helpful.</p>
|
||||
|
||||
<p>If you wrote something you think others could find useful just send it to the developers mailing list (<a href="mailto:videodb-devel@lists.sourceforge.net">videodb-devel@lists.sourceforge.net</a>) or join the <a href="http://lists.sourceforge.net/mailman/listinfo/videodb-devel">Developer Mailinglist</a> and post it there.</p>
|
||||
|
||||
<a name="mklist"></a>
|
||||
<h2>mklist.pl</h2>
|
||||
|
||||
<p>This generates a plaintextlist of all files in the database. Edit the variables at the top</p>
|
||||
|
||||
<a name="setgenre"></a>
|
||||
<h2>setGenre.pl</h2>
|
||||
|
||||
<p>This script is useful to set the same genres for a bunch of entries based on their title. For example setting all <code>Simpsons</code> episodes to <code>Animation</code> and <code>Comedy</code>. You have to edit some variables at top of the file to make it do what you want.</p>
|
||||
|
||||
<a name="videoadd"></a>
|
||||
<h2>videoadd.pl</h2>
|
||||
|
||||
<p>This tool is very useful to automatically add some videofiles to the database. It mounts your CD-ROM drive, searches for video files, tries to guess the title and some other infos from the filename and adds them to the database. It uses <a href="http://www.mplayerhq.hu/">mPlayer</a> to extract video informations from the file. It accepts the path to your CD-ROM drive as argument.</p>
|
||||
|
||||
<a name="direxport"></a>
|
||||
<h2>direxport.pl</h2>
|
||||
|
||||
<p>This creates single html pages from the movies in the database. It allows me to browse the database content with my <a href="http://splitbrain.org/go/irfc">IR File Chooser</a> tool.</p>
|
||||
|
||||
<a name="langcheck"></a>
|
||||
<h2>langcheck.php</h2>
|
||||
|
||||
<p>This PHP tool checks all language files for missing translations and displays the missing keys. This is useful for <a href="translate.html">Translators</a>. Just call it from your webbrowser like this: <code>http://myserver.com/videodb/contrib/langcheck.php</code></p>
|
||||
|
||||
<a name="tvtome"></a>
|
||||
<h2>tvtome.php</h2>
|
||||
|
||||
<p>To use this PHP tool call it from your webbrowser like this: <code>http://myserver.com/videodb/contrib/twtome.php</code>. This tool can fetch episode infos from <a href="http://www.tvtome.com">www.tvtome.com</a> and add the data to the episodes in your VideoDB.</p>
|
||||
|
||||
<p>You need to enter the complete URL to the TV shows episode guide at tvtome (eg. <code>http://www.tvtome.com/Futurama/guide.html</code> for Futurama) and some Searchstring to select the episodes of this show stored in your VideoDB (eg. <code>Futurama*</code> to find all movies with their titles beginning with Futurama)</p>
|
||||
|
||||
<p>After you press the "submit query" button the tool fetches the episode guide and lists all episodes. For each episode you have to choose the matching movie in your VideoDB. The tool tries to suggest the matching title based upon an similarity comparison. For each episodes data you want to import you need to check the checkbox. Then pressing thefinal submit button the selected data is imported.</p>
|
||||
|
||||
<p>You need to have Admin rights to use this tool in multiuser mode.</p>
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
21
videodb/doc/manual/detailview.html
Normal file
21
videodb/doc/manual/detailview.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="index.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
|
||||
<h1>Usage</h1>
|
||||
|
||||
<h2>The Detail View</h2>
|
||||
|
||||
<p>When clicking on a title in the <a href="browse.html">Browse View</a>, you're presented with the movies detail view. It's pretty self-explanatory. You just see all the inforamation thats stored in the database about the selected movie.<br />
|
||||
Clicking the cover image opens the IMDB page for the movie. Clicking an actors name will <a href="search.html">search</a> for movies with that actor. The same applies to all other clickable labels.</p>
|
||||
|
||||
<p>You can click the random link in the top menu to get a random view</p>
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
42
videodb/doc/manual/devel.html
Normal file
42
videodb/doc/manual/devel.html
Normal file
@@ -0,0 +1,42 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="index.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
|
||||
<h1>Development</h1>
|
||||
|
||||
<a name="res"></a>
|
||||
<h2>Developer Ressources</h2>
|
||||
|
||||
<p>If you want to join the development of VideoDB the first you should do is joining the <a href="http://lists.sourceforge.net/mailman/listinfo/videodb-devel" target="_blank">Developer Mailinglist</a>.</p>
|
||||
|
||||
<p>To stay up to date you should also use the current CVS version of VideoDB to avoid writing something that maybe is already included there. You can get the current development version from the CVS Server either by browsing the <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/videodb/videodb/" target="_blank">Web-Interface</a> or accessing the repository directly via anonymous CVS:
|
||||
|
||||
<pre>
|
||||
cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/videodb login
|
||||
cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/videodb co videodb
|
||||
</pre>
|
||||
|
||||
<p>When prompted for a password just hit enter.</p>
|
||||
|
||||
<p>Please note that the webbased access is up to 24 hours behind the real CVS Server so a real checkout is always to prefer.</p>
|
||||
|
||||
<a name="guide"></a>
|
||||
<h2>Coding guidelines</h2>
|
||||
|
||||
<p>Here are some simple guidelines when contributing to VideoDB:</p>
|
||||
|
||||
<ul>
|
||||
<li>Use an indention width of 4</li>
|
||||
<li>Don't use tabs! Use spaces instead. Tabs look different in different editors, that makes problems...</li>
|
||||
<li>Comment your code!</li>
|
||||
<li>Use <a href="http://www.phpdoc.org">phpDocumentor</a> tags to explain your functions</li>
|
||||
</ul>
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
74
videodb/doc/manual/faq.html
Normal file
74
videodb/doc/manual/faq.html
Normal file
@@ -0,0 +1,74 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="index.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
|
||||
<h1>Usage</h1>
|
||||
|
||||
<h2>Frequently Asked Questions</h2>
|
||||
|
||||
<p>Here are some frequently asked questions:</p>
|
||||
|
||||
<dl>
|
||||
<dt><b>I installed the database and changed the config.inc.php but when I try to browse the videodb it doesn't work.</b></dt>
|
||||
<dd>Make sure your PHP installation has 'short_open_tag' enabled (should be by default).</dd>
|
||||
|
||||
<dt><b>I want more Inputfields!</b></dt>
|
||||
<dd>There are four custom fields! Use them! Read the comments in custom.php for informations how to change the output and input of them.</dd>
|
||||
|
||||
<dt><b>My videos are not in english, german, french or spanish! What should I put into the language box?</b></dt>
|
||||
<dd>Just put in your desired language it is just a freeform textfield. If you want to have a country flag displayed for it, place a GIF image named like the language into the flags directory. It should be 30x15 pixels in size. There is a README in the images/flags directory - read it.</dd>
|
||||
|
||||
<dt><b>I can't borrow a video! How is this done?</b></dt>
|
||||
<dd>You have to assign a diskid to it! If you have done so, select the video and click on [ borrow ] in the top row.</dd>
|
||||
|
||||
<dt><b>My movies are stored on some really weird media! How can I add some new mediatypes?</b></dt>
|
||||
<dd>Use your favourite MySQL tool to add them into the mediatypes table. Does anyone own LaserDisks? Should they be in by default?</dd>
|
||||
|
||||
<dt><b>The Adult genre never get's filled by an IMDB lookup!</b></dt>
|
||||
<dd>Yes - there is no such category in IMDB - You have to mark your pr0n yourself ;-)</dd>
|
||||
|
||||
<dt><b>How does the wishlist work?</b></dt>
|
||||
<dd>To add a movie to wishlist find the wanted movie on IMDB, add the movie as usual but choose <code>wanted</code> as mediatype - the movie will appear on your wishlist. When you finally get the movie you can change the mediatype setting to appropriated in the edit screen.</dd>
|
||||
|
||||
<dt><b>I enabled the multiuser support. But now I can't login to add users!</b></dt>
|
||||
<dd>There is a default user named <code>admin</code> created on database creation. An his password is - you guessed it - <code>admin</code>. BTW: Be sure to change the password once you logged in.</dd>
|
||||
|
||||
<dt><b>Some of my movies are spread about multiple disks. How do I add them?</b></dt>
|
||||
<dd>There are two ways people handle this. What I do is adding them twice (or how many disks you have) with some label like "CD2" or something in the title or subtitle field. Others use a custom field to store the number of disks - but this makes the file information fields a little bit useless. All other solutions would require drastic database changes.</dd>
|
||||
|
||||
<dt><b>I have multiple movies on one disk. Is that a problem?</b></dt>
|
||||
<dd>No. Just add any movie and give each the same diskID - All movies on the same disk become unavailable if you borrow the disk.</dd>
|
||||
|
||||
<dt><b>Can I add some more genres?</b></dt>
|
||||
<dd>Just add them with your favourite MySQL tool to the genres table.</dd>
|
||||
|
||||
<dt><b>I tried to translate the english language file but when I select my newly created language everything stays in english!?</b></dt>
|
||||
<dd>If there is a bug in the language file the default one is used. Try to load your file directly in the browser. This will parse the file and display an error message which should help you. Another hint: You have to escape doublequotes with a backslash.</dd>
|
||||
|
||||
<dt><b>My cache/imdb directory is getting large - Can I delete the files in it?</b></dt>
|
||||
<dd>Yes. Or just use the cache controlbar in the <a href="configview.html">Config Screen</a></dd>
|
||||
|
||||
<dt><b>Arghh! I locked my self out from the config screen by making a mistake in the localnet option.</b></dt>
|
||||
<dd>Use your favourite MySQL tool to delete the option from the config table: <code>DELETE FROM config WHERE opt='localnet';</code></dd>
|
||||
|
||||
<dt><b>Hey your tool is great! Can I do anything for you?</b></dt>
|
||||
<dd>Read, inform yourself and think before voting your next president.</dd>
|
||||
|
||||
<dt><b>I want to support you and the development of VideoDB - can I donate something?</b></dt>
|
||||
<dd>Of course you can :-D Use the <a href="https://www.paypal.com/xclick/business=cpuidle%40gmx.de&item_name=videoDB&no_note=1&tax=0¤cy_code=EUR">PayPal Account</a></dd>
|
||||
|
||||
<dt><b>Are all these questions really asked frequently or do you just make them up?</b></dt>
|
||||
<dd>Yes :-)</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<p>your question isn't answered here? just mail me :-)</p>
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
20
videodb/doc/manual/imdbbrowser.html
Normal file
20
videodb/doc/manual/imdbbrowser.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="index.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
|
||||
<h1>Usage</h1>
|
||||
|
||||
<h2>The IMDB Browser</h2>
|
||||
|
||||
<p>This feature is disabled by default! Enable it in the <a href="configview.html">configuration screen</a> to use it.</p>
|
||||
|
||||
<p>The IMDB Browser integrates the Internet Movie Database directly into VideoDB. When enabled you can access the IMDB website from the menubar. You can use their site as usual, but after every mentioned movie title you'll find a little <code>+</code> button. By pressing this button you can add this movie to your VideoDB. This feature is very useful to fill your <a href="browse.html#wishlist">wishlist</a>.</p>
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
62
videodb/doc/manual/index.html
Normal file
62
videodb/doc/manual/index.html
Normal file
@@ -0,0 +1,62 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<!-- begin content -->
|
||||
<h1>VideoDB Online Manual</h1>
|
||||
<h2>Table of Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li>Installation</li>
|
||||
<ul>
|
||||
<li><a href="installation.html#requirements">Requirements</a></li>
|
||||
<li><a href="installation.html#firsttime">First time installation</a></li>
|
||||
<li><a href="installation.html#update">Update from a previous version</a></li>
|
||||
</ul>
|
||||
<li>Usage</li>
|
||||
<ul>
|
||||
<li><a href="browse.html">Browsing the Database</a></li>
|
||||
<li><a href="detailview.html">The Detail View</a></li>
|
||||
<li>The Edit Screen</li>
|
||||
<li>The Borrow Manager</li>
|
||||
<li><a href="imdbbrowser.html">The IMDB Browser</a></li>
|
||||
<li><a href="search.html">Searching the Database</a></li>
|
||||
<li><a href="configview.html">The Configuration Screen</a></li>
|
||||
<li>Viewing Database statistics</li>
|
||||
<li><a href="multiuser.html">Multiuser Options</a></li>
|
||||
<li><a href="profile.html">User Profile</a></li>
|
||||
<li><a href="usermanager.html">User Management</a></li>
|
||||
<li><a href="keys.html">Access Keys</a></li>
|
||||
<li><a href="faq.html">Frequently Asked Questions</a></li>
|
||||
</ul>
|
||||
<li>Additional Scripts</li>
|
||||
<ul>
|
||||
<li><a href="contrib.html#mklist">mklist.pl</a></li>
|
||||
<li><a href="contrib.html#setgenre">setGenre.pl</a></li>
|
||||
<li><a href="contrib.html#videoadd">videoadd.pl</a></li>
|
||||
<li><a href="contrib.html#direxport">direxport.pl</a></li>
|
||||
<li><a href="contrib.html#langcheck">langcheck.php</a></li>
|
||||
</ul>
|
||||
<li>Development</li>
|
||||
<ul>
|
||||
<li><a href="devel.html#res">Developer Ressources</a></li>
|
||||
<li><a href="devel.html#guide">Coding Guidelines</a></li>
|
||||
<li><a href="translate.html">Languages</a></li>
|
||||
<li><a href="stylesheets.html">Stylesheets</a></li>
|
||||
<li><a href="templates.html">Templates</a></li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<table><tr><td>
|
||||
<b>Your Help is needed!</b><br />
|
||||
<p>This manual is far from complete. Please help completing it by contributing to the documentation Wiki at
|
||||
<a href="http://www.splitbrain.org/dokuwiki/vdb:videodb">http://www.splitbrain.org/dokuwiki/vdb:videodb</a>. Just visit the site and contribute.</p>
|
||||
<p>The videoDB development team can be reached at <a href="mailto:videodb-devel@lists.sourceforge.net">videodb-devel@lists.sourceforge.net</a>
|
||||
</p>
|
||||
</td></tr></table>
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
65
videodb/doc/manual/installation.html
Normal file
65
videodb/doc/manual/installation.html
Normal file
@@ -0,0 +1,65 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="index.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
|
||||
<h1>Installation</h1>
|
||||
|
||||
<p>The examples in this document assumes you're using Linux and Apache. The Apaches document root is in <code>/var/www</code> and VideoDB is to be installed in <code>/var/www/videodb</code>. But it shouldn't be difficult for you to follow the steps with any other environment.</p>
|
||||
|
||||
<a name="requirements"></a>
|
||||
<h2>Requirements</h2>
|
||||
|
||||
<p>VideoDB works with the typical LAMP and WAMP environments. Here are the requirements in detail:</p>
|
||||
|
||||
<ul>
|
||||
<li>A Webserver wich supports PHP (<a href="http://httpd.apache.org" target="_blank">Apache</a> recommended)</li>
|
||||
<li>A recent version of <a href="http://www.php.net" target="_blank">PHP 4</a>, at least 4.1.0 is required</li>
|
||||
<li>A <a href="http://www.mysql.com" target="_blank">MySQL</a> Database</li>
|
||||
<li>A WebBrowser (something new is probably better)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<a name="firsttime"></a>
|
||||
<h2>First time installation</h2>
|
||||
|
||||
<p>Unzip the tarball into a directory below your webserver document root and make the cache directories writable.</p>
|
||||
|
||||
<p>Example:</p>
|
||||
<pre>
|
||||
$> cd /var/www
|
||||
$> tar -xzvf ~/videodb-*.tgz
|
||||
$> chmod 777 videodb/cache/*
|
||||
</pre>
|
||||
|
||||
<p>Then create a new database using the <code>install.sql</code> file in the <code>install</code> directory</p>
|
||||
|
||||
<p>Example:</p>
|
||||
<pre>
|
||||
$> mysqladmin -p create videodb
|
||||
$> mysql -p videodb < /var/www/videodb/install/install.sql
|
||||
</pre>
|
||||
|
||||
|
||||
<p>Now edit the <code>config.inc.php</code> file to match your database settings.</p>
|
||||
|
||||
<p>Thats it. Now point your webbrowser to your new videodb and add some movies</p>
|
||||
|
||||
|
||||
<a name="update"></a>
|
||||
<h2>Update from a previous version</h2>
|
||||
|
||||
<p>For updating from a previous version just delete all files but the cache directory and keep your database. Then unzip the new tarball as described <a href="installation.html#firsttime">above</a>. Then apply the <code>upgrade.sql</code> to your database using the the <code>-f</code> parameter to ignore errors.</p>
|
||||
|
||||
<p>Example:</p>
|
||||
<pre>
|
||||
$> mysql -p -f videodb < /var/www/videodb/install/upgrade.sql
|
||||
</pre>
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
31
videodb/doc/manual/keys.html
Normal file
31
videodb/doc/manual/keys.html
Normal file
@@ -0,0 +1,31 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="index.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
|
||||
<h1>Usage</h1>
|
||||
|
||||
<h2>Access Keys</h2>
|
||||
|
||||
<p>The default template implements the use of access keys to speed up accessing certain parts
|
||||
of VideoDB. Here is a list of currently assigned Keys.</p>
|
||||
|
||||
<table>
|
||||
<tr><th>Key</th><th></th></tr>
|
||||
<tr><td><code>Alt+i</code></td><td>Brings you back to the <b>i</b>ndex page</td></tr>
|
||||
<tr><td><code>Alt+f</code></td><td>Opens the search page to <b>f</b>ind a movie</td></tr>
|
||||
<tr><td><code>Alt+n</code></td><td>This creates a <b>n</b>ew entry in the database</td></tr>
|
||||
<tr><td><code>Alt+e</code></td><td>Using this combination you can <b>e</b>dit the current movie</td></tr>
|
||||
<tr><td><code>Alt+b</code></td><td>This opens the <b>b</b>orrowmanager</td></tr>
|
||||
<tr><td><code>Alt+h</code></td><td>Opens the <b>h</b>elp with the user manual</td></tr>
|
||||
<tr><td><code>Alt+l</code></td><td>Use this for <b>l</b>logging in or out</td></tr>
|
||||
<tr><td><code>Alt+s</code></td><td>Pressing this key lets you <b>s</b>ave entered formdata</td></tr>
|
||||
</table>
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
30
videodb/doc/manual/multiuser.html
Normal file
30
videodb/doc/manual/multiuser.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="index.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
|
||||
<h1>Usage</h1>
|
||||
|
||||
<h2>Multiuser Options</h2>
|
||||
|
||||
<p>VideoDB can work with multiple user as an option. To enable this go to the <a href="configview.html">Configuration Screen</a> and check the <code>Multiuser Support</code> checkbox.</p>
|
||||
|
||||
<h3>Logging in</h3>
|
||||
|
||||
<p>When the Multiusermode is enabled a new menu item <code>Login</code> appears. Use your Username and Password to login. You must have cookies enabled or it won't work!! When you check the <code>stay logged in</code> checkbox the cookie will not expire after the actual browser session.</p>
|
||||
|
||||
<p>On database creation an initial user with administration rights is created: Username: <code>admin</code> Password: <code>admin</code></p>
|
||||
|
||||
<h3>Add and modify users</h3>
|
||||
|
||||
<p>Follow the link <code>Usermanagement</code> from the <a href="configview.html">Configuration Screen</a>.</p>
|
||||
|
||||
<p>Be sure to change the password of the <code>admin</code> user!</p>
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
18
videodb/doc/manual/profile.html
Normal file
18
videodb/doc/manual/profile.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="index.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
|
||||
<h1>Usage</h1>
|
||||
|
||||
<h2>User Profile</h2>
|
||||
|
||||
<b>needs to be written</b>
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
29
videodb/doc/manual/search.html
Normal file
29
videodb/doc/manual/search.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="index.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
|
||||
<h1>Usage</h1>
|
||||
|
||||
<h2>Searching the Database</h2>
|
||||
|
||||
<p>The search screen allows you to search for one or more movies that match your criteria.</p>
|
||||
|
||||
<p>The simplest thing is to search for one or more keywords. Just put into the textfield and hit <code>Search</code>. The search is caseinsensitive and matches word parts, too. To search phrases you can enclose them in quotes <code>"</code>.<p>
|
||||
|
||||
<p>Examples:<br />
|
||||
<code>wood</code> matches <code>Ed Wood</code> as well as <code>Clint Eastwood</code><br />
|
||||
<code>"Ed wood"</code> only matches <code>Ed Wood</code> but <code>Ed Wood</code> matches <code>Eddy got lost in Sherwood Forest.</code>, too<br />
|
||||
</p>
|
||||
|
||||
<p>To refine your search you can use the boolean operators <code>AND</code>, <code>OR</code> and <code>NOT</code></p>
|
||||
|
||||
<p>You can restrict your search to some genres by selecting the wanted genres and to some database fields by selecting them in the selectbox. To select multiple fields hold the <code>Ctrl</code>-Key while selecting.</p>
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
19
videodb/doc/manual/stylesheets.html
Normal file
19
videodb/doc/manual/stylesheets.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="index.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
|
||||
<h1>Development</h1>
|
||||
|
||||
<h2>Stylesheets</h2>
|
||||
|
||||
<p>Instead of designing a whole new <a href="templates.html">Template</a> you can add new Stylesheets to existing templates. Just copy an exisisting stylesheet to a new name and adjust it to your match your ideas. All <code>.css</code> files become automatically available in the <a href="configview.html">Configuration Screen</a>.</p>
|
||||
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
142
videodb/doc/manual/templates.html
Normal file
142
videodb/doc/manual/templates.html
Normal file
@@ -0,0 +1,142 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="index.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
|
||||
<h1>Development</h1>
|
||||
|
||||
<h2>Templates</h2>
|
||||
|
||||
<h3>General</h3>
|
||||
|
||||
<p>VideoDB uses the <a href="http://smarty.php.net" target="_blank">Smarty Template engine</a>. Thus everybody interested in writing his own templates should have a look at the <a href="http://smarty.php.net/docs.php" target="_blank">Smarty Documentation</a></p>
|
||||
|
||||
<p>What follows is a list of all templates used by VideoDB and the variables assigned to them. Of course you can split your templates by using Smarty's <code>{include}</code> statement.</p>
|
||||
|
||||
<h3>All Templates</h3>
|
||||
|
||||
<p>The following variables are available in all templates:</p>
|
||||
|
||||
<table cellspacing="4" cellpadding="4">
|
||||
<tr>
|
||||
<th valign="top" nowrap="nowrap">name</th>
|
||||
<th valign="top" nowrap="nowrap">type</th>
|
||||
<th valign="top">description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top" nowrap="nowrap">$lang</td>
|
||||
<td valign="top" nowrap="nowrap">associative array</td>
|
||||
<td valign="top">Contains all language specific strings for the current language. Have a look at the files in the <code>language</code> directory for available keys.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top" nowrap="nowrap">$config</td>
|
||||
<td valign="top" nowrap="nowrap">associative array</td>
|
||||
<td valign="top">All config options as set in the <a href="configview.html">Configuration Screen</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>header.tpl</h3>
|
||||
|
||||
<p>This template is included at the top of every page and should set up the needed HTML headers and include the stylesheet</P>
|
||||
|
||||
<table cellspacing="4" cellpadding="4">
|
||||
<tr>
|
||||
<th valign="top" nowrap="nowrap">name</th>
|
||||
<th valign="top" nowrap="nowrap">type</th>
|
||||
<th valign="top">description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top" nowrap="nowrap">$header</td>
|
||||
<td valign="top" nowrap="nowrap">associative array</td>
|
||||
<td valign="top">Contains the URLs for the top navigation. The available keys are: <code>browse, random, search, stats, new, setup, edit, view, del, borrow, imdbBrowser, help</code>. You should check if the key is empty and only display a link when an URL was given.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top" nowrap="nowrap">$style</td>
|
||||
<td valign="top" nowrap="nowrap">string</td>
|
||||
<td valign="top">Deprecated - use <code>$config.style</code> instead.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top" nowrap="nowrap">$langcode</td>
|
||||
<td valign="top" nowrap="nowrap">string</td>
|
||||
<td valign="top">Deprecated - use <code>$config.language</code> instead.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top" nowrap="nowrap">$localnet</td>
|
||||
<td valign="top" nowrap="nowrap">boolean</td>
|
||||
<td valign="top">True if VideoDB is accessed from the localnet else false.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>footer.tpl</h3>
|
||||
|
||||
<p>The footer is included at the bottom of every page</p>
|
||||
|
||||
<h3>filter.tpl</h3>
|
||||
|
||||
<p>This template displays the row of available filters in the browsing view.</p>
|
||||
|
||||
<table cellspacing="4" cellpadding="4">
|
||||
<tr>
|
||||
<th valign="top" nowrap="nowrap">name</th>
|
||||
<th valign="top" nowrap="nowrap">type</th>
|
||||
<th valign="top">description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top" nowrap="nowrap">$filters</td>
|
||||
<td valign="top" nowrap="nowrap">associative array</td>
|
||||
<td valign="top">Contains all available filters as keys and their Names (translations) as values</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top" nowrap="nowrap">$filter</td>
|
||||
<td valign="top" nowrap="nowrap">string</td>
|
||||
<td valign="top">The currently selected filter in the browsing view</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top" nowrap="nowrap">$showtv</td>
|
||||
<td valign="top" nowrap="nowrap">boolean</td>
|
||||
<td valign="top">True if TV-Episodes are to be shown else false.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top" nowrap="nowrap">$listcolumns</td>
|
||||
<td valign="top" nowrap="nowrap">integer</td>
|
||||
<td valign="top">This is currently only used in the modern template and determines how many columns are to be used in the browsing view.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>browse.tpl</h3>
|
||||
|
||||
<table cellspacing="4" cellpadding="4">
|
||||
<tr>
|
||||
<th valign="top" nowrap="nowrap">name</th>
|
||||
<th valign="top" nowrap="nowrap">type</th>
|
||||
<th valign="top">description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top" nowrap="nowrap">$</td>
|
||||
<td valign="top" nowrap="nowrap"></td>
|
||||
<td valign="top"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<p>Needs to be continued...</p>
|
||||
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
30
videodb/doc/manual/translate.html
Normal file
30
videodb/doc/manual/translate.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="index.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
|
||||
<h1>Development</h1>
|
||||
|
||||
<h2>Languages</h2>
|
||||
|
||||
<p>VideoDB already comes with a lot of languages, but if your's isn't supported why don't you become a translator?</p>
|
||||
|
||||
<p>The first thing you should do is to join the <a href="http://lists.sourceforge.net/mailman/listinfo/videodb-devel" target="_blank">Developer Mailinglist</a> at SourceForge to stay informed when new language strings are added.</p>
|
||||
|
||||
<p>To create a new language file just copy the <code>en.php</code> file in the <code>language</code> directory and translate the all the contained strings to your language. I think you'll get the system when you have a look at it ;-).<br />
|
||||
However pay attention to the <code>$lang[encoding]</code> field. This contains the character encoding you used in the file. You may use another encoding than <code>iso-8859-1</code>. See the <code>bg.php</code> as an example.<br />
|
||||
You should adjust the the header at the top of the file to reflect your authorship, too. ;-). When updating or correcting a file of someone else just add another <code>@author</code> line with your name.</p>
|
||||
|
||||
<p>After translation you should send the file to the mailing list to be included in the next release.</p>
|
||||
|
||||
<p>Sometimes translations get slightly behind the english version. Missing translations will are always replaced by the english strings.</p>
|
||||
|
||||
<p>Hint: The <a href="contrib.html#langcheck">langcheck.php</a> tool can be very helpful to see a list of missing translations</p>
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
37
videodb/doc/manual/usermanager.html
Normal file
37
videodb/doc/manual/usermanager.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
||||
<head>
|
||||
<title>VideoDB - Documentation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="index.html">Table of Contents</a>
|
||||
<!-- begin content -->
|
||||
|
||||
<h1>Usage</h1>
|
||||
|
||||
<h2>Usermanagement</h2>
|
||||
|
||||
<p>In the usermanagement Screen you can add, delete and modify users for multiuser mode.</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Modify own movies</td>
|
||||
<td>Users with this flag may add, delete and change their own movies. However they can not change movies of other users.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Modify others movies</td>
|
||||
<td>Users with this flag may change details of movies belonging to other users, too.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Administration</td>
|
||||
<td>Users with this flag may do everything. Setting this implies all other flags.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>See adult movies</td>
|
||||
<td>You can define movie genres which are not suitable for minors and should be hidden from all users which do not have this permission flag set.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- end content -->
|
||||
</body>
|
||||
</html>
|
||||
BIN
videodb/doc/screenshots/0.png
Normal file
BIN
videodb/doc/screenshots/0.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 225 KiB |
BIN
videodb/doc/screenshots/1.png
Normal file
BIN
videodb/doc/screenshots/1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 125 KiB |
BIN
videodb/doc/screenshots/2.png
Normal file
BIN
videodb/doc/screenshots/2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
BIN
videodb/doc/screenshots/3.png
Normal file
BIN
videodb/doc/screenshots/3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 149 KiB |
BIN
videodb/doc/screenshots/4.png
Normal file
BIN
videodb/doc/screenshots/4.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
86
videodb/docker-entrypoint.sh
Normal file
86
videodb/docker-entrypoint.sh
Normal file
@@ -0,0 +1,86 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
DB_HOST="${DB_HOST:-db}"
|
||||
DB_USER="${DB_USER:-videodb}"
|
||||
DB_PASSWORD="${DB_PASSWORD:-videodb_secret}"
|
||||
DB_NAME="${DB_NAME:-videodb}"
|
||||
DB_PREFIX="${DB_PREFIX:-videodb_}"
|
||||
|
||||
CONFIG_FILE="/var/www/html/config.inc.php"
|
||||
|
||||
# ── Write config.inc.php from environment variables ──────────────────────────
|
||||
cat > "$CONFIG_FILE" <<PHP
|
||||
<?php
|
||||
\$config['db_server'] = '${DB_HOST}';
|
||||
\$config['db_user'] = '${DB_USER}';
|
||||
\$config['db_password'] = '${DB_PASSWORD}';
|
||||
\$config['db_database'] = '${DB_NAME}';
|
||||
\$config['db_prefix'] = '${DB_PREFIX}';
|
||||
\$config['offline'] = 0;
|
||||
\$config['debug'] = 0;
|
||||
\$config['httpclientlog'] = 0;
|
||||
\$config['IMDBage'] = 604800;
|
||||
\$config['hierarchical'] = 1;
|
||||
\$config['cache_pruning'] = 1;
|
||||
\$config['http_caching'] = 0;
|
||||
\$config['lookupdefault_edit'] = 0;
|
||||
\$config['lookupdefault_new'] = 2;
|
||||
\$config['diskid_digits'] = 4;
|
||||
\$config['thumbnail_level'] = 1;
|
||||
\$config['thumbnail_quality'] = 80;
|
||||
\$config['xml'] = 0;
|
||||
\$config['xml_thumbnails'] = 0;
|
||||
\$config['rss'] = 1;
|
||||
\$config['pdf'] = 1;
|
||||
\$config['pdf_font_title'] = 'Arial';
|
||||
\$config['pdf_font_plot'] = 'Times';
|
||||
\$config['pdf_font_size'] = 10;
|
||||
\$config['pdf_image_max_width'] = 95;
|
||||
\$config['pdf_image_max_height'] = 135;
|
||||
\$config['pdf_image_media_width'] = 8;
|
||||
\$config['pdf_page_width'] = 210;
|
||||
\$config['pdf_text_length'] = 500;
|
||||
\$config['pdf_margin'] = 5;
|
||||
\$config['pdf_left_margin'] = 5;
|
||||
\$config['pdf_right_margin'] = 5;
|
||||
\$config['pdf_image_height'] = 24;
|
||||
\$config['pdf_image_width'] = intval((\$config['pdf_image_max_width'] / \$config['pdf_image_max_height']) * \$config['pdf_image_height']);
|
||||
\$config['xls'] = 1;
|
||||
\$config['xls_sheet_title'] = 'VideoDB';
|
||||
\$config['xls_output_filename'] = 'VideoDB';
|
||||
\$config['xls_show_headline'] = 1;
|
||||
\$config['xls_mark_unseen'] = 1;
|
||||
\$config['xls_mark_lent'] = 1;
|
||||
\$config['xls_extra_fields'] = 'title (plot), diskid, genres, language, mediatype, runtime, year, custom1, custom2, custom3, custom4, insertdate, owner, lent';
|
||||
\$config['dvdb_user'] = '';
|
||||
\$config['dvdb_password'] = '';
|
||||
PHP
|
||||
|
||||
chown www-data:www-data "$CONFIG_FILE"
|
||||
echo "[entrypoint] config.inc.php written."
|
||||
|
||||
# ── Wait for MySQL ─────────────────────────────────────────────────────────────
|
||||
echo "[entrypoint] Waiting for MySQL at ${DB_HOST}..."
|
||||
until mysqladmin ping -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASSWORD" --silent 2>/dev/null; do
|
||||
printf "."
|
||||
sleep 2
|
||||
done
|
||||
echo ""
|
||||
echo "[entrypoint] MySQL is ready."
|
||||
|
||||
# ── Initialize DB schema (idempotent) ─────────────────────────────────────────
|
||||
php /usr/local/bin/init-db.php
|
||||
|
||||
# ── Ensure cache dirs exist and are writable ──────────────────────────────────
|
||||
mkdir -p \
|
||||
/var/www/html/cache/smarty \
|
||||
/var/www/html/cache/imdb \
|
||||
/var/www/html/cache/img \
|
||||
/var/www/html/cache/thumbs \
|
||||
/var/www/html/cache/javascript \
|
||||
/var/www/html/cache/local
|
||||
chown -R www-data:www-data /var/www/html/cache /var/www/html/images
|
||||
|
||||
echo "[entrypoint] Starting Apache..."
|
||||
exec "$@"
|
||||
430
videodb/edit.php
Normal file
430
videodb/edit.php
Normal file
@@ -0,0 +1,430 @@
|
||||
<?php
|
||||
/**
|
||||
* Edit Page
|
||||
*
|
||||
* The edit form for adding and editing video data
|
||||
*
|
||||
* @todo Add error message for unknown genres
|
||||
*
|
||||
* @package videoDB
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @version $Id: edit.php,v 2.90 2013/03/11 19:00:26 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './core/genres.php';
|
||||
require_once './core/custom.php';
|
||||
require_once './core/edit.core.php';
|
||||
require_once './engines/engines.php';
|
||||
|
||||
// check for localnet
|
||||
localnet_or_die();
|
||||
|
||||
global $CLIENTERROR;
|
||||
|
||||
/**
|
||||
* input id
|
||||
*/
|
||||
$id = req_int('id');
|
||||
|
||||
// multiuser permission check
|
||||
permission_or_die(PERM_WRITE, ($id) ? get_owner_id($id) : PERM_ANY);
|
||||
|
||||
/**
|
||||
* input
|
||||
*/
|
||||
$save = req_int('save');
|
||||
$ajax_type = req_string('ajax_type');
|
||||
$ajax_prefetch_id = req_string('ajax_prefetch_id'); // elegant only
|
||||
$ajax_autocomplete_title = req_string('ajax_autocomplete_title'); // elegent and nexgen
|
||||
$ajax_autocomplete_subtitle = req_string('ajax_autocomplete_subtitle'); // not used
|
||||
$ajax_check_duplicate = req_string('ajax_check_duplicate'); // not used
|
||||
$import = req_string('import');
|
||||
$lookup = req_int('lookup');
|
||||
$engine = req_string('engine');
|
||||
$genres = req_array('genres');
|
||||
$copy = req_int('copy');
|
||||
$copyid = req_int('copyid');
|
||||
// $imdb_set_fields
|
||||
$md5 = req_string('md5');
|
||||
$title = req_string('title');
|
||||
$subtitle = req_string('subtitle');
|
||||
$language = req_string('language');
|
||||
$diskid = req_string('diskid');
|
||||
$mediatype = req_string('mediatype');
|
||||
$comment = req_string('comment');
|
||||
$disklabel = req_string('disklabel');
|
||||
$imdbID = req_string('imdbID');
|
||||
$year = req_string('year');
|
||||
$imgurl = req_string('imgurl');
|
||||
$director = req_string('director');
|
||||
$actors = req_string('actors');
|
||||
$runtime = req_string('runtime');
|
||||
$country = req_string('country');
|
||||
$plot = req_string('plot');
|
||||
$filename = req_string('filename');
|
||||
$filesize = req_string('filesize');
|
||||
$filedate = req_string('filedate');
|
||||
$audio_codec = req_string('audio_codec');
|
||||
$video_codec = req_string('video_codec');
|
||||
$video_width = req_string('video_width');
|
||||
$video_height = req_string('video_height');
|
||||
$istv = req_int('istv');
|
||||
$rating = req_string('rating');
|
||||
$custom1 = req_string('custom1');
|
||||
$custom2 = req_string('custom2');
|
||||
$custom3 = req_string('custom3');
|
||||
$custom4 = req_string('custom4');
|
||||
// from engineGetData (specific imdb)
|
||||
$mpaa = req_string('mpaa'); // if customXtype == mpaa => imdbdata[mpaa]
|
||||
$origtitle = req_string('origtitle'); // ?
|
||||
$tvseries_id = req_string('tvseries_id'); // ?
|
||||
// from edit.tpl
|
||||
$autoid = req_string('autoid');
|
||||
$oldmediatype = req_string('oldmediatype');
|
||||
$owner_id = req_int('owner_id');
|
||||
$seen = req_int('seen');
|
||||
$add_flag = req_int('add_flag');
|
||||
|
||||
// clean input data
|
||||
$genres = (is_array($genres)) ? array_filter($genres) : array();
|
||||
|
||||
// ajax autocomplete?
|
||||
if ($ajax_prefetch_id || $ajax_autocomplete_title || $ajax_autocomplete_subtitle)
|
||||
{
|
||||
// add some delay for debugging
|
||||
if ($config['debug'] && $_SERVER['SERVER_ADDR'] == '127.0.0.1') usleep(rand(200,1000)*1000);
|
||||
|
||||
// prefetch external data
|
||||
if ($ajax_prefetch_id)
|
||||
{
|
||||
$data = engineGetData($ajax_prefetch_id, engineGetEngine($ajax_prefetch_id));
|
||||
if (count($data))
|
||||
{
|
||||
$data['imdbID'] = $ajax_prefetch_id;
|
||||
$data['actors'] = $data['cast'];
|
||||
$data['imgurl'] = $data['coverurl'];
|
||||
}
|
||||
/*
|
||||
// load languages and config into Smarty
|
||||
tpl_language();
|
||||
tpl_edit($data);
|
||||
$content = $smarty->fetch('edit.tpl');
|
||||
# file_append(LOG_FILE, $content);
|
||||
|
||||
echo $content;
|
||||
*/
|
||||
exit;
|
||||
}
|
||||
|
||||
// use subtitle for aka search
|
||||
$data = ($ajax_autocomplete_title) ?
|
||||
engineSearch($ajax_autocomplete_title, engineGetDefault()) :
|
||||
engineSearch($ajax_autocomplete_subtitle, engineGetDefault(), true);
|
||||
|
||||
if ($ajax_type == 'json') {
|
||||
# file_append(LOG_FILE, $res);
|
||||
header("Content-Type: application/json");
|
||||
echo(json_encode($data));
|
||||
exit;
|
||||
}
|
||||
|
||||
foreach ($data as $item)
|
||||
{
|
||||
$text = preg_replace('/('.$ajax_autocomplete_title.')/i', '<em>\1</em>', $item['title']);
|
||||
$text.= (($item['year']) ? "<span class='informal'> (".$item['year'].")</span>" : '');
|
||||
$ret .= "<li id='".$item['id']."'>".$text."</li>";
|
||||
}
|
||||
$ret = "<ul>$ret</ul>";
|
||||
|
||||
exit($ret);
|
||||
}
|
||||
|
||||
// duplicate check
|
||||
if ($ajax_check_duplicate)
|
||||
{
|
||||
$q = escapeSQL($ajax_check_duplicate);
|
||||
$res = runSQL("SELECT id, title FROM ".TBL_DATA." WHERE imdbid='".$q."' OR title LIKE '%".$q."%' AND owner_id=".get_current_user_id());
|
||||
|
||||
header('X-JSON: '.json_encode($res));
|
||||
exit;
|
||||
}
|
||||
|
||||
// XML import
|
||||
if ($config['xml'] && ($import == 'xml'))
|
||||
{
|
||||
require_once './core/xml.php';
|
||||
|
||||
// xml file upload
|
||||
if (isset($_FILES['xmlfile']) && is_uploaded_file($_FILES['xmlfile']['tmp_name']))
|
||||
{
|
||||
$file = $_FILES['xmlfile']['tmp_name'];
|
||||
$xmldata = file_get_contents($file);
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
// uploading XML data directly or loaded from file
|
||||
if (!empty($xmldata))
|
||||
{
|
||||
$error = '';
|
||||
$item_id = 0;
|
||||
|
||||
require_once './core/xmlimport.php'; // @todo 404
|
||||
|
||||
if (function_exists('xmlimport') && ($xmlitems = xmlimport($xmldata, $error)) !== false)
|
||||
{
|
||||
// multiple items imported
|
||||
if ($xmlitems === true)
|
||||
{
|
||||
redirect('index.php?filter=new');
|
||||
}
|
||||
// exactly one movie imported?
|
||||
else
|
||||
{
|
||||
redirect('show.php?id='.$xmlitems);
|
||||
}
|
||||
}
|
||||
$smarty->assign('xmlerror', $error);
|
||||
}
|
||||
|
||||
// prepare templates
|
||||
tpl_page();
|
||||
|
||||
// display templates
|
||||
tpl_display('xmlimport.tpl');
|
||||
exit;
|
||||
}
|
||||
|
||||
// legacy
|
||||
if (isset($imdb) && $imdb) {$lookup = 1;}
|
||||
|
||||
// get default lookup mode (0=ignore, 1=lookup, 2=overwrite) if not set
|
||||
if (!isset($lookup)) $lookup = (empty($id)) ? $lookup = $config['lookupdefault_new'] : $config['lookupdefault_edit'];
|
||||
|
||||
// preload old data for refresh all mechanism
|
||||
if ($lookup > 2)
|
||||
{
|
||||
// get a list of movies in DB
|
||||
$video = runSQL('SELECT * FROM '.TBL_DATA.' WHERE id = '.$id);
|
||||
|
||||
// get fields (according to list) from db to be saved later
|
||||
foreach ($video[0] as $name => $val)
|
||||
{
|
||||
if (in_array($name, $imdb_set_fields)) $$name = $val;
|
||||
}
|
||||
$owner_id = $video[0]['owner_id'];
|
||||
|
||||
// Build a list of all fields which are allowed to be overwritten
|
||||
$overwrites = array();
|
||||
foreach ($imdb_set_fields as $field)
|
||||
{
|
||||
$tempFieldName = 'update_'.$field;
|
||||
if (isset($$tempFieldName) && $$tempFieldName == 1) $overwrites[] = $field;
|
||||
}
|
||||
$imdb_set_fields = $overwrites;
|
||||
|
||||
// valid input values for lookup > 2 are either 5 (add missing) or 6 (overwrite)
|
||||
$lookup -= 4;
|
||||
}
|
||||
|
||||
// lookup imdb
|
||||
if ($lookup && $imdbID)
|
||||
{
|
||||
// get engine from id
|
||||
if (empty($engine)) $engine = engineGetEngine($imdbID);
|
||||
|
||||
// get external data
|
||||
$imdbdata = engineGetData($imdbID, $engine);
|
||||
|
||||
// lookup cover
|
||||
if (empty($imgurl) || ($lookup > 1))
|
||||
{
|
||||
$imgurl = $imdbdata['coverurl'];
|
||||
}
|
||||
|
||||
// lookup genres
|
||||
if (count($genres) == 0 || ($lookup > 1))
|
||||
{
|
||||
$genres = array();
|
||||
$gnames = $imdbdata['genres'];
|
||||
if (isset($gnames))
|
||||
{
|
||||
foreach ($gnames as $gname)
|
||||
{
|
||||
// check if genre is found- otherwise fail silently
|
||||
if (is_numeric($genre = getGenreId($gname)))
|
||||
{
|
||||
$genres[] = $genre;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// lookup actors
|
||||
if (empty($actors) || ($lookup > 1))
|
||||
{
|
||||
$actors = $imdbdata['cast'];
|
||||
}
|
||||
|
||||
// lookup all other fields
|
||||
foreach (array_keys($imdbdata) as $name)
|
||||
{
|
||||
if (in_array($name, array('coverurl', 'genres', 'cast', 'id'))) continue;
|
||||
|
||||
// use !$$ as empty($$) doesn't seem to work
|
||||
if (!$$name || ($lookup > 1))
|
||||
{
|
||||
$$name = $imdbdata[$name];
|
||||
}
|
||||
}
|
||||
|
||||
// custom fields
|
||||
for ($i=1; $i<=4; $i++)
|
||||
{
|
||||
$custom = 'custom'.$i;
|
||||
$type = $config[$custom.'type'];
|
||||
if (!empty($type) && isset($$type))
|
||||
{
|
||||
// copy imdb data into corresponding custom field
|
||||
$$custom = $$type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get fields from db if copying
|
||||
if ($copy && $copyid)
|
||||
{
|
||||
$video = runSQL('SELECT * FROM '.TBL_DATA.' WHERE id = '.$copyid);
|
||||
|
||||
// get fields (according to list) from db to be saved later
|
||||
foreach ($video[0] as $name => $val)
|
||||
{
|
||||
// don't copy diskid
|
||||
if ($name == 'diskid')
|
||||
{
|
||||
if ($config['autoid'])
|
||||
{
|
||||
$$name = getDiskId();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (in_array($name, $imdb_set_fields)) $$name = $val;
|
||||
}
|
||||
}
|
||||
|
||||
$genres = getItemGenres($copyid);
|
||||
}
|
||||
|
||||
|
||||
// save data
|
||||
if ($save)
|
||||
{
|
||||
// uncomment the following line to provide simple protection for your own public access videoDB
|
||||
//if (!preg_match('/[0-9]{2+}/', $id)) break;
|
||||
|
||||
// implicit owner id if not set
|
||||
if (!$owner_id) $owner_id = get_current_user_id();
|
||||
|
||||
// generate diskid
|
||||
if (empty($diskid) && $config['autoid'] && $mediatype != MEDIA_WISHLIST) $diskid = getDiskId();
|
||||
|
||||
// write videodata table
|
||||
$SETS = prepareSQL($GLOBALS);
|
||||
$id = updateDB($SETS, $id, ($oldmediatype == MEDIA_WISHLIST) && ($mediatype != MEDIA_WISHLIST));
|
||||
|
||||
// save genres
|
||||
setItemGenres($id, $genres);
|
||||
|
||||
// set seen for currently logged in user
|
||||
set_userseen($id, $seen);
|
||||
|
||||
// uploaded cover?
|
||||
if (isset($_FILES['coverupload']['tmp_name']) &&
|
||||
isset($_FILES['coverupload']['type']) &&
|
||||
isset($_FILES['coverupload']['name']))
|
||||
{
|
||||
processUpload($id, $_FILES['coverupload']['tmp_name'], $_FILES['coverupload']['type'], $_FILES['coverupload']['name']);
|
||||
}
|
||||
|
||||
// make sure no artifacts
|
||||
$smarty->clearCache('list.tpl');
|
||||
$smarty->clearCache('show.tpl', get_current_user_id().'|'.$id);
|
||||
|
||||
// add another?
|
||||
if ($add_flag)
|
||||
{
|
||||
// remove id to prevent edit mode instead of new
|
||||
$id = '';
|
||||
$smarty->assign('add_flag', $add_flag);
|
||||
}
|
||||
else
|
||||
{
|
||||
// show the saved movie
|
||||
redirect('show.php?id='.$id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// load existing data
|
||||
if ($id)
|
||||
{
|
||||
$SELECT = '';
|
||||
// select all fields according to list, plus id
|
||||
foreach ($imdb_set_fields as $name)
|
||||
{
|
||||
if ($SELECT) $SELECT .= ', ';
|
||||
$SELECT .= $name;
|
||||
}
|
||||
|
||||
$SELECT = 'SELECT '.TBL_DATA.'.id, '.TBL_DATA.'.owner_id, '.TBL_USERS.'.name AS owner,
|
||||
!ISNULL('.TBL_USERSEEN.'.video_id) AS seen, '.$SELECT.'
|
||||
FROM '.TBL_DATA.'
|
||||
LEFT JOIN '.TBL_USERS.' ON '.TBL_DATA.'.owner_id = '.TBL_USERS.'.id
|
||||
LEFT JOIN '.TBL_USERSEEN.'
|
||||
ON '.TBL_DATA.'.id = '.TBL_USERSEEN.'.video_id AND '.TBL_USERSEEN.'.user_id = '.get_current_user_id().'
|
||||
WHERE '.TBL_DATA.'.id = '.$id;
|
||||
$video = runSQL($SELECT);
|
||||
|
||||
// diskid to global scope:
|
||||
$diskid = $video[0]['diskid'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$video[0]['language'] = $config['langdefault'];
|
||||
}
|
||||
|
||||
|
||||
// assign automatic disk id
|
||||
if ($config['autoid'] && (empty($diskid) || $add_flag) && $mediatype != MEDIA_WISHLIST)
|
||||
{
|
||||
$video[0]['diskid'] = getDiskId();
|
||||
|
||||
// Fix for Bugreport [1122052] Automatic DiskID generation problem
|
||||
$smarty->assign('autoid', $result[0]['max']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$smarty->assign('autoid', "");
|
||||
}
|
||||
|
||||
if (empty($video[0]['owner_id']) && !empty($owner_id))
|
||||
{
|
||||
$video[0]['owner_id'] = $owner_id;
|
||||
}
|
||||
|
||||
|
||||
// prepare templates
|
||||
tpl_page();
|
||||
tpl_edit($video[0]);
|
||||
|
||||
$smarty->assign('lookup_id', $lookup);
|
||||
$smarty->assign('http_error', $CLIENTERROR);
|
||||
|
||||
// allow XML import
|
||||
if ($config['xml'] && empty($id)) $smarty->assign('xmlimport', true);
|
||||
|
||||
// display templates
|
||||
tpl_display('edit.tpl');
|
||||
|
||||
602
videodb/engines/allocine.php
Executable file
602
videodb/engines/allocine.php
Executable file
@@ -0,0 +1,602 @@
|
||||
<?php
|
||||
/**
|
||||
* Allocine Parser
|
||||
*
|
||||
* Parses data from the Allocine.fr
|
||||
*
|
||||
* @package Engines
|
||||
* @author Douglas Mayle <douglas@mayle.org>
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author tedemo <tedemo@free.fr>
|
||||
* @link http://www.allocine.fr Internet Movie Database
|
||||
* @version $Id: allocine.php,v 1.17 2011/06/24 23:08:06 robelix Exp $
|
||||
*/
|
||||
|
||||
$GLOBALS['allocineServer'] = 'https://www.allocine.fr';
|
||||
$GLOBALS['allocineIdPrefix'] = 'allocine:';
|
||||
|
||||
/**
|
||||
* Get meta information about the engine
|
||||
*
|
||||
* @todo Include image search capabilities etc in meta information
|
||||
*/
|
||||
|
||||
function allocineMeta()
|
||||
{
|
||||
return array('name' => 'Allocine (fr)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode title search to allow results with accentued characters
|
||||
* @author Martin Vauchel <martin@vauchel.com>
|
||||
* @param string The search string
|
||||
* @return string The search string with no accents
|
||||
*/
|
||||
function removeAccents($title)
|
||||
{
|
||||
$accentued = array("à","á","â","ã","ä","ç","è","é","ê","ë","ì",
|
||||
"í","î","","ï","ñ","ò","ó","ô","õ","ö","ù","ú","û","ü","ý","ÿ",
|
||||
"À","Á","Â","Ã","Ä","Ç","È","É","Ê","Ë","Ì","Í","Î","Ï","Ñ","Ò",
|
||||
"Ó","Ô","Õ","Ö","Ù","Ú","Û","Ü","Ý");
|
||||
$nonaccentued = array("a","a","a","a","a","c","e","e","e","e","i","i",
|
||||
"i","i","n","o","o","o","o","o","u","u","u","u","y","y","A","A","A",
|
||||
"A","A","C","E","E","E","E","I","I","I","I","N","O","O","O","O","O",
|
||||
"U","U","U","U","Y");
|
||||
|
||||
$title = str_replace($accentued, $nonaccentued, $title);
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url to search Allocine for a movie
|
||||
*
|
||||
* @author Douglas Mayle <douglas@mayle.org>
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string The search string
|
||||
* @return string The search URL (GET)
|
||||
*/
|
||||
function allocineSearchUrl($title)
|
||||
{
|
||||
global $allocineServer;
|
||||
// The removeAccents function is added here
|
||||
return $allocineServer.'/recherche/?q='.urlencode(removeAccents($title));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url to visit Allocine for a specific movie
|
||||
*
|
||||
* @author Douglas Mayle <douglas@mayle.org>
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string $id The movie's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function allocineContentUrl($id)
|
||||
{
|
||||
global $allocineServer;
|
||||
global $allocineIdPrefix;
|
||||
|
||||
$allocineID = preg_replace('/^'.$allocineIdPrefix.'/', '', $id);
|
||||
return $allocineServer.'/film/fichefilm_gen_cfilm='.$allocineID.'.html';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search a Movie
|
||||
*
|
||||
* Searches for a given title on Allocine and returns the found links in
|
||||
* an array
|
||||
*
|
||||
* @author Douglas Mayle <douglas@mayle.org>
|
||||
* @author Tiago Fonseca <t_r_fonseca@yahoo.co.uk>
|
||||
* @author Charles Morgan <cmorgan34@yahoo.com>
|
||||
* @param string The search string
|
||||
* @return array Associative array with id and title
|
||||
*/
|
||||
function allocineSearch($title)
|
||||
{
|
||||
global $allocineServer;
|
||||
global $CLIENTERROR;
|
||||
|
||||
// The removeAccents function is added here
|
||||
$resp = httpClient(allocineSearchUrl($title), 1);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
$data = array();
|
||||
|
||||
#echo '<pre>';
|
||||
#dump(htmlspecialchars($resp['data']));
|
||||
#echo '</pre>';
|
||||
|
||||
// add encoding
|
||||
$data['encoding'] = $resp['encoding'];
|
||||
|
||||
// direct match (redirecting to individual title)?
|
||||
// no longer needed??
|
||||
$single = array();
|
||||
if (preg_match('#^'.preg_quote($allocineServer,'/').'/film/fichefilm_gen_cfilm=(\d+)\.html#', $resp['url'], $single))
|
||||
{
|
||||
$data[0]['id'] = 'allocine:'.$single[2];
|
||||
$data[0]['title']= $title;
|
||||
return $data;
|
||||
}
|
||||
|
||||
// multiple matches
|
||||
// We remove all the multiples spaces and line breakers
|
||||
$resp['data'] = preg_replace('/[\s]{2,}/','',$resp['data']);
|
||||
// To have the result zone
|
||||
#$debutr = strpos($resp['data'], '<table class="totalwidth noborder purehtml">')+strlen('<table class="totalwidth noborder purehtml">');
|
||||
#$finr = strpos($resp['data'], '</table>', $debutr);
|
||||
#$chaine = substr($resp['data'], $debutr, $finr-$debutr);
|
||||
|
||||
preg_match('#<h2>\s*?Films\s*?</h2>(.*?)<h2>#si',$resp['data'],$ary);
|
||||
|
||||
$chaine = $ary[1];
|
||||
# contains some pretty random <b></b>
|
||||
$chaine = preg_replace('/<b>/','',$chaine);
|
||||
$chaine = preg_replace('/<\/b>/','',$chaine);
|
||||
|
||||
/*
|
||||
<tr><td style=" vertical-align:top;">
|
||||
<a href='/film/fichefilm_gen_cfilm=57999.html'><img
|
||||
src='http://images.allocine.fr/r_75_106/medias/nmedia/18/36/26/78/18759563.jpg'
|
||||
alt='Clerks II' /></a>
|
||||
</td><td style=" vertical-align:top;" class="totalwidth"><div><div style="margin-top:-5px;">
|
||||
<a href='/film/fichefilm_gen_cfilm=57999.html'>
|
||||
Clerks II</a>
|
||||
<br />
|
||||
<span class="fs11">
|
||||
2006<br />
|
||||
de Kevin Smith<br />
|
||||
avec Brian O'Halloran, Jeff Anderson<br />
|
||||
<div>
|
||||
<div class="spacer vmargin10"></div>
|
||||
</span> <!-- /fs11 -->
|
||||
*/
|
||||
|
||||
preg_match_all('#<a href=\'/film/fichefilm_gen_cfilm=(\d+).html\'>\s*?(.*?)</a>\s*?<br />\s*?<span class=\"fs11\">\s*?(\d+)<br />\s*?de (.*?)\s*?/#si', $chaine, $m, PREG_SET_ORDER);
|
||||
|
||||
foreach ($m as $row)
|
||||
{
|
||||
$info['id'] = 'allocine:'.$row[1];
|
||||
|
||||
$info['title'] = html_clean_utf8(strip_tags($row[2]));
|
||||
$info['title'] = str_replace("(", " (", $info['title']);
|
||||
|
||||
// add year (helpful in case of multiple matches)
|
||||
if (isset($row[3])) {$info['year'] = html_clean_utf8($row[3]);}
|
||||
|
||||
// add director (helpful in case of multiple matches)
|
||||
if (isset($row[4])) {
|
||||
$info['director'] = html_clean_utf8($row[4]);
|
||||
$info['director'] = preg_replace("/^de\s/", "", $info['director']);
|
||||
}
|
||||
|
||||
$data[] = $info;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the data for a given Allocine-ID
|
||||
*
|
||||
* @author Douglas Mayle <douglas@mayle.org>
|
||||
* @author Tiago Fonseca <t_r_fonseca@yahoo.co.uk>
|
||||
* @param int imdb-ID
|
||||
* @return array Result data
|
||||
*/
|
||||
function allocineData($imdbID)
|
||||
{
|
||||
global $allocineServer;
|
||||
global $allocineIdPrefix;
|
||||
global $CLIENTERROR;
|
||||
|
||||
$allocineID = preg_replace('/^'.$allocineIdPrefix.'/', '', $imdbID);
|
||||
|
||||
// fetch mainpage
|
||||
$resp = httpClient($allocineServer.'/film/fichefilm_gen_cfilm='.$allocineID.'.html', 1); // added trailing / to avoid redirect
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
$data = array(); // result
|
||||
$ary = array(); // temp
|
||||
|
||||
// add encoding
|
||||
$data['encoding'] = $resp['encoding'];
|
||||
|
||||
// Allocine ID
|
||||
$data['id'] = "allocine:".$allocineID;
|
||||
|
||||
// We remove all the multiples spaces and line breakers
|
||||
$resp['data'] = preg_replace('/[\s]{2,}/','',$resp['data']);
|
||||
|
||||
/*
|
||||
Title and subtitle
|
||||
*/
|
||||
preg_match('#<h1.*?>(.*?)</h1>#si', $resp['data'], $ary);
|
||||
list($t, $s) = explode(" - ",trim($ary[1]),2);
|
||||
// Some bugs when using html_clean function --> using html_clean_utf8
|
||||
$data['title'] = html_clean_utf8($t);
|
||||
$data['subtitle'] = html_clean_utf8($s);
|
||||
|
||||
|
||||
/*
|
||||
Year
|
||||
*/
|
||||
preg_match('/<a.*? href="\/film\/tous\/decennie.*?year=(\d+)">(\d+)<\/a>/i', $resp['data'], $ary);
|
||||
if (!empty($ary[1])) {$data['year'] = trim($ary[1]);}
|
||||
|
||||
|
||||
/*
|
||||
Release Date
|
||||
added to the comments
|
||||
*/
|
||||
preg_match('#<a.*? href="/film/agenda\.html\?week=\d+\-\d+\-\d+">(.*)</a>#i',$resp['data'], $ary);
|
||||
$release_date = "";
|
||||
if (!empty($ary[1])) {$release_date = "\r\nDate de sortie cinéma : ".html_clean_utf8($ary[1]);}
|
||||
|
||||
/*
|
||||
Cover URL
|
||||
*/
|
||||
preg_match('#<div class="colleft">\s*?<div class="vmargin20b">\s*?<div class=\"poster\">\s*?<em class=\"imagecontainer\">\s*?<a .*?>\s*?<img.*?src=\'(.*?)\'.*?>#si', $resp['data'], $ary);
|
||||
$data['coverurl'] = trim($ary[1]);
|
||||
|
||||
|
||||
/*
|
||||
Runtime
|
||||
*/
|
||||
#Durée : 02h13min
|
||||
|
||||
preg_match('/Durée :\s*?(\d+)h(\d+)\s*?min/i', $resp['data'], $ary);
|
||||
$hours = preg_replace('/,/', '', trim($ary[1]));
|
||||
$minutes = preg_replace('/,/', '', trim($ary[2]));
|
||||
$data['runtime'] = $hours * 60 + $minutes;
|
||||
|
||||
|
||||
/*
|
||||
Director
|
||||
*/
|
||||
preg_match('#Réalisé par\s*<span.*?><a.*?rel="v:directedBy".*?href=\'/personne/fichepersonne_gen_cpersonne=\d+\.html\' title=\'.*\'>(.*)</a></span>#i', $resp['data'], $ary);
|
||||
$data['director'] = trim($ary[1]);
|
||||
|
||||
|
||||
/*
|
||||
Rating
|
||||
*/
|
||||
preg_match('#<p class="withstars"><a.*?href="/film/critiquepublic_gen_cfilm=\d+\.html"><img.*?class="stareval.*?".*?<span class=\"moreinfo\">\((.*)\)</span></p>#i', $resp['data'], $ary);
|
||||
$data['rating'] = trim($ary[1]);
|
||||
$data['rating'] = str_replace(",", ".", $data['rating']);
|
||||
// Allocine rating is based on 5, imdb is based on 10
|
||||
$data['rating'] = $data['rating'] * 2;
|
||||
|
||||
|
||||
/*
|
||||
Countries
|
||||
*/
|
||||
// Countries in English
|
||||
$map_countries = array(
|
||||
'allemand' => 'Germany',
|
||||
'américain' => 'USA',
|
||||
'arménien' => 'Armenia',
|
||||
'argentin' => 'Argentina',
|
||||
'sud-africain' => 'South Africa',
|
||||
'australien' => 'Australia',
|
||||
'belge' => 'Belgium',
|
||||
'britannique' => 'UK',
|
||||
'bulgare' => 'Bulgaria',
|
||||
'canadien' => 'Canada',
|
||||
'chinois' => 'China',
|
||||
'coréen' => 'South Korea',
|
||||
'danois' => 'Denmark',
|
||||
'espagnol' => 'Spain',
|
||||
'français' => 'France',
|
||||
'grec' => 'Greece',
|
||||
'hollandais' => 'Netherlands',
|
||||
'hong-kongais' => 'Hong-Kong',
|
||||
'hongrois' => 'Hungary',
|
||||
'indien' => 'India',
|
||||
'irlandais' => 'Republic of Ireland',
|
||||
'islandais' => 'Iceland',
|
||||
'israëlien' => 'Israel',
|
||||
'italien' => 'Italy',
|
||||
'japonais' => 'Japan',
|
||||
'luxembourgeois' => 'Luxembourg',
|
||||
'mexicain' => 'Mexico',
|
||||
'norvégien' => 'Norge',
|
||||
'néo-zélandais' => 'New Zealand',
|
||||
'polonais' => 'Poland',
|
||||
'portugais' => 'Portugal',
|
||||
'roumain' => 'Romania',
|
||||
'russe' => 'Russia',
|
||||
'serbe' => 'Serbia',
|
||||
'suédois' => 'Sweden',
|
||||
'taïwanais' => 'Taiwan',
|
||||
'tchèque' => 'Czech Republic',
|
||||
'thaïlandais' => 'Thailand',
|
||||
'turc' => 'Turkey',
|
||||
'ukrainien' => 'Ukraine',
|
||||
'vietnamien' => 'Vietnam');
|
||||
|
||||
if (preg_match_all('#Long\-métrage\s*?<a.*?href=".*?">(.*?)</a>#si', $resp['data'], $ary, PREG_PATTERN_ORDER) > 0)
|
||||
{
|
||||
$originlist = explode(",",trim(join(', ', $ary[1])));
|
||||
foreach ($originlist as $origin)
|
||||
{
|
||||
$mapped_country_found = '';
|
||||
|
||||
foreach ($map_countries as $pattern_c => $mapped_country)
|
||||
{
|
||||
if (preg_match_all('/'.$pattern_c.'/i', $origin, $junk, PREG_PATTERN_ORDER) > 0)
|
||||
{
|
||||
$mapped_country_found = $mapped_country;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if($data['country'] == '') {$data['country'] = $mapped_country_found;}
|
||||
elseif(stristr($data['country'], $mapped_country_found) == TRUE)
|
||||
{
|
||||
$data['country'] = $data['country'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['country'] = $data['country'] . ', ' . $mapped_country_found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Plot
|
||||
*/
|
||||
preg_match('#<div id="synopsis_full">\s*?<p>\s*?<span class=\"bold\">Synopsis \: </span>\s*?<span property="v:summary">(.*?)</span>#is', $resp['data'], $ary);
|
||||
if (!empty($ary[1])) {
|
||||
$data['plot'] = $ary[1];
|
||||
$data['plot']= html_clean_utf8($data['plot']);
|
||||
|
||||
// And cleanup
|
||||
$data['plot'] = trim($data['plot']);
|
||||
$data['plot'] = preg_replace('/[\n\r]/',' ', $data['plot']);
|
||||
$data['plot'] = preg_replace('/ /',' ', $data['plot']);
|
||||
}
|
||||
|
||||
/*
|
||||
Genres (as Array)
|
||||
*/
|
||||
$map_genres = array(
|
||||
'Action' => 'Action',
|
||||
'Animation' => 'Animation',
|
||||
'Arts Martiaux' => 'Action',
|
||||
'Aventure' => 'Adventure',
|
||||
'Biopic' => 'Biography',
|
||||
'Bollywood' => 'Musical',
|
||||
'Classique' => '-',
|
||||
'Comédie Dramatique' => 'Drama',
|
||||
'Comédie musicale' => 'Musical',
|
||||
'Comédie' => 'Comedy',
|
||||
'Dessin animé' => 'Animation',
|
||||
'Divers' => '-',
|
||||
'Documentaire' => 'Documentary',
|
||||
'Drame' => 'Drama',
|
||||
'Epouvante-horreur' => 'Horror',
|
||||
'Erotique' => 'Adult',
|
||||
'Espionnage' => '-',
|
||||
'Famille' => 'Family',
|
||||
'Fantastique' => 'Fantasy',
|
||||
'Guerre' => 'War',
|
||||
'Historique' => 'History',
|
||||
'Horreur' => 'Horror',
|
||||
'Musique' => 'Musical',
|
||||
'Policier' => 'Crime',
|
||||
'Péplum' => 'History',
|
||||
'Romance' => 'Romance',
|
||||
'Science fiction' => 'Sci-Fi',
|
||||
'Thriller' => 'Thriller',
|
||||
'Western' => 'Western');
|
||||
|
||||
if (preg_match_all('#Genre :(.*?)</a>\s*?<br#si', $resp['data'], $ary, PREG_PATTERN_ORDER) > 0)
|
||||
{
|
||||
$genrelist = explode(",", trim(join(', ', $ary[1])));
|
||||
|
||||
foreach ($genrelist as $genre)
|
||||
{
|
||||
$mapped_genre_found = '';
|
||||
foreach ($map_genres as $pattern => $mapped_genre)
|
||||
{
|
||||
if (preg_match_all('/'.$pattern.'/i', $genre, $junk, PREG_PATTERN_ORDER) > 0)
|
||||
{
|
||||
$mapped_genre_found = $mapped_genre;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$data['genres'][] = ($mapped_genre_found != '-') ? $mapped_genre_found : trim($genre);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Original Title
|
||||
*/
|
||||
preg_match('#Titre original : <span class=\"purehtml\"><em>(.*)</em></span>#', $resp['data'], $ary);
|
||||
$data['origtitle'] = trim($ary[1]);
|
||||
|
||||
/*
|
||||
Title and Subtitle
|
||||
If sub-title is blank, we'll try to fill in the original title for foreign films.
|
||||
*/
|
||||
if (empty($data['subtitle']))
|
||||
{
|
||||
if ($data['origtitle'])
|
||||
{
|
||||
$data['subtitle'] = $data['title'];
|
||||
$data['title'] = $data['origtitle'];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
CREDITS AND CAST
|
||||
*/
|
||||
// fetch credits
|
||||
// Another HTML page
|
||||
$resp = httpClient($allocineServer.'/film/casting_gen_cfilm='.$allocineID.'.html', 1);
|
||||
if (!$resp['success']) {$CLIENTERROR .= $resp['error']."\n";}
|
||||
|
||||
// We remove all the multiples spaces and line breakers
|
||||
$resp['data'] = preg_replace('/[\s]{2,}/','',$resp['data']);
|
||||
|
||||
if (preg_match('#<h2>Acteurs, rôles, personnages</h2>(.*?)<div class="titlebar">\s*?<a class="anchor" id=\'actors\'></a>\s*?<h2>#is', $resp['data'], $Section))
|
||||
{
|
||||
|
||||
# the big ones with image
|
||||
/*
|
||||
<div class="titlebar">
|
||||
<h3>
|
||||
<a href="/personne/fichepersonne_gen_cpersonne=5568.html">Liam Neeson</a>
|
||||
</h3>
|
||||
</div>
|
||||
<p>
|
||||
Rôle : Qui-Gon Jinn
|
||||
</p>
|
||||
<div class="spacer"></div>
|
||||
*/
|
||||
preg_match_all('#<div class="titlebar">\s*?<h3>\s*?<a href="/personne/fichepersonne_gen_cpersonne=(\d+?).html">(.*?)</a>\s*?</h3>\s*?</div>\s*?<p>\s*Rôle : (.*?)\s*</p>#is', $Section[1], $ary, PREG_PATTERN_ORDER);
|
||||
|
||||
$count = 0;
|
||||
$cast = '';
|
||||
while (isset($ary[1][$count]))
|
||||
{
|
||||
$cast .= $ary[2][$count]."::".$ary[3][$count]."::allocine:".$ary[1][$count]."\n";
|
||||
$count++;
|
||||
}
|
||||
|
||||
# extended cast - without image
|
||||
/*
|
||||
<tr class="odd">
|
||||
<td>
|
||||
Shmi Skywalker
|
||||
</td>
|
||||
<td>
|
||||
<a href="/personne/fichepersonne_gen_cpersonne=14279.html">Pernilla August</a>
|
||||
</td>
|
||||
</tr>
|
||||
*/
|
||||
preg_match_all('#<tr.*?>\s*?<td>\s*(.*?)\s*</td>\s*?<td>\s*?<a href="/personne/fichepersonne_gen_cpersonne=(\d+).html">(.*?)</a>\s*?</td>#si', $Section[1], $ary, PREG_PATTERN_ORDER);
|
||||
|
||||
$count = 0;
|
||||
while (isset($ary[1][$count]))
|
||||
{
|
||||
$cast .= $ary[3][$count]."::".$ary[1][$count]."::allocine:".$ary[2][$count]."\n";
|
||||
$count++;
|
||||
}
|
||||
$data['cast'] = trim($cast);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Comments
|
||||
*/
|
||||
// By default
|
||||
$data['language'] = 'french';
|
||||
|
||||
// Another HTML page
|
||||
$resp = httpClient($allocineServer.'/film/fichefilm-'.$allocineID.'/technique/', 1);
|
||||
if (!$resp['success']) {$CLIENTERROR .= $resp['error']."\n";}
|
||||
|
||||
// We remove all the multiples spaces and line breakers
|
||||
$resp['data'] = preg_replace('/[\s]{2,}/','',$resp['data']);
|
||||
|
||||
// Technical informations as comment
|
||||
preg_match('#<div class=\"rubric\">\s*?<div class=\"vpadding20b\">\s*(.*?)\s*</div>\s*?</div>#si', $resp['data'], $ary);
|
||||
if (!empty($ary[1]))
|
||||
{
|
||||
$data['comment'] = $ary[1];
|
||||
|
||||
$data['comment'] = str_replace("Tourné en :", "Tourné en : ", $data['comment']);
|
||||
|
||||
// Adding the release date in theater
|
||||
$data['comment'] = $data['comment'] . $release_date;
|
||||
|
||||
// Search the language
|
||||
// Default language
|
||||
$data['language'] = "french";
|
||||
|
||||
if (preg_match('#<p>\s*?<span class=\"bold\">Tourné en :</span>\s*(.*?)\s*</p>#si', $resp['data'], $ary))
|
||||
{
|
||||
$data['language'] = $ary[1];
|
||||
|
||||
// Converting languages from french to english
|
||||
$map_languages = array(
|
||||
'Anglais' => 'english',
|
||||
'Français' => 'french',
|
||||
'Allemand' => 'german',
|
||||
'Italien' => 'italian',
|
||||
'Espagnol' => 'spanish',
|
||||
'Coréen' => 'Korean',
|
||||
'Roumain' => 'romanian',
|
||||
'Autre' => 'french',
|
||||
'Hindi' => 'hindi',
|
||||
'Arabe' => 'arabic',
|
||||
'Thaï' => 'thai',
|
||||
'Danois' => 'danish',
|
||||
'Suédois' => 'swedish',
|
||||
'Tchèque' => 'czech',
|
||||
'Japonais' => 'japanese',
|
||||
'Portugais' => 'portuguese',
|
||||
'Norvégien' => 'norwegian',
|
||||
'Bulgare' => 'bulgarian',
|
||||
'Grec' => 'greek',
|
||||
'Hongrois' => 'hungarian',
|
||||
'Turc' => 'turkish',
|
||||
'Islandais' => 'icelandic',
|
||||
'Polonais' => 'polish',
|
||||
'Russe' => 'russian',
|
||||
'Ukrainien' => 'ukrainian',
|
||||
'Serbe' => 'serbian',
|
||||
'Vietnamien' => 'vietnamese',
|
||||
'Afrikaans' => 'afrikaans'
|
||||
);
|
||||
|
||||
foreach($map_languages as $pattern => $map_lang)
|
||||
{
|
||||
$data['language'] = str_replace($pattern, $map_lang, $data['language']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the data collected
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Actor-Details
|
||||
*
|
||||
* Find image and detail URL for actor, not sure if this can be made
|
||||
* a one-step process? Completion waiting on update of actor
|
||||
* functionality to support more than one engine.
|
||||
*
|
||||
* @author Douglas Mayle <douglas@mayle.org>
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string $name Name of the Actor
|
||||
* @return array array with Actor-URL and Thumbnail
|
||||
*/
|
||||
function allocineActor($name, $actorid)
|
||||
{
|
||||
global $allocineServer;
|
||||
|
||||
if (empty ($actorid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$url = 'https://www.allocine.fr/personne/fichepersonne_gen_cpersonne='.urlencode($actorid).'.html';
|
||||
$resp = httpClient($url, 1);
|
||||
|
||||
$single = array();
|
||||
if (preg_match ('/src="([^"]+allocine.fr\/acmedia\/medias\/nmedia\/[^"]+\/[0-9]+\.jpg)[^>]+width="120"/', $resp['data'], $single)) {
|
||||
$ary[0][0]=$url;
|
||||
$ary[0][1]=$single[1];
|
||||
return $ary;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
331
videodb/engines/dvdfr.php
Executable file
331
videodb/engines/dvdfr.php
Executable file
@@ -0,0 +1,331 @@
|
||||
<?php
|
||||
/**
|
||||
* Dvdfr Parser
|
||||
*
|
||||
* Parses data from www.dvdfr.com (french site)
|
||||
* 2006-08-12 Update Sebastien Koechlin <seb.videodb@koocotte.org>
|
||||
*
|
||||
* @package Engines
|
||||
* @author tedemo <tedemo@free.fr>
|
||||
* @link http://www.dvdfr.com
|
||||
* @version $Id: dvdfr.php,v 1.7 2011/06/23 12:27:28 robelix Exp $
|
||||
*/
|
||||
|
||||
require_once './core/compatibility.php';
|
||||
|
||||
$GLOBALS['dvdfrServer'] = 'https://www.dvdfr.com';
|
||||
$GLOBALS['dvdfrIdPrefix'] = 'dvdfr:';
|
||||
|
||||
/**
|
||||
* Get meta information about the engine
|
||||
*
|
||||
* @todo Include image search capabilities etc in meta information
|
||||
*/
|
||||
function dvdfrMeta()
|
||||
{
|
||||
return array('name' => 'Dvdfr (fr)', 'stable' => 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clean a string
|
||||
*
|
||||
* @param string The string to clean
|
||||
* @return string The cleaned string
|
||||
*/
|
||||
function dvdfrCleanStr($str)
|
||||
{
|
||||
// Remove spaces
|
||||
$str = trim($str);
|
||||
|
||||
// Translate strange (MS-Word?) quotes
|
||||
$str = preg_replace( '/'/', '\'', $str );
|
||||
|
||||
// Remove HTML entities
|
||||
$str = html_entity_decode($str);
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url to search Dvdfr for a movie
|
||||
*
|
||||
* @param string The search string
|
||||
* @return string The search URL (GET)
|
||||
*/
|
||||
function dvdfrSearchUrl($title)
|
||||
{
|
||||
global $dvdfrServer;
|
||||
return $dvdfrServer.'/api/search.php?title='.urlencode(mb_convert_encoding($title,'ISO-8859-15','UTF-8'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url to visit Dvdfr for a specific movie
|
||||
*
|
||||
* @param string $id The movie's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function dvdfrContentUrl($id)
|
||||
{
|
||||
list($engineword, $dvdfrID) = explode(':',$id,2);
|
||||
global $dvdfrServer;
|
||||
return $dvdfrServer.'/api/dvd.php?id='.$dvdfrID;
|
||||
#return 'http://koocotte.org/DVDMARK';
|
||||
}
|
||||
|
||||
/**
|
||||
* Search a Movie
|
||||
*
|
||||
* Searches for a given title on Dvdfr and returns the found links in
|
||||
* an array
|
||||
*
|
||||
* @return array Associative array with id and title
|
||||
*/
|
||||
function dvdfrSearch($title)
|
||||
{
|
||||
global $dvdfrServer;
|
||||
global $CLIENTERROR;
|
||||
|
||||
$para['useragent'] = 'VideoDB (http://www.videodb.net/)';
|
||||
|
||||
$resp = httpClient(dvdfrSearchUrl($title), 1, $para);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// Encoding
|
||||
$ary['encoding'] = $resp['encoding'];
|
||||
|
||||
/* No more direct match with XLM API
|
||||
|
||||
// direct match (redirecting to individual title)?
|
||||
$single = array();
|
||||
if (preg_match('/\/dvd\/dvd\.php\?id=(\d+)/', $resp['url'], $single))
|
||||
{
|
||||
$ary[0]['id'] = 'dvdfr:'.$single[1];
|
||||
preg_match('/<td><div class=\"dvd_title\">([^<]+)<\/div>[^<]*<div class=\"dvd_titlevo\">([^<]+)<\/div>[^<]*<div class=\"dvd_titleinfo\">([^<]+)</is', $resp['data'], $single);
|
||||
$ary[0]['title']= $single[1].' ('.$single[2].'/'.$single[3].')';
|
||||
return $ary;
|
||||
}
|
||||
*/
|
||||
// multiple matches
|
||||
/*
|
||||
<dvd>
|
||||
<id>16892</id> <= $1
|
||||
<media>DVD</media> <= $2
|
||||
<titres>
|
||||
<fr>Star Wars - Clone Wars - Vol. 1</fr> <= $3
|
||||
<vo>Star Wars: Clone Wars</vo> <= $4
|
||||
<alternatif></alternatif>
|
||||
<alternatif_vo></alternatif_vo>
|
||||
</titres>
|
||||
<annee>2003</annee> <= $5
|
||||
<edition></edition> <= $6
|
||||
<editeur>20th Century Fox</editeur> <= $7
|
||||
<stars>
|
||||
<star type="Réalisateur" id="49661">Genndy Tartakovsky</star>
|
||||
</stars>
|
||||
</dvd>
|
||||
*/
|
||||
|
||||
preg_match_all('#<dvd>\s*<id>(\d+)</id>\s*<media>(\w+)</media>\s*<titres>\s*<fr>(.+?)</fr>\s*<vo>(.*?)</vo>.*?<annee>(.*?)</annee>\s*<edition>(.*?)</edition>\s*<editeur>(.*?)</editeur>\s*.*?</dvd>#is', $resp['data'], $data, PREG_SET_ORDER);
|
||||
foreach ($data as $row)
|
||||
{
|
||||
$info['id'] = 'dvdfr:'.$row[1];
|
||||
$title = dvdfrCleanStr($row[3]);
|
||||
// add native title
|
||||
if( !empty($row[4]) ) $title .= " / " . dvdfrCleanStr($row[4]);
|
||||
|
||||
if( !empty($row[5]) and !empty($row[6]) and !empty($row[7]) ) {
|
||||
$title .= ' (';
|
||||
// add year (helpful in case of multiple matches)
|
||||
if( !empty($row[5]) ) $title .= dvdfrCleanStr($row[5]);
|
||||
$title .= '/';
|
||||
// add edition and editor
|
||||
if( !empty($row[6]) ) $title .= dvdfrCleanStr($row[6]);
|
||||
$title .= '/';
|
||||
if( !empty($row[7]) ) $title .= dvdfrCleanStr($row[7]);
|
||||
$title .=')';
|
||||
}
|
||||
|
||||
// Add record
|
||||
$info['title'] = $title;
|
||||
$ary[] = $info;
|
||||
}
|
||||
|
||||
return $ary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the data for a given Dvdfr-ID
|
||||
*
|
||||
* @param int IMDB-ID
|
||||
* @return array Result data
|
||||
*/
|
||||
function dvdfrData($imdbID)
|
||||
{
|
||||
global $dvdfrServer;
|
||||
global $CLIENTERROR;
|
||||
|
||||
$data= array(); // result
|
||||
$ary = array(); // temp
|
||||
|
||||
$para['useragent'] = 'VideoDB (http://www.videodb.net/)';
|
||||
|
||||
// fetch mainpage
|
||||
$resp = httpClient(dvdfrContentUrl($imdbID), 1, $para); // added trailing / to avoid redirect
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// add encoding
|
||||
$data['encoding'] = $resp['encoding'];
|
||||
|
||||
// See http://www.dvdfr.com/api/dvd.php?id=2869 for output
|
||||
|
||||
// Titles
|
||||
preg_match('#<titres>\s*<fr>(.+?)</fr>\s*<vo>(.+?)</vo>#is', $resp['data'], $ary);
|
||||
$data['title'] = mb_convert_case(dvdfrCleanStr($ary[1]), MB_CASE_TITLE, $data['encoding']);
|
||||
$data['subtitle'] = mb_convert_case(dvdfrCleanStr($ary[2]), MB_CASE_TITLE, $data['encoding']);
|
||||
|
||||
// I found: <div class="dvd_titleinfo">USA, Royaume-Uni , 2004<br />R&D TV, Sky TV, USA Cable Entertainment</div>
|
||||
preg_match('#<listePays>\s*<pays.*?>(.+?)</pays>#is', $resp['data'], $ary);
|
||||
$data['country'] = dvdfrCleanStr($ary[1]);
|
||||
preg_match('#<annee>(\d+)</annee>#is', $resp['data'], $ary);
|
||||
$data['year'] = dvdfrCleanStr($ary[1]);
|
||||
|
||||
// Cover URL
|
||||
preg_match('#<cover>(.*?)</cover>#i', $resp['data'], $ary);
|
||||
$data['coverurl'] = trim($ary[1]);
|
||||
|
||||
// Runtime
|
||||
preg_match('#<duree>(\d+)</duree>#i', $resp['data'], $ary);
|
||||
$data['runtime'] = $ary[1];
|
||||
|
||||
// Director (only the first one)
|
||||
preg_match('#<star type="R.*?alisateur" id="\d+">(.*?)</star>#i', $resp['data'], $ary);
|
||||
$data['director'] = dvdfrCleanStr($ary[1]);
|
||||
|
||||
// Plot
|
||||
preg_match('#<synopsis>(.*?)</synopsis>#is', $resp['data'], $ary);
|
||||
if (!empty($ary[1])) {
|
||||
$data['plot'] = $ary[1];
|
||||
// And cleanup
|
||||
$data['plot'] = preg_replace('/[\n\r]/',' ', $data['plot']);
|
||||
$data['plot'] = preg_replace('/\s+/',' ', $data['plot']);
|
||||
$data['plot'] = dvdfrCleanStr($data['plot']);
|
||||
}
|
||||
|
||||
// maps dvdfr category ids to videodb category names
|
||||
$category_map = array
|
||||
(
|
||||
"1" => "Action",
|
||||
"2" => "Animation",
|
||||
"61" => "", // "Autres séries"
|
||||
"3" => "Adventure",
|
||||
"72" => "", //"Beaux-Arts"
|
||||
"81" => "Musical", //"Bollywood"
|
||||
"4" => "Comedy",
|
||||
"5" => "Drama", // "Comédie dramatique"
|
||||
"6" => "Musical", //"Comédie musicale"
|
||||
"74" => "Romance", // "Comédie romantique"
|
||||
"7" => "Music", //"Concert"
|
||||
"8" => "" , //"Conte"
|
||||
"9" => "Short", //"Court-Métrage"
|
||||
"10" => "Documentary", //"Culture"
|
||||
"78" => "Documentary", //"Culture Gay"
|
||||
"11" => "Music", //"Danse"
|
||||
"12" => "", //"Divers"
|
||||
"13" => "Documentary", //"Documentaire"
|
||||
"14" => "Drama", //"Drame"
|
||||
"73" => "Drama", //"Emotion"
|
||||
"15" => "Adult", //"Erotique"
|
||||
"16" => "Action", //"Espionnage"
|
||||
"17" => "Sci-Fi", //"Fantastique"
|
||||
"30" => "Musical", //"Film musical"
|
||||
"83" => "Sport", //"Freefight"
|
||||
"18" => "War", //"Guerre"
|
||||
"19" => "Musical", //"Hard-rock"
|
||||
"20" => "History", //"Historique"
|
||||
"21" => "Horror", //"Horreur"
|
||||
"22" => "Comedy", //"Humour"
|
||||
"23" => "Animation", //"Japanimation"
|
||||
"24" => "Adult", //"Japanimation érotique"
|
||||
"25" => "Music", //"Jazz & Blues"
|
||||
"79" => "", //"Jeux"
|
||||
"26" => "Music", //"Karaoke"
|
||||
"27" => "Action", //"Kung Fu"
|
||||
"28" => "", //"Méthode"
|
||||
"57" => "", //"Mini-series / Feuilletons"
|
||||
"29" => "Documentary", //"Muet"
|
||||
"32" => "Music", //"Musique Classique"
|
||||
"71" => "Music", //"Musiques du monde"
|
||||
"31" => "Music", //"Opéra"
|
||||
"33" => "War", //"Péplum"
|
||||
"34" => "Crime", //"Policier"
|
||||
"54" => "", //"Pour enfants"
|
||||
"76" => "Music", //"R&B & Soul"
|
||||
"55" => "Music", //"Rap"
|
||||
"56" => "Sci-Fi", //"Science Fiction"
|
||||
"60" => "", //"Série Anime / OAV"
|
||||
"75" => "", //"Série d'animation enfants"
|
||||
"58" => "", //"Série TV"
|
||||
"59" => "", //"Sitcom"
|
||||
"62" => "", //"Spectacle"
|
||||
"63" => "Sport",
|
||||
"82" => "Sport", //"Sports mécaniques"
|
||||
"64" => "Music", //"Techno / Electro"
|
||||
"65" => "", //"Theatre"
|
||||
"66" => "Thriller",
|
||||
"67" => "Music", //"Variété française"
|
||||
"68" => "Music", //"Variété internationale"
|
||||
"69" => "Documentary", //"Voyages"
|
||||
"70" => "Western",
|
||||
"Science Fiction" => "Sci-Fi",
|
||||
);
|
||||
|
||||
// Genres (as Array)
|
||||
if (preg_match_all('#<categorie>(.*?)</categorie>#i', $resp['data'], $ary, PREG_PATTERN_ORDER) > 0)
|
||||
{
|
||||
$count = 0;
|
||||
while (isset($ary[1][$count]))
|
||||
{
|
||||
$data['genres'][] = $category_map[dvdfrCleanStr($ary[1][$count])];
|
||||
$count ++;
|
||||
}
|
||||
}
|
||||
|
||||
// Cast
|
||||
if( preg_match('#<stars>(.*)</stars>#is', $resp['data'], $Section) ) {
|
||||
preg_match_all('#<star type="Acteur" id="(\d+)">(.*?)</star>#i', $Section[1], $ary,PREG_PATTERN_ORDER);
|
||||
$cast = '';
|
||||
for ($i=0; $i < sizeof($ary[0]); $i++)
|
||||
{
|
||||
$cast .= dvdfrCleanStr($ary[2][$i]) . '::::dvdfr' . dvdfrCleanStr($ary[1][$i]) . "\n";
|
||||
#$cast .= "$actor::$character::$imdbIdPrefix$actorid\n";
|
||||
}
|
||||
$data['cast'] = dvdfrCleanStr($cast);
|
||||
}
|
||||
|
||||
#// Convert ISO to UTF8
|
||||
#$encoding = $data['encoding'];
|
||||
#foreach( $data as $k => $v ) {
|
||||
# $data[$k] = mb_convert_encoding(trim($v),'UTF-8',$encoding);
|
||||
#}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Actor-Details
|
||||
*
|
||||
* Find image and detail URL for actor, not sure if this can be made
|
||||
* a one-step process? Completion waiting on update of actor
|
||||
* functionality to support more than one engine.
|
||||
*
|
||||
* @param string $name Name of the Actor
|
||||
* @return array array with Actor-URL and Thumbnail
|
||||
*/
|
||||
function dvdfrActor($name, $actorengineid)
|
||||
{
|
||||
global $dvdfrServer;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
452
videodb/engines/engines.php
Normal file
452
videodb/engines/engines.php
Normal file
@@ -0,0 +1,452 @@
|
||||
<?php
|
||||
/**
|
||||
* Multi-engine glue logic
|
||||
*
|
||||
* @package Engines
|
||||
*
|
||||
* @todo Remove global $cache variable
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: engines.php,v 1.45 2010/10/15 08:13:01 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/httpclient.php'; // include for all engines
|
||||
require_once './core/encoding.php';
|
||||
|
||||
/**
|
||||
* Determine the default engine
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @return string engine name
|
||||
*/
|
||||
function engineGetDefault()
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (!empty($config['enginedefault']))
|
||||
{
|
||||
$engine = $config['enginedefault'];
|
||||
}
|
||||
elseif (count($engine_list = array_keys($config['engines'])))
|
||||
{
|
||||
// first valid engine from list
|
||||
$engine = $engine_list[0];
|
||||
}
|
||||
else $engine = 'imdb'; // last resort
|
||||
|
||||
return $engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine engine from id
|
||||
*
|
||||
* @todo Enhance DB schema to store engine type explicitly
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string item id
|
||||
* @return string engine name
|
||||
*/
|
||||
function engineGetEngine($id)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// recognize engine from id
|
||||
if ($id)
|
||||
{
|
||||
// engine prefixed (imdb:081547)
|
||||
// currently working for imdb, amazon, amazoncom and tvcom
|
||||
if (preg_match('/^(\w+):/', $id, $match)) $engine = $match[1];
|
||||
elseif (preg_match('/^[0-9A-Z]{10,}$/', $id)) $engine = 'amazonaws'; // Amazon
|
||||
}
|
||||
if (empty($engine)) $engine = 'imdb';
|
||||
return $engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include engine file and retrieve item data
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string item id
|
||||
* @param string engine name
|
||||
* @return array item data
|
||||
*/
|
||||
function engineGetData($id, $engine = 'imdb')
|
||||
{
|
||||
global $lang, $cache;
|
||||
|
||||
if (!engine_load_engine($engine)) return array();
|
||||
$func = $engine.'Data';
|
||||
|
||||
$result = array();
|
||||
if (function_exists($func))
|
||||
{
|
||||
$cache = true;
|
||||
$result = $func($id);
|
||||
}
|
||||
|
||||
// make sure all engines properly return the encoding type
|
||||
if (empty($result['encoding'])) errorpage('Engine Error', 'Engine '.$engine.' does not properly return encoding');
|
||||
|
||||
// set default encoding iso-8859-1
|
||||
$source_encoding = ($result['encoding']) ? $result['encoding'] : $lang['encoding'];
|
||||
$target_encoding = 'utf-8';
|
||||
unset($result['encoding']);
|
||||
|
||||
// convert to unicode
|
||||
if ($source_encoding != $target_encoding)
|
||||
{
|
||||
$result = iconv_array($source_encoding, $target_encoding, $result);
|
||||
}
|
||||
engine_clean_input($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include engine file and execute item search
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string search string
|
||||
* @param string engine name
|
||||
* @return array list of item data
|
||||
*/
|
||||
function engineSearch($find, $engine = 'imdb', $para1 = null, $para2 = null)
|
||||
{
|
||||
global $lang, $cache;
|
||||
|
||||
if (!engine_load_engine($engine)) return array();
|
||||
$func = $engine.'Search';
|
||||
|
||||
$result = array();
|
||||
if (function_exists($func))
|
||||
{
|
||||
$cache = true;
|
||||
// check if additional parameters given to avoid overriding default values
|
||||
$result = (isset($para1)) ? $func($find, $para1, $para2) : $func($find);
|
||||
}
|
||||
|
||||
// make sure all engines properly return the encoding type
|
||||
# if (empty($result['encoding'])) errorpage('Engine Error', 'Engine does not properly return encoding');
|
||||
|
||||
// set default encoding iso-8859-1
|
||||
$source_encoding = ($result['encoding']) ? $result['encoding'] : $lang['encoding'];
|
||||
$target_encoding = 'utf-8';
|
||||
unset($result['encoding']);
|
||||
|
||||
// convert to unicode
|
||||
if ($source_encoding != $target_encoding)
|
||||
{
|
||||
#dump("Converting from $source_encoding to $target_encoding");
|
||||
$result = iconv_array($source_encoding, $target_encoding, $result);
|
||||
}
|
||||
|
||||
// obtain unique entries
|
||||
$result = engine_deduplicate_result($result);
|
||||
|
||||
engine_clean_input($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item details URL in external site
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string item id
|
||||
* @param string engine name
|
||||
* @return string item details url
|
||||
*/
|
||||
function engineGetContentUrl($id, $engine = 'imdb')
|
||||
{
|
||||
if (empty($id)) return '';
|
||||
if (!engine_load_engine($engine)) return '';
|
||||
|
||||
$func = $engine.'ContentUrl';
|
||||
|
||||
$result = '';
|
||||
if (function_exists($func))
|
||||
{
|
||||
$result = $func($id);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get recommendations for a specific movie that meets the requirements
|
||||
* of rating and release year.
|
||||
*
|
||||
* @author Klaus Christiansen <klaus_edwin@hotmail.com>
|
||||
* @param int $id The external movie id.
|
||||
* @param float $rating The minimum rating for the recommended movies.
|
||||
* @param int $year The minimum year for the recommended movies.
|
||||
* @return array Associative array with: id, title, rating, year.
|
||||
*/
|
||||
function engineGetRecommendations($id, $rating, $year, $engine = 'imdb')
|
||||
{
|
||||
if (empty($id)) return '';
|
||||
|
||||
if (!engine_load_engine($engine)) return '';
|
||||
$func = $engine.'Recommendations';
|
||||
|
||||
if (function_exists($func))
|
||||
{
|
||||
return $func($id, $rating, $year);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get complete search URL for external site
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string search string
|
||||
* @param string engine name
|
||||
* @return string item search url
|
||||
*/
|
||||
function engineGetSearchUrl($find, $engine = 'imdb')
|
||||
{
|
||||
if (!engine_load_engine($engine)) return '';
|
||||
$func = $engine.'SearchUrl';
|
||||
|
||||
$result = '';
|
||||
if (function_exists($func))
|
||||
{
|
||||
$result = $func($find);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used internally by setup and engines to add meta-engine of the engine's capability type
|
||||
* e.g. if the youtube engine provides 'trailer' capability, this will add $config[engine][trailer] = (youtube)
|
||||
*/
|
||||
function engine_setup_meta($engine, $meta)
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (array_key_exists('capabilities', $meta) && is_array($meta['capabilities'])) {
|
||||
foreach ($meta['capabilities'] as $caps) {
|
||||
$config['engine'][$caps][] = $engine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve meta information about all available engines
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @return array engines array containing engine names
|
||||
*/
|
||||
function engineMeta()
|
||||
{
|
||||
$engines = array();
|
||||
|
||||
if ($dh = @opendir(__DIR__))
|
||||
{
|
||||
while (($file = readdir($dh)) !== false)
|
||||
{
|
||||
if ((preg_match("/(.*)\.php$/", $file, $matches)) && ($matches[1] != 'engines'))
|
||||
{
|
||||
// engine file
|
||||
$engine = $matches[1];
|
||||
|
||||
// get meta data
|
||||
engine_load_engine($engine);
|
||||
|
||||
$func = $engine.'Meta';
|
||||
|
||||
if (function_exists($func))
|
||||
{
|
||||
$meta = $func();
|
||||
$engines[$engine] = $meta;
|
||||
|
||||
// required php version present?
|
||||
if (array_key_exists( 'php', $engines[$engine] ) && (version_compare(phpversion(), $engines[$engine]['php']) < 0))
|
||||
{
|
||||
unset($engines[$engine]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
|
||||
return $engines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine actor engine from actor id, defaults to imdb
|
||||
*
|
||||
* @author Michael Kollmann <acidity@online.de>
|
||||
* @param string actor id
|
||||
* @return string engine name
|
||||
*/
|
||||
function engineGetActorEngine($id)
|
||||
{
|
||||
// recognize engine from id
|
||||
if ($id)
|
||||
{
|
||||
// actor engine prefixed, too? (imdb:nm0347149)
|
||||
if (preg_match('/^(\w+):/', $id, $match)) $engine = $match[1];
|
||||
elseif (preg_match('/^tv\d+$/', $id)) $engine = 'tvcom';
|
||||
}
|
||||
if (empty($engine)) $engine = 'imdb';
|
||||
|
||||
return $engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get actors details URL in external site
|
||||
*
|
||||
* @author Michael Kollmann <acidity@online.de>
|
||||
* @param string actor name
|
||||
* @param string actor id
|
||||
* @param string engine name
|
||||
* @return string actor details url
|
||||
*/
|
||||
function engineGetActorUrl($name, $id, $engine = 'imdb')
|
||||
{
|
||||
if (!engine_load_engine($engine)) return '';
|
||||
$func = $engine.'ActorUrl';
|
||||
|
||||
$result = '';
|
||||
if (function_exists($func))
|
||||
{
|
||||
$id = preg_replace('|^'.$engine.':|', '', $id);
|
||||
$result = $func($name, $id);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include engine file and execute item search
|
||||
*
|
||||
* @author Michael Kollmann <acidity@online.de>
|
||||
* @param string actor name
|
||||
* @param string actor id
|
||||
* @param string engine name
|
||||
* @return array array with Actor-URL and Thumbnail
|
||||
*/
|
||||
function engineActor($name, $id, $engine = 'imdb')
|
||||
{
|
||||
global $cache;
|
||||
|
||||
if (!engine_load_engine($engine)) return array();
|
||||
$func = $engine.'Actor';
|
||||
|
||||
$result = array();
|
||||
if (function_exists($func))
|
||||
{
|
||||
$id = preg_replace('|^'.$engine.':|', '', $id);
|
||||
|
||||
$cache = true;
|
||||
$result = $func($name, $id);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function for validating if an engine has a certain capability
|
||||
*/
|
||||
function engine_get_capability($engine, $searchtype)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// get the meta information
|
||||
$engine = $config['engines'][$engine];
|
||||
|
||||
if (array_key_exists( 'capabilities', $engine) && is_array($engine['capabilities']))
|
||||
{
|
||||
return in_array($searchtype, $engine['capabilities']);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $searchtype == 'movie';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of engines which have certain capability
|
||||
*
|
||||
* 'movie' search capability is assumed as default, either if
|
||||
* $searchtype is empty or engine does not maintain specific capability
|
||||
*
|
||||
* @return array list of capable engines
|
||||
*/
|
||||
function engine_get_capable_engines($searchtype)
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (!$searchtype) $searchtype = 'movie';
|
||||
|
||||
$engines = array();
|
||||
foreach ($config['engines'] as $engine => $meta)
|
||||
{
|
||||
$enabled = $config['engine'][$engine];
|
||||
if ($enabled && engine_get_capability($engine, $searchtype)) $engines[$engine] = $enabled;
|
||||
}
|
||||
|
||||
return $engines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean HTML tags from hierarchical associative array
|
||||
*
|
||||
* @param array $data string or hierarchical array to convert
|
||||
*/
|
||||
function engine_clean_input(&$data)
|
||||
{
|
||||
if (is_array($data)) foreach ($data as $key => $val)
|
||||
{
|
||||
if (is_array($val))
|
||||
engine_clean_input($data[$key]);
|
||||
else
|
||||
{
|
||||
$val = html_to_text($val);
|
||||
$data[$key] = html_clean_utf8($val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter result set for unique engine ids.
|
||||
* This avoids deduplication of search results inside every single engine.
|
||||
*/
|
||||
function engine_deduplicate_result($data)
|
||||
{
|
||||
$keys = array();
|
||||
for ($i=0; $i<count($data); $i++)
|
||||
{
|
||||
$id = $data[$i]['id'];
|
||||
// early exit if engine (e.g. google images) doesn't return ids
|
||||
if (!$id) return $data;
|
||||
// exclude duplicates
|
||||
if (in_array($id, $keys))
|
||||
unset($data[$i]);
|
||||
else
|
||||
$keys[] = $id;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the selected engine without errors
|
||||
*
|
||||
* @param string $engine
|
||||
* @return bool
|
||||
*/
|
||||
function engine_load_engine($engine) {
|
||||
if (file_exists(__DIR__ . '/' . $engine.'.php')) {
|
||||
include_once __DIR__ . '/' . $engine.'.php';
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
333
videodb/engines/filmweb.php
Normal file
333
videodb/engines/filmweb.php
Normal file
@@ -0,0 +1,333 @@
|
||||
<?php
|
||||
/**
|
||||
* FilmWeb Parser (pl)
|
||||
*
|
||||
* Parses data from the Polish FilmWeb site
|
||||
*
|
||||
* @package Engines
|
||||
* @author Marek Domaniuk <domanm@o2.pl>
|
||||
* @author Victor La <cyridian@users.sourceforge.net>
|
||||
* @desc Original filmweb.php by Marek Domaniuk, rewritten by Victor La
|
||||
* @desc using Andreas Goetz's imdb.php as a template
|
||||
* @link https://www.filmweb.com Internet Movie Database
|
||||
* @version $Id: filmweb.php,v 1.4 2007/08/08 18:28:15 andig2 Exp $
|
||||
*/
|
||||
|
||||
$GLOBALS['filmwebServer'] = 'https://www.filmweb.pl';
|
||||
$GLOBALS['filmwebIdPrefix'] = 'filmweb:';
|
||||
|
||||
/**
|
||||
* Get meta information about the engine
|
||||
*
|
||||
* @todo Include image search capabilities etc in meta information
|
||||
*/
|
||||
function filmwebMeta()
|
||||
{
|
||||
return array('name' => 'FilmWeb (pl)', 'stable' => 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url to search FilmWeb for a movie
|
||||
*
|
||||
* @author Marek Domaniuk <domark@o2.pl>
|
||||
* @param string The search string
|
||||
* @return string The search URL (GET)
|
||||
*/
|
||||
function filmwebSearchUrl($title)
|
||||
{
|
||||
global $filmwebServer;
|
||||
return $filmwebServer.'/Find?query='.urlencode($title).'&category=1&submit=szukaj';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url to visit FilmWeb for a specific movie
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @author Marek Domaniuk <domark@o2.pl>
|
||||
* @author Victor La <cyridian@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function filmwebContentUrl($id)
|
||||
{
|
||||
global $filmwebServer;
|
||||
global $filmwebIdPrefix;
|
||||
$id = preg_replace('/^'.$filmwebIdPrefix.'/', '', $id);
|
||||
return $filmwebServer.'/Film?id='.$id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url for actor on FilmWeb
|
||||
*
|
||||
* @author Victor La <cyridian@users.sourceforge.net>
|
||||
* @param string $name Name of the Actor
|
||||
* @return string The actor URL (GET)
|
||||
*/
|
||||
function filmwebActorUrl($name, $actorid)
|
||||
{
|
||||
global $filmwebServer;
|
||||
$url = ($actorid) ? '/Person,id='.urlencode($actorid) : '/szukaj?q='.urlencode($name).'&alias=person';
|
||||
return $filmwebServer.$url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search a Movie
|
||||
*
|
||||
* Searches for a given title on the FilmWeb and returns the found links in
|
||||
* an array
|
||||
*
|
||||
* @author Marek Domaniuk <domark@o2.pl>
|
||||
* @author Victor La <cyridian@users.sourceforge.net>
|
||||
* @param string The search string
|
||||
* @return array Associative array with id and title
|
||||
*/
|
||||
function filmwebSearch($title)
|
||||
{
|
||||
global $filmwebServer;
|
||||
global $filmwebIdPrefix;
|
||||
global $CLIENTERROR;
|
||||
|
||||
$resp = httpClient(filmwebSearchUrl($title), 1);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
preg_match_all('/<a class="searchResultTitle" href="(.+?)">(.+?)<\/a>.+?\((.+?)\)/si', $resp['data'], $data, PREG_SET_ORDER);
|
||||
foreach ($data as $row)
|
||||
{
|
||||
$info['id'] = trim($row[1]);
|
||||
|
||||
$row[2] = preg_replace('/<b>/','', $row[2]);
|
||||
$row[2] = preg_replace('/<\/b>/','', $row[2]);
|
||||
$info['title'] = trim($row[2]);
|
||||
|
||||
// add year (helpful in case of multiple matches)
|
||||
$info['title'] = $info['title'].' ('.$row[3].')';
|
||||
|
||||
//Check URL to see if the movie ID is in it, if not, load the page and grab it from that new page
|
||||
if (preg_match('/id=(\d+)/', $info['id'], $single))
|
||||
{
|
||||
$info['id'] = $single[1];
|
||||
}
|
||||
elseif ((strpos($info['id'], 'id=')) != true)
|
||||
{
|
||||
$subResp = httpClient($info['id'],1);
|
||||
if (!$subResp['success']) $CLIENTERROR .= $subResp['error']."\n";
|
||||
//<a class="n" href="https://www.filmweb.pl/AddFilmFavourite?film.id=108130">dodaj do ulubionych</a>
|
||||
preg_match('/,id=(\d+)">/i', $subResp['data'], $single);
|
||||
$info['id'] = $single[1];
|
||||
}
|
||||
$info['id'] = $filmwebIdPrefix.$info['id'];
|
||||
|
||||
$ary[] = $info;
|
||||
}
|
||||
|
||||
return $ary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the data for a given FilmWeb-ID
|
||||
*
|
||||
* @author Marek Domaniuk <domark@o2.pl>
|
||||
* @author Victor La <cyridian@users.sourceforge.net>
|
||||
* @param int FilmWeb-ID
|
||||
* @return array Result data
|
||||
*/
|
||||
function filmwebData($filmwebID)
|
||||
{
|
||||
global $filmwebServer;
|
||||
global $filmwebIdPrefix;
|
||||
global $CLIENTERROR;
|
||||
|
||||
$filmwebID = preg_replace('/^'.$filmwebIdPrefix.'/', '', $filmwebID);
|
||||
$data= array(); // result
|
||||
$ary = array(); // temp
|
||||
|
||||
// fetch mainpage
|
||||
$resp = httpClient(filmwebContentUrl($filmwebID), 1);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// Titles - Fixed
|
||||
preg_match('/<div id="filmTitle">(.*?)<span class="otherTitle">(.+?)<\/span>/is', $resp['data'], $ary);
|
||||
$data['title'] = trim($ary[1]);
|
||||
|
||||
//DOUBLE CHECK THIS SECTION OF CODE FOR THE SUBTITLE!
|
||||
if (!preg_match('/<a href/i', $ary[2], $tempary)) {
|
||||
$data['subtitle'] = trim($ary[2]);
|
||||
}
|
||||
if (preg_match('/\(AKA (.+?)\)/i', $ary[2], $tempary)) {
|
||||
$data['subtitle'] = trim($tempary[1]);
|
||||
}
|
||||
|
||||
// Year - Fixed
|
||||
preg_match('/\(([1-2][0-9][0-9][0-9])\)/i', $resp['data'], $ary);
|
||||
$data['year'] = trim($ary[1]);
|
||||
|
||||
// Cover-URL - Fixed
|
||||
//<img src="https://gfx.filmweb.pl/f/94745/po.6954459.jpg"
|
||||
//https://gfx.filmweb.pl/f/520/520.jpg
|
||||
preg_match('/<div id="filmPhoto">.+?<img border="0" src="(.+?)"/si', $resp['data'], $ary);
|
||||
$data['coverurl'] = trim($ary[1]);
|
||||
|
||||
// MPAA Rating
|
||||
$data['mpaa'] = '';
|
||||
|
||||
// UK BBFC Rating
|
||||
$data['bbfc'] = '';
|
||||
|
||||
// Runtime
|
||||
preg_match('/czas trwania.+?([0-9,]+)\s/si', $resp['data'], $ary);
|
||||
$data['runtime'] = preg_replace('/,/', '', trim($ary[1]));
|
||||
|
||||
// Director - Fixed
|
||||
//re¿yseria <a class="n" title="Kerry Conran: filmografia [Filmweb.pl]" //href="https://www.filmweb.pl/Kerry,Conran,filmografia,Person,id=138676">Kerry Conran</a>
|
||||
preg_match('/re.yseria.+?title="(.+?)- filmografia.+?"/i', $resp['data'], $ary);
|
||||
$data['director'] = trim($ary[1]);
|
||||
|
||||
// Rating - Fixed
|
||||
preg_match('/<b class="rating">(.+?)<\/b>\/10/i', $resp['data'], $ary);
|
||||
$data['rating'] = trim($ary[1]);
|
||||
|
||||
// Countries - Fixed
|
||||
preg_match_all('/<a href="https:\/\/www.filmweb.pl\/szukaj\/film\?countryids=\d.+?">(.+?)<\/A>/i', $resp['data'], $ary, PREG_PATTERN_ORDER);
|
||||
$data['country'] = trim(join(', ', $ary[1]));
|
||||
|
||||
// Languages - DOES THIS NEED TO BE FIXED?
|
||||
//$data['language'] = '';
|
||||
|
||||
// Plot (movies in their early stages have the plot here but not yet in plotsummary?) - Fixed 4-5-07
|
||||
// Not necessary for FilmWeb?
|
||||
|
||||
// Genres (as Array) - Fixed
|
||||
$genres = array(
|
||||
'Przygodowy' => 'Adventure',
|
||||
'Akcja' => 'Action',
|
||||
'Komedia' => 'Comedy',
|
||||
'Familijny' => 'Family',
|
||||
'Muzyka' => 'Music',
|
||||
'Western' => 'Western',
|
||||
'Dla doros³ych' => 'Adult',
|
||||
'Krymina³' => 'Crime',
|
||||
'Fantasy' => 'Fantasy',
|
||||
'Musical' => 'Musical',
|
||||
'Muzyczny' => 'Musical',
|
||||
'Krótkometra¿owy' => 'Short',
|
||||
'Dokumentalny' => 'Documentary',
|
||||
'Film-Noir' => 'Film-Noir',
|
||||
'Mystery' => 'Mystery',
|
||||
'Thriller' => 'Thriller',
|
||||
'Dreszczowiec' => 'Thriller',
|
||||
'Animacja' => 'Animation',
|
||||
'Dramat' => 'Drama',
|
||||
'Melodramat' => 'Drama',
|
||||
'Dramat historyczny' => 'History',
|
||||
'Historyczny' => 'History',
|
||||
'Dramat obyczajowy' => 'Drama',
|
||||
'Dramat s±dowy' => 'Drama',
|
||||
'Dramat spo³eczny' => 'Drama',
|
||||
'Horror' => 'Horror',
|
||||
'Romans' => 'Romance',
|
||||
'Wojenny' => 'War',
|
||||
'Biograficzny' => 'Biographic',
|
||||
'Erotyczny' => 'Adult',
|
||||
'Komedia kryminalna' => 'Comedy',
|
||||
'Komedia obycz.' => 'Comedy',
|
||||
'Komedia rom.' => 'Comedy',
|
||||
'Komedia' => 'Comedy',
|
||||
'Czarna komedia' => 'Comedy',
|
||||
'Dla dzieci' => '',
|
||||
'Obyczajowy' => '',
|
||||
'Bibilijny' => '',
|
||||
'Sensacja' => 'Action',
|
||||
'Sensacyjny' => 'Action',
|
||||
'Fabularyzowany dok.' => 'Documentary',
|
||||
'Psychologiczny' => ''
|
||||
);
|
||||
preg_match_all('/genreIds=\d.+?">(.+?)</i', $resp['data'], $ary, PREG_PATTERN_ORDER);
|
||||
foreach($ary[1] as $genre)
|
||||
{
|
||||
$genre = trim($genre);
|
||||
if (!($genre)) continue;
|
||||
if (isset($genres[$genre])) $genre = $genres[$genre];
|
||||
if (!($genre)) continue;
|
||||
$data['genres'][] = $genre;
|
||||
}
|
||||
|
||||
// Cast - Fixed
|
||||
preg_match_all('/<a class="filmActor" HREF="(.+?)".+?>(.+?)<\/a>.+?((<br\/>).|(<div class="filmRoleSeparator">:<\/div>.+?<div class="filmRole">(.+?)<\/div>))/si', $resp['data'], $ary,PREG_PATTERN_ORDER);
|
||||
$count = 0;
|
||||
$cast = '';
|
||||
while (isset($ary[1][$count]))
|
||||
{
|
||||
$actor = trim(strip_tags($ary[2][$count]));
|
||||
$role = trim(strip_tags($ary[6][$count]));
|
||||
$role = preg_replace('/ /',' ', $role);
|
||||
$role = trim($role);
|
||||
|
||||
//$actorid= $ary[1][$count]; //, $m)) ? $m[1] : '';
|
||||
preg_match('/.+?Person\,id=(\d+)/i', $ary[1][$count], $ary2);
|
||||
|
||||
if (!empty($ary2[1]))
|
||||
{
|
||||
$actorid= $ary2[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
$resp = httpClient($ary[1][$count], 1);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
preg_match('/,Person.+?,id=(\d+)">/i', $resp['data'], $ary2);
|
||||
if (!empty($ary2[1])) $actorid = $ary2[1];
|
||||
}
|
||||
|
||||
|
||||
$cast .= "$actor::$role::$filmwebIdPrefix$actorid\n";
|
||||
$count++;
|
||||
}
|
||||
$data['cast'] = trim($cast);
|
||||
|
||||
// fetch Plot
|
||||
$resp = httpClient($filmwebServer.'/FilmDescriptions?id='.$filmwebID, 1);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// Plot
|
||||
preg_match('/<li><div.+?">(.+?)<\/div><\/li>/is', $resp['data'], $ary);
|
||||
if (!empty($ary[1])) $data['plot'] = trim($ary[1]);
|
||||
$data['plot'] = preg_replace('/[\n\r]/',' ', $data['plot']);
|
||||
$data['plot'] = preg_replace('/ /',' ', $data['plot']);
|
||||
$data['plot'] = trim($data['plot']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Actor-Details
|
||||
*
|
||||
* Find image and detail URL for actor, not sure if this can be made
|
||||
* a one-step process?
|
||||
*
|
||||
* @author Victor La <cyridian@users.sourceforge.net>
|
||||
* @param string $name Name of the Actor
|
||||
* @return array array with Actor-URL and Thumbnail
|
||||
*/
|
||||
function filmwebActor($name, $actorid)
|
||||
{
|
||||
global $filmwebServer;
|
||||
|
||||
// search directly by id or via name?
|
||||
$resp = httpClient(filmwebActorUrl($name, $actorid), 1);
|
||||
|
||||
$ary = array();
|
||||
|
||||
if (preg_match('/<a class="searchResultTitle" href="(.+?)">/i', $resp['data'], $m)) {
|
||||
$resp = httpClient($m[1], true);
|
||||
}
|
||||
|
||||
// now we should have loaded the best match
|
||||
if (preg_match('/<img src="https:\/\/gfx.filmweb.pl\/p\/(.+?)"/i', $resp['data'], $m))
|
||||
{
|
||||
$ary[0][0] = 'https://gfx.filmweb.pl/p/'.$m[1];
|
||||
$ary[0][1] = 'https://gfx.filmweb.pl/p/'.$m[1];
|
||||
return $ary;
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
|
||||
98
videodb/engines/google.php
Normal file
98
videodb/engines/google.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
// DEFUNCT, no clue if this is alternative: https://developers.google.com/custom-search/v1/reference/rest/v1/cse/list
|
||||
/**
|
||||
* Google Image Parser
|
||||
*
|
||||
* Lookup cover images from Google
|
||||
*
|
||||
* @package Engines
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
*
|
||||
* @link http://images.google.com Google image search
|
||||
* @link http://code.google.com/apis/ajaxsearch/documentation/ API doc
|
||||
*
|
||||
* @version $Id: google.php,v 1.13 2013/03/16 14:29:47 andig2 Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get meta information about the engine
|
||||
*
|
||||
* @todo Include image search capabilities etc in meta information
|
||||
*/
|
||||
function googleMeta()
|
||||
{
|
||||
return array('name' => 'Google', 'stable' => 1, 'capabilities' => array('image'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Search an image on Google
|
||||
*
|
||||
* Searches for a given title on the google and returns the found links in
|
||||
* an array
|
||||
*
|
||||
* @param string The search string
|
||||
* @return array Associative array with id and title
|
||||
*/
|
||||
function googleSearch($title)
|
||||
{
|
||||
global $CLIENTERROR;
|
||||
global $cache;
|
||||
global $config;
|
||||
global $savedata_for_errorpage;
|
||||
|
||||
$page = 1;
|
||||
$data = array();
|
||||
$data['encoding'] = 'utf-8';
|
||||
|
||||
do
|
||||
{
|
||||
$url = "http://ajax.googleapis.com/ajax/services/search/images?v=1.0&rsz=large&q=".urlencode($title)."&start=".count($data);
|
||||
|
||||
if ( $config['debug'] )
|
||||
{
|
||||
// save data to pass to functions.php - erropage
|
||||
// if url fails in httpclient it can go directly to errorpage which loses
|
||||
// message set in httpCLient
|
||||
// this is a cause of not finding cover url
|
||||
$savedata_for_errorpage = 'Module->google.php, Message->';
|
||||
}
|
||||
|
||||
$resp = httpClient($url, $cache);
|
||||
|
||||
if ( $config['debug'] )
|
||||
{
|
||||
unset($savedata_for_errorpage);
|
||||
}
|
||||
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
$json = json_decode($resp['data']);
|
||||
# dump($resp['data']);
|
||||
# dump($page);
|
||||
# dump($json);
|
||||
|
||||
// prevent caching invalid responses
|
||||
if ($json->responseStatus != 200 && $cache) {
|
||||
$cache_file = cache_get_filename($url, CACHE_HTML);
|
||||
@unlink($cache_file);
|
||||
}
|
||||
|
||||
foreach ($json->responseData->results as $row)
|
||||
{
|
||||
# dump($row);
|
||||
$res = array();
|
||||
$res['title'] = $row->width.'x'.$row->height; // width x height
|
||||
$res['imgsmall']= $row->tbUrl; // small thumbnail url
|
||||
$res['coverurl']= $row->url; // resulting target url
|
||||
$data[] = $res;
|
||||
}
|
||||
}
|
||||
// Google does not return more than 4 pages of results. Limiting to 2 for performance
|
||||
while ($page++ < 3);
|
||||
|
||||
# dump($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
?>
|
||||
804
videodb/engines/imdb.php
Normal file
804
videodb/engines/imdb.php
Normal file
@@ -0,0 +1,804 @@
|
||||
<?php
|
||||
/**
|
||||
* IMDB Parser
|
||||
*
|
||||
* Parses data from the Internet Movie Database
|
||||
*
|
||||
* @package Engines
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @link http://www.imdb.com Internet Movie Database
|
||||
* @version $Id: imdb.php,v 1.76 2013/04/10 18:11:43 andig2 Exp $
|
||||
*/
|
||||
|
||||
$GLOBALS['imdbServer'] = 'https://www.imdb.com';
|
||||
$GLOBALS['imdbIdPrefix'] = 'imdb:';
|
||||
|
||||
/**
|
||||
* Get meta information about the engine
|
||||
*
|
||||
* @todo Include image search capabilities etc in meta information
|
||||
*/
|
||||
function imdbMeta()
|
||||
{
|
||||
return array('name' => 'IMDB', 'stable' => 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Url to search IMDB for a movie
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string The search string
|
||||
* @return string The search URL (GET)
|
||||
*/
|
||||
function imdbSearchUrl($title)
|
||||
{
|
||||
global $imdbServer;
|
||||
return $imdbServer.'/find?s=all&q='.urlencode($title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url to visit IMDB for a specific movie
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string $id The movie's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function imdbContentUrl($id)
|
||||
{
|
||||
global $imdbServer;
|
||||
global $imdbIdPrefix;
|
||||
$id = preg_replace('/^'.$imdbIdPrefix.'/', '', $id);
|
||||
return $imdbServer.'/title/tt'.$id.'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get IMDB recommendations for a specific movie that meets the requirements
|
||||
* of rating and release year.
|
||||
*
|
||||
* @author Klaus Christiansen <klaus_edwin@hotmail.com>
|
||||
* @param int $id The external movie id.
|
||||
* @param float $rating The minimum rating for the recommended movies.
|
||||
* @param int $year The minimum year for the recommended movies.
|
||||
* @return array Associative array with: id, title, rating, year.
|
||||
* If error: $CLIENTERROR contains the http error and blank is returned.
|
||||
*/
|
||||
// Only used in contrib/add_recommended_movies.php
|
||||
function imdbRecommendations($id, $required_rating, $required_year)
|
||||
{
|
||||
global $CLIENTERROR;
|
||||
|
||||
$url = imdbContentUrl($id);
|
||||
$resp = httpClient($url, true);
|
||||
|
||||
$recommendations = array();
|
||||
preg_match_all('/<div class="rec_item" data-info=".*?" data-spec=".*?" data-tconst="tt(\d+)">/si', $resp['data'], $ary, PREG_SET_ORDER);
|
||||
|
||||
foreach ($ary as $recommended_id) {
|
||||
$rec_resp = getRecommendationData($recommended_id[1]);
|
||||
$imdbId = $recommended_id[1];
|
||||
$title = $rec_resp['title'];
|
||||
$year = $rec_resp['year'];
|
||||
$rating = $rec_resp['rating'];
|
||||
|
||||
// matching at least required rating?
|
||||
if (empty($required_rating) || (float) $rating < $required_rating) continue;
|
||||
|
||||
// matching at least required year?
|
||||
if (empty($required_year) || (int) $year < $required_year) continue;
|
||||
|
||||
$data = array();
|
||||
$data['id'] = $imdbId;
|
||||
$data['rating'] = $rating;
|
||||
$data['title'] = $title;
|
||||
$data['year'] = $year;
|
||||
|
||||
$recommendations[] = $data;
|
||||
}
|
||||
return $recommendations;
|
||||
}
|
||||
|
||||
function getRecommendationData($imdbID) {
|
||||
global $imdbServer;
|
||||
global $imdbIdPrefix;
|
||||
global $CLIENTERROR;
|
||||
|
||||
$imdbID = preg_replace('/^'.$imdbIdPrefix.'/', '', $imdbID);
|
||||
|
||||
// fetch mainpage
|
||||
$resp = httpClient($imdbServer.'/title/tt'.$imdbID.'/', true); // added trailing / to avoid redirect
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// Titles and Year
|
||||
// See for different formats. https://contribute.imdb.com/updates/guide/title_formats
|
||||
if ($data['istv']) { // @todo this is always false
|
||||
if (preg_match('/<title>"(.+?)"(.+?)\(TV Episode (\d+)\) - IMDb<\/title>/si', $resp['data'], $ary)) {
|
||||
# handles one episode of a TV serie
|
||||
$data['title'] = trim($ary[1]);
|
||||
$data['year'] = $ary[3];
|
||||
} else if (preg_match('/<title>(.+?)\(TV Series (\d+).+?<\/title>/si', $resp['data'], $ary)){
|
||||
$data['title'] = trim($ary[1]);
|
||||
$data['year'] = trim($ary[2]);
|
||||
}
|
||||
} else {
|
||||
preg_match('/<title>(.+?)\((\d+)\).+?<\/title>/si', $resp['data'], $ary);
|
||||
$data['title'] = trim($ary[1]);
|
||||
$data['year'] = trim($ary[2]);
|
||||
}
|
||||
|
||||
// Rating
|
||||
preg_match('/<span class="AggregateRatingButton__RatingScore-.+?">(.+?)<\/span>/si', $resp['data'], $ary);
|
||||
$data['rating'] = trim($ary[1]);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search a Movie
|
||||
*
|
||||
* Searches for a given title on the IMDB and returns the found links in
|
||||
* an array
|
||||
*
|
||||
* @author Tiago Fonseca <t_r_fonseca@yahoo.co.uk>
|
||||
* @author Charles Morgan <cmorgan34@yahoo.com>
|
||||
* @param string title The search string
|
||||
* @param boolean aka Use AKA search for foreign language titles
|
||||
* @return array Associative array with id and title
|
||||
*/
|
||||
function imdbSearch($title, $aka=null)
|
||||
{
|
||||
global $imdbServer;
|
||||
global $imdbIdPrefix;
|
||||
global $CLIENTERROR;
|
||||
global $cache;
|
||||
|
||||
$url = $imdbServer.'/find?q='.urlencode($title);
|
||||
if ($aka) $url .= ';s=tt;site=aka';
|
||||
|
||||
$resp = httpClient($url, $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
$data = array();
|
||||
|
||||
// add encoding
|
||||
$data['encoding'] = $resp['encoding'];
|
||||
|
||||
// direct match (redirecting to individual title)?
|
||||
// @todo i don't think this gets called anymore, investigate
|
||||
if (preg_match('/^'.preg_quote($imdbServer,'/').'\/[Tt]itle(\?|\/tt)([0-9?]+)\/?/', $resp['url'], $single))
|
||||
{
|
||||
$info = array();
|
||||
$info['id'] = $imdbIdPrefix.$single[2];
|
||||
|
||||
// Title
|
||||
preg_match('/<title>(.*?) \([1-2][0-9][0-9][0-9].*?\)<\/title>/i', $resp['data'], $m);
|
||||
list($t, $s) = explode(' - ', trim($m[1]), 2);
|
||||
$info['title'] = trim($t);
|
||||
$info['subtitle'] = trim($s);
|
||||
|
||||
$data[] = $info;
|
||||
}
|
||||
|
||||
// multiple matches
|
||||
else if (preg_match_all('#div class="ipc-metadata-list-summary-item__tc".*href="/title/tt(\d+)/.*>([^\<]+)</a>.*<ul.*>(.*)</ul>.*</div>#Uism', $resp['data'], $multi, PREG_SET_ORDER))
|
||||
{
|
||||
foreach ($multi as $row)
|
||||
{
|
||||
$info = [
|
||||
'id' => $imdbIdPrefix.$row[1],
|
||||
'title' => $row[2],
|
||||
'year' => null
|
||||
];
|
||||
if (preg_match_all('#<label.*>([^\<]+)</label>#Uism', $row[3], $labels, PREG_PATTERN_ORDER))
|
||||
{
|
||||
foreach ($labels[1] as $label)
|
||||
{
|
||||
if (preg_match('#^(\d{4})$#i', $label)) $info['year'] = $label;
|
||||
if (preg_match('#^.*(episode|series)$#i', $label)) $info['title'] .= ' ('.$label.')';
|
||||
}
|
||||
}
|
||||
$data[] = $info;
|
||||
}
|
||||
} elseif (preg_match_all('/<div class="col-title">.+?<a href="\/title\/tt(\d+)\/\?ref_=adv_li_tt".+?>(.+?)<\/a>.+?<span .+?>\((\d+).*?\)<\/span>/is', $resp['data'], $ary, PREG_SET_ORDER)) {
|
||||
foreach ($ary as $row) {
|
||||
$info = array();
|
||||
$info['id'] = $imdbIdPrefix.$row[1];
|
||||
$info['title'] = $row[2];
|
||||
$info['year'] = $row[3];
|
||||
$data[] = $info;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the data for a given IMDB-ID
|
||||
*
|
||||
* @author Tiago Fonseca <t_r_fonseca@yahoo.co.uk>
|
||||
* @author Victor La <cyridian@users.sourceforge.net>
|
||||
* @author Roland Obermayer <robelix@gmail.com>
|
||||
* @param int IMDB-ID
|
||||
* @return array Result data
|
||||
*/
|
||||
function imdbData($imdbID)
|
||||
{
|
||||
global $imdbServer;
|
||||
global $imdbIdPrefix;
|
||||
global $CLIENTERROR;
|
||||
global $cache;
|
||||
|
||||
$imdbID = preg_replace('/^'.$imdbIdPrefix.'/', '', $imdbID);
|
||||
$data= array(); // result
|
||||
$ary = array(); // temp
|
||||
|
||||
// fetch mainpage
|
||||
$resp = httpClient($imdbServer.'/title/tt'.$imdbID.'/', $cache); // added trailing / to avoid redirect
|
||||
#testing code save resp data from imdb
|
||||
#file_put_contents('./cache/httpclient-php_imdbData_title.html', $resp['data']); // write page data to file
|
||||
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// extract json data from page
|
||||
if (preg_match('#(\<script id\="__NEXT_DATA__".*?\>)(.*?)(\</script\>)#',$resp['data'],$matches))
|
||||
{
|
||||
#file_put_contents('./cache/nextdata.json', $matches[2]); // write json data to file
|
||||
$json_data = json_decode($matches[2],true);
|
||||
#file_put_contents('./cache/nextdata-decoded.json', print_r($json_data, true)); // write formated json data to file
|
||||
}
|
||||
|
||||
// add encoding
|
||||
$data['encoding'] = $resp['encoding'];
|
||||
|
||||
// Check if it is a TV series episode
|
||||
if (preg_match('/<title>.+?\(TV (Episode|Series|Mini-Series).*?<\/title>/si', $resp['data'])) {
|
||||
$data['istv'] = 1;
|
||||
|
||||
# find id of Series
|
||||
preg_match('/<meta property="imdb:pageConst" content="tt(\d+)"\/>/si', $resp['data'], $ary);
|
||||
$data['tvseries_id'] = trim($ary[1]);
|
||||
}
|
||||
|
||||
// Titles and Year
|
||||
// See for different formats. https://contribute.imdb.com/updates/guide/title_formats
|
||||
if ($data['istv']) {
|
||||
if (preg_match('/<title>"(.+?)"(.+?)\(TV Episode (\d+)\) - IMDb<\/title>/si', $resp['data'], $ary)) {
|
||||
# handles one episode of a TV serie
|
||||
$data['title'] = trim($ary[1]);
|
||||
$data['subtitle'] = trim($ary[2]);
|
||||
$data['year'] = $ary[3];
|
||||
} else if (preg_match('/<title>(.+?)\(TV (?:Series|Mini-Series) (\d+).+?\) - IMDb<\/title>/si', $resp['data'], $ary)) {
|
||||
# handles a TV series.
|
||||
# split title - subtitle
|
||||
list($t, $s) = explode(' - ', $ary[1], 2);
|
||||
# no dash, lets try colon
|
||||
if ($s == false) {
|
||||
list($t, $s) = explode(': ', $ary[1], 2);
|
||||
}
|
||||
$data['title'] = trim($t);
|
||||
$data['subtitle'] = trim($s);
|
||||
$data['year'] = trim($ary[2]);
|
||||
}
|
||||
} else {
|
||||
preg_match('/<title>(.+?)\(.*?(\d+)\).+?<\/title>/si', $resp['data'], $ary);
|
||||
$data['year'] = trim($ary[2]);
|
||||
# split title - subtitle
|
||||
list($t, $s) = explode(' - ', $ary[1], 2);
|
||||
# no dash, lets try colon
|
||||
if ($s == false) {
|
||||
list($t, $s) = explode(': ', $ary[1], 2);
|
||||
}
|
||||
$data['title'] = trim($t);
|
||||
$data['subtitle'] = trim($s);
|
||||
}
|
||||
# orig. title
|
||||
preg_match('/<div class="originalTitle">(.+?)<span class="description"> \(original title\)<\/span><\/div>/si', $resp['data'], $ary);
|
||||
$data['origtitle'] = trim($ary[1]);
|
||||
|
||||
// Cover URL
|
||||
$data['coverurl'] = imdbGetCoverURL($resp['data'], $json_data);
|
||||
|
||||
// MPAA Rating
|
||||
$data['mpaa'] = "";
|
||||
$data['mpaa'] = $json_data["props"]["pageProps"]["aboveTheFoldData"]["certificate"]["rating"];
|
||||
|
||||
// Runtime
|
||||
if (filter_var($json_data["props"]["pageProps"]["aboveTheFoldData"]["runtime"]["seconds"], FILTER_SANITIZE_NUMBER_INT) > 0) {
|
||||
# use the runtime from the next_data json data
|
||||
$data['runtime'] = filter_var($json_data["props"]["pageProps"]["aboveTheFoldData"]["runtime"]["seconds"], FILTER_SANITIZE_NUMBER_INT) / 60;
|
||||
} else if (preg_match('/<li role="presentation" class="ipc-inline-list__item">(\d+)(?:<!-- --> ?)+(?:h|s).*?(?:(?:<!-- --> ?)+(\d+)(?:<!-- --> ?)+.+?)?<\/li>/si', $resp['data'], $ary)) {
|
||||
# handles Hours and maybe minutes. Some movies are exactly 1 hours.
|
||||
$minutes = intval($ary[2]);
|
||||
if (is_numeric($ary[1])) {
|
||||
$minutes += intval($ary[1]) * 60;
|
||||
}
|
||||
|
||||
$data['runtime'] = $minutes;
|
||||
} else if (preg_match('/<li role="presentation" class="ipc-inline-list__item">(\d+)(?:<!-- --> ?)+m.*?<\/li>/si', $resp['data'], $ary)) {
|
||||
# handle only minutes
|
||||
$data['runtime'] = $ary[1];
|
||||
} else if (preg_match('/<div class="ipc-metadata-list-item__content-container">(\d+)(?:<!-- --> ?)+m.*?<\/div>/si', $resp['data'], $ary)) {
|
||||
# handle only minutes
|
||||
# Handles the case where runtime is only in the technical spec section.
|
||||
$data['runtime'] = $ary[1];
|
||||
}
|
||||
|
||||
// Rating
|
||||
preg_match('/<div data-testid="hero-rating-bar__aggregate-rating__score" class="sc-.+?"><span class="sc-.+?">(.+?)<\/span><span>\/<!-- -->10<\/span><\/div>/si', $resp['data'], $ary);
|
||||
$data['rating'] = trim($ary[1]);
|
||||
|
||||
// Countries
|
||||
preg_match_all('/href="\/search\/title\/\?country_of_origin.+?>(.+?)<\/a>/si', $resp['data'], $ary, PREG_PATTERN_ORDER);
|
||||
$data['country'] = trim(join(', ', $ary[1]));
|
||||
|
||||
// Languages
|
||||
$data['language'] = '';
|
||||
if (isset( $json_data["props"]["pageProps"]["mainColumnData"]["spokenLanguages"]["spokenLanguages"]) &&
|
||||
is_array($json_data["props"]["pageProps"]["mainColumnData"]["spokenLanguages"]["spokenLanguages"]))
|
||||
{
|
||||
foreach ($json_data["props"]["pageProps"]["mainColumnData"]["spokenLanguages"]["spokenLanguages"] as $languagedata)
|
||||
{
|
||||
$languagearray[] = trim($languagedata["text"]);
|
||||
}
|
||||
$data['language'] = trim(strtolower(join(', ',$languagearray)));
|
||||
}
|
||||
|
||||
// Genres (as Array)
|
||||
preg_match_all('/class="ipc-chip__text">(.+?)<\/span><\/a>/si', $resp['data'], $ary, PREG_PATTERN_ORDER);
|
||||
foreach($ary[1] as $genre) {
|
||||
$data['genres'][] = trim($genre);
|
||||
}
|
||||
|
||||
// for Episodes - try to get some missing stuff from the main series page
|
||||
if ( $data['istv'] and (!$data['runtime'] or !$data['country'] or !$data['language'] or !$data['coverurl'])) {
|
||||
$sresp = httpClient($imdbServer.'/title/tt'.$data['tvseries_id'].'/', $cache);
|
||||
if (!$sresp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
# runtime
|
||||
if (preg_match('/<li role="presentation" class="ipc-inline-list__item">(\d+)(?:<!-- --> ?)+(?:h|s).*?(?:(?:<!-- --> ?)+(\d+)(?:<!-- --> ?)+.+?)?<\/li>/si', $resp['data'], $ary)) {
|
||||
# handles Hours and maybe minutes. Some movies are exactly 1 hours.
|
||||
$minutes = intval($ary[2]);
|
||||
if (is_numeric($ary[1])) {
|
||||
$minutes += intval($ary[1]) * 60;
|
||||
}
|
||||
|
||||
$data['runtime'] = $minutes;
|
||||
} else if (preg_match('/<li role="presentation" class="ipc-inline-list__item">(\d+)(?:<!-- --> ?)+m.*?<\/li>/si', $resp['data'], $ary)) {
|
||||
# handle only minutes
|
||||
$data['runtime'] = $ary[1];
|
||||
} else if (preg_match('/<div class="ipc-metadata-list-item__content-container">(\d+)(?:<!-- --> ?)+m.*?<\/div>/si', $resp['data'], $ary)) {
|
||||
# handle only minutes
|
||||
# Handles the case where runtime is only in the technical spec section.
|
||||
$data['runtime'] = $ary[1];
|
||||
}
|
||||
|
||||
# country
|
||||
if (!$data['country']) {
|
||||
preg_match_all('/href="\/search\/title\/\?country_of_origin.+?>(.+?)<\/a>/si', $sresp['data'], $ary, PREG_PATTERN_ORDER);
|
||||
$data['country'] = trim(join(', ', $ary[1]));
|
||||
}
|
||||
|
||||
# language
|
||||
if (!$data['language']) {
|
||||
preg_match_all('/<a class=".+?" rel="" href="\/search\/title\?title_type=feature&primary_language=.+?&sort=moviemeter,asc&ref_=tt_dt_ln">(.+?)<\/a>/', $sresp['data'], $ary, PREG_PATTERN_ORDER);
|
||||
$data['language'] = trim(strtolower(join(', ', $ary[1])));
|
||||
}
|
||||
|
||||
# cover
|
||||
if (!$data['coverurl']) {
|
||||
$data['coverurl'] = imdbGetCoverURL($sresp['data']);
|
||||
}
|
||||
}
|
||||
|
||||
// Plot
|
||||
if (array_key_exists('plainText', $json_data["props"]["pageProps"]["aboveTheFoldData"]["plot"]["plotText"]) )
|
||||
{
|
||||
$data['plot'] = stripslashes($json_data["props"]["pageProps"]["aboveTheFoldData"]["plot"]["plotText"]["plainText"]);
|
||||
}
|
||||
|
||||
// Fetch credits
|
||||
$resp = imdbFixEncoding($data, httpClient($imdbServer.'/title/tt'.$imdbID.'/fullcredits', $cache));
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// Cast
|
||||
// Directors
|
||||
#testing code save resp data from imdb
|
||||
#file_put_contents('./cache/httpclient-php_imdbData_cast.html', $resp['data']); // write page data to file
|
||||
|
||||
// Increase the PCRE backtrack limit for a potentially large regex operation
|
||||
$origBacktrackLimit = ini_get('pcre.backtrack_limit');
|
||||
$newBacktrackLimit = '10000000';
|
||||
ini_set('pcre.backtrack_limit', $newBacktrackLimit);
|
||||
|
||||
// extract json data from page
|
||||
if (preg_match('#(\<script id\="__NEXT_DATA__".*?\>)(.*?)(\</script\>)#s',$resp['data'],$matches))
|
||||
{
|
||||
#file_put_contents('./cache/nextdata.json-cast', $matches[2]); // write json data to file
|
||||
$json_data_cast = json_decode($matches[2],true);
|
||||
#file_put_contents('./cache/nextdata-decoded.json-cast', print_r($json_data_cast, true)); // write formated json data to file
|
||||
}
|
||||
//revert the PCRE limits back to their original values after regex operation,
|
||||
ini_set('pcre.backtrack_limit', $origBacktrackLimit);
|
||||
|
||||
// cast and directors
|
||||
$data['cast'] = "";
|
||||
$data['director'] = "";
|
||||
$cast_done = false;
|
||||
$directors_done = false;
|
||||
|
||||
if (isset($json_data_cast['props']['pageProps']['contentData']['categories']) &&
|
||||
is_array($json_data_cast['props']['pageProps']['contentData']['categories']))
|
||||
{
|
||||
foreach ($json_data_cast['props']['pageProps']['contentData']['categories'] as $category)
|
||||
{
|
||||
if (!isset($category['name']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
switch (strtolower($category['name']))
|
||||
{
|
||||
case "cast":
|
||||
$cast = imdbGetCast($category, $imdbID);
|
||||
$data['cast'] = $cast;
|
||||
$cast_done = true;
|
||||
break;
|
||||
case "directors":
|
||||
case "director":
|
||||
$dirs = imdbGetDirectors($category);
|
||||
$data['director'] = $dirs;
|
||||
$directors_done = true;
|
||||
break;
|
||||
default:
|
||||
// Other categories can be handled here if needed
|
||||
break;
|
||||
}
|
||||
if ($cast_done && $directors_done)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch plot
|
||||
$resp = $resp = imdbFixEncoding($data, httpClient($imdbServer.'/title/tt'.$imdbID.'/plotsummary', $cache));
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// Plot
|
||||
//<li class="ipl-zebra-list__item" id="summary-ps0695557">
|
||||
// <p>A nameless first person narrator (<a href="/name/nm0001570/">Edward Norton</a>) attends support groups in attempt to subdue his emotional state and relieve his insomniac state. When he meets Marla (<a href="/name/nm0000307/">Helena Bonham Carter</a>), another fake attendee of support groups, his life seems to become a little more bearable. However when he associates himself with Tyler (<a href="/name/nm0000093/">Brad Pitt</a>) he is dragged into an underground fight club and soap making scheme. Together the two men spiral out of control and engage in competitive rivalry for love and power. When the narrator is exposed to the hidden agenda of Tyler's fight club, he must accept the awful truth that Tyler may not be who he says he is.</p>
|
||||
// <div class="author-container">
|
||||
// <em>—<a href="/search/title?plot_author=Rhiannon&view=simple&sort=alpha&ref_=ttpl_pl_0">Rhiannon</a></em>
|
||||
// </div>
|
||||
//</li>
|
||||
preg_match('/<li class="ipl-zebra-list__item" id="summary-p.\d+">\s+<p>(.+?)<\/p>/is', $resp['data'], $ary);
|
||||
if ($ary[1])
|
||||
{
|
||||
$data['plot'] = trim($ary[1]);
|
||||
$data['plot'] = preg_replace('/"/', '"', $data['plot']); //Replace HTML " with "
|
||||
|
||||
// removed linked actors like: <a href="/name/nm0001570?ref_=tt_stry_pl">Edward Norton</a>
|
||||
$data['plot'] = preg_replace('/<a href="\/name\/nm\d+.+?">/', '', $data['plot']);
|
||||
$data['plot'] = preg_replace('/<\/a>/', '', $data['plot']);
|
||||
$data['plot'] = preg_replace('/\s+/s', ' ', $data['plot']);
|
||||
}
|
||||
|
||||
$data['plot'] = html_clean_utf8($data['plot']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* At the moment - oct 2010 - most imdb-pages were changed to utf8,
|
||||
* but e.g. fullcredits are still iso-8859-1
|
||||
* so data is recoded here
|
||||
*/
|
||||
function imdbFixEncoding($data, $resp)
|
||||
{
|
||||
$result = $resp;
|
||||
$pageEncoding = $resp['encoding'];
|
||||
|
||||
if ($pageEncoding != $data['encoding'])
|
||||
{
|
||||
$result['data'] = iconv($pageEncoding, $data['encoding'], html_entity_decode_all($resp['data']));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url of Cover Image
|
||||
*
|
||||
* @author Roland Obermayer <robelix@gmail.com>
|
||||
* @param string $data IMDB Page data
|
||||
* @param string $jsondata IMDB json Data
|
||||
* @return string Cover Image URL
|
||||
*/
|
||||
function imdbGetCoverURL($data, $jsondata = null) {
|
||||
global $imdbServer;
|
||||
global $CLIENTERROR;
|
||||
global $cache;
|
||||
|
||||
if ($jsondata !== null)
|
||||
{
|
||||
$url = '';
|
||||
if (isset($jsondata["props"]["pageProps"]["aboveTheFoldData"]["primaryImage"]))
|
||||
{
|
||||
$url = $jsondata["props"]["pageProps"]["aboveTheFoldData"]["primaryImage"]["url"];
|
||||
// If you want the image to scaled to a certain size you can do this.
|
||||
// UX800 sets the width of the image to 800 with correct aspect ratio with regard to height.
|
||||
// UY800 set the height to 800 with correct aspect ratio with regard to width.
|
||||
// $url= str_replace('.jpg', 'UY800_.jpg', $url);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
// find cover image url
|
||||
if (preg_match('/<a class="ipc-lockup-overlay ipc-focusable.*?" href="(\/title\/tt\d+\/mediaviewer\/\??rm.+?)" aria-label=".*?Poster.*?"><div class="ipc-lockup-overlay__screen"><\/div><\/a>/s', $data, $ary))
|
||||
{
|
||||
// Fetch the image page
|
||||
$resp = httpClient($imdbServer.$ary[1], $cache);
|
||||
|
||||
if ($resp['success'])
|
||||
{
|
||||
// get big cover image.
|
||||
preg_match('/<div style=".+?" class=".+?"><img src="(.+?)"/si', $resp['data'], $ary);
|
||||
// If you want the image to scaled to a certain size you can do this.
|
||||
// UX800 sets the width of the image to 800 with correct aspect ratio with regard to height.
|
||||
// UY800 set the height to 800 with correct aspect ratio with regard to width.
|
||||
// return str_replace('.jpg', 'UY800_.jpg', $ary[1]);
|
||||
return trim($ary[1]);
|
||||
}
|
||||
$CLIENTERROR .= $resp['error']."\n";
|
||||
return '';
|
||||
}
|
||||
// src look somthing like: src="https://images-na.ssl-images-amazon.com/images/M/MV5BMTc0MDMyMzI2OF5BMl5BanBnXkFtZTcwMzM2OTk1MQ@@._V1_UX214_CR0,0,214,317_AL_.jpg"
|
||||
// The last part ._V1_UX214.....jpg seams to be an function that scales the image. Just remove that we want the full size.
|
||||
else if (preg_match('/<div.*?class="poster".*?<img.*?src="(.*?\.)_v.*?"/si', $data, $ary))
|
||||
{
|
||||
$img_url = $ary[1]."jpg";
|
||||
// Replace the https wtih http.
|
||||
$img_url = str_replace("https://images-na.ssl-images-amazon.com", "http://ecx.images-amazon.com", $img_url);
|
||||
return $img_url;
|
||||
}
|
||||
else
|
||||
{
|
||||
# no image
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Url to visit IMDB for a specific actor
|
||||
*
|
||||
* @author Michael Kollmann <acidity@online.de>
|
||||
* @param string $name The actor's name
|
||||
* @param string $id The actor's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function imdbActorUrl($name, $id)
|
||||
{
|
||||
global $imdbServer;
|
||||
|
||||
$path = ($id) ? 'name/'.urlencode($id).'/' : 'Name?'.urlencode(html_entity_decode_all($name));
|
||||
|
||||
return $imdbServer.'/'.$path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Actor-Details
|
||||
*
|
||||
* Find image and detail URL for actor, not sure if this can be made
|
||||
* a one-step process?
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string $name Name of the Actor
|
||||
* @return array array with Actor-URL and Thumbnail
|
||||
*/
|
||||
function imdbActor($name, $actorid)
|
||||
{
|
||||
global $imdbServer;
|
||||
global $cache;
|
||||
|
||||
// search directly by id or via name?
|
||||
$resp = httpClient(imdbActorUrl($name, $actorid), $cache);
|
||||
//testing code save resp data from imdb
|
||||
//$file_path = './cache/httpclient-php_imdbActor_call_1.html';
|
||||
//file_put_contents($file_path, $resp['data']);
|
||||
|
||||
// if not direct match load best match
|
||||
if (preg_match('#<b>Popular Names</b>.+?<a\s+href="(.*?)">#i', $resp['data'], $m) ||
|
||||
preg_match('#<b>Names \(Exact Matches\)</b>.+?<a\s+href="(.*?)">#i', $resp['data'], $m) ||
|
||||
preg_match('#<b>Names \(Approx Matches\)</b>.+?<a\s+href="(.*?)">#i', $resp['data'], $m))
|
||||
{
|
||||
if (!preg_match('/http/i', $m[1]))
|
||||
{
|
||||
$m[1] = $imdbServer.$m[1];
|
||||
}
|
||||
$resp = httpClient($m[1], true);
|
||||
//testing code save resp data from imdb
|
||||
//$file_path = './cache/httpclient-php_/_imdbActor_call_2.html';
|
||||
//file_put_contents($file_path, $resp['data']);
|
||||
}
|
||||
|
||||
// now we should have loaded the best match
|
||||
|
||||
// only search in img_primary <td> - or we get far to many useless images
|
||||
preg_match('/<div class="ipc-poster.*?>(.*?)<\/a><\/div>/si', $resp['data'], $match);
|
||||
|
||||
$ary = array();
|
||||
if (preg_match('/.+?src="(.+?)".+?<a.*?href="(\/name\/nm\d+\/).+?/si', $match[1], $m))
|
||||
{
|
||||
$ary[0][0] = $m[2];
|
||||
$ary[0][1] = $m[1];
|
||||
}
|
||||
|
||||
return $ary;
|
||||
}
|
||||
|
||||
function imdbGetCast(array $category, string $imdbID)
|
||||
{
|
||||
$cast = [];
|
||||
if (isset($category['section']['items']) && is_array($category['section']['items'])) {
|
||||
$pageSize = $category['pagination']['queryVariables']['first'];
|
||||
$total_cast = $category['section']['total'];
|
||||
|
||||
if ($total_cast > $pageSize) {
|
||||
$cast = imdbCastExtra($imdbID);
|
||||
} else {
|
||||
$cast = imdbCast($category['section']['items']);
|
||||
}
|
||||
}
|
||||
return $cast;
|
||||
}
|
||||
|
||||
function imdbGetDirectors(array $category)
|
||||
{
|
||||
$directors = [];
|
||||
if (isset($category['section']['items']) && is_array($category['section']['items'])) {
|
||||
foreach ($category['section']['items'] as $item) {
|
||||
if (isset($item['rowTitle'])) {
|
||||
$directors[] = $item['rowTitle'];
|
||||
}
|
||||
}
|
||||
}
|
||||
$dirs = implode(', ', $directors);
|
||||
$dirs = substr($dirs, 0, 250);
|
||||
|
||||
return $dirs;
|
||||
}
|
||||
|
||||
function imdbCast(array $items)
|
||||
{
|
||||
global $imdbIdPrefix;
|
||||
|
||||
// Loop through each item in the items array
|
||||
foreach ($items as $item)
|
||||
{
|
||||
// Check if the required keys exist.
|
||||
$actorid = isset($item['id']) ? $item['id'] : "";
|
||||
$actor = isset($item['rowTitle']) ? $item['rowTitle'] : "";
|
||||
// Build the $character string from characters and attributes
|
||||
if (isset($item['characters']) && is_array($item['characters']) && !empty($item['characters']))
|
||||
{
|
||||
// Join all characters if available
|
||||
$character = implode(" / ", $item['characters']);
|
||||
// Append attributes if present
|
||||
if (isset($item['attributes']) && !empty($item['attributes']))
|
||||
{
|
||||
$character .= " " . $item['attributes'];
|
||||
}
|
||||
}
|
||||
elseif (isset($item['attributes']) && !empty($item['attributes']))
|
||||
{
|
||||
// Use only attributes if characters are not set or empty
|
||||
$character = $item['attributes'];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default to an empty string if neither field is available
|
||||
$character = "";
|
||||
}
|
||||
// Append episodic credit data if available
|
||||
if (isset($item['episodicCreditData']) && is_array($item['episodicCreditData']))
|
||||
{
|
||||
$episodicParts = [];
|
||||
if (isset($item['episodicCreditData']['episodesText']) && !empty($item['episodicCreditData']['episodesText'])) {
|
||||
$episodicParts[] = $item['episodicCreditData']['episodesText'];
|
||||
}
|
||||
if (isset($item['episodicCreditData']['tenureText']) && !empty($item['episodicCreditData']['tenureText'])) {
|
||||
$episodicParts[] = $item['episodicCreditData']['tenureText'];
|
||||
}
|
||||
if (!empty($episodicParts)) {
|
||||
$character .= " " . implode(", ", $episodicParts);
|
||||
}
|
||||
}
|
||||
// Append the current actor's details
|
||||
$cast .= "$actor::$character::$imdbIdPrefix$actorid\n";
|
||||
}
|
||||
|
||||
return $cast;
|
||||
}
|
||||
|
||||
function imdbCastExtra($imdbID)
|
||||
{
|
||||
global $imdbIdPrefix;
|
||||
global $CLIENTERROR;
|
||||
global $cache;
|
||||
|
||||
$param = ['header' => ['Accept' => 'application/json',
|
||||
'User-Agent' => 'Mozilla/5.0',
|
||||
'Content-Type' => 'application/json',
|
||||
]
|
||||
];
|
||||
$after = '';
|
||||
$cast = '';
|
||||
|
||||
do
|
||||
{
|
||||
$url = 'https://caching.graphql.imdb.com/?operationName=TitleCreditSubPagePagination&variables={"after":"'.$after.'","category":"cast","const":"tt'.$imdbID.'","first":250,"locale":"en-US","originalTitleText":false,"tconst":"tt'.$imdbID.'"}&extensions={"persistedQuery":{"sha256Hash":"716fbcc1b308c56db263f69e4fd0499d4d99ce1775fb6ca75a75c63e2c86e89c","version":1}}';
|
||||
|
||||
$resp = httpClient($url, $cache, $param);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// Cast
|
||||
#testing code save resp data from imdb
|
||||
#file_put_contents('./cache/httpclient-php_imdbData_castextra.html', $resp['data']); // write page data to file
|
||||
#file_put_contents('./cache/json-castextra', $resp['data']); // write json data to file
|
||||
$json_data_castextra = json_decode( $resp['data'],true);
|
||||
#file_put_contents('./cache/jsonDecoded-castextra', print_r($json_data_castextra, true)); // write formated json data to file
|
||||
|
||||
if (isset($json_data_castextra['data']['title']['credits']) &&
|
||||
is_array($json_data_castextra['data']['title']['credits']))
|
||||
{
|
||||
$credits = $json_data_castextra['data']['title']['credits'];
|
||||
// Loop through each item in the items array
|
||||
foreach ($credits['edges'] as $edge)
|
||||
{
|
||||
// Check if the required keys exist.
|
||||
$actorId = isset($edge['node']['name']['id']) ? $edge['node']['name']['id'] : "";
|
||||
$actor = isset($edge['node']['name']['nameText']['text']) ? $edge['node']['name']['nameText']['text'] : "";
|
||||
// Build the $character string from characters and attributes
|
||||
|
||||
if (is_array($edge['node']['characters']))
|
||||
{
|
||||
$characterNames = array_map(function ($char)
|
||||
{
|
||||
return $char['name'];
|
||||
}, $edge['node']['characters']);
|
||||
$role = implode(' / ', $characterNames);
|
||||
|
||||
if ($edge['node']['attributes'])
|
||||
{
|
||||
foreach($edge['node']['attributes'] as $attr)
|
||||
{
|
||||
$role .= " (" . $attr['text'] . ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$role = $edge['node']['attributes']['text'];
|
||||
}
|
||||
if ($edge['node']['episodeCredits'] && $edge['node']['episodeCredits']['total'] > 0)
|
||||
{
|
||||
$total = $edge['node']['episodeCredits']['total'];
|
||||
$from = $edge['node']['episodeCredits']['yearRange']['year'];
|
||||
$to = $edge['node']['episodeCredits']['yearRange']['endYear'];
|
||||
|
||||
$role .= ", $total episodes, $from";
|
||||
if ($to)
|
||||
{
|
||||
$role .= "-$to";
|
||||
}
|
||||
}
|
||||
// Append the current actor's details
|
||||
$cast .= "$actor::$role::$imdbIdPrefix$actorId\n";
|
||||
}
|
||||
}
|
||||
|
||||
$after = $credits['pageInfo']['endCursor'];
|
||||
} while ($credits['pageInfo']['hasNextPage']);
|
||||
|
||||
return $cast;
|
||||
}
|
||||
698
videodb/engines/ofdb.php
Executable file
698
videodb/engines/ofdb.php
Executable file
@@ -0,0 +1,698 @@
|
||||
<?php
|
||||
/**
|
||||
* OFDB Parser
|
||||
*
|
||||
* Parses data from the OFDB
|
||||
*
|
||||
* @package Engines
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @link http://www.ofdb.de
|
||||
* @version $Id: ofdb.php,v 1.27 2013/03/16 14:29:47 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/xml.core.php';
|
||||
|
||||
$GLOBALS['ofdbServer'] = 'https://www.ofdb.de';
|
||||
$GLOBALS['ofdbGW'] = 'http://www.ofdbgw.org'; // defunct
|
||||
$GLOBALS['ofdbIdPrefix'] = 'ofdb:';
|
||||
|
||||
/**
|
||||
* Get meta information about the engine
|
||||
*
|
||||
* @todo Include image search capabilities etc in meta information
|
||||
*/
|
||||
function ofdbMeta()
|
||||
{
|
||||
return array(
|
||||
'name' => 'OFDB (de)'
|
||||
, 'stable' => 1
|
||||
, 'supportsEANSearch' => 1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get search Url for OfDB
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string The search string
|
||||
* @return string The search URL (GET)
|
||||
*/
|
||||
function ofdbSearchUrl($title, $searchType = 'title')
|
||||
{
|
||||
global $ofdbServer;
|
||||
|
||||
// auto switch to ean Mode if title is exactly 13 digits
|
||||
if (preg_match('#^\s*[0-9]{13}\s*$#',$title)) $searchType = 'ean';
|
||||
|
||||
$url = $ofdbServer.'/view.php?page=suchergebnis&SText='.urlencode($title);
|
||||
switch($searchType)
|
||||
{
|
||||
default :
|
||||
case 'text': {
|
||||
$url = $url.'&Kat=All'; break;
|
||||
}
|
||||
case 'ean' : {
|
||||
$url = $url.'&Kat=EAN'; break;
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content overview URL
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbContentUrl($id)
|
||||
{
|
||||
global $ofdbServer;
|
||||
global $ofdbIdPrefix;
|
||||
|
||||
$id = preg_replace('/^'.$ofdbIdPrefix.'/', '', $id);
|
||||
list($id, $vid) = explode("-", $id, 2);
|
||||
return $ofdbServer.'/view.php?page=film&fid='.$id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content detail URL
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbDetailUrl($id)
|
||||
{
|
||||
global $ofdbServer;
|
||||
return $ofdbServer.'/view.php?page=film_detail&fid='.$id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get explicit version URL
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @param string $vid The movie's version id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbVersionUrl($id, $vid)
|
||||
{
|
||||
global $ofdbServer;
|
||||
return $ofdbServer.'/view.php?page=fassung&fid='.$id.'&vid='.$vid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content description URL
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @param string $sid The movie's description id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbDescriptionUrl($id, $sid)
|
||||
{
|
||||
global $ofdbServer;
|
||||
return $ofdbServer.'/view.php?page=inhalt&fid='.$id.'&sid='.$sid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search a Movie
|
||||
*
|
||||
* Searches for a given title on the OfDB and returns the found links in
|
||||
* an array
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string The search string
|
||||
* @return array Associative array with id and title
|
||||
*/
|
||||
function ofdbSearch($title, $searchType = 'title')
|
||||
{
|
||||
global $CLIENTERROR;
|
||||
global $cache;
|
||||
global $ofdbServer;
|
||||
global $ofdbGW;
|
||||
global $ofdbIdPrefix;
|
||||
|
||||
$url = $ofdbGW.'/search/'.$title;
|
||||
$resp = httpClient($url, $cache);
|
||||
# dump($resp);
|
||||
|
||||
if (!$resp['success']) {
|
||||
$CLIENTERROR .= $resp['error']."\n";
|
||||
return(false);
|
||||
}
|
||||
|
||||
$xml = load_xml($resp['data']);
|
||||
# dump($xml);
|
||||
|
||||
if ((int) $xml->status->rcode > 0) {
|
||||
// prevent caching bad data
|
||||
if ($cache) {
|
||||
$cache_file = cache_get_filename($url, CACHE_HTML);
|
||||
@unlink($cache_file);
|
||||
|
||||
if ($resp['source']) {
|
||||
// TODO make sure redirects are deleted as well
|
||||
$url = $resp['source'];
|
||||
$cache_file = cache_get_filename($url, CACHE_HTML);
|
||||
@unlink($cache_file);
|
||||
}
|
||||
}
|
||||
$CLIENTERROR .= ((string) $xml->status->rcodedesc)."\n";
|
||||
return(false);
|
||||
}
|
||||
|
||||
$data = array();
|
||||
$data['encoding'] = 'utf-8';
|
||||
|
||||
foreach($xml->resultat->eintrag as $item)
|
||||
{
|
||||
$data = array();
|
||||
|
||||
// Id
|
||||
$data['id'] = $ofdbIdPrefix.((string) $item->id);
|
||||
|
||||
// Title
|
||||
$data['title'] = (string) $item->titel;
|
||||
$data['orgtitle'] = (string) $item->titel_orig;
|
||||
list($data['title'], $data['subtitle']) = explode(" - ", $data['title'], 2);
|
||||
|
||||
// Year
|
||||
$data['year'] = (string) $item->jahr;
|
||||
|
||||
// cover url for image lookup
|
||||
$data['coverurl'] = (string) $item->bild;
|
||||
|
||||
$result[] = $data;
|
||||
}
|
||||
# dump($data);
|
||||
|
||||
return($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the data for a given OfDB id
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param int OfDB id
|
||||
* @return array Result data
|
||||
*/
|
||||
function ofdbData($id)
|
||||
{
|
||||
global $CLIENTERROR;
|
||||
global $cache;
|
||||
global $ofdbServer;
|
||||
global $ofdbGW;
|
||||
global $ofdbIdPrefix;
|
||||
|
||||
// Languages
|
||||
$map_laguages = array(
|
||||
'arabisch' => 'arabic',
|
||||
'bulgarisch' => 'bulgarian',
|
||||
'chinesisch' => 'chinese',
|
||||
'tschechisch' => 'czech',
|
||||
'dänisch' => 'danish',
|
||||
'holländisch' => 'dutch',
|
||||
'englisch' => 'english',
|
||||
'französisch' => 'french',
|
||||
'deutsch' => 'german',
|
||||
'griechisch' => 'greek',
|
||||
'ungarisch' => 'hungarian',
|
||||
'isländisch' => 'icelandic',
|
||||
'indisch' => 'indian',
|
||||
'israelisch' => 'israeli',
|
||||
'italienisch' => 'italian',
|
||||
'japanisch' => 'japanese',
|
||||
'koreanisch' => 'korean',
|
||||
'norwegisch' => 'norwegian',
|
||||
'polnisch' => 'polish',
|
||||
'portugisisch' => 'portuguese',
|
||||
'rumänisch' => 'romanian',
|
||||
'russisch' => 'russian',
|
||||
'serbisch' => 'serbian',
|
||||
'spanisch' => 'spanish',
|
||||
'schwedisch' => 'swedish',
|
||||
'thailändisch' => 'thai',
|
||||
'türkisch' => 'turkish',
|
||||
'vietnamesisch' => 'vietnamese',
|
||||
'kantonesisch' => 'cantonese',
|
||||
'katalanisch' => 'catalan',
|
||||
'zypriotisch' => 'cypriot',
|
||||
'zyprisch' => 'cypriot',
|
||||
'esperanto' => 'esperanto',
|
||||
'gälisch' => 'gaelic',
|
||||
'hebräisch' => 'hebrew',
|
||||
'hindi' => 'hindi',
|
||||
'jüdisch' => 'jewish',
|
||||
'lateinisch' => 'latin',
|
||||
'mandarin' => 'mandarin',
|
||||
'serbokroatisch' => 'serbo-croatian',
|
||||
'somalisch' => 'somali'
|
||||
);
|
||||
|
||||
// Genres
|
||||
$map_genres = array(
|
||||
'Amateur' => '',
|
||||
'Eastern' => '',
|
||||
'Experimentalfilm' => '',
|
||||
'Mondo' => '',
|
||||
'Kampfsport' => 'Sport',
|
||||
'Biographie' => 'Biography',
|
||||
'Katastrophen' => 'Thriller',
|
||||
'Krimi' => 'Crime',
|
||||
'Science-Fiction' => 'Sci-Fi',
|
||||
'Kinder-/Familienfilm' => 'Family',
|
||||
'Dokumentation' => 'Documentary',
|
||||
'Action' => 'Action',
|
||||
'Drama' => 'Drama',
|
||||
'Abenteuer' => 'Adventure',
|
||||
'Historienfilm' => 'History',
|
||||
'Kurzfilm' => 'Short',
|
||||
'Liebe/Romantik' => 'Romance',
|
||||
'Heimatfilm' => 'Romance',
|
||||
'Grusel' => 'Horror',
|
||||
'Horror' => 'Horror',
|
||||
'Erotik' => 'Adult',
|
||||
'Hardcore' => 'Adult',
|
||||
'Sex' => 'Adult',
|
||||
'Musikfilm' => 'Musical',
|
||||
'Animation' => 'Animation',
|
||||
'Fantasy' => 'Fantasy',
|
||||
'Trash' => 'Horror',
|
||||
'Komödie' => 'Comedy',
|
||||
'Krieg' => 'War',
|
||||
'Mystery' => 'Mystery',
|
||||
'Thriller' => 'Thriller',
|
||||
'Tierfilm' => 'Documentary',
|
||||
'Western' => 'Western',
|
||||
'TV-Serie' => '',
|
||||
'TV-Mini-Serie' => '',
|
||||
'Sportfilm' => 'Sport',
|
||||
'Splatter' => 'Horror',
|
||||
'Manga/Anime' => 'Animation'
|
||||
);
|
||||
|
||||
$data = array();
|
||||
$data['encoding'] = 'utf-8';
|
||||
$data['imdbID'] = $id;
|
||||
|
||||
$id = preg_replace('/^'.$ofdbIdPrefix.'/', '', $id);
|
||||
list($id, $vid) = explode("-", $id, 2);
|
||||
|
||||
$url = $ofdbGW.'/movie/'.$id;
|
||||
# dump($url);
|
||||
$resp = httpClient($url, $cache);
|
||||
|
||||
if (!$resp['success']) {
|
||||
$CLIENTERROR .= $resp['error']."\n";
|
||||
return(false);
|
||||
}
|
||||
|
||||
$xml = load_xml($resp['data']);
|
||||
# dump($xml);
|
||||
|
||||
if ((int) $xml->status->rcode > 0) {
|
||||
// prevent caching bad data
|
||||
if ($cache) {
|
||||
$cache_file = cache_get_filename($url, CACHE_HTML);
|
||||
@unlink($cache_file);
|
||||
}
|
||||
$CLIENTERROR .= ((string) $xml->status->rcodedesc)."\n";
|
||||
return(false);
|
||||
}
|
||||
|
||||
// set root
|
||||
$item = $xml->resultat;
|
||||
|
||||
// Title
|
||||
$data['title'] = (string) $item->titel;
|
||||
$data['orgtitle'] = (string) $item->alternativ;
|
||||
list($data['title'], $data['subtitle']) = explode(" - ", $data['title'], 2);
|
||||
|
||||
// Year
|
||||
$data['year'] = (string) $item->jahr;
|
||||
|
||||
// Cover url for image lookup
|
||||
$data['coverurl'] = (string) $item->bild;
|
||||
|
||||
// Plot
|
||||
$data['plot'] = (string) $item->beschreibung;
|
||||
if (!$data['plot']) $data['plot'] = (string) $item->kurzbeschreibung;
|
||||
|
||||
// Rating
|
||||
$data['rating'] = round((float) $item->bewertung->note);
|
||||
|
||||
// Cast
|
||||
foreach ($item->besetzung->person as $cast) {
|
||||
$data['cast'] .= "\n";
|
||||
$data['cast'] .= ((string) $cast->name);
|
||||
if ((string) $cast->rolle) $data['cast'] .= '::'.((string) $cast->rolle);
|
||||
if ((string) $cast->id) $data['cast'] .= '::'.((string) $cast->id);
|
||||
}
|
||||
|
||||
// Director
|
||||
foreach ($item->regie->person as $director) {
|
||||
if ($data['director']) $data['director'] .= ', ';
|
||||
$data['director'] .= (string) $director->name;
|
||||
}
|
||||
|
||||
// Country
|
||||
foreach ($item->produktionsland as $country) {
|
||||
if ($data['country']) $data['country'] .= ', ';
|
||||
$data['country'] .= (string) $country->name;
|
||||
}
|
||||
|
||||
// Genre
|
||||
$data['genres'] = array();
|
||||
foreach ($item->genre->titel as $genre) {
|
||||
$genre = (string) $genre;
|
||||
// mapping
|
||||
if ($map_genres[$genre]) $data['genres'][] = $map_genres[$genre];
|
||||
}
|
||||
|
||||
|
||||
// Fetch first VID if none already selected
|
||||
if (!$vid) {
|
||||
foreach ($item->fassungen->titel as $fassung) {
|
||||
$vid = (string) $fassung->id; // 1545;210858
|
||||
break;
|
||||
}
|
||||
if ($vid) {
|
||||
// IMDB ID
|
||||
$data['imdbID'] = $ofdbIdPrefix.preg_replace('/;/', '-', $vid);
|
||||
}
|
||||
}
|
||||
|
||||
# dump($data);
|
||||
return($data);
|
||||
/*
|
||||
$data = array(); //result
|
||||
$ary = array(); //temp
|
||||
$ary2 = array(); //temp2
|
||||
|
||||
// Fetch Mainpage
|
||||
$resp = httpClient(ofdbContentUrl($id), $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// add encoding
|
||||
$data['encoding'] = $resp['encoding'];
|
||||
|
||||
// add engine ID -> important for non edit.php refetch
|
||||
$data['imdbID'] = $ofdbIdPrefix.$id;
|
||||
|
||||
$resp['data'] = preg_replace('/[\r\n\t]/',' ', $resp['data']);
|
||||
|
||||
// Titles / Year
|
||||
preg_match('/<title>(.*?)<\/title>/i', $resp['data'], $ary);
|
||||
$ary[1] = preg_replace('/^OFDb[\s-]*!!!!!!!!!!!/', '', $ary[1]);
|
||||
$ary[1] = preg_replace('/\[.*\]/', ' ', $ary[1]);
|
||||
if (preg_match('/\(([0-9]*)\)/i',$ary[1],$ary2))
|
||||
{
|
||||
$data['year'] = trim($ary2[1]);
|
||||
}
|
||||
$ary[1] = preg_replace('/\([0-9]*\)/', ' ', $ary[1]);
|
||||
$ary[1] = preg_replace('/\s{2,}/s', ' ', $ary[1]);
|
||||
|
||||
// check if there is a comma sperated article at the end
|
||||
if (preg_match('#(.*),\s*(A|The|Der|Die|Das|Ein|Eine|Einer)\s*$#i',$ary[1],$subRes)) {
|
||||
$ary[1] = $subRes[2].' '.$subRes[1];
|
||||
}
|
||||
|
||||
list($t,$s) = explode(" - ",trim($ary[1]),2);
|
||||
$data['title'] = trim($t);
|
||||
$data['subtitle'] = trim($s);
|
||||
|
||||
// Original Title
|
||||
if (preg_match('/Originaltitel.*?<b>(.*?)</i', $resp['data'], $ary))
|
||||
{
|
||||
$data['orgtitle'] .= trim($ary[1]);
|
||||
}
|
||||
|
||||
// Country
|
||||
if (preg_match('/>Herstellungsland:.*?<b><a.*?>(.*?)<\/a>/i', $resp['data'], $ary))
|
||||
{
|
||||
$data['country'] .= trim($ary[1]);
|
||||
}
|
||||
|
||||
// Rating
|
||||
if (preg_match('/<br>Note:\s*([0-9\.]+)/', $resp['data'], $ary)) {
|
||||
$data['rating'] = $ary[1];
|
||||
}
|
||||
|
||||
// Cover URL
|
||||
if (preg_match('#<img src="(http://img.ofdb.de/film/.*?\.jpg)"#i', $resp['data'], $ary))
|
||||
{
|
||||
$data['coverurl'] = trim($ary[1]);
|
||||
}
|
||||
|
||||
// Fetch first VID if none already selected
|
||||
if (!$vid)
|
||||
{
|
||||
if (preg_match_all('/view\.php\?page=fassung&fid='.$id.'&vid=([0-9]+)".*?class="Klein">(.*?)</i', $resp['data'], $ary, PREG_SET_ORDER))
|
||||
{
|
||||
foreach($ary as $row)
|
||||
{
|
||||
if (trim($row[2]) == "K" || trim($row[2]) == "KV") // Check if there is a good result
|
||||
{
|
||||
$vid=$row[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$vid) // Still empty -> Take the first one
|
||||
{
|
||||
$vid=$ary[1][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IMDB ID
|
||||
$data['imdbID'] = $ofdbIdPrefix."$id-$vid";
|
||||
|
||||
// Fetch Plot
|
||||
if (preg_match('#href="(plot/[^"]+)"#i', $resp['data'], $ary))
|
||||
{
|
||||
$subresp = httpClient($ofdbServer.'/'.$ary[1], $cache);
|
||||
|
||||
if (!$resp['success']) $CLIENTERROR .= $subresp['error']."\n";
|
||||
$subresp['data'] = preg_replace('/[\r\n\t]/',' ', $subresp['data']);
|
||||
|
||||
if (preg_match('#</b><br><br>(.*?)</font></p>#i', $subresp['data'], $ary))
|
||||
{
|
||||
|
||||
$ary[1] = preg_replace('/\s{2,}/s', ' ', $ary[1]);
|
||||
$ary[1] = preg_replace('#<(br|p)[ /]*>#i', "\n", $ary[1]);
|
||||
$data['plot'] = trim($ary[1]);
|
||||
//$data['plot'] = "aeääääaaaä";
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch Details
|
||||
$resp = httpClient(ofdbDetailUrl($id), $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
$resp['data'] = preg_replace('/[\r\n\t]/',' ', $resp['data']);
|
||||
|
||||
// Director
|
||||
if (preg_match('/<b><i>Regie<\/i><\/b>.*?<table.*?>(.*?)<\/table>/i', $resp['data'], $ary))
|
||||
{
|
||||
if (preg_match_all('/class="Daten"><a.*?>(.*?)<\/a>/i',$ary[1],$ary2, PREG_SET_ORDER))
|
||||
{
|
||||
foreach ($ary2 as $row)
|
||||
{
|
||||
$data['director'] .= trim($row[1]).', ';
|
||||
}
|
||||
$data['director'] = preg_replace('/, $/', '', $data['director']);
|
||||
}
|
||||
}
|
||||
|
||||
// Cast
|
||||
if (preg_match('/<b><i>Darsteller<\/i><\/b>.*?<table.*?>(.*)<\/table>/', $resp['data'], $ary))
|
||||
{
|
||||
// dirty workaround for (.*?) failed on very long match groups issue (tested at PHP 5.2.5.5)
|
||||
// e.g.: ofdb:7749-111320 (Angel - Jäger der Finsternis)
|
||||
$ary[1] = preg_replace('#</table.*#','',$ary[1]);
|
||||
|
||||
if (preg_match_all('/class="Daten"><a(.*?)">(.*?)<\/a>.*?<\/td> <td.*?<\/td> <td[^>]*>(.*?)<\/td>/i',$ary[1],$ary2, PREG_SET_ORDER))
|
||||
{
|
||||
foreach ($ary2 as $row)
|
||||
{
|
||||
$actor = trim(strip_tags($row[2]));
|
||||
|
||||
$actorid = "";
|
||||
if (!empty($row[1]))
|
||||
{
|
||||
if (preg_match('#href="view.php\?page=person&id=([0-9]*)#i', $row[1], $idAry))
|
||||
{
|
||||
$actorid = $ofdbIdPrefix.$idAry[1];
|
||||
}
|
||||
}
|
||||
|
||||
$character = "";
|
||||
if (!empty($row[3]))
|
||||
{
|
||||
if (preg_match('#class="Normal">... ([^<]*)<#i', $row[3], $charAry))
|
||||
{
|
||||
$character = trim(strip_tags($charAry[1]));
|
||||
}
|
||||
}
|
||||
$data['cast'] .= "$actor::$character::$actorid\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (preg_match('/>Genre\(s\)\:.*?<b>(.*?)<\/b>/i', $resp['data'], $ary))
|
||||
{
|
||||
if (preg_match_all('/<a.*?>(.*?)<\/a>/i',$ary[1],$ary2, PREG_SET_ORDER))
|
||||
{
|
||||
foreach($ary2 as $row) {
|
||||
$genre = trim(html_entity_decode($row[1]));
|
||||
$genre = strip_tags($genre);
|
||||
if (!$genre) continue;
|
||||
if (isset($map_genres[$genre])) $data['genres'][] = $map_genres[$genre];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch Version
|
||||
$resp = httpClient(ofdbVersionUrl($id, $vid), $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
$resp['data'] = preg_replace('/[\r\n\t]/',' ', $resp['data']);
|
||||
|
||||
// FSK
|
||||
$fsks = array(
|
||||
'FSK o.A.' => '0',
|
||||
'FSK 6' => '6',
|
||||
'FSK 12' => '12',
|
||||
'FSK 16' => '16',
|
||||
'FSK 18' => '18',
|
||||
'Keine Jugendfreigabe' => '18',
|
||||
'SPIO/JK' => '18',
|
||||
'juristisch geprüft' => '',
|
||||
'ungeprüft' => ''
|
||||
);
|
||||
if (preg_match('/>Freigabe:<.*?<b>(.*?)<\/tr>/i', $resp['data'], $ary))
|
||||
{
|
||||
$fsk = trim(html_entity_decode($ary[1]));
|
||||
$fsk = strip_tags($fsk);
|
||||
if (isset($fsks[$fsk])) $data['fsk'] = $fsks[$fsk];
|
||||
}
|
||||
|
||||
$lang_list = array();
|
||||
if (preg_match('/>Tonformat:(.*?)<\/tr>/i', $resp['data'], $ary) &&
|
||||
preg_match_all('/<a.*?>(\w+?)(\s\().*?a>/si', $ary[1], $langs, PREG_PATTERN_ORDER))
|
||||
{
|
||||
foreach($langs[1] as $language) {
|
||||
$language = trim(strtolower($language));
|
||||
$language = html_entity_decode(strip_tags($language));
|
||||
$language = preg_replace('/\s+$/','',$language);
|
||||
if (!$language) continue;
|
||||
if (isset($map_laguages[$language])) $language = $map_laguages[$language];
|
||||
else continue;
|
||||
if (!$language) continue;
|
||||
$lang_list[] = $language;
|
||||
}
|
||||
$data['language'] = trim(join(', ', array_unique($lang_list)));
|
||||
}
|
||||
|
||||
// Runtime
|
||||
if (preg_match('/>Laufzeit:<.*?<b>(.*?)\s*Min/i', $resp['data'], $ary))
|
||||
{
|
||||
$ary[1] = preg_replace('/:.*!!!!!!!/','', $ary[1]);
|
||||
$data['runtime'] = trim($ary[1]);
|
||||
}
|
||||
|
||||
// EAN-Code
|
||||
if (preg_match('/>EAN\/UPC<\/a>:.*?<b>\s*([0-9]+)\s*<\/b>/i', $resp['data'], $ary))
|
||||
{
|
||||
$data['barcode'] = $ary[1];
|
||||
}
|
||||
|
||||
return $data;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Url to visit OFDB for a specific actor
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $name The actor's name
|
||||
* @param string $id The actor's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbActorUrl($name, $id)
|
||||
{
|
||||
global $ofdbServer;
|
||||
global $ofdbIdPrefix;
|
||||
|
||||
if ($id) {
|
||||
$id = preg_replace('/^'.$ofdbIdPrefix.'/', '', $id);
|
||||
} else {
|
||||
$id = ofdbGetActorId($name);
|
||||
}
|
||||
|
||||
// now we have for shure an id
|
||||
return ($id) ? $ofdbServer.'/view.php?page=person&id='.$id : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Actor-Details
|
||||
*
|
||||
* Find image and detail URL for actor.
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $name Name of the actor
|
||||
* @param string $id Prefixed ofdb actor id
|
||||
* @return array array with Actor-URL and Thumbnail
|
||||
*/
|
||||
function ofdbActor($name, $id)
|
||||
{
|
||||
global $ofdbServer;
|
||||
global $ofdbIdPrefix;
|
||||
|
||||
if ($id) {
|
||||
$id = preg_replace('/^'.$ofdbIdPrefix.'/', '', $id);
|
||||
} else {
|
||||
$id = ofdbGetActorId($name);
|
||||
}
|
||||
|
||||
// now we have for shure an id
|
||||
$folderId = ($id < 1000) ? 0 : substr($id,0,strlen($id)-3);
|
||||
|
||||
$imgUrl = $ofdbServer.'/images/person/'.$folderId.'/'.$id.'.jpg';
|
||||
|
||||
$ary = array();
|
||||
$ary[0][0] = ofdbActorUrl($name, $id);
|
||||
$ary[0][1] = $imgUrl;
|
||||
return $ary;
|
||||
}
|
||||
|
||||
function ofdbGetActorId($name)
|
||||
{
|
||||
global $ofdbServer;
|
||||
global $CLIENTERROR;
|
||||
|
||||
// try to guess the id -> first actor found with this name
|
||||
$url = $ofdbServer.'/view.php?page=liste&Name='.urlencode(html_entity_decode_all($name));
|
||||
$resp = httpClient($url, $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
$resp['data'] = preg_replace('/[\r\n\t]/',' ', $resp['data']);
|
||||
|
||||
return (preg_match('#view.php?page=person&id=([0-9]+)#i', $resp['data'], $ary)) ? $ary[1] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of all previous prefixes for the ImdbId
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @return array Associative array with ImdbId prefixes
|
||||
*/
|
||||
function ofdbImdbIdPrefixes()
|
||||
{
|
||||
global $ofdbIdPrefix;
|
||||
return array($ofdbIdPrefix);
|
||||
}
|
||||
|
||||
?>
|
||||
564
videodb/engines/ofdbscraper.php
Executable file
564
videodb/engines/ofdbscraper.php
Executable file
@@ -0,0 +1,564 @@
|
||||
<?php
|
||||
/**
|
||||
* OFDB Parser
|
||||
*
|
||||
* Parses data from the OFDB
|
||||
*
|
||||
* @package Engines
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @link http://www.ofdb.de
|
||||
* @version $Id: ofdb.php,v 1.24 2011/06/18 21:28:01 robelix Exp $
|
||||
*/
|
||||
|
||||
$GLOBALS['ofdbscraperServer'] = 'https://www.ofdb.de';
|
||||
$GLOBALS['ofdbscraperIdPrefix'] = 'ofdbscraper:';
|
||||
|
||||
/**
|
||||
* Get meta information about the engine
|
||||
*
|
||||
* @todo Include image search capabilities etc in meta information
|
||||
*/
|
||||
function ofdbscraperMeta()
|
||||
{
|
||||
return array(
|
||||
'name' => 'OFDB (de) Scraper'
|
||||
, 'stable' => 1
|
||||
, 'supportsEANSearch' => 0
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get search Url for OfDB
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string The search string
|
||||
* @return string The search URL (GET)
|
||||
*/
|
||||
function ofdbscraperSearchUrl($title, $searchType = 'title')
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
|
||||
// auto switch to ean Mode if title is exactly 13 digits
|
||||
if (preg_match('#^\s*[0-9]{13}\s*$#',$title)) $searchType = 'ean';
|
||||
|
||||
$url = $ofdbscraperServer.'/view.php?page=suchergebnis&SText='.urlencode($title);
|
||||
switch($searchType)
|
||||
{
|
||||
default :
|
||||
case 'text': {
|
||||
$url = $url.'&Kat=All'; break;
|
||||
}
|
||||
case 'ean' : {
|
||||
$url = $url.'&Kat=EAN'; break;
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content overview URL
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbscraperContentUrl($id)
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
global $ofdbscraperIdPrefix;
|
||||
|
||||
$id = preg_replace('/^'.$ofdbscraperIdPrefix.'/', '', $id);
|
||||
list($id, $vid) = explode("-", $id, 2);
|
||||
return $ofdbscraperServer.'/view.php?page=film&fid='.$id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content detail URL
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbscraperDetailUrl($id)
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
return $ofdbscraperServer.'/view.php?page=film_detail&fid='.$id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get explicit version URL
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @param string $vid The movie's version id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbscraperVersionUrl($id, $vid)
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
return $ofdbscraperServer.'/view.php?page=fassung&fid='.$id.'&vid='.$vid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content description URL
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @param string $sid The movie's description id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbscraperDescriptionUrl($id, $sid)
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
return $ofdbscraperServer.'/view.php?page=inhalt&fid='.$id.'&sid='.$sid;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search a Movie
|
||||
*
|
||||
* Searches for a given title on the OfDB and returns the found links in
|
||||
* an array
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string The search string
|
||||
* @return array Associative array with id and title
|
||||
*/
|
||||
function ofdbscraperSearch($title, $searchType = 'title')
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
global $ofdbscraperIdPrefix;
|
||||
global $CLIENTERROR;
|
||||
global $cache;
|
||||
|
||||
// auto switch to ean Mode if title is exactly 13 digits
|
||||
if (preg_match('#^\s*[0-9]{13}\s*$#',$title)) $searchType = 'ean';
|
||||
|
||||
// search for series
|
||||
$resp = httpClient(ofdbscraperSearchUrl($title, $searchType), $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
# dump($resp);
|
||||
|
||||
// add encoding
|
||||
$ary['encoding'] = $resp['encoding'];
|
||||
|
||||
if (preg_match_all('/<br>[0-9]+\.\s*<a href="film\/([0-9]+),[^"]*" onmouseover="[^"]*"[^>]*>([^<]*)<font.*?\/font> \(([\/\-0-9]+)\)<\/a>/', $resp['data'], $data, PREG_SET_ORDER))
|
||||
{
|
||||
foreach ($data as $row) {
|
||||
$info['id'] = $ofdbscraperIdPrefix.$row[1];
|
||||
$info['title'] = trim($row[2]).' ('.$row[3].')';
|
||||
$ary[] = $info;
|
||||
}
|
||||
}
|
||||
if (preg_match_all('/<br>[0-9]+\.\s*<a href="film\/([0-9]+),[^"]*" onmouseover="[^"]*"><b>([^<]*)<.*?<a href="view\.php\?page=fassung.*?fid=[0-9]+.*?vid=([0-9]+)" onmouseover="[^"]*">([^<]*)</i', $resp['data'], $data, PREG_SET_ORDER))
|
||||
{
|
||||
foreach ($data as $row) {
|
||||
$info['id'] = $ofdbscraperIdPrefix.$row[1]."-".$row[3];
|
||||
$info['title'] = trim($row[2]).' - '.$row[4];
|
||||
$ary[] = $info;
|
||||
}
|
||||
}
|
||||
// do not return an array which contains only an encoding attribute
|
||||
if (count($ary) < 2) return array();
|
||||
|
||||
return $ary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the data for a given OfDB id
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param int OfDB id
|
||||
* @return array Result data
|
||||
*/
|
||||
function ofdbscraperData($id)
|
||||
{
|
||||
global $CLIENTERROR;
|
||||
global $ofdbscraperServer;
|
||||
global $ofdbscraperIdPrefix;
|
||||
global $cache;
|
||||
global $config;
|
||||
|
||||
$id = preg_replace('/^'.$ofdbscraperIdPrefix.'/', '', $id);
|
||||
list($id, $vid) = explode("-", $id, 2);
|
||||
|
||||
$data = array(); //result
|
||||
$ary = array(); //temp
|
||||
$ary2 = array(); //temp2
|
||||
|
||||
// Fetch Mainpage
|
||||
$resp = httpClient(ofdbscraperContentUrl($id), $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// add encoding
|
||||
$data['encoding'] = $resp['encoding'];
|
||||
|
||||
// add engine ID -> important for non edit.php refetch
|
||||
$data['imdbID'] = $ofdbscraperIdPrefix.$id;
|
||||
|
||||
$resp['data'] = preg_replace('/[\r\n\t]/',' ', $resp['data']);
|
||||
|
||||
// Titles / Year
|
||||
preg_match('/<title>(.*?)<\/title>/i', $resp['data'], $ary);
|
||||
$ary[1] = preg_replace('/^OFDb[\s-]*/', '', $ary[1]);
|
||||
$ary[1] = preg_replace('/\[.*\]/', ' ', $ary[1]);
|
||||
if (preg_match('/\(([0-9]*)\)/i',$ary[1],$ary2))
|
||||
{
|
||||
$data['year'] = trim($ary2[1]);
|
||||
}
|
||||
$ary[1] = preg_replace('/\([0-9]*\)/', ' ', $ary[1]);
|
||||
$ary[1] = preg_replace('/\s{2,}/s', ' ', $ary[1]);
|
||||
|
||||
// check if there is a comma sperated article at the end
|
||||
if (preg_match('#(.*),\s*(A|The|Der|Die|Das|Ein|Eine|Einer)\s*$#i',$ary[1],$subRes)) {
|
||||
$ary[1] = $subRes[2].' '.$subRes[1];
|
||||
}
|
||||
|
||||
list($t,$s) = explode(" - ",trim($ary[1]),2);
|
||||
$data['title'] = trim($t);
|
||||
$data['subtitle'] = trim($s);
|
||||
|
||||
// Original Title
|
||||
if (preg_match('/Originaltitel.*?<b>(.*?)</i', $resp['data'], $ary))
|
||||
{
|
||||
$data['orgtitle'] .= trim($ary[1]);
|
||||
}
|
||||
|
||||
// Country
|
||||
if (preg_match('/>Herstellungsland:.*?<b><a.*?>(.*?)<\/a>/i', $resp['data'], $ary))
|
||||
{
|
||||
$data['country'] .= trim($ary[1]);
|
||||
}
|
||||
|
||||
// Rating
|
||||
if (preg_match('/Note: <span itemprop="ratingValue">([0-9\.]+)/', $resp['data'], $ary)) {
|
||||
// if (preg_match('/<br>Note:\s*([0-9\.]+)/', $resp['data'], $ary)) {
|
||||
$data['rating'] = $ary[1];
|
||||
}
|
||||
|
||||
// Cover URL
|
||||
if (preg_match('#<img src="(http://img.ofdb.de/film/na.gif)"#i', $resp['data'], $ary))
|
||||
{
|
||||
$data['coverurl'] = "";
|
||||
}
|
||||
else if (preg_match('#<img src="(http://img.ofdb.de/film/.*?\.jpg)"#i', $resp['data'], $ary))
|
||||
{
|
||||
$data['coverurl'] = trim($ary[1]);
|
||||
}
|
||||
|
||||
// Fetch first VID if none already selected
|
||||
if (!$vid)
|
||||
{
|
||||
if (preg_match_all('/view\.php\?page=fassung&fid='.$id.'&vid=([0-9]+)".*?class="Klein">(.*?)</i', $resp['data'], $ary, PREG_SET_ORDER))
|
||||
{
|
||||
foreach($ary as $row)
|
||||
{
|
||||
if (trim($row[2]) == "K" || trim($row[2]) == "KV") // Check if there is a good result
|
||||
{
|
||||
$vid=$row[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$vid) // Still empty -> Take the first one
|
||||
{
|
||||
$vid=$ary[1][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IMDB ID
|
||||
$data['imdbID'] = $ofdbscraperIdPrefix."$id-$vid";
|
||||
|
||||
// Fetch Plot
|
||||
if (preg_match('#href="(plot/[^"]+)"#i', $resp['data'], $ary))
|
||||
{
|
||||
$subresp = httpClient($ofdbscraperServer.'/'.$ary[1], $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $subresp['error']."\n";
|
||||
$subresp['data'] = preg_replace('/[\r\n\t]/',' ', $subresp['data']);
|
||||
//ofdbDbg($subresp['data'],false);
|
||||
if (preg_match('#</b><br><br>(.*?)</font></p>#i', $subresp['data'], $ary))
|
||||
{
|
||||
|
||||
$ary[1] = preg_replace('/\s{2,}/s', ' ', $ary[1]);
|
||||
$ary[1] = preg_replace('#<(br|p)[ /]*>#i', "\n", $ary[1]);
|
||||
$data['plot'] = trim($ary[1]);
|
||||
//$data['plot'] = "aeääääaaaä";
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch Details
|
||||
$resp = httpClient(ofdbscraperDetailUrl($id), $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
$resp['data'] = preg_replace('/[\r\n\t]/',' ', $resp['data']);
|
||||
|
||||
// Director
|
||||
if (preg_match('/<b><i>Regie<\/i><\/b>.*?<table.*?>(.*?)<\/table>/i', $resp['data'], $ary))
|
||||
{
|
||||
if (preg_match_all('/class="Daten"><a.*?>(.*?)<\/a>/i',$ary[1],$ary2, PREG_SET_ORDER))
|
||||
{
|
||||
foreach ($ary2 as $row)
|
||||
{
|
||||
$data['director'] .= trim($row[1]).', ';
|
||||
}
|
||||
$data['director'] = preg_replace('/, $/', '', $data['director']);
|
||||
}
|
||||
}
|
||||
|
||||
// Cast
|
||||
if (preg_match('/<b><i>Darsteller<\/i><\/b>.*?<table.*?>(.*)<\/table>/', $resp['data'], $ary))
|
||||
{
|
||||
// dirty workaround for (.*?) failed on very long match groups issue (tested at PHP 5.2.5.5)
|
||||
// e.g.: ofdb:7749-111320 (Angel - Jäger der Finsternis)
|
||||
$ary[1] = preg_replace('#</table.*#','',$ary[1]);
|
||||
|
||||
if (preg_match_all('/class="Daten"><a(.*?)">(.*?)<\/a>.*?<\/td> <td.*?<\/td> <td[^>]*>(.*?)<\/td>/i',$ary[1],$ary2, PREG_SET_ORDER))
|
||||
{
|
||||
foreach ($ary2 as $row)
|
||||
{
|
||||
$actor = trim(strip_tags($row[2]));
|
||||
|
||||
$actorid = "";
|
||||
if (!empty($row[1]))
|
||||
{
|
||||
if (preg_match('#href="view.php\?page=person&id=([0-9]*)#i', $row[1], $idAry))
|
||||
{
|
||||
$actorid = $ofdbscraperIdPrefix.$idAry[1];
|
||||
}
|
||||
}
|
||||
|
||||
$character = "";
|
||||
if (!empty($row[3]))
|
||||
{
|
||||
if (preg_match('#class="Normal">... ([^<]*)<#i', $row[3], $charAry))
|
||||
{
|
||||
$character = trim(strip_tags($charAry[1]));
|
||||
}
|
||||
}
|
||||
$data['cast'] .= "$actor::$character::$actorid\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Genres
|
||||
$genres = array(
|
||||
'Amateur' => '',
|
||||
'Eastern' => '',
|
||||
'Experimentalfilm' => '',
|
||||
'Mondo' => '',
|
||||
'Kampfsport' => 'Sport',
|
||||
'Biographie' => 'Biography',
|
||||
'Katastrophen' => 'Thriller',
|
||||
'Krimi' => 'Crime',
|
||||
'Science-Fiction' => 'Sci-Fi',
|
||||
'Kinder-/Familienfilm' => 'Family',
|
||||
'Dokumentation' => 'Documentary',
|
||||
'Action' => 'Action',
|
||||
'Drama' => 'Drama',
|
||||
'Abenteuer' => 'Adventure',
|
||||
'Historienfilm' => 'History',
|
||||
'Kurzfilm' => 'Short',
|
||||
'Liebe/Romantik' => 'Romance',
|
||||
'Heimatfilm' => 'Romance',
|
||||
'Grusel' => 'Horror',
|
||||
'Horror' => 'Horror',
|
||||
'Erotik' => 'Adult',
|
||||
'Hardcore' => 'Adult',
|
||||
'Sex' => 'Adult',
|
||||
'Musikfilm' => 'Musical',
|
||||
'Animation' => 'Animation',
|
||||
'Fantasy' => 'Fantasy',
|
||||
'Trash' => 'Horror',
|
||||
'Komödie' => 'Comedy',
|
||||
'Krieg' => 'War',
|
||||
'Mystery' => 'Mystery',
|
||||
'Thriller' => 'Thriller',
|
||||
'Tierfilm' => 'Documentary',
|
||||
'Western' => 'Western',
|
||||
'TV-Serie' => '',
|
||||
'TV-Mini-Serie' => '',
|
||||
'Sportfilm' => 'Sport',
|
||||
'Splatter' => 'Horror',
|
||||
'Manga/Anime' => 'Animation'
|
||||
);
|
||||
if (preg_match('/>Genre\(s\)\:.*?<b>(.*?)<\/b>/i', $resp['data'], $ary))
|
||||
{
|
||||
if (preg_match_all('/<a.*?>(.*?)<\/a>/i',$ary[1],$ary2, PREG_SET_ORDER))
|
||||
{
|
||||
foreach($ary2 as $row) {
|
||||
$genre = trim(html_entity_decode($row[1]));
|
||||
$genre = strip_tags($genre);
|
||||
if (!$genre) continue;
|
||||
if (isset($genres[$genre])) $data['genres'][] = $genres[$genre];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch Version
|
||||
$resp = httpClient(ofdbscraperVersionUrl($id, $vid), $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
$resp['data'] = preg_replace('/[\r\n\t]/',' ', $resp['data']);
|
||||
|
||||
// FSK
|
||||
$fsks = array(
|
||||
'FSK o.A.' => '0',
|
||||
'FSK 6' => '6',
|
||||
'FSK 12' => '12',
|
||||
'FSK 16' => '16',
|
||||
'FSK 18' => '18',
|
||||
'Keine Jugendfreigabe' => '18',
|
||||
'SPIO/JK' => '18',
|
||||
'juristisch geprüft' => '',
|
||||
'ungeprüft' => ''
|
||||
);
|
||||
if (preg_match('/>Freigabe:<.*?<b>(.*?)<\/tr>/i', $resp['data'], $ary))
|
||||
{
|
||||
$fsk = trim(html_entity_decode($ary[1]));
|
||||
$fsk = strip_tags($fsk);
|
||||
if (isset($fsks[$fsk])) $data['fsk'] = $fsks[$fsk];
|
||||
}
|
||||
|
||||
// Languages
|
||||
// Languages (as Array)
|
||||
$laguages = array(
|
||||
'arabisch' => 'arabic',
|
||||
'bulgarisch' => 'bulgarian',
|
||||
'chinesisch' => 'chinese',
|
||||
'tschechisch' => 'czech',
|
||||
'dänisch' => 'danish',
|
||||
'holändisch' => 'dutch',
|
||||
'englisch' => 'english',
|
||||
'französisch' => 'french',
|
||||
'deutsch' => 'german',
|
||||
'griechisch' => 'greek',
|
||||
'ungarisch' => 'hungarian',
|
||||
'isländisch' => 'icelandic',
|
||||
'indisch' => 'indian',
|
||||
'israelisch' => 'israeli',
|
||||
'italienisch' => 'italian',
|
||||
'japanisch' => 'japanese',
|
||||
'koreanisch' => 'korean',
|
||||
'norwegisch' => 'norwegian',
|
||||
'polnisch' => 'polish',
|
||||
'portugisisch' => 'portuguese',
|
||||
'rumänisch' => 'romanian',
|
||||
'russisch' => 'russian',
|
||||
'serbisch' => 'serbian',
|
||||
'spanisch' => 'spanish',
|
||||
'schwedisch' => 'swedish',
|
||||
'thailändisch' => 'thai',
|
||||
'türkisch' => 'turkish',
|
||||
'vietnamesisch' => 'vietnamese',
|
||||
'kantonesisch' => 'cantonese',
|
||||
'katalanisch' => 'catalan',
|
||||
'zypriotisch' => 'cypriot',
|
||||
'zyprisch' => 'cypriot',
|
||||
'esperanto' => 'esperanto',
|
||||
'gälisch' => 'gaelic',
|
||||
'hebräisch' => 'hebrew',
|
||||
'hindi' => 'hindi',
|
||||
'jüdisch' => 'jewish',
|
||||
'lateinisch' => 'latin',
|
||||
'mandarin' => 'mandarin',
|
||||
'serbokroatisch' => 'serbo-croatian',
|
||||
'somalisch' => 'somali'
|
||||
);
|
||||
$lang_list = array();
|
||||
|
||||
// Runtime
|
||||
if (preg_match('/>Laufzeit:<.*?<b>(.*?)\s*Min/i', $resp['data'], $ary))
|
||||
{
|
||||
$ary[1] = preg_replace('/:.*/','', $ary[1]);
|
||||
$data['runtime'] = trim($ary[1]);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Url to visit OFDB for a specific actor
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $name The actor's name
|
||||
* @param string $id The actor's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbscraperActorUrl($name, $id)
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
global $ofdbscraperIdPrefix;
|
||||
|
||||
if ($id) {
|
||||
$id = preg_replace('/^'.$ofdbscraperIdPrefix.'/', '', $id);
|
||||
} else {
|
||||
$id = ofdbscraperGetActorId($name);
|
||||
}
|
||||
|
||||
// now we have for shure an id
|
||||
return ($id!=0) ? $ofdbscraperServer.'/view.php?page=person&id='.$id : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Actor-Details
|
||||
*
|
||||
* Find image and detail URL for actor.
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $name Name of the actor
|
||||
* @param string $id Prefixed ofdb actor id
|
||||
* @return array array with Actor-URL and Thumbnail
|
||||
*/
|
||||
function ofdbscraperActor($name, $id)
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
|
||||
if ($id) {
|
||||
$id = preg_replace('/^'.$ofdbscraperIdPrefix.'/', '', $id);
|
||||
} else {
|
||||
$id = ofdbscraperGetActorId($name);
|
||||
}
|
||||
|
||||
// now we have for shure an id
|
||||
$folderId = ($id < 1000) ? 0 : substr($id,0,strlen($id)-3);
|
||||
|
||||
$imgUrl = $ofdbscraperServer.'/images/person/'.$folderId.'/'.$id.'.jpg';
|
||||
|
||||
$ary = array();
|
||||
$ary[0][0] = ofdbscraperActorUrl($name, $id);
|
||||
$ary[0][1] = $imgUrl;
|
||||
return $ary;
|
||||
}
|
||||
|
||||
function ofdbscraperGetActorId($name)
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
|
||||
// try to guess the id -> first actor found with this name
|
||||
$url = $ofdbscraperServer.'/view.php?page=liste&Name='.urlencode(html_entity_decode_all($name));
|
||||
$resp = httpClient($url, $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
$resp['data'] = preg_replace('/[\r\n\t]/',' ', $resp['data']);
|
||||
|
||||
return (preg_match('#view.php?page=person&id=([0-9]+)#i', $resp['data'], $ary)) ? $ary[1] : 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get an array of all previous prefixes for the ImdbId
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @return array Associative array with ImdbId prefixes
|
||||
*/
|
||||
function ofdbscraperImdbIdPrefixes()
|
||||
{
|
||||
global $ofdbscraperIdPrefix;
|
||||
return array($ofdbscraperIdPrefix);
|
||||
}
|
||||
|
||||
function ofdbscraperDbg($text,$append = true)
|
||||
{
|
||||
file_append('debug.txt', $text, $append);
|
||||
}
|
||||
?>
|
||||
74
videodb/engines/youtube.php
Normal file
74
videodb/engines/youtube.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
// DEFUNCT, maybe implement new api since current code doesn't work anymore: https://developers.google.com/youtube/v3/docs/search
|
||||
|
||||
/**
|
||||
* youtube.com trailer search
|
||||
*
|
||||
* Search trailers on youtube.com
|
||||
*
|
||||
* @package Engines
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @author Adam Benson <precarious_panther@bigpond.com>
|
||||
* @link http://www.youtube.com YouTube
|
||||
* @version $Id: youtube.php,v 1.9 2012/08/10 16:07:53 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './core/httpclient.php';
|
||||
|
||||
define('YOUTUBE_CLIENT_ID', 'ytapi-AndreasGoetz-videodb-g7dk2dh6-0');
|
||||
define('YOUTUBE_DEVELOPER_KEY', 'AI39si7znfvxGu-6OfT-PIPHxUJbAy429l63_jnWSThlJ7Hitv_gmCpJ9cE_HCnH7PDvSLgthw4wEZ5wSrw139DPLbbmLb50GQ');
|
||||
|
||||
// http://gdata.youtube.com/feeds/api/videos?client=ytapi-AndreasGoetz-videodb-g7dk2dh6-0&key=AI39si7znfvxGu-6OfT-PIPHxUJbAy429l63_jnWSThlJ7Hitv_gmCpJ9cE_HCnH7PDvSLgthw4wEZ5wSrw139DPLbbmLb50GQ&v=2&start-index=1&max-results=10&q=alien
|
||||
|
||||
/**
|
||||
* Get meta information about the engine
|
||||
*/
|
||||
function youtubeMeta()
|
||||
{
|
||||
return array('name' => 'YouTube', 'stable' => 1, 'php' => '5.0', 'capabilities' => array('trailer'));
|
||||
}
|
||||
|
||||
function youtubeHasTrailer($title)
|
||||
{
|
||||
return count(youtubeSearch($title)) > 0;
|
||||
}
|
||||
|
||||
function normalize($str)
|
||||
{
|
||||
return preg_replace('/[^a-zäöüA-ZÄÖÜ0-9\s]/', '', $str);
|
||||
}
|
||||
|
||||
function youtubeSearch($title)
|
||||
{
|
||||
$trailers = array();
|
||||
$title = normalize($title);
|
||||
$trailerquery = $title." trailer";
|
||||
|
||||
$youtubeurl = "http://gdata.youtube.com/feeds/api/videos?client=".YOUTUBE_CLIENT_ID."&key=".YOUTUBE_DEVELOPER_KEY."&v=2&".
|
||||
"q=".urlencode($trailerquery)."&start-index=1&max-results=10";
|
||||
|
||||
$resp = httpClient($youtubeurl, true);
|
||||
if (!$resp['success']) return $trailers;
|
||||
|
||||
$xml = simplexml_load_string($resp['data']);
|
||||
|
||||
// obtain namespaces
|
||||
$namespaces = $xml->getNameSpaces(true);
|
||||
|
||||
foreach ($xml->entry as $trailer)
|
||||
{
|
||||
$media = $trailer->children($namespaces['media']);
|
||||
$yt = $media->group->children($namespaces['yt']);
|
||||
$id = $yt->videoid;
|
||||
|
||||
// API filtering code removed
|
||||
$trailers[] = array('id' => (string) $id,
|
||||
'src' => (string) $trailer->content['src'],
|
||||
'title' => (string) $trailer->title);
|
||||
if (count($trailers) >= 10) break;
|
||||
}
|
||||
|
||||
return $trailers;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user