Jul
14th
 

How to script Realtime backups in Python

Posted by admin in Python - No Comments

In this tutorial we shall show you how easy it is to make simple real-time backup software by using the Python module called Pyinotify. This module is based on the Linux kernel feature named inotify (included since kernel 2.6.13); and this being an event-driven notifier, it’ll convey its notifications from kernel space to user space by means of using system-calls. The Pyinotify module will eventually bind such calls.

Let’s get to the code now: create a file labelled “backup.py” in your working directory and paste in the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import os, os.path, time, signal, sys, operator, glob, shutil, filecmp
from pyinotify import WatchManager, Notifier, ThreadedNotifier, EventsCodes, ProcessEvent
 
 
BACKUP = {
        "/home/user/my_dir" : "/home/user/my_backup",
        "/home/user/test" : "/home/user/test_backup"        
}
 
 
class FileSystemEvent(ProcessEvent):
 
        def __init__(self, watcher):
                self.f = FileBackup(watcher)                
 
        def process_event(self, event):
                self.f.process_file(event.path, event.name)
 
        def process_IN_CREATE(self, event):
                self.process_event(event)
 
        def process_IN_DELETE(self, event):
                self.process_event(event)
 
        def process_IN_MODIFY(self, event):
                self.process_event(event)
 
 
class FileBackup:
        def __init__(self, watcher):
                self.watcher = watcher
                self.l = BACKUP.keys()
 
        def process_file(self, event_path, event_name):
                path = os.path.join(event_path, event_name)
 
                if os.path.isdir(path):
                        self.watcher.add(path) #watch new dir
                        base = self.get_base_path(path)
                else:
                        base = self.get_base_path(os.path.dirname(path))
 
                dst = BACKUP[base[0]]+base[1]
 
                try:
                        os.makedirs(dst)
                except: pass
 
 
                if os.path.isfile(path):
                        if os.path.isfile(dst+"/"+event_name):
                                if filecmp.cmp(path, dst+"/"+event_name):
                                        return                                
 
                        shutil.copy2(path, dst+"/"+event_name)
 
 
        def get_base_path(self, path):                
                for p in self.l:
                        if (len(path.replace(p, '')) < len(path)):
                                return p, path.replace(p, '')
                return "",""
 
 
class FileSystemWatcher():
        def __init__(self, dirs=[]):
                self.wm       = WatchManager()
                self.fse      = FileSystemEvent(self)
 
                self.mask     = EventsCodes.IN_DELETE | EventsCodes.IN_CREATE | EventsCodes.IN_MODIFY # events
                self.notifier = ThreadedNotifier(self.wm, self.fse)
 
                for dir in dirs: self.add(dir)               
 
        def start(self):
                self.notifier.start()
 
        def block(self):
                self.notifier.join() 
 
        def close(self):
                self.notifier.close() 
 
        def add(self, dirpath):
                if os.path.isdir(dirpath):
                        self.wdd = self.wm.add_watch(dirpath, self.mask, rec=True)
 
 
class KeyboardCatcher:
 
        def __init__(self):
                self.child = os.fork()
 
                if self.child == 0:
                        return
                else:
                        self.watch()
 
        def watch(self):
                try:
                        os.wait()
 
                except KeyboardInterrupt:
                        print 'KeyBoardInterrupt'
                        self.kill()
                sys.exit()                               
 
        def kill(self):
                try:
                        os.kill(self.child, signal.SIGKILL)
                except OSError: pass
 
 
 
 
def _copy_base_dir(src, dst):
        try:
                os.makedirs(dst)
 
        except OSError:                
                pass # Directory already exists!
 
        for path in glob.glob("%s/*" % src):
                dst2 = os.path.join(dst, os.path.basename(path))
 
                if os.path.isdir(path):
                        _copy_base_dir(path, dst2)                        
 
                elif os.path.isfile(path):
                        if os.path.isfile(dst2):
                                if filecmp.cmp(path, dst2):
                                        continue
 
                        shutil.copy2(path, dst)
 
 
def copy_base_dir():
        for src in BACKUP: 
                _copy_base_dir(src, BACKUP[src])        
 
 
 
def main():         
        KeyboardCatcher()
 
        #copy_base_dir()
 
        w = FileSystemWatcher(BACKUP.keys())
        w.start()          
        w.block()
 
 
if __name__ == "__main__":
        main()

With this script we’ll be able to backup our files in real-time.
First off we created a dictionary called BACKUP, in which we set those directories which are to be monitored and where we’re going to save all our files; in this way we can back-up one or more directories.

BACKUP = {
        "from1" : "to1",
        "from2" : "to2"
}

Now… on with the main() function:

The first instruction, KeyboardCatcher(), provides us with a new process in our program. This class is not mandatory, but allows us to catch any possible keyboard exceptions (ctrl-c). The main program will stand by, waiting; whilst the child process can continue following the script.

We commented out the call to the copy_base_dir() method, but you could use it as best suits your necessities. In a nutshell this method will back-up the directories—before starting with the file-system monitoring—and skip every already-existing file.

We reach now the program’s very core, that is monitoring the file-system using python.
We’ve done a class called FileSystemWatcher to which we pass the list of files to be monitored. This class has the office of ‘listening’ for file-system events via the Pyinotify module.

Of course, we’re the ones to appoint which events are to be captured. Indeed, with the following line, we choose the events we want secured.

self.mask = EventsCodes.IN_DELETE | EventsCodes.IN_CREATE | EventsCodes.IN_MODIFY

Establishing the events’ names is not enough though, we’ve to make a class whose callback functions are triggered by the occurrence of such event; in this case it’s the class FileSystemEvent with its three callbacks: process_IN_CREATE – process_IN_DELETE – process_IN_MODIFY.

Finally the class FileBackup, thanks to the process_file method, will check whether the file to be saved is already in the backup directory.

As previously addressed, this is a very simple script to make backups and could be surely improved and optimized.

Well, have fun!

NOTE: The script has been tested with Python 2.5.2 and, needless to say, with GNU Linux OS; those of you who are MS-windows dependent should probably fast for this time :-)

Jul
8th
 

Is your code fast? Find out with timeit!

Posted by admin in Python - No Comments

I bet many of you have wondered, at least once, how much time your method or class is going to take when executed. Well, thanks to the python timeit module we can really time our own code.
Quite often when tweaking with the code, it would be quite a good practice to test such tweaks by means of timing them; in this way we could be able to see which tweaked version of the code takes the more time. In this tutorial we’re going into the timeit module which has been added since python 2.3.

Using the aforementioned module is definitely simple; indeed with just three lines of code we shall be able to assess the execution time of our script, or part of it that is.

Let’s create a file called “test_timeit.py” in our working directory and let’s also copy the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import timeit
 
class Tester:
        def __init__(self):
                self.MAX = 100
                self.my_list = []
 
 
        def add_to_list(self):
                for i in range(self.MAX):
                        self.my_list.append(i)
 
 
        def remove_from_list(self):
                for elem in self.my_list:
                        self.my_list.remove(elem)
 
 
if __name__=="__main__":
        inst = Tester()
        t1   = timeit.Timer("inst.add_to_list()", "from __main__ import inst")
	#t1  = timeit.Timer("inst.remove_from_list()", "from __main__ import inst")
 
        try:
                print t1.timeit(200)        
		print t1.repeat(repeat=3, number=200)
        except:
                t1.print_exc()

Now for the explanatory part:

First of all we created a simple class named “Tester”, thus bundling two methods which we shall use to determine the execution time; they’re called add_to_list() and remove_to_list() and they’ll take care of adding or removing elements from our list, named as “my_list”.

Let’s get to the __main__ part now where, thanks to inst = Tester(), we shall create a new instance of our Tester class—this instance will let us reach each method which has to be timed.
Then from line 21 onwards, we tackle the timeit part.

The first one:

t1 = timeit.Timer("inst.add_to_list()", "from __main__ import inst")

by which we create an instance of the Timer class that will let us measure the execution time of our python code—each parameter used in this example is referring respectively to the method we time, namely “inst.add_to_list()”, and to the mandatory import which is enabling us to get an instance called inst.

NOTE: We would get the same result with: t1 = timeit.Timer(”Tester().add_to_list()”, “from __main__ import Tester”)

Now, getting to the real time-appraising part, the Timer class deploys two methods:

timeit([number=1000000])

This method returns the execution time of the main statement, which has been recalled as many times as parameter “number” dictates; in our example(line 25) we’ve used print t1.timeit(200), that is to say, the add_to_list() method of Tester class will be called for 200 times, at the end of which the amount of time(float) spent on such office will be returned.

repeat([repeat=3[, number=1000000]])

The repeat() method works in the same way of timeit(), just with a trifling variation; quite useful.
The number specified by “repeat” pinpoints how many times we take the measure.
As it is in our example, print t1.repeat(repeat=3, number=200), the method add_to_list() of Tester class is being recalled 200 times, at the end of which a new measure ensues, and so on as many times as it is indicated in the number “repeat”. As we can easily guess, the repeat() method returns a list with every recorded amount of time.

Here come other two simple and explanatory examples:

#Example 1
def factorial(x):
	if x == 0:
		return 1
	else:
		return x * factorial(x-1)
 
if __name__=="__main__":
    from timeit import Timer
    t = Timer("factorial(5)", "from __main__ import factorial")
    print t.timeit()
 
 
#Example 2
import timeit
 
s = """
for i in range(10):
    if i % 2 == 0:
        pass
"""
t= timeit.Timer(s)
print t.timeit()

As you can clearly see, using timeit is that easy, with ever so few steps we were able to time our python code.
Well? What are you waiting for? Get on with your testing! :-)

created by Damiano Porta and translated by Daniele Feuli

Jul
7th
 

Send email with attachments using Python

Posted by admin in Python - 1 Comment

Today we will look at a method of using the SMTP protocol via Python. Our goal is to create a class through which we can send emails with attachments.

First, a word about the SMTP protocol.

  • SMTP (Simple Mail Transfer Protocol) is the standard protocol for sending email via internet. By default, SMTP uses port number 25 and the transmission protocol is TCP. One of the first SMTP servers is sendmail, still widely in use, others exist, such as Postfix, Exim.

Ok, on to the code. The main way of sending emails via python is the smtplib.

Create a file called “smtp.py” in your working directory and paste the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import smtplib, os, time, atexit
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import formatdate
from email import Encoders
 
class ConnectionError(smtplib.SMTPException): pass
class LoginError(smtplib.SMTPException): pass
class DisconnectionError(smtplib.SMTPException): pass
class EmailSendError(smtplib.SMTPException): pass
 
class Smtp:
 
        def __init__(self, host, user, password, port=25):
                self._host        = host
                self._port        = port                
                self._user        = user
                self._password    = password
 
                self._message     = None
                self._subject     = None
                self._from_addr   = None
                self._rcpt_to     = None               
                self._server      = None         
                self._attachments = []
 
                atexit.register(close) #our close() method will be automatically executed upon normal interpreter termination
 
                self.connect()
 
 
        def connect(self):
 
                if all([self._host, self._port, self._user, self._password]):
 
                        try:    
                                self._server = smtplib.SMTP(self._host, self._port)
 
                        except smtplib.SMTPException, e:
                                raise ConnectionError("Connection failed!")
 
                        try:
                                self._server.login(self._user, self._password)        
 
                        except smtplib.SMTPException, e:                                
                                raise LoginError("Login Failed!")
 
 
 
        def close(self):                
 
                if self._server:
                        try:
                                self._server.quit()
 
                        except smtplib.SMTPException, e:                                
                                raise DisconnectionError("Disconnection failed!")
 
 
        def message(self, message):
                self._message = message
 
 
        def subject(self, subject):
                self._subject = subject
 
 
        def from_addr(self, email):
                self._from_addr = email
 
 
        def rcpt_to(self, email):
                self._rcpt_to = email
 
 
        def attach(self, file):
                if os.path.exists(file):
                        self._attachments.append(file)
 
 
        def load_attachments(self, m_message):
                for file in self._attachments:
                        part = MIMEBase('application', "octet-stream")
                        part.set_payload(open(file,"rb").read())
                        Encoders.encode_base64(part)
                        part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file))
                        m_message.attach(part)    
 
                return m_message
 
 
        def send(self, content_type='plain', charset='UTF-8'):
 
                if all([self._message, self._subject, self._from_addr, self._rcpt_to]):                                
 
                        m_message             = MIMEMultipart()
 
                        m_message['From']     = self._from_addr
                        m_message['To']       = self._rcpt_to
                        m_message['Date']     = formatdate(localtime=True)
                        m_message['Subject']  = self._subject
                        m_message['X-Mailer'] = "Python X-Mailer"
 
                        m_message.attach(MIMEText(self._message, content_type, charset))
 
                        m_message = self.load_attachments(m_message)
 
                        try:
                                self._server.sendmail(self._from_addr, self._rcpt_to, m_message.as_string())       
 
                        except smtplib.SMTPException, e:
                                raise EmailSendError("Email has not been sent")

Here we have a simple class ready for sending email over an authenticated connection via python.

Now for the explanation (This should be easy to understand for those of us who already use python a bit).

Skipping over the various module import commands required to run our class, we come to the declaration of 4 classes (from line 8 to 11) needed for error management.

  • ConnectionError – the exception generated if there is a problem in connecting to the SMTP server.
  • Loginerror – the exception generated when there is a problem with the login (user/password).
  • DisconnectionError – the exception generated when there is a problem when disconnecting from SMTP server.
  • EmailSendError – the exception generated when there is a problem in sending the email.

As you can see every exception inherits smtplib.SMTPException. In this way you can also catch our exceptions, by using the baseclass smtplib module.

Now we move on to the explanation of SMTP class

The class has an initialiser for the declaration of all attributes for the class and automatically calls the connect() method to connect to the SMTP server.

Moving on… at line number 33, we meet our connect() method, in which we will create an instance of the SMTP class (smtplib) and will then try to authenticate to the smtp server with self._server.login(). If there are errors in the connection or the login to the server, the two exceptions (ConnectionError, Loginerror) will be generated.

To successfully send an email certain data are needed: the sender, recipient, subject and message. For this reason, using our methods: from_addr(), rcpt_to(), subject(), and message() we will be able to upload all data needed to send our email. In addition to these basic methods, our class has a very useful method for attaching a file or files to our email, attach(file_path).

Now lets give it a try! Create a file named “test.py” in your working directory and paste the following code:

from smtp import Smtp
 
smtp = Smtp("mail.server.com", "user", "password")
smtp.subject('This is a test')
smtp.message('Email message')
smtp.from_addr('from@server.com')
smtp.rcpt_to('to@server.com')
smtp.attach("file1.jpg")
smtp.attach("file2.gif")
smtp.attach("file3.pdf")
smtp.send()

Need more explanation? :-)

Have fun using this!

Jul
6th
 

Generating PDF Files Using PHP

Posted by admin in PHP - No Comments

Creating PDF files with PHP is actually much less confusing than it may at first sound. One extension in PHP 4, named the PDFLib extension, enables you to dynamically create PDF files with the PHP scripts that you have.

If you have Windows, you already have a pre-installed PDF library that came with your package, so all you need to do is uncomment, or delete the # sign, from the appropriate lines. Linux users can download this extension at the website, http://www.pdflib.com/, but no matter which type of system you are working with, you need to have this installed before you can start. You also need to have Adobe Acrobat PDF reader installed on your computer. If you do not have this, you can easily download it for free at http://www.adobe.com/.

To read existing PDF files with PHP, you can also install the XPDF package on the website, http://www.foolabs.com/xpdf/about.html. This program includes “pdftotext”.

If you have these programs, you are ready to begin. First, you need to create a simple PDF file and save it to your computer.

// create handle for new PDF document
$pdf = pdf_new();
 
// open a file
pdf_open_file($pdf, "dogs.pdf");
 
// start a new page (A4)
pdf_begin_page($pdf, 550, 860);
 
// set a fill colour
pdf_setcolor($pdf, "fill", "rgb", 1, 1, 0);
 
// set a stroke colour
pdf_setcolor($pdf, "stroke", "rgb", 0, 0, 0);
 
// draw a rectangle
pdf_rect($pdf, 45, 480, 210, 320);
pdf_fill_stroke($pdf);
 
// set a fill colour
pdf_setcolor($pdf, "fill", "rgb", 0, 1, 0);
 
// set a stroke colour
pdf_setcolor($pdf, "stroke", "rgb", 0, 0, 1);
 
// get and use a font object
$arial = pdf_findfont($pdf, "verdana", "host", 1); pdf_setfont($pdf, $verdana, 12);
 
// print text
pdf_show_xy($pdf, "Dogs have made excellent companions to humans for hundreds of years,",50, 750);
pdf_show_xy($pdf, "so much so that they have been known as \"man's best friend\"", 60,745);
 
// add an image under the text
$image = pdf_open_image_file($pdf, "jpeg", "goldenretriever.jpg");
pdf_place_image($pdf, $image, 40, 700, 0.75);
 
// end page
pdf_end_page($pdf);
 
// close and save file
pdf_close($pdf);

The next step is to locate the file through your web browser. Once you have done this, PHP will implement the script, and a new PDF file will be created and stored on your computer in the particular location listed at the top of the document.

Listed are the basic steps to generating a PDF file using PHP:

  • First, you need to create a handle for the PDF script, which is also shown in the first line of the code above. Returning a handle to the document is done through the pdf_new() function.
  • Secondly, you have to name the file (second line of the code). This is done through the pdf_open_file() function. This requires the handle that was returned from the previous step, along with a file name that you create.
  • In the next step (third and sixth lines of the code), you are able to insert new pages into the document and end them with the pdf_begin_page() and pdf_end_page() functions. In between these two functions is the code that adds something into the document, including images, text, and geometric shapes.
  • Choosing and registering a font (fourth line of code) is done through the pdf_findfont() function, which is the selection part and requires the font name, the encoding that is to be used, and the Boolean values (the numbers or text that convert to “true”, or permit, and “false”, or not permit) and pdf_setfont(), which actually registers the font.
  • After the font is selected and registered, next is writing a line of text (fifth line). This is done through the pdf_show_xy() function. This requires a handle to the PDF file, a mention of the font type that is to be used in the document, the line of text that you want added into the document, and the X and Y coordinates, which give the points at where you want the text to start at. The coordinate numbers are based from the origin, which is located at (0,0).
  • The final step (seventh line) is to close the document, which is done through the pdf_close() function. This will also save the file to the location specified in the second step with the pdf_open_file() function and will get rid of the handle that was created in the document.

The PDFLib extension will not only allow you to write text to a page, but will also enable you to insert images, which occurs through the the pdf_open_image_file() and pdf_place_image() functions and geometric shapes, such as lines and circles. The drawing of a line, for example, will happen through pdf_moveto(), pdf_lineto() and pdf_stroke() functions.

Another addition you can insert into your document is a grid. This code shows how to draw a rectangular grid using horizontal and vertical lines:

// create new handle
$pdf = pdf_new();
 
// open PDF file
pdf_open_file($pdf, "my_grid.pdf");
 
// new page (A4)
pdf_begin_page_ext($pdf, 595, 842);
 
// set a color
pdf_setcolor($pdf, "stroke", "rgb", 0, 0, 0);
 
// draw vertical lines
for ($x=0; $x<=595; $x+=25) {
    pdf_moveto($pdf, $x, 0);
    pdf_lineto($pdf, $x, 842);
    pdf_stroke($pdf);
}
 
// draw horizontal lines
for ($y=0; $y<=842; $y+=25){
    pdf_moveto($pdf, 0, $y);
    pdf_lineto($pdf, 595, $y);
    pdf_stroke($pdf);
}
 
// finish page
pdf_end_page($pdf);
 
// close and save PDF document
pdf_end_document($pdf);

Once you know the steps and coding formats, creating PDF files with PHP is really quite simple and does not involve as much as some may first perceive.

Jul
6th
 

Using PHP to Count Active Website Users

Posted by admin in PHP - 1 Comment

This tutorial will show you two different methods to count the users currently surfing your website.

The first method uses a MySQL table to track users, although it can be used with any database supported by PHP with appropriate modification to the scripts. Here is the structure of the table you will need to create within an existing database:

CREATE TABLE `online_users` (
        `id` INT( 5 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
        `session` VARCHAR( 64 ) NOT NULL ,
        `timestamp` TIMESTAMP NOT NULL ,
        UNIQUE (
                `session`
        )
)

This table has three fields:

  • id, a counter that automatically increments for each new user that connects to the site
  • session, the unique session ID of each user
  • timestamp, the user’s date and time of connection

The PHP code to manage the counting of users is split into two files in order to improve readability.

First is the connection class contained in “Mysql.class.php”:

class Mysql{
 
        public function __construct($host='', $user='', $password='', $db=''){
                $this->conn = mysql_connect($host, $user, $password);
                if ($this->conn)
                        mysql_select_db($db, $this->conn);                
        }
 
        public function __destruct(){
                if ($this->conn)
                        mysql_close($this->conn);
        }
 
        public function query($sql){
                if ($this->conn)
                        return mysql_query($sql);
        }
 
        public function get_connection(){
                return $this->conn;
        }
}

This class has a constructor in which connects to the MySQL database, and a destructor that automatically closes the connection at the end of the script. The other two methods are used to execute the queries and to get the MySQL connection that we can use in other functions.

Most of the work will be done by this class in “User.class.php”:

class User{        
 
        public function __construct($db, $timer=TIMER){
                $this->session = session_id();
                $this->db      = $db;
                $this->timer   = $timer;
        }
 
        public function update(){
                $this->db->query("UPDATE online_users SET online_users.timestamp = CURRENT_TIMESTAMP WHERE online_users.session='". $this->session ."'");  
                if (mysql_affected_rows($this->db->get_connection()) < 1)
                        $this->db->query("INSERT INTO online_users(session) VALUES ('". $this->session ."')"); 
 
                $this->db->query("DELETE FROM online_users WHERE online_users.timestamp < CURRENT_TIMESTAMP - INTERVAL ". $this->timer ." SECOND");          
        }
 
        public function count_users(){
                $rs = $this->db->query("SELECT COUNT(*) AS users FROM online_users WHERE online_users.timestamp > CURRENT_TIMESTAMP - INTERVAL ". $this->timer ." SECOND");
                if ($rs){
                        $row = mysql_fetch_array($rs);
                        return $row['users'];
                }
                else
                        return -1;
        }
}

The constructor’s parameters are the instance of the MySql class from the first file, and the maximum duration (in seconds) for which a user will be considered active. The default duration is specified via a constant called TIMER provided by user code.

The purpose of the update() method is to update or create the record in the MySQL table that corresponds to the current connection, and then to remove all rows older that the duration passed to the constructor.

The count_users() method returns the number of users connected to the site based on when they last connected.

Here is a script that we can use to test the functionality of the code, after changing the parameters passed to the Mysql constructor to appropriate values:

session_start();
define('TIMER', 300); //5 minutes
 
require_once "Mysql.class.php";
require_once "User.class.php";
 
$db   = new Mysql("127.0.0.1", "root", "password", "users");
$user = new User($db);
 
$user->update(); 
echo $user->count_users();

The second method for counting users does not use MySQL, but instead uses PHP’s session functionality.

This class in “User.class.php” will do all the work:

class User{
 
        public function __construct($timer=TIMER){    
                $this->timer   = $timer;        
        }
 
        public function count_users(){
                $counter=0;
                foreach (glob(SESSION_PATH.'/*') as $file){
                        if(time() - fileatime($file) < $this->timer)
                                $counter++;                        
                }
                return $counter;
        }
}

This script tests the functionality of the class:

define('TIMER', 300); //5 minutes
define('SESSION_PATH', '/home/user/session');
 
session_save_path(SESSION_PATH);
session_start();
 
$user = new User();
echo $user->count_users();

Through use of session_save_path(SESSION_PATH) we set a unique directory for storage of session information in order to prevent conflicts with other PHP applications running on the server.

IMPORTANT: session_save_path() MUST be called before session_start().

After this step we create a new instance of the User class. There is no need for an update() method since we use a quirk of PHP’s session functionality. The count_users() method checks the last access time of the session information files in order to determine how many users are currently connected.

IMPORTANT: On UNIX-like operating systems, this method will NOT work on file systems that are mounted with the noatime mount option.

Jul
2nd
 

How to use Python Imaging Library

Posted by admin in Python - No Comments

The Python Imaging Libray (PIL) is a library that allows Python Programmers to open, save, and manipulate images. PIL mostly deals with image formats TIFF, JPG, BMP, PNG, and GIF, but there are even ways for a common user to add their own formats to the Library. The Python Imaging Library greatly speeds up programming time if the Python program deals with images at all.

To open an image with PIL, the library module merely needs to be defined, and then the Open command needs to be issued. To create an image from scratch, the “new” command must be used. Saving an image is as simple as using the “save” command. (Use “save” after modifying or creating an image).

#start out python code with the import of the Image Library
#The Image and ImageDraw libraries are part of PIL
 
import Image, ImageDraw
 
#now open the mypicture.bmp image, assign the image to the variable "bmp"
 
bmp = Image.open("mypicture.bmp")
 
#create a new image using the "new" command
 
newbmp = Image.new("RGB", (128, 128), "White")
 
#save the new image
 
newbmp.save("mypicture2.bmp")
 
#now, display both of the images
 
bmp.show()
 
newbmp.show()
 
# To do more than just a block of color, there are simple commands to write whatever you want.
# This is where the beauty of PIL comes into play.
# To draw a red line on the black image that was just created
 
draw = ImageDraw.Draw(newbmp)
 
draw.line((0, 0, 100, 100), fill=rgb(255,0,0))
 
del draw
 
# And to save and see the recent handiwork
 
newbmp.save("mypicturewithline.bmp")
 
newbmp.show()

Using PIL, you can also grab a single pixel and change it. Let’s see hows that’s done…

import Image, ImageDraw
 
bmp = Image.open("mypicture.bmp")
 
draw = ImageDraw.Draw(bmp )
 
draw.point((64,64), fill=None)
 
del draw
 
bmp.show()

To be able to work with PIL, you only need to know a few functions. New and open will get you an image to work with, save will write your image to the disk, and show will display what you’ve done so far. A bunch of other functions exist for modifying your image once you have it open. You can draft, convert (from one file type to another), crop (cut the image to a new size), and thumbnail and resize (excellent for automatic blogging or news sites).


How to add a watermark to your images using Python Imaging Library

One method involves putting one image on top of another. You will need an image of your transparent watermark handy, and then you’ll need the image you want to put it on. Then it’s just a simple process of “pasting” your watermark on the image. Let’s see how easy this process is using PIL.

import Image, ImageDraw
 
bmp= Image.open("mypicture.bmp")
 
mywatermark = Image.open("mywatermark.bmp")
 
bmp.paste(mywatermark, (0,0,100,100))
 
bmp.show()

Another water mark method just writes a text onto your image. You’ll need a little more doing, but it’s still really easy. (You will need a font file handy, just so you know.) In the middle of this function, you will notice a while loop. What we are doing here is testing the text size against the size of the image we want to watermark. We want the text to be a big as possible, and still remain inside the image. A little dynamic code goes a long way.

import Image, ImageDraw, ImageFont
 
bmp = Image.open("mypicture.bmp")
 
mywatermark = Image.new("RGBA", (bmp.size[0], bmp.size[1]))
 
drawing = ImageDraw.ImageDraw(mywatermark, "RGBA")
 
size = 0
 
while True:
 
    size += 1
 
    testfont = ImageFont.truetype(FONT, size)
 
    testtextw, testtexth = testfont.getsize("My Watermark Text")
 
    if testtextw+testtexth/3 > mywatermark.size[0]:
 
        break
 
    font = nextfont
 
    textw, texth = testtextw, testtexth
 
drawing.setfont(font)
 
drawing.text(((mywatermark.size[0]-textw)/2, (mywatermark.size[1]-texth)/2), "My Watermark Text")
 
bmp.paste(mywatermark, None, mywatermark)
 
bmp.show()

Nearly any image manipulation is incredibly simple when you use the Python Imaging Library. This is a very well thought out program that is freely available for you to use.

Jun
30th
 

Setting up a Basic Lighttpd Server

Posted by admin in Server - 1 Comment

Lighttpd is geared for speed, and has a smaller footprint than Apache. Having a decreased footprint is critical when the server is in high stress situations and when available hardware is scarce. Popular websites such as Youtube and Imageshack who receive great amounts of traffic each minute are served up by Lighttpd.

How to install Lighttpd and have a basic functioning server:

First, get the newest source from http://www.lighttpd.net .

Then login as super user:

user@linux-588u:~> su
Password:
linux-588u:/home/user #

Unpack using:

linux-588u:/home/user/desktop #  tar -xf /home/user/lighttpd-1.4.22.tar.gz

Then change the directory to where the Lighttpd source got unpacked:

linux-588u:/home/user/desktop #  cd /home/user/lighttpd-1.4.22
linux-588u:/home/user/lighttpd-1.4.22 #

Use the configure script, compile, and install:

linux-588u:/home/user/lighttpd-1.4.22 #  ./configure && make && make install

Now run lighttpd:

linux-588u:/home/user #  lighttpd

If Lighttpd installed correctly, you should get something like this:

2009-06-26 01:35:52: (server.c.552) No configuration available. Try using -foption.

Ok, now that we have Lighttpd installed, we can move onto creating the config file so Lighttpd can run correctly.

We will create the config file in the /etc directory using vi:

linux-588u:/home/user #  vi /etc/lighttpd.conf

This will bring up vi where we can add the following for a basic Lighttpd server, press the insert key then enter:

server.document-root = "/home/user/www/htdoc"
 
server.port = 80
 
mimetype.assign = (
  ".html" => "text/html",
  ".txt" => "text/plain",
  ".jpg" => "image/jpeg",
  ".png" => "image/png"
)
 
static-file.exclude-extensions = ( ".fcgi", ".php", ".py" )
 
index-file.names = ( "index.html", "index.py" )
 
server.modules = (
"mod_access",
"mod_cgi"
)
 
cgi.assign = ( ".py" => "/usr/bin/python",
                   ".php" => "/usr/bin/cgi-php")

After entering the config script, hit the escape key and type “wq” then enter to save and quit.

Now to get the server running with the conf file:

linux-588u:/home/user #  lighttpd -f /etc/lighttpd.conf
2009-06-26 01:52:36: (log.c.97) server started

Congratulations, you now have a working Lighttpd setup!

Config File Explained

“server.document-root”

Sets the document root for the server, where index.html and other files that need to be available to the web user.

“server.port”

Sets the port, TCP port 80 being the default port for http.

“mimetype.assign”

Sets the mimetype mappings.

“static-file.exclude-extensions”

Tells Lighttpd that these file types are handled by a cgi plugin that has been enabled. ( mod_cgi )

“server.modules”

Tells Lighttpd what modules to load.

“cgi.assign”

Tells what file types are handled by a cgi program.

For further information, visit http://www.lighttpd.net.

Search



Categories