Cavidan Quliyevin Bloqu

Burada proqramlaşdırma haqqında paylaşmaq istədiyim subyektiv fikirlərimi yazıram.

Tənbəlliyin yaxşı cəhəti - 35mm.az saytında film əlavəsi prosesi.
27 February 2013 at 12:32

Mənim bir proyektim var, bir zamanlar azdan çoxdan tanınırdı. 35mm.az - Onlayn film izləmə saytı. İndi çox vaxtım olmadığından sayt yenilənmir, amma girib hal hazırki filmlərə baxanlar hələ də var. Bu proyektin qurulması əsnasında problemlərdən biri filmlərin vebdə göstərmək üçün lazım olan formata çevirmək idi. Bu əvvəllər .flv formatı idi amma sonra keyfiyyət baxımından qabağa düşmək üçün keçdik .mp4-ə.

HDRIP keyfiyyətində bir filmin biz istədiyimiz ayarlarla mp4-ə çevirmək aşağı yuxarı həmin film uzunluğu qədər çəkir. Hardasa saat yarımdan iki saata qədər və bununla birlikdə çox resurs aparır. Filmi ADSL-də endirmək, çevirmək, sonra hostinqə yükləmək əməlli vaxt və əsəb aparır, özüdə çevirmə zamanı demək olarki həmin kompüterdən istifadə etmək qeyri mümkün deyil. Çox əziyyətli işdir amm o biri tərəfdən xalq yenilik istəyir :).

İlk vaxtlar bütün bunlar əlnən bir bir müxtəlif könüllü dost tanışın köməyi ilə edilirdi. Amma yavaş yavaş hamı bezdi qaldım tək. Mənimdə bu işdən düzünü heç xoşum gəlmir, bu vaxtı daha mərifətli işlərə ayırmaq olar. Ona görə çevirmə işi tam avtomatlaşdırmaq qərarına gəldim. Hətta birazda qabağa gedib hərşeyi avtomatlaşdırmaq istədim.

Deməli elemək istədiyim:

  1. Film avtomatik torrent saytından endirilsin
  2. Film mən əvvəlcədən verdiyim parametrlərlə mp4-ə çevrilsin.
  3. Film haqqında məlumat(aktyorlar, rejisser, müddət, treyler, poster və s.) internetdə tapılsın endirilsin.
  4. Sonda məlumat, treyler, poster, film sayta əlavə olunsun.

Bunların hamısı mənnən xəbərsiz avtomatik olsun ki mənim başım ağrımasın. Başlayaq.

1) Filmin torrent saytından avtomatik endirilməsi

Faylı Torrentdən endirmək üçün linux altında torrent server və ona vebinterfeys lazım idi. Torrent endirmək  işinin öhdəsindən Rtorrent klienti çox yaxşı gəlir. Bu klient konsolda işləyir ona görə bizə vebinterfeys lazımdır. Bu işində öhdəsindən RuTorrent gəlir. Rutorrent Rtorrent üçün interfeysdi. Axırda alınan budur.

Bütün siyahı

Torrent faylı əlavə edəndə:

 

2) Filmin mp4-ə çevrilməsi prosesi

Ən çətin iş bütün prosessdə çevirmə idi. Linux altında video formatlarının çevrilməsi üçün FFMpeg-dən istifadə edirdim. Bu çox böyük imkanları olan proqramdı sadəcə bütün idarə etmə konsoldan həyata keçirilir, bizə isə veb lazımdır. Düzünü deyim ffmpeg-i vebdən idarə edən düz əməlli heçnə yoxdur yazılmış ona görə özüm yazası oldum. Çevirmə proqramı Nodejs-də yazılıb, javascriptə olan sevgim tükənməzdir :). Proqram verilən qovluğa nəzarət edir, əgər yeni fayl varsa qovluqda onu çevirmə növbəsinə atır və sırası gələndə çevirməyə başlayır. Onlaynda bütün prosesi görmək, idarə etmək, çevrilmiş videoya baxmaq olur.

Anna Karenina konvert olur

 

3) Film haqqında məlumatın doldurulması

Çevirmə bitdikdən sonra filmin adına və ilinə uyğun internetdə axtarış aparılır. Bunun üçün Themoviedb.orgKinobaza.tv saytları işimə yaradı. Hər iki saytın öz REST API-yı var hansından ki istifadə edib kino adını göndərərək XML və JSON formatında film haqqında bütün məlumatı əldə etmək olar. Bundan başqa ən əsası filmin posterində API vasitəsiylə almaq olar.

 

Sonda bütün məlumat toplanaraq Saytın öz API-yı vasitəsiylə sayta əlavə olunur. Və ana səhifədə göstərilir. Beləliklə bütün bu sevmədiyim işi tam olaraq avtomatlaşdırdım. Lazım olan ancaq torrent fayl idi. Əslində ideyam va idiki birazda qabağa gedib internetdə çıxan yenilikləri vaxt aşırı tapıb endirən bir sistem yazım amma hal hazırda buna ayıracaq vaxtım yoxdur.

Javascriptlə SQL
30 January 2013 at 13:57

Biraz dəlifason səslənir amma reallıqdı. Bir ay əvvəl mənə 20-30 sətirlik tekst faylın bazaya əlavə edib üzərində işləmək lazım idi. Kompüterə mysql və ya başqa DBMS yükləməyə həvəs yox idi on görə əlimin altında olanlarla kifayətlənmək qərarına gəldim. Əlimin altında isə Google Chrome 5 brauzeri birdə notepad++ var idi. Az adam bilirki HTML5 standartında offline data management kimi birşey var. Yəni informasiyanı klient brauzerinin bazasında saxlamaq olur. Bunun üçün 3 yol var, Web Storage, Web SQL Database, IndexedDB. Üçündən mən ancaq Web SQL Database sistemini istifadə edəcəm çünki mənə SQL ilə işləmək lazımdır. Əvvəlcədən demək istəyirəm texnalogiyanı təzə olduğu üçün çox az brauzer dəstəkləyir, Specifikasiyadan 200 qram araqsız baş açabilməzsən. İE, Firefox dəstəkləmir, Safariylə Operada yoxlamamışam amma Safari netdə yazılana görə dəstəkləyir. Google Chrome-da brauzerlə birlikdə gələn SQLite bazası var, ondan istifadə edəcəyik. İndi baxaq bundan necə istifadə etmək olar. İlk olaraq bazanı yaradaq.

var db = openDatabase('testDb', '1.0', 'my first database', 2 * 1024 * 1024);

Bazamızı yaratdıq. Argumentlərə baxsaq baza adı, versiya, qısa təsvir, birdə bazanın ölçüsü(Kilobaytla) verilir.

Bazanın yarandığını Chrome-da Developer tools-u açaraq Storage bölməsində görəbilərsiniz(CTRL+SHIFT+I və ya menudan açın).

{% img /files/Screenshot-16.png %}

Yaxshi indi isə ilk cədvəlimizi düzəldək

   
db.transaction(function (tx) {
      tx.executeSql('CREATE TABLE tbl1 (id unique, ad, soyad, yash)',[],
         // success callback
         function(tx,result){
               console.log('result')
          },
          //error callback
          function(tx,error){
              console.log(error)
          }
      });
    });

Cədvəli qurandan sonra eyni şəkildə select, insert, delete SQL kommandalrın istifadə edə bilərik. SQL kommandaları tranzaksiyayla, asinxron icra olunacaq. Yəni Hər sql sorğu qurtarandan nəticədən asılı olaraq bir və ya digər Callback funksiyası çağırılır bununla bərabər kod SQL sorğunun tamamlanmasın gəzləməyərək davam edir. Əgər biz birdən çox bir birindən asılı asinxron SQL sorğu göndərmək istəsək bu kod nəzərindən çox narahat və qəlizdir. Fikirləşinki 3 dənə SQL sorğu yazmaq üçün bu boyda həngamə yazmaq lazımdır.

db.transaction(function (tx) {
  //birinci sorğu
  tx.executeSql('CREATE TABLE tbl1 (id unique, ad, soyad, yash)',[],
     //əgər sorğu keçərsə çağırılan funksiya
     function(tx,message){
           // ikinci sorğu
           tx.executeSql("INSERT INTO tbl1(id, ad, soyad, yash) VALUES (?,?,?,?)",[1,'Cavidan','Quliyev','25'],function(tx,message){
                       //üçüncü sorğu
                       tx.executeSql('SELECT * FROM tbl1',[],function(tx,error){
                         alert(error);  
                       });
           },
           //Əgər keçməzsə çağırılan funksiya
           function(tx,error){
                alert(error)
           })
  }),
  //error callback
  function(tx,error){
     alert(error)
  }
});

Bu cəmi 3 dənə sorğudur, əgər 10 dənə sorğu olsa yeni il yolkası olacaq kodumuz. Əslində alternativ olaraq sinxron sorğulardan istifadə edəbilərik, spesifikasiyaya əsasən belə sorğu tipidə mövcuddur amma mən sorğuların asinxron olmasın istəyirəm. Bu qədər kodu qısaltmaq üçün kiçik class yazmışam. Bununla bölüşmək istəyirəm.

//mesajları Chrome consolunda rahat görək deyə alert() funksiyasını override edirik
   function alert(log){
      console.log(log)
}

İndi bu funksiya ilə yuxarıdakı sorğuları icra etmək istəsək

var db = new DB('testDb', '1.0', 'test database', 3 * 1024 * 1024);
db.startTransact()
      .sql('CREATE TABLE tbl1 (id unique, ad, soyad, yash)')
      .sql("INSERT INTO tbl1(id, ad, soyad, yash) VALUES (1,'Cavidan','Quliyev','25')")
      .sql("INSERT INTO tbl1(id, ad, soyad, yash) VALUES (1,'Mamedov','Mamed','23')")
      .sql("INSERT INTO tbl1(id, ad, soyad, yash) VALUES (1,'Samedov','Samed','20')")
      .stopTransact();  
var Members = db.select("SELECT * FROM tbl1",function(tx,result){
        var rows = db.fetchObject(result);
        alert(rows)
})

Gördüyünüz kimi indi sql yazmaq çox rahatlaşdı. Özünüzdə kodu buradan yükləyib istifadə edəbilərsiniz.

Javascript Xətalarını Server Tərəfdə Loqlamaq
30 January 2013 at 13:57

Bəzi proyektlərdə kodun 70%-i clientside javascript olduğundan çıxa-biləcək bütün javascript xətalarını görmək və incələmək məcburiyyətində qalırsan. Javascript özü də brauzer versiyalarından çox asılı olduğundan bütün mümkün problemləri development mərhələsində tapıb çıxarmaq çətindir. Bunun üçün nə edirik? Bütün javascript xətaların; server-ə yönləndiririk. Javascript-də xəta baş verdiyi zaman window obyektinin onerror listener funksiyası işə salınır. Window içərisində hər-hansı xəta baş verincə bu listener-dəki callback çağrılır.
   window.onerror = function (msg, url, lno) {
      //kod kod kod
   }
Koddanda görüldüyü kimi callback funksiyasına xətanın mətni, sətir nömrəsi və hansı faylda baş verdiyi göndərilir. Əlavə olaraq bizə istifadəçinin brauzer bilgilərini də almaq pis olmazdı, məsələn brauzer versiyası, ekran böyüklüyü və sairə. Axırda da bütün bunları paketləyib ajaxla serverə göndərəcəyik.
var n = navigator;
  //burada bütün bilgiləri biryerə yığırıq.
  var info = {
  message: msg,
  url: url,
  line: lno,
      //brauzer bilgilərini toplayırıq
  browser: n.userAgent + ' ' + n.vendor + ', platform:' +n.platform + ', lang:' +n.language + ', cookie:' +n.cookieEnabled ,
      //ekran ölçüləri
  resolution: screen.width + 'x' + screen.height
  }
  //göndərəcəyimiz sətri düzəldirik
  var str = 'err:'+ info.line + '-' + info.message + ', url:' + url + ', ua:' + info.browser;
  // İnternet Explorer xhr sorğular üçün XDomainRequest obyektini, digər brauzerlər isə XMLHttpRequest obyektini istifadə edirlər
  var xhr = (XMLHttpRequest) ? new XMLHttpRequest() : new XDomainRequest();
  //parametrləri əlavə edirik
  var params="log="+encodeURI(encodeURIComponent(str));
  //sorğu başlığını əlavə edib post göndəririk
  xhr.open("post", "/log/", true);
  xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  xhr.onload = function(){
    //bilgilər serverə göndəriləndən sonra nəsə etmək istəsəz
  };
  xhr.send(params);
}
Yaddan çıxarmayın bu kod bütün javascript kodlarınızdan əvvəl əlavə olunmalıdır, çünki əgər bu koddan əvvəl nəsə xəta çıxsa kod icra olunmayacaq. Sonda da server tərəfdə istifadə etdiyim kod. Mənim kodum Ruby-dədir, sizdə istifadə etdiyiniz dilə uyğunlaşdıra bilərsiniz. Ruby kodu
def log
  require 'cgi'
  time = Time.new
  log = Logger.new('log/client.txt')
  log.debug time.inspect + ' ' + CGI.unescape(params[:log]) + ", ip:" + request.remote_ip
  render :nothing=>true
end
Kod ie8+, chrome, firefox, opera brauzerində yoxlanılıb. Köhnə İE də işləyib işləmədiyini bilmirəm.