def run(self, imp_id): from importer.models import Importer imp = Importer.objects.get(id=imp_id) ts = get_timestamp() if imp.started and not imp.ended: # TODO : 시간 체크가 아니라 실제 celery task 가 실행되고 있는지를 확인하는 구현으로 변경 if ts - imp.started < 12 * 60 * 60 * 1000: return False result = True imp.started = ts imp.ended = None imp.save() # 현재는 ImporterTask 가 하는 일은 없다 # TODO : 향후 iplace 를 물리적 혹은 User vds 들을 합친 VD 등을 생성하는 튜닝 진행 시 추가 구현 필요 # ProxyTask 처리 try: r = imp.publisher.start() if r.failed(): print('ImporterTask : if r.failed()') result = False except: print('ImporterTask : except') result = False imp.ended = get_timestamp() imp.save() return result
def test_json(self): test_data = 'http://blogthumb2.naver.net/20160302_285/mardukas_1456922688406bYGAH_JPEG/DSC07301.jpg' img, is_created = Image.get_or_create_smart(test_data) img.summarize() self.assertIn('uuid', img.json) self.assertIn('content', img.json) self.assertNotIn('note', img.json) self.assertNotIn('timestamp', img.json) self.assertIn('summary', img.json) img.timestamp = get_timestamp() inote = ImageNote(content='img note') inote.save() img.note = inote self.assertIn('uuid', img.json) self.assertIn('content', img.json) self.assertIn('note', img.json) #self.assertIn('timestamp', img.json) self.assertIn('summary', img.json) self.assertIn('uuid', img.json['note']) self.assertIn('content', img.json['note']) self.assertNotIn('timestamp', img.json['note']) inote.timestamp = get_timestamp() self.assertIn('uuid', img.json['note']) self.assertIn('content', img.json['note']) self.assertIn('timestamp', img.json['note']) saved = Image.get_from_json(img.json) self.assertEqual(saved, img) self.assertEqual(saved.note, img.note)
def run(self, proxy_id): from importer.models import Proxy proxy = Proxy.objects.get(id=proxy_id) ts = get_timestamp() if proxy.started and not proxy.ended: # TODO : 시간 체크가 아니라 실제 celery task 가 실행되고 있는지를 확인하는 구현으로 변경 if ts - proxy.started < 12 * 60 * 60 * 1000: return False result = True proxy.started = ts proxy.ended = None proxy.save() # guide 에 따른 분기 처리 guide_type = proxy.guide['type'] if guide_type == 'nothing': pass elif guide_type == 'user': # TODO : 향후엔 별도로 생성한 VD 에 해당 유저의 uplace 정보를 모으는 형태의 튜닝 필요할지도... result = True elif guide_type == 'images': task = ImagesProxyTask() result = task.run(proxy) else: print('ProxyTask : else') result = False proxy.ended = get_timestamp() proxy.save() return result
def test_created_modified(self): uplace = UserPlace(vd=self.vd, place=self.place) self.assertEqual(uplace.created, None) self.assertEqual(uplace.modified, None) uplace.save() t1 = uplace.modified self.assertNotEqual(t1, None) self.assertEqual(uplace.created, t1) self.assertAlmostEqual(t1, get_timestamp(), delta=1000) uplace.save() self.assertGreater(uplace.modified, t1) self.assertAlmostEqual(uplace.modified, t1, delta=1000) self.assertEqual(uplace.created, t1) t2 = get_timestamp() uplace.save(timestamp=t2) self.assertEqual(uplace.modified, t2) self.assertEqual(uplace.created, t1)
def test_string_representation(self): lonLat = GEOSGeometry('POINT(127.1037430 37.3997320)', srid=4326) timestamp = get_timestamp() vd_id = self.vd_id tracking = Tracking.create(vd_id, lonLat, timestamp) self.assertEqual( unicode(tracking), "VD(id=%d)'s Tracking(lat=%0.6f, lon=%0.6f)" % (vd_id, lonLat.y, lonLat.x))
def create(self, request, *args, **kwargs): vd = self.vd if not vd: return Response(status=status.HTTP_401_UNAUTHORIZED) v = json_loads(request.data['value']) lonLat = GEOSGeometry('POINT(%f %f)' % (v['lon'], v['lat']), srid=4326) timestamp = request.data.get('timestamp', get_timestamp()) instance = Tracking.create(vd.id, lonLat, timestamp) serializer = self.get_serializer(instance) return Response(serializer.data, status=status.HTTP_201_CREATED)
def test_id_property_with_timestamp(self): pp = PostPiece(vd=self.vd) timestamp = get_timestamp() pp.save(timestamp=timestamp) self.assertEqual((int(pp.id) >> 8 * 8) & BIT_ON_8_BYTE, timestamp) self.assertEqual((int(pp.id) >> 2 * 8) & BIT_ON_6_BYTE, self.vd.id) saved = PostPiece.objects.first() self.assertEqual(saved, pp) self.assertEqual(saved.id, pp.id)
def test_id_property_with_timestamp(self): uplace = UserPlace(vd=self.vd) timestamp = get_timestamp() uplace.save(timestamp=timestamp) self.assertEqual((int(uplace.id) >> 8 * 8) & BIT_ON_8_BYTE, timestamp) self.assertEqual((int(uplace.id) >> 2 * 8) & BIT_ON_6_BYTE, self.vd.id) saved = UserPlace.objects.first() self.assertEqual(saved, uplace) self.assertEqual(saved.id, uplace.id)
def add_access_history(self, uplaces): if not self.accessHistory: self.accessHistory = dict(uplaces=[]) if not type(uplaces) is list: uplaces = [uplaces] for uplace in uplaces: uuid = uplace.uuid timestamp = get_timestamp() self.accessHistory['uplaces'].insert( 0, dict(uuid=uuid, timestamp=timestamp)) super(VD, self).save()
def test_basic(self): guide_json = '{"type": "nothing"}' self.imp.publisher.guide = guide_json self.imp.publisher.save() ts = get_timestamp() r = self.imp.start() self.assertEqual(r.state, 'SUCCESS') self.assertEqual(r.result, True) self.imp = self.imp.reload() self.assertAlmostEqual(self.imp.started, ts, delta=1000) self.assertAlmostEqual(self.imp.ended, ts, delta=1000) self.assertGreater(self.imp.ended, self.imp.started)
def create(cls, vd_id, lonLat, timestamp=None): from uuid import UUID if not vd_id: raise ValueError if not timestamp: timestamp = get_timestamp() # TODO : 남은 하위 2byte 활용 hstr = hex((vd_id << 10 * 8) | (timestamp << 2 * 8) | 0)[2:-1] # 끝에 붙는 L 을 떼내기 위해 -1 _id = UUID(hstr.rjust(32, b'0')) instance = Tracking.objects.create(id=_id, lonLat=lonLat) return instance
def save(self, *args, **kwargs): self.modified = kwargs.pop('timestamp', get_timestamp()) if not self.id: self.id = self._id(self.modified) if not self.lonLat: self.lonLat = (self.place and self.place.lonLat) or None if not self.mask: self.mask = 0 if self.parent: if not self.parent.is_parent: self.parent.is_parent = True self.parent.save() super(UserPlace, self).save(*args, **kwargs)
def save(self, *args, **kwargs): if not self.id: timestamp = kwargs.pop('timestamp', get_timestamp()) self.id = self._id(timestamp) self.process_tag() if not self.mask: self.mask = 0 if not self.place and (self.uplace and self.uplace.place): self.place = self.uplace.place # Machine 이 포스팅한 경우 vd를 None 으로. 단, vd값이 넘어온 경우 id값 계산시엔 활용 (위에서 이미 id 계산) if self.by_MAMMA: self.vd = None super(PostPiece, self).save(*args, **kwargs)
def test_save_and_retreive(self): lonLat = GEOSGeometry('POINT(127.1037430 37.3997320)', srid=4326) timestamp = get_timestamp() vd_id = self.vd_id vd = VD.objects.get(id=vd_id) self.assertEqual(Tracking.objects.count(), 0) tracking = Tracking.create(vd_id, lonLat, timestamp) self.assertEqual(Tracking.objects.count(), 1) self.assertEqual(tracking.vd_id, vd_id) self.assertEqual(tracking.created, timestamp) self.assertEqual(tracking.vd, vd) saved = Tracking.objects.first() self.assertEqual(saved, tracking) self.assertEqual(saved.vd_id, vd_id) self.assertEqual(saved.created, timestamp) self.assertEqual(saved.vd, vd)
def test_import_images(self): # data μΈν # importer task test guide_json = '{"type": "images", "vd": "myself"}' self.imp.publisher.guide = guide_json self.imp.publisher.save() self.imp.publisher.vd.parent = self.subscriber self.imp.publisher.vd.save() ts = get_timestamp() r = self.imp.start() self.assertEqual(r.state, 'SUCCESS') self.assertEqual(r.result, True) self.imp = self.imp.reload() self.assertAlmostEqual(self.imp.started, ts, delta=1000) self.assertAlmostEqual(self.imp.ended, ts, delta=1000) self.assertGreater(self.imp.ended, self.imp.started)
def test_id_property(self): pp = PostPiece(vd=self.vd) self.assertEqual(pp.id, None) timestamp = get_timestamp() pp.save() self.assertNotEqual(pp.id, None) self.assertAlmostEqual((int(pp.id) >> 8 * 8) & BIT_ON_8_BYTE, timestamp, delta=1000) self.assertEqual((int(pp.id) >> 2 * 8) & BIT_ON_6_BYTE, self.vd.id) saved = PostPiece.objects.first() self.assertEqual(saved, pp) self.assertEqual(saved.id, pp.id) # for timestamp property self.assertEqual(saved.timestamp, pp.timestamp) self.assertAlmostEqual(pp.timestamp, timestamp, delta=1000)
def test_id_property(self): uplace = UserPlace(vd=self.vd) self.assertEqual(uplace.id, None) timestamp = get_timestamp() uplace.save() self.assertNotEqual(uplace.id, None) self.assertAlmostEqual((int(uplace.id) >> 8 * 8) & BIT_ON_8_BYTE, timestamp, delta=1000) self.assertEqual((int(uplace.id) >> 2 * 8) & BIT_ON_6_BYTE, self.vd.id) saved = UserPlace.objects.first() self.assertEqual(saved, uplace) self.assertEqual(saved.id, uplace.id) # for timestamp property self.assertEqual(uplace.created, uplace.modified) self.assertEqual(saved.created, uplace.created) self.assertEqual(saved.modified, uplace.modified) self.assertAlmostEqual(uplace.created, timestamp, delta=1000)
def test_import_user(self): publisher_vd1 = VD.objects.create(realOwner=self.ru) publisher_vd2 = VD.objects.create() place1 = Place.objects.create() uplace1 = ImportedPlace.objects.create(place=place1, vd=publisher_vd1) place2 = Place.objects.create() uplace2 = ImportedPlace.objects.create(place=place2, vd=publisher_vd2) response = self.client.get('/iplaces/') self.assertEqual(response.status_code, status.HTTP_200_OK) results = json_loads(response.content)['results'] self.assertEqual(len(results), 0) guide_json = '{"type": "user", "email": "*****@*****.**"}' self.imp.publisher.guide = guide_json self.imp.publisher.save() ts = get_timestamp() r = self.imp.start() self.assertEqual(r.state, 'SUCCESS') self.assertEqual(r.result, True) self.imp = self.imp.reload() self.assertAlmostEqual(self.imp.started, ts, delta=1000) self.assertAlmostEqual(self.imp.ended, ts, delta=1000) self.assertGreater(self.imp.ended, self.imp.started) response = self.client.get('/iplaces/') self.assertEqual(response.status_code, status.HTTP_200_OK) results = json_loads(response.content)['results'] self.assertEqual(len(results), 1) self.assertEqual(results[0]['iplace_uuid'], uplace1.uuid) publisher_vd2.realOwner = self.ru publisher_vd2.save() self.clear_cache(self.vd) response = self.client.get('/iplaces/') self.assertEqual(response.status_code, status.HTTP_200_OK) results = json_loads(response.content)['results'] self.assertEqual(len(results), 2)
def test_post(self): place = Place() place.save() vd1 = VD() vd1.save() uplace1 = UserPlace(vd=vd1, place=place) uplace1.save() point1 = GEOSGeometry('POINT(127 37)', srid=4326) name1, is_created = PlaceName.get_or_create_smart('능라') addr1, is_created = Address.get_or_create_smart( '경기도 성남시 분당구 운중동 883-3') note11, is_created = PlaceNote.get_or_create_smart('분당 냉면 최고') note12, is_created = PlaceNote.get_or_create_smart('만두도 괜찮음') imgNote1, is_created = ImageNote.get_or_create_smart('냉면 사진') img1_content = 'http://blogthumb2.naver.net/20160302_285/mardukas_1456922688406bYGAH_JPEG/DSC07301.jpg' img1, is_created = Image.get_or_create_smart(img1_content) phone1, is_created = PhoneNumber.get_or_create_smart('010-5686-1613') vd2 = VD() vd2.save() uplace2 = UserPlace(vd=vd2, place=place) uplace2.save() point2 = GEOSGeometry('POINT(127.1037430 37.3997320)', srid=4326) name2, is_created = PlaceName.get_or_create_smart('능라도') addr2, is_created = Address.get_or_create_smart( '경기도 성남시 분당구 산운로32번길 12') note21, is_created = PlaceNote.get_or_create_smart('여기 가게 바로 옆으로 이전') note22, is_created = PlaceNote.get_or_create_smart('평양냉면 맛집') img21_content = 'http://blogpfthumb.phinf.naver.net/20100110_16/mardukas_1263055491560_VI01Ic_JPG/DSCN1968.JPG' img22_content = 'http://mblogthumb3.phinf.naver.net/20160807_298/mardukas_14705287064440EYVC_JPEG/DSC03530.JPG?type=w800' img21, is_created = Image.get_or_create_smart(img21_content) img22, is_created = Image.get_or_create_smart(img22_content) imgNote2, is_created = ImageNote.get_or_create_smart('만두 사진') url2, is_created = Url.get_or_create_smart('http://www.naver.com/') lp, is_created = LegacyPlace.get_or_create_smart( '4ccffc63f6378cfaace1b1d6.4square') phone2, is_created = PhoneNumber.get_or_create_smart('010-5597-9245') json_userPost = ''' { "lonLat": {"lon": %f, "lat": %f}, "name": {"uuid": "%s", "content": "%s"}, "addr2": {"uuid": "%s", "content": "%s"}, "notes": [{"uuid": "%s", "content": "%s"}, {"uuid": "%s", "content": "%s"}], "images": [{"uuid": "%s", "content": "%s", "note": {"uuid": "%s", "content": "%s"}}], "urls": [], "lps": [], "phone": {"uuid": "%s", "content": "%s"} } ''' % ( point1.x, point1.y, name1.uuid, name1.content, addr1.uuid, addr1.content, note12.uuid, note12.content, note11.uuid, note11.content, img1.uuid, img1.content, imgNote1.uuid, imgNote1.content, phone1.uuid, phone1.content, ) json_placePost = ''' { "lonLat": {"lon": %f, "lat": %f}, "name": {"uuid": "%s", "content": "%s"}, "addr1": {"uuid": "%s", "content": "%s"}, "addr2": {"uuid": "%s", "content": "%s"}, "notes": [ {"uuid": "%s", "content": "%s"}, {"uuid": "%s", "content": "%s"}, {"uuid": "%s", "content": "%s"}, {"uuid": "%s", "content": "%s"} ], "images": [ {"uuid": "%s", "content": "%s", "note": null}, {"uuid": "%s", "content": "%s", "note": {"uuid": "%s", "content": "%s"}}, {"uuid": "%s", "content": "%s", "note": {"uuid": "%s", "content": "%s"}} ], "urls": [{"uuid": "%s", "content": "%s"}], "lps": [{"uuid": "%s", "content": "%s"}], "phone": {"uuid": "%s", "content": "%s"} } ''' % ( point2.x, point2.y, name2.uuid, name2.content, addr2.uuid, addr2.content, addr1.uuid, addr1.content, note22.uuid, note22.content, note21.uuid, note21.content, note12.uuid, note12.content, note11.uuid, note11.content, img22.uuid, img22.content, img21.uuid, img21.content, imgNote2.uuid, imgNote2.content, img1.uuid, img1.content, imgNote1.uuid, imgNote1.content, url2.uuid, url2.content, lp.uuid, lp.content, phone2.uuid, phone2.content, ) pb1 = PostBase(json_userPost) pb2 = PostBase(json_placePost) self.assertEqual(PostPiece.objects.count(), 0) pp1 = PostPiece.create_smart(uplace1, pb1) self.assertEqual(PostPiece.objects.count(), 1) pp2 = PostPiece.create_smart(uplace2, pb2) pp3 = PostPiece.create_smart_4place(place, vd1, pb2, by_MAMMA=True) self.assertEqual(PostPiece.objects.count(), 3) want_userPost = json_loads(json_userPost) want_placePost = json_loads(json_placePost) self.assertNotIn('timestamp', uplace1.userPost.json['lonLat']) self.assertNotIn('timestamp', uplace1.userPost.json['name']) self.assertIn('timestamp', uplace1.userPost.json['notes'][0]) self.assertNotIn('timestamp', uplace1.userPost.json['images'][0]) self.assertIn('timestamp', uplace1.userPost.json['images'][0]['note']) self.assertNotIn('timestamp', uplace2.userPost.json['urls'][0]) self.assertNotIn('timestamp', uplace2.userPost.json['lps'][0]) timestamp = uplace1.userPost.json['notes'][0]['timestamp'] self.assertAlmostEqual(get_timestamp(), timestamp, delta=1000) self.assertIn('summary', uplace1.userPost.json['images'][0]) self.assertIn('phone', uplace1.userPost.json) self.assertNotEqual(uplace1.userPost.json['images'][0]['content'], None) self.assertIsSubsetOf(want_userPost, uplace1.userPost) self.assertIsNotSubsetOf(uplace1.userPost, want_userPost) self.assertIsSubsetOf(want_placePost, uplace1.place.placePost) self.assertIsNotSubsetOf(uplace1.place.placePost, want_placePost) uplace1._clearCache() p1 = uplace1.place.placePost uplace2._clearCache() p2 = uplace2.place.placePost place._clearCache() p3 = place.placePost self.assertDictEqual(p1.json, p3.json) self.assertDictEqual(p2.json, p3.json) pb12 = PostBase(json_userPost) pb12.update(pb1) self.assertNotEqual(pb12.json, pb1.json) pb12.normalize() self.assertEqual(pb12.json, pb1.json) pb13 = PostBase(json_userPost) pb13.update(pb1) pb13.update(pb1, add=False) pb_null = PostBase() self.assertEqual(pb13.json, pb_null.json) totalPost = place._totalPost self.assertIsSubsetOf(uplace1.place.placePost, totalPost) #self.assertIsSubsetOf(uplace1.userPost, totalPost) # Note 에서 timestamp 를 제거해야... #self.assertIsSubsetOf(uplace2.userPost, totalPost) # 상동 #self.assertIsNotSubsetOf(totalPost, uplace1.place.placePost) # userPost 를 하나 더 생성해야... # child/parent test uplace3 = UserPlace.objects.create(parent=uplace1) self.assertEqual(uplace3.parent, uplace1) self.assertNotEqual(uplace3.userPost, uplace1.userPost) self.printJson(uplace3.userPost.json) self.printJson(uplace1.userPost.json) self.assertEqual(uplace3.userPost.json, uplace1.userPost.json) uplace1._clearCache() uplace3._clearCache() pb3 = PostBase('{"notes": [{"content": "child"}]}') pp3 = PostPiece.create_smart(uplace3, pb3) self.assertNotEqual(uplace3.userPost, uplace1.userPost) self.assertNotEqual(uplace3.userPost.json, uplace1.userPost.json) place4 = Place.objects.create() uplace4 = UserPlace.objects.create(parent=uplace1, vd=vd1, place=place4) self.assertEqual(uplace4.parent, uplace1) self.assertNotEqual(uplace4.userPost, uplace1.userPost) self.assertEqual(uplace4.userPost.json, uplace1.userPost.json) uplace1._clearCache() uplace4._clearCache() pb3 = PostBase('{"notes": [{"content": "child"}]}') pp3 = PostPiece.create_smart(uplace4, pb3) self.assertNotEqual(uplace4.userPost, uplace1.userPost) self.assertNotEqual(uplace4.userPost.json, uplace1.userPost.json)
def save(self, *args, **kwargs): if not self.created: self.created = get_timestamp() self.data = convert_to_json(self.data) super(Inquiry, self).save(*args, **kwargs)
def create(self, request, *args, **kwargs): # vd 조회 vd = self.vd if not vd: return Response(status=status.HTTP_401_UNAUTHORIZED) # 결과 처리를 위한 변수 선언 uplace = None ####################################### # 삭제 포스트 처리 ####################################### if 'remove' in request.data and request.data['remove']: # PostBase instance 생성 pb = PostBase(request.data['remove']) if 'place_id' in request.data and request.data['place_id']: pb.place_id = request.data['place_id'] if 'uplace_uuid' in request.data and request.data['uplace_uuid']: pb.uplace_uuid = request.data['uplace_uuid'] # 삭제 포스트는 반드시 uplace_uuid 가 지정되어야 한다. uplace = UserPlace.get_from_uuid(pb.uplace_uuid) if not uplace: raise ValueError('삭제 포스트 처리 시에는 반드시 uplace_uuid 가 지정되어야 함') # 삭제 PostPiece 생성 pp = PostPiece.create_smart(uplace, pb, is_remove=True) ####################################### # 추가 포스트 처리 ####################################### if 'add' in request.data and request.data['add']: # PostBase instance 생성 pb = PostBase(request.data['add']) if 'place_id' in request.data and request.data['place_id']: pb.place_id = request.data['place_id'] if 'uplace_uuid' in request.data and request.data['uplace_uuid']: pb.uplace_uuid = request.data['uplace_uuid'] # 추가 정보 가져오기 : 유저가 직접 입력했다고 봐도 무방한 사항만 pb.load_additional_info() # UserPlace/Place 찾기 uplace, is_created = UserPlace.get_or_create_smart(pb, vd) # valid check if not pb.is_valid(uplace): raise ValueError('PostPiece 생성을 위한 최소한의 정보도 없음') # PostPiece 생성 pp = PostPiece.create_smart(uplace, pb) # 임시적인 어드민 구현을 위해, MAMMA 가 추가로 뽑아준 post 가 있으면 추가로 포스팅 pb_MAMMA = pb.pb_MAMMA if pb_MAMMA: # 아래 호출에서 Place 가 생성되고, 필요시 Place PostPiece 도 생성됨 # TODO : 좀 더 Readability 가 높은 형태로 리팩토링 uplace, is_created = UserPlace.get_or_create_smart( pb_MAMMA, vd) # Place.lonLat 관련 예외 처리 lonLat = (pb_MAMMA and pb_MAMMA.lonLat) or pb.lonLat if lonLat and uplace.place and (not uplace.place.lonLat or (pb_MAMMA and pb_MAMMA.lonLat)): uplace.place.lonLat = lonLat uplace.place.save() # 현재 위치 저장인 경우 이미지에 추가 정보 붙이기 if is_created and lonLat and pb.images and len( pb.images) == 1 and pb.images[0]: img = pb.images[0] img.lonLat = lonLat img.timestamp = uplace.created - 1000 img.save() # 빠른 장소화를 위한 flag 세팅 if is_created and not uplace.place: uplace.is_hurry2placed = True # 최종 저장 uplace.lonLat = (uplace.place and uplace.place.lonLat) or lonLat or uplace.lonLat uplace.modified = get_timestamp() # TODO : 아래 코드가 테스트되는 테스트 추가 uplace.is_drop = False uplace.save() # Placed by Contents if pb.urls: placesets = [ set(url.places.all()) for url in pb.urls if url.places ] if placesets: places = list(reduce(lambda a, b: a & b, placesets)) for place in places: uplace.process_child(place) ####################################### # 결과 처리 ####################################### serializer = self.get_serializer(uplace) cache_expire_ru(vd, 'uplaces') cache_expire_ru(vd, uplace.post_cache_name) return Response(serializer.data, status=status.HTTP_201_CREATED)