Exemple #1
0
def get_files(ids):
    '''
    Recibe lista de tuplas de tamaño 3 (como devueltas por get_ids de search)
    y devuelve los ficheros del mongo correspondiente que no estén bloqueados.
    Si se recibe un fichero bloqueado, lo omite y bloquea en el sphinx.

    @type ids: iterable de tuplas de tamaño 3 o mayor
    @param ids: lista de tuplas (mongoid, id servidor, id sphinx)

    @yield: cada uno de los resultados de los ids en los mongos

    '''
    toblock = []
    already = False
    for f in filesdb.get_files(ids, servers_known = True, bl = None):
        if f["bl"] == 0 or f["bl"] is None:
            yield f
        else:
            toblock.append(mid2bin(f["_id"]))

    # bloquea en sphinx los ficheros bloqueados
    if toblock:
        cache.cacheme = False
        id_list = {i[0]:i[2] for i in ids}
        block_files( sphinx_ids=[id_list[i] for i in toblock] )
Exemple #2
0
def get_id_server_from_search(mongoid, file_name):
    uri1, uri2, uri3 = struct.unpack("III", mid2bin(mongoid))
    sph = sphinxapi2.SphinxClient()
    sph.SetMatchMode(sphinxapi2.SPH_MATCH_ALL)
    sph.SetServer(current_app.config["SERVICE_SPHINX"], current_app.config["SERVICE_SPHINX_PORT"])
    sph.SetConnectTimeout(current_app.config["SERVICE_SPHINX_CONNECT_TIMEOUT"])
    sph.SetMaxQueryTime(current_app.config["SERVICE_SPHINX_MAX_QUERY_TIME"])
    sph.SetLimits(0, 1, 1, 1)
    sph.SetFilter("uri1", [uri1])
    sph.SetFilter("uri2", [uri2])
    sph.SetFilter("uri3", [uri3])

    if file_name:
        query = " ".join(split_phrase(file_name, True)[0])
        query = sph.EscapeString(query)
    else:
        query = ""
    query = sph.Query(query, "idx_files")
    warn = error = ret = None
    if query and "total" in query and query["total"] == 1:
        if query["warning"]:
            warn = query["warning"]
        if query["error"]:
            error = query["error"]
        ret = query["matches"][0]["id"] / 0x100000000
    else:
        warn = sph.GetLastWarning()
        error = sph.GetLastError()
    if warn:
        logging.warn(
            "Warning on a Sphinx response",
            extra={"method": "get_id_server_from_search", "id": mongoid, "orig_msg": warn},
        )
    if error:
        logging.error(
            "Error on a Sphinx response",
            extra={"method": "get_id_server_from_search", "id": mongoid, "orig_msg": error},
        )
    sph.Close()
    feedbackdb.notify_indir(mongoid, ret)
    return ret
Exemple #3
0
def get_files(ids):
    '''
    Recibe lista de tuplas de tamaño 3 (como devueltas por get_ids de search)
    y devuelve los ficheros del mongo correspondiente que no estén bloqueados.
    Si se recibe un fichero bloqueado, lo omite y bloquea en el sphinx.

    @type ids: iterable de tuplas de tamaño 3 o mayor
    @param ids: lista de tuplas (mongoid, id servidor, id sphinx)

    @yield: cada uno de los resultados de los ids en los mongos

    '''
    already = False
    files = filesdb.get_files(ids, servers_known = True, bl = None)
    for r in files:
        if r["bl"] == 0 or r["bl"] is None:
            yield r
        elif not already:
            already = True
            id_list = {i[0]:i[2] for i in ids}
            block_files( sphinx_ids=[id_list[mid2bin(i["_id"])] for i in files if i["bl"] != 0 and not i["bl"] is None ])
Exemple #4
0
def block_files(sphinx_ids=(), mongo_ids=(), block=True):
    """
    Recibe ids de sphinx u ObjectIDs de mongodb de ficheros y los bloquea en el
    sphinx (atributo bl a 1).
    """
    sph = sphinxapi2.SphinxClient()
    sph.SetServer(current_app.config["SERVICE_SPHINX"], current_app.config["SERVICE_SPHINX_PORT"])
    sph.SetConnectTimeout(current_app.config["SERVICE_SPHINX_CONNECT_TIMEOUT"])
    sph.SetMatchMode(sphinxapi2.SPH_MATCH_FULLSCAN)
    sph.SetLimits(0, 1, 1, 1)
    sphinx_ids = list(sphinx_ids)
    if mongo_ids:
        # Si recibo ids de mongo, ejecuto una petición múltiple para encontrar
        # los ids de sphinx
        for i in xrange(0, len(mongo_ids), 32):
            # Proceso los ids de mongo en grupos de 32, que es el límite que
            # me permite sphinx
            for mongoid in mongo_ids[i : i + 32]:
                uri1, uri2, uri3 = struct.unpack("III", mid2bin(mongoid))
                sph.ResetFilters()
                sph.SetFilter("uri1", [uri1])
                sph.SetFilter("uri2", [uri2])
                sph.SetFilter("uri3", [uri3])
                sph.AddQuery("", "idx_files", "Searching fileid %s" % mid2hex(mongoid))
            results = sph.RunQueries()
            if results:
                for result in results:
                    if "matches" in result and result["matches"]:
                        sphinx_ids.append(result["matches"][0]["id"])
                    if "warning" in result and result["warning"]:
                        logging.warning(result["warning"])
            else:
                logging.error(sph.GetLastError())
    sph.ResetFilters()
    tr = sph.UpdateAttributes("idx_files", ["bl"], {i: [1 if block else 0] for i in sphinx_ids})
    sph.Close()
    return tr == len(sphinx_ids) and tr == len(mongo_ids)
Exemple #5
0
def download(file_id,file_name=None):
    '''
    Muestra el archivo a descargar, votos, comentarios y archivos relacionados
    '''
    def choose_filename_related(file_data):
        '''
        Devuelve el nombre de fichero elegido
        '''
        f=init_data(file_data)
        choose_filename(f)
        return f

    def comment_votes(file_id,comment):
        '''
        Obtiene los votos de comentarios
        '''
        comment_votes={}
        if "vs" in comment:
            for i,comment_vote in enumerate(usersdb.get_file_comment_votes(file_id)):
                if not comment_vote["_id"] in comment_votes:
                    comment_votes[comment_vote["_id"][0:40]]=[0,0,0]

                if comment_vote["k"]>0:
                    comment_votes[comment_vote["_id"][0:40]][0]+=1
                else:
                    comment_votes[comment_vote["_id"][0:40]][1]+=1

                #si el usuario esta logueado y ha votado se guarda para mostrarlo activo
                if current_user.is_authenticated() and comment_vote["u"]==current_user.id:
                    comment_votes[comment_vote["_id"][0:40]][2]=comment_vote["k"]

        return comment_votes

    #guardar los parametros desde donde se hizo la busqueda si procede
    args={}
    if request.referrer:
        querystring = urlparse(request.referrer).query
        if querystring:
            for params in u(querystring).encode("UTF-8").split("&"):
                param=params.split("=")
                if len(param) == 2:
                    args[param[0]]=u(urllib.unquote_plus(param[1]))

    try:
        file_id=url2mid(file_id)
    except Exception as e:
        # Comprueba que se trate de un ID antiguo
        try:
            possible_file_id = filesdb.get_newid(file_id)
            if possible_file_id is None:
                logging.warn("%s - %s" % (e, file_id))
                flash("link_not_exist", "error")
                abort(404)
            return redirect(
                url_for(".download", file_id=mid2url(possible_file_id), file_name=file_name),
                code=301)
        except filesdb.BogusMongoException as e:
            logging.exception(e)
            abort(503)

    try:
        data = filesdb.get_file(file_id, bl = None)
    except filesdb.BogusMongoException as e:
        logging.exception(e)
        abort(503)

    # intenta sacar el id del servidor de sphinx,
    # resuelve inconsistencias de los datos
    if not data:
        sid = get_id_server_from_search(file_id, file_name)
        if sid:
            try:
                data = filesdb.get_file(file_id, sid = sid, bl = None)
            except filesdb.BogusMongoException as e:
                logging.exception(e)
                abort(503)

    if data:
        if not data["bl"] in (0, None):
            if data["bl"] == 1: flash("link_not_exist", "error")
            elif data["bl"] == 3: flash("error_link_removed", "error")
            goback = True
            #block_files( mongo_ids=(data["_id"],) )
            abort(404)
    else:
        flash("link_not_exist", "error")
        abort(404)

    #obtener los datos
    file_data=fill_data(data, True, file_name)
    if file_data["view"]["sources"]=={}: #si tiene todos los origenes bloqueados
        flash("error_link_removed", "error")
        abort(404)

    save_visited([file_data])
    # Título
    title = u(file_data['view']['fn'])
    g.title = u"%s \"%s%s\"%s%s" % (
        _(file_data['view']['action']).capitalize(),
        title[:50],
        "..." if len(title) > 50 else "",
        " - " if g.title else "",
        g.title)

    #obtener los archivos relacionados
    related_files = search_related(split_file(file_data["file"])[0][:10])
    bin_file_id=mid2bin(file_id)
    ids=sorted({fid[0:3] for related in related_files for fid in get_ids(related) if fid[0]!=bin_file_id})[:5]
    files_related=[choose_filename_related(data) for data in get_files(ids)]

    #si el usuario esta logueado se comprueba si ha votado el archivo para el idioma activo
    vote=None
    if current_user.is_authenticated():
        vote=usersdb.get_file_vote(file_id,current_user,g.lang)

    if vote is None:
        vote={"k":0}

    #formulario para enviar comentarios
    form = CommentForm(request.form)
    if request.method=='POST' and current_user.is_authenticated() and (current_user.type is None or current_user.type==0) and form.validate():
        usersdb.set_file_comment(file_id,current_user,g.lang,form.t.data)
        form.t.data=""
        flash("comment_published_succesfully")
        #actualizar el fichero con la suma de los comentarios por idioma
        filesdb.update_file({"_id":file_id,"cs":usersdb.get_file_comments_sum(file_id),"s":file_data["file"]["s"]},direct_connection=True)

    #si tiene comentarios se guarda el número del comentario, el usuario que lo ha escrito, el comentario en si y los votos que tiene
    comments=[]
    if "cs" in file_data["file"]:
        comments=[(i,usersdb.find_userid(comment["_id"][0:24]),comment,comment_votes(file_id,comment)) for i,comment in enumerate(usersdb.get_file_comments(file_id,g.lang),1)]

    return render_template('files/download.html',file=file_data,args=args,vote=vote,files_related=files_related,comments=comments,form=form)
Exemple #6
0
def download(file_id,file_name=None):
    '''
    Muestra el archivo a descargar, votos, comentarios y archivos relacionados
    '''
    def choose_filename_related(file_data):
        '''
        Devuelve el nombre de fichero elegido
        '''
        f=init_data(file_data)
        choose_filename(f)
        return f

    def comment_votes(file_id,comment):
        '''
        Obtiene los votos de comentarios
        '''
        comment_votes={}
        if "vs" in comment:
            for i,comment_vote in enumerate(usersdb.get_file_comment_votes(file_id)):
                if not comment_vote["_id"] in comment_votes:
                    comment_votes[comment_vote["_id"][0:40]]=[0,0,0]

                if comment_vote["k"]>0:
                    comment_votes[comment_vote["_id"][0:40]][0]+=1
                else:
                    comment_votes[comment_vote["_id"][0:40]][1]+=1

                #si el usuario esta logueado y ha votado se guarda para mostrarlo activo
                if current_user.is_authenticated() and comment_vote["u"]==current_user.id:
                    comment_votes[comment_vote["_id"][0:40]][2]=comment_vote["k"]

        return comment_votes

    if file_name is not None:
        g.title = _("download").capitalize()+" "+file_name+" - "+g.title
    else:
        g.title =_("download").capitalize()

    #guardar los parametros desde donde se hizo la busqueda si procede
    args={}
    if request.referrer:
        querystring = urlparse(request.referrer).query
        if querystring:
            for params in querystring.split("&"):
                param=params.split("=")
                if len(param) == 2:
                    args[param[0]]=u(urllib.unquote_plus(param[1]))

    try:
        file_id=url2mid(file_id)
    except BaseException as e:
        logging.warn((e, file_id))
        abort(404)

    data = filesdb.get_file(file_id, bl = None)

    if data:
        if not data["bl"] in (0, None):
            if data["bl"] == 1: flash("link_not_exist", "error")
            elif data["bl"] == 3: flash("error_link_removed", "error")
            goback = True
            #block_files( mongo_ids=(data["_id"],) )
            abort(404)
    else:
        flash("link_not_exist", "error")
        abort(404)

    #obtener los datos
    file_data=fill_data(data, True, file_name)
    save_visited([file_data])

    #obtener los archivos relacionados
    related_files = search_related(split_file(file_data["file"])[0][0:50])
    bin_file_id=mid2bin(file_id)
    ids=sorted({fid for related in related_files for fid in get_ids(related) if fid[0]!=bin_file_id})[:5]
    files_related=[choose_filename_related(data) for data in get_files(ids)]

    #si el usuario esta logueado se comprueba si ha votado el archivo para el idioma activo
    vote=None
    if current_user.is_authenticated():
        vote=usersdb.get_file_vote(file_id,current_user,g.lang)

    if vote is None:
        vote={"k":0}

    #formulario para enviar comentarios
    form = CommentForm(request.form)
    if request.method=='POST' and current_user.is_authenticated() and (current_user.type is None or current_user.type==0) and form.validate():
        usersdb.set_file_comment(file_id,current_user,g.lang,form.t.data)
        form.t.data=""
        flash("comment_published_succesfully")
        #actualizar el fichero con la suma de los comentarios por idioma
        filesdb.update_file({"_id":file_id,"cs":usersdb.get_file_comments_sum(file_id),"s":file_data["file"]["s"]},direct_connection=True)

    #si tiene comentarios se guarda el número del comentario, el usuario que lo ha escrito, el comentario en si y los votos que tiene
    comments=[]
    if "cs" in file_data["file"]:
        comments=[(i,usersdb.find_userid(comment["_id"][0:24]),comment,comment_votes(file_id,comment)) for i,comment in enumerate(usersdb.get_file_comments(file_id,g.lang),1)]

    return render_template('files/download.html',file=file_data,args=args,vote=vote,files_related=files_related,comments=comments,form=form)
Exemple #7
0
 def get_id_server_from_search(self, file_id, file_name, timeout=1000):
     return self.sphinx.get_id_server_from_search(mid2bin(file_id), escape_string(" ".join(slugify(file_name).split(" ")[:4])) if file_name else "", timeout)