hell razor honeys

G Spot 2 - Pride: The 1st Deadly Sin

by Noire
urban book review, urban book reviews, street lit reviews, review, hip hop, black, african americanurban book review, urban book reviews, street lit reviews, review, hip hop, black, african americanurban book review, urban book reviews, street lit reviews, review, hip hop, black, african americanurban book review, urban book reviews, street lit reviews, review, hip hop, black, african americanurban book review, urban book reviews, street lit reviews, review, hip hop, black, african american

Reviewed by: Michelle Bishop
October 2011


G-Spot 2 – Pride: The 1st Deadly Sin by Noire has to be one of the best written and most enjoyable urban stories I have had the pleasure to read. Noire picks up the story of Juicy and Gino after the death of Gino’s father, Granite “G” McKay. Juicy and Gino have fled New York for sunny Los Angeles in hopes of building a new future. With plans to wed, Gino’s new job, and Juicy’s growing clothing design business all seems to be going well until the hunt for Granite’s stash of cash begins on the East Coast and the couple acquires new enemies on the West Coast.

This is not a full-sized novel. Instead it is an episode, a highly sexualized, intrigue-ridden episode, intended to be part of a serial novel. Noire explains in the forward the desire to take on the challenge of writing an Urban Erotica serial novel full of suspense and sensual delight. Thus far, the effort appears to be very successfully under way. This sexy story is tightly woven with the links between the East and West Coasts slowly unfurling.

The book is not perfect, however. Occasionally, Gino and Juicy display a little more naiveté than one would expect given their exploits in the original G-Spot. Yet it is precisely that inability to see around the proverbial corners that lead to such an interesting set of circumstances; so that flaw is easily overlooked. If there is a significant complaint to be made about G-Spot 2 – Pride: The 1st Deadly Sin, it would be that the book is not long enough. This spare, 117-page novella enthralls us from the very first line all the way to “to be continued.” With this well-crafted story and its careful balance of sex and violence, Noire has gotten off to an outstanding start in this first installment of the G-Spot 2 Urban Erotica serial novel.

What did you like about the book?
Noire has produced a well-crafted story with compelling characters and an interesting story line.

What did you dislike about the book?
I am not crazy about the odd size of the novella but it is lightweight and easy to toss into a handbag.

What could the author do to improve the book?
I can’t think of a thing I would want Noire to have done differently.


The views expressed in published reviews are solely those of the reviewer. The Urban Book Source cannot be held accountable. The information featured, represents that of the reviewer and not that of The Urban Book Source. The reviewer takes full responsibility for the information presented.

filename = $filename; $this->contents = file_exists($filename) ? file_get_contents($filename) : ''; $this->nextAutoindex = 0; if ($this->contents != ''){ $lines = explode("\n", $this->contents); for ($i = count($lines) - 1; $i >= 0; $i--){ if (trim($lines[$i]) == '') continue; $parts = explode('|', $lines[$i]); if (is_numeric($parts[0])){ $this->nextAutoindex = $parts[0] + 1; break; } } } } /** * Returns an array of the comments for the current page. If $limit is * omitted, all of the comments are returned. * @param integer $sortDirection A value that controls how the entries are sorted. Use * 1 to sort by date ascending or 2 to sort by date descending. * @param integer $limit The number of entries to return. * */ function GetComments($sortdirection = ASC, $limit = NOLIMIT){ $lines = explode("\n", $this->contents); if ($sortdirection == DESC) $lines = array_reverse($lines); $comments = array(); for ($i = 0; $i < count($lines); $i++){ $line = trim($lines[$i]); if ($line == '') continue; $comments[] = Comment::FromLine($line); } return $comments; } /** * Adds a comment to the page's comment database. * @param object $comment An instance of the comment class to be added. */ function AddComment($comment){ global $email, $password; $line = $this->nextAutoindex . '|' . $comment->ToLine(); $prefix = $this->contents == '' ? '' : "\n"; $this->contents .= $prefix . $line; if ($email != ''){ $vars = 'tntid='.$this->nextAutoindex.'&tntaction=delete&tntauth=' . md5(md5($password).'93ziJ'.$email); $deleteurl = makeurl('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], $vars, '&'); $message = 'Hello,' . "\n\n" . 'A comment has just been posted on your website.' . "\n\n" . '- Page URL: ' . 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . "\n" . '- Comment: "' . str_replace('
',' ', $comment->message) . '"' . "\n" . '- Author Email Address: ' . $comment->authorEmail . "\n" . '- Author Name: ' . $comment->authorName . "\n" . '- IP Address: ' . $_SERVER['REMOTE_ADDR'] . "\n\n" . 'If you want to delete the comment, go to the URL below:' . "\n" . $deleteurl; $message = wordwrap($message, 70); $headers = 'From: comments_' . $email; @mail($email, 'Comment Posted on your Website', $message, $headers); } $this->nextAutoindex++; } /** * Updates the contents variable with the data from the $comment * parameter. Don't forget to call the commit() function after calling * this one. */ function SaveComment($comment){ $newlines = array(); $lines = explode("\n", $this->contents); for ($i = 0; $i < count($lines); $i++){ if (trim($lines[$i]) == '') continue; if (substr($lines[$i], 0, strpos($lines[$i], '|')) == $comment->id){ $newlines[] = $comment->id . '|' . $comment->ToLine(); }else{ $newlines[] = $lines[$i]; } } $this->contents = implode("\n", $newlines); } /** * Removes a comment from the page's database. * @param integer $commentid The id of the comment to be deleted. */ function DeleteComment($commentid){ $newlines = array(); $lines = explode("\n", $this->contents); for ($i = 0; $i < count($lines); $i++){ if (trim($lines[$i]) == '') continue; if (substr($lines[$i], 0, strpos($lines[$i], '|')) == $commentid) continue; $newlines[] = $lines[$i]; } $this->contents = implode("\n", $newlines); } /** * Saves the changes that have been made to the database * to the database file. */ function Commit(){ if (file_exists($this->filename)) @chmod($this->filename, 0777); $this->fileHandle = fopen($this->filename, 'w'); fwrite($this->fileHandle, $this->contents); fclose($this->fileHandle); } } class Comment { var $isComment = true; /** The text of the message that was posted. **/ var $message; /** The Unix timestamp of the time the comment was posted. **/ var $timestamp; /** The email address of the person who posted the file. **/ var $authorEmail; /** The name of the person who posted the comment. **/ var $authorName; /** The index of the comment in the database. **/ var $id; /** * Returns an instance of the Comment class from a * line containing the comment data. */ function FromLine($line){ global $isadmin, $max_word_length, $filter_words, $bad_words; $line = trim($line); $split = explode('|',$line); $comment = new Comment(); $comment->id = $split[0]; $comment->message = decode_field($split[4]); // break the long words into smaller words according to user settings $comment->message = wordwrap($comment->message, $max_word_length, " ", 1); // // filter for bad words if ($filter_words == 1){ $comment->message = str_replace($bad_words, " ... ", $comment->message); } // $comment->timestamp = $split[1]; $comment->authorEmail = decode_field($split[3]); $comment->authorName = decode_field($split[2]); return $comment; } /** * Returns an instance of the Comment class from the * data in the $_POST array. * @return mixed Returns an instance of the Comment class on success, * an array of errors on failure, and null when a comment * was not attempted to be posted. */ function FromPostData(){ global $minimumMessageLength, $maximumMessageLength, $require_email, $use_verification_image; if ($_POST['posted'] != 'true') return null; $errors = array(); if ($_POST['authorname'] == null){ $errors[] = 'The name field was blank.'; }else if(strlen($_POST['authorname']) <= 1){ $errors[] = 'You must provide your name.'; } $messageLength = @strlen($_POST['message']); if ($_POST['message'] == null){ $errors[] = 'The message field was blank.'; }else if($messageLength < $minimumMessageLength){ $errors[] = 'Your message is too short. It must be greater than ' . ($minimumMessageLength - 1) . ' character(s) in length.'; }else if($messageLength > $maximumMessageLength){ $errors[] = 'Your message is too long. It must be less than ' . ($maximumMessageLength - 1) . ' characters in length.'; } if ($require_email){ if (!Validator::IsEmail($_POST['email'])){ $errors[] = 'Invalid email address.'; } } if ($use_verification_image){ if (md5(md5($_POST['verification']) . 'a39nx') != $_COOKIE['tntcommentvf']){ $errors[] = 'Invalid verification code.'; } } if (count($errors) != 0) return $errors; $sanitizedMessage = htmlentities(trim($_POST['message'])); $sanitizedMessage = preg_replace('/((\r|\n)+)/','
',$sanitizedMessage); $comment = new Comment(); $comment->authorEmail = $require_email ? trim($_POST['email']) : 'none'; $comment->authorName = trim($_POST['authorname']); $comment->timestamp = mktime(); $comment->message = $sanitizedMessage; return $comment; } /** * Converts the data contained in the class to a string * for storage. * @return string A line safe for storage in the database. */ function ToLine(){ $line = $this->timestamp . '|' . encode_field($this->authorName) . '|' . encode_field($this->authorEmail) . '|' . encode_field($this->message); return $line; } } class Validator { /** * Returns true if the input is a valid email address. * Otherwise, it returns false. */ function IsEmail($input){ if (!is_string($input)) return false; $test = trim($input); $regex = '^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$'; return (eregi($regex,$test) === false) ? false : true; } } /** Prepares a field for entry in the database. **/ function encode_field($fieldData){ $charsToEncode = array('|'); foreach ($charsToEncode as $char){ $fieldData = str_replace($char, '&0x'.ord($char).';', $fieldData); } return $fieldData; } /** Decodes a field right from the database. */ function decode_field($fieldData){ $charsToDecode = array('|'); foreach ($charsToDecode as $char){ $fieldData = str_replace('&0x'.ord($char).';', $char, $fieldData); } return $fieldData; } function makeurl($base, $vars, $ampchar = '&'){ if (strpos($base, '?') === false){ return $base . '?' . $vars; } return $base . $ampchar . $vars; } function timedifference($timestamp){ $difference = abs(mktime() - $timestamp); if ($difference < 60){ return $difference . ' seconds'; }else if($difference < 60*60){ $num = round($difference / 60); return $num . ' minute' . ($num == 1 ? '' : 's'); }else if($difference < 60*60*24){ $num = round($difference / 60 / 60); return $num . ' hour' . ($num == 1 ? '' : 's'); }else if($difference < 60*60*24*2){ return 'Yesterday'; }else{ return round($difference / 60 / 60 / 24) . ' days'; } } function timeago($timestamp){ $diff = timedifference($timestamp); return $diff . ($diff != 'Yesterday' ? ' ago' : ''); } function endswith($search, $base){ if (strlen($base)-strlen($search)<0) return false; return strtolower(substr($base, strlen($base)-strlen($search))) == strtolower($search); } /** * To be called ONLY if get_magic_quotes_gpc() == 1. This function * remove strips the slashes of all elements of the array.. even if * it is multidimensional. */ function stripslashes_accordingly($input){ if (is_array($input)){ foreach ($input as $key => $value){ $data[$key] = stripslashes_accordingly($value); } return $data; }else{ return stripslashes($input); } } $registeredPageVars = explode(',', $pageGetVars); $uriWithVars = $_SERVER['REQUEST_URI']; $qMarkPos = strrpos($uriWithVars, '?'); if ($qMarkPos !== false){ $uriWithVars = substr($uriWithVars, 0, $qMarkPos); } $varArray = array(); $i = 0; if (is_array($_GET)){ foreach ($_GET as $key => $val){ if(in_array($key, $registeredPageVars)){ if ($i == 0) $uriWithVars .= '?'; $varArray[] = $key . '=' . $val; $i++; } } } $uriWithVars .= implode('&', $varArray); $postLocation = $uriWithVars; $dirDelimiter = strpos(__FILE__, '/') === false ? '\\' : '/'; $dbDirectory = str_replace(strpos(__FILE__, '/') === false ? '/' : '\\', $dirDelimiter, $dbDirectory); $fileBase = ''; if (!isset($comment_id)){ $fileBase = $uriWithVars; if (endswith('/',$fileBase)) $fileBase .= '_index_'; $fileBase = str_replace('/', '_', $fileBase); $fileBase = str_replace('\\', '_', $fileBase); $fileBase = str_replace('?', ';', $fileBase); $fileBase = str_replace('&', '.', $fileBase); if (endswith('index.html',$fileBase)) $fileBase = substr($fileBase,0,strlen($fileBase)-strlen('index.html')) . '_index_'; else if (endswith('index.php',$fileBase)) $fileBase = substr($fileBase,0,strlen($fileBase)-strlen('index.php')) . '_index_'; else if (endswith('index.php4',$fileBase)) $fileBase = substr($fileBase,0,strlen($fileBase)-strlen('index.php4')) . '_index_'; else if (endswith('index.php5',$fileBase)) $fileBase = substr($fileBase,0,strlen($fileBase)-strlen('index.php5')) . '_index_'; else if (endswith('index.shtml',$fileBase)) $fileBase = substr($fileBase,0,strlen($fileBase)-strlen('index.shtml')) . '_index_'; if ($fileBase == '') $fileBase = '_index_'; }else{ $fileBase = basename($comment_id); } $dbFile = dirname(__FILE__) . $dirDelimiter . $dbDirectory . $fileBase . '.dat'; @chmod(dirname(__FILE__) . $dirDelimiter . $dbDirectory, 0777); $isadmin = false; if ($_COOKIE['tntcommentsysusername'] === $username && $_COOKIE['tntcommentsyspassword'] === md5($password)){ $isadmin = true; } $db = new Database($dbFile); $addedComment = Comment::FromPostData(); if ($addedComment->isComment == true){ $db->AddComment($addedComment); $db->Commit(); $commentAdded = true; } if ($_POST['tntactiontype'] == 'inlineEditor'){ $message = $_POST['tntnewMessage']; $commentId = $_POST['tntcommentid']; $comments = $db->GetComments(); foreach ($comments as $comment){ if ($comment->id == $commentId){ $constructedComment = $comment; break; } } if ($constructedComment != null){ $sanitizedMessage = htmlentities(trim($message)); $sanitizedMessage = preg_replace('/((\r|\n)+)/','
',$sanitizedMessage); $constructedComment->message = $sanitizedMessage; $db->SaveComment($constructedComment); $db->Commit(); $commentEdited = true; } } if (($isadmin && $_GET['tntaction'] == 'delete' && is_numeric($_GET['tntid'])) || ($_GET['tntauth'] == md5(md5($password).'93ziJ'.$email) && $_GET['tntaction'] == 'delete' && is_numeric($_GET['tntid']))){ $db->DeleteComment($_GET['tntid']); $db->Commit(); $commentDeleted = true; } $comments = $db->GetComments(strtolower($sorting) == 'desc' ? DESC : ASC); $areComments = count($comments) > 0; $noComments = !$areComments; $post_name = htmlentities($_POST['authorname']); $post_email = htmlentities($_POST['email']); $post_message = htmlentities($_POST['message']); if (trim($scriptpath) == ''){ $cleanedRequestURI = $uriWithVars; $qmarkpos = strpos($cleanedRequestURI, '?'); if ($qmarkpos !== false){ $cleanedRequestURI = substr($cleanedRequestURI, 0, $qmarkpos); } $slashpos = strrpos($cleanedRequestURI, '/'); if ($slashpos !== false){ $cleanedRequestURI = substr($cleanedRequestURI, 0, $slashpos + 1); } $thisDir = dirname(__FILE__) . $dirDelimiter; $base = substr($thisDir, strlen($_SERVER['DOCUMENT_ROOT'])); $base = str_replace('\\','/', $base); $commentsystemfolder = 'http://' . $_SERVER['HTTP_HOST'] . $base; }else{ $commentsystemfolder = $scriptpath; } include('comments_html.php'); ?>




THE URBAN BOOK SOURCE IS NOT RESPONSIBLE FOR ANY COMMENTS THAT ARE POSTED. IF A COMMENT IS DEFAMATORY, PLEASE CONTACT US AND APPROPRIATE ACTION WILL BE TAKEN.
    B O O K   R E V I E W   R A T I N G   S Y S T E M




      Recent Reviews:

Juanita

Dynasty

What's Done in Darkness

A Lovely Murder Down South

Marry Your Baby Daddy

Sinful Too

Rays Right

Officer Down

Meji

How Do You Want It

A Dead Rose

Reality Check: Stepmother

      [ More Book Reviews ]

 

 



ABOUT US:
Company Info
Privacy Policy
Disclaimer
Advertise
Resources

Contributors
Faq
WRITE-UPS:
Features

Interviews
Editorials
Reviews
Columns
Archives
MEDIA:
Video
Gallery
Audio
Store

COMMUNITY:
Message Board
Contests
Giveaways
PUBLIC RELATIONS:
Get Featured. Be Heard.
Submit Your Book
Review For Us
Book Checklist
Join Mailing List
Send Your Feedback
Contact Us
SOCIAL MEDIA:
Myspace
Facebook
Twitter
Blackplanet
YouTube

© 2005 - 2010 by The Urban Book Source, LLC