Jul 28, 2011

Facebook php-sdk 3.0 changes getLoginURL()

Somehow these frequent changes are still poorly documented. Documentation is scattered across forums, changelogs, code comments and docs pages. Never on the single place. This is horrible. I'm sorry Facebook people, but this makes you look incompetent.

The most obvious change is the abandonment of the getSession method. I have also found out that getLoginURL has been changed.
'req_perms' has been changed to 'scope'
'next' has been changed to 'redirect_uri'
'cancel_url' option has been removed. You'll have to find another way. If the user denies access it will be redirected to 'redirect_uri'. The user will also be redirected to 'redirect_uri' if he clicks allow.
You can know if the user denied access by looking at these GET parameters:
[error_reason] => user_denied 
[error] => access_denied 
[error_description] => The user denied your request.
Also worth knowing is that redirect_uri will not work every time on a single page load (without refreshing the page).
Explanation:
The first time the users sees the oauth dialog there will be two options: Allow and Deny. Both buttons will redirect to 'redirect_uri'.
The second time the user sees the oauth dialog, Deny option will be renamed to 'Leave app'. 'redirect_uri' will still work.
The third time and so on, the button 'Leave app' will redirect to facebook.com/home.php

While this may not be entirely precise, it is true that eventually the Deny/Leave app button will not follow the redirect_uri parameter.

Jul 24, 2011

SiOL TV, dve mrežni kartici, VLC player, Windows 7 x64-bit

V primeru da vam IPTv ne deluje, če imate dve mrežni kartici (eno za internet in drugo za TV), poskusite pri mrežnem adapterju za TV nastaviti metriko na 2.



Ne pozabite na ostale nastavitve za vzpostavitev TV na VLC playerju:
-odprite VLC in pritisnite CTRL+P (Preferences)
-spodaj levo obkljukate Show settings "All"-s tem se omogočijo napredne nastavitve
-v meniju gremo na Input/Codecs - na desni pri UDP portu vnesemo pravi port, ki je za t2 "5000", pri MTU pa imam "1492", potem pa še obkljukamo "Force IPv4"
-gremo v meni "Video" in nato kliknemo "output modules" - pri "Video output modules" izberemo možnost iz seznama "OpenGL video output"
-nato v levem meniju izberemo meni "Stream output" in nato "Access output"
-V Access output sem v okence kjer piše "Multicast output interface" vpisal IP mrežne kartice, ki jo uporabljam za internet, v okence "IPv4 multicast output interface adress" pa sem vpisal IP mrežne kartice, ki jo uporabljam zgolj za IPTV
-zadevo shranite in ponovno zaženite program.



M3U file editor

M3U are playlist files. I have developed this simple editor for a friend, that needed to edit IPTv playlist files.

The editor includes mass (bulk) edits as well as item editor. You can upload and export the same filetype.

You can check out the editor here:
http://kafol.net/code/m3u-edit/

M3U files are easy to parse:
<?
class m3u {
 public $data = array();
 public $name = '';
 
 public function __construct($data = null) {
  if(!is_null($data)) {
   $this->load($data);
  }
 }
 
 public function load($data) {
  if(!is_array($data)) explode("\n",$data);
  
  foreach($data as $i=>$line) {
   if(preg_match('/^#EXTNAME:(.+)/is',$line,$m)) {
    $this->name = clean($m[1]);
   }
   if(preg_match('/^#EXTINF:(\d+),(.+)/is',$line,$m)) {
    $item = new m3uitem();
    $item->length = intval($m[1]);
    $item->setName($m[2]);
    if(preg_match('/^#EXTTV:(.+)/is',$data[$i+1],$m)) {
     $item->setCategories($m[1]);
    }
    $item->file = trim($data[$i+2]);
    $this->data[] = $item;
   }
  }
 }
 
 public function sort() {
  usort($this->data, array(__CLASS__,'cmp'));
 }
 
 public static function cmp($a,$b) {
  if($a->sort == $b->sort) {
   return 0;
  }
  return ($a->sort > $b->sort) ? +1 : -1;
 }
 
 public function export() {
  $r = "#EXTM3U\n#EXTNAME:{$this->name}\n\n";
  foreach($this->data as $d) {
   $r .= "#EXTINF:{$d->length},{$d->getName()}\n";
   if($d->getCategories() != '') {
    $r .= "#EXTTV:{$d->getCategories()}\n";
   }
   $r .= "{$d->file}\n\n";
  }
  return $r;
 }
 
}

class m3uitem {
 public $sort = 0;
 public $length = 0;
 public $file = '';
 private $name = '';
 private $categories = array();
 
 public function __construct() {}
 
 public function getName() { 
  return $this->name; 
 }
 
 public function setName($name) {
  $this->name = clean($name);
 }
 
 public function getCategories() {
  return implode(';',$this->categories);
 }
 
 public function setCategories($data) {
  $this->categories = is_array($data) ? $data : explode(';',clean($data));
  
  foreach($this->categories as $i=>$cat) {
   if(empty($cat)) {
    unset($this->categories[$i]);
   } else {
    $this->categories[$i] = clean($this->categories[$i]);
   }
  }
 }
}
?>


Jul 19, 2011

Automatically download subtitles in VLC player

You can write VideoLAN VLC player's extensions in LUA programming language.
Extensions are in Videolan\VLC directory lua\extensions directory.

This is a modified extension to automatically download subtitles.

Download extension
Save extension (the code/text file) as AutoSubtitles.lua in the extensions directory mentioned above.

Will add more languages upon request.
Currently this extension is intended for personal use.

Screenshots:



PHP goo.gl url shortener

Here's an implementation of Google's url shortener: goo.gl.
<?
class googl {
 const api = 'https://www.googleapis.com/urlshortener/v1/url';
 private $key = null;
 
 public function __construct($key = null) {
  if(defined('GOOGLE_API_KEY')) {
   $this->setKey(GOOGLE_API_KEY);
  }
  
  if(!is_null($key)) {
   $this->setKey($key);
  }
 }
 
 public function setKey($key) {
  $this->key = $key;
 }
 
 public function s($url) {
  $data = $this->shorten($url);
  return isset($data->id) ? $data->id : $url;
 }
 
 public function shorten($url) {
  $key = '';
  $data = array();
  $data['longUrl'] = $url;
  
  if(!is_null($this->key)) {
   $key = '?key='.$this->key;
  }
  
  return $this->fetch(self::api.$key,$data);
 }
 
 public function expand($url) {
  $key = is_null($this->key) ? '' : "&key={$this->key}";
  return $this->fetch(self::api.'?shortUrl='.urlencode($url)."$key&projection=FULL");
 }
 
 private function fetch($url, $data = array()) {
  $ch = curl_init();
  
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_HEADER, 0);
  curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json'));
  
  if(!empty($data)) {
   curl_setopt($ch, CURLOPT_POST, 1);
   curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
  }
  
  $r = curl_exec($ch);
  curl_close($ch);
  
  return json_decode($r);
 }
}
?>