Esempio n. 1
0
bool User::Create()
{
  NoErrorConnection conn;
  user.id = conn.InsertAutoIncrement("users", user, "uid");
  if (user.id == -1) return false;
  UpdateLog();
  return true;
}
Esempio n. 2
0
long long TransfersUser(acl::UserID uid, ::stats::Timeframe timeframe, 
      const std::string& section, ::stats::Direction direction)
{
  mongo::BSONObjBuilder match;
  match.append("direction", util::EnumToString(direction));
  if (!section.empty())
    match.append("section", section);
  else
  {
    mongo::BSONArrayBuilder sections;
    for (const auto& kv : cfg::Get().Sections())
      sections.append(kv.first);
    match.appendElements(BSON("section" << BSON("$nin" << sections.arr())));
  }
  match.appendElements(Serialize(timeframe));
  
  mongo::BSONObj cmd = BSON("aggregate" << "transfers" << "pipeline" <<
    BSON_ARRAY(
      BSON("$match" << match.obj()) <<
      BSON("$group" << 
        BSON("_id" << (uid == -1 ? "" : "$uid") <<
          "total" << BSON("$sum" << "$kbytes")
        ))));
  
  
  mongo::BSONObj result;
  NoErrorConnection conn;
  if (conn.RunCommand(cmd, result))
  {
    try
    {
      auto elems = result["result"].Array();
      if (!elems.empty())
      {
        return elems[0]["total"].Long();
      }
    }
    catch (const mongo::DBException& e)
    {
      LogException("Unserialize transfers total", e, result);
    }
  }
  
  return 0;
}
Esempio n. 3
0
long long XfertimeCorrection(acl::UserID          uid, 
                             long long            kBytes,
                             time_t               modTime, 
                             ::stats::Direction   direction)
{
  long long xfertime = -1; 
  util::Time t(modTime);

  auto cmd = BSON("aggregate" << "transfers" << "pipeline" << 
    BSON_ARRAY(
        BSON("$match" << 
          BSON("year" << t.Year() << "month" << t.Month()  <<
               "week" << t.Week() << "day" << t.Day() <<
               "direction" << util::EnumToString(direction))) <<
        BSON("$group" << 
          BSON("_id" << uid << 
            "total kbytes" << BSON("$sum" << "$kbytes") <<
            "total xfertime" << BSON("$sum" << "$xfertime")
      ))));

  NoErrorConnection conn;
  mongo::BSONObj result;
  if (conn.RunCommand(cmd, result))
  {
    auto elems = result["result"].Array();
    if (!elems.empty())
    {
      try
      {
        long long totalXfertime = elems[0]["total xfertime"].Long();
        if (totalXfertime > 0)
          xfertime = std::ceil(static_cast<double>(totalXfertime) / elems[0]["total kbytes"].Long() * kBytes);
        else
          xfertime = 0;
      }
      catch (const mongo::DBException& e)
      {
        LogException("Unserialize upload decr avg speed", e, result);
      }
    }
  }
  
  return xfertime;
}
Esempio n. 4
0
bool User::DecrCredits(const std::string& section, long long kBytes, bool force)
{
  if (!kBytes) return true;
  
  mongo::BSONObjBuilder elemQuery;
  elemQuery.append("section", section);
  if (!force) elemQuery.append("value", BSON("$gte" << kBytes));
  
  auto query = BSON("uid" << user.id << 
                    "credits" << BSON("$elemMatch" << elemQuery.obj()));
                    
  auto update = BSON("$inc" << BSON("credits.$.value" << -kBytes));
                    
  auto cmd = BSON("findandmodify" << "users" <<
                  "query" << query <<
                  "update" << update);
  NoErrorConnection conn;                  
  mongo::BSONObj result;
  bool ret = conn.RunCommand(cmd, result);
  return force || (ret && result["value"].type() != mongo::jstNULL);
}
Esempio n. 5
0
void User::IncrCredits(const std::string& section, long long kBytes)
{
  auto doIncrement = [section, kBytes](acl::UserID uid)
    {
      NoErrorConnection conn;
      auto updateExisting = [&]() -> bool
        {
          auto query = BSON("uid" << uid << 
                            "credits" << BSON("$elemMatch" << BSON("section" << section)));
                            
          auto update = BSON("$inc" << BSON("credits.$.value" << kBytes));
                            
          auto cmd = BSON("findandmodify" << "users" <<
                          "query" << query <<
                          "update" << update);
                          
          mongo::BSONObj result;
          return conn.RunCommand(cmd, result) && 
                 result["value"].type() != mongo::jstNULL;
        };

      auto doInsert = [&]() -> bool
      {
        auto query = QUERY("uid" << uid << "credits" << BSON("$not" << 
                           BSON("$elemMatch" << BSON("section" << section))));
        auto update = BSON("$push" << BSON("credits" << BSON("section" << section << "value" << kBytes)));
        return conn.Update("users", query, update, false) > 0;
      };
      
      if (updateExisting()) return;
      if (doInsert()) return;
      if (updateExisting()) return;

      logs::Database("Unable to increment credits for UID %1%%2%", uid,
                     !section.empty() ? " in section " + section : 
                     std::string(""));
    };
  
  asyncTasks.Assign(std::async(std::launch::async, doIncrement, user.id));
}
Esempio n. 6
0
void User::SaveGIDs()
{
  NoErrorConnection conn;
  conn.SetFields("users", QUERY("uid" << user.id), user, { "primary gid", "secondary gids", "gadmin gids" });
  UpdateLog();
}
Esempio n. 7
0
void User::SavePassword()
{
  NoErrorConnection conn;
  conn.SetFields("users", QUERY("uid" << user.id), user, { "password", "salt" });
  UpdateLog();
}
Esempio n. 8
0
void User::SaveField(const std::string& field, bool updateLog) const
{
  NoErrorConnection conn;
  conn.SetField("users", QUERY("uid" << user.id), user, field);
  if (updateLog) UpdateLog();
}
Esempio n. 9
0
void User::Purge() const
{
  NoErrorConnection conn;
  conn.Remove("users", QUERY("uid" << user.id));
  UpdateLog();
}
Esempio n. 10
0
void User::SaveLoggedIn()
{
  NoErrorConnection conn;
  conn.SetFields("users", QUERY("uid" << user.id), user, { "logged in", "last login" });
}
Esempio n. 11
0
std::vector< ::stats::Stat> 
RetrieveUsers(const std::string&                    section, 
              ::stats::Timeframe                    timeframe, 
              ::stats::Direction                    direction, 
              boost::optional< ::stats::SortField>  sortField = boost::none, 
              boost::optional<acl::UserID>          uid = boost::none)
{
  static const char* sortFields[] =
  {
    "total kbytes",
    "total files",
    "avg speed"
  };

  mongo::BSONObjBuilder match;
  match.append("direction", util::EnumToString(direction));
  match.appendElements(Serialize(timeframe));
  
  if (!section.empty())
    match.append("section", section);
  else
  {
    mongo::BSONArrayBuilder sections;
    for (const auto& kv : cfg::Get().Sections())
      sections.append(kv.first);
    match.appendElements(BSON("section" << BSON("$in" << sections.arr())));
  }
  
  if (uid) match.append("uid", *uid);
  
  mongo::BSONArrayBuilder ops;
  ops.append(BSON("$match" << match.obj()));
  ops.append(BSON("$group" << BSON("_id" << "$uid" <<
             "total kbytes" << BSON("$sum" << "$kbytes") <<
             "total files" << BSON("$sum" << "$files") <<
             "total xfertime" << BSON("$sum" << "$xfertime"))));
  
  ops.append(BSON("$project" << BSON("total kbytes" << 1 <<
             "total files" << 1 <<
             "total xfertime" << 1 <<
             "avg speed" << BSON("$divide" << 
             BSON_ARRAY("$total kbytes" << "$total xfertime")))));
           
  if (sortField)
  {
    ops.append(BSON("$sort" << BSON(sortFields[static_cast<unsigned>(*sortField)] << -1)));
  }

  auto cmd = BSON("aggregate" << "transfers" << "pipeline" << ops.arr());

  std::vector< ::stats::Stat> users;
  mongo::BSONObj result;
  NoErrorConnection conn;
  if (conn.RunCommand(cmd, result))
  {
    for (const auto& elem : result["result"].Array())
    {
      users.emplace_back(Unserialize(elem.Obj()));
    }
  }
  
  return users;
}