git reset --hard HEAD^

git push -f origin develop

'분류없음' 카테고리의 다른 글

[cpp] std::move는 단지 캐스팅일 뿐이라고?  (0) 2017.02.08
Same string but different length  (0) 2016.10.28
JIT vs Interpreter  (0) 2016.10.25
[encoding] javascript write to csv  (0) 2015.04.11
APNS python failure and feedback  (0) 2015.04.06
블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,

see: https://stackoverflow.com/questions/21177078/javascript-download-csv-as-file/23786965#23786965

key point is \uFEFF


version 1.

var encodedUri = 'data:text/csv;charset=UTF-8,\uFEFF'+encodeURI(comma_data);

var link = document.createElement("a");

link.setAttribute("href", encodedUri);

var name = 'gem_use.csv';

if (key == 'container_get') {

    name = 'gem_get.csv';

}

link.setAttribute("download", name);

link.click();


version 2. (<table></table> to excel file)

usage: tablesToOneExcelSheet(tables, sheets, today+filename, 'Excel');(tables => table element id list, sheet => name list of each table)

* Should use Blob to enable large file size.

var tablesToOneExcelSheet = (function() {
var uri = 'data:application/vnd.ms-excel;base64,'
, tmplWorkbookXML = '<'+'?xml version="1.0"?><'+'?mso-application progid="Excel.Sheet"?><Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">'
+ '<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Author>NM</Author><Created>{created}</Created></DocumentProperties>'
+ '<Styles>'
+ '<Style ss:ID="Currency"><NumberFormat ss:Format="Currency"></NumberFormat></Style>'
+ '<Style ss:ID="Date"><NumberFormat ss:Format="Medium Date"></NumberFormat></Style>'
+ '</Styles>'
+ '{worksheets}</Workbook>'
, tmplWorksheetXML = '<Worksheet ss:Name="{nameWS}"><Table>{rows}</Table></Worksheet>'
, tmplCellXML = '<Cell{attributeStyleID}{attributeFormula}><Data ss:Type="{nameType}">{data}</Data></Cell>'
, base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))) }
, format = function(s, c) { return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) }
return function(tables, wsnames, wbname, appname) {
var ctx = "";
var workbookXML = "";
var worksheetsXML = "";
var rowsXML = "";

for (var i = 0; i < tables.length; i++) {
if (!tables[i].nodeType) tables[i] = document.getElementById(tables[i]);
for (var j = 0; j < tables[i].rows.length; j++) {
if(i>0 && j==0) {
continue;
}
rowsXML += '<Row>';
for (var k = 0; k < tables[i].rows[j].cells.length; k++) {
var dataType = tables[i].rows[j].cells[k].getAttribute("data-type");
var dataStyle = tables[i].rows[j].cells[k].getAttribute("data-style");
var dataValue = tables[i].rows[j].cells[k].getAttribute("data-value");
dataValue = (dataValue)?dataValue:tables[i].rows[j].cells[k].innerHTML;
var dataFormula = tables[i].rows[j].cells[k].getAttribute("data-formula");
dataFormula = (dataFormula)?dataFormula:(appname=='Calc' && dataType=='DateTime')?dataValue:null;
ctx = { attributeStyleID: (dataStyle=='Currency' || dataStyle=='Date')?' ss:StyleID="'+dataStyle+'"':''
, nameType: (dataType=='Number' || dataType=='DateTime' || dataType=='Boolean' || dataType=='Error')?dataType:'String'
, data: (dataFormula)?'':dataValue
, attributeFormula: (dataFormula)?' ss:Formula="'+dataFormula+'"':''
};
rowsXML += format(tmplCellXML, ctx);
}
rowsXML += '</Row>';
}
}

ctx = {rows: rowsXML, nameWS: "Data"};
worksheetsXML += format(tmplWorksheetXML, ctx);

ctx = {created: (new Date()).getTime(), worksheets: worksheetsXML};
workbookXML = format(tmplWorkbookXML, ctx);
window.URL= window.URL || window.webkitURL;
var blob = new Blob([workbookXML], {type: 'application/vnd.ms-excel;base64'});
var blobUrl = window.URL.createObjectURL(blob);

var link = document.createElement("A");
// link.href = uri + base64(workbookXML);
link.href = blobUrl;
link.download = wbname || 'Workbook.xls';
link.target = '_blank';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
})();


'분류없음' 카테고리의 다른 글

[cpp] std::move는 단지 캐스팅일 뿐이라고?  (0) 2017.02.08
Same string but different length  (0) 2016.10.28
JIT vs Interpreter  (0) 2016.10.25
git pushed merge cancel  (0) 2015.04.13
APNS python failure and feedback  (0) 2015.04.06
블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,


https://pypi.python.org/pypi?%3Aaction=search&term=apns&submit=search


apns-client(0.2.1)

pushjack(0.3.0)

apns(2.0.1)

download count

(201503 1달동안)

1524

2041

4731

bulk tokens 보내기

O

O

O

invalid token handling

(invalid token 이 한 APNs connection에 섞여있을 경우)

send에 대한 return값으로 failed tokens 전달

(retry code 필요)

Exception처리로 몇번째 token이 invalid token인지 전달됨

(retry code 필요)

error handler thread에서 failed tokens retry 해줌

기타특징

async/sync send

GCM, APNS둘다 제공



  • pyapns(download count: 1664) 는 제외함: 기본적으로 푸시 보내는 방식이 별도의 APNSSever를 twisted(event-driven network engine)를 이용해서 띄워놓고 여기로 보내는 방식.
  • 참고로 android는 python-gcm 이 있는데, push jack은 토큰 하나씩 for문을 돌면서 하나씩 보내는데 비해 python-gcm은 한번에 보낸다. 그리고 에러처리는 실패한 토큰들을 모아서 다시보내기를 5번 반복하고 끝내는 방식으로 되어있다.


'python' 카테고리의 다른 글

gunicorn vs uwsgi  (0) 2017.01.20
flask async response  (0) 2017.01.04
functools.wraps에 대해  (0) 2015.04.15
Getting specific timezone timestamp from time string  (0) 2015.01.20
Shallow copy VS Deep copy  (0) 2014.08.27
블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,

https://github.com/djacobs/PyAPNs

Problem 1. Push notification Failed right after sending invalid token

APNS uses socket to send notification object. and if it use invalid token, that connection will be disconnected. you can overcome this by re-generating APNs Object.

But there is one more problem. If you use for loop with same APNs Object, and there is an invalid token, the tokens right after sending invalid token will be failed. 

So, there is an option named enhanced=True, it will check each tokens if it succeeded. and It uses non-blocking ssl socket, and check error using another thread. So I think there is no critical waiting. In the function "_resend_notification_by_range" It sends only notifications after invalid token.

They also provide "send_notification_multiple" function. This function doesn't check error and discard all tokens after invalid token.


Issue 1. FeedbackConnection

https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW3

- connection method and how many tokens you can receive?

they use socket. and It reads data using streaming until there is no data. see below


Once you are connected, transmission begins immediately; you do not need to send any command to APNs. Read the stream from the feedback service until there is no more data to read.

... 

The feedback service’s list is cleared after you read it. Each time you connect to the feedback service, the information it returns lists only the failures that have happened since you last connected.


'분류없음' 카테고리의 다른 글

[cpp] std::move는 단지 캐스팅일 뿐이라고?  (0) 2017.02.08
Same string but different length  (0) 2016.10.28
JIT vs Interpreter  (0) 2016.10.25
git pushed merge cancel  (0) 2015.04.13
[encoding] javascript write to csv  (0) 2015.04.11
블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,

nginx log ratation

nginx 2015. 4. 6. 11:15

nginx설정을 따로 안하면 미친듯이 로그를 쌓아서 10기가나 차지하고 있는것을 볼수 있다.

weekly로 쌓는 로그를 가능하면 daily로 바꿔주거나 로그가 필요하면 디스크용량을 충분히 갖춰야!

설정법

http://www.nginxtips.com/how-to-rotate-nginx-logs/

'nginx' 카테고리의 다른 글

Loadbalancer를 통해서 올때 client ip가 전달되도록하는 방법  (0) 2018.01.12
ssl setting  (0) 2015.03.12
mac 에서 nginx 설치 및 설정 하기  (0) 2014.10.24
블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,

Approach1. Using awscli (you don't have to make codes)

1. before collecting some metrics from your instance, your instance must be lauched with CloudWatchFullAccess IAM role.

ref: http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/UsingIAM.html

Amazon CloudWatch integrates with AWS Identity and Access Management (IAM) so that you can specify which CloudWatch actions a user in your AWS Account can perform. For example, you could create an IAM policy that gives only certain users in your organization permission to use GetMetricStatistics. They could then use the action to retrieve data about your cloud resources. 

* in my  case, I made new role(named cloudwatch_test) on IAM service with CloudWatchFullAccess, CloudWatchLogsFullAccess policies. and launch ec2 instance with this IAM role. 


2. follow this. to install cloudwatch tool stuffs

http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/mon-scripts-perl.html


3. After installing perl stuffs and finishing role settings, you can use perl command like this.

$ sudo mv aws-scripts-mon /usr/local/bin/aws-scripts-mon

$ echo "* * * * * ubuntu /usr/local/bin/aws-scripts-mon/mon-put-instance-data.pl --mem-used --mem-avail --disk-path=/dev/xvda1 --disk-space-used --dis-space-avail --from-cron" | sudo tee /etc/cron.d/aws-monitor-mem-disk-usage

* "ubuntu" is user name 

now you can check your custom metric in Ec2 monitoring->View all CloudWatch metrics->Metrics-> Linux System Metrics

if you want to monitor your existing ec2 instance, unfortunately there is no way. I tried below, but it was not working.

(you should install awscli tool first, just type $sudo apt-get install awscli, $aws configure)

1. aws iam create-instance-profile --instance-profile-name CloudWatchProfile

2. aws iam add-role-to-instance-profile --instance-profile-name CloudWatchProfile --role-name cloudwatch_test


Approach2. Using Boto (you have to do some works, but could be more flexible)

http://arr.gr/blog/2013/08/monitoring-ec2-instance-memory-usage-with-cloudwatch/

followed record.

1. make t2 micro ec2 instance (ubuntu)

2. install prerequisites

$sudo apt-get update

$sudo apt-get install python-pip

$sudo pip install boto

3. setup boto config file

$sudo vim /etc/boto.cfg

[Credentials]
aws_access_key_id = <your_access_key_here>
aws_secret_access_key = <your_secret_key_here>

4. get source code and set to cron job

$ curl https://gist.githubusercontent.com/shevron/6204349/raw/cw-monitor-memusage.py | sudo tee /usr/local/bin/cw-monitor-memusage.py

$ sudo chmod +x /usr/local/bin/cw-monitor-memusage.py

$ echo "***** ubuntu /usr/local/bin/cw-monitor-memusage.py" | sudo tee /etc/cron.d/cw-monitor-memusage

* "ubuntu" is user name 

5. check it in AWS management console

Ec2 monitoring->View all CloudWatch metrics->Metrics-> Custom Metrics (it will take a time, wait until this menu created)




'aws' 카테고리의 다른 글

AWS lambda 삽질 일기  (0) 2017.03.17
kinesis firehose 삽질일기  (0) 2017.03.16
elasticache dump to file  (1) 2015.03.23
[ubuntu server instance] mytoon setting  (0) 2014.10.24
HTTP 505: HTTP Version Not Supported  (0) 2014.07.09
블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,

elasticache dump to file

aws 2015. 3. 23. 21:48

elasticache는 save명령어가 disable되어있다. 

replica set으로 구성되어있어서 불필요한 disk 저장이 필요없기도 하거니와 save명령어는 synchronous 하기때문에 redis block을 초래하기 떄문일지도 모르겠다.

암튼, 혹 redis를 아마존 서비스를 이용해서가 아닌 그냥 ec2에 띄워서 쓰고 싶다면, 어쨌거나 data를 백업해서 가져와야하는데 save가 없으니 어떻게 하냐

redis-cli -h hostname sync > dump.rdb

명령어를 이용. (로컬에서 해봤더니 자체 sync만 동작하고 파일엔 데이터가 안써짐. 아무래도 remote host에 있는걸 여기로 sync한다는 것으로 remote에 있는 redis host를 써야하나봄)

아무튼 elasticache host는 위 명령어로 data를 backup할 수 있고 

redis.conf 파일에 셋팅된 dir 패스에 dump.rdb를 넣어놓고 redis를 다시 시작하면 쭉~ 들어간다.

'aws' 카테고리의 다른 글

kinesis firehose 삽질일기  (0) 2017.03.16
How to EC2 disk and memory usage monitoring  (0) 2015.03.27
[ubuntu server instance] mytoon setting  (0) 2014.10.24
HTTP 505: HTTP Version Not Supported  (0) 2014.07.09
boto s3 Broken pipe error  (0) 2014.04.25
블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,

celery 오해와 진실

celery 2015. 3. 13. 11:44

Python Celery를 보면 기본적으로 워커와 잡의 개념이기 때문에

일단 task를 요청하면 무조건 잡이 큐에 들어갈 것같다.

하지만 이건 오해다.


진실을 말하자면,

잡은 sync와 async로 요청을 할 수 있는데, 이때 sync로 요청하면 큐에 들어가지 않고 부른 프로세스에서 걍 처리한다. 

이렇게 직접 일을 처리하기위함도 있고 기타 등등의 설정을 유지하기 위해 워커뿐 아니라 잡을 요청하는 녀석도 celery app을 실행시키는 스크립트를 실행한다. (보통 celery.py 라고 명명하고 쓰는..)


그래서 주의할 것은

다이나믹 실행환경을 쓸경우 env라는 키를 만들어서 큐 Broker url을 동적으로 넣어줄 수 있는데, 이때 워커가 실행될때 설정되는것 이외에 잡을 던지는 녀석이 실행될때도 올바른 Broker url 이 들어가도록 해야한다는 것이다.

블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,

ssl setting

nginx 2015. 3. 12. 10:48

sites-available 에 ssl 파일을 만들어 다음을 추가한다.

server {

listen        443 ssl;

        root /usr/share/nginx/www;

keepalive_timeout         70;

server_name        any.yourdomain.com;

ssl_protocols               TLSv1 TLSv1.1 TLSv1.2;

        ssl_certificate             /etc/nginx/conf/self-cert.pem;

        ssl_certificate_key         /etc/nginx/conf/privkey.pem;

        ssl_session_cache           shared:SSL:10m;

        ssl_session_timeout         10m;

}

reference

http://nginx.org/en/docs/http/configuring_https_servers.html


블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,

1. crossdomain.xml Issue

-> your target server should offer this file via https(443 port) But not CA certificate needed. self-signed certificate is available.

<?xml version="1.0"?>

<cross-domain-policy>

<allow-access-from domain="*" to-ports="*" secure="false"/>

</cross-domain-policy>

-> I noticed that webPlayer send request for "crossdomain.xml" file via http not https. if your server domain "sub.yourdomain.com:9989", the webPlayer will send request to find "crossdomain.xml" via "sub.yourdomain.com:9989/crossdomain.xml"  

(So, I think "Https setting is not neccessary for crossdomain.xml)


2. explorer blocks post request.

-> check your headers, If there is an empty value on the key, The request could be blocked when using microsoft explorer.


3. (python tornado) request.arguments could be empty

-> just use request.body instead of arguments

블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,