from settings import Settings, SettingsRBPath, SettingsIPath, SettingsSPath from flask import request, render_template, redirect, url_for from flask_login import login_required, current_user from main import db, app, ma from shared import PA ################################################################################ # PA_UserState: preference data for a given user / path_type combo, so a given user # and their prefs for say the import path(s) and storage path(s) etc, each # path_type has different defaults, and keeping those works better ################################################################################ class PA_UserState(db.Model): __tablename__ = "pa_user_state" pa_user_dn = db.Column(db.String, db.ForeignKey('pa_user.dn'), primary_key=True ) path_type = db.Column(db.String, primary_key=True, unique=False, nullable=False ) noo = db.Column(db.String, unique=False, nullable=False ) grouping = db.Column(db.String, unique=False, nullable=False ) how_many = db.Column(db.Integer, unique=False, nullable=False ) st_offset = db.Column(db.Integer, unique=False, nullable=False ) size = db.Column(db.Integer, unique=False, nullable=False ) folders = db.Column(db.Boolean, unique=False, nullable=False ) fullscreen = db.Column(db.Boolean, unique=False, nullable=False ) root = db.Column(db.String, unique=False, nullable=False ) cwd = db.Column(db.String, unique=False, nullable=False ) ## for now being lazy and not doing a separate table until I settle on needed fields and when # only used if ptype == View view_eid = db.Column(db.Integer, unique=False, nullable=False ) orig_ptype = db.Column(db.String, unique=False, nullable=False ) # only used if view and orig_ptype was search orig_search_term = db.Column(db.String, unique=False, nullable=False ) def __repr__(self): return f"" ################################################################################ # States: class to store set of default values for viewing (order/size, etc.) # and if a request object (from a POST) is passed in, it returns those instead # it also handles the cwd appropriately, paths, fullscreen, search, etc. ################################################################################ class States(PA): def __init__(self, request): self.path_type='' self.url = request.path # this occurs ONLY when a POST to /view/ occurs (at this stage orig_url will be from an import, storage, bin or search) if 'orig_url' in request.form: self.path_type='View' # use orig url to define defaults/look up states for 'last' import/storage/bin/search url = request.form['orig_url'] # get the eid out of the url /view/ self.view_eid = request.path[6:] else: url = request.path self.view_eid = None if 'files_ip' in url or 'file_list_ip' in url: if self.path_type == "View": self.orig_ptype = 'Import' else: self.path_type = 'Import' elif 'files_sp' in url: if self.path_type == "View": self.orig_ptype = 'Storage' else: self.path_type = 'Storage' elif 'files_rbp' in url: if self.path_type == "View": self.orig_ptype = 'Bin' else: self.path_type = 'Bin' elif 'search' in url: # okay if we are a search, but came from a view then get last_search_state form prefs and use it if self.path_type == "View": last_search_state = PA_UserState.query.filter(PA_UserState.pa_user_dn==current_user.dn,PA_UserState.path_type=='Search').first() self.orig_search_term = last_search_state.orig_search_term self.orig_ptype = 'Search' else: self.orig_search_term = url[8:] self.path_type = 'Search' elif 'view' in url: # use url to get eid of viewed entry self.view_eid = self.url[6:] self.path_type="View" else: print( f"ERROR: DDP messed up, failed to match URL {url} for settings this will fail, redirecting to home" ) return if self.path_type == 'View': pref=PA_UserState.query.filter(PA_UserState.pa_user_dn==current_user.dn,PA_UserState.path_type==self.path_type,PA_UserState.view_eid==self.view_eid).first() else: pref=PA_UserState.query.filter(PA_UserState.pa_user_dn==current_user.dn,PA_UserState.path_type==self.path_type).first() if pref: self.folders=pref.folders self.noo=pref.noo self.grouping=pref.grouping self.how_many=pref.how_many self.offset=pref.st_offset self.size=pref.size self.root=pref.root self.cwd=pref.cwd self.orig_ptype=pref.orig_ptype self.orig_search_term=pref.orig_search_term else: self.folders=False self.noo="Oldest" self.grouping="None" self.how_many="50" self.offset="0" self.size="128" if self.path_type == "View": self.root='static/' + self.orig_ptype else: self.root='static/' + self.path_type self.cwd=self.root if not hasattr(self, 'orig_ptype'): self.orig_ptype=None if not hasattr(self, 'orig_search_term'): self.orig_search_term=None # the above are defaults, if we are here, then we have current values, use them instead if they are set -- AI: searches dont set them so then we use those in the DB first if request.method=="POST": if 'noo' in request.form: self.noo=request.form['noo'] if 'how_many' in request.form: self.how_many=request.form['how_many'] if 'offset' in request.form: self.offset=int(request.form['offset']) if 'grouping' in request.form: self.grouping=request.form['grouping'] # this can be null if we come from view by details if 'size' in request.form: self.size = request.form['size'] # seems html cant do boolean, but uses strings so convert if 'folders' not in request.form or request.form['folders'] == "False": self.folders=False elif request.form['folders'] == "True": self.folders=True # have to force grouping to None if we flick to folders from a flat # view with grouping (otherwise we print out group headings for # child content that is not in the CWD) self.grouping=None # possible to not be set for an AI: search if 'cwd' in request.form: self.cwd = request.form['cwd'] if 'fullscreen' in request.form: self.fullscreen=request.form['fullscreen'] else: self.fullscreen=False if 'prev' in request.form: self.offset -= int(self.how_many) if self.offset < 0: self.offset=0 if 'next' in request.form: self.offset += int(self.how_many) # now save pref if not pref: # if there is an PA_UserState( pa_user_dn=current_user.dn, # path_type=self.path_type ), then its for a different view_eid and we are viewing, delete it before we insert the new old_pref=PA_UserState.query.filter(PA_UserState.pa_user_dn==current_user.dn,PA_UserState.path_type==self.path_type).delete() pref=PA_UserState( pa_user_dn=current_user.dn, path_type=self.path_type, view_eid=self.view_eid, noo=self.noo, grouping=self.grouping, how_many=self.how_many, st_offset=self.offset, size=self.size, folders=self.folders, root=self.root, cwd=self.cwd, orig_ptype=self.orig_ptype, orig_search_term=self.orig_search_term ) else: pref.pa_user_dn=current_user.dn pref.path_type=self.path_type pref.view_eid=self.view_eid pref.noo=self.noo pref.grouping=self.grouping pref.how_many=self.how_many pref.st_offset=self.offset pref.size=self.size pref.folders=self.folders pref.root = self.root pref.cwd = self.cwd pref.orig_ptype = self.orig_ptype pref.orig_search_term = self.orig_search_term db.session.add(pref) db.session.commit() return ################################################################################ # /states -> GET only -> prints out list of all prefs (simple for now) ################################################################################ @app.route("/states", methods=["GET"]) @login_required def states(): states = PA_UserState.query.filter( PA_UserState.pa_user_dn==current_user.dn ).all() return render_template("states.html", states=states )