armchair programmer python program looking for soem peer review

Brian Skahan bskahan at spam.etria.com.invalid
Wed Dec 4 04:15:07 EST 2002


Hi folks,

I just finished a small python screenshot program and was hoping you
might take a look at it a give me some feedback.  It requires
python-2.2, python-xlib, and imagemagick.  Any advice on how to simplify
it it, add error handling, or remove some dependencies is appreciated.
tia,

-brian

-- 
* Brian Skahan|Towson  University|bskahan at etria.com|http://www.etria.com *
* Remember: People who send HTML mail are going to be the first against  *
*           the wall when the revolution comes.                          *

------------------------- begin code -----------------------

#!/usr/bin/env python
#
# Copyright (C) 2002 Brian Skahan
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with the program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

__author__ = "Brian Skahan <bskahan at etria.com>"
__date__ = "Dec 02 2002"
__version__ = "0.1"

import os
import ConfigParser
import calendar
from ftplib import FTP
from Xlib import *

class Screenshot:
    """Uses ImageMagick to create a screenshot

    if more than 1 X display screen is declared in ~/.circus/cscreenshot.cfg
    shots are taken of each screen and tacked together with montage.  A
    thumbnail is created from the final shot.  The files are named by date"""

    config = ConfigParser.ConfigParser()
    config.read(os.path.expanduser('~/.cscreenshot.cfg'))
    date = None
    short_file_name = None
    file_name = None
    short_thumb_name = None
    thumb_name = None
    screenshot = None
    screens = []
    disp = display.Display()  #should move this to num_screens()
    web_file = None

    # for multiheaded displays not using Xinerama, set the num_screens option
    # in ~/.circus/cscreenshot.cfg
    def num_screens(self):
        i=0
        while i < self.config.getint('main','num_screens'):
            self.screens.append(self.disp.get_display_name()[:-1] + str(i))
            i += 1

    # format the date into YYYY-MM-DD
    def get_date(self):
        full_date = calendar.localtime()
        self.date = "%d-%d-%d" %(full_date[0],full_date[1],full_date[2])

    # make sure we're putting things in the right directories
    def set_names(self):
        self.get_date()
        self.short_file_name = self.date    \
                                + "."       \
                                + self.config.get('main','img_type')

        self.file_name = self.config.get('main','img_dir')  \
                            + "/"                           \
                            + self.short_file_name

        self.short_thumb_name = self.date    \
                                + ".thumb."       \
                                + self.config.get('main','img_type')

        self.thumb_name = self.config.get('main','img_dir') \
                            + "/"                           \
                            + self.short_thumb_name

    # this does most of the work, use import to get shots for each screen and
    # use montage to join them if there's more than one display screen
    def snag_new(self):
        # theses are for the hardcode kludge
        temp0 = self.config.get('main','img_dir')   \
                                        + '/temp0.' \
                                        + self.config.get('main','img_type')

        temp1 = self.config.get('main','img_dir')   \
                                        + '/temp1.' \
                                        + self.config.get('main','img_type')

        for screen in self.screens:
            pid = os.fork()
            if not pid:
                os.execvp('import',['import',
                                    '-display',
                                    screen,
                                    '-window',
                                    'root',
                                    '-geometry',
                                    '1024',
                                    self.config.get('main','img_dir')\
                                        + '/'
                                        + 'temp'            \
                                        + str(screen[-1:])  \
                                        + "."               \
                                        + self.config.get('main','img_type')])
            os.wait()

        # XXX this is dumb, hard coded for 2 screens fix me
        # see about using os.tmpname
        if len(self.screens) > 1:
            pid = os.fork()
            if not pid:
                os.execvp('montage',['montage', 
                                     temp0, 
                                     temp1, 
                                     '-geometry', 
                                     '+0+0', 
                                     self.file_name])
            os.wait()

            # do some cleanup
            os.remove(temp0)
            os.remove(temp1)
        else:
            os.rename(temp0,self.file_name)

    # take self.file_name and make a thumb from it
    def make_thumb(self):
        pid = os.fork()
        if not pid:
            os.execvp('convert',['convert',
                                 '-geometry',
                                 self.config.get('main','thumb_size'),
                                 self.file_name,
                                 self.thumb_name])
        os.wait()

    # expands the html template and appends it to web_file
    # TODO put the new screenshot at the top instead
    def write_html(self):    
        # you can change this template as you like, each %s is replace in
        # order with the variables in parenthesis
        template = '''
<br class=\"divider\"/>
<div class=\"entry\">
  <a href=\"screens/%s\">
    <img class=\"thumb\" src=\"screens/%s\" alt=\"%s\"/>
  </a>
  <div class=\"heading\">%s</div>
  <br/>
</div> 
''' % (self.short_file_name,
        self.short_thumb_name,
        self.short_file_name,
        self.date)

        web_file = file(self.config.get('main','img_dir')   \
					+'/'		    \
					+self.config.get('main','web_file'),
								'a+')
        web_file.write(template)
        web_file.close()

    # connect to ftp site, upload web_file, screenshot and thumb
    def ftp_transfer(self):
        # get the configs for readability
        host = self.config.get('main','ftp_site')
        user = self.config.get('main','ftp_user')
        passwd = self.config.get('main','ftp_pass')
        remote_dir = self.config.get('main','remote_dir')

        # open the files for ftp
        img = file(self.file_name)
        thumb = file(self.thumb_name)
        web_file = file(self.config.get('main','img_dir')   \
                + '/'                                       \
                + self.config.get('main','web_file'),'r+')

        # intitiate FTP and connect
        ftp = FTP(host,user,passwd)

        # change to the correct directory
        ftp.cwd(remote_dir)

        # upload
        ftp.storlines('STOR ' + self.config.get('main','web_file'),web_file)
        ftp.storbinary('STOR ' + self.short_file_name,img)
        ftp.storbinary('STOR ' + self.short_thumb_name,thumb)

        # close files
        img.close()
        thumb.close()
        web_file.close()

    def main(self):
        self.num_screens()
        self.set_names()
        self.snag_new()
        self.make_thumb()
        if self.config.get('main','write_html') == 'true':
            self.write_html()
        if self.config.get('main','upload') == 'true':
            self.ftp_transfer()

if __name__ == '__main__':
    new = Screenshot()
    new.main()
 
#####################################################################
#
# Sample config file
#
#[main]
#
#img_dir = /home/you/pub_html/screens/
#
# at the moment I recomend using gifs (patent issues aside) pngs are to large
# and montage is fucking up jpgs for some reason.
#img_type = gif
#
# the number of monitors you have if you don't use xinerama
#num_screens = 2
#
#thumb_size = 200
#
# do you want to append the html template to a file
#write_html = true
#
# for now web file has to be in the img directory
#web_file = index.html
#
# do you want to upload the images and html
#upload = true
#
# the directory everything will go on your ftp site
#remote_dir = www/screens
#
#ftp_site = 555.555.555.555
#
#ftp_user = myusername
#
#ftp_pass = XXXXXXXX 

------------------ end code --------------------



More information about the Python-list mailing list