Translate

2018년 9월 2일 일요일

[Blogger / Blogspot / 구글 블로그] 로그인 시에만 보이는 태그 만들기 (글쓰기, 글수정 등)




내 블로그로 예를 들어보면 위가 로그인 전, 아래가 로그인 후이다.

자세히 차이점을 찾아보면 왼쪽메뉴 최하단의 글쓰기와 각 글 옆의 펜모양이 보일 것이다.
이렇게 로그인 시에만, 즉 자신에게만 보이는 버튼을 만들어 보자.

사실 기본 블로그 테마들을 이용하면 상단에 navbar라는 게 있어서 글쓰기 버튼에 대한 고민은 하지 않아도 되고,
글 수정 버튼도 기본적으로 있지만,
나처럼 외부 템플릿을 불러왔는데 이것들이 없을 경우에 참고하면 좋은 글이다.

그리고 위치 지정의 경우 스스로의 블로그에 대한 html 소스를 대략 알고 있어야 가능해서,
소스에 대해서만 설명하겠다.

우선 글쓰기 버튼은, 확인해야할 사항이 하나 있다.
blogger.com으로 들어가서 글쓰기 버튼을 누르고 URL을 복사해온다.

https://www.blogger.com/blog/post/edit/★
같은 형식일텐데, ★ 부분은 랜덤한 숫자처럼 보이는 걸로 봐선 아마 계정별로 다를 것이다.

그리고 원하는 위치에 다음 소스를 붙히면 된다. (href 속성 안에 URL를 붙이면 된다)
<span class='item-control blog-admin'>
    <a target='_blank' href='https://www.blogger.com/blog/post/edit/★'>글쓰기</a>
</span>


두번째로 수정 버튼은, 사실 기본 테마에서 그대로 가져온 소스긴 하지만 어쨌든 적어보자면

<b:include data='post' name='postQuickEdit'/>
<b:if cond='data:post.editUrl'>
   <span expr:class='&quot;item-control &quot; + data:post.adminClass'>
       <a target='_blank' expr:href='data:post.editUrl' expr:title='data:top.editPostMsg'>
           <img alt='' class='icon-action' height='18' src='http://img2.blogblog.com/img/icon18_edit_allbkg.gif' width='18'/>
       </a>
   </span>
</b:if>

이건 내부적으로 blogger 자체 태그를 쓰는거라 따로 변경해줄 부분은 없다.
여기도 문자로 바꾸고 싶다면 img 태그 대신 문자를 그대로 쓰면 된다.


2018년 7월 23일 월요일

[Java] String to JSON 라이브러리 정리



Laptop
운영체제Windows 10 Home 64bit
개발프로그램Eclipse Oxygen (4.7)

예제 String:
String jsonString = "{" +
 "'name' : 'Ronaldo', " +
 "'age' : 25, " +
 "'id' : 121.5, " +
 "'lastScores' : [ 2, 1, 3, 5, 0, 0, 1, 1 ]" +
 "}";

1. json Path
https://mvnrepository.com/artifact/com.jayway.jsonpath/json-path

import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;

...

System.out.println(document.read("$.name") + " / " + document.read("$.name").getClass().getName());
System.out.println(document.read("$.age") + " / " + document.read("$.age").getClass().getName());
System.out.println(document.read("$.id") + " / " + document.read("$.id").getClass().getName());
System.out.println(document.read("$.lastScores") + " / " + document.read("$.lastScores").getClass().getName());
System.out.println(document.read("$.lastScores[3]") + " / " + document.read("$.lastScores[3]").getClass().getName());

결과:







- 입력된 자료에 따라 반환값 타입이 고정됨. 다른 타입 사용 시 형변환 필요.
- accessors-smart, json-smart, slf4j-api, slf4j-jdk 라이브러리가 함께 필요


2. json simple
https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

...

JSONParser parser = new JSONParser();
Object obj = null;

// 따옴표 변환 필요
jsonString = jsonString.replace("'", "\"");

try {
 obj = parser.parse(jsonString);
} catch (ParseException e) {
 e.printStackTrace();
}
JSONObject jsonObj = (JSONObject) obj;

System.out.println(jsonObj.get("name") + " / " + jsonObj.get("name").getClass().getName());
System.out.println(jsonObj.get("age") + " / " + jsonObj.get("age").getClass().getName());
System.out.println(jsonObj.get("id") + " / " + jsonObj.get("id").getClass().getName());
System.out.println(jsonObj.get("lastScores") + " / " + jsonObj.get("lastScores").getClass().getName());

JSONArray jsonArray = (JSONArray) jsonObj.get("lastScores");
System.out.println(jsonArray.get(3) + " / " + jsonArray.get(3).getClass());

결과:


입력된 자료에 따라 반환값 타입이 고정됨. 다른 타입 사용 시 형변환 필요.
- JSONArray 사용 시 추가적인 JSONArray 선언이 필요


3. Gson

import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

...

JsonParser parser = new JsonParser();
JsonElement element = parser.parse(jsonString);

System.out.println(element.getAsJsonObject().get("name").getAsString());
System.out.println(element.getAsJsonObject().get("age").getAsFloat());
System.out.println(element.getAsJsonObject().get("lastScores").getAsJsonArray().get(3));

결과:




- .getAs... 메소드로 형변환 가능 
- JSONArray의 경우 getAsJsonArray 사용

4. boon

POJO 형식의 클래스 필요.

Player.class

package jsonTest;

import java.util.ArrayList;

public class Player {
 String name;
 int age;
 float id;
 ArrayList lastScores;
 
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 public float getId() {
  return id;
 }
 public void setId(float id) {
  this.id = id;
 }
 public ArrayList getLastScores() {
  return lastScores;
 }
 public void setLastScores(ArrayList lastScores) {
  this.lastScores = lastScores;
 }
}

(ArrayList 대신 int[]형으로 써도 무방함)

import org.boon.json.JsonFactory;
import org.boon.json.ObjectMapper;

import jsonTest.Player;

...

ObjectMapper mapper = new JsonFactory().create();
Player p = mapper.fromJson(jsonString, Player.class);

System.out.println(p.getName());
System.out.println(p.getLastScores().get(3));

결과:



- POJO로 형변환 문제 해결 가능
- Java의 데이터형 객체를 활용 가능

참고 사이트:
http://www.java67.com/2016/10/3-ways-to-convert-string-to-json-object-in-java.html

2018년 6월 22일 금요일

[Blogger / Blogspot / 구글 블로그] 사진, 동영상 크기 관련 팁


1. 사진 여러 장 업로드 시 일괄 크기 지정법





기본적으로 글쓰기 탭에서 사진을 여러 장 삽입할 경우,
별 중간과정 없이 그대로, 그것도 Blogger 기준 '크게' 사이즈로 삽입되기 때문에
그 크기를 바라지 않을 경우 일일히 노가다를 하는 수밖에 없다.

그런데 사실 Blogger에는 이를 보완할 기능이 있다.

바로 글쓰기 옆의 HTML 탭으로 변경 후 사진을 여러 장 삽입해보면,
아까와는 달리 이런 창이 등장한다.




딱 보면 알겠지만, 사진들을 일괄처리할 수 있는 기능이다.

추측으로는 만들었다가 현재 글쓰기 메뉴에 적용을 실수로 안한 게 아닐까 생각한다.



2. 동영상 크기 변경법

Blogger에서 제공하는 기능으로 개인 동영상을 올리든, 유튜브 동영상을 올리든
공통적으로 크기가 너무 작다.

html 값을 보면 희한하게도 크기를 320 * 266 으로 딱 고정해놓았다.

CSS 추가로 강제로 이 기본값을 바꿀 수 있다.


Blogger에서 테마 - 맞춤설정을 선택,
고급 탭에서 맨 아래의 CSS추가를 선택한다.
(간혹 외부 템플릿을 적용한 경우는 너비 조정 탭에서 나온다.)


그리고 아래 소스를 입력한다.


.b-hbp-video, .YOUTUBE-iframe-video
{
  width: 90%;
  height: 56vh;
}

간단히 설명하자면 b-hbp-video 와 YOUTUBE-iframe-video라는 클래스(각각 업로드 동영상, 유튜브 동영상)의 크기를 조정하는 것인데,

가로는 포스트창 기준으로 %가 적용되지만,
세로는 기준이 뭔지 %는 이상한 결과가 나오고
그 대신 vh라는 브라우저 높이값에 비례하는 값을 썼다.
이게 모바일에서도 제일 무난하게 나오는 것 같다.

위 값대로 하면 이 정도 사이즈가 되고,




만약 변경하고 싶다면 F12를 누르면 나오는 개발자모드에서 미리보기를 할 수 있다.
왼쪽 상단에 커서 버튼을 클릭하고 동영상을 누르면 해당 태그를 쉽게 찾을 수 있다.
(선택한 채로 위, 아래 방향키로 값 조정이 가능하다.)


계속 느끼는 지만, Blogger는 html 지식이 없는 사용자에게는 상당히 불편한 플랫폼인 것 같다.

2018년 6월 10일 일요일

[Blogspot / Blogger / 구글 블로그] 외부 템플릿 불러오기 시 Google+ 댓글이 나오지 않는 현상 해결


대부분의 외부 템플릿이 기본적으로 Blogger 자체의 댓글이 보이도록 되어있는데,
댓글을 Google+로 변환 시 아예 다른 api를 사용하게 되는 모양인지 댓글이 전부 없어져 버리는 현상이 발생한다. 

다시 제공 템플릿으로 돌아오면 보이는 걸 보면 제공 템플릿에는 자동적으로 소스가 변경되도록 어떤 장치가 되어있는 것 같은데, 그게 뭔지는 잘 이해를 못했다.

어쨌든 변경해야 할 부분은 댓글 수 부분과 댓글이 보이는 부분이다.


테마 HTML 편집을 보면 다음과 같은 부분이 두 군데 있다. (showThreadedComments 를 검색)

<b:if cond='data:blog.pageType == &quot;static_page&quot;'>
  <b:if cond='data:post.showThreadedComments'>
 <b:include data='post' name='threaded_comments'/>
  <b:else/>
 <b:include data='post' name='comments'/>
  </b:if>
</b:if>
<b:if cond='data:blog.pageType == &quot;item&quot;'>
  <b:if cond='data:post.showThreadedComments'>
 <b:include data='post' name='threaded_comments'/>
  <b:else/>
 <b:include data='post' name='comments'/>
  </b:if>
</b:if>


그 두 부분을 모두 이렇게 변경한다.

<b:if cond='data:blog.pageType == &quot;static_page&quot;'>
  <b:include data='post' name='comment_picker'/>
</b:if>
<b:if cond='data:blog.pageType == &quot;item&quot;'>
  <b:include data='post' name='comment_picker'/>
</b:if>


이러면 댓글을 보이게 하는데까진 성공이나,
아직 댓글 수는 Blogger 댓글 수로 나오기 때문에 바뀌지 않은 상태일 것이다.


이 부분도 역시 HTML 편집에서 comment_count_picker를 검색하고, 해당 태그를 아래와 같이 변경한다. (만약에 없다면, comment_picker 등 유사한 이름을 찾아보거나 새로 만들면 된다.)

<b:includable id='comment_count_picker' var='post'>
  <b:if cond='data:post.commentSource == 1'>
    <span class='cmt_count_iframe_holder' expr:data-count='data:post.numComments' expr:data-onclick='data:post.addCommentOnclick' expr:data-post-url='data:post.url' expr:data-url='data:post.canonicalUrl'>
    </span>
  <b:else/>
    <a class='comment-link' expr:href='data:post.addCommentUrl' expr:onclick='data:post.addCommentOnclick'>
      <data:post.commentLabelFull/>:
    </a>
  </b:if>
</b:includable> 


그리고 댓글 수가 나오는 부분을 찾는다.
보통 다음과 같은 구성이다. (post-comment-link를 검색)

<span class='post-comment-link'>
                <b:if cond='data:blog.pageType != &quot;item&quot;'>
                  <b:if cond='data:blog.pageType != &quot;static_page&quot;'>
                    <b:if cond='data:post.allowComments'>
                      <a class='comment-link' expr:href='data:post.addCommentUrl' expr:onclick='data:post.addCommentOnclick'><b:if cond='data:post.numComments == 1'>1 <data:top.commentLabel/><b:else/><data:post.numComments/> <data:top.commentLabelPlural/></b:if></a>
                    </b:if>
                  </b:if>
                </b:if>
</span>


이것을 아래와 같이 바꾼다. (아까 작성한 comment_count_picker를 사용하는 걸 볼 수 있다.)


<span class='post-comment-link'>
                <b:if cond='data:blog.pageType != &quot;item&quot;'>
                  <b:if cond='data:blog.pageType != &quot;static_page&quot;'>
                    <b:if cond='data:post.allowComments'>
                      <b:include data='post' name='comment_count_picker'/>
                    </b:if>
                  </b:if>
                </b:if>
</span>


다만 제공해주는 api를 이용하는 것이기 때문에 디자인은 기본 템플릿에서 벗어날 수 있다.
이 부분은 css등을 이용하여 조정해주면 되고,
그게 싫다면 Google+ 댓글을 안쓰거나 제공 템플릿을 쓰는 수밖에...

주의사항은, Blogger 댓글을 사용하다가 Google+ 댓글로 전환하고 이 방법을 썼을 경우
보이는 데는 문제가 없으나, 왜인지 댓글 수가 2배로 나오고 뭔가가 별개로 구분되어 버리는 건지 삭제 등의 작업을 할 수 없게 된다.

결국 둘 다 기능 문제 없이 사용하고 싶다면 제공 템플릿을 쓸 수밖에 없고,
혹은 처음부터 Google+ 댓글을 쓸건지 말건지를 확실히 하는 것 같다.



참고 사이트:

댓글 보이게 하기:

댓글 수:

2018년 6월 7일 목요일

2018년 4월 29일 일요일

[Android Studio] Android Studio에서 Eclipse 프로젝트 열기 (the output path is not specified ~ 오류 해결법)


Laptop
운영체제Windows 10 Home 64bit
개발프로그램Android Studio 3.1.1


github같은 외부 소스 파일을 불러오다보면, 컴파일을 했을 때 다음과 같은 경고창을 띄울 때가 있다.


output path를 설정하라고 되어있는데, 그 말대로 설정에서 output 경로를 설정하고 컴파일해도 아래와 같이 Can't find bundle for base name messages.AndroidJpsBundle, locale ko_KR 하는 오류를 다시 뱉는다.


이것은 Eclipse 프로젝트를 Android Studio에서 Open하려고 했을 때 나타날 수 있는 현상이며, 이 경우 아예 다른 방법으로 열어야 한다.






사실 초기 화면에서 이미 알려주고 있기는 하다. 어쨌든 Import Project를 선택하면 되며, 탐색기가 뜨면 해당 프로젝트를 다시 선택해준다.



그러고나면 이렇게 Directory를 입력하라는 창이 뜰텐데, (캡쳐에서는 지웠지만 아마 해당 프로젝트명에 1을 붙인 이름으로 되어있을 것이다.)
새로운 프로젝트를 생성하는 것과 동일하므로 기존 이름과 겹치지 않는 다른 이름을 지어주면 된다.

그 후 나오는 Maven 등의 추가 요구사항은 알맞게 설치해주면 된다.


[AutoHotkey] Window 10 OneNote에, AutoHotkey를 이용한 그리기 단축키 만들기 (요가북 기준)


Laptop
운영체제Windows 10 Home 64bit
개발프로그램AutoHotkey


Window 10의 기본프로그램 중에, OneNote라는 이름 뒤에 넘버링이 붙지 않은, 보라색 바탕에 흰색 아이콘을 가진 프로그램이 있다. (아래 그림 참고)



이는 Window 10 전용 버전인데, UI를 보면 넘버링이 붙는 버전과 다르게 심플한, 태블릿을 타겟으로 했다는 느낌이 강하다. 
요가북의 경우 펜 전환 버튼을 누르면 화면 하단에 퀵 아이콘이 뜨기도 한다.



이 프로그램의 그리기 기능을 써서 손필기 용도로 사용해보면서 느낀 가장 아쉬운 점은, 별도의 단축키가 없다는 점이다. 
예를 들어 필기 도중 지우개를 쓸 때도, 화면 상단으로 마우스를 끌어 지우개 버튼을 클릭, 지우기, 다시 펜 버튼 클릭 후 필기를 계속하는 수밖에 없다는 뜻이다.


목적이 다르긴 하지만 역시 펜을 주로 쓰는 그림툴인 메디방페인트(MedibangPaint)의 경우, 
Z키를 누른 채로 그리기를 하면 지우개 기능이 적용되고, 떼면 다시 펜으로 돌아오는 기능이 있다.



여기서 아이디어를 얻어, 매크로 작성 프로그램인 AutoHotkey로 해당 기능을 구현해보기로 했다.

다운로드는 간단하므로 따로 설명하지 않겠다.
AutoHotkey 공식 페이지: https://autohotkey.com/



다운로드가 끝나면, 바탕화면에서 우클릭 후 새로 만들기를 보면 다음과 같은 항목이 추가된 것을 볼 수 있다.



클릭하면 .ahk 확장자 파일이 하나 생성된다. 

생성 파일에서 우클릭 후 Edit Script를 클릭하면 메모장으로 열리게 되고, 아래의 코드를 입력한다. 상단 부분은 자동으로 생성된다.


 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
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
; 자동 생성

; 시작 메시지박스 1초간 띄우기
MsgBox, 0, , Onenote_Script START, 1

;무한 루프 (실행 유지)
LOOP
{
 ; F2를 눌렀을 때 (Down Event)
 if(GetKeyState("F2", P))
 {
  ; 지우개 클릭 후 커서 제자리로
  MouseGetPos, xpos, ypos 
  MouseClick, left,  250,  150
  MouseMove, xpos, ypos
  
  ; Down Event 이후에 Up이 입력됐을 경우, 다시 pen을 클릭하여 원상태 복구
  LOOP
  {
   if(!GetKeyState("F2", P))
   {
    MouseGetPos, xpos, ypos 
    MouseClick, left,  300,  150
    MouseMove, xpos, ypos
    break
   }
  }
 }

 if(GetKeyState("F3", P))
 {
  MouseGetPos, xpos, ypos 
  MouseClick, left,  350,  150
  MouseMove, xpos, ypos
  
  LOOP
  {
   if(!GetKeyState("F3", P))
   {
    MouseGetPos, xpos, ypos 
    MouseClick, left,  300,  150
    MouseMove, xpos, ypos
    break
   }
  }
 }

 if(GetKeyState("F4", P))
 {
  MouseGetPos, xpos, ypos 
  MouseClick, left,  410,  150
  MouseMove, xpos, ypos
  
  LOOP
  {
   if(!GetKeyState("F4", P))
   {
    MouseGetPos, xpos, ypos 
    MouseClick, left,  300,  150
    MouseMove, xpos, ypos
    break
   }
  }
 }

 if(GetKeyState("F5", P))
 {
  MouseGetPos, xpos, ypos 
  MouseClick, left,  470,  150
  MouseMove, xpos, ypos
  
  LOOP
  {
   if(!GetKeyState("F5", P))
   {
    MouseGetPos, xpos, ypos 
    MouseClick, left,  300,  150
    MouseMove, xpos, ypos
    break
   }
  }
 }

 ; Ctrl + "-" 입력 시, 메시지박스 띄운 후 종료
 if(GetKeyState("-", P) && GetKeyState("Ctrl", P))
 {
  MsgBox, 0, , Onenote_Script END, 1
  break
 }
}

특정 조건이 눌리면 현 커서 위치를 저장했다가 화면 상에서 버튼 위치로 이동 후 클릭하고 저장했던 위치로 돌아오는, 단순한 원리의 코드이다.
단 요가북에서만 테스트 해봤기 때문에, 다른 해상도의 PC에서도 동일한 위치값을 가질지는 모르겠다. 만약 아니라면 X, Y값의 조정이 필요하다.

첫번째 if문 이후는 키만 변경한 반복되는 코드이다.
사용하는 단축키는 OneNote의 기존 단축키와 겹치지 않는 F2~F5로 했다.
정리하자면 아래와 같다.



그 전에 Ctrl 이나 Alt로도 실험을 해봤는데, 충돌되는 뭔가가 있는지 반응 속도가 엄청 느렸다.


사용한 함수들을 간단히 설명하자면, 다음과 같다.
쓰지 않은 매개변수를 생략했으니 더 자세히 알고 싶으면 공식 도움말을 참고하도록 하자.

GetKeyState (KeyName , Mode )

Mode는 두 가지가 있다.
P: 키를 누르고 있는지의 물리적 상태. Down(누르고 있음)의 경우 1, Up(손을 떼고있음)의 경우 0을 반환
T: CapsLock, NumLock 등의 토글 상태에 따라 켜지면 1, 꺼지면 0을 반환


MouseGetPos  , OutputVarX, OutputVarY

현재 마우스 커서의 위치값을 읽어 저장한다.
OutputVarX/Y 에 변수명을 쓰면 된다.


MouseClick , WhichButton, X, Y

클릭 이벤트를 실행시킨다.
WhichButton에는 Left (default), Right, Middle 혹은 스크롤을 감지하는 WheelUp 등을 넣을 수 있다. X, Y에는 위치값을 넣는다.


MouseMove, X, Y

마우스 커서를 특정 위치로 이동시킨다.
X, Y에 위치값을 넣는다.


MsgBox , Options, Title, Text, Timeout

메시지 박스를 띄운다.

Options: 확인, 중단, 예/아니오 등의 메시지 박스의 종류를 나타낸다. 0은 기본값인 확인버튼이다.

Title: 제목의 텍스트. 생략 시 스크립트 파일명이 된다.

Text: 본문 텍스트

Timeout: 해당 시간이 지나면 창이 자동으로 꺼진다. 초 단위.


그 외 LOOP문의 경우 while(1)와 같다고 생각하면 된다. break로 중간에 강제 종료시키는 것도 동일하다.



스크립트 파일을 더블클릭해도 실행이 되지만,
스크립트 파일에서 우클릭 후 Compile Script를 선택하면 동일한 이름의 .exe 파일이 생성되고, 이것을 실행해도 된다.
그리고 작업표시줄에 등록해놓고 쓰면 편리하다.

종료 시에는 Ctrl + "-" 를 누르면 된다. (중복되지 않게 잘 쓰지 않는 단축키를 사용한 것뿐, 큰 의미는 없다.)


결과 영상