#!/usr/bin/perl
##############################
##  AutoGallery Pro v3.0.x  ##
#######################################################################
##  submit.cgi - Handle general gallery submissions from webmasters  ##
#######################################################################

use Fcntl qw(:DEFAULT :flock);


eval
{
    require 'common.pl';
    require 'agp.pl';
    require 'http.pl';
    Header("Content-type: text/html\n\n");
    main();
};


if( $@ )
{
    Error("$@", 'submit.cgi');
}



sub main
{
    ParseRequest(1);


    ## Display the submissions closed page
    if( !$SUBMIT_STATUS )
    {
        ParseTemplate('submit_closed.tpl');
        exit;
    }


    if( $ENV{'REQUEST_METHOD'} eq 'GET' )
    {
        DisplaySubmit();
    }
    else
    {
        ProcessPost();
    }
}



## Display the gallery submission page
sub DisplaySubmit
{
    my %number    = ();
    my $total     = 0;
    my $row       = undef;
    my $available = 0;

    ## Add categories to the template
    GetCategoryList();

    if( !scalar(@CATEGORIES) )
    {
        SubmitError('E_NO_CATEGORIES');
    }

    for( @CATEGORIES )
    {
        my $H = {};

        $H->{'Category'} = $_;

        TemplateAdd('Categories', $H);
    }

    $T{'Submit_Status'} = $SUBMIT_STATUS;
    $T{'Width'}         = $THUMB_WIDTH;
    $T{'Height'}        = $THUMB_HEIGHT;

    ParseTemplate('submit_main.tpl');
}



## Display the thumbnail cropping page
sub DisplayCrop
{
    my $results = shift;

    $T{'Image_URL'}    = "$THUMB_URL/$T{'Image_Name'}";
    $T{'Thumb_URL'}    = $THUMB_URL;
    $T{'Thumb_Height'} = $THUMB_HEIGHT;
    $T{'Thumb_Width'}  = $THUMB_WIDTH;
    $T{'Encode_URL'}   = URLEncode($F{'End_URL'});

    if( !$F{'Preview'} )
    {
        for( my $i = 0; $i < scalar(@{$results->{'Thumbs'}}); $i++ )
        {
            my $H = {};

            $H->{'Thumbnail_URL'} = URLEncode($results->{'Thumbs'}[$i]);
            $H->{'Image_URL'}     = $results->{'Type'} eq 'Pictures' ? URLEncode($results->{'Content'}[$i]) : $H->{'Thumbnail_URL'};

            TemplateAdd('Thumbs', $H);
        }
    }   

    ParseTemplate('submit_crop.tpl');
}




## Crop the thumbnail
sub CropThumbnail
{
    my $gallery  = undef;

    if( -e "$THUMB_DIR/$F{'Gallery_ID'}.jpg" )
    {
        unlink("$THUMB_DIR/$F{'Image_Name'}") if( -e "$THUMB_DIR/$F{'Image_Name'}" );
        SubmitError('E_HAS_THUMB');
    }

    require 'image.pl';

    ## Get gallery information
    $gallery = DBSelect("$DDIR/dbs/$F{'Database'}", $F{'Gallery_ID'});

    ## Crop and save the thumbnail
    ManualResize("$THUMB_DIR/$F{'Image_Name'}", $gallery->{'Category'});
    rename("$THUMB_DIR/$F{'Image_Name'}", "$THUMB_DIR/$F{'Gallery_ID'}.jpg");
    Mode(0666, "$THUMB_DIR/$F{'Gallery_ID'}.jpg");

    HashToTemplate($gallery);

    ## Send confirmation e-mail
    if( $O_CONFIRM_EMAIL )
    {
        $T{'To'}          = $gallery->{'Email'};
        $T{'From'}        = $ADMIN_EMAIL;
        $T{'Confirm_ID'}  = $gallery->{'Confirm_ID'};
        $T{'Confirm_URL'} = "$CGI_URL/confirm.cgi";

        Mail("$TDIR/email_confirm.tpl");
    }

    $T{'Has_Thumb'}     = 1;
    $T{'Thumbnail_URL'} = "$THUMB_URL/$F{'Gallery_ID'}.jpg";
    $T{'Status'}        = $F{'Database'};

    ## Display the submit_complete template
    ParseTemplate('submit_complete.tpl');
}

#moshe Sat Oct  1 13:36:01 2005 62.0.132.43

## Process HTTP POST requests
sub ProcessPost
{
    my %map = ('D', 'DisplayUpload', 'U', 'UploadThumbnail', 'C', 'CropThumbnail', 'A', 'AccountData');

    if( $map{$F{'Run'}} )
    {
        &{$map{$F{'Run'}}};
    }
    else
    {
        ProcessSubmission();
    }
}



## Process a gallery submission
sub ProcessSubmission
{
    my $hex_ip        = IP2Hex($ENV{'REMOTE_ADDR'});
    my $category      = undef;
    my $results       = undef;
    my $code          = undef;
    my $account       = undef;
    my $database      = 'pending';
    my $blacklisted   = 0;
    my $whitelisted   = 0;
    my $min_thumbs    = 0;
    my $max_thumbs    = 0;
    my $min_size      = 0;

    $F{'Submit_Date'}   = $DB_DATE;
    $F{'Approve_Date'}  = undef;
    $F{'Display_Date'}  = undef;
    $F{'Display_Stamp'} = undef;
    $F{'Icons'}         = undef;
    $F{'Has_Thumb'}     = undef;
    $F{'Scanned'}       = 1;
    $F{'Account_ID'}    = undef;
    $F{'CPanel_ID'}     = undef;
    $F{'Confirm_ID'}    = undef;
    $F{'Submit_IP'}     = $ENV{'REMOTE_ADDR'};


    ## Convert AutoGallery Pro v2.x.x form fields
    if( !$F{'Gallery_URL'} )
    {
        $F{'Username'}    = $F{'user'};
        $F{'Password'}    = $F{'pass'};   
        $F{'Gallery_URL'} = $F{'gurl'};
        $F{'Category'}    = $F{'cat'};
        $F{'Thumbnails'}  = $F{'pics'} || $F{'num'};
        $F{'Code'}        = $F{'phrase'};
        $F{'Email'}       = $F{'email'} || "partner\@$ENV{'HTTP_HOST'}";
        $F{'Description'} = $F{'desc'};
        $F{'Preview'}     = $F{'upfile'};

        if( $F{'turl'} )
        {
            $F{'Thumb_Source'} = 'Select';
        }
        elsif( $F{'upfile'} )
        {
            $F{'Thumb_Source'} = 'Upload';
        }
    }


    ## Check form input
    SubmitError('E_BAD_EMAIL')                if( $F{'Email'} !~ /^[\w\d][\w\d\,\.\-]*\@([\w\d\-]+\.)+([a-zA-Z]+)$/ );
    SubmitError('E_BAD_URL')                  if( $F{'Gallery_URL'} !~ /^http:\/\/[\w\d\-\.]+\.[\w\d\-\.]+/ );
    SubmitError('E_REQUIRED', 'DESCRIPTION')  if( $O_NEED_DESC && !$F{'Description'} );
    SubmitError('E_REQUIRED', 'NICKNAME')     if( $O_NEED_NAME && !$F{'Nickname'} );
    SubmitError('E_TOO_SHORT', 'DESCRIPTION') if( ($O_NEED_DESC || $F{'Description'}) && length($F{'Description'}) < $MIN_LENGTH );
    SubmitError('E_TOO_LONG', 'DESCRIPTION')  if( ($O_NEED_DESC || $F{'Description'}) && length($F{'Description'}) > $MAX_LENGTH );
    SubmitError('E_NO_PASSWORD')              if( $SUBMIT_STATUS eq 'Password' && !$F{'Password'} );



    ## If username/password was entered, check it
    if( $F{'Username'} || $F{'Password'} )
    {
        $account = DBSelect("$DDIR/dbs/accounts", $F{'Username'});

        if( !$account || $account->{'Password'} ne $F{'Password'} )
        {
            SubmitError('E_BAD_PASSWORD');
        }

        
        ## If global auto-approve is off, determine whether to auto-approve this gallery
        if( !$O_AUTO_APPROVE )
        {
            $O_AUTO_APPROVE = $account->{'Auto_Approve'};
        }

        $F{'Icons'}      = $account->{'Icons'};
        $F{'Account_ID'} = $account->{'Account_ID'};
    }


    ## Check the submit code
    if( ($O_GEN_STRING && !$F{'Password'}) || ($O_TRUST_STRING && $F{'Password'}) )
    {
        $code = DBSelect("$DDIR/dbs/codes", $hex_ip);

        if( !$code || $code->{'Code'} ne $F{'Code'} )
        {
            SubmitError('E_BAD_CODE');
        }
    }


    ## Check for good category
    $category = DBSelect("$DDIR/dbs/categories", $F{'Category'});


    if( !$category )
    {
        SubmitError('E_BAD_CATEGORY');
    }


    ## Check the number of already submitted galleries
    ## and for duplicate gallery URLs
    CheckNumberSubmitted($account);


    ## See if the gallery is whitelisted
    $whitelisted = IsWhitelisted($F{'Gallery_URL'}); 


    ## Scan the gallery
    $results = ScanGallery($F{'Gallery_URL'}, $category, $account, $whitelisted);


    ## Setup the ending URL if a forward was done
    $F{'End_URL'} = $results->{'End_URL'};


    ## Setup min/max values based on the gallery type
    $min_thumbs = $category->{"Min_$results->{'Type'}"}; 
    $max_thumbs = $category->{"Max_$results->{'Type'}"}; 
    $min_size   = $category->{"Size_$results->{'Type'}"};


    ## Broken gallery URL
    if( $results->{'Errstr'} )
    {
        SubmitError('E_BROKEN_URL', $results->{'Errstr'});
    }

    
    ## Check the blacklist
    $F{'Submit_IP'} = $ENV{'REMOTE_ADDR'};

    if( !$whitelisted && !$account->{'Blacklist'} )
    {
        $blacklisted = IsBlacklisted(\%F);
    }

    if( $blacklisted && !$O_TRANSPARENT )
    {
        SubmitError('E_BLACKLISTED', $blacklisted->{'Item'});
    }


    ## Check for banned HTML
    if( $results->{'Has_Banned'} )
    {
        if( !$account->{'Account_ID'} || !$account->{'HTML'} )
        {
            $blacklisted = 1;
            SubmitError('E_BAD_HTML') if( !$O_TRANSPARENT )
        }
    }


    ## Check reciprocal link
    if( (!$account->{'Account_ID'} && $O_NEED_RECIP) || ($account->{'Recip'}) )
    {
        SubmitError('E_NO_RECIP') if( !$results->{'Has_Recip'} );
    }


    ## Override the submitted thumbnail count
    if( $O_COUNT_THUMBS )
    {
        $F{'Thumbnails'} = $results->{'Thumbnails'};
    }


    ## Make sure thumb count is within the min/max
    SubmitError('E_MIN_THUMBS', $min_thumbs) if( $F{'Thumbnails'} < $min_thumbs );
    SubmitError('E_MAX_THUMBS', $max_thumbs) if( $F{'Thumbnails'} > $max_thumbs );


    ## Check the number of external links
    if( $O_CHECK_LINKS )
    {
        SubmitError('E_EXCESSIVE_LINKS', $LINKS) if( $results->{'Links'} > $LINKS );
    }


    ## Check the mimimum content size
    if( $O_CHECK_SIZE )
    {
        SubmitError('E_MIN_SIZE', "$min_size bytes") if( $results->{'Size'} <= $min_size );
    }


    ## Check download speed
    if( $O_CHECK_SPEED )
    {
        SubmitError('E_TOO_SLOW', "$SPEED KB/s") if( $results->{'Speed'} <= $SPEED );
    }


    ## Change the text case of the description
    ChangeCase(\$F{'Description'}, $TEXT_CASE);
  


    ## If the source was an upload, see if a thumb was actually provided
    if( $F{'Thumb_Source'} eq 'Upload' )
    {
        ## No thumbnail uploaded
        if( !$F{'Preview'} )
        {
            if( $O_SELECT_THUMB )
            {
                $THUMB_NO_MATCH = 'AutoCrop';
                $F{'Preview'}   = SelectThumbnail($results);
            }
            elsif( $O_NEED_THUMB )
            {
                SubmitError('E_NO_THUMB');
            }
        }

        ## Make sure browser is capable of manual crop
        if( $THUMB_NO_MATCH eq 'ManualCrop' && BadBrowser() )
        {
            $THUMB_NO_MATCH = 'AutoCrop';
        }
    }
    ## Automatically selecting a thumbnail
    elsif( $F{'Thumb_Source'} eq 'Select' )
    {
        $THUMB_NO_MATCH = 'AutoCrop';
        $F{'Preview'}   = SelectThumbnail($results);
    }
    ## Select and crop a thumbnail
    else
    {
        $F{'Preview'} = undef;
    }


    ## Not allowing thumbnails
    if( !$O_ALLOW_THUMB )
    {
        $F{'Thumb_Source'} = 'Select';
        $F{'Preview'}      = undef;
    }


    if( !$HAVE_MAGICK )
    {
        $THUMB_NO_MATCH = 'Reject';
    }


    if( $F{'Preview'} )
    {
        require 'size.pl';

        my($x, $y, $id) = imgsize(\$F{'Preview'});

        if( !$x )
        {
            SubmitError('E_BAD_IMAGE');
        }

        ## Dimensions or filesize are not valid
        if( ($O_FORCE_DIMS && ($x != $THUMB_WIDTH || $y != $THUMB_HEIGHT)) || ($x > $THUMB_WIDTH || $y > $THUMB_HEIGHT) || (length($F{'Preview'}) > $THUMB_SIZE) )
        {
            if( $THUMB_NO_MATCH eq 'AutoCrop' )
            {
                require 'image.pl';
                AutoResize(\$F{'Preview'}, "t$hex_ip", $F{'Category'});
            }
            elsif( $THUMB_NO_MATCH eq 'Reject' )
            {   
                SubmitError('E_THUMB_SIZE');
            }
            else
            {
                $F{'Thumb_Source'} = 'Crop';
                FileWrite("$THUMB_DIR/t$hex_ip.jpg", $F{'Preview'});
            }
        }

        ## Good dimensions
        else
        {
            FileWrite("$THUMB_DIR/t$hex_ip.jpg", $F{'Preview'});

            if( $O_ANNOTATE )
            {
                require 'image.pl';
                Annotate("$THUMB_DIR/t$hex_ip.jpg", $F{'Category'});
            }
        }

        $F{'Has_Thumb'} = 1;
        $F{'Preview'}   = 1;
    }

    
    $F{'Gallery_ID'} = GetGalleryID();


    ## Setup the status
    if( $O_CONFIRM_EMAIL )
    {
        $F{'Confirm_ID'} = int(rand(999999999));
        $database        = 'unconfirmed';
    }
    elsif( $O_AUTO_APPROVE )
    {
        $database           = 'approved';
        $F{'CPanel_ID'}     = 'Auto-Approved';
        $F{'Approve_Date'}  = $DB_DATE;
        $F{'Display_Date'}  = Date('%Y-%m-%d', '%q', ($O_TODAY ? $TIME : $TIME + 86400));
        $F{'Display_Stamp'} = $TIME;
    }


    ## Remove submit code from the database
    if( $F{'Code'} )
    {
        DBDelete("$DDIR/dbs/codes", $hex_ip);
    }


    ## Transparently accept blacklisted galleries
    if( $blacklisted )
    {
        FileRemove("$THUMB_DIR/t$hex_ip.jpg") if( -e "$THUMB_DIR/t$hex_ip.jpg" );
        $T{'Gallery_ID'} = int(rand(9999)) + 287;
        ParseTemplate('submit_complete.tpl');
        exit;
    }


    $F{'Status'}     = $database;
    $F{'Gallery_IP'} = $results->{'Gallery_IP'};
    $F{'Links'}      = $results->{'Links'};
    $F{'Has_Recip'}  = $results->{'Has_Recip'};
    $F{'Page_Bytes'} = $results->{'Bytes'};

    HashToTemplate(\%F);

    DBInsert("$DDIR/dbs/$database");

    $T{'Thumbnail_URL'} = "$THUMB_URL/$T{'Gallery_ID'}.jpg";

    ## Add to the e-mail log
    $DEL = "\n"; DBInsert("$DDIR/emails"); $DEL = '|';

    if( $F{'Thumb_Source'} eq 'Crop' )
    {
        $T{'Image_Name'} = "t$hex_ip.jpg";
        DisplayCrop($results);
    }
    else
    {
        if( -e "$THUMB_DIR/t$hex_ip.jpg" )
        {
            rename("$THUMB_DIR/t$hex_ip.jpg", "$THUMB_DIR/$T{'Gallery_ID'}.jpg");
            Mode(0666, "$THUMB_DIR/$T{'Gallery_ID'}.jpg");
        }

        if( $O_CONFIRM_EMAIL )
        {
            $T{'To'}          = $F{'Email'};
            $T{'From'}        = $ADMIN_EMAIL;
            $T{'Confirm_URL'} = "$CGI_URL/confirm.cgi";

            Mail("$TDIR/email_confirm.tpl");
        }

        ParseTemplate('submit_complete.tpl');
    }
}



## Check how many other galleries this person has submitted
## and if the gallery URL is already in the database
sub CheckNumberSubmitted
{
    my $account = shift;
    my $date    = $DB_DATE;
    my @dbs     = ('unconfirmed', 'pending', 'approved');
    my $levelup = LevelUpURL($F{'Gallery_URL'});
    my $matches = 0;

    for( @dbs )
    {
        open(DB, "$DDIR/dbs/$_") || Error("$!", "$DDIR/dbs/$_");
        flock(DB, LOCK_SH);
        for( <DB> )
        {
            my $gallery = {};

            @$gallery{@{$DB_FORMAT{'galleries'}}} = split(/\|/, $_);

            ## Check for duplicate URL
            if( $O_CHECK_DUPS && $gallery->{'Gallery_URL'} eq $F{'Gallery_URL'} )
            {
                flock(DB, LOCK_UN);
                close(DB);
                SubmitError('E_DUPLICATE');
            }

            next if( $date ne $gallery->{'Submit_Date'} );

            ## Keep a running total of the number of matches
            if( $account && $account->{'Account_ID'} eq $gallery->{'Account_ID'} )
            {
                $matches++;
            }
            elsif( $gallery->{'Email'} eq $F{'Email'} ||
                   $gallery->{'Submit_IP'} eq $F{'Submit_IP'} ||
                   $levelup eq LevelUpURL($gallery->{'Gallery_URL'}) )
            {
                $matches++;
            }
        }
        flock(DB, LOCK_UN);
        close(DB);
    }


    if( $account && $matches >= $account->{'Allowed'} )
    {
        SubmitError('E_LIMIT_REACHED');
    }
    elsif( !$account && $matches >= $MAX_PERSON )
    {
        SubmitError('E_LIMIT_REACHED');
    }
}