Commits

Anonymous committed 99a1f73

Got the twitter page to work + openid input box.

  • Participants
  • Parent commits 5a3a671

Comments (0)

Files changed (10)

          ,{port, 8283}
 	 ,{log_dir, "/tmp"}
 	 ,{doc_root, "./www"}
+	 ,{twitter_user, "kruskakli"}
+	 ,{twitter_passwd, "mortuta42"}
 	 ,{authors, [{"http://etnt.myopenid.com/" % Claimed OpenID
                      ,"tobbe"                    % Nickname
                      ,"tobbe@tornkvist.org"},    % Email,

ebin/redhot2_common.beam

Binary file modified.

src/redhot2_common.erl

 -include_lib ("nitrogen/include/wf.hrl").
 
 -export([title/0
+         , header/0
          , header/1
          , footer/0
          , right/0
          , left/0
          , gravatar/1
          , raw_path/0
+         , logo_text/0
         ]).
 
 title() ->
 		default="identicon" }.
 
 
+header() ->
+    header(none).
+
 header(Selected) ->
-    wf:wire(Selected, #add_class { class=selected }),
-    #panel { body = [#h1 { class=header,
-                           text = "<span class='big'>R</span>ed<span class='big'>H</span>ot<span class='big'>E</span>rlang", html_encode=false},
-                     #panel { class=menu, 
-                              body=[#link { id=home,   url='/',            text="Home"  },
-                                    #link { id=logout, url='/logout',      text="Logout"  },
-                                    #link { id=about,  url='/about',       text="About"  }
-                                   ]}
+    lists:member(Selected,[home,twitter,logout,about]) andalso
+        wf:wire(Selected, #add_class { class=selected }),
+    #panel { body = [#h1 { class = "header",
+                           text  = logo_text(), html_encode=false},
+                     #panel { class = "menu_box",
+                              body  = [menu_box(),
+                                       openid_box()]}
                     ]}.
 
+menu_box() ->
+    #panel { class=menu, 
+             body=[#link { id=home,    url='/',          text="Home" },
+                   #link { id=twitter, url='/twitter',   text="Twitter" },
+                   #link { id=logout,  url='/logout',    text="Logout" },
+                   #link { id=about,   url='/about',     text="About" }
+                  ]}.
+
+openid_box() ->
+    case wf:session(authenticated) of
+        true ->
+            #panel { class = "openid_box",
+                     body = [wf:user()]};
+        _ ->
+            #panel { class = "openid_box",
+                     body = [#textbox{ class = "openid_login", 
+                                       id    = "claimed_id"}]}
+    end.
+
+logo_text() ->
+    "<span class='big'>R</span>ed<span class='big'>H</span>ot<span class='big'>E</span>rlang".
+
 footer() ->
     [#br{},
-     #panel { class=credits, body=[
+     #panel { class="footer", body=[
         "
         Copyright &copy; 2010 <a href='http://www.redhoterlang.com'>Torbjorn Tornkvist</a>. 
         Released under the MIT License.

src/redhot2_inets.erl

     [{"/",            redhot2_web_index}
      , {"/entry",     redhot2_web_entry}
      , {"/about",     redhot2_web_about}
+     , {"/twitter",   redhot2_web_twitter}
      , {"/login",     redhot2_web_login}
      , {"/logout",    redhot2_web_logout}
      , {"/auth",      redhot2_web_auth}

src/redhot2_twitter.erl

+%%% @author Torbjorn Tornkvist <tobbe@tornkvist.org>
+%%% @copyright (C) 2009-2010, Torbjorn Tornkvist
+
+-module(redhot2_twitter).
+
+-export([run/0, run/1]).
+
+-import(redhot2, [twitter_user/0, twitter_passwd/0]).
+
+-include_lib("nitrogen/include/wf.hrl").
+-include_lib("xmerl/include/xmerl.hrl").
+
+-define(txt(X),
+    (fun() ->
+       #xmlElement{name = _, 
+                   content = [#xmlText{value = V}|_]} = X,
+             V end)()).
+
+-define(href(X),
+    (fun() ->
+       #xmlElement{name = _, 
+                   attributes = As} = X,
+             [#xmlAttribute{value = V}|_] = 
+                 [W || W <- As,W#xmlAttribute.name == href],
+             V end)()).
+
+
+
+run() ->
+    run("erlang").
+
+run(KeyWord) ->
+    Url = twitter_atom_search_url(KeyWord),
+    Digest = base64:encode_to_string(twitter_user()++":"++twitter_passwd()),
+    Request = {Url, [{"authorization","Basic "++Digest}]},
+    case http:request(get, Request, [], []) of
+        {ok,{{_,200,_}, _Headers, Content}} ->
+            parse(Content);
+        Else ->
+            throw(Else)
+    end.
+
+parse(String) ->
+    {Xml, _} = xmerl_scan:string(String),
+    Z1 = [?txt(X) || X <- xmerl_xpath:string("//entry/author/name", Xml)],
+    Z2 = [?txt(X) || X <- xmerl_xpath:string("//entry/author/uri", Xml)],
+    Z3 = [fix_unicode(?txt(X)) || X <- xmerl_xpath:string("//entry/title", Xml)],
+    lists:zip3(Z1,Z2,Z3).
+
+
+
+twitter_atom_search_url(Q) ->
+    twitter_search_url("atom")++"?q="++Q.
+
+twitter_search_url(Type) ->
+    "http://search.twitter.com/search."++Type.
+
+%% Workaround for xmerl bug ?
+fix_unicode(XmlString) ->
+    Binary = unicode:characters_to_binary(XmlString, unicode),
+    binary_to_list(Binary). 

src/redhot2_web_about.erl

 
 layout() ->
     #container_12 {
-        body=[#grid_12 { class=header, body=redhot2_common:header(home) },
+        body=[#grid_12 { class=header, body=redhot2_common:header(about) },
               #grid_clear {},
 
               #grid_10 { alpha=true, body=about() },
 <p>
 Now it is making use of <a href='http://nitrogenproject.com/'>Nitrogen 2.0</a>
 and <a href='http://couchdb.apache.org/'>CouchDB</a>. Version 3 implemented a
-desktop like interface, with no visible pages but the top one. I have now
-returned to a more REST like structure.
+desktop like interface, with no visible pages but the top one. In version 4 it
+has returned to a more REST like structure. It has also got a new layout.
 </p>
-
-
 <p>If you would like to try it out or just look at the code, 
 you will find the git repository 
 <a href='http://dev.tornkvist.org/'>here</a>.

src/redhot2_web_entry.erl

 
 layout() ->
     #container_12 {
-        body=[#grid_12 { class=header, body=redhot2_common:header(home) },
+        body=[#grid_12 { class=header, body=redhot2_common:header() },
               #grid_clear {},
 
               #grid_10 { alpha=true, body=article() },
     A = proplists:get_value("author",L),
     H = proplists:get_value("html",L),
     Comform = "e_comform",
-    #panel{body=[#span{class="e_date" , text=gtostr(C)},
+    #panel{body=[#panel{class="e_author", body=[#panel{body=[gravatar(author2email(A))]},
+						#panel{body=["by: ",#span{class="blue",text=A}]}]},
+                 #span{class="e_date" , text=gtostr(C)},
                  #span{class="e_title", text=to_latin1(T)},
                  %#panel{class="e_author", body=["by: ",#span{class="blue",text=A}]},
-                 #panel{class="e_author", body=[#panel{body=[gravatar(author2email(A))]},
-						#panel{body=["by: ",#span{class="blue",text=A}]}]},
                  #panel{class="l_body" , body=to_latin1(H)}
 %                 #panel{class="e_comhdr", body=comhdr(Comform,Id)},
 %                 #panel{class=Comform, body=comform(Comform,Id)},

src/redhot2_web_index.erl

         body=[#grid_12 { class=header, body=redhot2_common:header(home) },
               #grid_clear {},
 
+              #grid_8 { alpha=true, body=intro() },
+              #grid_4 { omega=true, body=[] },
+              #grid_clear {},
+
               #grid_12 { alpha=true, body=redhot2_common:left() },
 %              #grid_8 { alpha=true, body=redhot2_common:left() },
 %              #grid_4 { omega=true, body=redhot2_common:right() },
               #grid_12 { body=redhot2_common:footer() }
              ]}.
 
+intro() ->
+    #panel { class = "intro",
+             body = intro_text()}.
+
+intro_text() ->
+    "Welcome to "++redhot2_common:logo_text()++". "
+        "Everything on this site revolves around <a href='http://www.erlang.org'>Erlang</a>; "
+        "either in form of tips and tricks from a couple of passionate Erlang "
+        "hackers, or in form of some experimental code being run.".
+
 event(Event) ->
     io:format("Event=~p~n",[Event]),
     ok.
+
+
+
+
+
+
+
+
+

src/redhot2_web_twitter.erl

+%% @author Torbjorn Tornkvist etnt@redhoterlang.com
+%% @copyright YYYY Torbjorn Tornkvist.
+
+-module(redhot2_web_twitter).
+
+-include_lib("nitrogen/include/wf.hrl").
+
+-export([main/0
+         , title/0
+         , layout/0
+	 , event/1
+	]).
+
+
+main() ->
+    #template { file="./templates/grid.html" }.
+
+title() ->
+    redhot2_common:title().
+
+layout() ->
+    #container_12 {
+        body=[#grid_12 { class=header, body=redhot2_common:header(twitter) },
+              #grid_clear {},
+
+              #grid_8 { alpha=true, body=intro() },
+              #grid_4 { omega=true, body=[] },
+              #grid_clear {},
+
+              #grid_12 { alpha=true, body=twitter(keyword()) },
+              #grid_clear {},
+              
+              #grid_12 { body=redhot2_common:footer() }
+             ]}.
+
+intro() ->
+    #panel { class = "intro",
+             body = intro_text()}.
+
+intro_text() ->
+    "Type in a Twitter keyword and press the button.".
+
+
+keyword() ->
+    case string:tokens(redhot2_common:raw_path(), "/") of
+        [_,KeyWord] -> wf:url_decode(KeyWord);
+        _           -> "erlang"  % default keyword
+    end.
+
+twitter(DefKw) ->
+    L=redhot2_twitter:run(DefKw),
+    K=#panel{
+      body = [#panel{class="tw_search", 
+                     body = [#button{id="tw_search",   text="Keyword:"},
+                             #textbox{id="tw_keyword", class="tw_keyword", text=DefKw}
+                            ]}]},
+    wf:wire("tw_search", #event {type=click, postback=twitter_search, delegate=?MODULE}),
+    R=#panel{body=[#panel{body=[#panel{class="tw_user", body=[#link{url=Url,text=User}]},
+                                #panel{class="tw_title",
+                                       body=[#span{text=urlify(Text),html_encode=false}]}]}
+                   || {User,Url,Text} <- L,length(Text)>20]}, % else, it is not interesting enough
+    #panel{body=[K,R]}.
+
+urlify(Text) ->
+    re:replace(Text,
+               "(http://[^ ]+)","<a href='\\1'>\\1</a>",
+               [{return,list},global]).
+
+
+event(twitter_search) ->
+    [KeyWord0] = wf:qs("tw_keyword"),
+    [KeyWord|_] = string:tokens(KeyWord0, " "),
+    wf:redirect("/twitter/"++wf:url_encode(KeyWord)).
+

www/css/digitalchili.css

 	background-color:#eff0e7;
 	margin:0;
 	padding:0;
-//	font-family:"Times New Roman", Times, serif;
 	font-family: Verdana,Arial,Helvetica,sans-serif;
 	font-size:1em;
 	line-height:1.6em;
 	color:#595959;
 }
 
+h1.header {
+    font-family:"Lucida Grande","Trebuchet MS",Verdana,sans-serif;
+//      font-family:"Book Antiqua","Warnock Pro","Goudy Old Style","Palatino","Georgia","serif"; 
+//	font-family:Geneva, "Times New Roman", Times, serif;
+//	font-family: Verdana,Arial,Helvetica,sans-serif;
+//	font-family: Arial,Helvetica,sans-serif;
+//	font-weight:bold; 
+    letter-spacing:1px;
+}
 
 
 form {
 
 // .header {margin:0 10px 0 -10px;}
 
+.openid_box {margin:25px 0px -25px 0px; padding-left:5px;}
 
-.menu {
+input.openid_login {
+   background: url(http://openid.net/login-bg.gif) no-repeat;
+   background-color: #fff;
+   background-position: 0 50%;
+   color: #000;
+   width:95%;
+}
+
+
+
+.menu_box {
 	margin:-40px 0 40px 0;
 	padding:0;
 	list-style-type:none;
 }
 
 .menu a  {
-	margin:0 0 0 2px;
-	padding:3px 6px;
+	margin:0 0 0 0px;
+	padding:0px 4px;
 	float:left;
 	color:#7d9093;
 	text-transform:uppercase;
+	letter-spacing:1px;
 	font-family:Geneva, Arial, Helvetica, sans-serif;
 	font-size:9px;
 	text-decoration:none;
-	background-color:#d7d8cf;
 	display:block;
-	padding-left:6px;
-	padding-right:6px;
 }
 
 .big {font-size:120%;color:#d13400;}
  */
 .e_date {font-size:1em; color:#d13400; font-weight:bold;}
 .e_title {font-size:1em; margin-left:2em; font-weight:bold; letter-spacing:1px; color:black;}
-.e_author {float:right; font-size:0.9em; margin:-3em 3em 3em -3em; font-weight:normal;}
+.e_author {float:left; font-size:0.9em; margin:4em 0 -4em -7em; padding-left:0; font-weight:normal;}
 
 code {font-size: 110%;line-height:90%;}
 
+a.selected {color:black; background-color:#d7d8cf;}
+
+
+.footer {
+	clear:both;
+	float:left;
+	width:980px;
+	margin:4em 0 0 0;
+	padding:1em 0 4em 0;
+	border-top:2px solid #cbd0c2;
+	color:#91918d;
+	font-weight:normal;
+	font-size:1.1em;
+}
+
+.intro {
+    margin:0 1.5em 1em -1.5em;
+    padding: 2px 0;
+    border-top:2px solid #cbd0c2;
+    border-bottom:2px solid #cbd0c2;
+    letter-spacing:1px;
+    font-family:Geneva, Arial, Helvetica, sans-serif;
+    font-size:9px;
+    text-decoration:none;
+    color:#91918d;
+    font-weight:normal;
+    font-size:120%;
+}
+
+.chilired {color:#d13430;}
+
+.tw_search {padding:0.5em;}
+
+
+
+
+
 
 
 #header h1 {
 
 
 /* **************** */
-
-#footer {
-	clear:both;
-	float:left;
-	width:980px;
-	margin:4em 0 0 0;
-	padding:1em 0 4em 0;
-	border-top:2px solid #cbd0c2;
-}
-
-
-#footer h3 {
-	color:#91918d;
-	font-weight:normal;
-	font-size:1.1em;
-}
-