0xGA: Check-in [3f38ad2fef]

Yet another PHP framework, but made for org-mode and geeks.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add interruption mechanism to narv.py to allow devs to add custom actions to their apps
Timelines: family | ancestors | descendants | both | narv
Files: files | file ages | folders
SHA1:3f38ad2fef554b290b221e31d53a0519d58349ca
User & Date: milouse 2014-05-07 00:47:26
Context
2014-05-07
00:49
Add sqlite support and features to example app check-in: 66313b85fd user: milouse tags: narv
00:47
Add interruption mechanism to narv.py to allow devs to add custom actions to their apps check-in: 3f38ad2fef user: milouse tags: narv
2014-05-04
21:20
New installer version check-in: 19fd48004e user: milouse tags: narv
Changes

Changes to create_narv_installer.sh.

48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
65
66
67
This program will now exit to let you do all the necessary things before."
    exit 1
fi

mkdir $WORKINGREP

echo ":: creating shared necessary directories structure"

install -dm 755 $WORKINGREP/var/log
install -dm 777 $WORKINGREP/var/tmp
install -dm 755	$WORKINGREP/usr/bin
install -dm 755	$WORKINGREP/etc

install -Dm 755 narv.py $WORKINGREP/usr/bin
install -Dm 755 narv    $WORKINGREP/usr/bin

rm narv narv.py

echo "General installation finished."
echo "You may now want to create your first app by entering the command:"
echo "$WORKINGREP/usr/bin/narv create [-d $WORKINGREP] <appname>"







>













48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
This program will now exit to let you do all the necessary things before."
    exit 1
fi

mkdir $WORKINGREP

echo ":: creating shared necessary directories structure"
install -dm 755 $WORKINGREP/var/db
install -dm 755 $WORKINGREP/var/log
install -dm 777 $WORKINGREP/var/tmp
install -dm 755	$WORKINGREP/usr/bin
install -dm 755	$WORKINGREP/etc

install -Dm 755 narv.py $WORKINGREP/usr/bin
install -Dm 755 narv    $WORKINGREP/usr/bin

rm narv narv.py

echo "General installation finished."
echo "You may now want to create your first app by entering the command:"
echo "$WORKINGREP/usr/bin/narv create [-d $WORKINGREP] <appname>"

Changes to narv.py.

35
36
37
38
39
40
41

42
43
44
45
46
47
48
...
196
197
198
199
200
201
202





203
204
205
206




207
208
209
210
211
212
213
...
296
297
298
299
300
301
302

303
304
305
306
307
308
309
...
329
330
331
332
333
334
335

336
337
338
339
340
341
342
...
352
353
354
355
356
357
358





359
360
361
362
363
364
365
        'woff': 'application/font-woff',
        'atom': 'application/atom+xml; charset=utf-8',
        'json': 'application/json; charset=utf-8',
        'js': 'text/javascript; charset=utf-8',
        'py': 'text/plain',
        'gpg': 'text/plain',
        'el': 'text/plain',

        'org': 'text/plain; charset=utf-8',
        'pdf': 'application/pdf'
    }

    def __init__(self, request, App):

        self.routes = []
................................................................................
        if not self.current_domain in config:
            self.error = 'Domain is not reachable in configuration file'

        else:
            self.config = config[self.current_domain]
            logging.debug('Request is for App {0}'.format(self.appname))







    def log_message(self, message, *args):
        logging.info(message % args)






    def do_error_page(self, errno, reason):
        self.build_headers(int(errno), 'text/html; charset=utf-8')

        if errno in self.config:
            with open(self.config[errno], 'rb') as f:
                shutil.copyfileobj(f, self.wfile)
................................................................................
        else:
            self.do_501(self.error)



class NarvThreadedServer(ThreadingMixIn, HTTPServer):
    """Main threaded server"""



class Narv:
    def __init__(self, server_infos=('', 8000), request_handler=IcanDoThat):

        config = ConfigParser()
        config.read('etc/rc.conf')
................................................................................
            format='%(asctime)s -- [%(levelname)s] %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S',
            filename=os.path.join(narv_root_path, 'var/log/', log_file),
            level=getattr(logging, log_level.upper()))

        signal.signal(signal.SIGINT, self.shutdown)
        signal.signal(signal.SIGTERM, self.shutdown)


        self.server = NarvThreadedServer(server_infos, request_handler)
        server_thread = threading.Thread(target=self.server.serve_forever)
        server_thread.daemon = True
        server_thread.start()

        if os.getuid() == 0:
................................................................................
            os.setuid(pwd.getpwnam('nobody').pw_uid)

            # Ensure a very conservative umask
            os.umask(int('077', 8))
        else:
            os.chdir(narv_root_path)







    def start(self):
        logging.info("Serving {0} at port {1}".format(self.server.server_name, self.server.server_port))
        self.server.serve_forever()


    def shutdown(self, signal, frame):







>







 







>
>
>
>
>




>
>
>
>







 







>







 







>







 







>
>
>
>
>







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
...
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
...
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
...
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
        'woff': 'application/font-woff',
        'atom': 'application/atom+xml; charset=utf-8',
        'json': 'application/json; charset=utf-8',
        'js': 'text/javascript; charset=utf-8',
        'py': 'text/plain',
        'gpg': 'text/plain',
        'el': 'text/plain',
        'txt': 'text/plain',
        'org': 'text/plain; charset=utf-8',
        'pdf': 'application/pdf'
    }

    def __init__(self, request, App):

        self.routes = []
................................................................................
        if not self.current_domain in config:
            self.error = 'Domain is not reachable in configuration file'

        else:
            self.config = config[self.current_domain]
            logging.debug('Request is for App {0}'.format(self.appname))

            if self.server.should_interrupt:
                logging.info('Processing request after SIGUSR1')
                self.server.should_interrupt = False
                self.do_interrupt()


    def log_message(self, message, *args):
        logging.info(message % args)


    def do_interrupt(self):
        pass


    def do_error_page(self, errno, reason):
        self.build_headers(int(errno), 'text/html; charset=utf-8')

        if errno in self.config:
            with open(self.config[errno], 'rb') as f:
                shutil.copyfileobj(f, self.wfile)
................................................................................
        else:
            self.do_501(self.error)



class NarvThreadedServer(ThreadingMixIn, HTTPServer):
    """Main threaded server"""
    should_interrupt = False


class Narv:
    def __init__(self, server_infos=('', 8000), request_handler=IcanDoThat):

        config = ConfigParser()
        config.read('etc/rc.conf')
................................................................................
            format='%(asctime)s -- [%(levelname)s] %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S',
            filename=os.path.join(narv_root_path, 'var/log/', log_file),
            level=getattr(logging, log_level.upper()))

        signal.signal(signal.SIGINT, self.shutdown)
        signal.signal(signal.SIGTERM, self.shutdown)
        signal.signal(signal.SIGUSR1, self.interrupt)

        self.server = NarvThreadedServer(server_infos, request_handler)
        server_thread = threading.Thread(target=self.server.serve_forever)
        server_thread.daemon = True
        server_thread.start()

        if os.getuid() == 0:
................................................................................
            os.setuid(pwd.getpwnam('nobody').pw_uid)

            # Ensure a very conservative umask
            os.umask(int('077', 8))
        else:
            os.chdir(narv_root_path)


    def interrupt(self, signal, frame):
        logging.info('SIGUSR1 caught. Waiting for next request...')
        self.server.should_interrupt = True


    def start(self):
        logging.info("Serving {0} at port {1}".format(self.server.server_name, self.server.server_port))
        self.server.serve_forever()


    def shutdown(self, signal, frame):