For few days, i was trying to apply multitouch on my application(game). My application uses multiple views and I want that the user can touch each view at the same time.
my code for single touch was...
onTouch(Veiw v, MotionEvent event){
if(v==button1){
....
} else if(v==button2){
......
}
}
this style worked for single touch perfectly. So I could never doubt this won't differ the view I touched secondly(and more). But this method couldn't.
I'm not very well skilled programmer so not sure about there would be my fault. but for the if anybody has the same problem, just use "onTouchEvent(MotionEvent event)" and classify view by the position.
Dedicated to Korea (South)
2012년 2월 8일 수요일
2012년 1월 30일 월요일
Accident on The Music Trend
There was hu~ge accident on one of main South Korean TV channel SBS 2 days ago. The Music Trend was on air like any other Sunday afternoon. But the problem was,,, while there was a performance of popular idol group T-ara, one of the 18-year-old member Hwayoung's cloth has been slipped and it was broadcasted live..
The song was "Lovey Dovey" and in the song T-ara dances shuffling(according to their management agency Core Contents Medias). Because she dances so tough, the accident happened according to the press.
It seems to be very painful for her because her pictures are spread on the Internet specially many masculine gag sites(ridiculous edited pics). South Korea has insane network bandwidth so anyone can download it in minutes.
In my memory, it's the first time that South Korean main TV station broadcasts female's nipple on air. "화영 인기가요" translated to "Hwayoung The Music Trend" is still the top search word on Korean leading portal site Naver.
begin
Today I'm very surprised that 100 guys have visited my blog.
This blog now has nothing but from today, I'll write many dedicated things about South Korea and my programming life.
I really appreciate your visiting.
p.s. - If you were a native English speaker and found some wired expression from my blog, please tell me for my English study. I'll be really happy :)
This blog now has nothing but from today, I'll write many dedicated things about South Korea and my programming life.
I really appreciate your visiting.
p.s. - If you were a native English speaker and found some wired expression from my blog, please tell me for my English study. I'll be really happy :)
2011년 9월 29일 목요일
replyingtv - index.py
이 프로그램의 메인인 모듈인 index.py를 살펴보겠습니다.
시간에 쫓겨 만들다보니 생각하던 것 보단 지저분한 코드가 나왔는데요, 하나하나 살펴보겠습니다.
def userLogging(self) - 앱엔진에서 제공하는 구글 id 로그인 모듈입니다. self클래스를 받아 로그인url과 문자열 login/logout을 리턴합니다. url은 나중에 index.html에서 로그인 url로써 쓰이고, 문자열login/logout은 역시 index.html에서 링크를 나타낼 때 쓰일 문자열입니다.
def dateChanged(now) - datetime인 now를 입력받아 편성표의 날짜가 바뀌었으면 True, 아니면 False를 리턴합니다.
def getBroadcastingProgramNow(broadcastingChannel) - broadCastingChannel을 입력받아 현재 채널의 방송중인 프로그램을 찾아 ProgramGuide 인스턴스를 리턴해줍니다.
class RecentCommentsPage(webapp.RequestHandler) - /comment 페이지의get메시지를 처리해줍니다. 코멘트를 위한 gql query를 보낸 후 최근의 30개만 보여줍니다.
class MainPage(webapp.RequestHandler) - 루트 페이지로 들어오는 get 및 post를 처리해줍니다. get 함수에선 Program 인스턴스를 등록해줍니다. post함수에선 html을 통해 들어온 새로운 comment를 등록해줍니다.
class ApplyingForm(djangoforms.ModelForm) - 장고의 모델폼을 상속하여, 폼을 등록하는데 사용하는 클래스입니다.
class TextPage(webapp.RequestHandler) - 이 블로그로 redirect해주는 클래스입니다.
def main() - WSGIApplication으로 각각의 페이지들을 유도해줍니다.
# -*- coding: utf-8 -*- ''' Created on 2011. 9. 14. @author: Taejun Park ''' from datetime import datetime, timedelta import os import logging from google.appengine.api import memcache from google.appengine.api import users from google.appengine.ext import webapp from google.appengine.ext import db from google.appengine.ext.webapp import template from google.appengine.ext.webapp.util import run_wsgi_app from google.appengine.ext.db import djangoforms #I made import model import getPrograms #not yet attached from django.utils import simplejson as json def userLogging(self): """ Args: self: page handler Returns: Logout(in) URL as a string, 'Login(out)' """ if users.get_current_user(): return users.create_logout_url(self.request.uri), 'Logout' else: return users.create_login_url(self.request.uri), 'Login' def dateChanged(now): """ Args: now : Datetime class Returns: True if changed, False if not it checks wheather correct date was saved in the memcache/Parameter after it works, can use correct date guide """ today = now.date() programGuideDate = memcache.get("programGuideDate") #if memcache is empty if programGuideDate is None: parameter = model.Parameter.get_by_key_name(key_names='day') if parameter is None: #if it is the first run model.Parameter(key_name='day', date=today ).put() if not memcache.add("programGuideDate", today): #save into memcache logging.error("Memcache set failed") return True programGuideDate = parameter.date if not memcache.add("programGuideDate", programGuideDate): logging.error("Memcache set failed") if today > programGuideDate: #if date changed #if now is after 4AM or more than 2days after if now.hour > 4 or today-programGuideDate > timedelta(1): model.Parameter(key_name='day', date=today).put() if not memcache.add("programGuideDate", today): logging.error("Memcache set failed") return True #if not new day or tomorrow before 4am return False def getBroadcastingProgramNow(broadcastingChannel): """ Arg: broadcastingChannel : only KBS1 or KBS2 is supported now Return: ProgramGuide instance in this method, programLists: [program title+datetime] lists program = title+datetime+channel """ now = datetime.now() if dateChanged(now): #if date changed, delete yesterday's program guide db with the same channel db.delete(model.ProgramGuide.gql("WHERE channel = :1", broadcastingChannel)) #getPrograms returns [programtitle,datetime] as a list programLists = getPrograms.getPrograms(broadcastingChannel) #programs is list #parse programLists. the program name was got from KBS hompage so the encoding is euckr for program in programLists: model.ProgramGuide(key_name=program[0].decode('euckr', 'ignore'), programTime=program[1], channel=broadcastingChannel).put() #get if from db to match the type the same programs = model.ProgramGuide.gql("WHERE channel = :1 ORDER BY programTime ASC", broadcastingChannel) if not memcache.add(broadcastingChannel, programs): logging.error("Memcache set failed") else: #check if the time pasts programs = memcache.get(broadcastingChannel) if programs is None: #if memcache is empty, get it from db, add it to the memcache programs = model.ProgramGuide.gql("WHERE channel = :1 ORDER BY programTime ASC", broadcastingChannel) if not memcache.add(broadcastingChannel, programs): logging.error("Memcache set failed") #for ordered for clause. for more information, visit: #http://code.google.com/intl/ko-KR/appengine/docs/python/datastore/queries.html#Query_Cursors start_cursor = memcache.get("program_start_cursor") end_cursor = memcache.get("program_end_cursor") if start_cursor: programs.with_cursor(start_cursor = start_cursor) if end_cursor: programs.with_cursor(end_cursor = end_cursor) for program in programs: if program.programTime > now : #if there's no program matches, it means there's no program now so return "화면조정" if not memcache.add("program_start_cursor", start_cursor): logging.error("Memcache set failed") return program return None class RecentCommentsPage(webapp.RequestHandler): """this class get 30 comments from db and match it for comments.html """ def get(self): url, url_linktext = userLogging(self) comments = model.Comment.all().order('-written_datetime').fetch(30) username = users.get_current_user() template_values={ 'username':username, 'url':url, 'url_linktext':url_linktext, 'comments':comments, } path=os.path.join(os.path.dirname(__file__), 'comments.html') self.response.out.write(template.render(path, template_values)) class MainPage(webapp.RequestHandler): """get which channel user want. then get what program is running now. get comments for the program send them to index.html """ def get(self): #because there are not enough webpages, this program can only run over the KBSs. if self.request.path == '/2tv': channel = 'KBS2' else: channel = 'KBS1' #get what program is running. probramNow programGuide Instance programNow=getBroadcastingProgramNow(channel) if programNow is not None: programInstance = model.Program.get_or_insert(key_name=programNow.key().name(), channel=channel) comments = model.Comment.gql("WHERE program = :program ORDER BY written_datetime DESC", program=programInstance).fetch(5) program = programNow.key().name() else: comments = None program = None #make user signing up url url, url_linktext = userLogging(self) #HTML forms for POST form = ApplyingForm() username = users.get_current_user() template_values={ 'channel':channel, 'head_title': '프로그램 목록', 'page_title': 'TV 프로그램 댓글', 'program': program, 'username': username, 'url':url, 'url_linktext':url_linktext, 'form': form, 'comments': comments } path=os.path.join(os.path.dirname(__file__), 'index.html') self.response.out.write(template.render(path, template_values)) #see http://code.google.com/intl/ko-KR/appengine/articles/djangoforms.html def post(self): #get POST requests data = ApplyingForm(data=self.request.POST) if data.is_valid(): entity=data.save(commit=False) #get commenter: now this program saves email address of current user entity.commenter = users.get_current_user().email() entity.written_datetime =datetime.now() entity.written_via = 'replyingTV' #later would be another platform #get program name from the web page, and get the model reference matches #first from the memcache, sencond from the db programNow = self.request.get('program') programInstance = memcache.get(programNow) if not programInstance: programInstance = model.Program.get_by_key_name(programNow) entity.program = programInstance try: entity.put() #save except : print "don't type that long, plz less than 500 bytes" finally: #redirect it to 2tv if it was from 2tv if self.request.get('channel') == 'KBS2': self.redirect('/2tv', permenent=True) self.redirect('') else: #redirect it to 2tv if it was from 2tv if self.request.get('channel') == 'KBS2': self.redirect('/2tv', permenent=True) self.redirect('') class ApplyingForm(djangoforms.ModelForm): """this class makes form for the Comment model see http://code.google.com/intl/ko-KR/appengine/articles/djangoforms.html """ class Meta: model = model.Comment exclude=['commenter', 'written_datetime', 'program', 'written_via'] class TextPage(webapp.RequestHandler): """link to the replyingtv-program guide page """ def get(self): self.redirect("http://tj850413.blogspot.com/", permanent=True) def main(): application = webapp.WSGIApplication([ ('/about', TextPage), ('/2tv', MainPage), ('/comment', RecentCommentsPage), ('/.*', MainPage), ], debug=True) run_wsgi_app(application) if __name__ == '__main__': main()
시간에 쫓겨 만들다보니 생각하던 것 보단 지저분한 코드가 나왔는데요, 하나하나 살펴보겠습니다.
def userLogging(self) - 앱엔진에서 제공하는 구글 id 로그인 모듈입니다. self클래스를 받아 로그인url과 문자열 login/logout을 리턴합니다. url은 나중에 index.html에서 로그인 url로써 쓰이고, 문자열login/logout은 역시 index.html에서 링크를 나타낼 때 쓰일 문자열입니다.
def dateChanged(now) - datetime인 now를 입력받아 편성표의 날짜가 바뀌었으면 True, 아니면 False를 리턴합니다.
def getBroadcastingProgramNow(broadcastingChannel) - broadCastingChannel을 입력받아 현재 채널의 방송중인 프로그램을 찾아 ProgramGuide 인스턴스를 리턴해줍니다.
class RecentCommentsPage(webapp.RequestHandler) - /comment 페이지의get메시지를 처리해줍니다. 코멘트를 위한 gql query를 보낸 후 최근의 30개만 보여줍니다.
class MainPage(webapp.RequestHandler) - 루트 페이지로 들어오는 get 및 post를 처리해줍니다. get 함수에선 Program 인스턴스를 등록해줍니다. post함수에선 html을 통해 들어온 새로운 comment를 등록해줍니다.
class ApplyingForm(djangoforms.ModelForm) - 장고의 모델폼을 상속하여, 폼을 등록하는데 사용하는 클래스입니다.
class TextPage(webapp.RequestHandler) - 이 블로그로 redirect해주는 클래스입니다.
def main() - WSGIApplication으로 각각의 페이지들을 유도해줍니다.
replyingtv - html파일들
replyingtv의 index.html입니다.
css등은 적용되지 않았고, template를 적용시키는 내용 외엔 복잡한 태그는 쓰이지 않았습니다.
앞부분에선 for문으로 comments를 통해 얻어온 내용들을 뿌려주며
아래쪽에선 user가 로그인해있고 program이 None이 아니면 comment입력 form을 형성해줍니다.
앱엔진에서 지원해주는 구글 로그인 url을 넣어주어 로그인했을 시엔 logout 링크가, 반대일때는 login이 뜨도록 하였습니다.
그 아래엔 최근 댓글들을 보여주는 링크가 있고
그 다음으론 이 블로그로 통하는 링크를 넣어주어습니다.
다음은 comments.html입니다.
여기에선 comment를 뿌려주는 일 외엔 별다른 설명할 부분이 없는 것 같습니다.
css등은 적용되지 않았고, template를 적용시키는 내용 외엔 복잡한 태그는 쓰이지 않았습니다.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-16" />
<title>{{ head_title }} - 현재 사용자: {{ username }}</title>
</head>
<body>
{{ program }} 이 현재 방영되고 있습니다 | {{ channel }}
<h1>{{ page_title }}</h1>
<ul>{% for comment in comments %}
<li>{{ comment.commenter }}
{{ comment.written_datetime }} written via: {{ comment.written_via }}
{{ comment.text }}
<p/>
</li>
{% endfor %}
</ul>
{% if username and program %}
<table border="1" align="center">
<tr>
<td width="100" align="center">사용자:</td>
<td>{{ username }}</td>
</tr>
<tr >
<form method="post" action="." >
{{ form.as_table }}
<input type="hidden" name="program" value="{{ program }}">
</form>
</tr>
<tr>
</tr>
</table>
{% else %}{% if not program %}
<p>현재 방송중인 프로그램을 얻을 수 없습니다</p>
{% else %}
<p>로그인 하세요</p>
{% endif %}{% endif %}
<a href="{{ url }}">{{ url_linktext }}</a> |
<a href="/comment">최근 댓글 페이지</a>
<h2><a href="http://tj850413.blogspot.com/"> 이 사이트에 대하여</a></h2>
</body>
</html>
앞부분에선 for문으로 comments를 통해 얻어온 내용들을 뿌려주며
아래쪽에선 user가 로그인해있고 program이 None이 아니면 comment입력 form을 형성해줍니다.
앱엔진에서 지원해주는 구글 로그인 url을 넣어주어 로그인했을 시엔 logout 링크가, 반대일때는 login이 뜨도록 하였습니다.
그 아래엔 최근 댓글들을 보여주는 링크가 있고
그 다음으론 이 블로그로 통하는 링크를 넣어주어습니다.
다음은 comments.html입니다.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>최근 댓글 페이지 {{ username }}</title>
</head>
<body>
<h1>최근에 등록 된 댓글 30개</h1>
<ul>{% for comment in comments %}
<li>{{ comment.text }} |
{{ comment.commenter }}
{{ comment.program.key.name }}
{{ comment.written_datetime }} written via: {{ comment.written_via }}
<p/>
</li>
{% endfor %}
</ul>
<a href="{{ url }}">{{ url_linktext }}</a> |
<a href="/">main page</a>
</body>
</html>
여기에선 comment를 뿌려주는 일 외엔 별다른 설명할 부분이 없는 것 같습니다.
2011년 9월 30일 10시 40분 에러발생으로
갑자기 replyingtv가 에러가 발생해서 홈페이지를 이쪽으로 돌려놨습니다ㅠ
이번에도 로컬호스트에선 돌아가는데 앱엔진쪽엔 문제가 있네요... 고치고 있으니 나중에 다시 들려주세요ㅠㅠㅠ
http://replyingtv.appspot.com/2tv
를 들리시면 현재 상태를 아실 수 있습니다
이번에도 로컬호스트에선 돌아가는데 앱엔진쪽엔 문제가 있네요... 고치고 있으니 나중에 다시 들려주세요ㅠㅠㅠ
http://replyingtv.appspot.com/2tv
를 들리시면 현재 상태를 아실 수 있습니다
2011년 9월 28일 수요일
replyingtv - model.py
replyingtv의 소스코드 중 모델 선언부분인 model.py를 살펴보겠습니다.
별다른 어려운 부분은 없지만, Parameter 클래스는 변수 몇가지를 저장하기 위해 모델을 만들어 쓰게 돼서, 다른 방법이 없을까 하는 생각도 들었습니다만 뾰족한 방법을 모르겠네요
# -*- coding: utf-8 -*- ''' Created on 2011. 9. 8. @author: Park ''' from google.appengine.ext import db class Program(db.Model): """this class saves the program titles, channel and the date which the program instance made """ channel = db.StringProperty() date = db.DateTimeProperty(auto_now_add=True) class Comment(db.Model): """this class saves comments program references the Program class. written_via is for the multi-platform extension.(ex i-phone, LGtv etc """ #if there would be another platform, 'commenter' should be changed as string or etc for many format commenter = db.EmailProperty() written_datetime = db.DateTimeProperty() program = db.ReferenceProperty(Program) written_via = db.StringProperty() text = db.StringProperty() class Parameter(db.Model): """this class is for saving some parameters which need to run the whole program. 2011.09.29: now only has date. """ date = db.DateProperty() class ProgramGuide(db.Model): """it saves the channel guide today. channel and program time, and the title as a key_name. """ programTime = db.DateTimeProperty() channel = db.StringProperty(multiline=True) #ex) kbs1, kbs2 ...
별다른 어려운 부분은 없지만, Parameter 클래스는 변수 몇가지를 저장하기 위해 모델을 만들어 쓰게 돼서, 다른 방법이 없을까 하는 생각도 들었습니다만 뾰족한 방법을 모르겠네요
피드 구독하기:
덧글 (Atom)