25 Mar

Flash videoların kopyalanması

Sanırım linuxda olmanın bir handikapı, bazı şeyleri daha zor yollardan yapmanız gerekiyor. Eğer firefox eklentisi kullanmıyorsanız ya da yoksa böyle bir eklenti, izlediğiniz flash videoları bilgisayarınıza indirmeniz uğraşıtırıcı.

Gerçi önceden kolaydı (ubuntu 10.10 dan önce) , izelenen tüm flash videolar /tmp klasörü içerisine kopyalanıyordu. Videonun bulunduğu sayfayı kapadığınızda da, /tmp den siliniyordu. Flash videonun penceresini kapamadan, /tmp klasöründen alıp istediğiniz yere kopyalayabiliyordunuz.

Bu kolay adımlar bazılarının canını sıkmış sanırım, bu yüzden artık izlenen flash videolar tmp dizininde bulunmuyor. Bunun yerine /proc dizini altında, çalışan eklentinin process id si altındaki fd dizini içerisinde bulunan ilgili numaradaki dosya olarak bulunabiliyor 🙂

Şunun gibi yani (“lsof -n|grep Flash” komutunun çıktısı):

1
plugin-co 2535     ersin   16u      REG                8,1  5463336   12058865 /tmp/FlashXXcGtmnF (deleted)

Bunu bir arkadaştan öğrendim, lsof (açık olan tüm uygulamaların kullandığı dosyaları listeliyormuş) ile bu bilgilere ulaştıktan sonra geriye bu dosyayı kopyalamak kalıyordu :

1
cp /proc/2535/fd/16 ~/flash_dosyasi.flv

Bu yöntemin dez avantajı hangi dosyanın hangi video olduğunu bilmemeniz. Bu yüzden birden fazla flash video izliyorsanız, bunun takibini ve ayrımını yapmak tamamen size kalıyor.

Uzun sözün kısası şu, burda izlediğim adımları otomatize etmek için küçük bir php scripti yazdım, konsoldan çalışan. Bunu da burdan paylaşmak istedim :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#!/usr/bin/php
<?php
/**
 * Flas dosyalarını kopyalayabilmek için oluşturulacak Ui için ortak yapı
 * @author ersin
 *
 */

abstract class  Ui {
   /**
    *
    * Fla listesini tutar
    * @var array
    */

   protected $listArray;
   /**
    *
    * Komut çıktısını tutar
    * @var string
    */

   protected $list;
   /**
    *
    * Sistemde olan açık fla dosyalarının listesini dödnüdür
    */

   protected function listOpenFlas(){
      $this->list =`lsof -n|grep Flash`;
      $this->listArray = explode("\n",$this->list);
      array_pop($this->listArray);
   }
   /**
    *
    * Komut çıktısını ayrıştırarak fla dosyasına erişebilmeyi
    * sağlayan değerleri döndürür
    *
    * @param string $data
    */

   protected function parseFla($data){
       $res = array();
       $match = array();
       preg_match_all('/\d{1,}/',$data, $match);
       if(count($match)==0) {
       return false;
       }
   
       $res['pid'] = $match[0][0];
       $res['itm'] = (int)$match[0][1];
       return $res;
    }
   /**
    *
    * Fla dosyasının kaydedilmesini sağlar
    * @param integer $index
    * @param string $savePath
    */

   protected function saveFile($index,$savePath){
      @$file = $this->listArray[$index];
     
      if(!($fla  = $this->parseFla($file))){
         echo "\nFlash dosyası ayrıştırılamadı\n";
         return false;
      }
     
      $source ='/proc/'.$fla['pid'].'/fd/'.$fla['itm'];
         $res =`cp $source $savePath>&1`;
      if(null === $res) {
         echo "\nDosya aktarım işlemi başarılı ile sonuçlandı\n";
      }else {
         echo "\n\033[01;31mHata\t:\t\033[0m".$res."\n";
      }
   }
   /**
    *
    * Ortak başlatıcı
    */

   public function start(){}
}
/**
 *
 * Consoleda çalışan Ui
 * @author ersin
 *
 */

class ConsoleUi extends Ui {
   /**
    *
    * Conseole menü çıktısını verir
    */

   private function print_menu(){
      $msg= "\n\033[35;1m Seçenekler :\033[0m \n".
      "\033[01;31m(1)\t:\033[0m Flash Dosya Listesi\n".
      "\033[01;31m(2)\t:\033[0m Flashı farklı kaydet\n".
      "\033[01;31m(3)\t:\033[0m Çıkış\n".
      "\n\033[01;31mBir Seçenek Numarası Girin :\033[0m";
      return $this->prompt($msg);
   }
   /**
    *
    * Fla dosyalarının liste çıktısını verir
    */

   private function listMenu() {
      if(count($this->listArray)>0) {
         echo "\n\t\tŞu an açık olan flash dosyaları\n",
         $this->list;
      }else {
         echo "\nAçık flash dosyası bulunamadı\n";
         return false;
      }
   }
   /**
    * (non-PHPdoc)
    * @see Ui::listOpenFlas()
    */

   public function listOpenFlas(){
      parent::listOpenFlas();
      $this->listMenu();
   }
   /**
    *
    * Console dan parametre almamızı sağlar
    * @param string $message
    * @return string
    */

   private function prompt($message,$trim=true){
      echo $message;
      $input = fopen('php://stdin','r');
      $value = fgets($input);
      fclose($input);
      if($trim) {
         return trim($value);
      }else {
         return $value;
      }
   }
   /**
    *
    * Karar mekanizması
    * @param int $choice
    */

   private function makeAction($choice){
      switch($choice){
         case 1:
            $this->listOpenFlas();
            break;
         case 2:
            if(count($this->listArray)==0){
               if($this->prompt("\nListe boş görünüyor, tekrar kontrol edilsin mi? [e/h]")=="e"){
                  if(!$this->listOpenFlas()) return false;
               }else { return false;}
            }
            $fileChoice = $this->prompt("\nDosya indeksini girin(0 dan başlayarak) :");
            $savePath   = $this->prompt("\nDosyanın kaydedileceği yolu girin :");
            $this->saveFile($fileChoice,$savePath);
            break;
         case 3:
            exit(0);
            break;
         default :
            var_dump($choice);exit;
      }
   }
   /**
    * (non-PHPdoc)
    * @see Ui::start()
    */

   public function start(){
      while(true){
         $choice = $this->print_menu();
         $this->makeAction($choice);
      }
   }
}

$console = new ConsoleUi();

$console->start();

GTK destekli sürümünü de yapmak istediğimden, bunu yapabilecek şekilde düzenledim. Belki sizin de aklınıza farklı birşeyler gelir siz de ekleme yaparsınız,basit kullanışlı bir araç çıkar ortaya 🙂

09 Mar

Sphinx?in Ayarlanması ve Kullanımı

Önceki yazılarda sphinxin ne olduğunu açıklamaya çalışmıştım. Kısaca özet geçmek gerekirse, sphinx, bağımsız çalışan bir arama motorudur. Çok fazla veri içeren veritabanbları için , hızlı ve kolay, metin bazlı arama yapabilmek için kullanılabilecek bir uygulamadır.

Sphinxi paylaşımlı hostinglerde kullanabilmek pek mümkün olmaz sanırım. Çünkü sphinxi kullanabilmek için, sphinx sunucusu ve phpye has sphinx eklentisini kurmak gereklidir. Bunların haricinde, arama sunucusunun belirli aralıklarla çalışarak verileri yeniden indekslemesi gerekmektedir. Tüm bu ve buna benzer durumlardan ötürü, sphinxi sadece kendinizin yönetebildiği sunucularda kullanabileceğinizi unutmayın.

Şimdi gelelim sphinxin nasıl kullanılacağına. Bunun için sphinx ile birlikte gelen örnek veritabanını ve konfigürasyon dosyalarını kullanacağım.

Kurulumu tamamladıktan sonra, kurulum yaptığınız dizin altında bulunan etc kalsöründe (kendi bilgisayarımda sphinxi /opt/sphinx altına kurduğum için, /opt/sphinx/etc dizinini kullanacağım) bulunan example.sql dosyasını açarak başına kullanmak istediğimiz veritabanını ekleyelim:

CREATE DATABASE IF NOT EXISTS test;
use test;

Sonrasında :

1
mysql -u kullanici_adi -psifre<example.sql

komutunu çalıştırarak örnek veritabanını oluşturuyoruz. Bir sonraki adım ayar dosyasını oluştrumak. Yine aynı klasörde bulunan (/opt/sphinx/etc) sphinx.conf.dist sphinx-min.conf.dist dosyaları ile, tüm ayarları sıfırdan yapmak yerine. Varsayılan olarak gelen ayarları kullanıp veya düzenleyebiliriz. Varsayılan ayarlar her zaman işimize yaramaz, ama kendisi ile gelen örnek veritabanı ile uyumlu. Çok fazla karmaşaya sebep olmamak için en basit ve kısa olan ayarını kullanacağım :

1
sudo cp sphinx-min.conf.dist sphinx-test.conf

Yukarıdaki komutu çalıştırdığımızda, birlikte gelen ayar dosyalarından, sphinxin çalışabilmesi için gerekli olan minimum ayarların bulunduğu dosyayı, kendi ihtiyaçlarımız için düzenleyebileceğimiz ayrı bir dosya olarak kaydettim. sphinx-test.conf dosyasının içeriği aşağıdaki gibidir: (sphinx verisyonuna göre değişiklik gösterebilir)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#
# Minimal Sphinx configuration sample (clean, simple, functional)
#

source src1
{
   type        = mysql

   sql_host    = localhost
   sql_user    = test
   sql_pass    =
   sql_db         = test
   sql_port    = 3306   # optional, default is 3306

   sql_query      = \
      SELECT id, group_id, UNIX_TIMESTAMP(date_added) AS date_added, title, content \
      FROM documents

   sql_attr_uint     = group_id
   sql_attr_timestamp   = date_added

   sql_query_info    = SELECT * FROM documents WHERE id=$id
}


index test1
{
   source         = src1
   path        = /opt/sphinx/var/data/test1
   docinfo        = extern
   charset_type      = sbcs
}


index testrt
{
   type        = rt
   rt_mem_limit      = 32M

   path        = /opt/sphinx/var/data/testrt
   charset_type      = utf-8

   rt_field    = title
   rt_field    = content
   rt_attr_uint      = gid
}


indexer
{
   mem_limit      = 32M
}


searchd
{
   listen         = 9312
   listen         = 9306:mysql41
   log         = /opt/sphinx/var/log/searchd.log
   query_log      = /opt/sphinx/var/log/query.log
   read_timeout      = 5
   max_children      = 30
   pid_file    = /opt/sphinx/var/log/searchd.pid
   max_matches    = 1000
   seamless_rotate      = 1
   preopen_indexes      = 0
   unlink_old     = 1
   workers        = threads # for RT to work
}

Sphinxi hızlıca ayarlayabilmek için yapmanız gereken, bir source, bir index ve searchd ayarının tanımlı olması gerekiyor.

source : Arama yapılmasını istediğnizi veritabanına ve tabloya yapılacak bağlantı ve sorgunun tanımlaması burada yapılır. Sphinx bu ayar yardımı ile , veritabanına bağlanır, ilgili tabloadan verileri çeker ve indexler. Böylece sphinxe bir arama sorgusu gönderdiğinizde size sonuç döndürebilir. Burada veritabanına bağlanmak için gerekli parametrelerin nasıl verilmesi gerektiğini açıklamama grek yok sanırım. Ayar anahtarları gayet açıklayıcı duruyor. Ayar dosyası içeirisinde birden fazla source tanımlanabilir.

Burda üstünde duracağım ayar anahtarı “sql_query”. Buraya, indekslenmesini istediğiniz verileri elde edebileceğiniz sorguyu yazmalısınız. Sphinxin size dayattığı en belirgin kural, bu sql sorgusunun en az bir “id” alanı içermesidir. Bunun haricinde SQLinizi istediğiniz gibi yazabilirsiniz.

Sphinx ayar dosyasında mutlaka dikkat etmeniz gereken bir diğer husus ise, yeni bir satıra geçmek istiyorsanız satır bitimine \ karakteri eklemeniz gerektiğidir. Eğer buna dikkat etmezseniz sphinx ayar dosyasını ayrıştırıken hata verecek ve çalışmayı durduracaktır.

sql_attr_ ile başlayan ayar anahtarı, aramanız üzerinde filtreleme yapabilmeniz için kullanabileceğiniz alanları tanımlamanızı sağlar. Bu tanımlamalar, sorgu yaptığınız tablo üzerindeki alanlardan biri olmalıdır. sql_attr_ den sonra, ilgili alanın tipini belirtmelisiniz ( örneğin sql_attr_timestamp = date_added , sorgu yaptığınız tablo üzerinde timestamp tipinde date_added alanını temsil eder). Daha fazla ayrıntı için sphinx dökümantasyonunda “Data source configuration options” başlığına bakınız.

sql_query_info yu es geçebilirsiniz.

index : Bu başlıkta , sphinxin verileri nasıl indekslemesi gerektiği belirtilir. Ayar dosyası içerisinde birden faxla index başlığı olabilir ve bu index başlıklarını kod tarafında arama yaparken seçebilir ve istediğiniz indeks üzerinde arama yaptırabilirsiniz. Ayar dosyasında mutlaka bir index olmak zorundadır. index bir source a sahip olmalıdır. “index test1” başlığı altında tanımlanmış örnekte görüldüğü gibi , bir source tanımlanmış, index verilerilerinin nerede saklanması gerektiği belirtlimiş (path= /opt/sphinx/var/data/test1). docinfo ve charset_type ı es geçiyorum, bunlarla ilgili daha fazla bilgiyi sphinx dökümantasyonunda bulabilirsiniz. Basit bir ayar için belirttiğim iki anahtar yeterlidir. searchd de bulunan ayarları değiştirmenize gerek yok şimdilik.

Yukarıdaki ayar dosyasında gerekli ayarları yaptıktan sonra, sphinxin gerekli dataları oluşturmasını sağlamaktır. Bunun için:

1
sudo /opt/sphinx/bin/indexer --all --config /opt/sphinx/etc/sphinx-test.conf

Yukarıdaki kod ile, ayar dosyamızdaki direktiflere göre veriler indexlenecek. Eğer bir problem olmaz ise, aşağıdaki gibi bir çıktı alırsınız :

1
2
3
4
5
6
7
8
9
10
11
12
13
Sphinx 1.11-dev (r2709)
Copyright (c) 2001-2011, Andrew Aksyonoff
Copyright (c) 2008-2011, Sphinx Technologies Inc (http://sphinxsearch.com)

using config file '/opt/sphinx/etc/sphinx-test.conf'...
indexing index 'test1'...
collected 4 docs, 0.0 MB
sorted 0.0 Mhits, 100.0% done
total 4 docs, 193 bytes
total 0.036 sec, 5290 bytes/sec, 109.64 docs/sec
skipping non-plain index 'testrt'...
total 3 reads, 0.000 sec, 0.1 kb/call avg, 0.0 msec/call avg
total 9 writes, 0.000 sec, 0.1 kb/call avg, 0.0 msec/call avg

Örnek veritabanında çok fazla veri olmadığı için indeksleme işlemi çok kısa sürede tamamlandı. Şimdi sıra geldi arama sunucusunu çalıştırmaya :

1
sudo /opt/sphinx/bin/searchd --config /opt/sphinx/etc/sphinx-test.conf

Bunu çalıştırdığınızda aşağıdakine benzer bir sonuç alırsınız :

1
2
3
4
5
6
7
8
9
10
Sphinx 1.11-dev (r2709)
Copyright (c) 2001-2011, Andrew Aksyonoff
Copyright (c) 2008-2011, Sphinx Technologies Inc (http://sphinxsearch.com)

using config file '/opt/sphinx/etc/sphinx-test.conf'...
listening on all interfaces, port=9312
listening on all interfaces, port=9306
precaching index 'test1'
precaching index 'testrt'                                  
precached 2 indexes in 0.001 sec

Yukarıda çalıştırmış olduğumuz kod, arama sunucumuzun çalışmasını sağlar, böylece bizde arama sunucusuna sorgu göndererek arama işlemini gerçekleştirebiliriz.

Sphinx sunucumuzu ayarlayıp çalıştırmış olduk. Burda bahsettiğim /opt/sphinx klasörü kendi bilgisayarıma özgü bir yoldur. Siz nereye kurulum yaptı iseniz o dizini referans alınız.

Şimdi sphinxi ayarladık ve çalıştırdık, bitti mi ? Tam olarak bitti denemez, veritabanınıza sürekli veri ekleneceği için sphinx indekslerinin yenilenmesi gerekir. Bunun için de belirli aralıklarla :

1
/opt/sphinx/bin/indexer --all --rotate --config /opt/sphinx/etc/sphinx-test.conf

bu kodun çalışması gerekmektedir. Bu kod, indekslerin yenilenmesini sağlar. Bunu bir cron job olarak çalıştırabilirsiniz. Bu işlemin sıklığı ihtiyaçlarınıza göre değişir. Günde bir defa da yaptırabilirsiniz, dakikada bir de yaptırabilirsiniz. Bu tamamen size kalmış ( veritabanın büyüklüğü de rol oynuyor tabiki). Eğer yeniden indeksleme yapmazsanız, yeni girilen kayıtlar arama sonuçlarında çıkmaz.

Sunucunuzu ayarlayıp çalıştırdıktan sonra, buradaki örnekte olduğu gibi arama işlemi yapabilirsiniz.

Sphinx, çok fazla ayrıntıya sahip olan bir arama motoru sunucusudur. Burda aktarmaya çalıştıklarımdan daha fazlasını sphinx dökümantasyonunda bulabilirsiniz. Gayet anlaşılabilir bir dil ile örnekleyerek anlatmakta.

Bu seriye ait diğer yazılar :

Metin Bazlı Arama – Site İçi Arama Motoru
Aramanın Yapılması – Site İçi Arama Motoru
Sphinx nedir ?
Sphinx Kurulumu
Sphinx?in Ayarlanması ve Kullanımı