def channels_export(request): """Export channels to zone file.""" plugitapi = PlugItAPI(config.API_URL) retour = '' retour += '; GENERATED BY EBU RADIOVISMANAGER\n' retour += '; http://ebu.io/plugit/1\n\n' retour += '; Organization ' + plugitapi.get_orga( request.args.get('ebuio_orgapk')).name + '\n\n' oldStationName = '' for elem in Channel.query.join(Station).filter( Station.orga == int(request.args.get('ebuio_orgapk'))).order_by( Station.name, Channel.name).all(): if elem.station_name != oldStationName: retour += '\n;;; Station: ' + elem.station_name + '\n' oldStationName = elem.station_name retour += elem.dns_entry.ljust(40) + '\tIN\tCNAME\trdns.ebulabs.org.\n' if request.args.get('to') == 'file': retour_str = StringIO.StringIO() retour_str.write(str(retour)) retour_str.seek(0) return PlugItSendFile( retour_str, 'text/plain', True, plugitapi.get_orga(request.args.get('ebuio_orgapk')).name + '-radiodns.org.zone') return {'retour': retour}
def station_details(request, id): """Show the station.""" plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga(request.args.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by(ServiceProvider.codops).first() saved = request.args.get('saved') == 'yes' deleted = request.args.get('deleted') == 'yes' clients, stations = get_client_and_station(request, id) if stations == [None]: return PlugItRedirect('') if sp: sp = sp.json pictures = [] for elem in LogoImage.query.filter_by(orga=int(request.args.get('ebuio_orgapk'))).order_by(LogoImage.name).all(): pictures.append(elem.json) return {'clients_stations': combine_client_and_station(request, clients, stations, False), 'pictures': pictures, 'serviceprovider': sp, 'ebu_codops': orga.codops, 'saved': saved, 'deleted': deleted}
def stations_home(request): """Show the list of stations.""" plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga(request.args.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by(ServiceProvider.codops).first() stations = map( lambda station: station.json, Station.query.filter_by(orga=int(request.args.get('ebuio_orgapk')), parent=None).order_by(Station.name).all(), ) saved = request.args.get('saved') == 'yes' deleted = request.args.get('deleted') == 'yes' passworded = request.args.get('passworded') == 'yes' if sp: sp = sp.json return {'serviceprovider': sp, 'ebu_codops': orga.codops, 'stations': stations, 'saved': saved, 'deleted': deleted, 'passworded': passworded, 'RADIOTAG_ENABLED': config.RADIOTAG_ENABLED}
def stations_home(request): """Show the list of stations.""" plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga(request.args.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by( ServiceProvider.codops).first() stations = map( lambda station: station.json, Station.query.filter_by(orga=int(request.args.get('ebuio_orgapk')), parent=None).order_by(Station.name).all(), ) saved = request.args.get('saved') == 'yes' deleted = request.args.get('deleted') == 'yes' passworded = request.args.get('passworded') == 'yes' if sp: sp = sp.json return { 'serviceprovider': sp, 'ebu_codops': orga.codops, 'stations': stations, 'saved': saved, 'deleted': deleted, 'passworded': passworded, 'RADIOTAG_ENABLED': config.RADIOTAG_ENABLED }
def radiovis_gallery_delete(request, id): """Delete a picture.""" plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga( request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by( ServiceProvider.codops).first() object = Picture.query.filter_by(orga=int( request.args.get('ebuio_orgapk')), id=int(id)).first() # Remove File try: os.unlink(object.filename) except: pass # Remove from S3 try: awsutils.delete_public_image(sp, object.filename) except: pass db.session.delete(object) db.session.commit() return PlugItRedirect('radiovis/gallery/?deleted=yes')
def radiovis_gallery_delete(request, id): """Delete a picture.""" plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga(request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by(ServiceProvider.codops).first() object = Picture.query.filter_by(orga=int(request.args.get('ebuio_orgapk')), id=int(id)).first() # Remove File try: os.unlink(object.filename) except: pass # Remove from S3 try: awsutils.delete_public_image(sp, object.filename) except: pass db.session.delete(object) db.session.commit() return PlugItRedirect('radiovis/gallery/?deleted=yes')
def serviceprovider_edit(request, id): """Edit a serviceprovider.""" service_provider = None errors = [] plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga(request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')) if id != '-': service_provider = ServiceProvider.query.filter_by(id=id, codops=orga.codops).first() if not service_provider and id != '-': abort(404) if request.method == 'POST': if not service_provider: service_provider = ServiceProvider(int(request.form.get('ebuio_orgapk'))) service_provider.codops = orga.codops service_provider.short_name = request.form.get('short_name') service_provider.medium_name = request.form.get('medium_name') service_provider.long_name = request.form.get('long_name') service_provider.short_description = request.form.get('short_description') service_provider.long_description = request.form.get('long_description') service_provider.url_default = request.form.get('url_default') service_provider.default_language = request.form.get('default_language') service_provider.location_country = request.form.get('location_country') service_provider.postal_name = request.form.get('postal_name') service_provider.street = request.form.get('street') service_provider.city = request.form.get('city') service_provider.zipcode = request.form.get('zipcode') service_provider.phone_number = request.form.get('phone_number') service_provider.keywords = request.form.get('keywords') # Check errors if service_provider.medium_name == '': errors.append("Please set a medium name") if service_provider.short_description == '': errors.append("Please set a short description") # If no errors, save if not errors: if not service_provider.id: db.session.add(service_provider) db.session.commit() return PlugItRedirect('serviceprovider/?saved=yes') if service_provider: service_provider = service_provider.json return {'object': service_provider, 'errors': errors}
def channels_export(request): """Export channels to zone file.""" plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga(request.args.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by( ServiceProvider.codops).first() retour = '' retour += '; GENERATED BY EBU RADIODNS MANAGER v2015\n' retour += '; http://ebu.io/rdns\n\n' retour += '; Service Provider : ' + sp.medium_name + '\n' retour += '; EBU Codops : ' + sp.codops + '\n' retour += '; Organization : ' + orga.name + '\n' old_station_name = '' channel_elements = Channel.query.join(Station).filter( Station.orga == int(request.args.get('ebuio_orgapk'))).order_by( Station.name, Channel.name).all() dns_elements = [e.dns_entry for e in channel_elements] for elem in channel_elements: if elem.station_ascii_name != old_station_name: # If Channel Name changes output a new Station header retour += '\n;;; Station: ' + elem.station_ascii_name + '\n' old_station_name = elem.station_ascii_name # Ignore IP Channels in Zone File if elem.type_id != 'id': # Add Entries for all channels in ns and iso format wildcard_elem = '*' + elem.dns_entry[elem.dns_entry.find('.'):] wildcards = Channel.query.join(Station).filter( Channel.dns_entry == wildcard_elem).all() if wildcard_elem not in dns_elements or elem.dns_entry == wildcard_elem: retour += elem.dns_entry.ljust( 40) + '\tIN\tCNAME\t' + elem.station.fqdn + '\n' if elem.ecc_id: # Output ISO version if element has ECC retour += elem.dns_entry_iso.ljust( 40) + '\tIN\tCNAME\t' + elem.station.fqdn + '\n' if request.args.get('to') == 'file': retour_str = StringIO.StringIO() retour_str.write(str(retour)) retour_str.seek(0) return PlugItSendFile(retour_str, 'text/plain', True, sp.codops.lower() + '-radio-ebu-io-zone') return {'retour': retour}
def get_orga_service_provider(request): """ Returns the service provider and the organisation of the request if any present in body or url. :param request: The flask request. :return: The service provider and the organisation if any, (None, None) otherwise. """ plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga(request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by(ServiceProvider.codops).first() return orga, sp
def serviceprovider_check(request): """Check AWS State for Service Provider.""" plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga(request.args.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by(ServiceProvider.codops).first() if sp and not config.STANDALONE: return sp.check_aws() return {'isvalid': False}
def serviceprovider_check(request): """Check AWS State for Service Provider.""" plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga(request.args.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by( ServiceProvider.codops).first() if sp and not config.STANDALONE: return sp.check_aws() return {'isvalid': False}
def stations_linkserviceprovider(request, id): """Link station to its service provider.""" plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga(request.args.get('ebuio_orgapk')) if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by(ServiceProvider.codops).first() if sp: object = Station.query.filter_by(orga=int(request.args.get('ebuio_orgapk')), id=int(id)).first() object.service_provider = sp db.session.commit() return PlugItRedirect('stations/?serviceprovider=yes')
def channels_home(request): """Show the list of channels.""" plugitapi = PlugItAPI(config.API_URL) orga_id = request.args.get('ebuio_orgapk') or request.form.get( 'ebuio_orgapk') orga = plugitapi.get_orga(orga_id) expected_fqdn = 'radio.ebu.io' sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).first() if sp: expected_fqdn = sp.fqdn list = [] for elem in Channel.query.join(Station).filter( Station.orga == int(request.args.get('ebuio_orgapk'))).order_by( Station.name, Channel.type_id, Channel.name).all(): list.append(elem.json) stations = [] for station in Station.query.filter_by(orga=int( request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk'))).all(): stations.append(station.json) saved = request.args.get('saved') == 'yes' newchannelscount = request.args.get('newchannelscount') deleted = request.args.get('deleted') == 'yes' if sp: sp = sp.json return { 'list': list, 'stations': stations, 'expected_fqdn': expected_fqdn, 'serviceprovider': sp, 'ebu_codops': orga.codops, 'saved': saved, 'deleted': deleted, 'newchannelscount': newchannelscount }
def stations_linkserviceprovider(request, id): """Link station to its service provider.""" plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga(request.args.get('ebuio_orgapk')) if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by( ServiceProvider.codops).first() if sp: object = Station.query.filter_by(orga=int( request.args.get('ebuio_orgapk')), id=int(id)).first() object.service_provider = sp db.session.commit() return PlugItRedirect('stations/?serviceprovider=yes')
def serviceprovider_gallery_setdefault(request, id): """Delete an Image.""" plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga(request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by(ServiceProvider.codops).first() if sp: object = LogoImage.query.filter_by(codops=orga.codops, id=int(id)).first() if object: sp.default_logo_image = object db.session.commit() return PlugItRedirect('serviceprovider/?saved=yes')
def station_details(request, id): """Show the station.""" plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga(request.args.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by( ServiceProvider.codops).first() saved = request.args.get('saved') == 'yes' deleted = request.args.get('deleted') == 'yes' clients, stations = get_client_and_station(request, id) if stations == [None]: return PlugItRedirect('') if sp: sp = sp.json pictures = [] for elem in LogoImage.query.filter_by( orga=int(request.args.get('ebuio_orgapk'))).order_by( LogoImage.name).all(): pictures.append(elem.json) return { 'clients_stations': combine_client_and_station(request, clients, stations, False), 'pictures': pictures, 'serviceprovider': sp, 'ebu_codops': orga.codops, 'saved': saved, 'deleted': deleted }
def serviceprovider_gallery_delete(request, id): """Delete an Image.""" plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga( request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by( ServiceProvider.codops).first() object = LogoImage.query.filter_by(codops=orga.codops, id=int(id)).first() # Remove File try: os.unlink(object.filename) except: pass # Remove from S3 try: awsutils.delete_public_image(sp, object.filename) except: pass # Remove from S3 other sizes for size in config.RADIODNS_REQUIRED_IMAGESIZES: filename_prefix = '%dx%d/' % (size[0], size[1]) try: awsutils.delete_public_image(sp, filename_prefix + object.filename) except: pass import glob for f in glob.glob('media/uploads/serviceprovider/cache/*_L%s.png' % (object.id, )): os.unlink(f) db.session.delete(object) db.session.commit() return PlugItRedirect('serviceprovider/images/?deleted=yes')
def serviceprovider_gallery_delete(request, id): """Delete an Image.""" plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga(request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by(ServiceProvider.codops).first() object = LogoImage.query.filter_by(codops=orga.codops, id=int(id)).first() # Remove File try: os.unlink(object.filename) except: pass # Remove from S3 try: awsutils.delete_public_image(sp, object.filename) except: pass # Remove from S3 other sizes for size in config.RADIODNS_REQUIRED_IMAGESIZES: filename_prefix = '%dx%d/' % (size[0], size[1]) try: awsutils.delete_public_image(sp, filename_prefix + object.filename) except: pass import glob for f in glob.glob('media/uploads/serviceprovider/cache/*_L%s.png' % (object.id,)): os.unlink(f) db.session.delete(object) db.session.commit() return PlugItRedirect('serviceprovider/images/?deleted=yes')
def serviceprovider_gallery_setdefault(request, id): """Delete an Image.""" plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga( request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by( ServiceProvider.codops).first() if sp: object = LogoImage.query.filter_by(codops=orga.codops, id=int(id)).first() if object: sp.default_logo_image = object db.session.commit() return PlugItRedirect('serviceprovider/?saved=yes')
def serviceprovider_gallery_edit(request, id): """Edit an Image.""" object = None errors = [] plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga( request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by( ServiceProvider.codops).first() if id != '-': object = LogoImage.query.filter_by(id=int(id)).first() if request.method == 'POST': if not object: object = LogoImage(int(request.form.get('ebuio_orgapk'))) object.name = request.form.get('name') if sp: object.service_provider = sp object.codops = orga.codops def add_unique_postfix(fn): """__source__ = 'http://code.activestate.com/recipes/577200-make-unique-file-name/'""" if not os.path.exists(fn): return fn path, name = os.path.split(fn) name, ext = os.path.splitext(name) make_fn = lambda i: os.path.join(path, '%s(%d)%s' % (name, i, ext)) for i in xrange(2, sys.maxint): uni_fn = make_fn(i) if not os.path.exists(uni_fn): return uni_fn return None def unique_filename(fn): path, name = os.path.split(fn) name, ext = os.path.splitext(name) make_fn = lambda i: os.path.join(path, '%s%s' % (str(uuid.uuid4()), ext)) for i in xrange(2, sys.maxint): uni_fn = make_fn(i) if not os.path.exists(uni_fn): return uni_fn return None new_file = False if request.files: new_file = True file = request.files['file'] imageDirectoryPath = './media/uploads/serviceprovider/images/' if not os.path.exists(imageDirectoryPath): os.makedirs(imageDirectoryPath) if file: filename = secure_filename(file.filename) full_path = os.path.join( './media/uploads/serviceprovider/images/', filename) if not config.DEBUG: full_path = unique_filename(full_path) path, name = os.path.split(full_path) # Delete existing one and only create a unique filename otherwise if object.filename: try: os.unlink(object.filename) except: pass name = object.filename full_path = os.path.join(path, name) else: object.filename = name saved = file.save(full_path) # Check errors if object.name == '': errors.append("Please set a name") if object.filename == '' or object.filename is None: errors.append("Please upload an image") else: if imghdr.what(full_path) not in ['jpeg', 'png']: errors.append( "Image is not an png or jpeg image (it has header {})". format(imghdr.what(full_path))) os.unlink(full_path) object.filename = None else: errors.append("You must choose an image.") return {'errors': errors} # Check that we actually wrote the file if not os.path.isfile(full_path): errors.append( "Something went wrong while transforming your image. Try again later or contact the administration." ) # If no errors, save if not errors: # Upload MAIN Image to s3 if new_file: # Based on what size to replace only upload the required ones replace_size = request.form.get('replace_size') if not replace_size: try: if config.STANDALONE: send_image_to_mock_api( {name: open(full_path, 'rb')}) else: awsutils.upload_public_image(sp, name, full_path) except: pass # Create Required Image Sizes from PIL import Image for size in config.RADIODNS_REQUIRED_IMAGESIZES: size_prefix = '%dx%d' % (size[0], size[1]) if not replace_size or replace_size == size_prefix: image = Image.open(full_path) if image.size != (size[0], size[1]): image.thumbnail(size, Image.ANTIALIAS) background = Image.new( 'RGBA' if image.mode in ('RGBA', 'LA') else 'RGB', size, (255, 255, 255, 0)) background.paste(image, ((size[0] - image.size[0]) / 2, (size[1] - image.size[1]) / 2)) if config.DEBUG: pos = full_path.rfind(".") unique_path = full_path[: pos] + size_prefix + full_path[ pos:] else: unique_path = unique_filename(full_path) background.save(unique_path) else: # Keep original since size Match ! unique_path = full_path # Upload to s3 try: s3filename = size_prefix + '/' + name if config.STANDALONE: send_image_to_mock_api( {name: open(unique_path, 'rb')}, size_prefix) else: awsutils.upload_public_image( sp, s3filename, unique_path) if size == (32, 32): object.url32x32 = s3filename if size == (112, 32): object.url112x32 = s3filename if size == (128, 128): object.url128x128 = s3filename if size == (320, 240): object.url320x240 = s3filename if size == (600, 600): object.url600x600 = s3filename except: pass # Delete Temporary file os.unlink(unique_path) if not object.id: db.session.add(object) else: import glob for f in glob.glob( 'media/uploads/serviceprovider/cache/*_L%s.png' % (object.id, )): os.unlink(f) db.session.commit() try: # Remove local copy os.unlink(full_path) except: pass return PlugItRedirect('serviceprovider/images/?saved=yes') try: # Remove local copy os.unlink(full_path) except: pass if object: object = object.json return { 'object': object, 'sizes': config.RADIODNS_REQUIRED_IMAGESIZES, 'errors': errors }
def channels_edit(request, id): """Edit a channel.""" station = None channel = None errors = [] station_id = request.args.get('station_id') if station_id: station = Station.query.filter( Station.id == station_id, Station.orga == int( request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk'))).first() if id != '-': channel = Channel.query.join(Station).filter( Channel.id == int(id), Station.orga == int( request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk'))).first() if request.method == 'POST': if not channel: channel = Channel() channel.station_id = int(request.form.get('station')) # Get values for x in [ 'name', 'type_id', 'ecc_id', 'pi', 'frequency', 'eid', 'sid', 'scids', 'appty_uatype', 'pa', 'tx', 'cc', 'fqdn', 'stream_url', 'mime_type', 'bitrate', 'serviceIdentifier', 'fk_client' ]: val = request.form.get(x) if val == '': val = None setattr(channel, x, val) # Check errors if channel.name == '' or channel.name is None: errors.append("Please set a name") # Set to '' useless values, and check if values needed are present list_props = None for (type_id, _, type_props) in Channel.TYPE_ID_CHOICES: if type_id == channel.type_id: list_props = type_props if list_props is None: errors.append('Type not found!') if list_props: for x in [ 'ecc_id', 'pi', 'frequency', 'eid', 'sid', 'scids', 'appty_uatype', 'pa', 'tx', 'cc', 'fqdn', 'mime_type', 'stream_url', 'bitrate', 'serviceIdentifier' ]: if x in list_props: # Want it ? Keep it ! if x != 'appty_uatype' and x != 'pa': # Exception if getattr(channel, x) is None or getattr(channel, x) == '': errors.append(x + " cannot be empty") else: setattr(channel, x, None) # Check each prop if channel.pi is not None: if not re.match(r"^[a-fA-F0-9]{4}$", channel.pi): errors.append("pi must be 4 characters in hexadecimal") if channel.frequency is not None: if not re.match(r"^[0-9]{5}$", channel.frequency) and channel.frequency != '*': errors.append("frequency must be 5 digits or *") if channel.eid is not None: if not re.match(r"^[a-fA-F0-9]{4}$", channel.eid): errors.append("eid must be 4 characters in hexadecimal") if channel.sid is not None: if not re.match(r"^[a-fA-F0-9]{4}([a-fA-F0-9]{4})?$", channel.sid): errors.append("sid must be 4 or 8 characters in hexadecimal") if channel.scids is not None: if not re.match(r"^[a-fA-F0-9]([a-fA-F0-9]{2})?$", channel.scids): errors.append("scids must be 1 or 3 characters in hexadecimal") if channel.appty_uatype is not None: if not re.match(r"^[a-fA-F0-9]{2}\-[a-fA-F0-9]{3}$", channel.appty_uatype): errors.append( "appty_uatype must be 2 char hexadecimal, hyphen, 3 char hexadecimal" ) if channel.pa is not None: if channel.pa < 1 or channel.pa > 1023: errors.append("pa must be between 1 and 1023") if channel.tx is not None: if not re.match(r"^[a-fA-F0-9]{5}$", channel.tx): errors.append("tx must be 5 characters in hexadecimal") if channel.cc is not None: if not re.match(r"^[a-fA-F0-9]{3}$", channel.cc): errors.append("cc must be 3 characters in hexadecimal") if channel.fqdn is not None: channel.fqdn = channel.fqdn.rstrip('.') if not re.match( r"(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63}\.?$)", channel.fqdn): errors.append("fqdn must be a domain name") if channel.serviceIdentifier is not None: if not re.match(r"^[a-z0-9]{,16}$", channel.serviceIdentifier): errors.append( "serviceIdentifier must be up to 16 letters or number, lowercase" ) if channel.mime_type is not None: if not re.match(r"^([!-\.0-~]{1,}\/[!-\.0-~]{1,})+$", channel.mime_type): errors.append("mime_type must be of format string/string ") if channel.bitrate is not None: if not re.match(r"^[0-9]+$", channel.bitrate): errors.append("bitrate must be digits") # Check station sta = Station.query.filter_by(id=channel.station_id).first() if not sta or sta.orga != int(request.form.get('ebuio_orgapk')): errors.append("Please set a station") # If no errors, save if not errors: if not channel.id: db.session.add(channel) db.session.commit() # Update the service entries for the channel channel.updateservicefollowingentry() if station: return PlugItRedirect( ('stations/%s/channels?saved=yes') % station.id) else: return PlugItRedirect('channels/?saved=yes') default_country = None plugitapi = PlugItAPI(config.API_URL) orga_id = request.args.get('ebuio_orgapk') or request.form.get( 'ebuio_orgapk') orga = plugitapi.get_orga(orga_id) if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by( ServiceProvider.codops).first() if sp: cc_obj = CountryCode.query.filter_by( iso=sp.location_country).first() if cc_obj: default_country = cc_obj.id if channel: channel = channel.json stations = [] for s in Station.query.filter_by(orga=int( request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')), parent=None).all(): stations.append(s.json) if station: station = station.json clients = [gen_default_client()] + Clients.query.filter_by( orga=orga_id).order_by(Clients.id).all() return { 'object': channel, 'errors': errors, 'stations': stations, 'station': station, 'types_id': Channel.TYPE_ID_CHOICES, 'default_country': default_country, 'clients': map(lambda c: c.json, clients) }
def serviceprovider_gallery_edit(request, id): """Edit an Image.""" object = None errors = [] plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga(request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by(ServiceProvider.codops).first() if id != '-': object = LogoImage.query.filter_by(id=int(id)).first() if request.method == 'POST': if not object: object = LogoImage(int(request.form.get('ebuio_orgapk'))) object.name = request.form.get('name') if sp: object.service_provider = sp object.codops = orga.codops def add_unique_postfix(fn): """__source__ = 'http://code.activestate.com/recipes/577200-make-unique-file-name/'""" if not os.path.exists(fn): return fn path, name = os.path.split(fn) name, ext = os.path.splitext(name) make_fn = lambda i: os.path.join(path, '%s(%d)%s' % (name, i, ext)) for i in xrange(2, sys.maxint): uni_fn = make_fn(i) if not os.path.exists(uni_fn): return uni_fn return None def unique_filename(fn): path, name = os.path.split(fn) name, ext = os.path.splitext(name) make_fn = lambda i: os.path.join(path, '%s%s' % (str(uuid.uuid4()), ext)) for i in xrange(2, sys.maxint): uni_fn = make_fn(i) if not os.path.exists(uni_fn): return uni_fn return None new_file = False if request.files: new_file = True file = request.files['file'] imageDirectoryPath = './media/uploads/serviceprovider/images/' if not os.path.exists(imageDirectoryPath): os.makedirs(imageDirectoryPath) if file: filename = secure_filename(file.filename) full_path = os.path.join('./media/uploads/serviceprovider/images/', filename) if not config.DEBUG: full_path = unique_filename(full_path) path, name = os.path.split(full_path) # Delete existing one and only create a unique filename otherwise if object.filename: try: os.unlink(object.filename) except: pass name = object.filename full_path = os.path.join(path, name) else: object.filename = name saved = file.save(full_path) # Check errors if object.name == '': errors.append("Please set a name") if object.filename == '' or object.filename is None: errors.append("Please upload an image") else: if imghdr.what(full_path) not in ['jpeg', 'png']: errors.append("Image is not an png or jpeg image (it has header {})".format(imghdr.what(full_path))) os.unlink(full_path) object.filename = None else: errors.append("You must choose an image.") return {'errors': errors} # Check that we actually wrote the file if not os.path.isfile(full_path): errors.append( "Something went wrong while transforming your image. Try again later or contact the administration.") # If no errors, save if not errors: # Upload MAIN Image to s3 if new_file: # Based on what size to replace only upload the required ones replace_size = request.form.get('replace_size') if not replace_size: try: if config.STANDALONE: send_image_to_mock_api({name: open(full_path, 'rb')}) else: awsutils.upload_public_image(sp, name, full_path) except: pass # Create Required Image Sizes from PIL import Image for size in config.RADIODNS_REQUIRED_IMAGESIZES: size_prefix = '%dx%d' % (size[0], size[1]) if not replace_size or replace_size == size_prefix: image = Image.open(full_path) if image.size != (size[0], size[1]): image.thumbnail(size, Image.ANTIALIAS) background = Image.new('RGBA' if image.mode in ('RGBA', 'LA') else 'RGB', size, (255, 255, 255, 0)) background.paste(image, ((size[0] - image.size[0]) / 2, (size[1] - image.size[1]) / 2)) if config.DEBUG: pos = full_path.rfind(".") unique_path = full_path[:pos] + size_prefix + full_path[pos:] else: unique_path = unique_filename(full_path) background.save(unique_path) else: # Keep original since size Match ! unique_path = full_path # Upload to s3 try: s3filename = size_prefix + '/' + name if config.STANDALONE: send_image_to_mock_api({name: open(unique_path, 'rb')}, size_prefix) else: awsutils.upload_public_image(sp, s3filename, unique_path) if size == (32, 32): object.url32x32 = s3filename if size == (112, 32): object.url112x32 = s3filename if size == (128, 128): object.url128x128 = s3filename if size == (320, 240): object.url320x240 = s3filename if size == (600, 600): object.url600x600 = s3filename except: pass # Delete Temporary file os.unlink(unique_path) if not object.id: db.session.add(object) else: import glob for f in glob.glob('media/uploads/serviceprovider/cache/*_L%s.png' % (object.id,)): os.unlink(f) db.session.commit() try: # Remove local copy os.unlink(full_path) except: pass return PlugItRedirect('serviceprovider/images/?saved=yes') try: # Remove local copy os.unlink(full_path) except: pass if object: object = object.json return {'object': object, 'sizes': config.RADIODNS_REQUIRED_IMAGESIZES, 'errors': errors}
def radiovis_gallery_edit(request, id): """Edit a channel.""" object = None errors = [] plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga(request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by(ServiceProvider.codops).first() if id != '-': object = Picture.query.filter_by(orga=int(request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')), id=int(id)).first() if request.method == 'POST': if not object: object = Picture(int(request.form.get('ebuio_orgapk'))) if sp: object.image_url_prefix = sp.image_url_prefix object.name = request.form.get('name') object.radiotext = request.form.get('radiotext') object.radiolink = request.form.get('radiolink') def add_unique_postfix(fn): """__source__ = 'http://code.activestate.com/recipes/577200-make-unique-file-name/'""" if not os.path.exists(fn): return fn path, name = os.path.split(fn) name, ext = os.path.splitext(name) make_fn = lambda i: os.path.join(path, '%s(%d)%s' % (name, i, ext)) for i in xrange(2, sys.maxint): uni_fn = make_fn(i) if not os.path.exists(uni_fn): return uni_fn return None def unique_filename(fn): path, name = os.path.split(fn) name, ext = os.path.splitext(name) make_fn = lambda i: os.path.join(path, '%s%s' % (str(uuid.uuid4()), ext)) for i in xrange(2, sys.maxint): uni_fn = make_fn(i) if not os.path.exists(uni_fn): return uni_fn return None new_file = False if request.files: new_file = True file = request.files['file'] if file: filename = secure_filename(file.filename) full_path = unique_filename('media/uploads/radiovis/gallery/' + filename) path, name = os.path.split(full_path) file.save(full_path) if object.filename: try: os.unlink(object.filename) except: pass object.filename = name # Check errors if object.name == '': errors.append("Please set a name") if object.radiotext == '': errors.append("Please set a text") if object.radiolink == '': errors.append("Please set a link") if object.filename == '' or object.filename is None: errors.append("Please upload an image") else: if imghdr.what(full_path) not in ['jpeg', 'png']: errors.append("Image is not an png or jpeg image") os.unlink(full_path) object.filename = None else: im = Image.open(full_path) if im.size != (320, 240): errors.append("Image must be 320x240") del im os.unlink(full_path) object.filename = None pieces = urlparse.urlparse(object.radiolink) if pieces.scheme not in ['http', 'https', 'ftp']: errors.append("The link is not valid") # If no errors, save if not errors: # Upload to s3 if new_file: try: if config.STANDALONE: send_image_to_mock_api({name: open(full_path, 'rb')}) else: awsutils.upload_public_image(sp, name, full_path) except: pass # TODO Clean up old images on S3 if not object.id: db.session.add(object) db.session.commit() try: # Remove local copy os.unlink(full_path) except: pass return PlugItRedirect('radiovis/gallery/?saved=yes') try: # Remove local copy os.unlink(full_path) except: pass if object: object = object.json return {'object': object, 'errors': errors}
def radiovis_gallery_edit(request, id): """Edit a channel.""" object = None errors = [] plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga( request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')) sp = None if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by( ServiceProvider.codops).first() if id != '-': object = Picture.query.filter_by(orga=int( request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')), id=int(id)).first() if request.method == 'POST': if not object: object = Picture(int(request.form.get('ebuio_orgapk'))) if sp: object.image_url_prefix = sp.image_url_prefix object.name = request.form.get('name') object.radiotext = request.form.get('radiotext') object.radiolink = request.form.get('radiolink') def add_unique_postfix(fn): """__source__ = 'http://code.activestate.com/recipes/577200-make-unique-file-name/'""" if not os.path.exists(fn): return fn path, name = os.path.split(fn) name, ext = os.path.splitext(name) make_fn = lambda i: os.path.join(path, '%s(%d)%s' % (name, i, ext)) for i in xrange(2, sys.maxint): uni_fn = make_fn(i) if not os.path.exists(uni_fn): return uni_fn return None def unique_filename(fn): path, name = os.path.split(fn) name, ext = os.path.splitext(name) make_fn = lambda i: os.path.join(path, '%s%s' % (str(uuid.uuid4()), ext)) for i in xrange(2, sys.maxint): uni_fn = make_fn(i) if not os.path.exists(uni_fn): return uni_fn return None new_file = False if request.files: new_file = True file = request.files['file'] if file: filename = secure_filename(file.filename) full_path = unique_filename('media/uploads/radiovis/gallery/' + filename) path, name = os.path.split(full_path) file.save(full_path) if object.filename: try: os.unlink(object.filename) except: pass object.filename = name # Check errors if object.name == '': errors.append("Please set a name") if object.radiotext == '': errors.append("Please set a text") if object.radiolink == '': errors.append("Please set a link") if object.filename == '' or object.filename is None: errors.append("Please upload an image") else: if imghdr.what(full_path) not in ['jpeg', 'png']: errors.append("Image is not an png or jpeg image") os.unlink(full_path) object.filename = None else: im = Image.open(full_path) if im.size != (320, 240): errors.append("Image must be 320x240") del im os.unlink(full_path) object.filename = None pieces = urlparse.urlparse(object.radiolink) if pieces.scheme not in ['http', 'https', 'ftp']: errors.append("The link is not valid") # If no errors, save if not errors: # Upload to s3 if new_file: try: if config.STANDALONE: send_image_to_mock_api({name: open(full_path, 'rb')}) else: awsutils.upload_public_image(sp, name, full_path) except: pass # TODO Clean up old images on S3 if not object.id: db.session.add(object) db.session.commit() try: # Remove local copy os.unlink(full_path) except: pass return PlugItRedirect('radiovis/gallery/?saved=yes') try: # Remove local copy os.unlink(full_path) except: pass if object: object = object.json return {'object': object, 'errors': errors}
def serviceprovider_edit(request, id): """Edit a serviceprovider.""" service_provider = None errors = [] plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga( request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')) if id != '-': service_provider = ServiceProvider.query.filter_by( id=id, codops=orga.codops).first() if not service_provider and id != '-': abort(404) if request.method == 'POST': if not service_provider: service_provider = ServiceProvider( int(request.form.get('ebuio_orgapk'))) service_provider.codops = orga.codops service_provider.short_name = request.form.get('short_name') service_provider.medium_name = request.form.get('medium_name') service_provider.long_name = request.form.get('long_name') service_provider.short_description = request.form.get( 'short_description') service_provider.long_description = request.form.get( 'long_description') service_provider.url_default = request.form.get('url_default') service_provider.default_language = request.form.get( 'default_language') service_provider.location_country = request.form.get( 'location_country') service_provider.postal_name = request.form.get('postal_name') service_provider.street = request.form.get('street') service_provider.city = request.form.get('city') service_provider.zipcode = request.form.get('zipcode') service_provider.phone_number = request.form.get('phone_number') service_provider.keywords = request.form.get('keywords') # Check errors if service_provider.medium_name == '': errors.append("Please set a medium name") if service_provider.short_description == '': errors.append("Please set a short description") # If no errors, save if not errors: if not service_provider.id: db.session.add(service_provider) db.session.commit() return PlugItRedirect('serviceprovider/?saved=yes') if service_provider: service_provider = service_provider.json return {'object': service_provider, 'errors': errors}
def channels_import(request): """Import a list of channel.""" data = '' new_channels_count = 0 global_errors = [] error_lines = [] if request.method == 'POST': # Get values data = request.form.get('importdata') station_id = int(request.form.get('station')) # Foreach Line for line in data.split("\n"): line = line.strip() if line: errors = [] # Extract data channel = string_to_channel(line, station_id) # Check errors if channel is None: errors.append( "Could not convert text line to channel for line " + line) else: if channel.name == '' or channel.name is None: errors.append("Please set a name") # Set to '' useless values, and check if values needed are present list_props = None for (type_id, _, type_props) in Channel.TYPE_ID_CHOICES: if type_id == channel.type_id: list_props = type_props if list_props is None: errors.append('Type not found oO') if list_props: for x in [ 'ecc_id', 'pi', 'frequency', 'eid', 'sid', 'scids', 'appty_uatype', 'pa', 'tx', 'cc', 'fqdn', 'stream_url', 'mime_type', 'bitrate', 'serviceIdentifier' ]: if x in list_props: # Want it ? Keep it ! if x != 'appty_uatype' and x != 'pa': # Exception if getattr(channel, x) is None or getattr( channel, x) == '': errors.append(x + " cannot be empty") else: setattr(channel, x, None) # Check each prop if channel.pi is not None: if not re.match(r"^[a-fA-F0-9]{4}$", channel.pi): errors.append( "pi must be 4 characters in hexadecimal for line " + line) if channel.frequency is not None: if not re.match(r"^[0-9]{5}$", channel.frequency ) and channel.frequency != '*': errors.append("frequency must be 5 digits or *") if channel.eid is not None: if not re.match(r"^[a-fA-F0-9]{4}$", channel.eid): errors.append( "eid must be 4 characters in hexadecimal for line " + line) if channel.sid is not None: if not re.match(r"^[a-fA-F0-9]{4}([a-fA-F0-9]{4})?$", channel.sid): errors.append( "sid must be 4 or 8 characters in hexadecimal for line " + line) if channel.scids is not None: if not re.match(r"^[a-fA-F0-9]([a-fA-F0-9]{2})?$", channel.scids): errors.append( "scids must be 1 or 3 characters in hexadecimal for line " + line) if channel.appty_uatype is not None: if not re.match(r"^[a-fA-F0-9]{2}\-[a-fA-F0-9]{3}$", channel.appty_uatype): errors.append( "appty_uatype must be 2 char hexadecimal, hyphen, 3 char hexadecimal for line " + line) if channel.pa is not None: if channel.pa < 1 or channel.pa > 1023: errors.append( "pa must be between 1 and 1023 for line " + line) if channel.tx is not None: if not re.match(r"^[a-fA-F0-9]{5}$", channel.tx): errors.append( "tx must be 5 characters in hexadecimal for line " + line) if channel.cc is not None: if not re.match(r"^[a-fA-F0-9]{3}$", channel.cc): errors.append( "cc must be 3 characters in hexadecimal for line " + line) if channel.fqdn is not None: if not re.match( r"(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63}\.?$)", channel.fqdn): errors.append( "fqdn must be a domain name for line " + line) if channel.serviceIdentifier is not None: if not re.match(r"^[a-z0-9]{,16}$", channel.serviceIdentifier): errors.append( "serviceIdentifier must be up to 16 characters in hexadecimal, lowercase for line " + line) if channel.mime_type is not None: if not re.match(r"^\w+\/\w+$", channel.mime_type): errors.append( "mime_type must be of format string/string " + line) if channel.bitrate is not None: if not re.match(r"^[0-9]+$", channel.bitrate): errors.append("bitrate must be digits") # Check station sta = Station.query.filter_by( id=channel.station_id).first() if not sta or sta.orga != int( request.form.get('ebuio_orgapk')): errors.append("Please set a station") # If no errors, save if not errors: if not channel.id: db.session.add(channel) new_channels_count += 1 db.session.commit() else: global_errors = global_errors + errors error_lines.append(line) if not global_errors and new_channels_count > 0: return PlugItRedirect('channels/?saved=yes&newchannelscount=' + str(new_channels_count)) if new_channels_count == 0: global_errors.insert(0, "No new channel added.") else: global_errors.insert( 0, str(new_channels_count) + " new channel were already added.") default_country = None plugitapi = PlugItAPI(config.API_URL) orga = plugitapi.get_orga( request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk')) if orga.codops: sp = ServiceProvider.query.filter_by(codops=orga.codops).order_by( ServiceProvider.codops).first() if sp: cc_obj = Ecc.query.filter_by(iso=sp.location_country).first() default_country = cc_obj.id stations = [] for station in Station.query.filter_by(orga=int( request.args.get('ebuio_orgapk') or request.form.get('ebuio_orgapk'))).all(): stations.append(station.json) return { 'importdata': data, 'errors': global_errors, 'error_lines': error_lines, 'stations': stations, 'types_id': Channel.TYPE_ID_CHOICES, 'default_country': default_country }