示例#1
0
    def do_zip_post(self):

        # automatically acquires a post url
        u = urllib2.urlopen(serviceurl, data="any")
        h = json.loads(u.read())
        posturl = h["post_url"]
        redirect_url = h["redirect_url"]
        print "acquired post url", posturl
        print "redirected browser to", redirect_url

        args = [
            mwzip_cmd,
            '--daemonize',
            '--conf',
            "http://" + self.state.baseurl,
            '--posturl',
            posturl,
        ]

        for a in self.state.articles:
            a = a.split("/")[-1]
            if a:
                args.append('%s' % str(a))

        print "executing", mwzip_cmd, args
        daemonize()
        rc = subprocess.call(executable=mwzip_cmd, args=args)
        if rc != 0:
            self.send_response(500)
            self.end_headers()
            self.wfile.write("post failed")
        else:
            self.send_response(301)
            self.send_header("Location", redirect_url)
            self.end_headers()
示例#2
0
    def do_zip_post(self):

        # automatically acquires a post url 
        u = urllib2.urlopen(serviceurl, data="any")
        h = json.loads(u.read())
        posturl = h["post_url"]
        redirect_url = h["redirect_url"]
        print "acquired post url", posturl
        print "redirected browser to", redirect_url

        
        args = [
            mwzip_cmd,
            '--daemonize',
            '--conf', "http://" +self.state.baseurl,
            '--posturl', posturl,
        ]
        
        for a in self.state.articles:
            a = a.split("/")[-1]
            if a:
                args.append('%s' % str(a))

        print "executing", mwzip_cmd, args
        daemonize()
        rc = subprocess.call(executable=mwzip_cmd, args=args)
        if rc != 0:
            self.send_response(500)
            self.end_headers()
            self.wfile.write("post failed")
        else:
            self.send_response(301)
            self.send_header("Location", redirect_url)
            self.end_headers()
def post():
    parser = optparse.OptionParser(usage="%prog OPTIONS")
    parser.add_option("-i", "--input", help="ZIP file to POST")
    parser.add_option('-l', '--logfile',
        help='log output to LOGFILE',
    )
    parser.add_option("-p", "--posturl", help="HTTP POST ZIP file to POSTURL")
    parser.add_option("-g", "--getposturl",
        help='get POST URL from PediaPress.com, open upload page in webbrowser',
        action='store_true',
    )
    parser.add_option("-d", "--daemonize", action="store_true",
        help='become a daemon process as soon as possible')
    parser.add_option('--pid-file',
        help='write PID of daemonized process to this file',
    )
    options, args = parser.parse_args()
    
    use_help = 'Use --help for usage information.'
    if not options.input:
        parser.error('Specify --input.\n' + use_help)
    if (options.posturl and options.getposturl)\
        or (not options.posturl and not options.getposturl):
        parser.error('Specify either --posturl or --getposturl.\n' + use_help)
    if options.posturl:
        from mwlib.podclient import PODClient
        podclient = PODClient(options.posturl)
    elif options.getposturl:
        import webbrowser
        from mwlib.podclient import podclient_from_serviceurl
        podclient = podclient_from_serviceurl('http://pediapress.com/api/collections/')
        webbrowser.open(podclient.redirecturl)
    
    from mwlib import utils
    from mwlib.status import Status
    
    if options.logfile:
        utils.start_logging(options.logfile)
    
    if options.daemonize:
        utils.daemonize()
    if options.pid_file:
        open(options.pid_file, 'wb').write('%d\n' % os.getpid())
    
    
    status = Status(podclient=podclient)
    
    try:
        try:
            status(status='uploading', progress=0)
            podclient.post_zipfile(options.input)
            status(status='finished', progress=100)
        except Exception, e:
            status(status='error')
            raise
    finally:
        if options.pid_file:
            utils.safe_unlink(options.pid_file)
def watch():
    parser = optparse.OptionParser(usage="%prog [OPTIONS]")
    parser.add_option('-l', '--logfile',
        help='log output to LOGFILE',
    )
    parser.add_option('-d', '--daemonize',
        action='store_true',
        help='become daemon as soon as possible',
    )
    parser.add_option('--pid-file',
        help='write PID of daemonized process to this file',
    )
    parser.add_option('-q', '--queue-dir',
        help='queue directory, where new job files are written to (default: /var/cache/mw-watch/q/)',
        default='/var/cache/mw-watch/q/',
    )
    parser.add_option('-p', '--processing-dir',
        help='processing directory, where active job files are moved to (must be on same filesystem as --queue-dir, default: /var/cache/mw-watch/p/)',
        default='/var/cache/mw-watch/p/',
    )
    parser.add_option('-n', '--num-jobs',
        help='maximum number of simulataneous jobs (default: 5)',
        default='5',
    )
    options, args = parser.parse_args()
    
    try:
        options.num_jobs = int(options.num_jobs)
    except ValueError:
        parser.error('--num-jobs value must be an integer')
    
    from mwlib import filequeue, utils
    
    if options.logfile:
        utils.start_logging(options.logfile)
    
    if options.daemonize:
        utils.daemonize()
    if options.pid_file:
        open(options.pid_file, 'wb').write('%d\n' % os.getpid())
    
    poller = filequeue.FileJobPoller(
        queue_dir=options.queue_dir,
        processing_dir=options.processing_dir,
        max_num_jobs=options.num_jobs,
    ).run_forever()
    
    if options.pid_file:
        utils.safe_unlink(options.pid_file)
示例#5
0
文件: serve.py 项目: aarddict/mwlib
def main():
    from SocketServer import ForkingMixIn, ThreadingMixIn
    from wsgiref.simple_server import make_server, WSGIServer
    from flup.server import fcgi, fcgi_fork, scgi, scgi_fork
    
    class ForkingWSGIServer(ForkingMixIn, WSGIServer):
        pass
    
    class ThreadingWSGIServer(ThreadingMixIn, WSGIServer):
        pass
    
    proto2server = {
        'http': ForkingWSGIServer,
        'http_threaded': ThreadingWSGIServer,
        'fcgi': fcgi_fork.WSGIServer,
        'fcgi_threaded': fcgi.WSGIServer,
        'scgi': scgi_fork.WSGIServer,
        'scgi_threaded': scgi.WSGIServer,
    }
    
    parser = optparse.OptionParser(usage="%prog [OPTIONS]")
    parser.add_option('-l', '--logfile',
        help='log output to LOGFILE',
    )
    parser.add_option('-d', '--daemonize',
        action='store_true',
        help='become daemon as soon as possible',
    )
    parser.add_option('--pid-file',
        help='write PID of daemonized process to this file',
    )
    parser.add_option('-P', '--protocol',
        help='one of %s (default: http)' % ', '.join(proto2server.keys()),
        default='http',
    )
    parser.add_option('-p', '--port',
        help='port to listen on (default: 8899)',
        default='8899',
    )
    parser.add_option('-i', '--interface',
        help='interface to listen on (default: 0.0.0.0)',
        default='0.0.0.0',
    )
    parser.add_option('--cache-dir',
        help='cache directory (default: /var/cache/mw-serve/)',
        default='/var/cache/mw-serve/',
    )
    parser.add_option('--mwrender',
        help='(path to) mw-render executable',
        default='mw-render',
    )
    parser.add_option('--mwrender-logfile',
        help='global logfile for mw-render',
        metavar='LOGFILE',
    )
    parser.add_option('--mwzip',
        help='(path to) mw-zip executable',
        default='mw-zip',
    )
    parser.add_option('--mwzip-logfile',
        help='global logfile for mw-zip',
        metavar='LOGFILE',
    )
    parser.add_option('--mwpost',
        help='(path to) mw-post executable',
        default='mw-post',
    )
    parser.add_option('--mwpost-logfile',
        help='global logfile for mw-post',
        metavar='LOGFILE',
    )
    parser.add_option('-q', '--queue-dir',
        help='queue dir of mw-watch (if not specified, no queue is used)',
    )
    parser.add_option('-m', '--method',
        help='prefork or threaded (default: prefork)',
        default='prefork',
    )
    parser.add_option('--max-requests',
        help='maximum number of requests a child process can handle before it is killed, irrelevant for --method=threaded (default: 0 = no limit)',
        default='0',
        metavar='NUM',
    )
    parser.add_option('--min-spare',
        help='minimum number of spare processes/threads (default: 2)',
        default='2',
        metavar='NUM',
    )
    parser.add_option('--max-spare',
        help='maximum number of spare processes/threads (default: 5)',
        default='5',
        metavar='NUM',
    )
    parser.add_option('--max-children',
        help='maximum number of processes/threads (default: 50)',
        default='50',
        metavar='NUM',
    )
    parser.add_option('--report-from-mail',
        help='sender of error mails (--report-recipient also needed)',
        metavar='EMAIL',
    )
    parser.add_option('--report-recipient',
        help='recipient of error mails (--report-from-mail also needed)',
        metavar='EMAIL',
    )
    options, args = parser.parse_args()

    if args:
        parser.error('no arguments supported')
    
    
    if options.protocol not in proto2server:
        parser.error('unsupported protocol (must be one of %s)' % (
            ', '.join(proto2server.keys()),
        ))

    def to_int(opt_name):
        try:
            setattr(options, opt_name, int(getattr(options, opt_name)))
        except ValueError:
            parser.error('--%s value must be an integer' % opt_name.replace('_', '-'))
    
    to_int('port')
    to_int('max_requests')
    to_int('min_spare')
    to_int('max_spare')
    to_int('max_children')
    
    if options.method not in ('prefork', 'threaded'):
        parser.error('the only supported values for --method are "prefork" and "threaded"')
    
    from mwlib import serve, log, utils
    
    log = log.Log('mw-serve')
    
    if options.logfile:
        utils.start_logging(options.logfile)
    
    if options.daemonize:
        utils.daemonize()
    if options.pid_file:
        open(options.pid_file, 'wb').write('%d\n' % os.getpid())
    
    if options.method == 'threaded':
        options.protocol += '_threaded'
        flup_kwargs = {
            'maxThreads': options.max_children,
        }
    else:
        flup_kwargs = {
            'maxChildren': options.max_children,
            'maxRequests':  options.max_requests,
        }
    
    log.info("serving %s on %s:%s" % (options.protocol, options.interface, options.port))
    
    if options.report_recipient and options.report_from_mail:
        report_from_mail = options.report_from_mail.encode('utf-8')
        report_recipients = [options.report_recipient.encode('utf-8')]
    else:
        report_from_mail = None
        report_recipients = None
    
    app = serve.Application(
        cache_dir=options.cache_dir,
        mwrender_cmd=options.mwrender,
        mwrender_logfile=options.mwrender_logfile,
        mwzip_cmd=options.mwzip,
        mwzip_logfile=options.mwzip_logfile,
        mwpost_cmd=options.mwpost,
        mwpost_logfile=options.mwpost_logfile,
        queue_dir=options.queue_dir,
        report_from_mail=report_from_mail,
        report_recipients=report_recipients,
    )
    if options.protocol.startswith('http'):
        server = make_server(options.interface, options.port, app,
            server_class=proto2server[options.protocol],
        )
        try:
            server.serve_forever()
        except KeyboardInterrupt:
            pass
    else:
        serverclass = proto2server[options.protocol]
        serverclass(app,
            bindAddress=(options.interface, options.port),
            minSpare=options.min_spare,
            maxSpare=options.max_spare,
            **flup_kwargs
        ).run()
    
    if options.pid_file:
        utils.safe_unlink(options.pid_file)
    
    log.info('exit.')
示例#6
0
def main():    
    from mwlib.options import OptionParser

    parser = OptionParser()
    parser.add_option("-o", "--output", help="write output to OUTPUT")
    parser.add_option("-p", "--posturl", help="http post to POSTURL (directly)")
    parser.add_option("-g", "--getposturl",
        help='get POST URL from PediaPress.com, open upload page in webbrowser',
        action='store_true',
    )
    parser.add_option('--keep-tmpfiles',                  
        action='store_true',
        default=False,
        help="don't remove  temporary files like images",
    )
    
    parser.add_option("-s", "--status-file",
                      help='write status/progress info to this file')

    options, args = parser.parse_args()
    
    use_help = 'Use --help for usage information.'
        
                        
    if parser.metabook is None and options.collectionpage is None:
        parser.error('Neither --metabook nor, --collectionpage or arguments specified.\n' + use_help)
    if options.posturl and options.getposturl:
        parser.error('Specify either --posturl or --getposturl.\n' + use_help)
    if not options.posturl and not options.getposturl and not options.output:
        parser.error('Neither --output, nor --posturl or --getposturl specified.\n' + use_help)
    if options.posturl:
        from mwlib.podclient import PODClient
        podclient = PODClient(options.posturl)
    elif options.getposturl:
        import webbrowser
        from mwlib.podclient import podclient_from_serviceurl
        podclient = podclient_from_serviceurl('http://pediapress.com/api/collections/')
        pid = os.fork()
        if not pid:
            try:
                webbrowser.open(podclient.redirecturl)
            finally:
                os._exit(0)
        import time
        time.sleep(1)
        try:
            os.kill(pid, 9)
        except:
            pass
              
    else:
        podclient = None
    
    from mwlib import utils,  wiki
    
    if options.daemonize:
        utils.daemonize()
    if options.pid_file:
        open(options.pid_file, 'wb').write('%d\n' % os.getpid())

    filename = None
    status = None
    try:
        env = parser.makewiki()
        assert env.metabook, "no metabook"
            
        from mwlib.status import Status
        status = Status(options.status_file, podclient=podclient, progress_range=(1, 90))
        status(progress=0)
        output = options.output
            
        make_zip(output, options, env.metabook, podclient=podclient, status=status)
            
    except Exception, e:
        if status:
            status(status='error')
        raise
示例#7
0
        if output:
            zipfilename = output
        else:
            fd, zipfilename = tempfile.mkstemp()
            os.close(fd)

        if options.collectionpage:
            mwcollection = w['wiki'].getRawArticle(options.collectionpage)
            mb.loadCollectionPage(mwcollection)
        elif options.metabook:
            mb.readJsonFile(options.metabook)

        # do not daemonize earlier: Collection extension deletes input metabook file!
        if options.daemonize:
            daemonize()

        posturl = options.posturl
        if posturl:
            posturl = posturl.encode('utf-8')

        from mwlib.utils import get_multipart
        import urllib
        import urllib2

        zf = zipfile.ZipFile(zipfilename, 'w')
        z = recorddb.ZipfileCreator(zf, w['wiki'], w['images'])

        post_status('parsing')

        for x in articles:
def buildzip():
    from mwlib.options import OptionParser

    parser = OptionParser()
    parser.add_option("-o", "--output", help="write output to OUTPUT")
    parser.add_option("-p", "--posturl", help="http post to POSTURL (directly)")
    parser.add_option("-g", "--getposturl",
        help='get POST URL from PediaPress.com, open upload page in webbrowser',
        action='store_true',
    )
    options, args = parser.parse_args()
    
    use_help = 'Use --help for usage information.'
    if parser.metabook is None and options.collectionpage is None:
        parser.error('Neither --metabook nor, --collectionpage or arguments specified.\n' + use_help)
    if options.posturl and options.getposturl:
        parser.error('Specify either --posturl or --getposturl.\n' + use_help)
    if not options.posturl and not options.getposturl and not options.output:
        parser.error('Neither --output, nor --posturl or --getposturl specified.\n' + use_help)
    if options.posturl:
        from mwlib.podclient import PODClient
        podclient = PODClient(options.posturl)
    elif options.getposturl:
        import webbrowser
        from mwlib.podclient import podclient_from_serviceurl
        podclient = podclient_from_serviceurl('http://pediapress.com/api/collections/')
        webbrowser.open(podclient.redirecturl)
    else:
        podclient = None
    
    from mwlib import utils
    
    if options.daemonize:
        utils.daemonize()
    if options.pid_file:
        open(options.pid_file, 'wb').write('%d\n' % os.getpid())

    filename = None
    status = None
    try:
        try:
            env = parser.makewiki()
        
            from mwlib.status import Status
            from mwlib import zipcreator
        
            status = Status(podclient=podclient, progress_range=(1, 90))
            status(progress=0)
            
            filename = zipcreator.make_zip_file(options.output, env,
                status=status,
                num_threads=options.num_threads,
                imagesize=options.imagesize,
            )
            
            status = Status(podclient=podclient, progress_range=(91, 100))
            if podclient:
                status(status='uploading', progress=0)
                podclient.post_zipfile(filename)
            
            status(status='finished', progress=100)
        except Exception, e:
            if status:
                status(status='error')
            raise
    finally:
        if options.output is None and filename is not None:
            print 'removing %r' % filename
            utils.safe_unlink(filename)
        if options.pid_file:
            utils.safe_unlink(options.pid_file)
 if options.writer_options:
     for wopt in options.writer_options.split(';'):
         if '=' in wopt:
             key, value = wopt.split('=', 1)
         else:
             key, value = wopt, True
         writer_options[key] = value
 if options.language:
     writer_options['lang'] = options.language
 for option in writer_options.keys():
     if option not in getattr(writer, 'options', {}):
         print 'Warning: unknown writer option %r' % option
         del writer_options[option]
 
 if options.daemonize:
     utils.daemonize()
 if options.pid_file:
     open(options.pid_file, 'wb').write('%d\n' % os.getpid())
 
 status = Status(options.status_file, progress_range=(1, 70))
 status(progress=0)
 
 env = None
 try:
     try:
         env = parser.makewiki()            
         if not isinstance(env.wiki, zipwiki.Wiki)\
             or not isinstance(env.images, zipwiki.ImageDB):
             zip_filename = zipcreator.make_zip_file(options.keep_zip, env,
                 status=status,
                 num_threads=options.num_threads,
示例#10
0
 
 if output:
     zipfilename = output
 else:
     fd, zipfilename = tempfile.mkstemp()
     os.close(fd)
 
 if options.collectionpage:
     mwcollection = w['wiki'].getRawArticle(options.collectionpage)
     mb.loadCollectionPage(mwcollection)
 elif options.metabook:
     mb.readJsonFile(options.metabook)
 
 # do not daemonize earlier: Collection extension deletes input metabook file!
 if options.daemonize:
     daemonize()
 
 posturl = options.posturl
 if posturl:
     posturl = posturl.encode('utf-8')
 
 from mwlib.utils import get_multipart
 import urllib
 import urllib2
 
 zf = zipfile.ZipFile(zipfilename, 'w')
 z = recorddb.ZipfileCreator(zf, w['wiki'], w['images'])
 
 post_status('parsing')
 
 for x in articles:
示例#11
0
def buildzip():
    from mwlib.options import OptionParser

    parser = OptionParser()
    parser.add_option("-o", "--output", help="write output to OUTPUT")
    parser.add_option("-p",
                      "--posturl",
                      help="http post to POSTURL (directly)")
    parser.add_option(
        "-g",
        "--getposturl",
        help='get POST URL from PediaPress.com, open upload page in webbrowser',
        action='store_true',
    )
    options, args = parser.parse_args()

    use_help = 'Use --help for usage information.'
    if parser.metabook is None and options.collectionpage is None:
        parser.error(
            'Neither --metabook nor, --collectionpage or arguments specified.\n'
            + use_help)
    if options.posturl and options.getposturl:
        parser.error('Specify either --posturl or --getposturl.\n' + use_help)
    if not options.posturl and not options.getposturl and not options.output:
        parser.error(
            'Neither --output, nor --posturl or --getposturl specified.\n' +
            use_help)
    if options.posturl:
        from mwlib.podclient import PODClient
        podclient = PODClient(options.posturl)
    elif options.getposturl:
        import webbrowser
        from mwlib.podclient import podclient_from_serviceurl
        podclient = podclient_from_serviceurl(
            'http://pediapress.com/api/collections/')
        webbrowser.open(podclient.redirecturl)
    else:
        podclient = None

    from mwlib import utils

    if options.daemonize:
        utils.daemonize()
    if options.pid_file:
        open(options.pid_file, 'wb').write('%d\n' % os.getpid())

    filename = None
    status = None
    try:
        try:
            env = parser.makewiki()

            from mwlib.status import Status
            from mwlib import zipcreator

            status = Status(podclient=podclient, progress_range=(1, 90))
            status(status='parsing', progress=0)

            filename = zipcreator.make_zip_file(
                options.output,
                env,
                status=status,
                num_threads=options.num_threads,
                imagesize=options.imagesize,
            )

            status = Status(podclient=podclient, progress_range=(91, 100))
            if podclient:
                status(status='uploading', progress=0)
                podclient.post_zipfile(filename)

            status(status='finished', progress=100)
        except Exception, e:
            if status:
                status(status='error')
            raise
    finally:
        if options.output is None and filename is not None:
            print 'removing %r' % filename
            utils.safe_unlink(filename)
        if options.pid_file:
            utils.safe_unlink(options.pid_file)
示例#12
0
def watch():
    parser = optparse.OptionParser(usage="%prog [OPTIONS]")
    parser.add_option(
        '-l',
        '--logfile',
        help='log output to LOGFILE',
    )
    parser.add_option(
        '-d',
        '--daemonize',
        action='store_true',
        help='become daemon as soon as possible',
    )
    parser.add_option(
        '--pid-file',
        help='write PID of daemonized process to this file',
    )
    parser.add_option(
        '-q',
        '--queue-dir',
        help=
        'queue directory, where new job files are written to (default: /var/cache/mw-watch/q/)',
        default='/var/cache/mw-watch/q/',
    )
    parser.add_option(
        '-p',
        '--processing-dir',
        help=
        'processing directory, where active job files are moved to (must be on same filesystem as --queue-dir, default: /var/cache/mw-watch/p/)',
        default='/var/cache/mw-watch/p/',
    )
    parser.add_option(
        '-n',
        '--num-jobs',
        help='maximum number of simulataneous jobs (default: 5)',
        default='5',
    )
    options, args = parser.parse_args()

    try:
        options.num_jobs = int(options.num_jobs)
    except ValueError:
        parser.error('--num-jobs value must be an integer')

    from mwlib import filequeue, utils

    if options.logfile:
        utils.start_logging(options.logfile)

    if options.daemonize:
        utils.daemonize()
    if options.pid_file:
        open(options.pid_file, 'wb').write('%d\n' % os.getpid())

    poller = filequeue.FileJobPoller(
        queue_dir=options.queue_dir,
        processing_dir=options.processing_dir,
        max_num_jobs=options.num_jobs,
    ).run_forever()

    if options.pid_file:
        utils.safe_unlink(options.pid_file)
示例#13
0
def serve():
    from SocketServer import ForkingMixIn, ThreadingMixIn
    from wsgiref.simple_server import make_server, WSGIServer
    from flup.server import fcgi, fcgi_fork, scgi, scgi_fork

    class ForkingWSGIServer(ForkingMixIn, WSGIServer):
        pass

    class ThreadingWSGIServer(ThreadingMixIn, WSGIServer):
        pass

    proto2server = {
        'http': ForkingWSGIServer,
        'http_threaded': ThreadingWSGIServer,
        'fcgi': fcgi_fork.WSGIServer,
        'fcgi_threaded': fcgi.WSGIServer,
        'scgi': scgi_fork.WSGIServer,
        'scgi_threaded': scgi.WSGIServer,
    }

    parser = optparse.OptionParser(usage="%prog [OPTIONS]")
    parser.add_option(
        '-l',
        '--logfile',
        help='log output to LOGFILE',
    )
    parser.add_option(
        '-d',
        '--daemonize',
        action='store_true',
        help='become daemon as soon as possible',
    )
    parser.add_option(
        '--pid-file',
        help='write PID of daemonized process to this file',
    )
    parser.add_option(
        '-P',
        '--protocol',
        help='one of %s (default: http)' % ', '.join(proto2server.keys()),
        default='http',
    )
    parser.add_option(
        '-p',
        '--port',
        help='port to listen on (default: 8899)',
        default='8899',
    )
    parser.add_option(
        '-i',
        '--interface',
        help='interface to listen on (default: 0.0.0.0)',
        default='0.0.0.0',
    )
    parser.add_option(
        '--cache-dir',
        help='cache directory (default: /var/cache/mw-serve/)',
        default='/var/cache/mw-serve/',
    )
    parser.add_option(
        '--mwrender',
        help='(path to) mw-render executable',
        default='mw-render',
    )
    parser.add_option(
        '--mwrender-logfile',
        help='global logfile for mw-render',
        metavar='LOGFILE',
    )
    parser.add_option(
        '--mwzip',
        help='(path to) mw-zip executable',
        default='mw-zip',
    )
    parser.add_option(
        '--mwzip-logfile',
        help='global logfile for mw-zip',
        metavar='LOGFILE',
    )
    parser.add_option(
        '--mwpost',
        help='(path to) mw-post executable',
        default='mw-post',
    )
    parser.add_option(
        '--mwpost-logfile',
        help='global logfile for mw-post',
        metavar='LOGFILE',
    )
    parser.add_option(
        '-q',
        '--queue-dir',
        help='queue dir of mw-watch (if not specified, no queue is used)',
    )
    parser.add_option(
        '-m',
        '--method',
        help='prefork or threaded (default: prefork)',
        default='prefork',
    )
    parser.add_option(
        '--max-requests',
        help=
        'maximum number of requests a child process can handle before it is killed, irrelevant for --method=threaded (default: 0 = no limit)',
        default='0',
        metavar='NUM',
    )
    parser.add_option(
        '--min-spare',
        help='minimum number of spare processes/threads (default: 2)',
        default='2',
        metavar='NUM',
    )
    parser.add_option(
        '--max-spare',
        help='maximum number of spare processes/threads (default: 5)',
        default='5',
        metavar='NUM',
    )
    parser.add_option(
        '--max-children',
        help='maximum number of processes/threads (default: 50)',
        default='50',
        metavar='NUM',
    )
    parser.add_option(
        '--report-from-mail',
        help='sender of error mails (--report-recipient also needed)',
        metavar='EMAIL',
    )
    parser.add_option(
        '--report-recipient',
        help='recipient of error mails (--report-from-mail also needed)',
        metavar='EMAIL',
    )
    parser.add_option(
        '--clean-cache',
        help=
        'clean cache files that have not been touched for at least HOURS hours and exit',
        metavar='HOURS',
    )
    options, args = parser.parse_args()

    if options.clean_cache:
        try:
            options.clean_cache = int(options.clean_cache)
        except ValueError:
            parser.error('--clean-cache value must be an integer')
        from mwlib.serve import clean_cache
        clean_cache(options.clean_cache * 60 * 60, cache_dir=options.cache_dir)
        return

    if options.protocol not in proto2server:
        parser.error('unsupported protocol (must be one of %s)' %
                     (', '.join(proto2server.keys()), ))

    def to_int(opt_name):
        try:
            setattr(options, opt_name, int(getattr(options, opt_name)))
        except ValueError:
            parser.error('--%s value must be an integer' %
                         opt_name.replace('_', '-'))

    to_int('port')
    to_int('max_requests')
    to_int('min_spare')
    to_int('max_spare')
    to_int('max_children')

    if options.method not in ('prefork', 'threaded'):
        parser.error(
            'the only supported values for --method are "prefork" and "threaded"'
        )

    from mwlib import serve, log, utils

    log = log.Log('mw-serve')

    if options.logfile:
        utils.start_logging(options.logfile)

    if options.daemonize:
        utils.daemonize()
    if options.pid_file:
        open(options.pid_file, 'wb').write('%d\n' % os.getpid())

    if options.method == 'threaded':
        options.protocol += '_threaded'
        flup_kwargs = {
            'maxThreads': options.max_children,
        }
    else:
        flup_kwargs = {
            'maxChildren': options.max_children,
            'maxRequests': options.max_requests,
        }

    log.info("serving %s on %s:%s" %
             (options.protocol, options.interface, options.port))

    if options.report_recipient and options.report_from_mail:
        report_from_mail = options.report_from_mail.encode('utf-8')
        report_recipients = [options.report_recipient.encode('utf-8')]
    else:
        report_from_mail = None
        report_recipients = None

    app = serve.Application(
        cache_dir=options.cache_dir,
        mwrender_cmd=options.mwrender,
        mwrender_logfile=options.mwrender_logfile,
        mwzip_cmd=options.mwzip,
        mwzip_logfile=options.mwzip_logfile,
        mwpost_cmd=options.mwpost,
        mwpost_logfile=options.mwpost_logfile,
        queue_dir=options.queue_dir,
        report_from_mail=report_from_mail,
        report_recipients=report_recipients,
    )
    if options.protocol.startswith('http'):
        server = make_server(
            options.interface,
            options.port,
            app,
            server_class=proto2server[options.protocol],
        )
        try:
            server.serve_forever()
        except KeyboardInterrupt:
            pass
    else:
        serverclass = proto2server[options.protocol]
        serverclass(app,
                    bindAddress=(options.interface, options.port),
                    minSpare=options.min_spare,
                    maxSpare=options.max_spare,
                    **flup_kwargs).run()

    if options.pid_file:
        utils.safe_unlink(options.pid_file)

    log.info('exit.')
示例#14
0
def post():
    parser = optparse.OptionParser(usage="%prog OPTIONS")
    parser.add_option("-i", "--input", help="ZIP file to POST")
    parser.add_option(
        '-l',
        '--logfile',
        help='log output to LOGFILE',
    )
    parser.add_option("-p", "--posturl", help="HTTP POST ZIP file to POSTURL")
    parser.add_option(
        "-g",
        "--getposturl",
        help='get POST URL from PediaPress.com, open upload page in webbrowser',
        action='store_true',
    )
    parser.add_option("-d",
                      "--daemonize",
                      action="store_true",
                      help='become a daemon process as soon as possible')
    parser.add_option(
        '--pid-file',
        help='write PID of daemonized process to this file',
    )
    options, args = parser.parse_args()

    use_help = 'Use --help for usage information.'
    if not options.input:
        parser.error('Specify --input.\n' + use_help)
    if (options.posturl and options.getposturl)\
        or (not options.posturl and not options.getposturl):
        parser.error('Specify either --posturl or --getposturl.\n' + use_help)
    if options.posturl:
        from mwlib.podclient import PODClient
        podclient = PODClient(options.posturl)
    elif options.getposturl:
        import webbrowser
        from mwlib.podclient import podclient_from_serviceurl
        podclient = podclient_from_serviceurl(
            'http://pediapress.com/api/collections/')
        webbrowser.open(podclient.redirecturl)

    from mwlib import utils
    from mwlib.status import Status

    if options.logfile:
        utils.start_logging(options.logfile)

    if options.daemonize:
        utils.daemonize()
    if options.pid_file:
        open(options.pid_file, 'wb').write('%d\n' % os.getpid())

    status = Status(podclient=podclient)

    try:
        try:
            status(status='uploading', progress=0)
            podclient.post_zipfile(options.input)
            status(status='finished', progress=100)
        except Exception, e:
            status(status='error')
            raise
    finally:
        if options.pid_file:
            utils.safe_unlink(options.pid_file)
示例#15
0
    if options.writer is None:
        parser.error('Please specify a writer with --writer.\n' + use_help)

    writer = load_writer(options.writer)
    writer_options = {}
    if options.writer_options:
        for wopt in options.writer_options.split(';'):
            if '=' in wopt:
                key, value = wopt.split('=', 1)
                writer_options[key] = value
            else:
                writer_options[wopt] = True

    if options.daemonize:
        utils.daemonize()
    if options.pid_file:
        open(options.pid_file, 'wb').write('%d\n' % os.getpid())

    status = Status(options.status_file, progress_range=(1, 70))
    status(status='parsing', progress=0)

    env = None
    try:
        try:
            env = parser.makewiki()

            if not isinstance(env.wiki, zipwiki.Wiki)\
                or not isinstance(env.images, zipwiki.ImageDB):
                zip_filename = zipcreator.make_zip_file(
                    options.keep_zip,