def image(): if request.method == 'POST': if 'username' in session: parentAcct = session['username'] try: parentKey = ndb.Key(model.UserAccount, parentAcct).get().key except: flash( "Image save refused. User Account key is invalid. Try logging in again" ) return redirect(url_for('login')) uploaded_file = request.files.get('image') mimetype = uploaded_file.mimetype image_stream = uploaded_file.stream.read() # if user submits without selecting file, browser also submits a empty part without file type if mimetype == '': flash("No file selected. Try again") return redirect(url_for('image')) image = images.resize(image_stream, 96, 96) saveImage = model.Photo( image=image, mimetype=mimetype, parent=parentKey ) # stronger consistency -tied it to a parent record saveImage.put() imageID = saveImage.key.id() flash("Image upload complete. [{}] is its unique DB id".format( imageID)) return redirect(url_for('thumbnail', id=saveImage.key.urlsafe())) return render_template('image.html')
def get_photo(self, photo_id): if self.apikey: url_pattern = r'https://api.douban.com/v2/photo/{0}?apikey={1}' url = url_pattern.format(photo_id, self.apikey) else: url_pattern = r'https://api.douban.com/v2/photo/{0}' url = url_pattern.format(photo_id) jsonStr = self.get_html(url) data = json.loads(jsonStr) url = data['large'] position = data['position'] desc = data['desc'] created = data['created'] liked_count = data['liked_count'] comments_count = data['comments_count'] album_title = data['album_title'] album_id = data['album_id'] author_name = data['author']['name'] author_id = data['author']['id'] author_uid = data['author']['uid'] return model.Photo(id, url, position=position, desc=desc, created=created, liked_count=liked_count, comments_count=comments_count, album_title=album_title, album_id=album_id, author_name=author_name, author_id=author_id, author_uid=author_uid)
def test_model_insert(self): """Model insert testing.""" new_photo = model.Photo( id=3, name='photo4', width=640, height=480, date_original=datetime.datetime(2018, 1, 1, 15, 0, 2), aperture=2.8, shutter=1 / 100.0, iso=200, metering_mode='normal', exposure_mode='center weight', white_balance='daylight', camera='Canon EOS 70D', camera_id='123ABCDEF', lens_type='EF-S 70-200', lens_serial='234FDC', gps_lat="37 12' 34.5''N", gps_long="122 23'45.6''W", gps_alt=1.4, gps_datetime=datetime.datetime(2018, 1, 2, 11, 0, 0), comments='comment1', focal_length=15.5) self.session.add(new_photo) self.session.commit() self.assertEqual( new_photo, self.session.query( model.Photo).filter(model.Photo.name == new_photo.name).one())
def process_media(self, media_array, feed=1): media_amount = random.randint(3, 10) if (media_array): for media in media_array: if feed == 0: media_details = self.operation.get_photo_details( media['node']['shortcode']) else: media_details = self.operation.get_photo_details( media['code']) if (media_details): media_instance = model.Photo().from_json(media_details) self.unfilteredMediaList.append(media_instance) else: return False # Validate and pick random photos. media_list = self.spam_validator.validate_photos( self.unfilteredMediaList) if (media_amount > len(media_list)): media_amount = len(media_list) self.mediaList.extend(random.sample(media_list, media_amount)) if (len(self.mediaList) == 0): return False return True
def DeletePhoto(id): photo = model.Photo().get_by_id(int(id)) if photo is not None: u = UpYun() if photo.imgurl is not None: path = photo.imgurl.replace('http://imgstore.b0.upaiyun.com', '') u.delete(path) photo.Album.PhotoCount -= 1 photo.Album.put() photo.delete() memcache.delete('ALLALBUMS')
def get_photos(self, album_id): if self.apikey: url_pattern = r'https://api.douban.com/v2/album/{0}/photos?start={1}&count=100&apikey={2}' url = url_pattern.format(album_id, 0, self.apikey) else: url_pattern = r'https://api.douban.com/v2/album/{0}/photos?start={1}&count=100' url = url_pattern.format(album_id, 0) jsonStr = self.get_html(url) data = json.loads(jsonStr) size = int(data['album']['size']) # 分N次提取。每次最多100条 part = size / 100 if size % 100 == 0 else int(size / 100) + 1 urls = [ url.format(album_id, x * 100, self.apikey) for x in range(part) ] photos = [] for url in urls: jsonStr = self.get_html(url) data = json.loads(jsonStr) for x in data['photos']: id = x['id'] # 有的相册里没有large,那就取image if 'large' in x.keys(): url = x['large'] elif 'image' in x.keys(): url = x['image'] elif 'cover' in x.keys(): url = x['cover'] position = x['position'] desc = x['desc'].strip().strip() created = x['created'] liked_count = x['liked_count'] comments_count = x['comments_count'] album_title = x['album_title'].strip() album_id = x['album_id'] author_name = x['author']['name'] author_id = x['author']['id'] author_uid = x['author']['uid'] photo = model.Photo(id, url, position=position, desc=desc, created=created, liked_count=liked_count, comments_count=comments_count, album_title=album_title, album_id=album_id, author_name=author_name, author_id=author_id, author_uid=author_uid) photos.append(photo) return photos
def GetPhoto(id): '''根据ID获取单张相片''' id = int(id) photo = model.Photo().get_by_id(id) return photo if photo is not None: #photo.ViewCount+=1 #photo.Update() data['photo'] = photo data['prev'] = photo.Prev() data['next'] = photo.Next() return data
def like(self, photo): response = self.operation.like(photo['id']) self.photo_repository.like(model.Photo().from_json(photo), response.status_code) if (response.status_code != 200): self.last_error_code = response.status_code if (response.status_code == 400): self.ban400 += 1 self.failed_to_like() return False self.photo_liked() return True
def AddPhoto(name, description, mime, album, user, stream, imgurl=''): 'Add Photo' photo = model.Photo() photo.Album = album photo.Author = user photo.Description = description photo.Mime = mime photo.Name = name photo.PhotoStream = None photo.Size = len(stream) photo.FileType, photo.Width, photo.Height = getImageInfo(stream) photo.imgurl = imgurl photo.Save() memcache.delete('ALLALBUMS') return photo
def _create_db(self): """Creates database.""" self.photos = {} self.backups = {} for backup in BACKUPS: self.backups[backup['id']] = model.Backup(**backup) for photo in PHOTOS: self.photos[photo['id']] = model.Photo(**photo) for location in LOCATIONS: l = model.Location(path=location['path']) l.backup = self.backups[location['backup_id']] self.photos[location['photo_id']].locations.append(l) for id_, photo in self.photos.items(): self.session.add(photo) self.session.commit()
def get_photos(self): self.photos_from_model = [] self.users_from_model = [] no_of_photos = random.randint(2, 10) for tag in self.tags: try: self.log('getting photos from tag {0}...'.format(tag)) self.photos = self.operation.get_photos_by_tag(tag) except TypeError: self.log('oops! someting went wrong while fetching photos.') if not self.photos: return [] for photo in self.photos: photo_details = self.operation.get_photo_details(photo['code']) if (photo_details): photo_instance = model.Photo().from_json(photo_details) self.repository.merge_photo(photo_instance) self.photos_from_model.append(photo_instance) user_details = self.operation.get_user_details( photo_instance.owner_username.replace('\'', '')) if (user_details): user_instance = model.User().from_json(user_details) self.repository.merge_user(user_instance) self.users_from_model.append(user_instance) self.filter_photos() if (len(self.photos_from_model) < no_of_photos): no_of_photos = len(self.photos_from_model) self.photos_from_model = random.sample(self.photos_from_model, no_of_photos) self.users_from_model = self.spam_validator.validate_users( self.users_from_model) return self.photos_from_model
def test_delete_expired(self): """Test the flagging and deletion of expired records.""" def run_delete_expired_task(): """Runs the DeleteExpired task.""" self.initialize_handler(tasks.DeleteExpired()).get() # This test sets up two Person entities, self.p1 and self.p2. # self.p1 is deleted in two stages (running DeleteExpired once during # the grace period, then again after the grace period); self.p2 is # deleted in one stage (running DeleteExpired after the grace period). # Setup cheerfully stolen from test_model. set_utcnow_for_test(datetime.datetime(2010, 1, 1)) photo = model.Photo(bin_data='0x1111') photo.put() photo_id = photo.key().id() self.p1 = model.Person.create_original( 'haiti', first_name='John', last_name='Smith', home_street='Washington St.', home_city='Los Angeles', home_state='California', home_postal_code='11111', home_neighborhood='Good Neighborhood', author_name='Alice Smith', author_phone='111-111-1111', author_email='*****@*****.**', photo_url='', photo=photo, source_url='https://www.source.com', source_date=datetime.datetime(2010, 1, 1), source_name='Source Name', entry_date=datetime.datetime(2010, 1, 1), expiry_date=datetime.datetime(2010, 2, 1), other='') self.p2 = model.Person.create_original( 'haiti', first_name='Tzvika', last_name='Hartman', home_street='Herzl St.', home_city='Tel Aviv', home_state='Israel', source_date=datetime.datetime(2010, 1, 1), entry_date=datetime.datetime(2010, 1, 1), expiry_date=datetime.datetime(2010, 3, 1), other='') self.key_p1 = db.put(self.p1) self.key_p2 = db.put(self.p2) self.n1_1 = model.Note.create_original( 'haiti', person_record_id=self.p1.record_id, linked_person_record_id=self.p2.record_id, status=u'believed_missing', found=False, entry_date=get_utcnow(), source_date=datetime.datetime(2010, 1, 2)) note_id = self.n1_1.note_record_id db.put(self.n1_1) # Initial state: two Persons and one Note, nothing expired yet. eq(model.Person.all().count(), 2) eq(model.Person.past_due_records().count(), 0) assert model.Note.get('haiti', note_id) assert model.Photo.get_by_id(photo_id) run_delete_expired_task() # Confirm that DeleteExpired had no effect. eq(model.Person.all().count(), 2) eq(model.Person.past_due_records().count(), 0) eq(db.get(self.key_p1).source_date, datetime.datetime(2010, 1, 1)) eq(db.get(self.key_p1).entry_date, datetime.datetime(2010, 1, 1)) eq(db.get(self.key_p1).expiry_date, datetime.datetime(2010, 2, 1)) assert model.Note.get('haiti', note_id) assert model.Photo.get_by_id(photo_id) # Advance to just after the expiry_date of self.p1. set_utcnow_for_test(datetime.datetime(2010, 2, 2)) # self.p1 should now be past due. eq(model.Person.all().count(), 2) eq(model.Person.past_due_records().count(), 1) eq(db.get(self.key_p1).source_date, datetime.datetime(2010, 1, 1)) eq(db.get(self.key_p1).entry_date, datetime.datetime(2010, 1, 1)) eq(db.get(self.key_p1).expiry_date, datetime.datetime(2010, 2, 1)) assert model.Note.get('haiti', note_id) assert model.Photo.get_by_id(photo_id) run_delete_expired_task() # Confirm that DeleteExpired set is_expired and updated the timestamps # on self.p1, but did not wipe its fields or delete the Note or Photo. eq(model.Person.all().count(), 1) eq(model.Person.past_due_records().count(), 1) eq(db.get(self.key_p1).source_date, datetime.datetime(2010, 2, 2)) eq(db.get(self.key_p1).entry_date, datetime.datetime(2010, 2, 2)) eq(db.get(self.key_p1).expiry_date, datetime.datetime(2010, 2, 1)) eq(db.get(self.key_p1).is_expired, True) assert not model.Note.get('haiti', note_id) # Note is hidden assert db.get(self.n1_1.key()) # but the Note entity still exists assert model.Photo.get_by_id(photo_id) # Advance past the end of the expiration grace period of self.p1. set_utcnow_for_test(datetime.datetime(2010, 2, 5)) # Confirm that nothing has changed yet. eq(model.Person.all().count(), 1) eq(model.Person.past_due_records().count(), 1) eq(db.get(self.key_p1).source_date, datetime.datetime(2010, 2, 2)) eq(db.get(self.key_p1).entry_date, datetime.datetime(2010, 2, 2)) eq(db.get(self.key_p1).expiry_date, datetime.datetime(2010, 2, 1)) eq(db.get(self.key_p1).is_expired, True) eq(model.Note.get('haiti', note_id), None) # Note is hidden assert db.get(self.n1_1.key()) # but the Note entity still exists assert model.Photo.get_by_id(photo_id) run_delete_expired_task() # Confirm that the task wiped self.p1 without changing the timestamps, # and deleted the related Note and Photo. eq(model.Person.all().count(), 1) eq(model.Person.past_due_records().count(), 1) eq(db.get(self.key_p1).source_date, datetime.datetime(2010, 2, 2)) eq(db.get(self.key_p1).entry_date, datetime.datetime(2010, 2, 2)) eq(db.get(self.key_p1).expiry_date, datetime.datetime(2010, 2, 1)) eq(db.get(self.key_p1).is_expired, True) eq(db.get(self.key_p1).first_name, None) eq(model.Note.get('haiti', note_id), None) # Note is hidden eq(db.get(self.n1_1.key()), None) # Note entity is actually gone eq(model.Photo.get_by_id(photo_id), None) # Photo entity is gone # Advance past the end of the expiration grace period for self.p2. set_utcnow_for_test(datetime.datetime(2010, 3, 15)) # Confirm that both records are now counted as past due. eq(model.Person.all().count(), 1) eq(model.Person.past_due_records().count(), 2) eq(db.get(self.key_p1).source_date, datetime.datetime(2010, 2, 2)) eq(db.get(self.key_p1).entry_date, datetime.datetime(2010, 2, 2)) eq(db.get(self.key_p1).expiry_date, datetime.datetime(2010, 2, 1)) eq(db.get(self.key_p2).source_date, datetime.datetime(2010, 1, 1)) eq(db.get(self.key_p2).entry_date, datetime.datetime(2010, 1, 1)) eq(db.get(self.key_p2).expiry_date, datetime.datetime(2010, 3, 1)) run_delete_expired_task() # Confirm that the task wiped self.p2 as well. eq(model.Person.all().count(), 0) eq(model.Person.past_due_records().count(), 2) eq(db.get(self.key_p1).is_expired, True) eq(db.get(self.key_p1).first_name, None) eq(db.get(self.key_p1).source_date, datetime.datetime(2010, 2, 2)) eq(db.get(self.key_p1).entry_date, datetime.datetime(2010, 2, 2)) eq(db.get(self.key_p1).expiry_date, datetime.datetime(2010, 2, 1)) eq(db.get(self.key_p2).is_expired, True) eq(db.get(self.key_p2).first_name, None) eq(db.get(self.key_p2).source_date, datetime.datetime(2010, 3, 15)) eq(db.get(self.key_p2).entry_date, datetime.datetime(2010, 3, 15)) eq(db.get(self.key_p2).expiry_date, datetime.datetime(2010, 3, 1))
def upload(): username = session.get('username') if username: user_id = model_session.query(model.User).filter_by(username=username).first().id else: user_id = 0 f_keys = request.form.keys() pattern = re.compile(r'^data:image/(png|jpeg|jpg);base64,(.*)$') raw_data = [] for key in f_keys: if key != 'cloud_name' and key != 'choice': match = pattern.match(request.form[key]) if match is None: raise ValueError('Invalid image data.') content_type = 'image/{}'.format(match.group(1)) file_data = base64.b64decode(match.group(2)) raw_data.append(file_data) user_path = 'static/uploads/%d' % user_id if not os.path.exists(user_path): # user doesn't have his/her own directory yet, so create one os.mkdir(user_path) cloud_name = request.form['cloud_name'] algorithm = request.form['choice'] # save cloud to database new_cloud = model.Cloud(user_id=user_id, name=cloud_name) model_session.add(new_cloud) model_session.commit() model_session.refresh(new_cloud) cloud_id = model_session.query(model.Cloud.id).order_by(desc(model.Cloud.id)).first()[0] # create a new directory inside the user's directory for uploaded photos path = user_path + '/' + str(cloud_id) if not os.path.exists(path): os.mkdir(path) for idx, d in enumerate(raw_data): filename = '{}.{}'.format(len(raw_data)-idx, match.group(1)) with open(path + '/' + filename, 'w') as f: f.write(d) path = 'static/uploads/%d/%s' % (user_id, cloud_id) images = sorted(path + '/' + img for img in os.listdir(path) if img.rpartition('.')[2].lower() in ('jpg', 'jpeg', 'png')) points_path = os.path.abspath(os.path.join(path, "points")) reconstruct.start(algorithm, images, file_path=points_path) if algorithm == 'features': points = str(reconstruct.extract_points(points_path + "_inliers.txt")) elif algorithm == 'flow': points = str(reconstruct.extract_points(points_path + ".txt")) # set the path to the text file storing the 3D points of the cloud cloud = model_session.query(model.Cloud).filter_by(id=cloud_id).first() cloud.path = path model_session.commit() # save photos to database photos = [ img for img in os.listdir(path) if img.rpartition('.')[2].lower() in ('jpg', 'jpeg', 'png') ] for photo in photos: new_photo = model.Photo(filename=photo, path=path, cloud_id=cloud_id) model_session.add(new_photo) model_session.commit() model_session.refresh(new_photo) cloud_data = {'cloud_id': cloud_id, 'points': points} return jsonify(cloud_data)
def post(self): """Exposed as `POST /api/photos`. Takes the following payload in the request body. Payload represents a Photo that should be created. { 'id':0, 'ownerUserId':0, 'ownerDisplayName':'', 'ownerProfileUrl':'', 'ownerProfilePhoto':'', 'themeId':0, 'themeDisplayName':'', 'numVotes':0, 'voted':false, // Whether or not the current user has voted on this. 'created':0, 'fullsizeUrl':'', 'thumbnailUrl':'', 'voteCtaUrl':'', // URL for Vote interactive post button. 'photoContentUrl':'' // URL for Google crawler to hit to get info. } Returns the following JSON response representing the created Photo. { 'id':0, 'ownerUserId':0, 'ownerDisplayName':'', 'ownerProfileUrl':'', 'ownerProfilePhoto':'', 'themeId':0, 'themeDisplayName':'', 'numVotes':0, 'voted':false, // Whether or not the current user has voted on this. 'created':0, 'fullsizeUrl':'', 'thumbnailUrl':'', 'voteCtaUrl':'', // URL for Vote interactive post button. 'photoContentUrl':'' // URL for Google crawler to hit to get info. } Issues the following errors along with corresponding HTTP response codes: 400: 'Bad Request' if the request is missing image data. 401: 'Unauthorized request' (if certain parameters are present in the request) 401: 'Access token expired' (there is a logged in user, but he doesn't have a refresh token and his access token is expiring in less than 100 seconds, get a new token and retry) 500: 'Error while writing app activity: ' + error from client library. """ try: user = self.get_user_from_session() current_theme = model.Theme.get_current_theme() if current_theme: uploads = self.get_uploads('image') blob_info = uploads[0] photo = model.Photo( owner_user_id=user.key().id(), owner_display_name=user.google_display_name, owner_profile_photo=user.google_public_profile_photo_url, owner_profile_url=user.google_public_profile_url, theme_id=current_theme.key().id(), theme_display_name=current_theme.display_name, created=datetime.datetime.now(), num_votes=0, image_blob_key=blob_info.key()) photo.put() try: result = self.add_photo_to_google_plus_activity( user, photo) except apiclient.errors.HttpError as e: logging.error("Error while writing app activity: %s", str(e)) self.send_success(photo) else: self.send_error(404, 'No current theme.') except UserNotAuthorizedException as e: self.send_error(401, e.msg)