def callback(photolog_id): """ twitter로부터 callback url이 요청되었을때 최종인증을 한 후 트위터로 해당 사진과 커멘트를 전송한다. """ Log.info("callback oauth_token:" + request.args['oauth_token']); Log.info("callback oauth_verifier:" + request.args['oauth_verifier']); # oauth에서 twiter로 부터 넘겨받은 인증토큰을 세션으로 부터 가져온다. OAUTH_TOKEN = session['OAUTH_TOKEN'] OAUTH_TOKEN_SECRET = session['OAUTH_TOKEN_SECRET'] oauth_verifier = request.args['oauth_verifier'] try: # 임시로 받은 인증토큰을 이용하여 twitter 객체를 만들고 인증토큰을 검증한다. twitter = Twython(current_app.config['TWIT_APP_KEY'], current_app.config['TWIT_APP_SECRET'], OAUTH_TOKEN, OAUTH_TOKEN_SECRET) final_step = twitter.get_authorized_tokens(oauth_verifier) # oauth_verifier를 통해 얻은 최종 인증토큰을 이용하여 twitter 객체를 새로 생성한다. twitter = Twython(current_app.config['TWIT_APP_KEY'], current_app.config['TWIT_APP_SECRET'], final_step['oauth_token'], final_step['oauth_token_secret']) session['TWITTER'] = twitter # 파라미터로 받은 photolog_id를 이용하여 해당 사진과 커멘트를 트위터로 전송한다. __send_twit(twitter, photolog_id) except TwythonError as e: Log.error("callback(): TwythonError , "+ str(e)) session['TWITTER_RESULT'] = str(e) return redirect(url_for('.show_all'))
def __oauth(photolog_id): """ twitter로부터 인증토큰을 받기 위한 함수 """ try: twitter = Twython(current_app.config['TWIT_APP_KEY'], current_app.config['TWIT_APP_SECRET']) callback_svr = current_app.config['TWIT_CALLBACK_SERVER'] auth = twitter.get_authentication_tokens( callback_url= callback_svr + \ url_for('.callback', photolog_id=photolog_id)) # 중간단계로 받은 임시 인증토큰은 최종인증을 위해 필요하므로 세션에 저장한다. session['OAUTH_TOKEN'] = auth['oauth_token'] session['OAUTH_TOKEN_SECRET'] = auth['oauth_token_secret'] except TwythonError as e: Log.error("__oauth(): TwythonError , "+ str(e)) session['TWITTER_RESULT'] = str(e) return redirect(url_for('.show_all')) # 트위터의 사용자 권한 인증 URL로 페이지를 리다이렉트한다. return redirect(auth['auth_url'])
def close_db_session(exception=None): """요청이 완료된 후에 db연결에 사용된 세션을 종료함""" try: dao.remove() except Exception as e: Log.error(str(e))
def register_user(): """포토로그 사용자 등록을 위한 함수""" form = RegisterForm(request.form) if form.validate(): username = form.username.data email = form.email.data password = form.password.data try: user = User(username, email, generate_password_hash(password)) dao.add(user) dao.commit() Log.debug(user) except Exception as e: error = "DB error occurs : " + str(e) Log.error(error) dao.rollback() raise e else: # 성공적으로 사용자 등록이 되면, 로그인 화면으로 이동. return redirect(url_for('.login', regist_username=username)) else: return render_template('regist.html', form=form)
def update_user(username): """포토로그 사용자 정보 수정을 위한 함수""" current_user = __get_user(username) form = UpdateForm(request.form) if form.validate(): email = form.email.data password = form.password.data try: current_user.email = email current_user.password = generate_password_hash(password) dao.commit() except Exception as e: dao.rollback() Log.error(str(e)) raise e else: # 변경된 사용자 정보를 세션에 반영 session['user_info'].email = \ current_user.email session['user_info'].password = \ current_user.password session['user_info'].password_confirm = \ current_user.password # 성공적으로 사용자 등록이 되면, 로그인 화면으로 이동. return redirect(url_for('.login', update_username=username)) else: return render_template('regist.html', user=current_user, form=form)
def update_photo(photolog_id): """ 사진 업로드 화면에서 사용자가 수정한 내용을 DB에 업데이트 한다. """ form = PhotoUploadForm(request.form) if form.validate(): #: 업데이트 대상 항목들 tag = form.tag.data comment = form.comment.data lat = form.lat.data lng = form.lng.data try : #: 변경전 원래의 photo 테이블 값을 읽어 온다. photo = dao.query(Photo).filter_by(id=photolog_id).first() #: 업데이트 값 셋팅 photo.tag = tag photo.comment = comment photo.geotag_lat = lat photo.geotag_lng = lng dao.commit() except Exception as e: dao.rollback() Log.error("Update DB error : " + str(e)) raise e return redirect(url_for('.show_all')) else: return render_template('upload.html', photo=photo, form=form)
def update_photo(photolog_id): """ 사진 업로드 화면에서 사용자가 수정한 내용을 DB에 업데이트 한다. """ form = PhotoUploadForm(request.form) if form.validate(): #: 업데이트 대상 항목들 tag = form.tag.data comment = form.comment.data lat = form.lat.data lng = form.lng.data try: #: 변경전 원래의 photo 테이블 값을 읽어 온다. photo = dao.query(Photo).filter_by(id=photolog_id).first() #: 업데이트 값 셋팅 photo.tag = tag photo.comment = comment photo.geotag_lat = lat photo.geotag_lng = lng dao.commit() except Exception as e: dao.rollback() Log.error("Update DB error : " + str(e)) raise e return redirect(url_for('.show_all')) else: return render_template('upload.html', photo=photo, form=form)
def register_user(): form = RegisterForm(request.form) if form.validate(): username = form.username.data email = form.email.data password = form.password.data try: user = User(username=username, email=email, password=generate_password_hash(password)) dao.add(user) dao.commit() Log.debug(user) except Exception as e: error = "DB error occurs: " + str(e) Log.error(error) dao.rollback() raise e else: return redirect(url_for('.login', register_user=username)) else: return render_template('../photolog/templates/regist.html', form=form)
def __get_user(username): try: current_user = dao.query(User).filter_by(username=username).first() Log.debug(current_user) return current_user except Exception as e: Log.error(str(e)) raise e
def login(): """아이디/비밀번호 기반의 로그인 기능을 제공함 로그인 성공 시 세션에 사용자 정보를 저장하여 사용함 """ form = LoginForm(request.form) next_url = form.next_url.data login_error = None if form.validate(): """ 세션 생성""" session.permanent = True username = form.username.data password = form.password.data next_url = form.next_url.data Log.info('(%s)next_url is %s' % (request.method, next_url)) try: user = dao.query(User). \ filter_by(username=username). \ first() except Exception as e: Log.error(str(e)) raise e if user: if not check_password_hash(user.password, password): login_error = 'Invalid password' else: # 세션에 추가할 정보를 session 객체의 값으로 추가함 # 가령, User 클래스 같은 사용자 정보를 추가하는 객체 생성하고 # 사용자 정보를 구성하여 session 객체에 추가 session['user_info'] = user if next_url != '': return redirect(next_url) else: return redirect(url_for('.index')) else: login_error = 'User does not exist!' return render_template('login.html', next_url=next_url, error=login_error, form=form)
def login(): """아이디/비밀번호 기반의 로그인 기능을 제공함 로그인 성공 시 세션에 사용자 정보를 저장하여 사용함 """ form = LoginForm(request.form) next_url = form.next_url.data login_error = None if form.validate(): session.permanent = True username = form.username.data password = form.password.data next_url = form.next_url.data Log.info('(%s)next_url is %s' % (request.method, next_url)) try: user = dao.query(User). \ filter_by(username=username). \ first() except Exception as e: Log.error(str(e)) raise e if user: if not check_password_hash(user.password, password): login_error = 'Invalid password' else: # 세션에 추가할 정보를 session 객체의 값으로 추가함 # 가령, User 클래스 같은 사용자 정보를 추가하는 객체 생성하고 # 사용자 정보를 구성하여 session 객체에 추가 session['user_info'] = user if next_url != '': return redirect(next_url) else: return redirect(url_for('.index')) else: login_error = 'User does not exist!' return render_template('login.html', next_url=next_url, error=login_error, form=form)
def decorated_function(*args, **kwargs): try: session_key = \ request.cookies.get(current_app.config['SESSION_COOKIE_NAME']) is_login = False if session.sid == session_key and \ session.__contains__('user_info') : is_login = True if not is_login: return redirect(url_for('.login_form', next=request.url)) return f(*args, **kwargs) except Exception as e: Log.error("while checking session, error occurs : %s" % str(e)) raise e
def decorated_function(*args, **kwargs): try: session_key = request.cookies.get( current_app.config['SESSION_COOKIE_NAME']) is_login = False if session.sid == session_key and session.__contains__( 'user_info'): is_login = True if not is_login: return redirect(url_for('.login_form', next=request.url)) return f(*args, **kwargs) except Exception as e: Log.error("Phtolog error occurs: %s" % str(e)) raise e
def make_thumbnails(filename): """ 업로드된 파일은 사이즈가 크기때문에 preview등에 사용하기 위해 썸네일 이미지를 생성한다. """ upload_folder = os.path.join(current_app.root_path, current_app.config['UPLOAD_FOLDER']) original_file = upload_folder+filename target_name = upload_folder+"thumb_"+filename try: #: PIL 라이브러리를 이용하여 썸네일 생성 im = Image.open(original_file) im = im.convert('RGB') im.thumbnail((300,300), Image.ANTIALIAS) im.save(target_name) except Exception as e: Log.error("Thumbnails creation error : " + target_name+" , "+str(e)) raise e
def __send_twit(twitter, photolog_id): """ 실제로, photolog_id에 해당하는 사진과 커멘트를 트위터로 전송하는 내부 함수 """ try: photo_info = get_photo_info(photolog_id) download_filepath = photo_info[2] photo_comment = photo_info[3] photo = open(download_filepath, 'rb') twitter.update_status_with_media(status=photo_comment, media=photo) session['TWITTER_RESULT'] = 'ok' except IOError as e: Log.error("send(): IOError , " + str(e)) session['TWITTER_RESULT'] = str(e) except TwythonError as e: Log.error("send(): TwythonError , " + str(e)) session['TWITTER_RESULT'] = str(e)
def unregist(): user_id = session['user_info'].id try: user = dao.query(User).filter_by(id=user_id).first() Log.info("unregist:"+user.username) if user.id == user_id: dao.delete(user) # 업로드된 사진 파일 삭제 try: upload_folder = \ os.path.join(current_app.root_path, current_app.config['UPLOAD_FOLDER']) __delete_files(upload_folder, user.username) except Exception as e: Log.error("파일 삭제에 실패했습니다. : %s" + \ str(e)) dao.commit() else: Log.error("존재하지 않는 사용자의 탈퇴시도 : %d", user_id) raise Exception except Exception as e: Log.error(str(e)) dao.rollback() raise e # else: return redirect(url_for('.leave'))
def unregist(): user_id = session['user_info'].id try: user = dao.query(User).filter_by(id=user_id).first() Log.info("unregist:"+user.username) if user.id == user_id: dao.delete(user) # 업로드된 사진 파일 삭제 try: upload_folder = \ os.path.join(current_app.root_path, current_app.config['UPLOAD_FOLDER']) __delete_files(upload_folder, user.username) except Exception as e: Log.error("파일 삭제에 실패했습니다. : %s" + \ str(e)) dao.commit() else: Log.error("존재하지 않는 사용자의 탈퇴시도 : %d", user_id) raise Exception except Exception as e: Log.error(str(e)) dao.rollback() raise e # else: return redirect(url_for('.logout'))
def login(): form = LoginForm(request.form) next_url = form.next_url.data login_error = None if form.validate(): session.permanent = True username = form.username.data password = form.password.data next_url = form.next_url.data Log.info('(%s)next_url is %s' % (request.method, next_url)) try: user = dao.query(User).filter_by(username=username).first() except Exception as e: Log.error(str(e)) raise e if user: if not check_password_hash(user.password, password): login_error = 'Invalid password' else: session['user_info'] = user if next_url != '': return redirect(next_url) else: return redirect(url_for('.index')) else: login_error = 'User does not exist!' return render_template('../photolog/templates/login.html', next_url=next_url, error=login_error, form=form)
def remove(photolog_id): """ DB에서 해당 데이터를 삭제하고 관련된 이미지파일을 함께 삭제한다.""" user_id = session['user_info'].id try: photo = dao.query(Photo).filter_by(id=str(photolog_id)).first() dao.delete(photo) dao.commit() upload_folder = os.path.join(current_app.root_path, current_app.config['UPLOAD_FOLDER']) os.remove(upload_folder + str(photo.filename)) os.remove(upload_folder + "thumb_"+str(photo.filename)) except Exception as e: dao.rollback() Log.error("Photo remove error => " + photolog_id + ":" + user_id + \ ", " + str(e)) raise e return redirect(url_for('.show_all'))
def remove(photolog_id): """ DB에서 해당 데이터를 삭제하고 관련된 이미지파일을 함께 삭제한다.""" user_id = session['user_info'].id try: photo = dao.query(Photo).filter_by(id=str(photolog_id)).first() dao.delete(photo) dao.commit() upload_folder = os.path.join(current_app.root_path, current_app.config['UPLOAD_FOLDER']) os.remove(upload_folder + str(photo.filename)) os.remove(upload_folder + "thumb_" + str(photo.filename)) except Exception as e: dao.rollback() Log.error("Photo remove error => " + photolog_id + ":" + user_id + \ ", " + str(e)) raise e return redirect(url_for('.show_all'))
def upload_photo(): """ Form으로 파일과 변수들을 DB에 저장하는 함수. """ form = PhotoUploadForm(request.form) # HTTP POST로 요청이 오면 사용자 정보를 등록 if form.validate(): #: Session에 저장된 사용자 정보를 셋팅 user_id = session['user_info'].id username = session['user_info'].username #: Form으로 넘어온 변수들의 값을 셋팅함 tag = form.tag.data comment = form.comment.data lat = form.lat.data lng = form.lng.data upload_date = datetime.today() try: #: Exif에서 전달받은 data 형식을 파이썬 date 객체로 변환 taken_date = datetime.strptime(form.taken_date.data, "%Y:%m:%d %H:%M:%S") except: #: date 포맷 예외 발생: exif가 없거나, #: 사진찍은 시간이 없는 경우에는 현재시간으로 대체 taken_date = datetime.today() #: 업로드되는 파일정보 값들을 셋팅한다. upload_photo = request.files['photo'] filename = None filesize = 0 filename_orig = upload_photo.filename try: #: 파일 확장자 검사 : 현재 jpg, jpeg만 가능 if upload_photo and __allowed_file(upload_photo.filename): ext = (upload_photo.filename).rsplit('.', 1)[1] #: 업로드 폴더 위치는 얻는다. upload_folder = \ os.path.join(current_app.root_path, current_app.config['UPLOAD_FOLDER']) #: 유일하고 안전한 파일명을 얻는다. filename = \ secure_filename(username + '_' + unicode(uuid.uuid4()) + "." + ext) upload_photo.save(os.path.join(upload_folder, filename)) filesize = \ os.stat(upload_folder + filename).st_size #: 썸네일을 만든다. make_thumbnails(filename) else: raise Exception("File upload error : illegal file.") except Exception as e: Log.error(str(e)) raise e try: #: 사진에 대한 정보 DB에 저장 photo = Photo(user_id, tag, comment, filename_orig, filename, filesize, lat, lng, upload_date, taken_date) dao.add(photo) dao.commit() except Exception as e: dao.rollback() Log.error("Upload DB error : " + str(e)) raise e return redirect(url_for('.show_all')) else: return render_template('upload.html', form=form)
def upload_photo(): """ Form으로 파일과 변수들을 DB에 저장하는 함수. """ form = PhotoUploadForm(request.form) # HTTP POST로 요청이 오면 사용자 정보를 등록 if form.validate(): #: Session에 저장된 사용자 정보를 셋팅 user_id = session['user_info'].id username = session['user_info'].username #: Form으로 넘어온 변수들의 값을 셋팅함 tag = form.tag.data comment =form.comment.data lat = form.lat.data lng = form.lng.data upload_date = datetime.today() try: #: Exif에서 전달받은 data 형식을 파이썬 date 객체로 변환 taken_date = datetime.strptime(form.taken_date.data, "%Y:%m:%d %H:%M:%S") except : #: date 포맷 예외 발생: exif가 없거나, #: 사진찍은 시간이 없는 경우에는 현재시간으로 대체 taken_date = datetime.today() #: 업로드되는 파일정보 값들을 셋팅한다. upload_photo = request.files['photo'] filename = None filesize = 0 filename_orig = upload_photo.filename try: #: 파일 확장자 검사 : 현재 jpg, jpeg만 가능 if upload_photo and __allowed_file(upload_photo.filename): ext = (upload_photo.filename).rsplit('.', 1)[1] #: 업로드 폴더 위치는 얻는다. upload_folder = \ os.path.join(current_app.root_path, current_app.config['UPLOAD_FOLDER']) #: 유일하고 안전한 파일명을 얻는다. filename = \ secure_filename(username + '_' + unicode(uuid.uuid4()) + "." + ext) upload_photo.save(os.path.join(upload_folder, filename)) filesize = os.stat(upload_folder + filename).st_size #: 썸네일을 만든다. make_thumbnails(filename) else: raise Exception("File upload error : illegal file.") except Exception as e: Log.error(str(e)) raise e try : #: 사진에 대한 정보 DB에 저장 photo = Photo(user_id, tag, comment, filename_orig, filename, filesize, lat, lng, upload_date, taken_date) dao.add(photo) dao.commit() except Exception as e: dao.rollback() Log.error("Upload DB error : " + str(e)) raise e return redirect(url_for('.show_all')) else: return render_template('upload.html', form=form)