PythonGuide/QuoteOfTheDay

من PFWiki

اذهب إلى: تصفح, البحث

هننشئ فى المثال دا سرفس مشابهه ل "اقتباس اليوم" وهو سرفر يعمل فى الخلفية ويرسل اقتباس عشوائى لكل عميل ثم يغلق الإتصال معه

محتويات

ملف الإقتباسات

Never pretend to a love which you do not actually feel, for love is not ours to command.  --Alan Watts
To love deeply in one direction makes us more loving in all others. --Anne-Sophie Swetchine
There is always some madness in love. But there is also always some reason in madness. --Friedrich Nietzsche
Life is wasted on the living. --Douglas Adams
Life is just a chance to grow a soul. - A. Powell


quoter

ال quoter وهو موديل للحصول على الإقتباسات من ملف ما

#!bin/python
 
from __future__ import with_statement
import random as rnd
 
 
def get_quotes(f="quotes.txt"):
    ###quotes are separated by \n
    with open(f) as fh:
        lines=fh.read()
        quotes=lines.split("\n")
        return quotes
 
def get_random_quote(quotes=get_quotes()):
    return rnd.choice(quotes)
 
if __name__=="__main__":
    print get_random_quote()


زى ماشافين السطر الأول بيستدعى ال with_statement من المستقبل :d الإمكانات اللتى تم تقرير اضافتها للإصدارات الأحدث من بايثون والموديل random للحصول على اختيار عشوائى

  • الدالة get_quotes متغيرة فى f وهو مسار الملف اللذى يحوى الإقتباسات وجعلنها quotes.txt افتراضيا

لاحظ فى إستخدام with تم استبدال try/except لأنها تتم داخليا نحصل على الإقتباسات "كل سطر يحوى اقتباس" (ممكن تعمل strip للتأكيد على عدم وجود اسطر زائدة فى الملف

  • الدالة get_random_quote متغيرة فى quotes وهو قائمة list بالإقتباسات وجعلناها افتراضيا قيمة get_quotes() ، تستخدم للحصول على اختيار عشوائى من quotes ويتم ذلك بإستدعاء الدالة choice اللتى تعيد لنا اقتباس عشوائى متتابعة (قائمة) وهنا فى المثال هى quotes

السرفر quotd

from SocketServer import TCPServer, StreamRequestHandler, ThreadingMixIn
import threading
import quoter
from django.utils import daemonize
 
class MyServer(ThreadingMixIn,TCPServer):
    pass 
 
class MyStreamRequestHandler(StreamRequestHandler):
 
    def handle(self):
 
        self.request.send(self.get_quote()+"\r\n")
 
    def get_quote(self):
        return quoter.get_random_quote()
 
def go(endpoint=('', 58000)):
    addr=endpoint
    tcpServer=MyServer(addr, MyStreamRequestHandler)
    tcpServer.allow_reuse_address=1
    print "Server started..."
    tcpServer.serve_forever() #inf. loop
 
 
 
 
if __name__=="__main__":
    try:
        daemonize.become_daemon()
        go()
    except KeyboardInterrupt:
        exit()


الكود بسيط جدا عند اتصال اى عميل يتم الحصول على اقتباس عشوائى ويتم ارساله بس دا كود عادى جدا زى اللى سبق؟ بالفعل ولكن يختلف فى وجود الوحدة daemonize من django.utils وتنفيذ الدالة become_daemon منها

عمل خدمة

بكل بساطة هذا هو الكود المطلوب منك للتحويل الى daemon! تعالى نلقى نظرة على daemonize.become_daemon

 import os
import sys
 
if os.name == 'posix':
    def become_daemon(our_home_dir='.', out_log='/dev/null',
                      err_log='/dev/null', umask=022):
        "Robustly turn into a UNIX daemon, running in our_home_dir."
        # First fork
        try:
            if os.fork() > 0:
                sys.exit(0)     # kill off parent
        except OSError, e:
            sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
            sys.exit(1)
        os.setsid()
        os.chdir(our_home_dir)
        os.umask(umask)
 
        # Second fork
        try:
            if os.fork() > 0:
                os._exit(0)
        except OSError, e:
            sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
            os._exit(1)
 
        si = open('/dev/null', 'r')
        so = open(out_log, 'a+', 0)
        se = open(err_log, 'a+', 0)
        os.dup2(si.fileno(), sys.stdin.fileno())
        os.dup2(so.fileno(), sys.stdout.fileno())
        os.dup2(se.fileno(), sys.stderr.fileno())
        # Set custom file descriptors so that they get proper buffering.
        sys.stdout, sys.stderr = so, se
else:
    def become_daemon(our_home_dir='.', out_log=None, err_log=None, umask=022):
        """
        If we're not running under a POSIX system, just simulate the daemon
        mode by doing redirections and directory changing.
        """
        os.chdir(our_home_dir)
        os.umask(umask)
        sys.stdin.close()
        sys.stdout.close()
        sys.stderr.close()
        if err_log:
            sys.stderr = open(err_log, 'a', 0)
        else:
            sys.stderr = NullDevice()
        if out_log:
            sys.stdout = open(out_log, 'a', 0)
        else:
            sys.stdout = NullDevice()
 
    class NullDevice:
        "A writeable object that writes to nowhere -- like /dev/null."
        def write(self, s):
            pass


اذا لم تفهم الكود السابق من خبرة سابقة فى برمجة لينكس لاتقلق يكفيك استخدام الدالة مباشرة اذا لم يكن عندك django فلامشكلة قم بحفظ الملف السابق مع التطبيق

تجربة

استخدم telnet localhost 58000

striky@striky-desktop:~/workspace/pytut/src/nettut/quoter$ telnet localhost 58000 
Trying 127.0.0.1... 
Connected to localhost. 
Escape character is '^]'. 
Life is just a chance to grow a soul. - A. Powell 
Connection closed by foreign host.


→ Networking QuoteOfTheDay
أدوات شخصية