roller-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From she...@apache.org
Subject svn commit: r1158918 - in /roller/branches/roller_mobile: weblogger-business/src/main/java/org/apache/roller/weblogger/pojos/wrapper/ weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/model/ weblogger-web/src/main/java/org/apache/rol...
Date Wed, 17 Aug 2011 21:27:00 GMT
Author: shelan
Date: Wed Aug 17 21:27:00 2011
New Revision: 1158918

URL: http://svn.apache.org/viewvc?rev=1158918&view=rev
Log:
Bug fixes and adding a simple basic mobile theme

Added:
    roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/_day-mobile.vm
    roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/permalink-mobile.vm
    roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/searcresults-mobile.vm
Modified:
    roller/branches/roller_mobile/weblogger-business/src/main/java/org/apache/roller/weblogger/pojos/wrapper/WeblogWrapper.java
    roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/model/PageModel.java
    roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/SearchServlet.java
    roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/util/ParsedRequest.java
    roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEdit.java
    roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEditBean.java
    roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/theme.xml
    roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/weblog-mobile.vm

Modified: roller/branches/roller_mobile/weblogger-business/src/main/java/org/apache/roller/weblogger/pojos/wrapper/WeblogWrapper.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mobile/weblogger-business/src/main/java/org/apache/roller/weblogger/pojos/wrapper/WeblogWrapper.java?rev=1158918&r1=1158917&r2=1158918&view=diff
==============================================================================
--- roller/branches/roller_mobile/weblogger-business/src/main/java/org/apache/roller/weblogger/pojos/wrapper/WeblogWrapper.java
(original)
+++ roller/branches/roller_mobile/weblogger-business/src/main/java/org/apache/roller/weblogger/pojos/wrapper/WeblogWrapper.java
Wed Aug 17 21:27:00 2011
@@ -18,6 +18,7 @@
 
 package org.apache.roller.weblogger.pojos.wrapper;
 
+import com.sun.org.apache.bcel.internal.generic.RETURN;
 import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.roller.weblogger.WebloggerException;
 import org.apache.roller.weblogger.business.URLStrategy;
@@ -36,39 +37,56 @@ public class WeblogWrapper {
     
     // url strategy to use for any url building
     private final URLStrategy urlStrategy;
+
+    // type of the request detected at  Page model
+    private String type = "standard";
     
     
     // this is private so that we can force the use of the .wrap(pojo) method
-    private WeblogWrapper(Weblog toWrap, URLStrategy strat) {
+    private WeblogWrapper(Weblog toWrap, URLStrategy strat, String type) {
         this.pojo = toWrap;
         this.urlStrategy = strat;
+        this.type = type;
     }
     
     
-    // wrap the given pojo if it is not null
-    public static WeblogWrapper wrap(Weblog toWrap, URLStrategy strat) {
+    // wrap the given pojo if it is not null with detected type
+    public static WeblogWrapper wrap(Weblog toWrap, URLStrategy strat, String type) {
         if(toWrap != null)
-            return new WeblogWrapper(toWrap, strat);
+            return new WeblogWrapper(toWrap, strat , type);
         
         return null;
     }
+      //wrap the given pojo if it is not null without changing type. (i.e using default)
+     public static WeblogWrapper wrap(Weblog toWrap, URLStrategy strat) {
+        if(toWrap != null)
+            return new WeblogWrapper(toWrap, strat , "standard");
+
+        return null;
+    }
     
     
     public ThemeTemplateWrapper getPageByAction(String action)
             throws WebloggerException {
-        return ThemeTemplateWrapper.wrap(this.pojo.getTheme().getTemplateByAction(action));
+        ThemeTemplate templateToWrap = this.pojo.getTheme().getTemplateByAction(action);
+        prepareTemplate(templateToWrap, type);
+        return ThemeTemplateWrapper.wrap(templateToWrap);
     }
     
     
     public ThemeTemplateWrapper getPageByName(String name)
             throws WebloggerException {
-        return ThemeTemplateWrapper.wrap(this.pojo.getTheme().getTemplateByName(name));
+       ThemeTemplate templateToWrap = this.pojo.getTheme().getTemplateByName(name);
+        prepareTemplate(templateToWrap, type);
+        return ThemeTemplateWrapper.wrap(templateToWrap);
     }
     
     
     public ThemeTemplateWrapper getPageByLink(String link)
             throws WebloggerException {
-        return ThemeTemplateWrapper.wrap(this.pojo.getTheme().getTemplateByLink(link));
+        ThemeTemplate templateToWrap = this.pojo.getTheme().getTemplateByLink(link);
+        prepareTemplate(templateToWrap, type);
+        return ThemeTemplateWrapper.wrap(templateToWrap);
     }
     
     
@@ -454,5 +472,35 @@ public class WeblogWrapper {
     public Weblog getPojo() {
         return this.pojo;
     }
-    
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * @param page
+     * @param type
+     * @return
+     *
+     * Prepare template to add the correct template content
+     */
+    private ThemeTemplate prepareTemplate(ThemeTemplate page, String type) throws WebloggerException
{
+
+        WeblogTemplateCode templateCode = page.getTemplateCode(type);
+
+        if (templateCode != null) {
+            page.setContents(templateCode.getTemplate());
+            page.setTemplateLanguage(templateCode.getTemplateLanguage());
+            return page;
+        } else {
+            // if there is no template code present we fall back to default template
+            return page;
+        }
+
+    }
+
 }

Modified: roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/model/PageModel.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/model/PageModel.java?rev=1158918&r1=1158917&r2=1158918&view=diff
==============================================================================
--- roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/model/PageModel.java
(original)
+++ roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/model/PageModel.java
Wed Aug 17 21:27:00 2011
@@ -32,6 +32,7 @@ import org.apache.roller.weblogger.pojos
 import org.apache.roller.weblogger.pojos.wrapper.WeblogCategoryWrapper;
 import org.apache.roller.weblogger.pojos.wrapper.WeblogEntryWrapper;
 import org.apache.roller.weblogger.pojos.wrapper.WeblogWrapper;
+import org.apache.roller.weblogger.ui.rendering.mobile.MobileDeviceRepository;
 import org.apache.roller.weblogger.ui.rendering.pagers.WeblogEntriesDayPager;
 import org.apache.roller.weblogger.ui.rendering.pagers.WeblogEntriesLatestPager;
 import org.apache.roller.weblogger.ui.rendering.pagers.WeblogEntriesMonthPager;
@@ -54,6 +55,7 @@ public class PageModel implements Model 
     private WeblogEntryCommentForm commentForm = null;
     private Map requestParameters = null;
     private Weblog weblog = null;
+    private String type = null;
     
     
     /**
@@ -106,6 +108,8 @@ public class PageModel implements Model 
         
         // extract weblog object
         weblog = pageRequest.getWeblog();
+
+        this.type = weblogRequest.getType();
     }    
     
     
@@ -121,7 +125,7 @@ public class PageModel implements Model 
      * Get weblog being displayed.
      */
     public WeblogWrapper getWeblog() {
-        return WeblogWrapper.wrap(weblog, urlStrategy);
+        return WeblogWrapper.wrap(weblog, urlStrategy, getType());
     }
     
     
@@ -313,5 +317,12 @@ public class PageModel implements Model 
         }
         return null;
     }
-    
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
 }

Modified: roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/SearchServlet.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/SearchServlet.java?rev=1158918&r1=1158917&r2=1158918&view=diff
==============================================================================
--- roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/SearchServlet.java
(original)
+++ roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/SearchServlet.java
Wed Aug 17 21:27:00 2011
@@ -29,6 +29,7 @@ import org.apache.roller.weblogger.pojos
 import org.apache.roller.weblogger.pojos.Weblog;
 import org.apache.roller.weblogger.ui.rendering.Renderer;
 import org.apache.roller.weblogger.ui.rendering.RendererManager;
+import org.apache.roller.weblogger.ui.rendering.RenderingException;
 import org.apache.roller.weblogger.ui.rendering.mobile.MobileDeviceRepository;
 import org.apache.roller.weblogger.ui.rendering.model.Model;
 import org.apache.roller.weblogger.ui.rendering.model.ModelLoader;
@@ -100,7 +101,7 @@ public class SearchServlet extends HttpS
 
         //is a mobile request
 
-        boolean isMobileRequest = MobileDeviceRepository.isMobileDevice(request);
+       String  type = MobileDeviceRepository.getRequestType(request);
         
         // do we need to force a specific locale for the request?
         if(searchRequest.getLocale() == null && !weblog.isShowAllLangs()) {
@@ -204,7 +205,14 @@ public class SearchServlet extends HttpS
 				log.error("ERROR - reloading theme " + ex);
 			}
 		}
-		
+
+        //prepare template for detected type
+        try {
+            page = RendererManager.prepareTemplate(page ,type);
+        } catch (RenderingException e) {
+            log.debug("Error while preparing page template");
+        }
+
         // lookup Renderer we are going to use
         Renderer renderer = null;
         try {

Modified: roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/util/ParsedRequest.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/util/ParsedRequest.java?rev=1158918&r1=1158917&r2=1158918&view=diff
==============================================================================
--- roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/util/ParsedRequest.java
(original)
+++ roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/util/ParsedRequest.java
Wed Aug 17 21:27:00 2011
@@ -25,6 +25,7 @@ import org.apache.roller.weblogger.Weblo
 import org.apache.roller.weblogger.business.WebloggerFactory;
 import org.apache.roller.weblogger.business.UserManager;
 import org.apache.roller.weblogger.pojos.User;
+import org.apache.roller.weblogger.ui.rendering.mobile.MobileDeviceRepository;
 
 
 /**
@@ -46,6 +47,8 @@ public abstract class ParsedRequest {
     
     // lightweight attributes
     private String authenticUser = null;
+
+    private String type = "standard";
     
     // heavyweight attributes
     private User user = null;
@@ -70,6 +73,8 @@ public abstract class ParsedRequest {
         if(prince != null) {
             this.authenticUser = prince.getName();
         }
+        // set the detected type of the request
+        type = MobileDeviceRepository.getRequestType(request);
         
     }
     
@@ -107,5 +112,12 @@ public abstract class ParsedRequest {
     public boolean isLoggedIn() {
         return (this.authenticUser != null);
     }
-    
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
 }

Modified: roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEdit.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEdit.java?rev=1158918&r1=1158917&r2=1158918&view=diff
==============================================================================
--- roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEdit.java
(original)
+++ roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEdit.java
Wed Aug 17 21:27:00 2011
@@ -195,7 +195,7 @@ public class TemplateEdit extends UIActi
             //save template code
             WeblogTemplateCode templateCode = WebloggerFactory.getWeblogger().getWeblogManager().
                     getTemplateCodeByType(template.getId(),getBean().getType());
-            templateCode.setTemplate(template.getContents());
+            templateCode.setTemplate(getBean().getContents());
 
             WebloggerFactory.getWeblogger().getWeblogManager().saveTemplateCode(templateCode);
 

Modified: roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEditBean.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEditBean.java?rev=1158918&r1=1158917&r2=1158918&view=diff
==============================================================================
--- roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEditBean.java
(original)
+++ roller/branches/roller_mobile/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/TemplateEditBean.java
Wed Aug 17 21:27:00 2011
@@ -19,6 +19,7 @@
 package org.apache.roller.weblogger.ui.struts2.editor;
 
 import org.apache.roller.weblogger.pojos.WeblogTemplate;
+import org.apache.struts2.components.If;
 
 
 /**
@@ -136,7 +137,9 @@ public class TemplateEditBean {
     
     
     public void copyTo(WeblogTemplate dataHolder) {
-        
+
+        // change the default content of template if we are changing standard type code
+        if("standard".equals(getType()))
         dataHolder.setContents(getContents());
         
         // the rest of the template properties can only be modified when

Added: roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/_day-mobile.vm
URL: http://svn.apache.org/viewvc/roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/_day-mobile.vm?rev=1158918&view=auto
==============================================================================
--- roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/_day-mobile.vm
(added)
+++ roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/_day-mobile.vm
Wed Aug 17 21:27:00 2011
@@ -0,0 +1,4 @@
+#foreach( $entry in $entries )
+<ul data-role="listview" data-inset="true" data-dividertheme="b">
+    <li><a href=$entry.permalink>$entry.title</a></li>
+#end

Added: roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/permalink-mobile.vm
URL: http://svn.apache.org/viewvc/roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/permalink-mobile.vm?rev=1158918&view=auto
==============================================================================
--- roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/permalink-mobile.vm
(added)
+++ roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/permalink-mobile.vm
Wed Aug 17 21:27:00 2011
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Blog Post</title>
+
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+
+    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.css"/>
+    <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
+    <script type="text/javascript" src="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.js"></script>
+</head>
+<body>
+
+<div data-role="page" data-theme="b">
+
+    <div data-role="header" data-theme="b">
+        <h1>Weblog Post</h1>
+    </div>
+    <!-- /header -->
+
+## show next/previous paging controls
+    #set($pager = $model.getWeblogEntriesPager())
+    #set($prevLink = false)
+    #set($nextLink = false)
+    #if ($pager.prevLink)
+        #set($prevLink = $pager.prevLink)
+        #set($prevName = $pager.prevName)
+    #elseif ($pager.prevCollectionLink)
+        #set($prevLink = $pager.prevCollectionLink)
+        #set($prevName = $pager.prevCollectionName)
+    #end
+    #if ($pager.nextLink)
+        #set($nextLink = $pager.nextLink)
+        #set($nextName = $pager.nextName)
+    #elseif ($pager.nextCollectionLink)
+        #set($nextLink = $pager.nextCollectionLink)
+        #set($nextName = $pager.nextCollectionName)
+    #end
+    <div data-role="navbar">
+        <ul>
+        <li>#if ($prevLink)<a data-icon="arrow-l" data-theme="b" href="$prevLink">$prevName</a></li>#end
+
+            <li>#if ($prevLink || $nextLink)
+                <a data-icon="home" data-theme="b" href="$pager.getHomeLink()"
+                   class="ui-btn-active">$pager.getHomeName()</a>
+            #end </li>
+
+        <li>#if ($nextLink)<a data-icon="arrow-r" data-theme="b" href="$nextLink">$nextName</a></li>#end
+        </ul>
+    </div>
+
+    <div data-role="content" data-theme="c">
+        #set($map = $pager.getEntries())
+        #foreach($day in $map.keySet())
+            #set($entries = $map.get($day))
+        #end
+
+    ## show entry
+           #foreach( $entry in $entries )
+
+        <h3>$entry.title</h3>
+
+        <p>
+
+        <p> #if($model.permalink)
+                $entry.displayContent
+            #else
+            $entry.displayContent($url.entry($entry.anchor))
+        #end</p></p>
+
+    #end
+
+    ## show comments and comment form
+           #showWeblogEntryComments($model.weblogEntry)
+    ##showWeblogEntryCommentForm($model.weblogEntry)
+
+
+        </p>
+    </div>
+    <!-- /content -->
+
+    <div data-role="footer" data-theme="b">
+        <h4>Apache Roller @ 2011</h4>
+    </div>
+    <!-- /footer -->
+</div>
+<!-- /page -->
+
+</body>
+</html>
\ No newline at end of file

Added: roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/searcresults-mobile.vm
URL: http://svn.apache.org/viewvc/roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/searcresults-mobile.vm?rev=1158918&view=auto
==============================================================================
    (empty)

Modified: roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/theme.xml
URL: http://svn.apache.org/viewvc/roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/theme.xml?rev=1158918&r1=1158917&r2=1158918&view=diff
==============================================================================
--- roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/theme.xml
(original)
+++ roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/theme.xml
Wed Aug 17 21:27:00 2011
@@ -55,6 +55,12 @@
            <contentsFile>permalink.vm</contentsFile>
            <type>standard</type>
        </templateCode>
+        <templateCode>
+           <templateLanguage>velocity</templateLanguage>
+           <contentType>text/html</contentType>
+           <contentsFile>permalink-mobile.vm</contentsFile>
+           <type>mobile</type>
+       </templateCode>
     </template>
     
     <template action="search">
@@ -69,6 +75,12 @@
            <contentsFile>searchresults.vm</contentsFile>
            <type>standard</type>
        </templateCode>
+        <templateCode>
+           <templateLanguage>velocity</templateLanguage>
+           <contentType>text/html</contentType>
+           <contentsFile>searchresults-mobile.vm</contentsFile>
+           <type>mobile</type>
+       </templateCode>
     </template>
     
     <template action="custom">
@@ -83,6 +95,12 @@
            <contentsFile>_day.vm</contentsFile>
            <type>standard</type>
        </templateCode>
+        <templateCode>
+           <templateLanguage>velocity</templateLanguage>
+           <contentType>text/html</contentType>
+           <contentsFile>_day-mobile.vm</contentsFile>
+           <type>mobile</type>
+       </templateCode>
     </template>
     
     <template action="custom">

Modified: roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/weblog-mobile.vm
URL: http://svn.apache.org/viewvc/roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/weblog-mobile.vm?rev=1158918&r1=1158917&r2=1158918&view=diff
==============================================================================
--- roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/weblog-mobile.vm
(original)
+++ roller/branches/roller_mobile/weblogger-webapp/src/main/webapp/themes/basic/weblog-mobile.vm
Wed Aug 17 21:27:00 2011
@@ -1,10 +1,44 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!DOCTYPE html>
 <html>
 <head>
+    <title>$model.weblog.name</title>
 
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+
+    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.css"/>
+    <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
+    <script type="text/javascript" src="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.js"></script>
 </head>
 <body>
-This is the mobile template
+
+<div data-role="page">
+
+    <div data-role="header" data-theme="b">
+        <h1>$model.weblog.name </h1>
+        <a href=$url.home  data-icon="home" data-theme = "a">Home</a>
+        <a href=$url.home  data-icon="gear" data-theme = "a">Options</a>
+    </div>
+    <!-- /header -->
+
+    <form id="searchForm" method="get" action="$url.search">
+        <div data-role="fieldcontain">
+            <label for="search">Search :</label>
+            <input type="search" name="q" id="q" value=""/>
+        </div>
+    </form>
+    <div data-role="content" data-theme="d">
+        #set($rootCategory = $model.weblog.getWeblogCategory("nil"))
+  #set($pager = $model.getWeblogEntriesPager()) 
+  #showWeblogEntriesPager($pager)
+    </div>
+    <!-- /content -->
+
+    <div data-role="footer" data-theme="b">
+        <h4>Apache Roller Mobile @ 2011</h4>
+    </div>
+    <!-- /footer -->
+</div>
+<!-- /page -->
 
 </body>
-</html>
+</html>
\ No newline at end of file



Mime
View raw message