Comment: | Made the app substantially prettier |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
517f4aa073cf39995af8c701e95bf906 |
User & Date: | spiffy on 2011-11-30 04:12:13 |
Other Links: | manifest | tags |
2011-12-02
| ||
03:31 | Made feed and story list divs clickable instead of just their text check-in: 7ff27f901d user: spiffy tags: trunk | |
2011-11-30
| ||
04:12 | Made the app substantially prettier check-in: 517f4aa073 user: spiffy tags: trunk | |
02:49 | Made the story title in the story view nicely styled. Put the 'mark story read' button inside the header check-in: dea6297b3d user: spiffy tags: develop, v0.4 | |
2011-11-20
| ||
21:41 | Added support for multiple users to use the site simultaneously check-in: 2ac904a27b user: spiffy tags: trunk, v0.2 | |
Modified applications/mobileblur/controllers/default.py from [4edf6967cb] to [cdfea9e32e].
︙ | ︙ | |||
19 20 21 22 23 24 25 | Field("password", "password", requires=IS_NOT_EMPTY()) ) if login_form.accepts(request): try: results = newsblur.login(login_form.vars["username"], login_form.vars["password"]) response.cookies["nb_cookie"] = newsblur.cookies["newsblur_sessionid"] response.cookies["nb_cookie"]["path"] = "/" | < > > > > > > > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | Field("password", "password", requires=IS_NOT_EMPTY()) ) if login_form.accepts(request): try: results = newsblur.login(login_form.vars["username"], login_form.vars["password"]) response.cookies["nb_cookie"] = newsblur.cookies["newsblur_sessionid"] response.cookies["nb_cookie"]["path"] = "/" redirect(URL("index")) except Exception as ex: login_form.insert(-1, ex.message) login_form._class = "alert-message block-message error" return dict(login_form=login_form) def logout(): response.cookies["nb_cookie"] = "" response.cookies["nb_cookie"]["expires"] = -10 response.cookies["nb_cookie"]["path"] = "/" redirect(URL("index")) |
Modified applications/mobileblur/controllers/feeds.py from [b47f0eada4] to [30c965b149].
1 2 3 4 5 | # -*- coding: utf-8 -*- from pprint import pprint def view(): | > > > | > > > > > > > | > > > | > > > > > > | | 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 | # -*- coding: utf-8 -*- from pprint import pprint import time def view(): print "" s = time.time() feed = newsblur.feed(request.args[0]) stories = feed["stories"] print time.time() - s print feed.keys() if not feed.has_key("feed_title"): s = time.time() feeds = newsblur.feeds(flat=True)["feeds"] print time.time() - s s = time.time() feed = [feed for feed in feeds.itervalues() if feed["id"]==int(request.args[0])][0] print time.time() - s response.title = feed["feed_title"] return dict(stories=stories, feed=feed) def mark_read(): if len(request.args) > 0: newsblur.mark_feed_as_read(request.args[0]) redirect(URL("default", "index")) |
Modified applications/mobileblur/controllers/stories.py from [59984e848a] to [fbf9de8ba7].
1 2 3 4 5 6 7 | # -*- coding: utf-8 -*- from pprint import pprint def view(): stories = newsblur.feed(request.vars["feed_id"])["stories"] story = [story for story in stories if story["id"]==request.vars["story"]][0] | | > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 | # -*- coding: utf-8 -*- from pprint import pprint def view(): stories = newsblur.feed(request.vars["feed_id"])["stories"] story = [story for story in stories if story["id"]==request.vars["story"]][0] return dict(story=story, feed_id=request.vars["feed_id"]) def mark_read(): results = newsblur.mark_story_as_read(request.vars["story_id"], request.vars["feed_id"]) redirect(URL("default", "index")) |
Modified applications/mobileblur/models/0_helpers.py from [c67dbf684a] to [8ed26c507d].
1 2 3 4 5 6 | newsblur = local_import("newsblur") newsblur = newsblur.NewsBlur() threshold = 0 thresholds = ["nt", "ps", "ng"] # indices -1, 0, 1 for negative, neutral, and positive intelligence filters | < | 1 2 3 4 5 6 7 8 9 10 11 | newsblur = local_import("newsblur") newsblur = newsblur.NewsBlur() threshold = 0 thresholds = ["nt", "ps", "ng"] # indices -1, 0, 1 for negative, neutral, and positive intelligence filters if [request.application, request.controller, request.function] != [request.application, "default", "login"]: if "nb_cookie" not in request.cookies.keys(): redirect(URL("default", "login")) else: newsblur.cookies["newsblur_sessionid"] = request.cookies["nb_cookie"].value |
Modified applications/mobileblur/modules/newsblur.py from [a487a766ef] to [df40c3d1a1].
︙ | ︙ | |||
19 20 21 22 23 24 25 | Login as an existing user. If a user has no password set, you cannot just send any old password. Required parameters, username and password, must be of string type. ''' url = nb_url + 'api/login' results = requests.post(url, data={"username": username, "password": password}) | < < | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | Login as an existing user. If a user has no password set, you cannot just send any old password. Required parameters, username and password, must be of string type. ''' url = nb_url + 'api/login' results = requests.post(url, data={"username": username, "password": password}) self.cookies = results.cookies results = simplejson.loads(results.content) if results["authenticated"] is False: raise Exception("The newsblur credentials you provided are invalid") return results def logout(self, ): |
︙ | ︙ |
Modified applications/mobileblur/static/css/base.css from [0353986da0] to [c4d6d0ed8b].
︙ | ︙ | |||
23 24 25 26 27 28 29 | - always indent the first line and add space below paragraphs - bullets and numbers style and indent - form and table padding - code blocks - left and right padding to quoted text - page layout alignment, width and padding (change this for spaces) - column widths (change this to use left_sidebar and right_sidebar) | | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | - always indent the first line and add space below paragraphs - bullets and numbers style and indent - form and table padding - code blocks - left and right padding to quoted text - page layout alignment, width and padding (change this for spaces) - column widths (change this to use left_sidebar and right_sidebar) - background images and colors (change this for colors) - web2py specific (.flash, .error) Notice: - even if you use a different layout/css you may need classes .flash and .error - this is all color neutral except for #349C01 (header, links, lines) - there are two background images: images/background.png and images/header.png License: This file is released under BSD and MIT */ /* credit is left where credit is due. |
︙ | ︙ | |||
141 142 143 144 145 146 147 | h1,h2,h3,h4,h5,h6 { font-weight: bold; } /* always force a scrollbar in non-IE */ html { overflow-y: scroll; } /* Accessible focus treatment: people.opera.com/patrickl/experiments/keyboard/test */ a:hover, a:active { outline: none; } | | > | 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | h1,h2,h3,h4,h5,h6 { font-weight: bold; } /* always force a scrollbar in non-IE */ html { overflow-y: scroll; } /* Accessible focus treatment: people.opera.com/patrickl/experiments/keyboard/test */ a:hover, a:active { outline: none; } /* a, a:active, a:visited { color:#607890; } a:hover { color:#036; } */ ul, ol { margin-left: 1.8em; } ol { list-style-type: decimal; } /* Remove margins for navigation lists */ nav ul, nav li { margin: 0; } |
︙ | ︙ | |||
325 326 327 328 329 330 331 | } fieldset { border: 1px solid #dedede; padding: 6px; } legend { font-weight: bold; } input:focus, textarea:focus { background: #fafafa; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | } fieldset { border: 1px solid #dedede; padding: 6px; } legend { font-weight: bold; } input:focus, textarea:focus { background: #fafafa; } h1,h2,h3,h4,h5,h6 { line-height: 170%; } h1 {font-size: 2.0em;} h2 {font-size: 1.8em;} h3 {font-size: 1.4em;} h4 {font-size: 1.2em;} h5 {font-size: 1.0em;} h6 {font-size: 0.8em;} /*********** web2py specific ***********/ div.flash { font-weight: bold; display: none; position: fixed; padding: 10px; top: 40px; |
︙ | ︙ | |||
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 | /* Uncomment if you don't want iOS and WinMobile to mobile-optimize the text for you j.mp/textsizeadjust html { -webkit-text-size-adjust:none; -ms-text-size-adjust:none; } */ } /* * print styles * inlined to avoid required HTTP connection www.phpied.com/delay-loading-your-print-css/ */ @media print { * { background: transparent !important; color: #444 !important; text-shadow: none !important; } a, a:visited { color: #444 !important; text-decoration: underline; } a:after { content: " (" attr(href) ")"; } abbr:after { content: " (" attr(title) ")"; } .ir a:after { content: ""; } /* Don't show links for images */ pre, blockquote { border: 1px solid #999; page-break-inside: avoid; } thead { display: table-header-group; } /* css-discuss.incutio.com/wiki/Printing_Tables */ tr, img { page-break-inside: avoid; } @page { margin: 0.5cm; } p, h2, h3 { orphans: 3; widows: 3; } h2, h3{ page-break-after: avoid; } } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 | /* Uncomment if you don't want iOS and WinMobile to mobile-optimize the text for you j.mp/textsizeadjust html { -webkit-text-size-adjust:none; -ms-text-size-adjust:none; } */ } @media handheld { body { } } /* * print styles * inlined to avoid required HTTP connection www.phpied.com/delay-loading-your-print-css/ */ @media print { * { background: transparent !important; color: #444 !important; text-shadow: none !important; } a, a:visited { color: #444 !important; text-decoration: underline; } a:after { content: " (" attr(href) ")"; } abbr:after { content: " (" attr(title) ")"; } .ir a:after { content: ""; } /* Don't show links for images */ pre, blockquote { border: 1px solid #999; page-break-inside: avoid; } thead { display: table-header-group; } /* css-discuss.incutio.com/wiki/Printing_Tables */ tr, img { page-break-inside: avoid; } @page { margin: 0.5cm; } p, h2, h3 { orphans: 3; widows: 3; } h2, h3{ page-break-after: avoid; } } body { /* background-color: #f2c84b;*/ color: #493F3E } header { background-color: #95392E; padding: 1%; border-bottom: 1px solid #95392E; color: white; } header > h1 > a { text-decoration: none; color: white; font-weight: bold; } #story > header > a { color: white; } header > a> h2 { /* border-top: 1px solid white;*/ color: white; } #story-list { /* background-color: #f2c84b;*/ } #story-list > .story > a, .feed > a { text-decoration: none; font-weight: bold; margin-top: 0; } #story-list > .story > p { font-size: .75em; } #story-list > .story > .read { color: #D99B48; } #story-list > .story > .unread, .feed > a { color: #C57E3C; } #story-list > .story, .feed { padding: .5%; border-top: 1px solid #95392E; margin-top: .33%; } span.ps, span.nt, span.ng { padding: .05em; border-radius: 5px; } span.ps { background-color: #ABAA7A; } span.nt { background-color: #D99B48; } span.ng { background-color: red; } footer { background-color: #95392E; padding: 1%; border-top: 1px solid #95392E; color: white; } footer > a { text-decoration: none; color: white; font-weight: bold; } |
Modified applications/mobileblur/views/default/index.html from [1ac89d52bc] to [de8ac0789f].
|
| < > | | | | > < < < | 1 2 3 4 5 6 7 8 9 10 | {{extend 'layout.html'}} {{ for feed in feeds.itervalues(): }} <div class="feed"> {{ if threshold == -1 and feed["ng"] > 0: }} <span class='ng'>{{= feed["ng"] }}</span> {{ pass }} {{ if threshold <= 0 and feed["nt"] > 0: }} <span class='nt'>{{= feed["nt"] }}</span> {{ pass }} {{if feed["ps"] > 0: }}<span class='ps'>{{= feed["ps"] }}</span> {{ pass }} <a href="{{= URL(c="feeds", f="view", args=[feed["id"]]) }}">{{= feed["feed_title"] }}</a><br /> </div> {{ pass }} |
Modified applications/mobileblur/views/feeds/view.html from [3646a45d79] to [6526673ca3].
|
| < > | | > > > > > > > | > > > > > > | > > > > | | < < > | 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 | {{extend 'layout.html'}} {{ block header_bonus }} <h2>{{= feed["feed_title"] }}</h2> <a href="{{= URL("mark_read", args=[feed["id"]]) }}" class="button">Mark feed as read</a> {{ end }} <section id="story-list"> {{ import time s = time.time() }} {{ for story in stories: if sum([v for k,v in story["intelligence"].iteritems()]) < threshold: continue }} {{ print story["read_status"] }} <div class="story"> <a href="{{= URL(c="stories", f="view", vars=dict(story=story["id"], feed_id=feed["id"])) }}" class="{{= "unread" if story["read_status"] == 0 else "read" }}"> {{= story["story_title"] }} </a> <p>{{= story["story_date"] }}</p> </div> {{ pass }} {{ print time.time() - s }} </section> |
Modified applications/mobileblur/views/layout.html from [78b7d8a5ef] to [2dc8430c3d].
1 2 3 4 5 6 7 8 9 10 11 12 | <!DOCTYPE html> <html lang="{{=T.accepted_language or 'en'}}" class="no-js"><!-- no-js need it for modernzr --> <head> <meta charset="utf-8" /> <!-- www.phpied.com/conditional-comments-block-downloads/ --> <!--[if IE]><![endif]--> <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame Remove this if you use the .htaccess --> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> | | | | 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 | <!DOCTYPE html> <html lang="{{=T.accepted_language or 'en'}}" class="no-js"><!-- no-js need it for modernzr --> <head> <meta charset="utf-8" /> <!-- www.phpied.com/conditional-comments-block-downloads/ --> <!--[if IE]><![endif]--> <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame Remove this if you use the .htaccess --> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>{{ block title }}{{= " - ".join([response.title, request.application]) }}{{ end }}</title> <!-- http://dev.w3.org/html5/markup/meta.name.html --> <meta name="application-name" content="{{=request.application}}" /> <!-- Speaking of Google, don't forget to set your site up: http://google.com/webmasters --> <meta name="google-site-verification" content="" /> <!-- Mobile Viewport Fix j.mp/mobileviewport & davidbcalhoun.com/2010/viewport-metatag device-width: Occupy full width of the screen in its current orientation initial-scale = 1.0 retains dimensions instead of zooming out if page height > device height maximum-scale = 1.0 retains dimensions instead of zooming in if page width < device width --> <meta name="viewport" content="width=320" /> <!-- Place favicon.ico and apple-touch-icon.png in the root of your domain and delete these references --> <link rel="shortcut icon" href="{{=URL('static','favicon.ico')}}" type="image/x-icon"> <link rel="apple-touch-icon" href="{{=URL('static','favicon.png')}}"> <!-- For the less-enabled mobile browsers like Opera Mini --> <link rel="stylesheet" media="handheld" href="{{=URL('static','css/handheld.css')}}"> |
︙ | ︙ | |||
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | else: width_content='100%' if left_sidebar_enabled: left_sidebar_style = 'style="display: block;"' else: left_sidebar_style = 'style="display: none;"' if right_sidebar_enabled: right_sidebar_style = 'style="display: block;"' else: right_sidebar_style = 'style="display: none;"' style_content = 'style="width: %s"' % width_content }} </head> <!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ --> <!--[if lt IE 7 ]> <body class="ie6"> <![endif]--> <!--[if IE 7 ]> <body class="ie7"> <![endif]--> <!--[if IE 8 ]> <body class="ie8"> <![endif]--> <!--[if IE 9 ]> <body class="ie9"> <![endif]--> <!--[if (gt IE 9)|!(IE)]><!--> <body> <!--<![endif]--> <div class="flash">{{=response.flash or ''}}</div> <!-- notification div --> | > > < | < < < < < < < < | < < < < < < < < < | < | < | < < < < < < < | < | | < < | < < < < < < < < < < < < | < < < < < < < | | < < < | < | 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 | else: width_content='100%' if left_sidebar_enabled: left_sidebar_style = 'style="display: block;"' else: left_sidebar_style = 'style="display: none;"' if right_sidebar_enabled: right_sidebar_style = 'style="display: block;"' else: right_sidebar_style = 'style="display: none;"' style_content = 'style="width: %s"' % width_content }} <!-- <link rel="stylesheet" href="http://twitter.github.com/bootstrap/1.4.0/bootstrap.min.css">--> <link rel="stylesheet" href="{{= URL("static", "css/1140.css") }}"> </head> <!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ --> <!--[if lt IE 7 ]> <body class="ie6"> <![endif]--> <!--[if IE 7 ]> <body class="ie7"> <![endif]--> <!--[if IE 8 ]> <body class="ie8"> <![endif]--> <!--[if IE 9 ]> <body class="ie9"> <![endif]--> <!--[if (gt IE 9)|!(IE)]><!--> <body> <!--<![endif]--> <div class="flash">{{=response.flash or ''}}</div> <!-- notification div --> <header> {{block header}} <!-- this is default header --> <h1><a href="{{= URL("mobileblur", "default", "index") }}">MobileBlur</a></h1> {{end}} {{ block header_bonus }}{{end}} </header> <section id="content" class-"container" {{=XML(style_content)}} > {{include}} </section> <footer> <a href="{{= URL("default", "logout") }}">Log out</a> </footer> <!--[if lt IE 7 ]> <script src="{{=URL('static','js/dd_belatedpng.js')}}"></script> <script> DD_belatedPNG.fix('img, .png_bg'); //fix any <img> or .png_bg background-images </script> <![endif]--> <!-- asynchronous google analytics: mathiasbynens.be/notes/async-analytics-snippet change the UA-XXXXX-X to be your site's ID --> <script> var _gaq = [['_setAccount', 'UA-27222314-1'], ['_trackPageview']]; (function(d, t) { var g = d.createElement(t), s = d.getElementsByTagName(t)[0]; g.async = true; g.src = '//www.google-analytics.com/ga.js'; s.parentNode.insertBefore(g, s); })(document, 'script'); </script> </body> </html> |
Modified applications/mobileblur/views/stories/view.html from [859afcf521] to [bcfec0acca].
|
| < > | | > > > > > > | | < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 | {{extend 'layout.html'}} {{ block header_bonus }} <a href="{{= story["story_permalink"] }}"> <h2>{{= story["story_title"] }}</h2> </a> <a href="{{= URL("mark_read", vars=dict(story_id=story["id"], feed_id=feed_id)) }}" class="button"> Mark story as read </a> {{ end }} <section id="story"> {{= XML(story["story_content"]) }} </section> |
Added routes.py version [b42c3be42e].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 155 156 157 158 159 160 161 162 163 164 165 166 | #!/usr/bin/python # -*- coding: utf-8 -*- # default_application, default_controller, default_function # are used when the respective element is missing from the # (possibly rewritten) incoming URL # default_application = 'mobileblur' # ordinarily set in base routes.py default_controller = 'default' # ordinarily set in app-specific routes.py default_function = 'index' # ordinarily set in app-specific routes.py # routes_app is a tuple of tuples. The first item in each is a regexp that will # be used to match the incoming request URL. The second item in the tuple is # an applicationname. This mechanism allows you to specify the use of an # app-specific routes.py. This entry is meaningful only in the base routes.py. # # Example: support welcome, admin, app and myapp, with myapp the default: routes_app = ((r'/(?P<app>welcome|admin|app)\b.*', r'\g<app>'), (r'(.*)', r'myapp'), (r'/?(.*)', r'myapp')) # routes_in is a tuple of tuples. The first item in each is a regexp that will # be used to match the incoming request URL. The second item in the tuple is # what it will be replaced with. This mechanism allows you to redirect incoming # routes to different web2py locations # # Example: If you wish for your entire website to use init's static directory: # # routes_in=( (r'/static/(?P<file>[\w./-]+)', r'/init/static/\g<file>') ) # routes_in = ((r'.*:/favicon.ico', r'/examples/static/favicon.ico'), (r'.*:/robots.txt', r'/examples/static/robots.txt'), ((r'.*http://otherdomain.com.* (?P<any>.*)', r'/app/ctr\g<any>'))) # routes_out, like routes_in translates URL paths created with the web2py URL() # function in the same manner that route_in translates inbound URL paths. # routes_out = ((r'.*http://otherdomain.com.* /app/ctr(?P<any>.*)', r'\g<any>'), (r'/app(?P<any>.*)', r'\g<any>')) # Error-handling redirects all HTTP errors (status codes >= 400) to a specified # path. If you wish to use error-handling redirects, uncomment the tuple # below. You can customize responses by adding a tuple entry with the first # value in 'appName/HTTPstatusCode' format. ( Only HTTP codes >= 400 are # routed. ) and the value as a path to redirect the user to. You may also use # '*' as a wildcard. # # The error handling page is also passed the error code and ticket as # variables. Traceback information will be stored in the ticket. # # routes_onerror = [ # (r'init/400', r'/init/default/login') # ,(r'init/*', r'/init/static/fail.html') # ,(r'*/404', r'/init/static/cantfind.html') # ,(r'*/*', r'/init/error/index') # ] # specify action in charge of error handling # # error_handler = dict(application='error', # controller='default', # function='index') # In the event that the error-handling page itself returns an error, web2py will # fall back to its old static responses. You can customize them here. # ErrorMessageTicket takes a string format dictionary containing (only) the # "ticket" key. # error_message = '<html><body><h1>%s</h1></body></html>' # error_message_ticket = '<html><body><h1>Internal error</h1>Ticket issued: <a href="/admin/default/ticket/%(ticket)s" target="_blank">%(ticket)s</a></body></html>' # specify a list of apps that bypass args-checking and use request.raw_args # #routes_apps_raw=['myapp'] #routes_apps_raw=['myapp', 'myotherapp'] def __routes_doctest(): ''' Dummy function for doctesting routes.py. Use filter_url() to test incoming or outgoing routes; filter_err() for error redirection. filter_url() accepts overrides for method and remote host: filter_url(url, method='get', remote='0.0.0.0', out=False) filter_err() accepts overrides for application and ticket: filter_err(status, application='app', ticket='tkt') >>> import os >>> import gluon.main >>> from gluon.rewrite import regex_select, load, filter_url, regex_filter_out, filter_err, compile_regex >>> regex_select() >>> load(routes=os.path.basename(__file__)) >>> os.path.relpath(filter_url('http://domain.com/favicon.ico')) 'applications/examples/static/favicon.ico' >>> os.path.relpath(filter_url('http://domain.com/robots.txt')) 'applications/examples/static/robots.txt' >>> filter_url('http://domain.com') '/init/default/index' >>> filter_url('http://domain.com/') '/init/default/index' >>> filter_url('http://domain.com/init/default/fcn') '/init/default/fcn' >>> filter_url('http://domain.com/init/default/fcn/') '/init/default/fcn' >>> filter_url('http://domain.com/app/ctr/fcn') '/app/ctr/fcn' >>> filter_url('http://domain.com/app/ctr/fcn/arg1') "/app/ctr/fcn ['arg1']" >>> filter_url('http://domain.com/app/ctr/fcn/arg1/') "/app/ctr/fcn ['arg1']" >>> filter_url('http://domain.com/app/ctr/fcn/arg1//') "/app/ctr/fcn ['arg1', '']" >>> filter_url('http://domain.com/app/ctr/fcn//arg1') "/app/ctr/fcn ['', 'arg1']" >>> filter_url('HTTP://DOMAIN.COM/app/ctr/fcn') '/app/ctr/fcn' >>> filter_url('http://domain.com/app/ctr/fcn?query') '/app/ctr/fcn ?query' >>> filter_url('http://otherdomain.com/fcn') '/app/ctr/fcn' >>> regex_filter_out('/app/ctr/fcn') '/ctr/fcn' >>> filter_url('https://otherdomain.com/app/ctr/fcn', out=True) '/ctr/fcn' >>> filter_url('https://otherdomain.com/app/ctr/fcn/arg1//', out=True) '/ctr/fcn/arg1//' >>> filter_url('http://otherdomain.com/app/ctr/fcn', out=True) '/fcn' >>> filter_url('http://otherdomain.com/app/ctr/fcn?query', out=True) '/fcn?query' >>> filter_url('http://otherdomain.com/app/ctr/fcn#anchor', out=True) '/fcn#anchor' >>> filter_err(200) 200 >>> filter_err(399) 399 >>> filter_err(400) 400 >>> filter_url('http://domain.com/welcome', app=True) 'welcome' >>> filter_url('http://domain.com/', app=True) 'myapp' >>> filter_url('http://domain.com', app=True) 'myapp' >>> compile_regex('.*http://otherdomain.com.* (?P<any>.*)', '/app/ctr\g<any>')[0].pattern '^.*http://otherdomain.com.* (?P<any>.*)$' >>> compile_regex('.*http://otherdomain.com.* (?P<any>.*)', '/app/ctr\g<any>')[1] '/app/ctr\\\\g<any>' >>> compile_regex('/$c/$f', '/init/$c/$f')[0].pattern '^.*?:https?://[^:/]+:[a-z]+ /(?P<c>\\\\w+)/(?P<f>\\\\w+)$' >>> compile_regex('/$c/$f', '/init/$c/$f')[1] '/init/\\\\g<c>/\\\\g<f>' ''' pass if __name__ == '__main__': import doctest doctest.testmod() |