Python Gitlab Email Sender

Gitlab kullanıyor iseniz, gitlab sunucunuzdaki post-receive hook scriptinin içerisine, aşağıdaki python scriptini her push işleminden sonra çalıştıracak şekilde ayarlamanız durumunda, script her çalıştığında oluşturduğu commits.db sqlite database’indeki short commit’i ile karşılaştırıp, değişikli var ise aşağıdaki mail gönderim formatında maili ‘*protected email*’ adresine gönderir. Eğer db’de bulunmayan bir repo ile karşılaşması durumunda db’ye repo’yu insert eder.

#!/usr/bin/env python
__author__ = "Gokhan MANKARA <*protected email*"

import gitlab
import sqlite3 as sql
import requests
import smtplib
import os
import email.utils
from email.mime.text import MIMEText

gitlab_url = "https://gitlab.domain.com"
gitlab_access_token = "ABCDEFG"


class SendEmail(object):
    def __init__(self):
        self.mail_to = '*protected email*'
        self.mail_from = '*protected email*'
        self.mail_server = 'mail.domain.com'
        self.mail_subject = 'New Commit'

    def main(self, msg):
        msg = MIMEText(msg)
        msg['To'] = email.utils.formataddr(('Recipient', self.mail_to))
        msg['From'] = email.utils.formataddr((self.mail_subject, self.mail_from))
        msg['Subject'] = self.mail_subject

        server = smtplib.SMTP(self.mail_server, 25)
        server.set_debuglevel(False)

        try:
            server.sendmail(self.mail_from, self.mail_to, msg.as_string())
        finally:
            server.quit()


class Commit(object):
    def __init__(self):
        self.db = "commits.db"
        self.con = sql.connect(self.db)
        self.git = gitlab.Gitlab(gitlab_url, token=gitlab_access_token, verify_ssl=False)
        with self.con:
            self.cur = self.con.cursor()
        requests.packages.urllib3.disable_warnings()

        if not os.path.isfile(self.db):
            os.system("sqlite3 commits.db < commits.sql")

    def sql_insert(self, repo, branch, hash):
        sql = "insert into last_commit ('repo', 'branch', 'hash') values ('%s', '%s', '%s')" % (repo, branch, hash)
        self.cur.execute(sql)
        self.con.commit()

    def sql_select(self, branch, repo):
        sql = "select hash from `last_commit` where branch='%s' and repo='%s'" % (branch, repo)
        self.cur.execute(sql)
        return self.cur.fetchone()[0]

    def sql_update(self, new_hash, branch, repo):
        sql = "UPDATE last_commit SET hash='%s' WHERE branch='%s' and repo='%s'" % (new_hash, branch, repo)
        self.cur.execute(sql)
        self.con.commit()

    def commits(self):
        # git.getprojectsall => Returns a dictionary of all the projects for admins only
        # git.getprojects => Returns a dictionary of all the projects

        for i in self.git.getprojectsall():
            group_name = i["namespace"]["name"]
            project_name = i["path"]
            project_id = i["id"]
            for branches in self.git.getbranches(project_id):
                    new_commit = branches["commit"]["id"][:8]
                    branch_name = branches["name"]

                    try:
                        commit_in_sql = self.sql_select(branch_name, project_name)
                    except TypeError:
                        self.sql_insert(project_name, branch_name, new_commit)

                    if commit_in_sql != new_commit:
                        get_commit_info = self.git.getrepositorycommit(project_id, new_commit)
                        try:
                            author_name = get_commit_info["author_name"]
                            author_email = get_commit_info["author_email"]
                            author_message = get_commit_info["title"]
                            commit_date = get_commit_info["created_at"]
                        except TypeError:
                            pass

                        compare_url = "%s/%s/%s/compare/%s...%s" %\
                                      (gitlab_url, group_name, project_name, check_commit, new_commit)
                        send_email = SendEmail()
                        msg = 'Commit Repo: %s\nBranch Name: %s\nUser: %s\nUser Mail: %s\nCommit Message: %sCommit Time: %s\n\nDiff URL: %s' %\
                              (project_name, branch_name, author_name, author_email, author_message, commit_date, compare_url)
                        send_email.main(msg)
                        self.sql_update(new_commit, branch_name, project_name)

    def main(self):
        self.commits()


if __name__ == "__main__":
    Commit().main()

Python scripti ile aynı yerde oluşturmanız gereken commits.sql dosyası dosyası.

CREATE TABLE last_commit(id INTEGER PRIMARY KEY AUTOINCREMENT, repo TEXT, branch TEXT, hash TEXT);

Gönderilen mailin örnek içeriği,

Commit Repo: githlab-email-repo
Branch Name: master
User: gokhan
User Mail: *protected email*
Commit Message: First Test Email Commit
Commit Time: 2015-05-30T13:58:42.000+03:00

Diff URL: https://gitlab.domain.com/gokhan/gitlab-email-repo/compare/s1ws93...1ex4ng59

Gitlab server’da post-receive hook scriptine, başına “/usr/bin/python” koyarak scripti kullanabilirsiniz. Başına python path’ini koymamızın sebebi, gitlab’ın kendi python binary si olduğundan import ettiğimiz modüller gitlab’ın kendi lib’inde olmadığı için remote gitlab server’a push ettiğinizde “modül bulunamadı” şeklinde hata verecektir.

GitHub Repo

31 Mayıs 2015

Posted In: gitlab, gitlab hook, gitlab send email, lkd-gezegen, python, python gitlab hook

Python Paketi Hazırlamak

    Pebble Remote projesinin bana katkısı gerçekten çok büyük oldu. Daha buraya yazmadığım bir sürü büyük küçük birbirini gerektiren bi çok işi öğrendim.  Paketlemeyi öğrenme amacım pebble remote'un pip komutuyla kurulabilir hale gelmesini sağlamaktı.

Şimdi örnek olarak aşağıdaki python projesini pip ile kurulabilir hale getireceğiz

pebbleremote
└── pebble
    ├── bluetooth.py
    ├── data
    │   └── logo.png
    ├── __init__.py
    ├── py_script.py
    └── remote.py

setup.py dosyasını yazmalıyız

Öncelikle bu dosyanın yukarıdaki pebble modülü ile aynı seviyede olması gerekiyor.

pebble
├── pebble
│   ├── bluetooth.py
│   ├── data
│   │   └── logo.png
│   ├── __init__.py
│   ├── py_script.py
│   └── remote.py
└── setup.py

setup.py dosyasının içinde bulunması gerekenler:


from setuptools import setup

setup(name='pebble-remote',
version='1.0',
description='Libreoffice Impress tool for remoting presentations with Pebble',
url='http://github.com/Libreoffice/impress_remote/tree/master/pebble',
author='Gulsah Kose',
author_email='gulsah.1004@.gmail.com',
license='MPLv2',
packages=['pebble'],

scripts=['pebble/py_script.py'],

install_requires = ['setuptools'],
zip_safe=False)

Bu kadarını yazdığımızda sadece pebble modülünü gereken yere kuracak hale getirmiş oluruz. Ama içinde yukarıda olduğu gibi bir python dosyası olmayan modüle dahil olmayan dosyalar olabilir -data dizini ve altındaki png dosyası gibi-.

Onuda pakete dahil etmek için aşağıdaki yolu izliyoruz:

- Öncelikle MANIFEST.in dosyasının içinde aşağıdaki satırı  yazalım Bunu modül dışında olan dosyaları pakete dahil etmek için kullanıyoruz:

include /pebble/data/logo.png

 pebble
├── MANIFEST.in
├── pebble
│   ├── bluetooth.py
│   ├── data
│   │   └── logo.png
│   ├── __init__.py
│   ├── py_script.py
│   └── remote.py
└── setup.py

 - Bu ekleme için setup.py dosyasının içeriğini de değiştirmemiz gerekecek. Dosyanın son hali aşağıdaki gibi olacak:


from setuptools import setup 

setup(name='pebble-remote',
version='1.0',
description='Libreoffice Impress tool for remoting presentations with Pebble',
url='http://github.com/Libreoffice/impress_remote/tree/master/pebble',
author='Gulsah Kose',
author_email='gulsah.1004@.gmail.com',
license='MPLv2',
packages=['pebble'],

scripts=['pebble/py_script.py'],

package_data={
'pebble/data': ['logo.png'],
},

data_files=[
('/opt/pebble/logo/', ['pebble/data/logo.png'])

],

install_requires = ['setuptools'],

zip_safe=False)


Artık projemiz kurulmaya hazır hale gelmiştir. Aşağıdaki komutu kullanarak kurulumunu yapabilirsiniz:

$sudo python setup.py install

Kurulumu bu şekilde yaptığınızda paketi kaldırmak için aşağıdaki komutları kullanabilirsiniz:

$sudo python setup.py install --record file.txt
 
#cat file.txt | xargs rm -rf

 Şimdi bu projeyi python package index (PyPi) 'e yükleyelim:

Önce bu adresten bir hesap oluşturmalısınız. Projenizi buraya yüklemeden önce depoda aynı isimde başka bir proje varmı diye bakmalısınız. Çünkü pypi'de tüm paket isimleri eşsiz olmalıdır.

Sonra aşağısaki komutu çalıştırdığınızda karşınıza size kullanıcı adı parola gibi bilgilerinizi soran kısımlar çıkacak. Bunları doğru bir şekilde tamamladığınızda herşey yolundaysa 200(OK) kodunu göreceksiniz. Bunu gördüğünüzde artık projeniz pip ile kurulabilir hale gelmiş olacak.
 
$sudo python setup.py register sdist upload
 
Artık #pip install pebble-remote yazdığınızda projeniz sorunsuz kuruluyor olmalı.


Paketlemeyi öğrenirken faydalandığım linkler burada. Yukarıdaki setup.py dosyası içindeki alanların ne anlama geldiği ayrıntılı anlatılıyor:

1) http://www.scotttorborg.com/python-packaging/minimal.html#
2) https://pythonhosted.org/setuptools/setuptools.html

Bununla ilgili çok örnek bulmanız mümkün elbet ama pebble remote için yaptığım paketi aşağıdaki linkten inceleyebilirsiniz

3) https://pypi.python.org/pypi/pebble-remote/2.0

24 Ocak 2015

Posted In: Gezegen, index, linux, ozguryazilim, package, pebble, pebble-remote, pip, pypi, python

Python’da Kullanıcı Tanımlı Hatalar

    Python projelerinde kullanıcılar hata tanımlayabilir ve aynı sistem tarafından tanımlı hatalar gibi try-except içinde kullanabilir.

    Ben pebble-remote projesini geliştirirken bu hata yakalama kısmında şöyle bir sorunla karşılaşmıştım. Kullanıcı tanımlı hata sınıflarım vardı ve bu sınıfların tanımlandığı dosyanın dışında bir yerde bu tanımlanan hataları yakalamak istiyordum. Hatanın tanımlandığı python dosyasını da import ettiğim halde bu hataları yakalayamıyordum.

   Daha iyi bir yöntemi de olabilir elbet ama benim deneyerek bulduğum çözüm hata sınıfının tam yolunu yazmak oldu.

Kullanmaya çalıştığım python modülünün yapısı aşağıda:

libpebble/pebble
├── __init__.py
├── LightBluePebble.py
├── pebble.py
└── stm32_crc.py

LightBluePebble.py dosyası içinde bir hata aşağıdaki gibi tanımlanmış:


LightBluePebbleError(Exception):
def __init__(self, id, message):
self._id = id
self._message = message
def __str__(self):
return "%s ID:(%s) on LightBlue API" % (self._message, self._id)

Bu hatayı yakalamak istediğim dosya içinde  içinde modülü aşağıda şekilde import ettim:


import pebble as libpebble

Bu haliyle aşağıdaki kod hatalıydı:


try:
...
except LightBluePebbleError as e
...

Doğrusu:


LightBluePebbleError = libpebble.LightBluePebble.LightBluePebbleError

try:
...
except LightBluePebbleError as e
...

16 Ocak 2015

Posted In: exception, Gezegen, handling, impress, linux, ozguryazilim, pebble, pebble-remote, python, userdefinedexception

Python Projelerine Mimetype Desteği Eklemek

    Python projeniz eğer sadece konsol aracıysa ve bunu sağ tıkla şununla aç şeklinde çalıştırılabilecek hale getirmek istiyorsanız projenize mimetype desteği eklemeniz gerekir.

    Benim buna ihtiyaç duymam, gururla daha çok yerde anlatacağım bir olayın arkasından oldu. Bu sene bitirme projemin bir parçası olarak Pebble ile LibreOffice Impress uzaktan kumandasını yazdım. Ve yazdığım araç bir hafta önce LibreOffice deposuna kabul edildi. Ve daha güzeli LibreOffice deposunun tümüne yazma hakkım olması ve listedekilerin "LibreOffice geliştirici ekibine hoşgeldin" demeleriydi. O anki heyecanımla Çanakkaleyi koşarak turlayabilirdim :) Bu süreçteki tüm desteği için Necdet hocama ne kadar teşekkür etsem az. pebble-remote kabul edildikten sonra bu projenin kullanımını kurulumunu basitleştirmeye çalıştım. Mimetype desteğini eklediktan sonra pebble-remote artık sadece bir konsol aracı olmaktan çıktı ve kullanımı çok çok kolaylaştı.

Mimetype desteği eklenmesi şu adımlarla gerçekleştirdim:


* Menüde görünecek logoyu belirledim ve bu logoyu /usr/share/pixmaps/ dizini altına pebble-remote.png ismiyle kopyaladım.












* Menüde görünebilir hale gelmesi için aşağıdaki dosyayı  /usr/share/menu/ altına pebble-remote adıyla kopyaladım. 

---
?package(pebble-remote):needs="X11" section="Applications/Office"\
  title="Pebble Remote" command="/usr/bin/pebble-remote"\
  hints="Presentation"\
  kderemove="y"\
  icon="/usr/share/icons/hicolor/32x32/apps/libreoffice-impress.xpm"
---

* Aşağıdaki dosyayı  /usr/share/applications/ dizini altına pebble-remote.desktop ismiyle kaydettim:

---
[Desktop Entry]
Version=1.0
Terminal=false
Icon=/usr/share/pixmaps/pebble-remote.png
Type=Application
Categories=Office;Presentation;X-Red-Hat-Base;X-MandrivaLinux-Office-Presentations;
Exec=pebble-remote %U
MimeType=application/vnd.oasis.opendocument.presentation;application/vnd.oasis.opendocument.presentation-template;application/vnd.sun.xml.impress;application/vnd.sun.xml.impress.template;application/mspowerpoint;application/vnd.ms-powerpoint;application/vnd.openxmlformats-officedocument.presentationml.presentation;application/vnd.ms-powerpoint.presentation.macroenabled.12;application/vnd.openxmlformats-officedocument.presentationml.template;application/vnd.ms-powerpoint.template.macroenabled.12;application/vnd.openxmlformats-officedocument.presentationml.slide;application/vnd.openxmlformats-officedocument.presentationml.slideshow;application/vnd.ms-powerpoint.slideshow.macroEnabled.12;application/vnd.oasis.opendocument.presentation-flat-xml;application/x-iwork-keynote-sffkey;
Name=Pebble Remote
GenericName=Presentation
Comment=Pebble remote control for LibreOffice Impress.
StartupNotify=true
Keywords=Slideshow;Slides;OpenDocument Presentation;Microsoft PowerPoint;Microsoft Works;OpenOffice Impress;odp;ppt;pptx;
InitialPreference=5
StartupWMClass=libreoffice-impress
X-KDE-Protocols=file,http,smb,ftp,webdav
---

Bu işlemlerden sonra odp formatındaki dosyaya sağ tıkladığımda aşağıdaki görüntüyü gördüm:


16 Ocak 2015

Posted In: Gezegen, impress, mimetype, ozguryazilim, pebble, pebble-remote, python, remote

Python Uygulamalarına Dil Desteği Eklemek

Projemiz klasik olarak ekrana "Hello World"  yazdırsın ve buna dil desteği ekleyelim. Projenin dizin yapısı şöyle:
---
helloproject/
└── hello.py

---
hello.py dosyasının içeriği aşağıda:

---
print "Hello World"
---


1. _() Fonsiyonunu Belirlemek

Bu fonksiyon kodun içinde çevirilecek cümlelerin, kelimelerin belirlenmesine ve yerelimizde kullandığımız dil her ne ise cümlelerin o dile göre çevirilmiş halinin gösterilmesine yarayan fonksiyondur.

hello.py dosyası ile aynı dizine i18n.py isimli bir dosya açalım ve içine şunları yazalım.

---

# -*- coding: utf-8 -*-

import os, sys
import locale
import gettext

# Bu degisken ismine kendi uygulamanizin ismini yazmalısınız!
# Ceviri dosyaları bu yolda olmalıdır.
#  @LOCALE_DIR@/@LANGUAGE@/LC_MESSAGES/@APP_NAME@.mo
APP_NAME = "helloproject"



# Sisteminizde helloproject isim dosyanın bulunduğu yolu döndürecektir.

# Bu kismi baska projeler icin projenizin bulunduğu dizine göre değiştirmelisiniz.
APP_DIR = os.path.dirname(os.path.abspath("helloproject"))

# .mo dosyalari bu dizinin altinda olacaktir APP_Dir/i18n/LANGUAGECODE/LC_MESSAGES/

LOCALE_DIR = os.path.join(APP_DIR, 'i18n')

# Hangi dile cevrilecegini belirleyen kisim burasidir. Burada olusan
# listede ilk yazan dil hangisiyse ona ceviri yapilacaktir.
#
# hangi dile cevirilecegi LANG cevresel degiskenine bakilarak belirlenir.
DEFAULT_LANGUAGES = os.environ.get('LANG', '').split('.')
DEFAULT_LANGUAGES += ['en_US']

lc, encoding = locale.getdefaultlocale()
if lc:
    languages = [lc]

languages += DEFAULT_LANGUAGES
mo_location = LOCALE_DIR

# Burada herhangi bir degisiklik yapmaniza gerek yok
gettext.install(True, localedir=None, unicode=1)

gettext.find(APP_NAME, mo_location)

gettext.textdomain (APP_NAME)

gettext.bind_textdomain_codeset(APP_NAME, "UTF-8")

---

Şuan oluşan dizin yapısı:

---
 helloproject/
├── hello.py
└── i18n.py

---
2. Çevirmek İstediğimiz  Cümleleri Belirlemek

İçinde çeviri yapmak istediğimiz dosyaların başına şu kodu eklemeliyiz.

---
import i18n
_ = i18n.language.ugettext
---

Bu projede çevrilecek tek cümle "Hello World" oluğundan şimdi hello.py dosyasını aşağıdaki şekilde düzenleyelim.


---
import i18n
_ = i18n.language.ugettext 
 
print _("Hello World")
---

Çevilecek cümleler şu yapıda olmalı:

_("çevrilecek cümle")

3.Çeviriler İçin Şablon Oluşturmak

.pot uzantılı dosya şablon dosyasıdır. Her projede bir tane .pot uzantılı dosya bulunur. Çeviri yapılacak diller için oluşturulacak dosyalar bu .pot uzantılı dosya kullanılarak üretilecektir.

Şimdi helloproject.pot isimli dosyayı oluşturacağız. Önce projenin içine "po" isminde bir dizin oluşturalım ve aşağıdaki komutu çalıştıralım.

---
xgettext --language=Python --keyword=_ --output=po/helloproject.pot hello.py
---

Eğer "xgettext: Non-ASCII character at..." gibi bir hatayla karşılaşıyorsanız -başka projelerde- aşağıdaki komutu yazmalısınız:

---
xgettext --language=Python --keyword=_ --output=po/helloproject.pot --from-code=UTF-8 hello.py
---

Bu adımdan sonra oluşan dizin yapısı şu şekildedir:

---
 helloproject/
├── hello.py
├── i18n.py
└── po
    └── helloproject.pot

---

Oluşan helloproject.pot isimli dosya aşağıdaki gibi olmalı:

---
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-03 22:53+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#: hello.py:4
msgid "Hello World"
msgstr ""

---

! Buradaki isim soyisim email gibi bilgileri doldurmakta fayda var.

4. Bir Dil İçin Çeviri Dosyası Oluşturmak

Oluşturduğumuz bu şablon dosyasını kullanarak projenin türkçe için çeviri dosyasını oluşturacağız. Oluşturduğumuz po dizininin içinde aşağıdaki komutu çalıştıralım

---
msginit --input=helloproject.pot --locale=tr_TR
---

Bu işlemin sonunda oluşan dizin yapısı:

---
helloproject/
├── hello.py
├── i18n.py
└── po
    ├── helloproject.pot
    └── tr.po

---

Oluşan tr.po dosyasının içi şöyle olmalı:

---
# Turkish translations for PACKAGE package.
# Copyright (C) 2015 THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# gulsah <gulsah.1004@gmail.com>, 2015.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-03 22:53+0200\n"
"PO-Revision-Date: 2015-01-03 23:08+0200\n"
"Last-Translator: gulsah <gulsah.1004@gmail.com>\n"
"Language-Team: Turkish\n"
"Language: tr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ASCII\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#: hello.py:4
msgid "Hello World"
msgstr "
"
---


Burada .po uzantılı dosyaları çevirmek için çeşitli editörler var (poEdit ,pootle, transifex,...) Bizim projemiz minik olduğundan elle çeviriyi yapabiliriz. Çeviriyi yaptığımızda dosyanın son 2 satırı şöyle değişecek:

---
msgid "Hello World"
msgstr "Merhaba Dunya
"
---

5. Derleme

Program hızlı çalışabilmesi açısından oluşturduğumuz bu .po dosyalarına değil bunları derleyerek oluşturduğumuz .mo dosyalarına bakacaktır. Bu derleme işi ve derlenen dosyaları koyduğumuz yer program için önemli. i18n.py içinde belirttiğimiz şekilde bu proje için oluşan .mo dosyalarını aşağıdaki komutla oluşturacağımız dizin içinde saklayacağız. (Şuan helloproject dizini içindeyiz)

---
mkdir -p i18n/tr/LC_MESSAGES
---

Şimdi tr.po dosyasını derleyelim:

---
msgfmt po/tr.po --output-file i18n/tr/LC_MESSAGES/helloproject.mo
---

Sonuçta oluşan dizin yapısı şöyle olmalıdır:

---
helloproject/
├── hello.py
├── i18n
│   └── tr
│       └── LC_MESSAGES
│           └── helloproject.mo
├── i18n.py
└── po
    ├── helloproject.pot
    └── tr.po

---

Eğer LANG değişkenin içinde kullandığınız dil ingilizceyse onu türkçe ile değiştirirseniz hello.py dosyasını çalıştırdığınızda artık çıktısının "Merhaba Dunya" olduğunu göreceksiniz.





4 Ocak 2015

Posted In: Gezegen, i18n, internationalization, l10n, linux, Localization, ozguryazilim, python

Pebble ile Libreoffice Impress Uzaktan Kontrolü


    Libreoffice üzerinde sunumlarınızı yaparken slaytı değiştirmek için yeniden bilgisayarın başına mı gitmeniz gerekiyor? Ya da bu işi uzaktan yapmak için elinizde kocaman bir telefon mu taşımak zorunda kalıyorsunuz? Durun! Artık slaytlarınızı Pebble ile değiştirebilirsiniz... Nasıl mı? :D

    1) Pebble'ınızın telefonunuzla olan bağlantısını kesin.

    2) Pebble'ı bilgisayarınızın bluetoothu ile eşleştirin. Pebble sürekli dışarıya görünür halde olmadığından bu eşleşmeyi yapmak için biraz hızlı olmanız gerekecek. Pebble'ın dışarıya görünür hale gelmesi için  Settings-->Bluetooth ayarına girdiğinizde yukarıda "Now Discoverable" yazısı çıkacaktır. O anda bu eşleşmeyi yapmak gerekiyor. Bir defada olmayabilir. Bu kısım bi miktar sıkıntılı ancak bunu sadece bir kez yapmanız yeterli. Siz elle bu eşleşmeyi bitirmediğiniz sürece bir daha böyle bir işlemeye ihtiyaç olmayacaktır.

    3) pebble-remote uygulamasın indirin. Sıkıştırılmış bir şekilde indirebilirsiniz ya da şu komutu kullanarak uygulamayı klonlayabilirsiniz.

        $ git clone  https://github.com/COMU/pebble-remote

    4) Bağımlılıkları kuruyoruz.

        $ sudo apt-get install python-dev libopenobex1-dev python-tk python-lightblue python-pexpect xdotool python-bluez

     5) lightblue-0.4 uygulamasını indirip kuruyoruz:

        $ git clone https://github.com/pebble/lightblue-0.4/
          $ cd lightblue-0.4
          $ sudo python setup.py install

    6) Bir terminal aracılığıyla pebble-remote dizini içine geçin:
     
        $cd /path/to/pebble-remote

    7) Burada çalıştırmak için gerekli komutu yazarken bazı parametrelere ihtiyacınız olacak.

Birinci parametre pebble id Bu bilgiyi iki şekilde öğrenebilirsiniz. Birincisi Pebble üzerinde Settings-->About-->BT Address

İkincisi bilgisayarınızda bluetooth ayarlarında eşleşmiş cihazlara girip Pebble cihazına tıkladığınızda sağ tarafta adres bilgisi olacaktır.

Adres 6 oktetten oluşan 11:22:33:AA:BB:CC gibi bir bilgidir. Bu bilgiyi bir kenara not edelim.

İhtiyacımız olan ikinci parametre, yapmak istediğiniz sunumun bilgisayardaki tam yolu.
Örneğin: /home/gulsah/sunum1.odp

Artık  şu komutu çalışırabiliriz(Kendi pebble id niz ve sunumunuzun tam yolu ile):

./p.py --pebble_id 11:22:33:AA:BB:CC --lightblue remote libreoffice /home/gulsah /sunum1.odp

    Bu komutu çalıştırdıktan sonra pebble ile bağlantıda bir sorun yaşarsanız bir defa bu komutu çalıştırırken yine pebble'ın ikinci adımda tarif ettiğim gibi görünür olması gerekebilir.

    Sunum önünüze tam ekran açılacaktır. Pebble içindeki müzik uygulamasını açıp üst ve alt düğmelerini kullanarak slaytlarınızı Pebble ile değiştirebilirsiniz. :)

 


24 Aralık 2014

Posted In: Gezegen, linux, pebble, python, remote, smartwatch

cesi (Centralized Supervisor Interface)


    Bir önceki yazımda Supervisordan bahsetmiştim. Supervisor arayüzden de komut satırından da kullanılabilen bir API si olan Unix benzeri işletim sistemleri üzerinde çalışan bir süreç yönetim sistemidir. Bazı eksikleri şöyleydi:

  -- Supervisorun varolan arayüzü sadece kurulu olduğu makine üzerindeki süreçleri yönetebiliyordu. Ama API uzaktaki makinelerle iletişim kurmaya izin veriyordu.
  -- Arayüzde herhangi bir yetkilendirme seviyesi yoktu. Arayüzü görebilen herkes süreçlerle ilgili istediğini yapabiliyordu.
  -- Herhangi bir şekilde süreçler filtrelenerek yönetilemiyordu. Ya tek tek ya da hepsiyle birden iş yapılabiliyordu.

    Bu yaz stajımı Gamegos'ta Kaan'ın mentörlüğünde yaptım. Yaptığımız iş Supervisor'a yukarıda bahsettiğim eksiklikleri gideren yeni bir arayüz yazmaktı. Yeni arayüzü Python Flask ve Jquery kullanarak yazdık. Şimdilik paketlemedim. Nasıl kurulacağını projenin README kısmında açıkladım. Bu blogta arayüzün yeteneklerini ve kullanımını anlatacağım.
  Projeyi buradan bulabilirsiniz.

  DASHBOARD
--------------------------

    Program çalıştığında karşımıza gelen ilk sayfadır. Toplamda kaç node olduğunu kaçının bağlı kaçının sorunlu olduğunu, toplam kaç süreç olduğunu kaçının çalışıp kaçının durmuş olduğunu ve kullanıcının arayüzde yaptığı işlemlerin logunun son 12 satırını görüntüleyen paneller var.













    NODE
----------------
   
    Node özelliği bu arayüzün merkezi olmasını sağlayan özelliktir. Yani her bir node bizim iletişim kurduğumuz farklı bir supervisora denk geliyor. Kaç tane süpervisor ile iletişim kuracaksak hepsinin host port kullanıcı adı parola bilgilerini /etc/cesi.conf içine şu şekilde yazmalıyız (node isimleri eşsiz olmalıdır) :

  [node:gulsah]
 username = gulsah
 password = ***
 host = gulsah.xyz.com
 port = 9001
    
     Node seçeneğine tıkladığımızda açılan liste yapılandırma  dosyasındaki nodeların listesidir. Node eğer bağlıysa node  isminin  başında bir checkbox olacaktır. Bağlantıda bir  problem  olmuşsa node isminin başında bir çarpı olacaktır.  Buradan istediğimiz nodeları seçerek süreçlerini  yönetebiliriz.


   ENVİRONMENT
----------------------------

    Nodelardan oluşan topluluklardır. Bir filtreleme seçeneğidir. Environment'ı x node ismi y olan süreçler hakkında şunları yap dememize imkan tanır. İstediğimiz kadar environment tanımlayabiliriz. Environment isimleri eşsiz olmalıdır. /etc/cesi.conf  dosyasında şöyle tanımlanır:

  [environment:market]
  members = gulsah, kaan

  Arayüzde environment seçeneğine tıkladığımızda o environmenta üye olan ve bağlantısında problem olmayan nodeların listesini görürüz. Bu nodelardan hangisini seçersek onların süreçlerini yönetebiliriz.











  GROUP
---------------


   Grup zaten Supervisor'un sağladığı bir özellikti. Bu yüzden /etc/cesi.conf içine bununla ilgili birşey yazmaya gerek yok. Supervisor'un yapılandırma dosyasında tanımlanır. Süreçler bir gruba eklenebilir. Eğer sürecin grubu yoksa varsayılan olarak grup adı sürecin adı olur. Bu da arayüzde bir filtreleme seçeneğidir. Grubu x environmeti y olan süreçler için şunları yap deme imkanı sağlar.

    Arayüzde grup seçeneğine tıkladımızda içinde o grubu bulunduran  environmetların listesini görürüz. Buradan hangi environmentleri seçersek grubu seçtiğimiz grup, environmenti seçtiğimiz environment olan süreçleri görüntüleyip yönetebiliriz.

  *Aynı süreç birden fazla gruba ait olmamalıdır.










  SHOW ALL
---------------------

Show all seçeneği ne kadar node ve onların ne kadar süreci varsa hepsini birden görüntülemeyi ve yönetmeyi sağlar.




















    Ayrıca herhangi bir şekilde görüntülediğimiz tabloların üzerinde alt seçimler de yapabiliriz. O anda görüntülediğimiz süreçlerden hangisinin başındaki checkbox işaretliyse tabloların üstündeki turuncu butonları kullanarak sadece o süreçleri durdurup başlatabiliriz.


    Program çalıştırılmadan önce yapılandırma dosyasında veritabanı ve kullanıcı loglarının tutulduğu dosyaların yolunu /etc/cesi.conf dosyasında şu şekilde belirtmeliyiz:

    [cesi]
    database = /x/y/userinfo.db
    activity_log = /x/y/cesi_activity.log


   KULLANICI SEVİYELERİ
--------------------------------------------

   Admin:
   -- Kullanıcı ekleme silme işi sadece admin tipindeki kullanıcılar tarafından yapılır.
   -- Tüm süreçlerle ilgili herşeyi yapabilirler.

  Standart User:
   -- Tüm süreçler hakkında herşeyi yapabilir.

  Only Log
  -- Süreçlerin hepsini görüntüleyebilir
  -- Süreçlerin sadece loglarını okuyabilir.

  Read Only
  -- Sadece süreçleri görüntüleyebilir. Herhangi bir şeye müdahale edemez.




    Program ilk kurulduğunda varsayılan kullanıcı admindir. Kullanıcı adı ve parolası "admin" dir. Change password seçeneğini kullanarak admin ilk olarak parolasını değiştirmelidir. Gerek varsa istediği yetkilerde yeni kullanıcılar ekleyebilir. Eklediği yeni kullanıcılarda oturum açtıklarında aynı şekilde parolalarını değiştirebilirler.


Kullanıcı ekleme paneli:      
















Kullanıcı silme paneli:



Desteği için Kaan Özdinçer'e teşekkürler. 







29 Ağustos 2014

Posted In: Açık kaynak, bootstrap, centralized, cesi, flask, Gezegen, Özgür yazılım, ozguryazilim, process control, python, supervisor, supervisord

Bootstrap



  Bootstrap web uygulamalarımızı ekran boyutundan bağımsız bir şekilde yazmamızı sağlayan bir çatı. Yani uygulamayı tek bir web çatısı kullanarak yazıyoruz ve küçük ekran telefonlardan geniş ekran bilgisayarlara kadar her yerde görünümü bozulmadan kullanabiliyoruz. Bu yazımda bir önceki yazımda Flask ile yazdığım basit blog uygulamasının Bootstrapla iyileştirilme aşamalarını anlatacağım.

  Bootstrap'ın Flask için yazılmış bir modülüde mevcut "pip install flask-bootstrap" diyerek kurup öyle kullanılıyor.  Ama bunu kullanmak yazacağımız uygulamanın kullanım alanını daraltabilir. Örneğin eğer uygulama kararlı depoyu kullanan bir sunucu yada bilgisayarda kullanılacaksa yazacağımız uygulamayı buralarda kullanmak istemeyeceklerdir.

  Bootstrap'ın çok fazla bileşeni olduğundan sadece bloğumuz için gerekli olanlardan bahsedeceğim daha ayrıntılı bilgiyi buradan bulabilisiniz.

  Bootstrap'ı uygulayacağımız blog uygulamasını buradan bulabilirsiniz.

*  Öncelikle linkten Bootstrap için gerekli dosyaları indirmeliyiz. İndirdiğiniz dosyayı açarak uygulamamızın içindeki static dizini altına taşımalıyız.

*  .../templates/layout.html dosyasının başına şu satırı ekleyerek kullanacağımız css dosyasının yolunu belirtmiş oluyoruz:

     <link rel=stylesheet type=text/css href="{{ url_for('static', filename='bootstrap-3.1.1-\
dist/css/bootstrap.min.css') }}">

*  Şimdi bootstrap'ın  her ekran boyutunda düzgün görünmesini sağlayan layout özelliğini ekleyeceğiz. Bootstrap uygulamamızı 12 kolon'a kadar ölçekleyebilir. Biz ekranımızı şekilde görüldüğü gibi bölerek orta kolonu kullanacağız.

  Bunun için Bootstrap içindeki .col-md-* sınıfını kullanacağız. Daha küçük ekranlardaki görünümü için .col-xs-* sınıfını kullanacağız. Yine layout.html dosyasına şu kodu ekleyeceğiz:

<div class="row">
<div class="col-md-4"> İlk bölme </div>
<div class="col-xs-12 col-md-4"> Orta bölme </div>
<div class="col-md-4"> Son bölme</div>
</div>

*  İlk ve son bölmeyi boş bırakacağız. Orta bölmeye kodun layout kısmını içinde kullanıcıya göstereceğimiz kısmı koyacağız. 

* Aynı yerde "log in" ve "log out " butonlarınıda iyileştirmek için  butonların bulunduğu satırı şu şekilde değiştirelim:

 <a class="btn btn-primary btn-lg" role="button" href="{{ url_for('login') }}">log in</a>
 <a class="btn btn-primary btn-lg" role="button" href="{{ url_for('logout') }}">log out</a>

*  .../template/login.html dosyasını açalım ve oradaki kullanıcı adı ve parola kısımlarını ve submit butonunun görünümünü Bootstraptaki sınıfları kullanarak iyileştirmek için form etiketleri arasını aşağıdaki kod ile değiştirelim.

<form action="{{ url_for('login') }}" method=post role="form">
  <div class="form-group">
    <label for="exampleInputEmail1">User name</label>
      <input type="text" name="username" class="form-control"  placeholder="Enter user name please">
  </div>
  <div class="form-group">
    <label for="exampleInputPassword1">Password</label>
      <input type="password" name="password" class="form-control" placeholder="Enter password please">
  </div>
  <div class="metanav">
      <button type="submit" class="btn btn-primary btn-sm">Submit</button>
  </div>
  </form>

*  .../template/show_entries.html dosyasını açalım Yine aynı şekilde formun ve butonların görünümünü iyileştirmek için aşağıdaki form etiketleri içindeki kodu aşağıdaki kod parçasıyla değiştirelim.

  <form action="{{ url_for('add_entry') }}" method=post role="form">
    <div class="form-group">
      <label>Title</label>
        <input type="text" name="title" size=30 class="form-control"  placeholder="Enter title please">
    </div>
    <div class="form-group">
      <label>Text</label>
        <textarea name="text" row=5 cols=40 class="form-control" placeholder="Enter password please"></textarea>
    </div>
    <button type="submit" class="btn btn-primary btn-sm">Submit</button>
  </form>

* Aynı dosya içinde daha önce yazılmış bloglar liste şeklinde görünüyordu. Onların göürünümünü iyileştirmek için tablo kullanmayı tercih ettim. O kısmıda şu şekilde değiştirebiliriz:

<table class="table table-hover">
{% for entry in entries %}
  <tr class="info text-center"><td><h3>{{ entry.title }}</h3>{{ entry.text|safe }}</td></tr>
{% else %}
  <tr class="info text-center"><td><em>Unbelievable. No entries here so far</em></td></tr>
{% endfor %}
</table>

  Artık dosyayı kaydedip bloğu çalıştırdığımızda pencere küçülterek görüntünün bozulmadığını ve bloğun eskisinden daha iyi göründüğünü görebiliriz.

Ek olarak:

  Belki ileride işimiz yarayabilecek bir bileşen "navbar" bileşeni. Hızlıca nasıl çalıştığını layout.html dosyasının başına şu kodu eklediğimizde hızlıca görebiliriz:

<div>
  <nav class="navbar navbar-default navbar-fixed-top" role="navigation">
  <div class="container-fluid">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">Brand</a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Link</a></li>
        <li><a href="#">Link</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
          <ul class="dropdown-menu" role="menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li class="divider"></li>
            <li><a href="#">Separated link</a></li>
            <li class="divider"></li>
            <li><a href="#">One more separated link</a></li>
          </ul>
        </li>
      </ul>
      <form class="navbar-form navbar-left" role="search">
        <div class="form-group">
          <input type="text" class="form-control" placeholder="Search">
        </div>
        <button type="submit" class="btn btn-default">Submit</button>
      </form>
      <ul class="nav navbar-nav navbar-right">
        <li><a href="#">Link</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
          <ul class="dropdown-menu" role="menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="#">Something else here</a></li>
            <li class="divider"></li>
            <li><a href="#">Separated link</a></li>
          </ul>
        </li>
      </ul>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
  </nav>
</div>



27 Haziran 2014

Posted In: Açık kaynak, bootstrap, flask, Gezegen, linux, Özgür yazılım, ozguryazilim, python

Flask ile Blog Uygulaması





Önceki yazımda Flask'ın kurulumunu anlatmıştım. Şimdi Flask kullanarak basitçe bir blog nasıl yazılır adım adım anlatmaya çalışacağım.

  $ mkdir flaskr
  $ cd flaskr
  $ vim schema.sql

  Açılan dosya içine şu satırları ekleyelim:

  drop table if exists entries;
  create table entries (
          id integer primary key autoincrement,
          title text not null,
          text text not null
   );

  Kaydedip çıkalım. Database olarak sqlite3 kullanacağız. Yukarıda blog bilgilerimizi ( id, başlık, gövde ) tutacak basit bir tablo oluşturmak için kullanacağımız dosyayı yazdık. id bilgisi primary key dir ve otomatik olarak artar. Devam edelim.

  $ vim flaskr.py

  Açtığımız dosyaya şu satırları ekliyoruz:

  # Gerekli modülleri dahil ettik
  import os
  import sqlite3
  from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash

  # app adında küçük bir uygulama oluşturduk.
  app = Flask(__name__)
  app.config.from_object(__name__)

  # Uygulama için gerekli yapılandırma bilgilerini ekledik.
  app.config.update(dict(
          DATABASE='/tmp/flaskr.db',
          DEBUG=True,
          SECRET_KEY=’development key’,
          USERNAME=’admin’,
          PASSWORD=’default’
  ))
  app.config.from_envvar(’FLASKR_SETTINGS’, silent=True)

# Özel bir veritabanına bağlantı yapmak için    def connect_db():
          rv = sqlite3.connect(app.config[’DATABASE’])
          rv.row_factory = sqlite3.Row
          return rv

# Veritabanı bağlantısı için gerekli kısım.
  def get_db():
  if not hasattr(g, ’sqlite_db’):
          g.sqlite_db = connect_db()
   return g.sqlite_db

  @app.teardown_appcontext
  def close_db(error):
  if hasattr(g, ’sqlite_db’):
          g.sqlite_db.close()

  # Veritabanını başlatacak kısım
  def init_db():
          with app.app_context():
                  db = get_db()
                  with app.open_resource(’schema.sql’, mode=’r’) as f:
                          db.cursor().executescript(f.read())
                  db.commit()

  # Yazılmış olan blog yazılarını ve başlıklarını görüntüleyecek kısım.
  @app.route(’/’)
  def show_entries():
          db = get_db()
          cur = db.execute(’select title, text from entries order by id desc’)
          entries = cur.fetchall()
          return render_template(’show_entries.html’, entries=entries)

  # Yeni bir blog girdisinin veritabanına girişini sağlayan kısım.
  @app.route(’/add’, methods=[’POST’])
  def add_entry():
          if not session.get(’logged_in’):
                  abort(401)
          db = get_db()
          db.execute(’insert into entries (title, text) values (?, ?)’, [request.form[’title’], request.form[’text’]])
          db.commit()
          flash(’New entry was successfully posted’)
          return redirect(url_for(’show_entries’))

  # Giriş yapmayı sağlayan kısım
  @app.route(’/login’, methods=[’GET’, ’POST’])
  def login():
          error = None
          if request.method == ’POST’:
                  if request.form[’username’] != app.config[’USERNAME’]:
                          error = ’Invalid username’
                  elif request.form[’password’] != app.config[’PASSWORD’]:
                          error = ’Invalid password’
                  else:
                          session[’logged_in’] = True
                          flash(’You were logged in’)
                          return redirect(url_for(’show_entries’))
          return render_template(’login.html’, error=error)


  # Çıkış yapmayı sağlayan kısım
  @app.route(’/logout’)
  def logout():
          session.pop(’logged_in’, None)
          flash(’You were logged out’)
          return redirect(url_for(’show_entries’))

  # Uygulamayı başlatan kısım
  if __name__ == ’__main__’:
          app.run()

    Bu dosyayı kaydedip çıkıyoruz. Komut satırında veri tabanınındaki tablomuzun oluşması için şu komutu  veriyoruz:

  $ sqlite3 /tmp/flaskr.db < schema.sql

  Veri tabanını başlatmak için python kabuğunda şu komutları veriyoruz:

  $ python
  >>> from flaskr import init_db
  >>> init_db()


  Şimdi gereken şablonları ekleyelim:

  $ mkdir templates
  $ cd templates
  $ vim layout.html

  Açılan dosyaya şu satırları ekleyelim:

  <!doctype html>
 <title>Flaskr</title>
 <link rel=stylesheet type=text/css href="{{ url_for(’static’, filename=’style.css’) }}">
 <div class=page>
   <h1>Flaskr</h1>
     <div class=metanav>
     {% if not session.logged_in %}
       <a href="{{ url_for(’login’) }}">log in</a>
     {% else %}
       <a href="{{ url_for(’logout’) }}">log out</a>
     {% endif %}
     </div>
     {% for message in get_flashed_messages() %}
       <div class=flash>{{ message }}</div>
     {% endfor %}
     {% block body %}{% endblock %}
   </div>

  Kaydedip çıkalım. Blog girdilerini göstermek için bir şablon ekleyelim

  $ vim show_entries.html

  Açılan dosyaya şu satırları ekleyelim:

  {% extends "layout.html" %}
  {% block body %}
    {% if session.logged_in %}
       <form action="{{ url_for(’add_entry’) }}" method=post class=add-entry>
       <dl>
         <dt>Title:
           <dd><input type=text size=30 name=title>
         <dt>Text:
           <dd><textarea name=text rows=5 cols=40></textarea>
           <dd><input type=submit value=Share>
       </dl> 
     </form>
  {% endif %}
  <ul class=entries>
  {% for entry in entries %}
     <li><h2>{{ entry.title }}</h2>{{ entry.text|safe }}
  {% else %}
     <li><em>Unbelievable. No entries here so far</em>
  {% endfor %}
   </ul>
{% endblock %}

  Kaydedip çıkalım. Şimdi giriş için bir şablon ekleyelim:

  $ vim login.html

  Açılan dosyaya şunları ekleyelim:

  {% extends "layout.html" %}
  {% block body %}
    <h2>Login</h2>
    {% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %}
     <form action="{{ url_for(’login’) }}" method=post>
       <dl>
         <dt>Username:
           <dd><input type=text name=username>
        <dt>Password:
          <dd><input type=password name=password>
        <dd><input type=submit value=Login>
      </dl>
    </form>
  {% endblock %}

 Kaydedip çıkalım. Şimdi görünümü iyileştirmek için css dosyası ekleyeceğiz. 

 $ cd ..
 $ mkdir static
 $ cd static
 $ vim style.css

 Açılan dosya içine şunları ekleyelim: 

 body            { font-family: sans-serif; background: #eee; }
 a, h1, h2       { color: #377ba8; }
 h1, h2          { font-family: ’Georgia’, serif; margin: 0; }
 h1              { border-bottom: 2px solid #eee; }
 h2              { font-size: 1.2em; }

 .page           { margin: 2em auto; width: 35em; border: 5px solid #ccc; padding: 0.8em;  background: white; }
 .entries        { list-style: none; margin: 0; padding: 0; }
 .entries li     { margin: 0.8em 1.2em; }
 .entries li h2  { margin-left: -1em; }
 .add-entry      { font-size: 0.9em; border-bottom: 1px solid #ccc; }
 .add-entry dl   { font-weight: bold; }
 .metanav        { text-align: right; font-size: 0.8em; padding: 0.3em; margin-bottom: 1em;  background: #fafafa; }
 .flash          { background: #cee5F5; padding: 0.5em; border: 1px solid #aacbe2; }
 .error          { background: #f0d6d6; padding: 0.5em; }


  Dosyayı kaydedip çıkabiliriz. 


  Şimdi flaskr.py dosyasının olduğu dizine geçelim ve uygulamayı çalıştıralım

  $ cd ..
  $ python flaskr.py

  Komut satırında karşımıza çıkan url yi tarayıcıya yazarak uygulamanın nasıl çalıştığını görebiliriz.


  

23 Haziran 2014

Posted In: Açık kaynak, flask, Gezegen, linux, ozguryazilim, python

Flask Hello World

  Merhabalar

  Bu yaz stajımda kullanacağım web uygulama çatısı Flask ile basit bir örneğin nasıl yapıldığından bahsedeceğim.

  Flask'ın kurulumuyla başlayalım:
   
  Python ile geliştirme yapacaksak "virtualenv" yani sanal geliştirme ortamını kurmamız kolaylık sağlayacaktır.

  $ sudo pip install virtualenv
  $ mkdir myproject
  $ cd myproject
  $ virtualenv venv
  $ . venv/bin/activate
  $ pip install Flask 

  Şu anda bulunduğumuz dizin içinde "flask" adında bir dizin oluşmuş olmalı. O dizinin içindeki bin dizininin yolunu PATH 'e eklememiz gerekiyor.

  $ vim ~/.profile
 
  Açılan dosyanın sonuna şu satırı ekliyoruz ( bin kendi dosya sisteminizde neredeyse onun yolunu yazmalısınız ) :

  export PATH=~/myproject/flask/bin:$PATH

  Yaptığımız değişikliği aktif etmek için şu komutu veriyoruz:

  $ source ~/.profile

  Flask projelerinin dosya yapısı şu şekildedir :

             /hello_world
                   /static
                   /templates

  static            => css ve javascript dosyaları bu dizinin altında olur.
  templates     => içinde de şablon dosyalarımızı tutarız.

  İlk uygulama için bu dizinlere şimdilik ihtiyacımız yok. Şimdi ilk uygulamamıza geçebiliriz. Bunu yaparken uygulamalarımız için myproject dizininden farklı bir dizin seçersek karışıklığı önleyebiliriz.

  $ mkdir hello_world
  $ cd hello_world
  $ vim hello.py
  
  Açtığımız dosya içine şu satırları ekliyoruz:
  
  from flask import Flask
 app = Flask(__name__)
  

@app.route('/')


@app.route('/index')


def index():


    return "Hello World!"





app.run(debug = True)


  Dosyayı kaydedip çıkıyoruz. 

    $ python hello.py

  Bu komutu çalıştırdığımızda eğer bir sorun yoksa şu çıktıyı verecektir:
    
    * Running on http://127.0.0.1:5000/
 
  Çıktıdaki url yi browser'ın adres çubuğuna yazdığımızda ekranda Hello World! yazdığını görebiliriz.
  



23 Haziran 2014

Posted In: Açık kaynak, flask, Gezegen, linux, Özgür yazılım, python

WP Twitter Auto Publish Powered By : XYZScripts.com