Example #1
0
def velruse_login_complete_view(context, request):
    provider = context.provider_name
    profile = context.profile
    username = profile['accounts'][0]['username']
    root = root_factory(request)
    adapter = request.registry.queryMultiAdapter(
        (root, request), IUserLocator)
    if adapter is None:
        adapter = DefaultUserLocator(root, request)
    user = adapter.get_user_by_login(username)
    if user is None:
        registry = request.registry
        principals = find_service(root, 'principals')
        user = principals.add_user(username, registry=registry)
        performer = registry.content.create('Performer')
        root['performers'][username] = performer
        performer.title = profile['displayName']
        addresses = profile.get('addresses')
        if addresses:
            user.email = performer.email = addresses[0]['formatted']
        photos = profile.get('photos')
        if photos:
            performer.photo_url = photos[0]['value']
        performer.age = colander.null
        performer.sex = user.favorite_genre = None
        performer.user = user
        set_acl(performer, [(Allow, user.__oid__, ['yss.edit-profile'])])
        location = request.resource_url(performer, 'edit.html')
    else:
        location = request.resource_url(root['performers'][username])
    headers = remember(request, get_oid(user))
    return HTTPFound(location, headers=headers)
Example #2
0
    def finish_retime(self):
        request = self.request
        file_stream = self.request.params['data'].file

        song = self.context
        # XXX do this as methods of the song
        song.retiming = True
        song.retiming_blob = Blob()

        with song.retiming_blob.open("w") as saveto:
            shutil.copyfileobj(file_stream, saveto)

        redis = get_redis(self.request)
        redisval = f'{self.context.__oid__}|{time.time()}'
        redis.rpush("yss.new-retimings", redisval)
        event = ObjectModified(song)
        self.request.registry.subscribers((event, song), None)
        set_acl(song,
                [
                    (Allow, request.user.__oid__, ['yss.edit']),
                    (Deny, Everyone, ['yss.indexed']),
                ]
        )
        self.request.session.flash(
            'This is gonna take a while. It\'s not magic. But after the '
            'retiming is done processing, listen and watch to see that your '
            'spoken lyrics line up with the song, and hit accept if '
            'you are happy with the result. Remember: it\'s just karaoke.',
            'info')
        return self.request.resource_url(self.context, '@@retime')
Example #3
0
def persona_login(context, request):
    check_csrf_token(request)
    email = verify_persona_assertion(request)
    root = root_factory(request)
    adapter = request.registry.queryMultiAdapter(
        (root, request), IUserLocator)
    if adapter is None:
        adapter = DefaultUserLocator(root, request)
    user = adapter.get_user_by_email(email)
    if user is None:
        registry = request.registry
        username = '******' % email
        principals = find_service(root, 'principals')
        user = principals.add_user(username, registry=registry)
        user.email = email
        performer = registry.content.create('Performer')
        root['performers'][username] = performer
        performer.user = user
        set_acl(performer, [(Allow, user.__oid__, ['yss.edit-profile'])])
        location = request.resource_url(performer, 'edit.html')
        performer.title = email
        performer.email = email
        performer.photo_url = persona_gravatar_photo(request, email)
        performer.age = colander.null
        performer.sex = user.favorite_genre = None
        location = request.resource_url(performer, 'edit.html')
    else:
        location = request.resource_url(root['performers'][user.__name__])
    headers = remember(request, get_oid(user))
    request.response.headers.extend(headers)
    return {'redirect': location, 'success': True}
Example #4
0
def change_acl_callback(content, workflow, transition, request):
    new_acl = []
    current_acl = get_acl(content, [])
    admins = find_service(content, 'principals')['groups']['admins']
    recording = content
    performer = getattr(recording, 'performer', None)
    if performer is None:
        return # eyeroll, foil workflow initialization via subscriber
    user = performer.user
    owner_id = user.__oid__
    admins_id = admins.__oid__
    for ace in current_acl:
        # preserve all permissions defined by other subsystems (like "like")
        if ace == DENY_ALL:
            continue
        _, _, perms = ace
        if perms is ALL_PERMISSIONS:
            continue
        if not is_nonstr_iter(perms):
            perms = [perms]
        if 'view' in perms or 'yss.indexed' in perms or 'yss.edit' in perms:
            continue
        new_acl.append(ace)

    PRIVATE_ACES = [
        (Allow, admins_id, ALL_PERMISSIONS),
        (Allow, owner_id, ('view',)),
        (Allow, owner_id, ('yss.edit',)),
        DENY_ALL,
        ]

    if transition:
        # if not initial state
        if transition['name'].startswith('Make public'):
            new_acl.extend([
                (Allow, Everyone, ('view',)),
                (Allow, Everyone, ('yss.indexed',)),
                (Allow, owner_id, ('yss.edit',)),
            ])
        if transition['name'].startswith('Make private'):
            new_acl.extend(PRIVATE_ACES)
        if transition['name'].startswith('Make authenticated-only'):
            new_acl.extend([
                (Allow, admins_id, ALL_PERMISSIONS),
                (Allow, 'system.Authenticated', ('view',)),
                (Allow, 'system.Authenticated', ('yss.indexed',)),
                (Allow, owner_id, ('yss.edit',)),
                DENY_ALL,
            ])
    else:
        # initial state
        new_acl.extend(PRIVATE_ACES)

    set_acl(content, new_acl)
Example #5
0
    def after_create(self, inst, registry):
        request = get_current_request()
        if request is None:
            return

        user = request.user

        acl = getattr(self, '__acl__', [])
        acl.append(
            (Allow, get_oid(user), ('sdi.view', 'sdi.edit-properties',
                                    'sdi.add-content', 'sdi.manage-contents')))
        set_acl(inst, acl, registry=registry)
Example #6
0
def root_added(event):
    registry = event.registry
    root = event.object
    acl = list(root.__acl__)
    acl.extend(
        [
        (Allow, Everyone, 'view'),
        (Allow, Everyone, 'yss.indexed'),
        (Allow, Authenticated, 'yss.like'),
        ]
    )
    set_acl(root, acl)
    root.title = root.sdi_title = 'You Should Sing'
    root.max_framerate = 30

    root['catalogs'].add_catalog('yss')

    root['songs'] = registry.content.create('Songs')
    set_acl(root['songs'], [
        (Allow, Authenticated, 'yss.upload'),
        (Allow, Authenticated, 'yss.record'),
    ])

    performers = root['performers'] = registry.content.create('Performers')

    blameme = registry.content.create('Performer')
    performers['blameme'] = blameme
    blameme['recordings'] = registry.content.create('Recordings')
    blameme['photo'] = registry.content.create('File')
    blameme['photo_thumbnail'] = registry.content.create('File')

    blameme.user = root['principals']['users']['admin']

    timings_json = pkg_resources.resource_string(
        'yss', 'blackbird.json').decode('utf-8')
    song = registry.content.create(
        'Song',
        'Blackbird',
        'The Beatles',
        timings=timings_json,
        lyrics=timings_json,
        audio_stream=pkg_resources.resource_stream('yss', 'blackbird.opus')
    )
    root['songs']['blackbird'] = song
    song.mimetype = 'audio/opus'
    song.uploader = blameme
Example #7
0
 def accept_retime(self):
     song = self.context
     song.timings = song.alt_timings
     song.alt_timings = ''
     new_acl = []
     acl = get_acl(song)
     for ace in acl:
         if ace[0] == Deny and ace[2] == ['yss.indexed']:
             continue
         new_acl.append(ace)
     set_acl(song, new_acl)
     event = ObjectModified(song)
     self.request.registry.subscribers((event, song), None)
     self.request.session.flash(
         'Retime accepted, song will show up in searches, and may now be '
         'recorded by everyone. Nice work.', 'info')
     return self.request.resource_url(self.context, '@@retime')
Example #8
0
def set_acms_for_app_root(event):
    """Set/update :term:`acm`s for the root object of the pyramid application.

    :param event: this function should be used as a subscriber for the
                  :class:`pyramid.interfaces.IApplicationCreated` event.
                  That way everytime the application starts the root `acm`
                  is updated.

    The `root_acm` (:func:`root_acm_asset`) is extended by the :term:`acm`
    returned by the :class:`adhocracy_core.authorization.IRootACMExtension`
    adapter.

    In addition all permissions are granted the god user.
    """
    root, closer = get_root(event.app)
    acl = [god_all_permission_ace]
    acl += _get_root_extension_acl(root, event.app.registry)
    acl += _get_root_base_acl()
    old_acl = get_acl(root, [])
    if old_acl == acl:
        return
    set_acl(root, acl, event.app.registry)
    transaction.commit()
    closer()
Example #9
0
def _add_acl_to_app_root(context, registry):
    acl = acm_to_acl(root_acm, registry)
    set_acl(context, acl, registry=registry)
    set_god_all_permissions(context, registry)
Example #10
0
def create_profile(context, request):
    schema = CreatePerformerSchema().bind(request=request, context=context)
    form = deform.Form(schema, buttons=('Save',))
    rendered = None
    if 'Save' in request.POST:
        controls = request.POST.items()
        try:
            appstruct = form.validate(controls)
        except deform.ValidationFailure as e:
            rendered = e.render()
        else:
            registry = request.registry
            principals = find_service(context, 'principals')
            root = find_root(context)
            username = appstruct['username']
            userid = request.session.get('userid', username) # socmed signups
            user = principals.add_user(userid, registry=registry)
            performer = registry.content.create('Performer')
            root['performers'][username] = performer
            performer['recordings'] = registry.content.create('Recordings')
            performer['invitations'] = registry.content.create('Invitations')
            performer['invitations'].add_more(10)
            phdata = appstruct['photo']
            fp = phdata.get('fp')
            if fp is not None:
                for photoname, photosize in (
                        ('photo', (320, 320)),
                        ('photo_thumbnail', (40, 40)),
                ):
                    photo = registry.content.create('File')
                    alsoProvides(photo, IPerformerPhoto) # for view lookup
                    performer[photoname] = photo
                    fp.seek(0)
                    pil_image = PIL.Image.open(fp)
                    if pil_image.size[0] != photosize[0]: # width
                        pil_image.thumbnail(photosize, PIL.Image.ANTIALIAS)
                    buffer = io.BytesIO()
                    pil_image.save(buffer, 'png')
                    buffer.seek(0)
                    photo.upload(buffer)
                    photo.mimetype = 'image/png'
            # NB: performer.user required before setting tzname and email
            performer.user = user
            performer.title = appstruct['title']
            performer.email = appstruct['email']
            performer.birthdate = appstruct['birthdate']
            performer.sex = appstruct['sex']
            performer.genre = appstruct['genre']
            performer.tzname = appstruct['tzname']
            performer.location = appstruct['location']
            ctindex = find_index(context, 'system', 'content_type')
            nameindex = find_index(context, 'system', 'name')
            q = ctindex.eq('Invitation') & nameindex.eq(
                appstruct['invite_code'].upper())
            results = list(q.execute())
            if results:
                invitation = results[0]
                invitation.redeemer = performer
                invitation.redemption_date = datetime.datetime.utcnow(
                ).replace(tzinfo=pytz.UTC)
            set_acl(performer, [(Allow, user.__oid__, ['yss.edit'])])
            headers = remember(request, get_oid(user))
            request.session.flash('Your account is created. Welcome!', 'info')
            return HTTPFound(request.resource_url(performer), headers=headers)
    else:
        appstruct = {
            'csrf_token': request.session.get_csrf_token(),
            'username': request.session.get('profilename', ''),
            'title': request.session.get('realname', ''),
            'email': '',
            'photo':colander.null,
            'birthdate': colander.null,
            'sex': colander.null,
            'genre': colander.null,
            'tzname': colander.null,
            'location':colander.null,
        }
    if rendered is None:
        rendered = form.render(appstruct, readonly=False)
    return {
        'form':rendered,
        }
Example #11
0
def main(argv=sys.argv):
    def usage(msg):
        print (msg)
        sys.exit(2)
    description = "Import a set of video files into the songs folder"
    parser = optparse.OptionParser(
        "usage: %prog config_uri input_filenames",
        description=description
    )
    parser.add_option(
        '-d',
        '--dir',
        dest='directory',
        help='Use this directory as working directory instead of a tempdir'
        )
    parser.add_option(
        '-o',
        '--overwrite',
        dest='overwrite',
        help='Overwrite songs in the songs folder instead of skipping dupes',
        action='store_true',
        )
    parser.add_option(
        '-a',
        '--av-only',
        dest='av_only',
        help='Overwrite audio/video of songs only in songs folder (not metadata)',
        action='store_true',
        )
    opts, args = parser.parse_args(argv[1:])
    overwrite = opts.overwrite
    av_only = opts.av_only

    try:
        config_uri = args[0]
    except KeyError:
        usage('Requires a config_uri as an argument')

    outdir = opts.directory or tempfile.mkdtemp()
    setup_logging(config_uri)
    env = bootstrap(config_uri)
    root = env['root']
    registry = env['registry']
    songs = root['songs']
    restricted = songs.get('restricted')
    if restricted is None:
        restricted = registry.content.create('Folder')
        songs['restricted'] = restricted
        set_acl(
            restricted,
            [(Allow, 'system.Authenticated', ['view']),
             (Allow, 'system.Authenticated', ['yss.indexed']),
             (Deny, 'system.Everyone', ['view']),
             (Deny, 'system.Everyone', ['yss.indexed'])]
        )

    try:
        for input_filename in args[1:]:
            logging.info(input_filename)
            md5 = hashlib.md5()
            f = open(input_filename, 'rb')
            while True:
                data = f.read(1<<19)
                if not data:
                    break
                md5.update(data)
            hexdigest = md5.hexdigest()
            command = [
                'ffmpeg',
                '-i',
                input_filename,
                '-f',
                'ffmetadata',
                'pipe:1',
                ]
            print (' '.join([ shlex.quote(s) for s in command ]))
            proc = subprocess.Popen(
                command,
                universal_newlines=True,
                stdout=subprocess.PIPE,
            )
            stdout, _ = proc.communicate()
            md = {}
            for line in stdout.split('\n'):
                if '=' in line:
                    k, v = line.strip().split('=', 1)
                    md[k.lower()] = v[1:-1]
            name = slug.slug(md['title'])
            title=md['title']
            artist=md['artist']
            name = '%s-%s' % (name, hexdigest)
            if name in restricted and not (overwrite or av_only):
                logging.info('Not overwriting %s' % name)
                continue
            stream = open(input_filename, 'rb')
            if name in restricted and av_only:
                logger.info('replacing video for %s' % title)
                song = restricted[name]
                song.upload(stream)
                song.mimetype = 'video/webm'
            else:
                try:
                    del restricted[name]
                except KeyError:
                    pass
                song = registry.content.create(
                    'Song',
                    title=title,
                    artist=artist,
                    lyrics='',
                    timings='',
                    stream=stream,
                    mimetype='video/webm',
                    )
                restricted[name] = song
            blameme = root['performers']['blameme']
            song.uploader = blameme
            event = ObjectModified(song)
            registry.subscribers((event, song), None)
            print ('done %s, %s, %s' % (name, title, artist))
            transaction.commit()
            songs._p_jar.sync()
    finally:
        if not opts.directory:
            shutil.rmtree(outdir, ignore_errors=True)
Example #12
0
 def load(self, context):
     if context.exists(self.fn):
         acl = context.load_yaml(self.fn)
         set_acl(context.resource, acl)
Example #13
0
def _add_acl_to_app_root(context, registry):
    acl = acm_to_acl(root_acm, registry)
    set_acl(context, acl, registry=registry)
    set_god_all_permissions(context, registry)
Example #14
0
 def upload(self):
     context = self.context
     request = self.request
     schema = SongUploadSchema().bind(request=request, context=context)
     form = deform.Form(schema, buttons=('Save',))
     rendered = None
     if 'Save' in request.POST:
         controls = request.POST.items()
         try:
             appstruct = form.validate(controls)
         except deform.ValidationFailure as e:
             rendered = e.render()
         else:
             audio_file = appstruct['audio_file']
             tmpdir = request.registry.settings['substanced.uploads_tempdir']
             job = uuid.uuid4().hex
             jobdir = os.path.join(tmpdir, job)
             try:
                 try:
                     os.makedirs(jobdir)
                 except FileExistsError:
                     pass
                 inputfn = os.path.join(jobdir, 'inputfile')
                 inputfile = open(inputfn, 'wb')
                 fp = audio_file['fp']
                 fp.seek(0)
                 shutil.copyfileobj(fp, inputfile)
                 M = 1024 * 1024 * 1024
                 md5 = hashlib.md5()
                 f = open(inputfn, 'rb')
                 while True:
                     data = f.read(M)
                     if not data:
                         break
                     md5.update(data)
                 opus_filename = os.path.join(jobdir, 'output.opus')
                 ffmpeg.input(inputfn).output(
                     opus_filename, ar=48000).run()
                 song = request.registry.content.create(
                     'Song',
                     appstruct['title'],
                     appstruct['artist'],
                     appstruct['lyrics'],
                     timings='',
                     audio_stream=open(opus_filename, 'rb'),
                     audio_mimetype='audio/opus',
                     language=appstruct['language'],
                 )
             finally:
                 shutil.rmtree(jobdir, ignore_errors=True)
             request.session.flash(
                 'Song uploaded. Now voice lyrics like William Shatner in '
                 'rhythm with the song in order to time the karaoke '
                 'display text.',
                 'info')
             song.language = appstruct['language']
             song.genre = appstruct['genre']
             song.year = appstruct['year']
             songname = slug.slug(appstruct['title'])
             hashval = md5.hexdigest()
             songname = f'{songname}-{hashval}'
             if songname in self.context:
                 request.session.flash('this song has already been uploaded')
                 raise HTTPFound(request.resource_url(self.context))
             self.context[songname] = song
             song.uploader = request.performer # NB must be after seating
             set_acl(song,
                     [
                         (Allow, request.user.__oid__, ['yss.edit']),
                         (Deny, Everyone, ['yss.indexed']),
                     ]
             )
             event = ObjectModified(song)
             self.request.registry.subscribers((event, song), None)
             return HTTPFound(request.resource_url(song, '@@retime'))
     else:
         appstruct = {
             'title':colander.null,
             'artist':colander.null,
             'audio_file':colander.null,
             'genre':colander.null,
             'language':colander.null,
             'lyrics':colander.null,
             'year':colander.null,
             }
     if rendered is None:
         rendered = form.render(appstruct, readonly=False)
     return {'form':rendered, 'page_title':'Upload Song'}
Example #15
0
 def load(self, context):
     if context.exists(self.fn):
         acl = context.load_yaml(self.fn)
         set_acl(context.resource, acl)