def initial_setup(): form = RegistrationForm() if form.validate_on_submit(): hashed_password = generate_password_hash( form.password.data).decode("utf-8") user = User(username=form.username.data, email=form.email.data, password=hashed_password) user.save() flash( f"Account created for {form.username.data} - Bands Added! You can now log in.", "success") uid = user.id if not Towns.objects(): setup_towns() resource_path = os.path.join(app.root_path, 'setup') with open(os.path.join(resource_path, 'band.json')) as f: file_data = json.load(f) bandz = [] for band in file_data: if 'date_created' in band.keys(): date_created = datetime.strptime(band.pop('date_created'), "%Y-%m-%dT%H:%M:%S") else: date_created = datetime.utcnow bandz.append( Band(**band, created_by=uid, date_created=date_created)) bands = Band.objects.insert(bandz) return redirect(url_for("user.login")) if len(list(Band.objects())) == 0: return render_template("setup.html", form=form, fullpage=True) else: flash(f"Initial Setup Complete", "success") return redirect(url_for("public.home"))
def delete_band(bname): band = Band.objects(band_name=bname).first() if band.created_by.id != current_user.id: abort(403) band.delete() flash("Band has been deleted!", "danger") return redirect(url_for("manage.manage_bands_home", band_view='recent'))
def preview_band(bname=None, band_view='recent', letter='a'): if bname == None: return redirect(url_for('manage.manage_bands_home', band_view='alpha')) band = Band.objects(band_name=bname).first() image_file = url_for('static_media', filename='band_profile_pics/' + band.media_assets.featured_image) return render_template("band_detail.html", band=band, image_file=image_file, display_breadcrumbs=True)
def mhome(): page = request.args.get("page", 1, type=int) user = User.objects(id=current_user.id).first() bands = Band.objects(created_by=user).order_by( '-date_updated', '-date_created').paginate(per_page=PER_PAGE, page=page) alphabet = {key: 0 for key in ALPHABET} return render_template("manage_bands.html", bands=bands, display_breadcrumbs=True, alphabet=alphabet)
def band_detail(bname=None, letter='a'): letter = request.args.get("letter") band = Band.objects(band_name=bname).first() if letter: return render_template("band_detail.html", band=band, letter=letter, display_breadcrumbs=True) else: return render_template("band_detail.html", band=band, display_breadcrumbs=True)
def check(): bandname = re.sub(' {2,}', ' ', request.args.get("q")) #print(bandname) results = list(Band.objects(band_name__iexact=bandname)) lastmatch = "" if len(bandname) < 1 or len(results) < 1: return jsonify(False), 400 elif len(lastmatch) > 0 and (results[0].lower() == lastmatch.lower().rstrip()): return jsonify(False), 400 elif len(lastmatch) > 0 and (result[0].lower() != lastmatch.lower().rstrip()): lastmatch = "" return jsonify(False), 400 else: lastmatch = results[0]["band_name"] print(lastmatch) return jsonify(True), 200
def list_genres(): if Band.objects(): #print("there are bands") genres = list( Band.objects.aggregate([{ "$unwind": "$genres" }, { "$group": { "_id": "null", "genres": { "$addToSet": "$genres" } } }, { "$sort": { "genres": 1 } }]))[0]["genres"] else: genres = ["rock"] #prevent choking on setup return genres
def home(): pipeline = [{ "$sample": { "size": SAMPLE_SIZE } }, { "$project": { "_id": 1, "band_name": 1, "strapline": 1, "hometown": 1, "profile": 1, "description": 1, "genres": 1, "media_assets": 1, "letter": { "$toLower": { "$substr": ["$catalogue_name", 0, 1] } } } }] bands = list(Band.objects().aggregate(pipeline)) bands = Pagination(bands, 1, SAMPLE_SIZE) count = bands.pages if bands.total > 0: bands_total = bands.total alphabet = {key: 0 for key in ALPHABET} return render_template("bands_list_home.html", bands=bands, count=count, bands_total=bands_total, display_breadcrumbs=False, alphabet=alphabet) else: return redirect(url_for('user.initial_setup'))
def update_band_profile(bname, letter, band_view): # flask-login uses a proxy that doesn't play nice with mongoengine # so current_user must be cast as user user = User.objects(id=current_user.id).first() band = Band.objects(band_name=bname).first() if band.created_by.id != current_user.id: abort(403) form = CreateUpdateBandForm() if form.validate_on_submit(): if form.media_assets.featured_image.data: picture_file = save_picture(form.media_assets.featured_image.data, band=True) band.media_assets.featured_image = picture_file if form.media_assets.featured_video.data: band.media_assets.featured_video = get_video_service_and_id( form.media_assets.featured_video.data) contact = Contact() contact.contact_name = form.contact_details.contact_name.data contact.contact_title = form.contact_details.contact_title.data contact.contact_generic_title = form.contact_details.contact_generic_title.data phone = phonenumbers.parse( form.contact_details.contact_numbers.phone.data, form.contact_details.contact_numbers.region.data) new_phone = Phone(mobile=bool( form.contact_details.contact_numbers.mobile.data), number=phonenumbers.format_number( phone, phonenumbers.PhoneNumberFormat.E164)) contact.contact_numbers = new_phone new_email = Email( email_title=form.contact_details.contact_emails.email_title.data, email_address=form.contact_details.contact_emails.email_address. data) contact.contact_emails = new_email weblinks = Links() weblinks.enquiries = form.enquiries_url.data band.solo = bool(form.solo.data) band.band_name = form.band_name.data band.catalogue_name = de_article(form.band_name.data) band.date_updated = datetime.utcnow band.description = form.description.data band.genres.clear() returned_genrelist = [ genre.strip().replace(' ', '-').lower() for gl in request.form.getlist('genres') for genre in gl.split(',') ] returned_genrelist.extend(genre.strip().replace(' ', '-').lower() for genre in form.genres_other.data.split( ',')) if form.genres_other.data else None band.genres = list(filter(None, set(returned_genrelist))) band.hometown = { "town": form.hometown.origin_town.data, "county": form.hometown.origin_county.data } band.profile = form.profile.data band.strapline = form.strapline.data band.contact_details = contact band.links = weblinks band.band_members.clear() band.band_members = [ BandMember(**member) for member in form.members.data ] band.save() flash("Band details updated!", "success") return redirect(url_for('manage.manage_bands_home', toggle='recent')) elif request.method == "GET": form.solo.data = band.solo form.band_name.data = band.band_name form.description.data = band.description form.strapline.data = band.strapline form.profile.data = band.profile form.contact_details.contact_name.data = band.contact_details.contact_name form.contact_details.contact_title.data = band.contact_details.contact_title form.contact_details.contact_generic_title.data = band.contact_details.contact_generic_title form.contact_details.contact_generic_title.data = band.contact_details.contact_generic_title form.contact_details.contact_numbers.mobile.data = band.contact_details.contact_numbers.mobile form.contact_details.contact_numbers.region.data = "None" form.contact_details.contact_numbers.phone.data = band.contact_details.contact_numbers.number form.contact_details.contact_emails.email_title.data = band.contact_details.contact_emails.email_title form.contact_details.contact_emails.email_address.data = band.contact_details.contact_emails.email_address form.media_assets.featured_video.data = ( ("https://www.youtube.com/watch?v=" if band.media_assets.featured_video["service"] == "youtube" else "https://www.vimeo.com/") + band.media_assets.featured_video["vid"] ) if band.media_assets.featured_video else None form.genres.data = ",".join(map(str, band.genres)) selected_county = band.hometown["county"] if band.hometown[ "county"] is not None else "Antrim" selected_town = band.hometown["town"] if band.hometown[ "town"] is not None else "none" genres = list_genres() form_legend = "Edit Band Profile" return render_template("manage_band_update_form.html", form=form, genrelist=genres, form_legend="Edit Band Profile", formpage=True, selected_county=selected_county, selected_town=selected_town, band=band, display_breadcrumbs=True)
def add_band(stage): genres = list_genres() if stage == 1: form = CreateBandForm1() if request.method == "POST" and form.validate_on_submit(): if form.band_name.validate(form): catalogue_name = de_article(form.band_name.data) if int( form.solo.data) == 0 else de_singularise( form.band_name.data) session["band"] = { "band_name": form.band_name.data, "catalogue_name": catalogue_name, "hometown": { "town": form.hometown.origin_town.data, "county": form.hometown.origin_county.data }, "solo": form.solo.data } form = CreateBandForm2() stage = 2 return render_template("manage_new_stage2_band_details.html", form=form, formpage=True, display_breadcrumbs=True, stage=stage, genrelist=genres, bname=session["band"]["band_name"]) else: form = CreateBandForm1() return render_template('manage_new_stage1_band_check.html', form=form, formpage=True, display_breadcrumbs=True, stage=1, title="Band/Artist Name") if stage == 2: form = CreateBandForm2() if request.method == "POST" and form.validate_on_submit(): returned_genrelist = [ genre.strip().replace(' ', '-').lower() for gl in request.form.getlist('genres') for genre in gl.split(',') ] returned_genrelist.extend( genre.strip().replace(' ', '-').lower() for genre in form.genres_other.data.split( ',')) if form.genres_other.data else None session["band"]["strapline"] = form.strapline.data session["band"]["description"] = form.description.data session["band"]["genres"] = list( filter(None, set(returned_genrelist))) session.modified = True form = CreateBandForm3() stage = 3 return render_template("manage_new_stage3_band_profile.html", form=form, formpage=True, display_breadcrumbs=True, stage=stage, bname=session["band"]["band_name"]) else: stage = 2 return render_template("manage_new_stage2_band_details.html", form=form, formpage=True, display_breadcrumbs=True, stage=stage, genrelist=genres, bname=session["band"]["band_name"]) if stage == 3: form = CreateBandForm3() if request.method == "POST" and form.validate_on_submit(): if form.featured_image.data: picture_file = save_picture(form.featured_image.data, band=True) featured_image = picture_file if picture_file else 'defaultband.jpg' else: featured_image = "defaultband.jpg" session["band"]["featured_image"] = featured_image session["band"]["profile"] = form.profile.data session["band"]["members"] = [{ **member } for member in form.members.data] session.modified = True form = CreateBandForm4() stage = 4 return render_template("manage_new_stage4_band_contact.html", form=form, formpage=True, display_breadcrumbs=True, stage=stage, bname=session["band"]["band_name"]) else: stage = 3 return render_template("manage_new_stage3_band_profile.html", form=form, formpage=True, display_breadcrumbs=True, stage=stage, bname=session["band"]["band_name"]) if stage == 4: form = CreateBandForm4() if request.method == "POST" and form.validate_on_submit(): user = User.objects(id=current_user.id).first() contact = Contact() contact.contact_name = form.contact_details.contact_name.data if len(form.contact_details.contact_title.data.rstrip()) == 0: contact.contact_title = "Enquiries" else: contact.contact_title = form.contact_details.contact_title.data if len(form.contact_details.contact_generic_title.data.rstrip() ) == 0: contact.contact_generic_title = "Enquiries" else: contact.contact_generic_title = form.contact_details.contact_generic_title.data _phone = phonenumbers.parse( form.contact_details.contact_numbers.phone.data, form.contact_details.contact_numbers.region.data) contact.contact_numbers = Phone( mobile=bool(form.contact_details.contact_numbers.mobile.data), number=phonenumbers.format_number( _phone, phonenumbers.PhoneNumberFormat.E164)) contact.contact_emails = Email(email_title=form.contact_details. contact_emails.email_title.data, email_address=form.contact_details. contact_emails.email_address.data) weblinks = Links(enquiries=form.enquiries_url.data) assets = Assets(featured_image=session["band"]["featured_image"]) if form.featured_video.data: assets["featured_video"] = get_video_service_and_id( form.featured_video.data) band = Band(band_name=session["band"]["band_name"], catalogue_name=session["band"]["catalogue_name"], genres=session["band"]["genres"], hometown=session["band"]["hometown"], description=session["band"]["description"], strapline=session["band"]["strapline"], profile=session["band"]["profile"], band_members=[ BandMember(**member) for member in session["band"]["members"] ], media_assets=assets, contact_details=contact, links=weblinks, created_by=user, solo=bool(session["band"]["solo"])) band.save() band_id = band.id # user.update(push__posts=post) if associating band to user band = Band.objects(id=band_id).first() return redirect( url_for('manage.preview_band', band_view='alpha', letter=band.catalogue_name[0], bname=band.band_name)) else: stage = 4 return render_template("manage_new_stage4_band_contact.html", form=form, stage=stage, bname=session["band"]["band_name"], display_breadcrumbs=True)
def manage_bands_home(band_view='recent', letter='a'): letter = '_' if letter == '1' else letter user = User.objects(id=current_user.id).first() page = request.args.get("page", 1, type=int) if band_view == 'recent': bands = Band.objects(created_by=user).order_by( '-date_updated', '-date_created').paginate(per_page=PER_PAGE, page=page) alphabet = {key: 0 for key in ALPHABET} return render_template("manage_bands.html", bands=bands, display_breadcrumbs=True, alphabet=alphabet) else: pipeline = [{ "$match": { "created_by": user.id } }, { "$facet": { "numbers_by_letter": [{ "$group": { "_id": { "$substr": ["$catalogue_name", 0, 1] }, "number_of_bands": { "$sum": 1 } } }], "bands_by_letter": [{ "$match": { "catalogue_name": { "$regex": f"^{str(letter.upper())}" } } }, { "$project": { "_id": 1, "band_name": 1, "catalogue_name": 1, "strapline": 1, "hometown": 1, "profile": 1, "description": 1, "genres": 1, "media_assets": 1, "letter": { "$toLower": { "$substr": ["$catalogue_name", 0, 1] } } } }, { "$sort": { "catalogue_name": 1 } }] } }] result = list(Band.objects.aggregate(pipeline))[0] bands_by_letter = Pagination(result["bands_by_letter"], int(page), 12) _alphabet = 'abcdefghijklmnopqrstuvwxyz_' alphabet = { obj["_id"].lower(): int(obj["number_of_bands"]) for obj in result["numbers_by_letter"] } alphabet = {key: alphabet.setdefault(key, 0) for key in _alphabet} alphabet['1'] = alphabet.pop( '_') #swap out for letter links 1 == '#' === '_' count = bands_by_letter.pages if bands_by_letter.total > 0: bands_total = bands_by_letter.total #bands = Band.objects(created_by=user).order_by('-catalogue_name').paginate(per_page=PER_PAGE, page=page) return render_template("manage_bands.html", bands=bands_by_letter, bands_total=bands_total, count=count, display_breadcrumbs=True, alphabet=alphabet) else: return 'no bands created' #redirect
def results(): search_terms = '' filters = {} text_query = None search = None town = None page = request.args.get("page", 1, type=int) if request.args: text_query = request.args.get("q") print(text_query) if text_query != None and len(text_query) == 0: text_query = None genres = request.args.getlist("genres") andor = request.args.get("andor") letter = request.args.get( "letter") if "letter" in request.args else "a" letter = '_' if letter == '1' else letter counties = request.args.getlist("counties") #print(counties) town = request.args.get("town") _request_arqs = request.args.to_dict(flat=False) _search = { key: _request_arqs[key] for key in _request_arqs if key not in ["page", "letter", "munster", "leinster", "connaght", "ulster"] } #re.sub('\=[0-9]*', '=', search) search = urllib.parse.urlencode(_search, doseq=True) # towns if town: search_terms += f"in {town}, County {counties[0]}" bands = Band.objects(hometown__town__iexact=town).paginate( per_page=PER_PAGE, page=page) search_terms = search_terms.replace( 'bands', 'band') if bands.total == 1 else search_terms return render_template("bands_list_results.html", bands=bands, search=search, count=bands.pages, bands_total=bands.total, search_terms=search_terms) # build search_terms text string if len(genres) > 0: if andor == 'f': search_terms = f"<b>{genres[0]}</b> bands" if ( len(genres) <= 1) else "<b>" + ", ".join( genres[:-1]) + " or " + genres[-1] + " bands</b>" else: search_terms = f"<b>{genres[0]}</b> bands" if ( len(genres) <= 1 ) else "<b>" + "-".join(genres) + " bands</b>" if len(counties) > 0: search_terms += f" in County {counties[0].title()}" if ( len(counties) <= 1) else " in counties: " + ", ".join( counties[:-1]) + " and " + counties[-1] if len(genres) == 0 and len(counties) == 0: search_terms = "bands" if text_query: search_terms += f" containing <b>'{text_query}'</b>" if text_query == None: search_terms += f" beginning with the letter <b>{letter.upper()}</b>" # build QSet filters ala mongoengine if len(genres) == 0: pass else: if len(genres) == 1: genres = genres.pop() filters['genres'] = genres else: if andor == "t": filters['genres__all'] = genres else: filters['genres__in'] = genres if len(counties) > 0: filters['hometown__county__in'] = counties if text_query != None: pipeline = [{ "$match": { "$text": { "$search": text_query } } }] #text has to be first pipeline if 'genres' in filters.keys(): pipeline.append({"$match": {"genres": filters['genres']}}) if 'genres__in' in filters.keys(): pipeline.append( {"$match": { "genres": { "$in": filters['genres__in'] } }}) if 'genres__all' in filters.keys(): pipeline.append( {"$match": { "genres": { "$all": filters['genres__all'] } }}) if 'genres__all' in filters.keys(): pipeline.append( {"$match": { "genres": { "$all": filters['genres__all'] } }}) if 'hometown__county__in' in filters.keys(): pipeline.append({ "$match": { "hometown.county": { "$in": filters['hometown__county__in'] } } }) # end with facets pipeline.extend([{ "$facet": { "numbers_by_letter": [{ "$group": { "_id": { "$substr": ["$catalogue_name", 0, 1] }, "number_of_bands": { "$sum": 1 } } }], "bands_by_letter": [{ "$project": { "_id": 1, "band_name": 1, "strapline": 1, "hometown": 1, "profile": 1, "description": 1, "genres": 1, "media_assets": 1, "letter": { "$toLower": { "$substr": ["$catalogue_name", 0, 1] } } } }] } }]) result = list(Band.objects.aggregate(pipeline))[0] bands = Pagination(result["bands_by_letter"], page, 12) _alphabet = 'abcdefghijklmnopqrstuvwxyz_' alphabet = { obj["_id"].lower(): int(obj["number_of_bands"]) for obj in result["numbers_by_letter"] } alphabet = {key: alphabet.setdefault(key, 0) for key in _alphabet} alphabet['1'] = alphabet.pop( '_') #swap out for letter links 1 == '#' === '_' count = bands.pages if bands.total > 0: bands_total = bands.total search_terms = search_terms.replace( 'bands', 'band') if bands_total == 1 else search_terms return render_template("bands_list_results.html", bands=bands, search=search, count=count, bands_total=bands_total, search_terms=search_terms, letter=letter) else: return render_template("bands_list_results.html", display_breadcrumbs=True, search_terms=search_terms, no_results=True) else: if not filters: # mobile test, smaller PER_PAGE? return redirect(url_for("public.home")) if filters: queryset = Q(**filters) # use _AND or _OR Q Node Combinations pipeline = [{ "$facet": { "numbers_by_letter": [{ "$group": { "_id": { "$substr": ["$catalogue_name", 0, 1] }, "number_of_bands": { "$sum": 1 } } }], "bands_by_letter": [{ "$match": { "catalogue_name": { "$regex": f"^{letter.upper()}" } } }, { "$project": { "_id": 1, "band_name": 1, "strapline": 1, "hometown": 1, "profile": 1, "description": 1, "genres": 1, "media_assets": 1, "letter": { "$toLower": { "$substr": ["$catalogue_name", 0, 1] } } } }, { "$sort": { "catalogue_name": 1 } }] } }] result = list(Band.objects.filter(queryset).aggregate(pipeline))[0] bands = Pagination(result["bands_by_letter"], page, 12) _alphabet = 'abcdefghijklmnopqrstuvwxyz_' alphabet = { obj["_id"].lower(): int(obj["number_of_bands"]) for obj in result["numbers_by_letter"] } alphabet = {key: alphabet.setdefault(key, 0) for key in _alphabet} alphabet['1'] = alphabet.pop( '_') #swap out for letter links 1 == '#' === '_' count = bands.pages if bands.total > 0: bands_total = bands.total total_bands_in_query = sum(alphabet.values()) search_terms += f'; there are {total_bands_in_query} resullts in total - use the alphabet to navigate between them.' return render_template("bands_list_results.html", bands=bands, search=search, count=count, bands_total=bands_total, search_terms=search_terms, alphabet=alphabet, letter=letter) elif len(list(Band.objects.filter( queryset))) > 0: #some results irrespective of letter alphaset = [ ltr for ltr in alphabet.keys() if alphabet[ltr] > 0 ] return render_template("bands_list_results.html", closest_letters=closest_letters( alphaset, letter), search=search, display_breadcrumbs=True, alphabet=alphabet, letter=letter) else: return render_template("bands_list_results.html", display_breadcrumbs=True, search_terms=search_terms, no_results=True)
def check_bandname_unique(form, field): bname = field.data if len(list(Band.objects(band_name__iexact=bname))) > 0: raise ValidationError("This band name is already taken; sorry.")