죽녹원 입구이다.





블로그 이미지

와사비망고

,

광주 광산구에서 담양까지 자전거로 가기엔 정말 멀다. 

(오후 1시 30분에 출발해서 집에 도착하니 저녁 10시 10분)

편도로 가서 돌아올 땐 터미널의 광주로가는 직행 버스에 자전거를 실어와야 한다.

또 주의해야할것은 직행버스에 자전거가 겨우 들어가는데다 최대 2대를 넣을 수 있다.

자전거를 접이식을 가져가거나 두사람 초과해서 무리를 이뤄 같이 가면

버스로 돌아올때 귀찬다. ( 직행버스 여러대에 나눠 타야하는 ) 

가다가 농가의 똥냄새의 구간을 한번정도 지나야 한다. ( 마스크 필요 ) 

결론 : 나에겐 자전거 타고 갈만한곳은 아니었다. ( 차로 운전해서 한번쯤 떡갈비 먹으러 가보는건 괜찬은 ) 



전남 담양의 1박2일 촬영지 떡갈비본가




담양터미널의 광주 직행버스를 기다리고 있다.

집에 갈 수 있는건가 동동구르며 한 컷

다행히 자전거용 짐칸이 좁지만 광주로 가는 직행버스가 있다.





속이 부글거려 망고식스에서 비싼 블루베리스무디를 5800원에 먹었다.













광주 광천 터미널에서 광산구까지 또 자전거로 이동해서 집으로 돌아왔다.

블로그 이미지

와사비망고

,

웹페이지 개발시 로딩속도가 느린 원인을 찾기위해 특정 코드의 시간측정을 할 때 

사용하는 javascript 타이머 클래스를 만들어 보았다. 

내 경우 css 파일 link 로 읽어오는 부분에서 많은 시간을 먹는 경우가 많았다.





  javascript 클래스정의부분

<script type="text/javascript">


//-------------------------------------------------- //타이머 javascript 클래스정의 //-------------------------------------------------- var Timer = function(sWorkName) { this._sWorkName = sWorkName ; this._old = null; this._now = null; this._gap = 0; }; Timer.prototype = { start : function() { this._old = new Date(); }, end : function() { this._now = new Date(); this._gap = this._now.getTime() - this._old.getTime(); }, getDur : function(){ this._gap; }, _alert : function(){ var sec_gap = this._gap % 1000; var min_gap = this._gap / 1000 /60; alert( this._sWorkName +" 작업이 " + min_gap+'분 '+sec_gap+'초 가 걸렸습니다.'); } } Timer.prototype.constructor = Timer; //--------------------------------------------------

</script>






  사용하는 부분

<script type="text/javascript">

var timer1 = new Timer("작업1"); timer1.start(); //▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼ //시간 체크할 작업 코드들 위치... for(i = 0 ; i< 100000;i++){ console.log(i); } //▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲ timer1.end(); timer1._alert();

</script>



블로그 이미지

와사비망고

,

 

http://plugins.jquery.com/datetimepicker/

날짜만, 시간만, 날짜와 시간만 , 날짜 범위 선택이 다 돼는 웹컨트롤이다 .

날짜 와 시간선택시 마우스 스크롤로 넘겨가며 선택이 가능하고 

디자인도 내 취향이다. 

구체적인 적용 소스 코드는 

http://xdsoft.net/jqplugins/datetimepicker/ 이곳을 참조하면 된다.

 

 

일자와 시간 선택 모드 

 

 

시간만 선택 모드 

 

 

일자만 선택 모드

 

 

날짜 범위 선택 모드 

 

 

 

효능으로 맛집 검색

 

 

 

 

블로그 이미지

와사비망고

,

리워드앱 을 만드는 과정에 대해 대략적인 과정을 정리해 보고자 한다.


  앱화면구성


전체 와꾸는 com.astuetz.PagerSlidingTabStrip 오픈소스라이브러리 를 써서 슬라이딩 탭형식으로 

충전소 , 상점 , 내정보 정도로 만들면 되겠다.


충전소 에는 페북좋아요, 동영상광고, 앱설치 광고 , 사이트가입광고, 금융상품가입광고 등을 유치하여

배치해야한다. 

직접다이렉트로 광고주와 계약을 하거나 중간 광고회사로부터 광고물량을 유치 받을 수 있는 것으로 보인다. 

리워드업계의 현재 TOP인 캐시슬라이드는 아이지에이웍스 등으로 부터 광고물량을 유치했다고한다. 

이 부분은 추후 더 삽질해봐야겠다. 


상점 에는 유저들이 자신의 포인트로 구매할 수 있는 여러가지 상품목록이 떠야 하겠다. 

유저가 상품을 구매하면 유저의 폰으로 기프티콘이 발송된다.

이 기능은 KT 나 SK 와 제휴를 맺어야 하는 것으로 파악된다. 

KT 의 경우 http://www.mhows.com/download/giftishow_20140626.pdf 이곳을 보면 기업대 기업으로 계약을 맺어

기프티콘발송을 제공해주는 걸 알 수 있다. 

이때 유저들이 앱의 포인트로 구매한 상품의 실제 현금값은 리워드앱측에서 선불 혹은 후불로 KT에 지급하는 방식으로 보인다.  


내정보 

내정보에는 각 유저들의 보유 포인트가 나오고 포인트를 현금으로 환급해주는 기능을 위해서 현금환급 신청시 

매일 2시에(원하는 시간에) 환급을 원하는 유저들의 목록을 엑셀파일같은거로 뽑아 은행에 일괄송금을 요청하면 지급되는 방식으로 진행하는 것으로 알고있다. 물론 자동이 아닌 사람이 직접 송금요청파일을 수동으로 보내야하는 ( 지인의 소식에 따르면 리워드앱이 성장하여 회사 신용도가 올라간다면 은행과 계약을 맺어 다이렉트로 자동송금을 해주는 방식이 있는걸로 알고있다. 틀릴 수도 ) 






  서버측


서버측엔 유치된광고목록관리 , 회원관리 , 장부관리 , 광고주들에게 알려줄 통계자료 등의 기능들이 필요하겠다.

기타 , 설치형앱의 경우 설치후 지우지않은기간이나 누적사용시간 같은 걸 광고주들에게 알려주는 기능이 있다면

좋을듯 하다.


앱은 하이브리드로 만들면 수월할 것으로 보인다. 

하이브리드는 아이폰의 경우 스토어 등록 심사에서 차단 되는 경우가 많다는 걸 참고해야겠다. 







블로그 이미지

와사비망고

,

 

디비 설정 xml 내용

 

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

 

<!-- Root Context: defines shared resources visible to all other web components -->

 

     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>

        <property name="url" value="jdbc:mysql://localhost:3306/mydatabase"/>

        <property name="username" value="디비아이디"/>

        <property name="password" value="디비패스"/>

    </bean>

    

    

     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

        <property name="dataSource" ref="dataSource" />

        <property name="configLocation" value="/WEB-INF/spring/mybatis.config.xml"/>

        <property name="mapperLocations">

        <array>

        <value>classpath:/sqlmapper/one/*.xml</value>

        <value>classpath:/sqlmapper/two/*.xml</value>

        </array>

        </property>

    </bean>

    

     

    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">

        <constructor-arg index="0" ref="sqlSessionFactory"/>

    </bean>  

 

 

</beans>

 
/WEB-INF/spring/mybatis.config.xml 내용
 <!--?xml version="1.0" encoding="UTF-8"?--> <configuration> 	<plugins> 		<plugin interceptor="myprj.com.logInterceptor"> 	</plugin></plugins> </configuration> 
 

 

 
 
 
logInterceptor 클래스내용
 package myprj.com;  import java.util.Properties;  import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Plugin; import org.apache.ibatis.plugin.Signature; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import org.apache.log4j.LogManager; import org.apache.log4j.Logger;  @Intercepts(  { @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class })  ,@Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }) }) public class logInterceptor implements Interceptor { 	private Logger log = LogManager.getLogger(getClass());  	@Override 	public Object intercept(Invocation invocation) throws Throwable {  		Object[] args = invocation.getArgs(); 		MappedStatement ms = (MappedStatement) args[0]; 		Object param = (Object) args[1]; 		BoundSql boundSql = ms.getBoundSql(param);  		String query_name = invocation.getMethod().getName(); 		 		String query_id = ms.getId(); 		System.out.println("query_id:"+query_id);  		if ( query_id.contains("xml맵퍼의 로그출력을 원하는 쿼리id값")) { 			System.out.println("===================================="); 			System.out.println("1:" + invocation.getMethod().getName()); 			System.out.println("===================================="); 			System.out.println("2:" + ms.getId()); 			System.out.println("===================================="); 			System.out.println("3:" + boundSql.getSql()); 			System.out.println("===================================="); 			System.out.println("4:" + param); 			System.out.println("===================================="); 			System.out.println("5:" + ms.getId()); 		}   		return invocation.proceed(); 	}  	@Override 	public Object plugin(Object target) { 		return Plugin.wrap(target, this); 	}  	@Override 	public void setProperties(Properties properties) { 	} } 

 

위의 인터셉터로 인해 insert,update,delete,select 쿼리 모두 로그를 출력할 수 있었습니다.

 

log4j 를 사용하면 모든 쿼리를 출력하거나 출력안하거나 해야해서 쿼리호출이 많을경우 로그출력으로 인해 

속도가 늦어지는 문제가 있었습니다.

그래서 인터셉터 방식으로 원하는 쿼리만 로그출력을 해봤습니다. 

 

 

 

블로그 이미지

와사비망고

,


1. http://prismjs.com/download.html 에 접속합니다.

2. Languages에서 블로그에 출력할 프로그래밍언어를 선택합니다.

3. Plugins 에 

   Line Highlight ,

   Highlight ,

   Line Numbers , 

   Previewer Base ,

   Previewer Color ,

   Show Language 

   옵션들을 선택해줍니다. 

3. 맨 아래 DOWNLOAD JS, DOWNLOAD CSS 클릭으로 

    prism.css , prism.js 를 다운로드 합니다.



4. 블로그상에서 아래 빨간부분들을 순서대로 클릭합니다. 





5. 3번에서 다운로드 했던 prism.css, prism.js 파일을 업로드 해줍니다.







     <link rel="stylesheet" type="text/css" href="prism.css">
     <script src="prism.js"></script>

6. 위 코드를 </head> 안에 추가 해줍니다.


7. 티스토리 글쓰기 에디터에서 HTML 모드로 들어간 후 아래 테스트 코드를 입력합니다.


//▼▼▼▼▼▼▼▼▼▼ 복사할 테스트 코드 ▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼


<pre class="line-numbers"><code class="language-markup">

<p>&lt;!doctype html&gt;</p>

<p>...</p>

<p>&lt;!-- html태그 --&gt;</p>

<p>&lt;div class="center123"&gt;</p>

<p style="margin-left: 2em;">&lt;span &gt;망고땡&lt;/span&gt;</p>

<p>&lt;/div&gt;</p>

</code></pre>


  <pre class="line-numbers"><code class="language-css">

/* css */

#c1{ background-color:black}

#block{diaplay:block;background-color:#ff2343}

</code></pre>


<pre class="line-numbers"><code class="language-java">

public static void main(String[] args) throws Exception{

//java 코드

System.out.println("망고땡블로그");

}

</code></pre>


<pre class="line-numbers"><code class="language-csharp">

using System;

using 토니스타크.자비스;

namespace 인공지능

{

public partial class 알파고 : 자비스

{

//C# 코드

public 바둑좌표 get최적의수(int[][] 현재바둑판상황)

{

return CPU1202개_GPU176개로_검색(현재바둑판상황);

}

}

}

</code></pre>

//▲▲▲▲▲▲▲▲▲  복사할 테스트 코드 ▲▲▲▲▲▲▲▲▲▲▲▲▲


다운로드 받을때 선택한 테마(Themes) 에 따라 아래와 같은 스타일이 적용됩니다.



COY 테마

DARK 테마


DEFAULT 테마


FUNKY 테마


OKAIDIA 테마


SOLARIZED 테마


TWILIGHT 테마








블로그 이미지

와사비망고

,

<div id="container">

    <div class="box">머시기거시기거시기머시기</div>

</div>


위의 내용을 두고


box 를 position:relative 로 두면 container 내부에 영역을 차지하고 box div 사이즈가 커지면

container 요소의 사이즈도 커진다. 하지만 box 요소의 top 값을 조정해 이동시켜도 container 의 사이즈가 커지지는 않는다.

top,bottom,left, right 의 값은 먹힌다.

같은 부모 내부의 relative , static 요소간에는 질서가 유지된다.

(만약 같은 부모이고 자신의 앞부분에 static 이나 relative 요소를 추가하고 top 값을 지정하면

자신의 형제요소인 그 요소를 기준으로 top 이 계산되어진다. 부모의 top 을 기준으로한 top 이 아니라 말이다.)

그림으로 자세히 설명하자면

[[왼쪽소스]]

<div id="container">
    <div class="box">머시기거시기거시기머시기</div>
</div>


[[오른쪽소스]]

<div id="container">
    <div>앞</div>
    <div class="box">머시기거시기거시기머시기</div>
</div>



box 를 기본값인 position:static 으로 두면 container 내부에 영역을 차지하고 box div 사이즈가 커지면
container 요소의 사이즈도 커진다. 

또 top,left,bottom,right 값은 먹지 않는다.

그리고 한 라인을 다 차지한다. 

width, height 값은 적용된다. 



box를 position:absolute; 으로 두면 container 내부에 영역을 차지하지 않고 absolute 흐름으로 편입된다. 

부모가 position:absolute 요소 외에 자식이없다면 부모요소의 높이는 0이된다. 


position:fixed 의 경우 absolute 와 같지만 차이점은

브라우져 스크롤을 올리고 내려도 브라우져 client화면의 left,top 을 기준으로 그자리에 고정된다. 

블로그 이미지

와사비망고

,




이런식으로 안드로이드 앱의 레이아웃을 배치하는 방법은 이렇케


___________________________________________________________________________________

<LinearyLayout

    ...

    android:layout_height="wrap_content"

    >

<상단 임의컨트롤 

  android:layout_height="상단높이"

  ...

/>

</LinearyLayout>

<LinearLayout (or가운데배치할아무컨트롤)

   ...

    android:layout_height="0dip"

    android:layout_weight="1"

   ...

    />

<LinearyLayout

    android:layout_height="wrap_content"

    >

<하단임의컨트롤

android:layout_height="하단높이"

/>

</LinearyLayout>

___________________________________________________________________________________






블로그 이미지

와사비망고

,