Changeset 132:add99b61e833

Show
Ignore:
Timestamp:
03/22/2010 01:15:25 AM (4 months ago)
Author:
dcaoyuan
Branch:
default
Message:

Finished Routes with PackratParser?

Location:
blogbird/src/main/scala/org/aiotrade/blog/frontend
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • blogbird/src/main/scala/org/aiotrade/blog/frontend/Routes.scala

    r131 r132  
    99import org.aiotrade.blog.frontend.{Actions => A} 
    1010import org.aiotrade.blog.frontend.{Feeds => F} 
    11  
    12  
    13 object Routes { 
     11import scala.util.parsing.combinator.PackratParsers 
     12import scala.util.parsing.combinator 
     13import scala.util.parsing.input.CharSequenceReader 
     14 
     15 
     16object Routes extends PackratParsers { 
    1417  trait Route 
    1518  case class XhtmlView(view: V.View) extends Route 
     
    2629  case class NoSuchUri(uri: String) extends Route 
    2730 
     31  val entrance = phrase(uriParser) 
     32 
     33  def parse(text: String): ParseResult[_] = { 
     34    val input = new PackratReader(new CharSequenceReader(text)) 
     35    entrance(input) 
     36  } 
     37 
     38  def extractResult(r : ParseResult[_]) = r match { 
     39    case Success(a, _) => a 
     40    case NoSuccess(a, _) => a 
     41  } 
     42 
     43  /** the type of input elements defined in the Parsers is <code>Char</code> */ 
     44  override type Elem = Char 
     45 
     46  implicit def toString(cs: List[Char]) = cs.mkString 
     47   
     48  //  def   accept[ES](es: ES)(implicit arg0: (ES) ? List[Elem]): Parser[List[Elem]] 
     49  implicit def toCharList(s: String) = s.toList // 
     50  implicit def stringToParser(s: String) = accept(s) 
     51 
     52  def uriParser = (pages           | 
     53                   commands        | 
     54                   submit_comment  | 
     55                   post_comment    | 
     56                   delete_comment  | 
     57                   delete_comments | 
     58                   edit_comment    | 
     59                   rep(any) ^^  {s => NoSuchUri(s)}) 
     60 
     61  def pages = get_method ~> (single_article          | 
     62                             articles_by_tags        | 
     63                             articles                | 
     64                             feeds                   | 
     65                             review_pending_comments | 
     66                             review_comment          | 
     67                             add_comment_form) 
     68 
     69 
     70  def get_method  = "GET "  ^^^ () 
     71  def post_method = "POST " ^^^ () 
     72 
     73  def commands = 
     74    post_method ~ ("/commands" | "/c") ~> ingest_draft 
     75 
     76  def submit_comment = 
     77    post_method ~ "/e/add-comment/" ~> p_plink_title <~ eof ^^ { 
     78      t => CommentSubmission(t) 
     79    } 
     80 
     81  def edit_comment = 
     82    post_method ~ "/x/edit-comment/" ~> p_int <~ eof ^^ { 
     83      n => AlterComment(n) 
     84    } 
     85 
     86  def post_comment = 
     87    post_method ~ "/x/post-comment" ~ eof ^^^ PostComment 
     88 
     89  def delete_comment = 
     90    post_method ~ "/x/delete-comment" ~ eof ^^^ DeleteComment 
     91 
     92  def delete_comments = 
     93    post_method ~ "/x/delete-comments" ~ eof ^^^ DeleteComments 
     94 
     95  def review_pending_comments = 
     96    "/z/review-comments" ~> page <~ eof ^^ { 
     97      p => ReviewComments(p) 
     98    } 
     99 
     100  def review_comment = 
     101    "/z/review-comment/" ~> p_int <~ eof ^^ { 
     102      n => ReviewComment(n) 
     103    } 
     104 
     105  def add_comment_form = 
     106    "/c/add-comment/" ~>  p_plink_title <~ eof ^^ { 
     107      t => CommentFormView(t) 
     108    } 
     109 
     110  def ingest_draft = 
     111    "/post-draft/" ~> rep(any) ^^ { 
     112      x => Command(A.Ingest(x)) 
     113    } 
     114 
     115  // ----- feeds 
     116 
     117  def feeds = 
     118    ("/feeds" | "/f") ~> (articles_feed  | 
     119                          comments_feeds | 
     120                          tag_feed       | 
     121                          tags_feed      | 
     122                          article_comments_feed) 
     123 
     124  def articles_feed = 
     125    ("/articles" | "/a") ~> atom_xml ^^^ AtomFeed(F.AllPosts) 
     126 
     127  def comments_feeds = 
     128    all_comments_feed | article_comments_feed 
     129 
     130  def all_comments_feed = 
     131    ("/comments" | "/c") ~> atom_xml ^^^ AtomFeed(F.AllComments) 
     132 
     133  def article_comments_feed = 
     134    ("/comments/p/" | "/c/p/") ~> p_plink_title <~ atom_xml ^^ { 
     135      t => AtomFeed(F.PostComments(t)) 
     136    } 
     137 
     138  def tag_feed = 
     139    "/tag/" ~> p_tag_name <~ atom_xml ^^ { 
     140      t => AtomFeed(F.ByTag(t)) 
     141    } 
     142 
     143  def tags_feed = 
     144    ("/tags/" | "/t/") ~> repsep(p_tag_name, ',') <~ atom_xml ^^ { 
     145      ts => AtomFeed(F.ByTags(ts sortWith (_ < _))) 
     146    } 
     147 
     148  def atom_xml = 
     149    "/atom.xml" ~> eof ^^^ () 
     150 
     151 
     152  // ----- articles 
     153   
     154  def articles = 
     155    ("/articles" | "/a") ~> (all_articles     | 
     156                             single_article   | 
     157                             articles_by_date | 
     158                             articles_by_tag  | 
     159                             articles_by_tags) 
     160 
     161  def all_articles = 
     162    page ^^ { 
     163      p => XhtmlView(V.All(p)) 
     164    } 
     165 
     166  def single_article = 
     167    "/p/" ~> p_plink_title <~ eof ^^ { 
     168      t => XhtmlView(V.ByPermatitle(t)) 
     169    } 
     170 
     171  def articles_by_tag = 
     172    "/tag/" ~> p_tag_name ~ page ^^ { 
     173      case t ~ p => XhtmlView(V.ByTag(t, p)) 
     174    } 
     175 
     176  def articles_by_tags = 
     177    ("/t/" | "/tags/") ~> repsep(p_tag_name, ',') ~ page ^^ { 
     178      case ts ~ p => XhtmlView(V.ByTags(ts sortWith (_ < _), p)) 
     179    } 
     180 
     181  def articles_by_date_forRef = 
     182    '/' ~> p_int ~ (page ^^ {case x => } | 
     183                    '/' ~> p_int ~ (page | 
     184                                    '/' ~> p_int ~ (page | 
     185                                                    '/' ~> p_plink_title 
     186        ) 
     187      ) 
     188    ) 
     189 
     190  def articles_by_date = articles_by_date_1 | articles_by_date_2 | articles_by_date_3 | articles_by_date_4 
     191  def articles_by_date_1 = memo('/' ~ p_int) ~ page ^^ { 
     192    case '/' ~ y ~ p => XhtmlView(V.ByYear(y, p)) 
     193  } 
     194  def articles_by_date_2 = memo('/' ~ p_int ~ '/' ~ p_int) ~ page ^^ { 
     195    case '/' ~ y ~ '/' ~ m ~ p => XhtmlView(V.ByMonth(y, m, p)) 
     196  } 
     197  def articles_by_date_3 = memo('/' ~ p_int ~ '/' ~ p_int ~ '/' ~ p_int) ~ page ^^ { 
     198    case '/' ~ y ~ '/' ~ m ~ '/' ~ d ~ p => XhtmlView(V.ByDay(y, m, d, p)) 
     199  } 
     200  def articles_by_date_4 = memo('/' ~ p_int ~ '/' ~ p_int ~ '/' ~ p_int) ~ '/' ~ p_plink_title ^^ { 
     201    case '/' ~ y ~ '/' ~ m ~ '/' ~ d ~ '/' ~ t => XhtmlView(V.ByYMDPermatitle(y, m, d, t)) 
     202  } 
     203 
     204 
     205  // ----- elements 
     206   
     207  def page = (eof ^^^ None | ("/page/" | "/p/") ~> p_int <~ eof ^^ (Some(_))) 
     208  def p_int = rep1(digit) ^^ (toString(_).toInt) 
     209  def p_plink_title = rep1(alphaNum | '-' | '_') ^^ toString 
     210  def p_tag_name    = rep1(alphaNum | '-' | '_' | '.' ) ^^ toString 
     211 
     212  // ----- basic 
     213   
     214  def alphaNum  = elem("digit",  Character.isLetterOrDigit) 
     215  def digit     = elem("digit",  Character.isDigit) 
     216  def upper     = elem("upper",  Character.isUpperCase) 
     217  def lower     = elem("lower",  Character.isLowerCase) 
     218  def letter    = elem("letter", Character.isLetter) 
     219  def eof       = elem("end of file", _ == '\032') ^^^ () 
     220  def any       = elem("any char",    _ != '\032') 
     221 
     222 
     223  // ----- simple test 
     224 
     225  def main(args: Array[String]) { 
     226    val text = "GET /a/p/a_blog_title" 
     227    //val text = "GETapaaa" 
     228    val r = parse(text) 
     229 
     230    r match { 
     231      case Success(x, _) => x 
     232      case NoSuccess(x, _) => x 
     233    } 
     234 
     235    println(r) 
     236  } 
    28237} 
  • blogbird/src/main/scala/org/aiotrade/blog/frontend/Views.scala

    r131 r132  
    5151      case ByTag(t, _) => B.tag_filter(t) (md.all_posts) 
    5252      case ByTags(t, _) => B.tags_filter(t) (md.all_posts) 
    53       case ByYMDPermatitle(_, _, _, t) => md.maybe_post_by_permatitle(t).toList 
    54       case ByPermatitle(t) => md.maybe_post_by_permatitle(t).toList 
     53      case ByYMDPermatitle(_, _, _, t) => md.maybe_post_by_permatitle(t) toList 
     54      case ByPermatitle(t) => md.maybe_post_by_permatitle(t) toList 
    5555    } 
    5656 
     
    104104      case _ => this 
    105105    } 
     106 
     107    def discoverable_feeds = this match { 
     108      case All(_) => List(F.articles_feed, F.all_comments_feed) 
     109      case ByYear(_, _) => List(F.articles_feed, F.all_comments_feed) 
     110      case ByMonth(_, _, _) => List(F.articles_feed, F.all_comments_feed) 
     111      case ByDay(_, _, _, _) => List(F.articles_feed, F.all_comments_feed) 
     112      case ByYMDPermatitle(_, _, _, t) => List(F.articles_feed, F.all_comments_feed, F.comments_feed(t)) 
     113      case ByPermatitle(t) => List(F.articles_feed, F.all_comments_feed, F.comments_feed(t)) 
     114      case ByTag(t, _) => List(F.articles_feed, F.all_comments_feed, F.tags_feed(List(t))) 
     115      case ByTags(ts, _) => List(F.articles_feed, F.all_comments_feed, F.tags_feed(ts)) 
     116    } 
    106117  } 
     118   
    107119  case class All(page_n: Option[Int]) extends View 
    108120  case class ByYear(year: Int, page_n: Option[Int]) extends View