Ev Arşiv Hakkında

Django ile Wordpress'e bağlanmak

28-8-2010, 5:23 ö.s. // yorum // python , django , wordpress // 1716

Birkaç gün önce bir arkadaş sormuştu Django ile Wordpress'e nasıl bağlandığımı(bkz arşiv sayfam. Yaptığım şey, wordpress için bir model oluşturup, mümkün olduğunca wordpress veritabanını kopyaladım.

Kendi sitem için sadece wp_posts tablosunu aktardım, fakat tüm wordpress'de aktarılabilir biraz daha uğraşılarak. Bu yöntemle wordpress'e yazı bile girebilirsiniz aslında. Ben sadece yazıları çekiyorum.

wp_posts tablosu(wordpress 2.9.1 için) şu alanları içeriyor:

field           type
----------------------------
id              int(11)
post_date       datetime
post_title      varchar(100)
post_content    longtext
post_excerpt    varchar(100)
post_status     varchar(100)
guid            varchar(100)
comment_count   int(11)
post_type       varchar(20)

Bunu Django ORM'ine şu şekilde çevirdim(tam olarak aynısı olmasa da, eğer sadece yazıları okuyacaksanız gayet güzel çalışıyor, yazı eklemek için denemedim):

# models.py
from django.db import models

class Posts(models.Model):
    post_date = models.DateTimeField()
    post_content = models.TextField()
    post_title = models.CharField(max_length=100)
    post_content = models.TextField()
    post_excerpt = models.CharField(max_length=100)
    post_status = models.CharField(max_length=20)
    guid = models.CharField(max_length=100)
    comment_count = models.IntegerField()
    post_type = models.CharField(max_length=20)

Daha sonra views.py dosyamdan şu şekilde çekiyorum:

from wp.models import Posts

def wp():
    return [post for post in Posts.objects.order_by("-post_date") if post.post_type == "post" and post.post_status == "publish"]

Bundan sonrası normal Django işlemleri. wp() fonksiyonunu istediğim sayfaya gönderdikten sonra(render_to_response ile mesela) aşağıdaki template kodları ile wordpress yazılarıma ait verileri çekiyorum:

{% for yazi in wp %}
        {{ yazi.post_title }} *baslik*
        {{ yazi.post_date }} *tarih*
        {{ yazi.post_content }} *icerik*
        {{ yazi.coment_count }} *yorum sayisi*
{% endfor %}

Tabii bunları çekerken bazı builtin template taglardan yararlanıyorum. Bu arada, Django, 1.2 sürümüyle beraber artık birden fazla veritabanına bağlanabiliyor, wordpress yazılarınızı çekmek istiyorsanız bunu kullanabilirsiniz(ben aynı veritabanını kullanıyorum.

Nautilus için FTP upload scripti

28-8-2010, 12:42 ö.ö. // yorum // python , nautilus // 1736
30-08-2010. Biraz daha geliştirdim, artık eğer bilgisayarınızda pynotify kuruluysa(eğer nautilus kullanıyorsanız büyük ihtimalle gnome kullanıyorsunuzdur, dolayısıyla sorun yok) script çalışmaya başladığında ve çalışmayı bitirdiğinde bir uyarı veriyor(kaç dosya upload ettiği yazıyor). Arkaplanda ne olduğunu göremesek de, hiç yoktan iyidir.

"Upload bitti!"

Nautilus scriptleri işimi acayip kolaylaştırıyor, yazımı da çok kolay, bir gün içerisinde bir şeyi birden fazla kez yapıyorsam, o işlemi nautilus scripti aracılığıyla yapmaya çalışıyorum artık. Python ile tabii ki..

Bu seferki seçtiğiniz dosyaları(veya klasörleri)(birden fazla seçebilirsiniz), FTP sunucunuzda belirttiğiniz klasöre gönderiyor. Harici bir kütüphane kullanmadım, FTP işlemleri için ftplib kullandım. ftplib neredeyse bir kütüphane değil istemci, çok basit birkaç komutla her işinizi halledebilirsiniz.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import ftplib, os, sys

try:
    import pynotify
except ImportError:
    uyar = False
else:
    uyar = True

sayac = 0

# Debug icin, silinebilir
# sys.stderr = open('/home/osa1/Desktop/stderr.txt', 'w')
# sys.stdout = open('/home/osa1/Desktop/stdout.txt', 'w')

ftp = ftplib.FTP('ftp sunucunuz')
ftp.login(user='kullanici adiniz', passwd='sifreniz')

yerler = [f.strip() for f in os.environ['NAUTILUS_SCRIPT_SELECTED_URIS'].split('file://') if len(f) > 0]

def gonder(local, baslangic='/media'): # upload edilecek klasor
    global sayac
    if os.path.isdir(local):
        basename = os.path.basename(local)
        sunucuKlasor = '%s/%s' % (baslangic, basename)

        try:
            ftp.mkd(sunucuKlasor)
        except ftplib.error_perm:
            pass

        for dosya in os.listdir(local):
            localYeni = '%s/%s' % (local, dosya)
            gonder(localYeni, baslangic=sunucuKlasor)
    else:
        dosyalar = ftp.nlst(baslangic)
        if os.path.basename(local) in baslangic:
            ftp.delete(os.path.basename(local))
        ftp.storbinary('STOR %s/%s' % (baslangic, os.path.basename(local)),
                       open(local, 'rb'))
        sayac += 1

if uyar:
    n = pynotify.Notification("Upload basladi",
                              "%s dosya ve/veya klasor" % len(yerler))
    n.show()

for yer in yerler:
    gonder(yer)

if uyar:
    n = pynotify.Notification("Upload bitti",
                              "%s dosya upload edildi" % sayac,
                              "gnome-netstatus-txrx")
    n.show()

ftp.close()

Django'ya Pygments desteği

26-8-2010, 6:13 ö.s. // yorum // python , django , markdown, pygments // 1414

Daha önceden burada Django'ya Markdown desteği eklenmesinden bahsetmiştim(Django'nun Markdown eklentisi olduğunu farkettim çok sonradan). Bu sefer de syntax renklendirme için Pygments desteği ekledim. Pygments'den önce syntaxhighlighter kullanıyordum benim amacım için biraz fazla gelişmiş ve kompleks kaçıyordu.

Öncelikle django'ya pygments desteği için 2 tane çok iyi kaynak var(1, 2), fakat bu kaynaklardaki yöntemlerden ilki, veritabanına gerekli html tagları eklenmiş bir şekilde yazıyor, dolayısıyla bir daha düzenlemek istediğinizde kodunuz okunmaz bir halde oluyor. Benim yapmak istediğim şey, daha önceden markdown için de yaptığım gibi, bir template filter oluşturup istediğim yerde kullanabilmek. Hem bu şekilde daha esnek olabilirim. İkinci yöntem ise, açıkçası ne yaptığını anlamaya çalışmadım, markdown ve pygments'i beraber uyguluyor. Bu da benim istediğim şey değil. Benim amacım, istediğim yere markdown, istediğim yere pygments, istediğim yere de ikisini beraber uygulamak.

Bunun için verdiğim ilk kaynaktaki kodu kullandım aslında. Tek farkı, sonucu veritabanına yazdırmak yerine, fonksiyonu template filter haline getirdim.

# pygmentsf.py
from django import template
from BeautifulSoup.BeautifulSoup import BeautifulSoup #saka gibi
from pygments import lexers, highlight, formatters
from django.template.defaultfilters import stringfilter

register = template.Library()

@register.filter
@stringfilter
def pygmentsf(html):
    "String'i Pygments'den gecirir. BeautifulSoup ile pre taglarini ayristirir."
    soup = BeautifulSoup(html)
    preblocks = soup.findAll('pre')
    for pre in preblocks:
        if pre.has_key('class'):
            try:
                code = ''.join([unicode(item) for item in pre.contents])
                code = unescape_html(code)
                preclass = pre['class']
                # syntaxhighlighter icin yazilmis kodlar icin
                if preclass == 'brush: python' or preclass == 'brush; python':
                    preclass = 'python'
                lexer = lexers.get_lexer_by_name(preclass)
                formatter = formatters.HtmlFormatter()
                code_hl = highlight(code, lexer, formatter)
                pre.replaceWith(BeautifulSoup(code_hl))
            except:
                pass
    return unicode(soup)

def unescape_html(html):
    html = html.replace('&lt;', '<')
    html = html.replace('&gt;', '>')
    html = html.replace('&amp;', '&')
    return html

Ayrıca küçük bir düzenlemeyle daha önceden syntaxhighlighter için yazdığım yazılarla da uyumlu olmasını sağladım. Bu dosyayı uygulamanız altında eğer templatetags klasörüne attıktan sonra template dosyanızdan {% load pygmentsf %} dedikten sonra, istediğiniz değişkene uygulayabilirsiniz. {{ blog.body|pygmentsf|safe|escape }} gibi. Ya da isterseniz markdown yazımdaki template filter ile beraber {{ blog.body|markdown|pygmentsf|safe|escape }} şeklinde kullanabilirsiniz.

Unutmadan, HTML'i ayrıştırmak için BeautifulSoup kullanılıyor. Mükemmel bir kütüphane.

Eğer markdown ile beraber kullanacaksanız, bu yöntem pek de iyi değil. Şuraya bakın.

Pygame denemeleri 1 ve okunacaklar

15-8-2010, 5:10 ö.s. // yorum // python , pygame , django // 2050

Python ile Django'dan sonra pygame'e el attım biraz. Daha yeni başladım ve henüz pygame'in özelliklerinin çok azından yararlanarak birşeyler yapabiliyorum. Aşağıdaki kod ilk yazdığım basit bir çarpışma şeyi(neyi ben de bilmiyorum). İstediğiniz büyüklükte ekrana istediğiniz kadar top ekleyip onları rastgele hızlarda bir yerlere yolluyor ve çarpıştırıyor.

import pygame, random, math

screenx, screeny = 500, 500 #ekran buyuklugu

class Ball:
    def __init__(self, surface):
        self.surface = surface
        self.radius = 10
        self.color = (255, 255, 255)
        self.x = random.randint(0+self.radius, screenx-self.radius)
        self.y = random.randint(0+self.radius, screeny-self.radius)
        self.vx = random.randint(1, 10)
        self.vy = random.randint(1, 10)

    def move(self, time_passed):
        if self.x >= screenx-self.radius or self.x <= self.radius:
            self.vx *= -1
        if self.y >= screeny-self.radius or self.y <= self.radius:
            self.vy *= -1
        self.x += self.vx * time_passed
        self.y += self.vy * time_passed

    def draw(self):
        pygame.draw.circle(self.surface, self.color, (self.x, self.y),
                           self.radius)
pygame.init()

clock = pygame.time.Clock()
screen = pygame.display.set_mode((screenx, screeny), 0, 32)
running = True

balls = []
for i in range(1, 21): #top sayisi
    balls.append(Ball(screen))

def CollisionDetect(b1):
    for b2 in balls:
        if b1 is not b2:
            range = math.sqrt((b1.x - b2.x)**2 + (b1.y - b2.y)**2)
            if range < (b1.radius + b2.radius):
                b1.vx, b2.vx = b2.vx, b1.vx
                b1.vy, b2.vy = b2.vy, b1.vy
                #b1.move(); b2.move()

while running:
    for event in pygame.event.get():
        #print event
        if event.type == pygame.QUIT:
            running = False

    time_passed = clock.tick(50)
    screen.fill((0, 0, 0))

    for b in balls:
        b.draw()
        CollisionDetect(b)
        b.move(time_passed)

    pygame.display.flip()

Onun dışında kendime bir okunacaklar listesi hazırladım, ilk fırsatta okuyacaklarım:

Osa1 arşiv düzenleme scriptçiği nautilus scripti

6-8-2010, 10:49 ö.s. // yorum // python , nautilus // 2444

Daha önceden burada duyurdum arşiv düzenleyiciyi biraz daha geliştirdim.

Programın amacı basitçe mp3, ogg ve flac dosyalarından oluşan müzik arşivinizi düzenlemek. Ayrı bir klasöre kopyalayabiliyor ya da aynı klasörde dosyaları taşıyarak düzenleyebiliyor. Formata uymayan dosyaları da ayrı bir klasörde topluyor.

Bu arada not, müziklerinizi id3 etiketlerine göre düzenliyor, etiketleri yoksa, ayrı bir klasöre kopyalıyor.

Yeni sürümde bir de nautilus scripti hazırladım. Bunun sayesinde düzenlemek istediğiniz klasöre sağ tıklayıp seçerek daha kolay düzenlenebiliyor.

Önce:örnek

Sonra:örnek2

Onun dışında aynı klasörde dosyaları taşıyarak düzenleme özelliğini de yeni ekledim. İki ayrı scriptten birisi aynı klasör içerisinde taşıyarak düzenleme için, diğeri ise yeni bir klasör oluşturup düzenli halde oraya kopyalıyor.

Kurulum için arşivi açıp, klasöre gelip python setup.py install komutunu vermelisiniz. Duruma göre, başına sudo veya benzeri birşey eklemeniz gerekebilir. Scriptlerin için de python script.py komutunu vermeniz yeterli.

Aşağıdaki şekillerde kullanılabilir:

  • En basit ve kullanışlı olanı, direkt klasöre sağ tıklayıp scripti seçmek. 2 ayrı script var, birisi yeni bir klasör oluşturup(seçtiğiniz klasörün altına) düzenli halde arşivi oraya kopyalar, arşivin büyüklüğüne bağlı olarak kopyalama işlemi uzun sürebilir fakat arşivinizde hiçbir şekilde değişiklik yapılmaz. İkinci yöntem ise kopyalamadan, taşır. Bu arşivinizin düzenini bozabilir. Fakat aslında daha kullanışlıdır.

  • Nautilus scriptini kullanmadan çalıştırmak için, hiç kurulum yapmadan direkt osa1 ve mutagen klasörlerini kopyalayarak, osa1.py arsiv_yeri, duzenli_arsiv_yeri şeklinde çalıştırabilirsiniz. Onun dışında kurulum yaparak from osa1 import osa1 şeklinde import edip osa1.duzenle() fonksiyonu ile kendi programlarınızda kullanabilirsiniz. Ya da .bashrc dosyanıza alias osa1='python "/usr/local/lib/python2.6/dist-packages/osa1/osa1.py"' satırını ekledikten sonra terminalden osa1 arsiv_yeri, duzenli_arsiv_yeri şeklinde çalıştırabilirsiniz.

Windows ortamında test etmedim fakat kaynak koda baktığımda çalışmaması için bir sebep göremiyorum. Kurulum yine aynı fakat script.py dosyasını çalıştıramazsınız. Haliyle düzenlemek istediğinizde komut satırından programı çalıştırmalısınız.

Buradan indirebilirsiniz.

EKLEME: Scripte arayüz ekledim. İşlev olarak tamamen aynı, sadece nautilus ile değil de, bir arayüz ile çalıştırmanız gerekiyor(bence bu hali daha kullanışlı). Gnome kullanmayanların işine yarayabilir. Daha detaylı bilgi için kendi sayfasına bakın.(Bu arada aşağıdaki de ekran görüntüsü)

0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12