Using json API pull to store in file or database - json

I am trying to pull data from the justin.tv API and store the echo I get in the below code in to a database or a file to be included in the sidebar of website. I am not sure on how to do this. The example of what I am trying to achieve is the live streamers list on the sidebar of teamliquid.net. Which I have done but doing it the way I have done it slows the site way down because it does about 50 json requests every time the page loads. I just need to get this in to a cached file that updates every 60 seconds or so. Any ideas?
<?php
$json_file = file_get_contents("http://api.justin.tv/api/stream/list.json?channel=colcatz");
$json_array = json_decode($json_file, true);
if ($json_array[0]['name'] == 'live_user_colcatz') echo 'coL.CatZ Live<br>';
$json_file = file_get_contents("http://api.justin.tv/api/stream/list.json?channel=coldrewbie");
$json_array = json_decode($json_file, true);
if ($json_array[0]['name'] == 'live_user_coldrewbie') echo 'coL.drewbie Live<br>';
?>

I'm not entirely sure how you would imagine this being cached, but the code below is an adaption of a block of code I've used in the past for some Twitter work. There are a few things that could probably be done better from a security perspective. Anyway, this gives you a generic way of grabbing the Feed, parsing through it, and then sending it to the database.
Warning: This assumes that there is a database connection already established within your own system.
(* Make sure you scroll to the bottom of the code window *)
/**
* Class SM
*
* Define a generic wrapper class with some system
* wide functionality. In this case we'll give it
* the ability to fetch a social media feed from
* another server for parsing and possibly caching.
*
*/
class SM {
private $api, $init, $url;
public function fetch_page_contents ($url) {
$init = curl_init();
try {
curl_setopt($init, CURLOPT_URL, $url);
curl_setopt($init, CURLOPT_HEADER, 0);
curl_setopt($init, CURLOPT_RETURNTRANSFER, 1);
} catch (Exception $e) {
error_log($e->getMessage());
}
$output = curl_exec($init);
curl_close($init);
return $output;
}
}
/**
* Class JustinTV
*
* Define a specific site wrapper for getting the
* timeline for a specific user from the JustinTV
* website. Optionally you can return the code as
* a JSON string or as a decoded PHP array with the
* $api_decode argument in the get_timeline function.
*
*/
class JustinTV extends SM {
private $timeline_document,
$api_user,
$api_format,
$api_url;
public function get_timeline ($api_user, $api_decode = 1, $api_format = 'json', $api_url = 'http://api.justin.tv/api/stream/list') {
$timeline_document = $api_url . '.' . $api_format . '?channel=' . $api_user;
$SM_init = new SM();
$decoded_json = json_decode($SM_init->fetch_page_contents($timeline_document));
// Make sure that our JSON is really JSON
if ($decoded_json === null && json_last_error() !== JSON_ERROR_NONE) {
error_log('Badly formed, dangerous, or altered JSON string detected. Exiting program.');
}
if ($api_decode == 1) {
return $decoded_json;
}
return $SM_init->fetch_page_contents($timeline_document);
}
}
/**
* Instantiation of the class
*
* Instantiate our JustinTV class, fetch a user timeline
* from JustinTV for the user colcatz. The loop through
* the results and enter each of the individual results
* into a database table called cache_sm_justintv.
*
*/
$SM_JustinTV = new JustinTV();
$user_timeline = $SM_JustinTV->get_timeline('colcatz');
foreach ($user_timeline AS $entry) {
// Here you could check whether the entry already exists in the system before you cache it, thus reducing duplicate ID's
$date = date('U');
$query = sprintf("INSERT INTO `cache_sm_justintv` (`id`, `cache_content`, `date`) VALUES (%d, '%s', )", $entry->id, $entry, $date);
$result = mysql_query($query);
// Do some other stuff and then close the MySQL Connection when your done
}

Related

Issue trying to convert HTML to Ajax

I got this in the video script that I use for my website (Videos Page Layout):
<div class="video-views pull-left">
{$videos[i].viewnumber|kilo} {if $videos[i].viewnumber == '1'}{t c='global.view'}{else}{t c='global.views'}{/if}
</div>
Related videos section uses Ajax for videos page layout generated with the "show more" button.
My problem is: I don't know how to convert the "kilo" function in Ajax {$videos[i].viewnumber|kilo}. I attempted a few things but with no result.
$code[] = '<div class="video-views pull-left">';
$views = ($video['viewnumber'] == '1') ? $lang['global.view'] : $lang['global.views'];
$code[] = $video['viewnumber']. ' '.$views;
$code[] = '</div>';
Kilo is not a modifier that is included in the Smarty distribution, but if you have access to the code on your site, you can extract the code from the plugin file, it is most likely in smarty/libs/plugins/modifier.kilo.php.
It looks like you're working in PHP to construct a response to an AJAX request, so you can just pull that code out and re-use it.
If you do not have access to the modifier file, you can just recreate the formatting on your own. Judging by the context, it's something simple like:
<?php
/**
* Format integers into human readable strings indicating number of thousands
* Example: 1200 -> 1.2K
* #param int $value
* #return string
*/
function kilo(int $value): string
{
// If the value is less than 1000, just return it
if($value < 1000)
{
return $value;
}
/*
* If the value is evenly divisible by 1000, we want to show a whole number,
* otherwise format it as a single precision float. Add "K" string literal
* to indicate thousands
*/
$formatString = ($value % 1000) ? '%.1fK':'%dK';
// Divide value by 1000
$value /= 1000;
// Return the formatted string
return sprintf($formatString, $value);
}
// Define some test data and echo the formatted values
$testViewCounts = [1, 123, 1230, 12300, 123000];
foreach($testViewCounts as $views)
{
// If only one view, do not pluralize
$label = ($views == 1) ? 'view':'views';
echo kilo($views).' '.$label.PHP_EOL;
}

Writing GPS string to MySQL database on Ubuntu Server

I have an app that writes a set of GPS strings to a text file like this:
[{"date":"02/13/2017 19:26:00","time":1486974360428,"longitude":151.209900,"latitude":-33.865143}{"date":"02/13/2017 19:26:13","time":1486974373496,"longitude":151.209900,"latitude":-33.865143}{"date":"02/13/2017 19:26:23","time":1486974383539,"longitude":151.209900,"latitude":-33.865143}{"date":"02/13/2017 19:26:33","time":1486974393449,"longitude":151.209900,"latitude":-33.865143}{"date":"02/13/2017 19:26:43","time":1486974403423,"longitude":151.209900,"latitude":-33.865143}{"date":"02/13/2017 19:26:53","time":1486974413483,"longitude":151.209900,"latitude":-33.865143}]
the file always starts and ends with [].
This file gets uploaded to an Ubuntu server at
'filepath'/uploads/gps/'device ID'/'year-month-day'/'UTC download time'.txt
for example
/uploads/gps/12/2017-02-12/1486940878.txt
The text files get created when the file gets uploaded to the server, so there are multiple files written per day.
I would like a method to write the values to a MySQL database with the headings DEVICE (obtained from the filepath), DATE, TIME, LONGITUDE, LATITUDE.
Initially, just a command I can run on the server would be preferable, which I can eventually run from a PHP command on an admin panel.
Where do I start?
Instead of uploading, you could easily submit the text to a PHP program on the server. It would use JSON decode to convert it to an array, and then save each record to a table. The device ID would be one of the parameters to the script.
Using this type of approach would eliminate a lot of issues such as not importing a file twice, renaming/moving the files after import, finding the file(s), etc.
It would also mean your data is up to date every time the data is sent.
A script like that would be pretty trivial to write, but it should have some type of security built in to prevent data from being sent by an unauthorized entity.
Here's some sample code that will process the files and store them to the DB. I've removed certain info (user ID/password database name) that you will need to edit. It's a little longer that I guessed, but still pretty short. If you need more info, PM me.
<?php
/* ===============================================================
Locate and parse GPS files, then store to MySQL DB.
Presumes a folder stucture of gps/device_id/date:YYYY-MM-DD.
After a file is processed and stored in the DB table, the
file is renamed with a leading "_" so it will be ignored later.
===============================================================
*/
$DS = '/'; // Directory separator character. Use '/' for Linux, '\' for windows.
// Path to folder containing device folders.
$base_folder = "./gps";
// Today's date foratted like the folders under the devices. If parameter "date" has a value, use it instead of today's date. Parameter MUST be formatted correctly.
$today = isset($_REQUEST['date']) && $_REQUEST['date'] != '' ? $_REQUEST['date'] : date('Y-m-d');
// Get a list of device folders
$device_folders = get_folders($base_folder);
// Loop through all of the device folders
$num_file_processed = 0;
foreach($device_folders as $dev_folder) {
// Check to see if there is a folder in the device folder for today.
$folder_path = $base_folder.$DS.$dev_folder.$DS.$today;
// Check if the device/date folder exists.
if(file_exists($folder_path) && is_dir($folder_path)) {
// Folder exists, get a list of files that haven't been processed.
$file_list = get_files($folder_path);
// Process the files (if any)
foreach($file_list as $filename) {
$f_path = $folder_path.$DS.$filename;
$json = file_get_contents($f_path);
// Fix the JSON -- missing "," between records.
$json = str_replace("}{","},{",$json);
$data = json_decode($json);
// Process each row of data and save to DB.
$num_saved = 0;
$rec_num = 0;
foreach($data as $recno => $rec_data) {
if(save_GPS($dev_folder,$rec_data->date,$rec_data->time,$rec_data->longitude,$rec_data->latitude)) {
$num_saved++;
}
$rec_num++;
}
// Rename file so we can ignore it if processing is done again.
if($num_saved > 0) {
$newName = $folder_path.$DS."_".$filename;
rename($f_path,$newName);
$num_file_processed++;
}
}
} else {
echo "<p>" . $folder_path . " not found.</p>\n";
}
}
echo "Processing Complete. ".$num_file_processed." files processed. ".$num_saved." records saved to db.\n";
function save_GPS($dev_id,$rec_date,$rec_time,$long,$lat) {
$server = "localhost";
$uid = "your_db_user_id";
$pid = "your_db_password";
$db_name = "your_database_name";
$qstr = "";
$qstr .= "INSERT INTO `gps_log`\n";
$qstr .= "(`device`,`date`,`time`,`longitude`,`latitude`)\n";
$qstr .= "VALUES\n";
$qstr .= "('".$dev_id."','".$rec_date."','".$rec_time."','".$long."','".$lat."');\n";
$db = mysqli_connect($server,$uid,$pid,$db_name);
if(mysqli_connect_errno()) {
echo "Failed to connect to MySQL server: " . mysqli_connect_errno() . " " . mysqli_connect_error() . "\n";
return false;
}
// Connected to DB, so save the record
mysqli_query($db,$qstr);
mysqli_close($db);
return true;
}
function get_folders($base_folder) {
$rslts = array();
$folders = array_map("htmlspecialchars", scandir($base_folder));
foreach($folders as $folder) {
// Ignore files and folders that start with "." (ie. current folder and parent folder references)
if(is_dir($base_folder."/".$folder) && substr($folder,0,1) != '.') {
$rslts[] = $folder;
}
}
return $rslts;
}
function get_files($base_folder) {
$rslts = array();
$files = array_map("htmlspecialchars", scandir($base_folder));
foreach($files as $file) {
// Ignore files and folders that start with "." (ie. current folder and parent folder references), or "_" (files already processed).
if(!is_dir($file) && substr($file,0,1) != '.' && substr($file,0,1) != '_') {
$rslts[] = $file;
}
}
return $rslts;
}

When will the database connection be closed in prestashop 1.6.1.3 version?

When will the database connection be closed in prestashop 1.6.1.3 after a db instance is created by $db = Db::getInstance();
Do I need to close the database connection manually by writing any code db close function?
Or the db class in prestashop will handle this?
Actually when will be the PrestaShop db connection will be closed after a db object is created by $db = Db::getInstance();?
See below code which is a simple php file in my root directory of prestashop to update one of my tables and this page is called every one minute by cron job task ,here I am not closing the connection anywhere ,do we need to close it ?
$CheckStatusSql = "select * from ticket_status where item_id='$ItemID' and ticket_series='$TicketSeries' and status='BOOKED' ";
$db = Db::getInstance();
$result = $db->executeS($CheckStatusSql, false);
$ChangeStatus ='';
while ($row = $db->nextRow($result)) {
$status = $row['status'];
$booked_on = $row['booked_on'];
$ticket_no = $row['ticket_no'];
$to_time = strtotime(date("Y-m-d H:i:s"));// Time Now
$from_time = strtotime($booked_on); //Booked Time
$time_diff_minutes=round(abs($to_time - $from_time) / 60,2);
if($time_diff_minutes>$checkMinutes){
$ChangeStatus=$ChangeStatus."Booked ticket no: '".$ticket_no."' exceeds 30 Minutes and its now about ".$time_diff_minutes." minutes, status changed to AVAILABLE<br><br\>";
$updateSql = "UPDATE ticket_status SET status = 'AVAILABLE', booked_on = NULL WHERE item_id='$ItemID' and ticket_series='$TicketSeries' and status='BOOKED' and ticket_no='$ticket_no'";
$bookResult = $db->executeS($updateSql, false);
}
}
That is I am just including the config file (require 'config/config.inc.php';) and creating a db object and then executing my query as shown below :
require 'config/config.inc.php';
$checkMinutes = 30;// In minutes
$checkTimeInSeconds = $checkMinutes*60;
$sql = 'SELECT * FROM ps_ticket WHERE status=5';
$db = Db::getInstance();
$result = $db->executeS($sql, false);
$i=1;
while ($row = $db->nextRow($result)) {
$time = strtotime($row['hold_on']);
$curtime = time();
if(($curtime-$time) > $checkTimeInSeconds) { ///3600 seconds
$sql = 'UPDATE `'._DB_PREFIX_.'lopp_ticket`
SET
`id_customer` = 0,
`hold_on`=0,
`status` = 1
WHERE `ticket_id` = '.$row['ticket_id'];
if(Db::getInstance()->execute($sql)) {
echo $row['ticket_id'].' Updated'.'<br>';
}
}
else {
echo $row['ticket_no'].'No'.'<br>';
}
$i++;
}
So here do I need to close the db connection anywhere in the above code or PrestaShop will handle itself?
Because the server admin is saying too many database sessions are been opened by our code ,
Also Is there anyway to check from where too many db sessions are open/active always ?
As far as i know i never have closed a DB connection in Prestashop.
There documentation also does not explicitly state to close each DB request.
Looking into there source code they also never run a close command after a DB connection.
Looking into the classes\db\DbMySQLi.php class we can find the function below.
/**
* Destroys the database connection link.
*
* #see DbCore::disconnect()
*/
public function disconnect()
{
#$this->link->close();
}
Then we will look into classes\db\Db.php where we find that the function $this->disconnect() is called. So its safe to say they will close all there DB connections automatically.
/**
* Closes connection to database.
*/
public function __destruct()
{
if ($this->link) {
$this->disconnect();
}
}

Facebook login page and cache

I've got a Facebook login in my website
but I need to request permission to post in my user's wall.
I found many many examples on google that use the scope, but they're too different form mine, and I don't understand where to put it
This is the code:
<?php
session_start();
// added in v4.0.0
require_once 'autoload.php';
require 'functions.php';
use Facebook\FacebookSession;
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookRequest;
use Facebook\FacebookResponse;
use Facebook\FacebookSDKException;
use Facebook\FacebookRequestException;
use Facebook\FacebookAuthorizationException;
use Facebook\GraphObject;
use Facebook\Entities\AccessToken;
use Facebook\HttpClients\FacebookCurlHttpClient;
use Facebook\HttpClients\FacebookHttpable;
// init app with app id and secret
FacebookSession::setDefaultApplication( 'APPID','APPSECURE' );
// login helper with redirect_uri
$helper = new FacebookRedirectLoginHelper('http://www.bestparty.altervista.org/APP/facebook/fbconfig.php' );
try {
$session = $helper->getSessionFromRedirect();
} catch( FacebookRequestException $ex ) {
// When Facebook returns an error
} catch( Exception $ex ) {
// When validation fails or other local issues
}
// see if we have a session
if ( isset( $session ) ) {
// graph api request for user data
$request = new FacebookRequest( $session, 'GET', '/me' );
$response = $request->execute();
// get response
$graphObject = $response->getGraphObject();
$fbid = $graphObject->getProperty('id'); // To Get Facebook ID
$fbfullname = $graphObject->getProperty('name'); // To Get Facebook full name
$femail = $graphObject->getProperty('email');
/* ---- Session Variables -----*/
$_SESSION['FBID'] = $fbid;
$_SESSION['FULLNAME'] = $fbfullname;
$_SESSION['EMAIL'] = $femail;
checkuser($fbid,$fbfullname,$femail);
/* ---- header location after session ----*/
$cookie_name = 'FBID';
$cookie_value = $fbid;
setcookie($cookie_name, $cookie_value, time() + (86400 * 30), '/');
$cookie_name2 = 'FULLNAME';
$cookie_value2 = $fbfullname;
setcookie($cookie_name2, $cookie_value2, time() + (86400 * 30), '/');
header("Location: ../gestaccount.php");
} else {
$cookie_name = 'FBID';
$cookie_value = $fbid;
setcookie($cookie_name, $cookie_value, time() + (86400 * 30), '/');
$loginUrl = $helper->getLoginUrl();
header("Location: ".$loginUrl);
}
?>
Also:
May I save the access token in mysql to use it in future?
Why does the datas that I save in cache stays only until I close the browser?
1, You can store the access token however which way you like. As long as it's secure and you are able to update them in case of expired/updated/extended access tokens, it should be fine.
2, This is a bit unclear, are you setting and handling cookies correctly ?

PHP + MySQL profiler

You know how vBulletin has a sql profiler when in debug mode? How would I go about building one for my own web application? It's built in procedural PHP.
Thanks.
http://dev.mysql.com/tech-resources/articles/using-new-query-profiler.html
The above link links how you can get al the sql profile information after any query.
Best way to implement it is to create a database class and have it have a "profile" flag to turn on logging of queries and the appropriate information as shown int he link above.
Example:
Class dbthing{
var $profile = false;
function __construct($profile = false){
if($profile){
$this->query('set profiling=1');
$this->profile = true;
}
...
}
function query($sql, $profile_this == false){
...
if($this->profile && !$profile_this)
$this->query("select sum(duration) as qtime from information_schema.profiling where query_id=1", true);
... // store the timing here
}
}
I use a database connection wrapper that I can place a profiling wrapper arround. This way I can discard the wrapper, or change it, without changing my base connector class.
class dbcon {
function query( $q ) {}
}
class profiled_dbcon()
{
private $dbcon;
private $thresh;
function __construct( dbcon $d, $thresh=false )
{
$this->dbcon = $d;
$this->thresh = $thresh;
}
function queury( $q )
{
$begin = microtime( true );
$result = this->dbcon->query();
$end = microtime( true );
if( $this->thresh && ($end - $begin) >= $this->thresh ) error_log( ... );
return $result;
}
}
For profiling with a 10 second threshold:
$dbc = new profiled_dbcon( new dbcon(), 10 );
I have it use error_log() what the times were. I would not log query performance back to the database server, that affects the database server performance. You'd rather have your web-heads absorb that impact.
Though late, Open PHP MyProfiler would help you achieve this, and you can extract functional sections from the code for your usage.