<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://program.sonsuz.us/feed.xml" rel="self" type="application/atom+xml" /><link href="https://program.sonsuz.us/" rel="alternate" type="text/html" /><updated>2026-10-08T18:05:51+00:00</updated><id>https://program.sonsuz.us/feed.xml</id><title type="html">SonsuzUs</title><subtitle>Programlama ve Yazılım</subtitle><author><name>Sonsuz Us</name></author><entry><title type="html">Algoritma Yarışmalarının Perde Arkası: DOMjudge, DMOJ ve CMS</title><link href="https://program.sonsuz.us/posts/algoritma-yarismalarinin-perde-arkasi-domjudge-dmoj-ve-cms/" rel="alternate" type="text/html" title="Algoritma Yarışmalarının Perde Arkası: DOMjudge, DMOJ ve CMS" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/algoritma-yarismalarinin-perde-arkasi-domjudge-dmoj-ve-cms</id><content type="html" xml:base="https://program.sonsuz.us/posts/algoritma-yarismalarinin-perde-arkasi-domjudge-dmoj-ve-cms/"><![CDATA[<p>Bir algoritma yarışmasında çözümünüzü gönderip birkaç saniye sonra “Accepted” sonucunu gördüğünüzde arka planda küçük bir yazılım orkestrası çalışır. Kaynak kod derlenir, izole bir ortamda test edilir, süre ve bellek tüketimi ölçülür, çıktı karşılaştırılır ve puan hesaplanır. DOMjudge, DMOJ ve CMS, bu orkestrayı yöneten en popüler açık kaynak yarışma sistemleri arasındadır.
``</p>

<h2 id="online-judge-nasıl-çalışır">Online judge nasıl çalışır?</h2>

<p>Bir değerlendirme sisteminin temel girdileri kaynak kod, programlama dili ve problem kimliğidir. Sistem önce kodu derler, ardından her test için programı çalıştırır. En basit toplam değerlendirme süresi şöyle düşünülebilir:</p>

\[T_{toplam} = T_{derleme} + \sum_{i=1}^{n} T_{test_i}\]

<p>Programın herhangi bir testte süre sınırını aşması <strong>TLE</strong>, fazla bellek kullanması <strong>MLE</strong>, hatalı çıktı üretmesi ise <strong>WA</strong> sonucuna yol açar. Doğru sonuç yalnızca çıktının doğru olması değildir; programın belirlenen kaynak sınırları içinde çalışması da gerekir.</p>

<p>Gönderilen kod güvenilir kabul edilmez. Sonsuz döngüye girebilir, süreç oluşturmaya çalışabilir veya dosya sistemine erişmek isteyebilir. Bu nedenle judge sunucuları Linux kullanıcıları, cgroups, chroot, container veya benzeri izolasyon mekanizmalarından yararlanır. Kısacası değerlendirme sunucusu, yarışmacının koduna “Seni çalıştırırım ama evin anahtarını vermem” der.</p>

<h2 id="üç-platformun-karşılaştırması">Üç platformun karşılaştırması</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>DOMjudge</th>
      <th>DMOJ</th>
      <th>CMS</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ana kullanım</td>
      <td>ICPC tarzı yarışmalar</td>
      <td>Eğitim ve çevrim içi arşiv</td>
      <td>IOI tarzı olimpiyatlar</td>
    </tr>
    <tr>
      <td>Puanlama</td>
      <td>Genellikle problem bazlı</td>
      <td>Esnek, kısmi puan destekli</td>
      <td>Alt görev odaklı</td>
    </tr>
    <tr>
      <td>Teknoloji</td>
      <td>PHP, Symfony, MariaDB</td>
      <td>Python, Django, C++ judge</td>
      <td>Python tabanlı servisler</td>
    </tr>
    <tr>
      <td>Kurulum</td>
      <td>Orta</td>
      <td>Orta-zor</td>
      <td>Zor</td>
    </tr>
    <tr>
      <td>Kullanıcı arayüzü</td>
      <td>Yarışma odaklı</td>
      <td>Topluluk ve arşiv odaklı</td>
      <td>Yönetim odaklı</td>
    </tr>
    <tr>
      <td>Güçlü yanı</td>
      <td>Kararlı takım yarışmaları</td>
      <td>Dil ve problem çeşitliliği</td>
      <td>Gelişmiş olimpiyat değerlendirmesi</td>
    </tr>
  </tbody>
</table>

<h2 id="domjudge-icpc-ruhunun-temsilcisi">DOMjudge: ICPC ruhunun temsilcisi</h2>

<p>DOMjudge, takım yarışmaları ve klasik ICPC kuralları için oldukça uygundur. Yanlış gönderimler ceza süresine eklenir; problem çözüldüğünde süre hesabı kesinleşir. Basitleştirilmiş ceza modeli şöyledir:</p>

\[P = T_{kabul} + 20 \times W\]

<p>Burada $T_{kabul}$ kabul dakikası, $W$ ise kabulden önceki yanlış gönderim sayısıdır. DOMjudge; yarışma yönetimi, canlı sıralama, hakem işlemleri ve ayrı judgehost makineleriyle ölçeklendirme konusunda güçlüdür. Üniversite kulübünde gerçekçi bir ICPC provası düzenlemek istiyorsanız genellikle ilk adaydır.</p>

<h2 id="dmoj-esnek-ve-geliştirici-dostu">DMOJ: Esnek ve geliştirici dostu</h2>

<p>DMOJ, sürekli açık problem arşivleri ve eğitim platformları için öne çıkar. Çok sayıda dili destekler; özel checker, interaktif problem ve kısmi puanlama gibi özellikler sunar. Django tabanlı web uygulaması ile değerlendirme düğümleri birbirinden ayrılabilir.</p>

<p>Bir problemin basit yapılandırması kavramsal olarak şöyle görünebilir:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">archive</span><span class="pi">:</span> <span class="s">data.zip</span>
<span class="na">time</span><span class="pi">:</span> <span class="m">2</span>
<span class="na">memory</span><span class="pi">:</span> <span class="m">256</span>
<span class="na">test_cases</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">points</span><span class="pi">:</span> <span class="m">20</span>
    <span class="na">input</span><span class="pi">:</span> <span class="s">sample.in</span>
    <span class="na">output</span><span class="pi">:</span> <span class="s">sample.out</span>
  <span class="pi">-</span> <span class="na">points</span><span class="pi">:</span> <span class="m">80</span>
    <span class="na">batched</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">input</span><span class="pi">:</span> <span class="s">secret.in</span>
        <span class="na">output</span><span class="pi">:</span> <span class="s">secret.out</span>
</code></pre></div></div>

<p>Bu yapı süreyi, bellek sınırını ve testlerin puan ağırlığını tanımlar. Gerçek sözdizimi sürüme ve problem paketine göre değişebilse de temel fikir aynıdır: değerlendirme davranışı kod yerine yapılandırmayla açıklanır.</p>

<h2 id="cms-olimpiyat-seviyesinde-kontrol">CMS: Olimpiyat seviyesinde kontrol</h2>

<p>Contest Management System, özellikle IOI biçimindeki yarışmalara yöneliktir. Alt görevler, geri bildirim düzeyleri, token sistemi ve ayrıntılı puanlama senaryolarında çok başarılıdır. Örneğin çözüm ilk alt görevden 20, ikinci alt görevden 30 puan alabilir; en zor grup başarısız olsa bile toplam puan korunur.</p>

<p>CMS güçlüdür ancak kurulumu ve işletimi diğer seçeneklere göre daha fazla sistem yönetimi bilgisi ister. Servislerin dağıtılması, worker makinelerinin hazırlanması ve yarışma verilerinin doğru modellenmesi dikkat gerektirir.</p>

<h2 id="hangisini-seçmeli">Hangisini seçmeli?</h2>

<p>Tek günlük ICPC benzeri bir etkinlik için <strong>DOMjudge</strong>, okul veya topluluk tabanlı sürekli bir soru platformu için <strong>DMOJ</strong>, ulusal olimpiyat düzeyinde alt görevli yarışmalar için <strong>CMS</strong> daha doğal seçimdir. Platformdan bağımsız olarak yedekleme, HTTPS, kaynak izolasyonu ve yarışma öncesi yük testi ihmal edilmemelidir. Çünkü en zor algoritma sorusu bile çözülebilir; yarışma ortasında çöken judge sunucusu ise herkese aynı anda sistem tasarımı dersi verir.</p>

<p><img src="/img/algoritma-yarismalarinin-perde-38.svg" alt="algoritma-yarismalarinin-perde-38" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="algoritma" /><category term="online-judge" /><category term="domjudge" /><category term="dmoj" /><category term="cms" /><category term="programlama-yarışmaları" /><summary type="html"><![CDATA[Bir algoritma yarışmasında çözümünüzü gönderip birkaç saniye sonra “Accepted” sonucunu gördüğünüzde arka planda küçük bir yazılım orkestrası çalışır. Kaynak kod derlenir, izole bir ortamda test edilir, süre ve bellek tüketimi ölçülür, çıktı karşılaştırılır ve puan hesaplanır. DOMjudge, DMOJ ve CMS, bu orkestrayı yöneten en popüler açık kaynak yarışma sistemleri arasındadır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/algoritma-yarismalarinin-perde-38.png" /><media:content medium="image" url="https://program.sonsuz.us/img/algoritma-yarismalarinin-perde-38.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">API Dokümantasyon Sistemi Kurmak: Swagger UI, Redoc ve Docusaurus</title><link href="https://program.sonsuz.us/posts/api-dokumantasyon-sistemi-kurmak-swagger-ui-redoc-ve-docusaurus/" rel="alternate" type="text/html" title="API Dokümantasyon Sistemi Kurmak: Swagger UI, Redoc ve Docusaurus" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/api-dokumantasyon-sistemi-kurmak-swagger-ui-redoc-ve-docusaurus</id><content type="html" xml:base="https://program.sonsuz.us/posts/api-dokumantasyon-sistemi-kurmak-swagger-ui-redoc-ve-docusaurus/"><![CDATA[<p>Bir API geliştirmek yalnızca çalışan endpoint’ler yazmak değildir; diğer geliştiricilerin bu endpoint’leri keşfedebilmesini, deneyebilmesini ve doğru kullanabilmesini sağlamak da işin parçasıdır. Swagger UI, Redoc ve Docusaurus aynı dokümantasyon evreninde yaşasa da farklı sorunları çözer. Gelin bu araçları yarıştırmak yerine birlikte çalıştırabileceğimiz sürdürülebilir bir sistem tasarlayalım.
``</p>
<h2 id="önce-temel-openapi-nedir">Önce temel: OpenAPI nedir?</h2>

<p>OpenAPI, REST tabanlı bir API’nin insanlar ve makineler tarafından okunabilen sözleşmesidir. Endpoint yolları, HTTP metotları, parametreler, veri modelleri, kimlik doğrulama yöntemleri ve olası yanıtlar YAML veya JSON biçiminde tanımlanır.</p>

<p>Bir API sözleşmesini kabaca şu fonksiyonla düşünebiliriz:</p>

\[S = P + R + M + A + E\]

<p>Burada $P$ yolları, $R$ istekleri, $M$ veri modellerini, $A$ kimlik doğrulamayı ve $E$ hata yanıtlarını temsil eder. Sözleşme ne kadar eksiksizse istemci üretimi, test otomasyonu ve geliştirici deneyimi o kadar başarılı olur.</p>

<p>Swagger UI ve Redoc bu sözleşmeyi görselleştirir. Docusaurus ise rehberler, eğitimler, sürüm notları ve kavramsal açıklamalar için genel bir dokümantasyon sitesi sunar.</p>

<h2 id="araçların-karşılaştırması">Araçların karşılaştırması</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Swagger UI</th>
      <th>Redoc</th>
      <th>Docusaurus</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ana amaç</td>
      <td>API’yi etkileşimli denemek</td>
      <td>Okunabilir API referansı</td>
      <td>Tam dokümantasyon portalı</td>
    </tr>
    <tr>
      <td>OpenAPI desteği</td>
      <td>Doğrudan</td>
      <td>Doğrudan</td>
      <td>Eklentiyle</td>
    </tr>
    <tr>
      <td>İstek gönderme</td>
      <td>Güçlü</td>
      <td>Sınırlı veya sürüme bağlı</td>
      <td>Yerleşik değil</td>
    </tr>
    <tr>
      <td>Özelleştirme</td>
      <td>Orta</td>
      <td>Güçlü tema seçenekleri</td>
      <td>React ile çok güçlü</td>
    </tr>
    <tr>
      <td>En uygun kullanım</td>
      <td>Test ve keşif</td>
      <td>Referans dokümanı</td>
      <td>Rehber ve içerik yönetimi</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/api-dokumantasyon-sistemi-62.svg" alt="api-dokumantasyon-sistemi-62" /></p>

<p>Kısacası Swagger UI laboratuvar, Redoc düzenli bir ansiklopedi, Docusaurus ise bütün kampüstür.</p>

<h2 id="küçük-bir-openapi-sözleşmesi">Küçük bir OpenAPI sözleşmesi</h2>

<p>Aşağıdaki dosya, kullanıcı bilgisini kimliğe göre döndüren bir endpoint tanımlar:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">openapi</span><span class="pi">:</span> <span class="s">3.0.3</span>
<span class="na">info</span><span class="pi">:</span>
  <span class="na">title</span><span class="pi">:</span> <span class="s">Kullanıcı API</span>
  <span class="na">version</span><span class="pi">:</span> <span class="s">1.0.0</span>
<span class="na">paths</span><span class="pi">:</span>
  <span class="s">/users/{id}</span><span class="err">:</span>
    <span class="na">get</span><span class="pi">:</span>
      <span class="na">summary</span><span class="pi">:</span> <span class="s">Kimliğe göre kullanıcı getirir</span>
      <span class="na">parameters</span><span class="pi">:</span>
        <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">id</span>
          <span class="na">in</span><span class="pi">:</span> <span class="s">path</span>
          <span class="na">required</span><span class="pi">:</span> <span class="kc">true</span>
          <span class="na">schema</span><span class="pi">:</span>
            <span class="na">type</span><span class="pi">:</span> <span class="s">integer</span>
      <span class="na">responses</span><span class="pi">:</span>
        <span class="s1">'</span><span class="s">200'</span><span class="err">:</span>
          <span class="na">description</span><span class="pi">:</span> <span class="s">Kullanıcı bulundu</span>
          <span class="na">content</span><span class="pi">:</span>
            <span class="na">application/json</span><span class="pi">:</span>
              <span class="na">schema</span><span class="pi">:</span>
                <span class="na">$ref</span><span class="pi">:</span> <span class="s1">'</span><span class="s">#/components/schemas/User'</span>
      <span class="err">  </span><span class="s1">'</span><span class="s">404'</span><span class="err">:</span>
          <span class="na">description</span><span class="pi">:</span> <span class="s">Kullanıcı bulunamadı</span>
<span class="na">components</span><span class="pi">:</span>
  <span class="na">schemas</span><span class="pi">:</span>
    <span class="na">User</span><span class="pi">:</span>
      <span class="na">type</span><span class="pi">:</span> <span class="s">object</span>
      <span class="na">required</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">id</span><span class="pi">,</span> <span class="nv">name</span><span class="pi">]</span>
      <span class="na">properties</span><span class="pi">:</span>
        <span class="na">id</span><span class="pi">:</span>
          <span class="na">type</span><span class="pi">:</span> <span class="s">integer</span>
        <span class="na">name</span><span class="pi">:</span>
          <span class="na">type</span><span class="pi">:</span> <span class="s">string</span>
</code></pre></div></div>

<p>Bu tanım tek bir doğruluk kaynağıdır. Aynı dosya arayüz oluşturmak, sözleşme testi yapmak veya istemci SDK’sı üretmek için kullanılabilir.</p>

<h2 id="swagger-ui-ve-redocu-çalıştırmak">Swagger UI ve Redoc’u çalıştırmak</h2>

<p>En hızlı yöntem Docker kullanmaktır:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Etkileşimli Swagger UI</span>

docker run <span class="nt">--rm</span> <span class="nt">-p</span> 8080:8080 <span class="se">\</span>
  <span class="nt">-e</span> <span class="nv">SWAGGER_JSON</span><span class="o">=</span>/spec/openapi.yaml <span class="se">\</span>
  <span class="nt">-v</span> <span class="s2">"</span><span class="nv">$PWD</span><span class="s2">:/spec"</span> swaggerapi/swagger-ui

<span class="c"># Okuma odaklı Redoc</span>

docker run <span class="nt">--rm</span> <span class="nt">-p</span> 8081:80 <span class="se">\</span>
  <span class="nt">-e</span> <span class="nv">SPEC_URL</span><span class="o">=</span>openapi.yaml redocly/redoc
</code></pre></div></div>

<p>İlk komut API’yi <code class="language-plaintext highlighter-rouge">localhost:8080</code> üzerinde deneyebilmenizi sağlar. İkinci komut aynı sözleşmeyi daha sade ve referans odaklı bir görünümle sunar. Gerçek projede dosyayı Redoc sunucusunun erişebileceği dizine kopyalamak veya bir URL üzerinden yayımlamak gerekir.</p>

<h2 id="docusaurus-ile-merkezi-portal">Docusaurus ile merkezi portal</h2>

<p>Docusaurus projesinde kavramsal rehberleri Markdown ile tutabilir, API referansına menüden bağlantı verebilirsiniz:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// docusaurus.config.js</span>
<span class="k">export</span> <span class="k">default</span> <span class="p">{</span>
  <span class="na">themeConfig</span><span class="p">:</span> <span class="p">{</span>
    <span class="na">navbar</span><span class="p">:</span> <span class="p">{</span>
      <span class="na">items</span><span class="p">:</span> <span class="p">[</span>
        <span class="p">{</span> <span class="na">to</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/docs/intro</span><span class="dl">'</span><span class="p">,</span> <span class="na">label</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Rehberler</span><span class="dl">'</span> <span class="p">},</span>
        <span class="p">{</span> <span class="na">href</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/api/redoc.html</span><span class="dl">'</span><span class="p">,</span> <span class="na">label</span><span class="p">:</span> <span class="dl">'</span><span class="s1">API Referansı</span><span class="dl">'</span> <span class="p">},</span>
        <span class="p">{</span> <span class="na">href</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/swagger/</span><span class="dl">'</span><span class="p">,</span> <span class="na">label</span><span class="p">:</span> <span class="dl">'</span><span class="s1">API’yi Dene</span><span class="dl">'</span> <span class="p">}</span>
      <span class="p">]</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Bu yapı kullanıcıya üç katman sunar: “Neden kullanmalıyım?” sorusunu rehberler, “Hangi alanlar var?” sorusunu Redoc, “Bu istek gerçekten çalışıyor mu?” sorusunu Swagger UI cevaplar.</p>

<h2 id="sürdürülebilir-iş-akışı">Sürdürülebilir iş akışı</h2>

<p>OpenAPI dosyasını uygulama koduyla aynı depoda saklayın. CI sürecinde sözdizimini doğrulayın, kırıcı değişiklikleri karşılaştırın ve başarılı derlemeden sonra üç aracı da yayımlayın. Sürüm numarasını URL’ye eklemek, eski istemcilerin dokümantasyona erişmesini kolaylaştırır.</p>

<p>Ayrıca örneklerde gerçek erişim anahtarları kullanmayın. Swagger UI üzerindeki yetkilendirme alanlarını yalnızca güvenli test ortamlarına bağlayın. Böylece güzel görünen değil; güncel, test edilebilir ve güvenilir bir API dokümantasyon sistemi elde edersiniz.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="api" /><category term="swagger-ui" /><category term="redoc" /><category term="docusaurus" /><category term="openapi" /><category term="dokümantasyon" /><summary type="html"><![CDATA[Bir API geliştirmek yalnızca çalışan endpoint’ler yazmak değildir; diğer geliştiricilerin bu endpoint’leri keşfedebilmesini, deneyebilmesini ve doğru kullanabilmesini sağlamak da işin parçasıdır. Swagger UI, Redoc ve Docusaurus aynı dokümantasyon evreninde yaşasa da farklı sorunları çözer. Gelin bu araçları yarıştırmak yerine birlikte çalıştırabileceğimiz sürdürülebilir bir sistem tasarlayalım.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/api-dokumantasyon-sistemi-62.png" /><media:content medium="image" url="https://program.sonsuz.us/img/api-dokumantasyon-sistemi-62.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">API Test Arenası: Hoppscotch, Bruno ve Insomnia Karşılaştırması</title><link href="https://program.sonsuz.us/posts/api-test-arenasi-hoppscotch-bruno-ve-insomnia-karsilastirmasi/" rel="alternate" type="text/html" title="API Test Arenası: Hoppscotch, Bruno ve Insomnia Karşılaştırması" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/api-test-arenasi-hoppscotch-bruno-ve-insomnia-karsilastirmasi</id><content type="html" xml:base="https://program.sonsuz.us/posts/api-test-arenasi-hoppscotch-bruno-ve-insomnia-karsilastirmasi/"><![CDATA[<p>Bir API geliştirirken yalnızca endpoint’in çalışması yetmez; doğru durum kodunu, beklenen veriyi ve kabul edilebilir sürede yanıt verdiğini de doğrulamak gerekir. Postman dışında bir araç arıyorsanız Hoppscotch, Bruno ve Insomnia oldukça güçlü üç adaydır. Üstelik her biri API testine farklı bir pencereden bakar: biri hızlı ve web tabanlı, biri Git dostu, diğeri ise kapsamlı bir masaüstü çalışma alanıdır.</p>

<p><img src="/img/api-test-arenasi-95.svg" alt="api-test-arenasi-95" /></p>

<p>``</p>

<h2 id="api-testi-aslında-neyi-doğrular">API testi aslında neyi doğrular?</h2>

<p>Bir istemci API’ye HTTP isteği gönderir; sunucu ise durum kodu, başlıklar ve gövde içeren bir yanıt üretir. Test aracının temel görevi bu alışverişi görünür ve tekrar edilebilir hâle getirmektir.</p>

<p>Örneğin bir kullanıcı endpoint’i için yalnızca <code class="language-plaintext highlighter-rouge">200 OK</code> almak yeterli değildir. Yanıt gövdesindeki <code class="language-plaintext highlighter-rouge">id</code> alanının bulunması, içerik türünün JSON olması ve sürenin belirlenen sınırı aşmaması da kontrol edilmelidir.</p>

<p>Performansı basitçe şöyle değerlendirebiliriz:</p>

\[T_{toplam} = T_{ağ} + T_{sunucu} + T_{aktarım}\]

<p>Bir test 400 ms sürüyorsa bunun tamamı sunucunun işlem süresi değildir. Ağ gecikmesi ve yanıt boyutu da sonucu etkiler. Çoklu isteklerde ortalama süre ise</p>

\[\bar{T} = \frac{\sum_{i=1}^{n} T_i}{n}\]

<p>formülüyle hesaplanabilir. Bu nedenle tek bir hızlı yanıt görüp zafer dansına başlamak yerine testi birkaç kez çalıştırmak daha sağlıklıdır.</p>

<h2 id="üç-aracın-karakteri">Üç aracın karakteri</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Hoppscotch</th>
      <th>Bruno</th>
      <th>Insomnia</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Çalışma biçimi</td>
      <td>Web ve masaüstü</td>
      <td>Masaüstü ve CLI</td>
      <td>Masaüstü</td>
    </tr>
    <tr>
      <td>Başlangıç hızı</td>
      <td>Çok yüksek</td>
      <td>Yüksek</td>
      <td>Orta</td>
    </tr>
    <tr>
      <td>Git uyumu</td>
      <td>Sınırlı</td>
      <td>Çok güçlü</td>
      <td>Projeye göre değişir</td>
    </tr>
    <tr>
      <td>Yerel dosya yaklaşımı</td>
      <td>İkincil</td>
      <td>Temel özellik</td>
      <td>Kısmen</td>
    </tr>
    <tr>
      <td>Otomasyon</td>
      <td>Temel/orta</td>
      <td>CLI ile güçlü</td>
      <td>Eklenti ve CLI seçenekleri</td>
    </tr>
    <tr>
      <td>İdeal kullanıcı</td>
      <td>Hızlı deneme yapanlar</td>
      <td>Kod odaklı ekipler</td>
      <td>Geniş çalışma alanı isteyenler</td>
    </tr>
  </tbody>
</table>

<h3 id="hoppscotch-tarayıcıyı-aç-ve-isteği-gönder">Hoppscotch: Tarayıcıyı aç ve isteği gönder</h3>

<p>Hoppscotch, kurulumla uğraşmadan REST, GraphQL ve WebSocket istekleri denemek isteyenler için idealdir. Arayüzü hafiftir; URL’yi, metodu ve gerekli başlıkları girerek saniyeler içinde sonuç alabilirsiniz. Özellikle eğitimlerde, hata ayıklamada ve geçici kontrollerde parıldar.</p>

<p>Ancak hassas token’larla çalışırken ekip politikalarını ve verinin nerede saklandığını incelemek gerekir. Tarayıcı kolaylığı, güvenlik değerlendirmesini ortadan kaldırmaz.</p>

<h3 id="bruno-koleksiyonlar-da-kod-gibi-yaşasın">Bruno: Koleksiyonlar da kod gibi yaşasın</h3>

<p>Bruno, koleksiyonları düz metin dosyalarında saklayarak Git üzerinden sürümlemeyi kolaylaştırır. Böylece API değişiklikleri pull request içinde görülebilir; “Bu header’ı kim değiştirdi?” sorusu polisiye romana dönüşmez.</p>

<p>Örnek bir Bruno isteği şöyle görünebilir:</p>

<pre><code class="language-bru">meta {
  name: Kullanıcı Getir
  type: http
  seq: 1
}

get {
  url: {{baseUrl}}/users/42
  body: none
  auth: bearer
}

assert {
  res.status: eq 200
  res.body.id: eq 42
}
</code></pre>

<p>Bu dosya isteğin adresini tanımlar ve yanıtın durum koduyla kullanıcı kimliğini doğrular. CLI desteği sayesinde aynı koleksiyon CI/CD hattında da çalıştırılabilir.</p>

<h3 id="insomnia-düzenli-ve-kapsamlı-çalışma-masası">Insomnia: Düzenli ve kapsamlı çalışma masası</h3>

<p>Insomnia; ortam değişkenleri, kimlik doğrulama yöntemleri, GraphQL desteği ve koleksiyon organizasyonuyla kapsamlı projelerde rahat bir deneyim sunar. Çok sayıda servisi olan ekipler için klasörlü yapı ve yeniden kullanılabilir değişkenler önemlidir.</p>

<p>Örneğin geliştirme ve üretim adreslerini ayrı ayrı yazmak yerine şu mantık kullanılabilir:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"base_url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://api.example.com"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"token"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{{ secret_token }}"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>Böylece isteklerde `` kullanılır ve ortam değiştirirken her endpoint’i elle düzenlemek gerekmez. Token değerlerini repoya eklememek ise temel güvenlik kuralıdır.</p>

<h2 id="hangisini-seçmelisiniz">Hangisini seçmelisiniz?</h2>

<p>Hızlı, kurulumsuz denemeler için <strong>Hoppscotch</strong>; koleksiyonları Git ile yönetmek ve testleri pipeline’a taşımak için <strong>Bruno</strong>; kapsamlı masaüstü deneyimi ve düzenli proje yönetimi için <strong>Insomnia</strong> öne çıkar. En iyi araç, en fazla düğmeye sahip olan değil, ekibinizin testleri düzenli çalıştırmasını sağlayandır. Küçük bir örnek API’yi üçünde de deneyin; ardından hız, paylaşım, güvenlik ve otomasyon ihtiyaçlarınıza göre karar verin.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="api" /><category term="hoppscotch" /><category term="bruno" /><category term="insomnia" /><category term="rest" /><category term="yazılım-testi" /><summary type="html"><![CDATA[Bir API geliştirirken yalnızca endpoint’in çalışması yetmez; doğru durum kodunu, beklenen veriyi ve kabul edilebilir sürede yanıt verdiğini de doğrulamak gerekir. Postman dışında bir araç arıyorsanız Hoppscotch, Bruno ve Insomnia oldukça güçlü üç adaydır. Üstelik her biri API testine farklı bir pencereden bakar: biri hızlı ve web tabanlı, biri Git dostu, diğeri ise kapsamlı bir masaüstü çalışma alanıdır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/api-test-arenasi-95.png" /><media:content medium="image" url="https://program.sonsuz.us/img/api-test-arenasi-95.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Dijital Hafızanı Kur: Linkwarden, Linkding ve Shaarli Karşılaştırması</title><link href="https://program.sonsuz.us/posts/dijital-hafizani-kur-linkwarden-linkding-ve-shaarli-karsilastirmasi/" rel="alternate" type="text/html" title="Dijital Hafızanı Kur: Linkwarden, Linkding ve Shaarli Karşılaştırması" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/dijital-hafizani-kur-linkwarden-linkding-ve-shaarli-karsilastirmasi</id><content type="html" xml:base="https://program.sonsuz.us/posts/dijital-hafizani-kur-linkwarden-linkding-ve-shaarli-karsilastirmasi/"><![CDATA[<p>Tarayıcı yer imleri bir süre sonra çekmecedeki kablolara benzer: Hepsinin önemli olduğuna eminsindir ama hangisinin ne işe yaradığını bulamazsın. Linkwarden, Linkding ve Shaarli; bağlantıları etiketleyerek saklamayı, aramayı ve kendi sunucunda yönetmeyi sağlayan açık kaynaklı yer imi araçlarıdır. Böylece tarayıcıya veya ticari bir servise bağımlı kalmadan kişisel bir dijital kütüphane kurabilirsin.
``</p>
<h2 id="yer-imi-sistemi-aslında-ne-yapar">Yer imi sistemi aslında ne yapar?</h2>

<p>İyi bir bookmark sistemi yalnızca URL depolamaz. Bir bağlantıyı; başlık, açıklama, etiket, eklenme tarihi ve arşivlenmiş içerikle birlikte saklar. Teorik olarak her kaydı şu kümeyle gösterebiliriz:</p>

\[B = \{u, t, d, E, z, a\}\]

<p>Burada $u$ adresi, $t$ başlığı, $d$ açıklamayı, $E$ etiketler kümesini, $z$ eklenme zamanını ve $a$ arşiv kopyasını temsil eder. Etiketleme sayesinde arama alanı küçülür. Toplam $N$ bağlantının yalnızca belirli bir etikete ait $k$ tanesini incelemek, zihinsel yükü kabaca $N$ öğeden $k$ öğeye indirir.</p>

<p>Örneğin <code class="language-plaintext highlighter-rouge">python</code>, <code class="language-plaintext highlighter-rouge">veritabanı</code> ve <code class="language-plaintext highlighter-rouge">okunacak</code> etiketlerinin kesişimi şöyle düşünülebilir:</p>

\[S = E_{python} \cap E_{veritabanı} \cap E_{okunacak}\]

<p>Bu yaklaşım klasörlerden daha esnektir; çünkü aynı bağlantı birden fazla bağlama ait olabilir.</p>

<h2 id="üç-aracın-karakteri">Üç aracın karakteri</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Linkwarden</th>
      <th>Linkding</th>
      <th>Shaarli</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Arayüz</td>
      <td>Modern ve görsel</td>
      <td>Sade ve hızlı</td>
      <td>Minimal, klasik</td>
    </tr>
    <tr>
      <td>Sayfa arşivleme</td>
      <td>Güçlü; ekran görüntüsü ve belge</td>
      <td>Temel kullanım odaklı</td>
      <td>Sınırlı</td>
    </tr>
    <tr>
      <td>Çoklu kullanıcı</td>
      <td>Uygun</td>
      <td>Daha çok kişisel kullanım</td>
      <td>Temelde kişisel</td>
    </tr>
    <tr>
      <td>Kaynak tüketimi</td>
      <td>Görece yüksek</td>
      <td>Düşük</td>
      <td>Çok düşük</td>
    </tr>
    <tr>
      <td>Teknoloji</td>
      <td>Next.js, PostgreSQL</td>
      <td>Python, SQLite</td>
      <td>PHP, dosya tabanlı</td>
    </tr>
    <tr>
      <td>En iyi senaryo</td>
      <td>Ekip ve kalıcı arşiv</td>
      <td>Hızlı kişisel koleksiyon</td>
      <td>Küçük sunucu</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/dijital-hafizani-kur-71.svg" alt="dijital-hafizani-kur-71" /></p>

<h3 id="linkwarden">Linkwarden</h3>

<p>Linkwarden, bağlantı çürümesine karşı en güçlü seçenektir. Bir web sayfası silinse bile ekran görüntüsü veya PDF benzeri arşivleri koruyabilir. Koleksiyon paylaşımı ve kullanıcı yönetimi sayesinde ekipler için de uygundur. Bunun bedeli daha fazla RAM, depolama ve kurulum bileşenidir.</p>

<h3 id="linkding">Linkding</h3>

<p>Linkding, “yer imimi ekleyeyim ve hemen bulayım” yaklaşımını benimser. Arayüzü dikkat dağıtmaz; etiketleme, arama, içe aktarma ve tarayıcı eklentileri günlük kullanımda oldukça yeterlidir. SQLite kullanması yedeklemeyi de kolaylaştırır: Çoğu durumda veritabanı dosyasını güvenli biçimde kopyalamak yeterlidir.</p>

<h3 id="shaarli">Shaarli</h3>

<p>Shaarli, eski bir dizüstünü sunucuya dönüştürenlerin kahramanıdır. PHP çalıştırabilen mütevazı bir sunucuda yaşayabilir ve veritabanı sunucusu gerektirmez. Arayüzü rakipleri kadar modern değildir; fakat taşınabilirlik ve sadelik konusunda oldukça güçlüdür.</p>

<h2 id="docker-ile-linkding-kurulumu">Docker ile Linkding kurulumu</h2>

<p>Aşağıdaki <code class="language-plaintext highlighter-rouge">compose.yaml</code>, Linkding servisini başlatır ve verileri kalıcı bir klasörde tutar:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">services</span><span class="pi">:</span>
  <span class="na">linkding</span><span class="pi">:</span>
    <span class="na">image</span><span class="pi">:</span> <span class="s">sissbruecker/linkding:latest</span>
    <span class="na">container_name</span><span class="pi">:</span> <span class="s">linkding</span>
    <span class="na">ports</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s2">"</span><span class="s">9090:9090"</span>
    <span class="na">volumes</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">./data:/etc/linkding/data</span>
    <span class="na">environment</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">LD_SUPERUSER_NAME=admin</span>
      <span class="pi">-</span> <span class="s">LD_SUPERUSER_PASSWORD=guclu-bir-parola</span>
    <span class="na">restart</span><span class="pi">:</span> <span class="s">unless-stopped</span>
</code></pre></div></div>

<p>Dosyanın bulunduğu dizinde şu komutu çalıştır:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker compose up <span class="nt">-d</span>
</code></pre></div></div>

<p>Ardından <code class="language-plaintext highlighter-rouge">http://sunucu-adresi:9090</code> üzerinden giriş yapabilirsin. <code class="language-plaintext highlighter-rouge">volumes</code> bölümü, konteyner silinse bile kayıtların <code class="language-plaintext highlighter-rouge">data</code> klasöründe kalmasını sağlar. Gerçek kullanımda güçlü parola, HTTPS ve düzenli yedekleme şarttır; yönetim panelini doğrudan internete açmak iyi bir macera türü değildir.</p>

<h2 id="hangisini-seçmelisin">Hangisini seçmelisin?</h2>

<p>Kalıcı web arşivi ve ekip paylaşımı istiyorsan <strong>Linkwarden</strong>, hızlı ve dengeli bir kişisel sistem arıyorsan <strong>Linkding</strong>, en düşük kaynak tüketimiyle bağımsızlık hedefliyorsan <strong>Shaarli</strong> seç. En iyi araç, yüzlerce özelliği olan değil, yeni bağlantı eklemeyi erteletmeyecek kadar rahat olandır. Sistemi seçtikten sonra az sayıda tutarlı etiket belirle, tarayıcıdaki eski yer imlerini içe aktar ve otomatik yedekleme kur. Dijital çekmecen sonunda gerçekten düzenli kalabilir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="yer imi" /><category term="linkwarden" /><category term="linkding" /><category term="shaarli" /><category term="self-hosted" /><category term="docker" /><summary type="html"><![CDATA[Tarayıcı yer imleri bir süre sonra çekmecedeki kablolara benzer: Hepsinin önemli olduğuna eminsindir ama hangisinin ne işe yaradığını bulamazsın. Linkwarden, Linkding ve Shaarli; bağlantıları etiketleyerek saklamayı, aramayı ve kendi sunucunda yönetmeyi sağlayan açık kaynaklı yer imi araçlarıdır. Böylece tarayıcıya veya ticari bir servise bağımlı kalmadan kişisel bir dijital kütüphane kurabilirsin.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/dijital-hafizani-kur-71.png" /><media:content medium="image" url="https://program.sonsuz.us/img/dijital-hafizani-kur-71.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Dosyalar Güvende: Duplicati, BorgBackup ve Restic Karşılaştırması</title><link href="https://program.sonsuz.us/posts/dosyalar-guvende-duplicati-borgbackup-ve-restic-karsilastirmasi/" rel="alternate" type="text/html" title="Dosyalar Güvende: Duplicati, BorgBackup ve Restic Karşılaştırması" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/dosyalar-guvende-duplicati-borgbackup-ve-restic-karsilastirmasi</id><content type="html" xml:base="https://program.sonsuz.us/posts/dosyalar-guvende-duplicati-borgbackup-ve-restic-karsilastirmasi/"><![CDATA[<p>Bir diskin bozulması, yanlışlıkla çalıştırılan bir silme komutu veya fidye yazılımı, yılların verisini saniyeler içinde erişilemez hâle getirebilir. Neyse ki Duplicati, BorgBackup ve Restic; şifreleme, sıkıştırma ve artımlı yedekleme gibi modern özelliklerle “Keşke yedek alsaydım!” cümlesini tarihe gömmeyi amaçlıyor.
``</p>

<h2 id="sağlam-bir-yedekleme-sisteminin-mantığı">Sağlam bir yedekleme sisteminin mantığı</h2>

<p>Yedekleme, dosyaları başka bir klasöre kopyalamaktan ibaret değildir. Güvenilir bir plan için yaygın <strong>3-2-1 kuralı</strong> uygulanabilir:</p>

<ul>
  <li>Verinin en az <strong>3 kopyası</strong> bulunmalı.</li>
  <li>Kopyalar <strong>2 farklı ortamda</strong> tutulmalı.</li>
  <li>Kopyalardan <strong>1 tanesi uzak konumda</strong> olmalı.</li>
</ul>

<p>Depolama ihtiyacını azaltmak için üç araç da artımlı yedekleme yaklaşımından yararlanır. İlk çalıştırmada tüm veri saklanırken sonraki çalıştırmalarda yalnızca değişiklikler gönderilir. Basitleştirilmiş depolama hesabı şöyledir:</p>

\[S = F + \sum_{i=1}^{n} \Delta_i\]

<p>Burada $F$ ilk tam yedeğin boyutunu, $\Delta_i$ ise her çalıştırmada değişen veri miktarını temsil eder. Tekilleştirme sayesinde aynı veri bloklarının tekrar saklanması önlenebilir. Örneğin 10 GB’lık bir dosyanın yalnızca küçük bir bölümü değiştiğinde yeniden 10 GB göndermek gerekmez.</p>

<h2 id="üç-aracın-karşılaştırması">Üç aracın karşılaştırması</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Duplicati</th>
      <th>BorgBackup</th>
      <th>Restic</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kullanım biçimi</td>
      <td>Web arayüzü ve CLI</td>
      <td>Komut satırı</td>
      <td>Komut satırı</td>
    </tr>
    <tr>
      <td>İşletim sistemi</td>
      <td>Windows, Linux, macOS</td>
      <td>Özellikle Linux/macOS</td>
      <td>Windows, Linux, macOS</td>
    </tr>
    <tr>
      <td>Tekilleştirme</td>
      <td>Var</td>
      <td>Çok güçlü</td>
      <td>Var</td>
    </tr>
    <tr>
      <td>Şifreleme</td>
      <td>AES-256</td>
      <td>Yerleşik</td>
      <td>Yerleşik</td>
    </tr>
    <tr>
      <td>Uzak depolama</td>
      <td>Çok sayıda bulut servisi</td>
      <td>Genellikle SSH</td>
      <td>S3, SFTP ve çeşitli servisler</td>
    </tr>
    <tr>
      <td>İdeal kullanıcı</td>
      <td>Görsel arayüz isteyenler</td>
      <td>Performans odaklı Linux kullanıcıları</td>
      <td>Taşınabilirlik isteyenler</td>
    </tr>
  </tbody>
</table>

<p><strong>Duplicati</strong>, tarayıcıdan yönetilen arayüzü sayesinde zamanlama, hedef seçimi ve geri yükleme işlemlerini kolaylaştırır. Google Drive, OneDrive ve S3 gibi hedeflere doğrudan bağlanabilmesi önemli bir avantajdır. Buna karşılık büyük yedek kümelerinde veritabanı bakımı gerekebilir.</p>

<p><strong>BorgBackup</strong>, içerik tanımlı parçalama ve güçlü tekilleştirme özellikleriyle özellikle Linux sunucularında parlar. Depoların SSH üzerinden kullanılabilmesi güvenli ve hızlı bir yapı sunar. Ancak grafik arayüz bekleyen kullanıcılar için biraz fazla terminal kokabilir.</p>

<p><strong>Restic</strong> ise sade komutları, tek dosyalık kurulumu ve platformlar arası desteğiyle öne çıkar. Şifreleme varsayılan tasarımın parçasıdır; yedek deposu ele geçirilse bile parola olmadan içerik okunamaz.</p>

<h2 id="borgbackup-ile-örnek-yedekleme">BorgBackup ile örnek yedekleme</h2>

<p>Önce şifreli bir depo oluşturulur, ardından proje dizini arşivlenir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>borg init <span class="nt">--encryption</span><span class="o">=</span>repokey-blake2 /mnt/backup/borg-repo
borg create <span class="nt">--stats</span> /mnt/backup/borg-repo::proje-<span class="o">{</span>now<span class="o">}</span> ~/projeler
</code></pre></div></div>

<p>İlk komut şifreli depoyu hazırlar. İkinci komut, tarih bilgisini taşıyan yeni bir anlık görüntü oluşturur. Eski yedekleri kontrollü biçimde temizlemek için şu politika uygulanabilir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>borg prune <span class="nt">--list</span> /mnt/backup/borg-repo <span class="se">\</span>
  <span class="nt">--keep-daily</span><span class="o">=</span>7 <span class="nt">--keep-weekly</span><span class="o">=</span>4 <span class="nt">--keep-monthly</span><span class="o">=</span>6
</code></pre></div></div>

<p>Bu komut son yedi günlük, dört haftalık ve altı aylık yedeği korur.</p>

<h2 id="restic-ile-uzak-hedef-kullanımı">Restic ile uzak hedef kullanımı</h2>

<p>Restic deposu SFTP üzerinde hazırlanabilir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">RESTIC_REPOSITORY</span><span class="o">=</span>sftp:user@sunucu:/yedekler/restic
restic init
restic backup ~/Belgeler ~/Fotoğraflar
restic check
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">backup</code> verileri şifreleyerek gönderirken <code class="language-plaintext highlighter-rouge">check</code>, depo bütünlüğünü denetler. Parola otomasyon sırasında açıkça yazılmamalı; izinleri sınırlandırılmış bir parola dosyası veya güvenli sır yönetim sistemi kullanılmalıdır.</p>

<h2 id="hangisini-seçmeli">Hangisini seçmeli?</h2>

<p>Masaüstünde kolay yönetim ve bulut bağlantıları için <strong>Duplicati</strong>, Linux sunucusunda yüksek verimlilik için <strong>BorgBackup</strong>, farklı sistemlerde sade ve güvenli kullanım için <strong>Restic</strong> güçlü adaydır. Hangi araç seçilirse seçilsin, yalnızca yedek almak yeterli değildir. Düzenli geri yükleme testi yapılmayan bir yedek, açılana kadar Schrödinger’in yedeğidir: Hem vardır hem yoktur!</p>

<p><img src="/img/dosyalar-guvende-duplicati-70.svg" alt="dosyalar-guvende-duplicati-70" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="yedekleme" /><category term="duplicati" /><category term="borgbackup" /><category term="restic" /><category term="veri güvenliği" /><category term="linux" /><summary type="html"><![CDATA[Bir diskin bozulması, yanlışlıkla çalıştırılan bir silme komutu veya fidye yazılımı, yılların verisini saniyeler içinde erişilemez hâle getirebilir. Neyse ki Duplicati, BorgBackup ve Restic; şifreleme, sıkıştırma ve artımlı yedekleme gibi modern özelliklerle “Keşke yedek alsaydım!” cümlesini tarihe gömmeyi amaçlıyor.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/dosyalar-guvende-duplicati-70.png" /><media:content medium="image" url="https://program.sonsuz.us/img/dosyalar-guvende-duplicati-70.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Görsel Bulmacalar Olmadan CAPTCHA: ALTCHA, Friendly Captcha ve mCaptcha</title><link href="https://program.sonsuz.us/posts/gorsel-bulmacalar-olmadan-captcha-altcha-friendly-captcha-ve-mcaptcha/" rel="alternate" type="text/html" title="Görsel Bulmacalar Olmadan CAPTCHA: ALTCHA, Friendly Captcha ve mCaptcha" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/gorsel-bulmacalar-olmadan-captcha-altcha-friendly-captcha-ve-mcaptcha</id><content type="html" xml:base="https://program.sonsuz.us/posts/gorsel-bulmacalar-olmadan-captcha-altcha-friendly-captcha-ve-mcaptcha/"><![CDATA[<p>Trafik ışığı seçmekten motosiklet aramaya kadar klasik CAPTCHA’lar kullanıcıları küçük bir sınava sokar. ALTCHA, Friendly Captcha ve mCaptcha ise “İnsan olduğunu kanıtla” yaklaşımını tersine çevirir: Kullanıcı yerine tarayıcı, arka planda küçük bir hesaplama yapar. Böylece erişilebilirlik, gizlilik ve kullanıcı deneyimi açısından daha dost canlısı bir savunma katmanı ortaya çıkar.</p>

<p>``</p>

<h2 id="temel-fikir-proof-of-work">Temel fikir: Proof of Work</h2>

<p>Bu sistemlerin merkezinde <strong>iş ispatı</strong> veya benzeri görünmez doğrulama mekanizmaları bulunur. Sunucu, istemciye çözülmesi ölçülü miktarda işlem gerektiren bir problem verir. Tarayıcı çözümü bulur; sunucu ise sonucu çok daha düşük maliyetle doğrular.</p>

<p>Basitleştirilmiş bir problem şöyle düşünülebilir:</p>

\[H(\text{challenge} \parallel n) &lt; T\]

<p>Burada $H$ bir özet fonksiyonu, $n$ tarayıcının aradığı sayı ve $T$ zorluk eşiğidir. Eşik küçüldükçe uygun sayı bulmak zorlaşır. Ortalama hesaplama maliyeti yaklaşık olarak:</p>

\[E[\text{deneme}] \approx \frac{2^b}{T}\]

<p>şeklinde yorumlanabilir. Meşru bir kullanıcı için birkaç yüz milisaniyelik iş önemsizdir; milyonlarca sahte istek gönderen bot açısından aynı maliyet çarpılarak büyür. Yine de bu yöntem botları sihirli biçimde yok etmez, yalnızca saldırının ekonomisini bozar.</p>

<h2 id="üç-çözümün-karşılaştırması">Üç çözümün karşılaştırması</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>ALTCHA</th>
      <th>Friendly Captcha</th>
      <th>mCaptcha</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ana yaklaşım</td>
      <td>Proof of Work tabanlı challenge</td>
      <td>Arka planda kriptografik puzzle</td>
      <td>Uyarlanabilir Proof of Work</td>
    </tr>
    <tr>
      <td>Kullanıcı etkileşimi</td>
      <td>Genellikle tek kutu veya görünmez akış</td>
      <td>Çoğunlukla görünmez</td>
      <td>Görünmez doğrulama</td>
    </tr>
    <tr>
      <td>Self-hosting</td>
      <td>Güçlü ve esnek</td>
      <td>Ürüne/plana göre değerlendirilir</td>
      <td>Temel odak noktalarından biri</td>
    </tr>
    <tr>
      <td>Entegrasyon tarzı</td>
      <td>Açık kaynak kütüphane ve widget</td>
      <td>Yönetilen servis ve SDK’lar</td>
      <td>Açık kaynak sunucu kurulumu</td>
    </tr>
    <tr>
      <td>Uygun senaryo</td>
      <td>Kontrol isteyen geliştiriciler</td>
      <td>Hızlı SaaS entegrasyonu</td>
      <td>Tam bağımsız altyapı isteyenler</td>
    </tr>
  </tbody>
</table>

<p><strong>ALTCHA</strong>, sade protokolü ve self-hosting seçeneğiyle uygulama mimarisine kolayca yerleşir. <strong>Friendly Captcha</strong>, operasyon yükünü azaltmak isteyen ekipler için yönetilen hizmet deneyimine odaklanır. <strong>mCaptcha</strong> ise açık kaynaklı, bağımsız ve uyarlanabilir bir CAPTCHA altyapısı kurmak isteyenler açısından dikkat çekicidir.</p>

<h2 id="altcha-ile-örnek-sunucu-akışı">ALTCHA ile örnek sunucu akışı</h2>

<p>Aşağıdaki Express örneği bir challenge üretir ve tarayıcıdan gelen çözümü doğrular:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nx">express</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">express</span><span class="dl">"</span><span class="p">;</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">createChallenge</span><span class="p">,</span> <span class="nx">verifySolution</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">altcha-lib</span><span class="dl">"</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="nf">express</span><span class="p">();</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">use</span><span class="p">(</span><span class="nx">express</span><span class="p">.</span><span class="nf">json</span><span class="p">());</span>

<span class="kd">const</span> <span class="nx">hmacKey</span> <span class="o">=</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">ALTCHA_HMAC_KEY</span><span class="p">;</span>

<span class="nx">app</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="dl">"</span><span class="s2">/captcha/challenge</span><span class="dl">"</span><span class="p">,</span> <span class="k">async </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">challenge</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">createChallenge</span><span class="p">({</span>
    <span class="nx">hmacKey</span><span class="p">,</span>
    <span class="na">maxNumber</span><span class="p">:</span> <span class="mi">100000</span>
  <span class="p">});</span>

  <span class="nx">res</span><span class="p">.</span><span class="nf">json</span><span class="p">(</span><span class="nx">challenge</span><span class="p">);</span>
<span class="p">});</span>

<span class="nx">app</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">"</span><span class="s2">/contact</span><span class="dl">"</span><span class="p">,</span> <span class="k">async </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">valid</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">verifySolution</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">altcha</span><span class="p">,</span> <span class="nx">hmacKey</span><span class="p">);</span>

  <span class="k">if </span><span class="p">(</span><span class="o">!</span><span class="nx">valid</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">res</span><span class="p">.</span><span class="nf">status</span><span class="p">(</span><span class="mi">400</span><span class="p">).</span><span class="nf">json</span><span class="p">({</span> <span class="na">error</span><span class="p">:</span> <span class="dl">"</span><span class="s2">CAPTCHA doğrulanamadı</span><span class="dl">"</span> <span class="p">});</span>
  <span class="p">}</span>

  <span class="nx">res</span><span class="p">.</span><span class="nf">json</span><span class="p">({</span> <span class="na">success</span><span class="p">:</span> <span class="kc">true</span> <span class="p">});</span>
<span class="p">});</span>

<span class="nx">app</span><span class="p">.</span><span class="nf">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">);</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">maxNumber</code>, istemcinin yapabileceği maksimum arama miktarını sınırlar. HMAC anahtarı challenge’ın sunucu tarafından üretildiğini kanıtlar; bu anahtar istemciye kesinlikle gönderilmemelidir. Kullanılan kütüphane sürümüne göre fonksiyon imzalarının kontrol edilmesi de önemlidir.</p>

<h2 id="hangisini-seçmeli">Hangisini seçmeli?</h2>

<p>Hızlı entegrasyon ve yönetilen altyapı istiyorsanız Friendly Captcha pratik olabilir. Veriyi, anahtarları ve doğrulama sürecini kendi sisteminizde tutmak istiyorsanız ALTCHA daha hafif bir seçenek sunar. Tamamen açık kaynak bir CAPTCHA servisini bağımsız çalıştırmak ve iş yükünü dinamik ayarlamak istiyorsanız mCaptcha güçlü bir adaydır.</p>

<p>Hiçbiri tek başına yeterli savunma değildir. CAPTCHA’yı <strong>rate limiting</strong>, IP ve hesap bazlı kota, tekrar saldırısı engelleme, kısa challenge süresi ve davranışsal sinyallerle destekleyin. Mobil cihazlarda aşırı zorluk pil tüketebilir; çok düşük zorluk ise bot maliyetini artırmaz. En iyi ayar, güvenlik ile gerçek kullanıcıların bekleme süresi arasındaki dengedir.</p>

<p><img src="/img/gorsel-bulmacalar-olmadan-80.svg" alt="gorsel-bulmacalar-olmadan-80" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="captcha" /><category term="altcha" /><category term="friendly-captcha" /><category term="mcaptcha" /><category term="web-güvenliği" /><category term="proof-of-work" /><summary type="html"><![CDATA[Trafik ışığı seçmekten motosiklet aramaya kadar klasik CAPTCHA’lar kullanıcıları küçük bir sınava sokar. ALTCHA, Friendly Captcha ve mCaptcha ise “İnsan olduğunu kanıtla” yaklaşımını tersine çevirir: Kullanıcı yerine tarayıcı, arka planda küçük bir hesaplama yapar. Böylece erişilebilirlik, gizlilik ve kullanıcı deneyimi açısından daha dost canlısı bir savunma katmanı ortaya çıkar.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/gorsel-bulmacalar-olmadan-80.png" /><media:content medium="image" url="https://program.sonsuz.us/img/gorsel-bulmacalar-olmadan-80.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Hatalar Kaçmadan Yakalayın: Sentry, GlitchTip ve Bugsink Karşılaştırması</title><link href="https://program.sonsuz.us/posts/hatalar-kacmadan-yakalayin-sentry-glitchtip-ve-bugsink-karsilastirmasi/" rel="alternate" type="text/html" title="Hatalar Kaçmadan Yakalayın: Sentry, GlitchTip ve Bugsink Karşılaştırması" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/hatalar-kacmadan-yakalayin-sentry-glitchtip-ve-bugsink-karsilastirmasi</id><content type="html" xml:base="https://program.sonsuz.us/posts/hatalar-kacmadan-yakalayin-sentry-glitchtip-ve-bugsink-karsilastirmasi/"><![CDATA[<p>Uygulamanız geliştirme ortamında kusursuz çalışırken üretimde beklenmedik bir hata verebilir. Kullanıcının yalnızca “sayfa açılmadı” diye tarif ettiği bu olayın nedenini bulmak ise samanlıkta istisna aramaya benzer. Hata takip sistemleri; istisnaları, çağrı yığınlarını, kullanıcı etkileşimlerini ve ortam bilgilerini merkezi bir yerde toplayarak bu süreci hızlandırır. Bu alandaki popüler seçeneklerden Sentry, GlitchTip ve Bugsink aynı probleme farklı ölçek ve sadelik seviyeleriyle yaklaşır.</p>

<p><img src="/img/hatalar-kacmadan-yakalayin-56.svg" alt="hatalar-kacmadan-yakalayin-56" /></p>

<p>``</p>

<h2 id="hata-takip-sistemi-nasıl-çalışır">Hata takip sistemi nasıl çalışır?</h2>

<p>Uygulamaya eklenen SDK, yakalanmamış bir istisna oluştuğunda bir <strong>hata olayı</strong> üretir. Bu olay genellikle hata mesajını, stack trace bilgisini, sürümü, çalışma ortamını ve isteğe bağlı kullanıcı bağlamını içerir. Veriler bir DSN adresi üzerinden sunucuya gönderilir.</p>

<p>Sistem, benzer olayları tek bir sorun altında gruplandırmaya çalışır. Böylece aynı <code class="language-plaintext highlighter-rouge">NullReferenceException</code> hatası bin kez oluştuğunda panelde bin bağımsız kayıt yerine, gerçekleşme sayacı yükselen tek bir sorun görürüz.</p>

<p>Belirli sürede oluşan olay sayısını $E$, süreyi dakika cinsinden $t$ kabul edersek hata yoğunluğu şöyle ifade edilebilir:</p>

\[R = \frac{E}{t}\]

<p>Örneğin 10 dakikada 500 olay alınması, $R = 50$ olay/dakika anlamına gelir. Ancak yüksek sayı her zaman daha kritik hata demek değildir. Etkilenen kullanıcı sayısı, hata oranı ve işlemin önemi birlikte değerlendirilmelidir.</p>

<h2 id="üç-aracın-kısa-karşılaştırması">Üç aracın kısa karşılaştırması</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Sentry</th>
      <th>GlitchTip</th>
      <th>Bugsink</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Temel yaklaşım</td>
      <td>Kapsamlı gözlemlenebilirlik platformu</td>
      <td>Açık kaynaklı, Sentry uyumlu alternatif</td>
      <td>Hafif ve sade hata takibi</td>
    </tr>
    <tr>
      <td>Barındırma</td>
      <td>Bulut veya self-hosted</td>
      <td>Bulut veya self-hosted</td>
      <td>Özellikle self-hosted kullanım</td>
    </tr>
    <tr>
      <td>Kurulum yükü</td>
      <td>Self-hosted sürümde daha yüksek</td>
      <td>Orta düzey</td>
      <td>Görece düşük</td>
    </tr>
    <tr>
      <td>Performans izleme</td>
      <td>Gelişmiş</td>
      <td>Temel ve orta seviye ihtiyaçlara uygun</td>
      <td>Hata takibine odaklı</td>
    </tr>
    <tr>
      <td>İdeal kullanım</td>
      <td>Büyük ekipler ve ayrıntılı analiz</td>
      <td>Açık kaynak ve maliyet dengesi</td>
      <td>Küçük ekipler, kişisel sunucular</td>
    </tr>
  </tbody>
</table>

<p><strong>Sentry</strong>, hata takibinin yanında performans izleme, dağıtık tracing, sürüm takibi ve oturum tekrarı gibi geniş özellikler sunar. Yönetilen bulut hizmeti operasyon yükünü azaltır; fakat yoğun trafik, veri kotası ve gizlilik gereksinimleri dikkatle değerlendirilmelidir.</p>

<p><strong>GlitchTip</strong>, Sentry SDK’larıyla uyumlu açık kaynaklı bir deneyim sağlamayı amaçlar. Arayüzü daha sade, self-hosted kurulumu ise genellikle daha ulaşılabilirdir. Sentry’nin bütün ileri analiz özelliklerini beklemeyen ekipler için güçlü bir dengedir.</p>

<p><strong>Bugsink</strong>, “önce hatayı yakalayalım” yaklaşımına yakındır. Daha az bileşenle çalışması, küçük sunucularda yönetimi kolaylaştırabilir. Kapsamlı observability platformu yerine anlaşılır bir hata kutusu isteyen projelere uygundur.</p>

<h2 id="python-uygulamasına-sdk-eklemek">Python uygulamasına SDK eklemek</h2>

<p>Üç ürün de Sentry protokolüyle uyumlu kurulum senaryoları sunabildiğinden Python tarafında çoğunlukla resmi SDK kullanılabilir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">sentry_sdk</span>

<span class="n">sentry_sdk</span><span class="p">.</span><span class="nf">init</span><span class="p">(</span>
    <span class="n">dsn</span><span class="o">=</span><span class="sh">"</span><span class="s">https://anahtar@hata-sunucusu.example/1</span><span class="sh">"</span><span class="p">,</span>
    <span class="n">environment</span><span class="o">=</span><span class="sh">"</span><span class="s">production</span><span class="sh">"</span><span class="p">,</span>
    <span class="n">release</span><span class="o">=</span><span class="sh">"</span><span class="s">magaza-api@2.4.0</span><span class="sh">"</span><span class="p">,</span>
    <span class="n">traces_sample_rate</span><span class="o">=</span><span class="mf">0.1</span><span class="p">,</span>
<span class="p">)</span>

<span class="k">def</span> <span class="nf">fiyat_hesapla</span><span class="p">(</span><span class="n">toplam</span><span class="p">,</span> <span class="n">adet</span><span class="p">):</span>
    <span class="k">return</span> <span class="n">toplam</span> <span class="o">/</span> <span class="n">adet</span>

<span class="nf">fiyat_hesapla</span><span class="p">(</span><span class="mi">250</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</code></pre></div></div>

<p>Bu kodda DSN, olayların gideceği projeyi belirtir. <code class="language-plaintext highlighter-rouge">environment</code> üretim ve test kayıtlarını ayırır; <code class="language-plaintext highlighter-rouge">release</code> ise hatanın hangi sürümde başladığını bulmayı kolaylaştırır. <code class="language-plaintext highlighter-rouge">traces_sample_rate=0.1</code>, performans işlemlerinin yaklaşık yüzde 10’unu örnekler. Ürün ve sürüme göre desteklenen SDK özellikleri değişebileceğinden uyumluluk belgeleri kontrol edilmelidir.</p>

<h2 id="hangisini-seçmeli">Hangisini seçmeli?</h2>

<p>Hazır servis, gelişmiş analiz ve minimum bakım istiyorsanız Sentry mantıklı başlangıçtır. Veriyi kendi altyapınızda tutmak, açık kaynak kullanmak ve daha ölçülü kaynak tüketmek istiyorsanız GlitchTip değerlendirilebilir. Yalnızca temel hata toplama, gruplama ve bildirim özelliklerine ihtiyacınız varsa Bugsink sadeliğiyle öne çıkar.</p>

<p>Seçimden önce günlük olay hacmini, saklama süresini ve örnekleme oranını hesaplayın. Ayrıca parola, erişim belirteci ve kişisel veri gibi hassas bilgileri SDK filtreleriyle temizleyin. Çünkü iyi bir hata takip sistemi yalnızca çok veri toplayan değil, doğru veriyi güvenli biçimde anlamlı hale getiren sistemdir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="sentry" /><category term="glitchtip" /><category term="bugsink" /><category term="hata-takibi" /><category term="observability" /><category term="python" /><summary type="html"><![CDATA[Uygulamanız geliştirme ortamında kusursuz çalışırken üretimde beklenmedik bir hata verebilir. Kullanıcının yalnızca “sayfa açılmadı” diye tarif ettiği bu olayın nedenini bulmak ise samanlıkta istisna aramaya benzer. Hata takip sistemleri; istisnaları, çağrı yığınlarını, kullanıcı etkileşimlerini ve ortam bilgilerini merkezi bir yerde toplayarak bu süreci hızlandırır. Bu alandaki popüler seçeneklerden Sentry, GlitchTip ve Bugsink aynı probleme farklı ölçek ve sadelik seviyeleriyle yaklaşır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/hatalar-kacmadan-yakalayin-56.png" /><media:content medium="image" url="https://program.sonsuz.us/img/hatalar-kacmadan-yakalayin-56.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Kendi Bug Bounty ve Güvenli Hata Bildirim Sistemini Tasarlamak</title><link href="https://program.sonsuz.us/posts/kendi-bug-bounty-ve-guvenli-hata-bildirim-sistemini-tasarlamak/" rel="alternate" type="text/html" title="Kendi Bug Bounty ve Güvenli Hata Bildirim Sistemini Tasarlamak" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/kendi-bug-bounty-ve-guvenli-hata-bildirim-sistemini-tasarlamak</id><content type="html" xml:base="https://program.sonsuz.us/posts/kendi-bug-bounty-ve-guvenli-hata-bildirim-sistemini-tasarlamak/"><![CDATA[<p><img src="/img/kendi-bug-bounty-46.svg" alt="kendi-bug-bounty-46" /></p>

<p>Bir güvenlik araştırmacısı kritik bir açık bulduğunda kime, nasıl ve hangi kanıtlarla ulaşacağını bilmelidir. Open Bug Bounty veya HackerOne benzeri özel bir sistem; araştırmacıları, güvenlik ekiplerini ve ürün sahiplerini aynı iş akışında buluşturur. Fakat bu proje, sıradan bir destek talebi uygulamasından daha fazlasıdır: hassas verileri korumalı, mükerrer raporları yakalamalı ve kontrollü açıklama sürecini yönetmelidir.
``</p>

<h2 id="temel-iş-akışı">Temel iş akışı</h2>

<p>Bir raporun yaşam döngüsü durum makinesi olarak modellenebilir:</p>

<p><code class="language-plaintext highlighter-rouge">Taslak → Gönderildi → İnceleniyor → Doğrulandı → Çözüldü → Açıklandı</code></p>

<p>Rapor geçersizse <strong>Reddedildi</strong>, daha önce bildirilmişse <strong>Mükerrer</strong> durumuna taşınır. Durum makinesi kullanmak, örneğin çözülmüş bir raporun yanlışlıkla yeniden “gönderildi” yapılmasını engeller.</p>

<table>
  <thead>
    <tr>
      <th>Rol</th>
      <th>Yetki</th>
      <th>Görememesi gerekenler</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Araştırmacı</td>
      <td>Rapor oluşturma, kanıt ekleme</td>
      <td>Diğer özel raporlar</td>
    </tr>
    <tr>
      <td>Triyaj uzmanı</td>
      <td>Doğrulama, sınıflandırma</td>
      <td>Finansal yönetim ayarları</td>
    </tr>
    <tr>
      <td>Program sahibi</td>
      <td>Kapsam ve ödül yönetimi</td>
      <td>Gereksiz kişisel veriler</td>
    </tr>
    <tr>
      <td>Yönetici</td>
      <td>Rol ve sistem yönetimi</td>
      <td>Şifresiz gizli içerik</td>
    </tr>
  </tbody>
</table>

<p>Bu ayrım, <strong>en az ayrıcalık ilkesi</strong> üzerine kurulmalıdır. Yalnızca giriş yapmış olmak yeterli değildir; her API isteğinde rol, kaynak sahipliği ve program üyeliği ayrıca denetlenmelidir.</p>

<h2 id="önem-derecesi-ve-ödül-hesabı">Önem derecesi ve ödül hesabı</h2>

<p>Açıkların önceliği CVSS gibi standartlarla belirlenebilir. Daha sade bir özel puanlama için şu model kullanılabilir:</p>

\[Risk = Etki \times İstismarOlasılığı \times VarlıkKatsayısı\]

<p>Her değişken 1 ile 5 arasında seçilirse en yüksek risk puanı $5^3 = 125$ olur. Ödül ise taban tutar ve risk oranıyla hesaplanabilir:</p>

\[Ödül = TabanÖdül \times (Risk / 125)\]

<p>Ancak otomatik sonuç yalnızca öneri olmalıdır. Kaliteli açıklama, çalışan kavram kanıtı ve daha önce raporlanmış olma durumu nihai kararı değiştirebilir.</p>

<h2 id="veri-modeli-ve-güvenlik">Veri modeli ve güvenlik</h2>

<p>Temel tablolar <code class="language-plaintext highlighter-rouge">users</code>, <code class="language-plaintext highlighter-rouge">programs</code>, <code class="language-plaintext highlighter-rouge">assets</code>, <code class="language-plaintext highlighter-rouge">reports</code>, <code class="language-plaintext highlighter-rouge">comments</code>, <code class="language-plaintext highlighter-rouge">attachments</code>, <code class="language-plaintext highlighter-rouge">rewards</code> ve <code class="language-plaintext highlighter-rouge">audit_logs</code> olabilir. Rapor; başlık, etkilenen varlık, açıklık türü, tekrar üretme adımları, etki açıklaması ve çözüm önerisi içermelidir.</p>

<p>Kanıt dosyaları doğrudan herkese açık klasörlere konulmamalıdır. Nesne depolamada şifrelenmeli, kısa ömürlü imzalı bağlantılarla sunulmalı ve zararlı dosya taramasından geçirilmelidir. Parolalar Argon2id ile özetlenmeli; oturumlarda çok faktörlü kimlik doğrulama desteklenmelidir. Audit log kayıtları da “kim, neyi, ne zaman değiştirdi?” sorusunu yanıtlamalıdır.</p>

<h2 id="güvenli-durum-geçişi-örneği">Güvenli durum geçişi örneği</h2>

<p>Aşağıdaki FastAPI kodu, istemcinin istediği her duruma serbestçe geçmesini engeller:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">enum</span> <span class="kn">import</span> <span class="n">Enum</span>
<span class="kn">from</span> <span class="n">fastapi</span> <span class="kn">import</span> <span class="n">FastAPI</span><span class="p">,</span> <span class="n">HTTPException</span>

<span class="n">app</span> <span class="o">=</span> <span class="nc">FastAPI</span><span class="p">()</span>

<span class="k">class</span> <span class="nc">Status</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="n">Enum</span><span class="p">):</span>
    <span class="n">submitted</span> <span class="o">=</span> <span class="sh">"</span><span class="s">submitted</span><span class="sh">"</span>
    <span class="n">triage</span> <span class="o">=</span> <span class="sh">"</span><span class="s">triage</span><span class="sh">"</span>
    <span class="n">confirmed</span> <span class="o">=</span> <span class="sh">"</span><span class="s">confirmed</span><span class="sh">"</span>
    <span class="n">resolved</span> <span class="o">=</span> <span class="sh">"</span><span class="s">resolved</span><span class="sh">"</span>
    <span class="n">rejected</span> <span class="o">=</span> <span class="sh">"</span><span class="s">rejected</span><span class="sh">"</span>

<span class="n">ALLOWED</span> <span class="o">=</span> <span class="p">{</span>
    <span class="n">Status</span><span class="p">.</span><span class="n">submitted</span><span class="p">:</span> <span class="p">{</span><span class="n">Status</span><span class="p">.</span><span class="n">triage</span><span class="p">,</span> <span class="n">Status</span><span class="p">.</span><span class="n">rejected</span><span class="p">},</span>
    <span class="n">Status</span><span class="p">.</span><span class="n">triage</span><span class="p">:</span> <span class="p">{</span><span class="n">Status</span><span class="p">.</span><span class="n">confirmed</span><span class="p">,</span> <span class="n">Status</span><span class="p">.</span><span class="n">rejected</span><span class="p">},</span>
    <span class="n">Status</span><span class="p">.</span><span class="n">confirmed</span><span class="p">:</span> <span class="p">{</span><span class="n">Status</span><span class="p">.</span><span class="n">resolved</span><span class="p">},</span>
    <span class="n">Status</span><span class="p">.</span><span class="n">resolved</span><span class="p">:</span> <span class="nf">set</span><span class="p">(),</span>
    <span class="n">Status</span><span class="p">.</span><span class="n">rejected</span><span class="p">:</span> <span class="nf">set</span><span class="p">()</span>
<span class="p">}</span>

<span class="nd">@app.post</span><span class="p">(</span><span class="sh">"</span><span class="s">/reports/{report_id}/transition</span><span class="sh">"</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">transition</span><span class="p">(</span><span class="n">report_id</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">current</span><span class="p">:</span> <span class="n">Status</span><span class="p">,</span> <span class="n">target</span><span class="p">:</span> <span class="n">Status</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">target</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ALLOWED</span><span class="p">[</span><span class="n">current</span><span class="p">]:</span>
        <span class="k">raise</span> <span class="nc">HTTPException</span><span class="p">(</span><span class="mi">409</span><span class="p">,</span> <span class="sh">"</span><span class="s">Geçersiz durum geçişi</span><span class="sh">"</span><span class="p">)</span>

    <span class="c1"># Burada rol kontrolü ve veritabanı güncellemesi yapılır.
</span>    <span class="k">return</span> <span class="p">{</span><span class="sh">"</span><span class="s">report_id</span><span class="sh">"</span><span class="p">:</span> <span class="n">report_id</span><span class="p">,</span> <span class="sh">"</span><span class="s">status</span><span class="sh">"</span><span class="p">:</span> <span class="n">target</span><span class="p">}</span>
</code></pre></div></div>

<p>Gerçek uygulamada <code class="language-plaintext highlighter-rouge">current</code> değeri kullanıcıdan alınmamalı, veritabanından okunmalıdır. Güncelleme atomik bir işlem içinde yapılmalı ve audit log kaydı aynı işlemde oluşturulmalıdır.</p>

<h2 id="sistemi-olgunlaştıran-özellikler">Sistemi olgunlaştıran özellikler</h2>

<p>Mükerrer rapor tespiti için başlık benzerliği, açıklık türü ve etkilenen varlık birlikte değerlendirilebilir; ancak gizlilik nedeniyle araştırmacıya başka raporun ayrıntıları gösterilmemelidir. Bildirimler e-posta ve uygulama içi kanallardan iletilebilir. Oran sınırlama, CAPTCHA ve kötüye kullanım tespiti de spam saldırılarını azaltır.</p>

<p>Son olarak açık bir kapsam politikası hazırlayın: test edilebilen alan adları, yasak yöntemler, hizmet kesintisi kuralları, yanıt süreleri ve güvenli liman şartları net olsun. İyi bir bug bounty platformunun asıl süper gücü yalnızca kodu değil, araştırmacıyla kurulan güveni de korumasıdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="bug bounty" /><category term="siber güvenlik" /><category term="hata bildirimi" /><category term="güvenli yazılım" /><category term="api" /><category term="web geliştirme" /><summary type="html"><![CDATA[Bir güvenlik araştırmacısı kritik bir açık bulduğunda kime, nasıl ve hangi kanıtlarla ulaşacağını bilmelidir. Open Bug Bounty veya HackerOne benzeri özel bir sistem; araştırmacıları, güvenlik ekiplerini ve ürün sahiplerini aynı iş akışında buluşturur. Fakat bu proje, sıradan bir destek talebi uygulamasından daha fazlasıdır: hassas verileri korumalı, mükerrer raporları yakalamalı ve kontrollü açıklama sürecini yönetmelidir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/kendi-bug-bounty-46.png" /><media:content medium="image" url="https://program.sonsuz.us/img/kendi-bug-bounty-46.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Kendi RSS Okuyucunu Seç: FreshRSS, Miniflux ve Tiny Tiny RSS Karşılaştırması</title><link href="https://program.sonsuz.us/posts/kendi-rss-okuyucunu-sec-freshrss-miniflux-ve-tiny-tiny-rss-karsilastirmasi/" rel="alternate" type="text/html" title="Kendi RSS Okuyucunu Seç: FreshRSS, Miniflux ve Tiny Tiny RSS Karşılaştırması" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/kendi-rss-okuyucunu-sec-freshrss-miniflux-ve-tiny-tiny-rss-karsilastirmasi</id><content type="html" xml:base="https://program.sonsuz.us/posts/kendi-rss-okuyucunu-sec-freshrss-miniflux-ve-tiny-tiny-rss-karsilastirmasi/"><![CDATA[<p>İnternette sevdiğiniz siteleri tek tek ziyaret etmek yerine yeni içerikleri merkezi bir gelen kutusunda görmek ister misiniz? RSS okuyucuları tam olarak bunu sağlar. FreshRSS, Miniflux ve Tiny Tiny RSS ise verilerinizi üçüncü taraf platformlara teslim etmeden kendi sunucunuzda çalıştırabileceğiniz üç güçlü seçenektir. Gelin bu araçların çalışma mantığını, farklarını ve hangi senaryoda öne çıktıklarını inceleyelim.
``</p>
<h2 id="rss-okuyucu-nasıl-çalışır">RSS okuyucu nasıl çalışır?</h2>

<p>RSS, bir internet sitesinin güncel içeriklerini XML biçiminde yayımlamasını sağlayan standarttır. Akış içerisinde genellikle başlık, bağlantı, yayın tarihi, yazar ve içerik özeti bulunur. Okuyucu uygulama belirli aralıklarla bu XML belgesini indirir, daha önce görmediği kayıtları veritabanına ekler ve kullanıcıya okunabilir bir arayüz sunar.</p>

<p>Bir RSS sisteminin yaklaşık günlük istek sayısını şöyle düşünebiliriz:</p>

\[I = N \times \frac{24 \times 60}{T}\]

<p>Burada $N$ takip edilen akış sayısını, $T$ dakika cinsinden yenileme aralığını temsil eder. Örneğin 100 akışı 30 dakikada bir kontrol etmek teorik olarak günde $100 \times 48 = 4800$ HTTP isteği oluşturur. Bu nedenle çok sık güncelleme yapmak her zaman daha iyi değildir; hem sunucunuzu hem de içerik sağlayıcıları gereksiz yere yorabilir.</p>

<h2 id="üç-okuyucunun-karakteri">Üç okuyucunun karakteri</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>FreshRSS</th>
      <th>Miniflux</th>
      <th>Tiny Tiny RSS</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Temel teknoloji</td>
      <td>PHP</td>
      <td>Go</td>
      <td>PHP</td>
    </tr>
    <tr>
      <td>Arayüz yaklaşımı</td>
      <td>Geleneksel ve esnek</td>
      <td>Minimalist ve hızlı</td>
      <td>Yoğun özellikli</td>
    </tr>
    <tr>
      <td>Veritabanı</td>
      <td>SQLite, MySQL, PostgreSQL</td>
      <td>PostgreSQL</td>
      <td>PostgreSQL</td>
    </tr>
    <tr>
      <td>Eklenti desteği</td>
      <td>Güçlü</td>
      <td>Sınırlı</td>
      <td>Güçlü</td>
    </tr>
    <tr>
      <td>Kurulum kolaylığı</td>
      <td>Kolay</td>
      <td>Kolay</td>
      <td>Orta</td>
    </tr>
    <tr>
      <td>Kaynak tüketimi</td>
      <td>Düşük</td>
      <td>Çok düşük</td>
      <td>Orta</td>
    </tr>
    <tr>
      <td>İdeal kullanıcı</td>
      <td>Özelleştirme sevenler</td>
      <td>Sadelik arayanlar</td>
      <td>İleri düzey kullanıcılar</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/kendi-rss-okuyucunu-93.svg" alt="kendi-rss-okuyucunu-93" /></p>

<h3 id="freshrss">FreshRSS</h3>

<p>FreshRSS, dengeli bir çözüm arayanlar için güvenli tercihtir. Birden fazla veritabanını destekler, tema ve eklentilerle kişiselleştirilebilir. Klasörler, etiketler, filtreler ve çoklu kullanıcı desteği bakımından zengindir. Arayüzü ilk bakışta biraz klasik görünse de çok sayıda akışı yönetirken oldukça pratiktir.</p>

<h3 id="miniflux">Miniflux</h3>

<p>Miniflux, “az özellik, temiz deneyim” felsefesini benimser. Go ile geliştirildiği için hızlı çalışır ve düşük kaynak tüketir. Klavye kısayolları, sade okuma görünümü ve içerik temizleme yetenekleri başarılıdır. Ancak PostgreSQL zorunluluğu, yalnızca küçük bir SQLite dosyasıyla ilerlemek isteyen kullanıcılar için fazladan operasyon demektir.</p>

<h3 id="tiny-tiny-rss">Tiny Tiny RSS</h3>

<p>Tiny Tiny RSS, kısaca TT-RSS, ayrıntılı filtreleme ve eklenti seçenekleri isteyen deneyimli kullanıcılara hitap eder. Makaleleri kurallara göre etiketlemek, puanlamak veya işlemek mümkündür. Buna karşılık kurulumu ve bakımı diğer iki seçeneğe göre daha fazla dikkat ister. Güçlüdür; fakat kontrol panelindeki düğmelerle dostluk kurmanız biraz zaman alabilir.</p>

<h2 id="docker-ile-örnek-freshrss-kurulumu">Docker ile örnek FreshRSS kurulumu</h2>

<p>Aşağıdaki <code class="language-plaintext highlighter-rouge">compose.yaml</code> dosyası FreshRSS’i kalıcı veri alanı ve otomatik yeniden başlatma politikasıyla çalıştırır:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">services</span><span class="pi">:</span>
  <span class="na">freshrss</span><span class="pi">:</span>
    <span class="na">image</span><span class="pi">:</span> <span class="s">freshrss/freshrss:latest</span>
    <span class="na">container_name</span><span class="pi">:</span> <span class="s">freshrss</span>
    <span class="na">ports</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">8080:80</span>
    <span class="na">volumes</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">freshrss_data:/var/www/FreshRSS/data</span>
      <span class="pi">-</span> <span class="s">freshrss_extensions:/var/www/FreshRSS/extensions</span>
    <span class="na">environment</span><span class="pi">:</span>
      <span class="na">TZ</span><span class="pi">:</span> <span class="s">Europe/Istanbul</span>
      <span class="na">CRON_MIN</span><span class="pi">:</span> <span class="s1">'</span><span class="s">*/20'</span>
    <span class="na">restart</span><span class="pi">:</span> <span class="s">unless-stopped</span>

<span class="na">volumes</span><span class="pi">:</span>
  <span class="na">freshrss_data</span><span class="pi">:</span>
  <span class="na">freshrss_extensions</span><span class="pi">:</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">CRON_MIN</code> değeri akışların 20 dakikada bir yenilenmesini sağlar. Servisi başlatmak için dosyanın bulunduğu dizinde şu komut yeterlidir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker compose up <span class="nt">-d</span>
</code></pre></div></div>

<p>Ardından <code class="language-plaintext highlighter-rouge">http://sunucu-adresi:8080</code> adresini açarak kurulum sihirbazını tamamlayabilirsiniz. İnternet üzerinden erişim verecekseniz ters proxy, HTTPS ve düzenli yedekleme kullanmayı unutmayın.</p>

<h2 id="hangisini-seçmelisiniz">Hangisini seçmelisiniz?</h2>

<p>Hızlı karar formülü basit: Esneklik ve kolay kurulum istiyorsanız <strong>FreshRSS</strong>, dikkat dağıtmayan hafif bir sistem arıyorsanız <strong>Miniflux</strong>, ayrıntılı kurallar ve eklentiler sizin için vazgeçilmezse <strong>Tiny Tiny RSS</strong> seçin. Kararsız kalan çoğu kullanıcı için FreshRSS iyi bir başlangıç noktasıdır; minimalistlerin gönlünü ise büyük olasılıkla Miniflux çalacaktır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="rss" /><category term="freshrss" /><category term="miniflux" /><category term="tiny-tiny-rss" /><category term="self-hosted" /><category term="docker" /><summary type="html"><![CDATA[İnternette sevdiğiniz siteleri tek tek ziyaret etmek yerine yeni içerikleri merkezi bir gelen kutusunda görmek ister misiniz? RSS okuyucuları tam olarak bunu sağlar. FreshRSS, Miniflux ve Tiny Tiny RSS ise verilerinizi üçüncü taraf platformlara teslim etmeden kendi sunucunuzda çalıştırabileceğiniz üç güçlü seçenektir. Gelin bu araçların çalışma mantığını, farklarını ve hangi senaryoda öne çıktıklarını inceleyelim.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/kendi-rss-okuyucunu-93.png" /><media:content medium="image" url="https://program.sonsuz.us/img/kendi-rss-okuyucunu-93.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Kendi RSS Yayın Sistemini Kur: RSSHub, Feedgen ve WordPress RSS Rehberi</title><link href="https://program.sonsuz.us/posts/kendi-rss-yayin-sistemini-kur-rsshub-feedgen-ve-wordpress-rss-rehberi/" rel="alternate" type="text/html" title="Kendi RSS Yayın Sistemini Kur: RSSHub, Feedgen ve WordPress RSS Rehberi" /><published>2026-10-08T00:00:00+00:00</published><updated>2026-10-08T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/kendi-rss-yayin-sistemini-kur-rsshub-feedgen-ve-wordpress-rss-rehberi</id><content type="html" xml:base="https://program.sonsuz.us/posts/kendi-rss-yayin-sistemini-kur-rsshub-feedgen-ve-wordpress-rss-rehberi/"><![CDATA[<p>İnternetteki içerikleri tek tek ziyaret etmek yerine hepsini kronolojik bir akışta okumak kulağa küçük bir süper güç gibi gelir. RSS, tam olarak bunu sağlayan açık ve sade bir yayın standardıdır. Bu rehberde hazır WordPress akışlarından Python Feedgen ile özel yayın üretmeye, RSSHub sayesinde akışı bulunmayan siteleri takip etmeye kadar uzanan pratik bir sistem kuracağız.</p>

<p>``</p>

<h2 id="rss-nasıl-çalışır">RSS nasıl çalışır?</h2>

<p>RSS yayını, çoğunlukla XML biçiminde sunulan ve içerik kayıtlarını belirli kurallarla sıralayan bir belgedir. Bir RSS okuyucu, yayının URL’sini düzenli aralıklarla sorgular; yeni bir <code class="language-plaintext highlighter-rouge">guid</code> veya daha güncel bir tarih gördüğünde kaydı kullanıcıya gösterir.</p>

<p>Basitleştirilmiş bir RSS belgesi şöyledir:</p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;rss</span> <span class="na">version=</span><span class="s">"2.0"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;channel&gt;</span>
    <span class="nt">&lt;title&gt;</span>Teknoloji Günlüğü<span class="nt">&lt;/title&gt;</span>
    <span class="nt">&lt;link&gt;</span>https://ornek.com<span class="nt">&lt;/link&gt;</span>
    <span class="nt">&lt;item&gt;</span>
      <span class="nt">&lt;title&gt;</span>Yeni Yazı<span class="nt">&lt;/title&gt;</span>
      <span class="nt">&lt;link&gt;</span>https://ornek.com/yeni-yazi<span class="nt">&lt;/link&gt;</span>
      <span class="nt">&lt;guid&gt;</span>yazi-42<span class="nt">&lt;/guid&gt;</span>
    <span class="nt">&lt;/item&gt;</span>
  <span class="nt">&lt;/channel&gt;</span>
<span class="nt">&lt;/rss&gt;</span>
</code></pre></div></div>

<p>Sorgulama aralığı $T$, günlük istek sayısı ise yaklaşık $N$ olsun. Tek bir okuyucu için yük şu şekilde düşünülebilir:</p>

\[N = \frac{86400}{T}\]

<p>Örneğin her 30 dakikada bir kontrol yapıldığında $T=1800$ olur ve günde yaklaşık 48 istek gönderilir. Çok sık sorgulamak güncelliği artırır; ancak sunucu yükünü de büyütür. Önbellekleme bu dengenin gizli kahramanıdır.</p>

<h2 id="üç-yaklaşımın-karşılaştırması">Üç yaklaşımın karşılaştırması</h2>

<table>
  <thead>
    <tr>
      <th>Araç</th>
      <th>En uygun senaryo</th>
      <th>Güçlü yanı</th>
      <th>Dikkat edilmesi gereken</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>WordPress RSS</td>
      <td>WordPress içeriklerini yayınlamak</td>
      <td>Yerleşik ve zahmetsizdir</td>
      <td>Tema veya eklenti akışı değiştirebilir</td>
    </tr>
    <tr>
      <td>Feedgen</td>
      <td>Kendi verinden RSS üretmek</td>
      <td>Tam kontrol sağlar</td>
      <td>Barındırma ve güncelleme sana aittir</td>
    </tr>
    <tr>
      <td>RSSHub</td>
      <td>RSS sunmayan kaynakları izlemek</td>
      <td>Çok sayıda hazır rota içerir</td>
      <td>Kaynak değişince rota bozulabilir</td>
    </tr>
  </tbody>
</table>

<h2 id="wordpress-rss-akışını-kullanmak">WordPress RSS akışını kullanmak</h2>

<p>WordPress çoğu kurulumda RSS üretimini otomatik yapar. Ana yayın genellikle aşağıdaki adrestedir:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://siteadresi.com/feed/
</code></pre></div></div>

<p>Kategoriye özel yayın için <code class="language-plaintext highlighter-rouge">/category/yazilim/feed/</code>, yorumlar için <code class="language-plaintext highlighter-rouge">/comments/feed/</code> kullanılabilir. <code class="language-plaintext highlighter-rouge">functions.php</code> veya SEO eklentileriyle özet, görsel ve özel alanlar akışa eklenebilir. Ancak çekirdek dosyaları düzenlemek yerine çocuk tema ya da özel eklenti kullanmak güncellemelerde yaşanacak sürprizleri önler.</p>

<h2 id="python-feedgen-ile-özel-yayın">Python Feedgen ile özel yayın</h2>

<p>Veriler bir API’den, veritabanından veya küçük bir otomasyon betiğinden geliyorsa Feedgen oldukça kullanışlıdır:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">feedgen.feed</span> <span class="kn">import</span> <span class="n">FeedGenerator</span>

<span class="n">feed</span> <span class="o">=</span> <span class="nc">FeedGenerator</span><span class="p">()</span>
<span class="n">feed</span><span class="p">.</span><span class="nf">title</span><span class="p">(</span><span class="sh">"</span><span class="s">Haftalık Python Notları</span><span class="sh">"</span><span class="p">)</span>
<span class="n">feed</span><span class="p">.</span><span class="nf">link</span><span class="p">(</span><span class="n">href</span><span class="o">=</span><span class="sh">"</span><span class="s">https://ornek.com</span><span class="sh">"</span><span class="p">,</span> <span class="n">rel</span><span class="o">=</span><span class="sh">"</span><span class="s">alternate</span><span class="sh">"</span><span class="p">)</span>
<span class="n">feed</span><span class="p">.</span><span class="nf">description</span><span class="p">(</span><span class="sh">"</span><span class="s">Otomatik oluşturulan yazılım notları</span><span class="sh">"</span><span class="p">)</span>

<span class="n">entry</span> <span class="o">=</span> <span class="n">feed</span><span class="p">.</span><span class="nf">add_entry</span><span class="p">()</span>
<span class="n">entry</span><span class="p">.</span><span class="nf">id</span><span class="p">(</span><span class="sh">"</span><span class="s">python-101</span><span class="sh">"</span><span class="p">)</span>
<span class="n">entry</span><span class="p">.</span><span class="nf">title</span><span class="p">(</span><span class="sh">"</span><span class="s">Generator Mantığı</span><span class="sh">"</span><span class="p">)</span>
<span class="n">entry</span><span class="p">.</span><span class="nf">link</span><span class="p">(</span><span class="n">href</span><span class="o">=</span><span class="sh">"</span><span class="s">https://ornek.com/generator</span><span class="sh">"</span><span class="p">)</span>
<span class="n">entry</span><span class="p">.</span><span class="nf">description</span><span class="p">(</span><span class="sh">"</span><span class="s">Bellek dostu yineleyicilere giriş.</span><span class="sh">"</span><span class="p">)</span>

<span class="n">feed</span><span class="p">.</span><span class="nf">rss_file</span><span class="p">(</span><span class="sh">"</span><span class="s">rss.xml</span><span class="sh">"</span><span class="p">)</span>
</code></pre></div></div>

<p>Bu kod bir kanal oluşturur, kanala tek bir kayıt ekler ve sonucu <code class="language-plaintext highlighter-rouge">rss.xml</code> dosyasına yazar. Üretim ortamında her kayda benzersiz kimlik, yayın tarihi ve kalıcı bağlantı eklemek gerekir. Betiği cron ile periyodik çalıştırarak tamamen otomatik bir yayın hattı kurulabilir.</p>

<h2 id="rsshub-ile-akışı-olmayan-kaynaklar">RSSHub ile akışı olmayan kaynaklar</h2>

<p>RSSHub, desteklediği platformları “rota” adı verilen adreslerle RSS’e dönüştürür. Docker ile yerel kurulum yapılabilir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker run <span class="nt">-d</span> <span class="nt">--name</span> rsshub <span class="nt">-p</span> 1200:1200 diygod/rsshub
</code></pre></div></div>

<p>Ardından akışlara <code class="language-plaintext highlighter-rouge">http://localhost:1200/rota/parametre</code> biçiminde erişilir. Gerçek rota, takip edilen platforma göre RSSHub belgelerinden seçilir. Herkese açık örnek sunucular deneme için uygundur; düzenli kullanımda kendi örneğini barındırmak hız, gizlilik ve kota kontrolü sağlar.</p>

<h2 id="sağlam-bir-yayın-için-son-dokunuşlar">Sağlam bir yayın için son dokunuşlar</h2>

<p>RSS çıktısını bir XML doğrulayıcıyla test et, açıklamalardaki HTML’i güvenli biçimde temizle ve <code class="language-plaintext highlighter-rouge">ETag</code> ile <code class="language-plaintext highlighter-rouge">Last-Modified</code> başlıklarını etkinleştir. Böylece okuyucular değişmeyen dosyayı tekrar indirmez. Kısacası WordPress hızlı başlangıç, Feedgen özel üretim, RSSHub ise keşif ve dönüştürme aracıdır. Üçünü birlikte kullandığında dağınık internet, düzenli ve sana ait bir haber merkezine dönüşür.</p>

<p><img src="/img/kendi-rss-yayin-12.svg" alt="kendi-rss-yayin-12" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="rss" /><category term="rsshub" /><category term="feedgen" /><category term="wordpress" /><category term="xml" /><category term="python" /><category term="otomasyon" /><summary type="html"><![CDATA[İnternetteki içerikleri tek tek ziyaret etmek yerine hepsini kronolojik bir akışta okumak kulağa küçük bir süper güç gibi gelir. RSS, tam olarak bunu sağlayan açık ve sade bir yayın standardıdır. Bu rehberde hazır WordPress akışlarından Python Feedgen ile özel yayın üretmeye, RSSHub sayesinde akışı bulunmayan siteleri takip etmeye kadar uzanan pratik bir sistem kuracağız.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/kendi-rss-yayin-12.png" /><media:content medium="image" url="https://program.sonsuz.us/img/kendi-rss-yayin-12.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>