def index(self): user = self.request.user years = range(2010, date.today().year + 1) + [''] months = range(1, 13) + [''] days = range(1, 32) + [''] search_components = dict(years = zip(years, years), months = zip(months, months), days = zip(days, days), ) if Role.GALLERY_ADMIN in user.role_ids: query = DBSession.query(Gallery) \ .join(Gallery.creator_detail) else: authorized_galleries = DBSession.query(Gallery.id) \ .join(Gallery.permission) \ .filter(GalleryPermission.role_id.in_(user.role_ids)) \ .group_by(Gallery.id) query = DBSession.query(Gallery) \ .join(Gallery.creator_detail) \ .filter(Gallery.id.in_(authorized_galleries)) galleries = self.__paginate__(query, order='gallery_date', sort='desc') return {'galleries' : galleries, 'search_components' : search_components, 'filter_errors' : self.filter_errors, 'request' : self.request}
def new(self): user = self.request.user form = Form(self.request, schema=GallerySchema) if form.validate(): #Generate a name for the new directory. Check if it exists. new_directory_name = None while not new_directory_name or (DBSession.query(Gallery).filter(Gallery.directory_name == new_directory_name).first()): new_directory_name = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(12)) gallery_directory = self.request.registry.settings['gallery.directory'] mkdir(path.join(gallery_directory, new_directory_name)) mkdir(path.join(gallery_directory, new_directory_name, 'raw')) mkdir(path.join(gallery_directory, new_directory_name, 'thumbs')) mkdir(path.join(gallery_directory, new_directory_name, 'web')) data = form.data.copy() data['directory_name'] = new_directory_name data['created'] = datetime.now() data['creator'] = user.id #temporary del data['permissions'] gallery = Gallery(**data) DBSession.add(gallery) DBSession.flush() return HTTPFound(self.request.route_url('gallery_view', id=gallery.id)) return {'request' : self.request, 'form_rend' : FormRenderer(form)}
def get_user(request): '''fetches the user. Used to attach a user object to the request''' user = unauthenticated_userid(request) if user is not None: return DBSession.query(User).filter(User.user == user).first() else: return DBSession.query(User).filter(User.user == User.VISITOR).first()
def edit(self): user = self.request.user form = Form(self.request, schema=GallerySchema) gallery = DBSession.query(Gallery).get(self.request.matchdict['id']) roles = DBSession.query(Role).all() if form.validate(): gallery.modified = datetime.now() gallery.last_update_by = user.id gallery.title = form.data['title'] gallery.description = form.data['description'] gallery.gallery_date = form.data['gallery_date'] #Need to make an object exists validator temp_perms = [] for existing_gallery_permission in gallery.permission: DBSession.delete(existing_gallery_permission) for r_id in form.data['permissions']: temp_perms.append(GalleryPermission(gallery_id = gallery.id, role_id = r_id)) gallery.permission[:] = temp_perms return HTTPFound(self.request.route_url('gallery_view', id=gallery.id)) return {'request' : self.request, 'gallery' : gallery, 'roles' : roles, 'form_rend' : FormRenderer(form)}
def get(cls, gallery_id, user): gallery = DBSession.query(cls) \ .join(GalleryPermission) \ .filter(and_( cls.id == gallery_id, GalleryPermission.role_id.in_(user.role_ids))).first() return gallery
def rebuild_symlinks(self): '''In certain situations where the symlinks are not correct, this action can be used to rebuild them''' #-------------- # ToDO # - Exception handling in general #-------------- gallery_id = self.request.POST['id'] gallery = DBSession.query(Gallery).get(gallery_id) #Remove the directory directory_path = path.join(self.request.registry.settings['gallery.directory'], gallery.directory_name) shutil.rmtree(directory_path, True) #Recreate the directory tree for the gallery gallery_directory = self.request.registry.settings['gallery.directory'] mkdir(path.join(gallery_directory, gallery.directory_name)) mkdir(path.join(gallery_directory, gallery.directory_name, 'raw')) mkdir(path.join(gallery_directory, gallery.directory_name, 'thumbs')) mkdir(path.join(gallery_directory, gallery.directory_name, 'web')) #Loop through the images in the gallery and recreate the symlinks for media in gallery.media: for sub_directory in ['raw', 'web', 'thumbs']: sym_path = path.join( self.request.registry.settings['gallery.directory'], gallery.directory_name, sub_directory, media.file_name) media_path = path.join( self.request.registry.settings['gallery.directory'], sub_directory, media.file_name) os.symlink(media_path,sym_path) return HTTPFound(location=self.request.route_url('gallery_index'))
def restore(self): medium_id = self.request.matchdict['medium_id'] medium = DBSession.query(Medium).get(medium_id) original_path = path.join( self.request.registry.settings['gallery.directory'], 'original', medium.file_name) raw_path = path.join( self.request.registry.settings['gallery.directory'], 'raw', medium.file_name) web_path = path.join( self.request.registry.settings['gallery.directory'], 'web', medium.file_name) thumb_path = path.join( self.request.registry.settings['gallery.directory'], 'thumbs', medium.file_name) try: with open(original_path, 'r') as original_raw: original_media = Image.open(original_raw) #restore thumb version thumb_media = original_media.copy() thumb_media.thumbnail((150, 150)) thumb_media.save(thumb_path) #restore web version web_media = original_media.copy() web_media.thumbnail((800, 800)) web_media.save(web_path) #restore raw original_media.save(raw_path) except: raise return Response('error') else: return Response('ok')
def get(cls, medium_id, user): medium = DBSession.query(cls) \ .join(Gallery, GalleryPermission) \ .filter(and_( cls.id == medium_id, GalleryPermission.role_id.in_(user.role_ids))).first() return medium
def new(self): entry_types = list((i.id, i.description) for i in DBSession.query(EntryType).all()) entry_types.append(('', '')) form = Form(self.request, schema=EntrySchema) if form.validate(): data = form.data.copy() data['date'] = datetime.now() DBSession.add(Entry(**data)) return HTTPFound(location="/") return {'request' : self.request, 'entry_types' : entry_types, 'form_rend' : FormRenderer(form)}
def delete(self): medium_id = self.request.POST['id'] medium = DBSession.query(Medium).get(medium_id) #build the paths to delete phy_path = self.request.registry.settings['gallery.directory'] sym_path = path.join(self.request.registry.settings['gallery.directory'], medium.gallery.directory_name) paths = [path.join(phy_path,'raw',medium.file_name), path.join(phy_path,'original',medium.file_name), path.join(phy_path,'thumbs',medium.file_name), path.join(phy_path,'web',medium.file_name), path.join(sym_path,'raw',medium.file_name), path.join(sym_path,'thumbs',medium.file_name), path.join(sym_path,'web',medium.file_name)] for file_path in paths: remove(file_path) DBSession.delete(medium) return Response('ok')
def home(request): entry_level = ["NP"] if request.user and (request.user.check_role(Role.FAMILY) or request.user.check_role(Role.FRIENDS)): entry_level.append("RT") if request.user and request.user.check_role(Role.OWNER): entry_level.append("PS") entries = DBSession.query(Entry).filter(Entry.entry_type.in_(entry_level)).order_by(desc(Entry.date)).limit(4).all() return {"entries": entries}
def index(self): #Generate the supporting data for the search form years = range(2010, date.today().year + 1) + [''] months = range(1, 13) + [''] days = range(1, 32) + [''] entry_types = [(i.id, i.description) for i in DBSession.query(EntryType).all()] + [('', '')] search_components = dict(years = zip(years, years), months = zip(months, months), days = zip(days, days), entry_types = entry_types ) query = DBSession.query(Entry) \ .join(EntryType) entries = self.__paginate__(query, order='date', sort='desc') return {'entries' : entries, 'search_components' : search_components, 'filter_errors' : self.filter_errors, 'request' : self.request}
def __check_file_existance(self): '''Check if a file possibly exists in the file system. If it does then append a short unique identifier to make the name unique.''' #First check the Media table to see if it present. We will onlygg allow # the name to occur once. medium = (DBSession.query(Medium) .filter(Medium.file_name == self.upload_full_name) .first()) if medium: uid = '__' + str(uuid.uuid4())[0:8] self.upload_full_name = self.upload_name + uid + self.upload_extension
def upload(self): #-------------- # ToDO # - Better exception handling # - Add cleanup when exception occurs # - Remove any files that were uploaded, but be careful about errors # that occur because the file already exists. # - Remove media record if it exists. # - Add support for PNG? # - Videos? #-------------- #check the directory in the request against the Gallery directory user = self.request.user gallery = DBSession.query(Gallery).get(self.request.POST['id']) if not gallery or gallery.directory_name != self.request.POST['dir']: return Response(status_int=409) try: self.__sanitize_file_name(self.request.POST['Filename']) self.__check_file_existance() #sys.exit() input_file = self.request.POST['Filedata'].file self.__save_jpeg(input_file, gallery, 'original', create_symlink = False) self.__save_jpeg(input_file, gallery, 'raw') self.__save_jpeg(input_file, gallery, 'thumbs', 150) self.__save_jpeg(input_file, gallery, 'web', 800) except UploadError: return Response(status_int=409) except: return Response(status_int=409) #add database record medium = Medium(file_name = self.upload_full_name, created = datetime.now(), creator = user.id, gallery_id = gallery.id, media_type = MediumType.IMAGE) DBSession.add(medium) return Response('ok', status_int=200)
def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ engine = engine_from_config(settings, "sqlalchemy.") DBSession.configure(bind=engine) authn_policy = AuthTktAuthenticationPolicy("sosecret", callback=user_check) authz_policy = ACLAuthorizationPolicy() session_factory = session_factory_from_settings(settings) config = Configurator( settings=settings, root_factory="firsttest.models.RootFactory", session_factory=session_factory ) config.add_subscriber(add_renderer_globals, BeforeRender) config.set_authentication_policy(authn_policy) config.set_authorization_policy(authz_policy) config.set_request_property(get_user, "user", reify=True) config.add_static_view("static", "static") config.add_route("priv_res", "priv_res/*subpath") # config.add_view('firsttest.private_static.private_static_view', route_name='priv_res', permission='owner') config.add_route("home", "/") config.add_route("about", "about") config.add_route("login", "login") config.add_route("logout", "logout") config.add_route("entry_index", "entry/index") config.add_route("entry_view", "entry/view/{id}") config.add_route("entry_edit", "entry/edit/{id}") config.add_route("entry_new", "entry/new") config.add_route("entry_delete", "entry/delete") config.add_route("gallery_index", "gallery/index") config.add_route("gallery_new", "gallery/new") config.add_route("gallery_view", "gallery/view/{id}") config.add_route("gallery_edit", "gallery/edit/{id}") config.add_route("gallery_delete", "gallery/delete") config.add_route("gallery_rebuild_symlinks", "gallery/rebuild_symlinks") config.add_route("media_upload", "media/upload") config.add_route("media_update_ajax", "media/update_ajax") config.add_route("media_delete", "media/delete") config.add_route("media_rotate", "media/rotate/{medium_id}") config.add_route("media_restore", "media/restore/{medium_id}") config.add_route("media_view", "media/{medium_id}/{type}") config.scan() return config.make_wsgi_app()
def update_ajax(self): form = Form(self.request, schema=MediaNewSchema) if form.validate(): medium = DBSession.query(Medium).get(form.data['id']) medium.title = form.data['title'] medium.description = form.data['description'] return Response('ok', status_int=200) else: return Response('error', status_int=400)
def edit(self): entry_id = self.request.matchdict['id'] entry = DBSession.query(Entry).get(entry_id) entry_types = list((i.id, i.description) for i in DBSession.query(EntryType).all()) entry_types.append(('', '')) form = Form(self.request, schema=EntrySchema, obj=entry) if form.validate(): #TODO: This would be nice #entry.update(**form.data) entry.title = form.data['title'] entry.entry_type= form.data['entry_type'] entry.entry = form.data['entry'] return HTTPFound(location="/") return {'request' : self.request, 'entry' : entry, 'entry_types' : entry_types, 'form_rend' : FormRenderer(form)}
def view(self): gallery = Gallery.get(self.request.matchdict['id'], self.request.user) if gallery: media_query = DBSession.query(Medium).filter( Medium.gallery_id == gallery.id) media = self.__paginate__( media_query, order='medium_created', sort='desc') return {'request' : self.request, 'gallery' : gallery, 'media' : media} else: self.request.session.flash('Gallery not found') return HTTPFound(location=self.request.route_url('home'))
def delete(self): gallery_id = self.request.POST['id'] gallery = DBSession.query(Gallery).get(gallery_id) #Check if the gallery is empty if len(gallery.media): self.request.session.flash('Gallery %s is not empty. Only empty galleries can be deleted' % gallery.title) return HTTPFound(location=self.request.route_url('gallery_index')) #Get the paths directory_path = path.join(self.request.registry.settings['gallery.directory'], gallery.directory_name) paths = [path.join(directory_path,'thumbs'), path.join(directory_path,'web'), path.join(directory_path,'raw'), path.join(directory_path)] #Delete the paths for dir_path in paths: rmdir(dir_path) #Delete the database record DBSession.delete(gallery) self.request.session.flash('Gallery %s was deleted' % gallery.title) return HTTPFound(location=self.request.route_url('gallery_index'))
def rotate(self): #TODO: Need to get a media type flag in the media table medium_id = self.request.matchdict['medium_id'] direction = int(self.request.POST.get('direction')) if direction % 90 != 0: raise ValueError medium = DBSession.query(Medium).get(medium_id) lock_path = path.join( self.request.registry.settings['gallery.directory'], 'gallery.lock') medium_path = path.join( self.request.registry.settings['gallery.directory'], 'raw', medium.file_name) web_path = path.join( self.request.registry.settings['gallery.directory'], 'web', medium.file_name) thumb_path = path.join( self.request.registry.settings['gallery.directory'], 'thumbs', medium.file_name) try: with open(lock_path, 'a') as lock: fcntl.flock(lock, fcntl.LOCK_EX | fcntl.LOCK_NB) with open(medium_path, 'r') as original_raw: #create lock fcntl.flock(original_raw, fcntl.LOCK_EX | fcntl.LOCK_NB) original_media = Image.open(original_raw) rotated_media = original_media.rotate(direction) thumb_media = rotated_media.copy() web_media = rotated_media.copy() rotated_media.save(medium_path) #save the thumb version thumb_media.thumbnail((150, 150)) thumb_media.save(thumb_path) #save the web version web_media.thumbnail((800, 800)) web_media.save(web_path) #release the lock fcntl.flock(original_raw, fcntl.LOCK_UN) fcntl.flock(lock, fcntl.LOCK_UN) except: raise return Response('error') else: return Response('ok')
def view(self): query = DBSession.query(Entry) \ .filter(Entry.id == self.request.matchdict['id']) entry = query.first() return {'entry' : entry, 'request' : self.request}
def user_validate(cls, user, password): return DBSession.query(cls).filter(and_(cls.user == user, cls.password == func.password(password))).first()
def delete(self): entry_id = self.request.POST['id'] entry = DBSession.query(Entry).get(entry_id) self.request.session.flash('Deleted "%s" entry' % entry.title) DBSession.delete(entry) return HTTPFound(location=self.request.route_url('entry_index'))
def user_check(user, request): '''callback for the authentication policy''' user = DBSession.query(User).filter(User.user == user, ).first() return [(role.name) for role in user.roles] if user else None