Esempio n. 1
0
		public static void UpdateRevisionWorkState (this DBWork w, DB db)
		{
			DBRevisionWork rw = w.GetRevisionWork (db);

			if (rw != null)
				rw.UpdateState (db);
		}
Esempio n. 2
0
 public ReportBuildStateResponse ReportBuildStateSafe(DBWork work)
 {
     return(ExecuteSafe("report build state", delegate()
     {
         return this.ReportBuildState(WebServiceLogin, work);
     }));
 }
Esempio n. 3
0
        public static void DeleteNumber(int pointRN_del, List <Route> listRoute, List <Point> data, int way)
        {
            //При удалении точки делаем сдвиг всех последующих номеров на  -1

            //находим маршрут
            var w = 0;

            try
            {
                while (listRoute[w].RouteNumber != way)
                {
                    w++;
                }
            }
            catch (Exception)
            {
            }
            var route = listRoute[w];

            //для каждой найденной точки на маршруте, большей, чем удаляемый номер, уменьшается номер на 1
            foreach (var point in data)
            {
                if (point.ID_Route == route.ID_Route)
                {
                    if (point.PointType > pointRN_del)
                    {
                        //убавляем точке номер и обновляем в бд
                        point.PointType--;
                        DBWork db = new DBWork();
                        db.UpdatePoint(point.ID_Point, point);
                    }
                }
            }
        }
Esempio n. 4
0
        private static void ProcessNotify(DBWork work, DBRevisionWork revision_work)
        {
            List <NotificationBase> notifications;

            Logger.Log("Notifications.ProcessNotify (lane_id: {1} revision_id: {2} host_id: {3} State: {0})", work.State, revision_work.lane_id, revision_work.revision_id, revision_work.host_id);

            try {
                lock (lock_obj) {
                    // We broadcast the notification to the API endpoint
                    WebNotification.BroadcastBuildNotification(work, revision_work);

                    if (!notifications_per_lane.TryGetValue(revision_work.lane_id, out notifications))
                    {
                        Logger.Log("Notifications.ProcessNotify (lane_id: {1} revision_id: {2} host_id: {3} State: {0}): Lane doesn't have any notifications enabled", work.State, revision_work.lane_id, revision_work.revision_id, revision_work.host_id);
                        return;
                    }

                    foreach (var notification in notifications)
                    {
                        notification.Notify(work, revision_work);
                    }
                }
            } catch (Exception ex) {
                Logger.Log("Exception while processing notification: {0}", ex.Message);
            }
        }
Esempio n. 5
0
        static Build GetBuildFromDBItems(DBWork work, DBRevisionWork revisionWork)
        {
            DBRevision revision;
            DBLane     lane, parentLane;
            DBHost     host;

            using (DB db = new DB()) {
                revision   = DBRevision_Extensions.Create(db, revisionWork.revision_id);
                lane       = DBLane_Extensions.Create(db, revisionWork.lane_id);
                parentLane = GetTopMostParent(lane, db);
                host       = DBHost_Extensions.Create(db, revisionWork.host_id);
            }

            var url = Configuration.GetWebSiteUrl();

            url += string.Format("/ViewLane.aspx?lane_id={0}&host_id={1}&revision_id={2}", lane.id, host.id, revision.id);

            return(new Build {
                Commit = revision.revision,
                CommitId = revision.id,
                Date = revisionWork.completed ? revisionWork.endtime : revision.date,
                Lane = lane.lane,
                Project = parentLane.lane,
                State = revisionWork.State,
                Author = revision.author,
                BuildBot = host.host,
                Url = url
            });
        }
Esempio n. 6
0
        public LostBook(string reader, Form1 f1)
        {
            this.read = reader;
            InitializeComponent();
            this.StartPosition = FormStartPosition.CenterScreen;
            db = new DBWork();
            DataSet tmp = db.getBooksForReader(reader);

            if (tmp.Tables["booksonreader"].Rows.Count == 0)
            {
                MessageBox.Show("За читателем не числится книг");
                return;
            }
            dataGridView1.AutoGenerateColumns = true;
            dataGridView1.DataSource          = tmp.Tables["booksonreader"];
            dataGridView1.SelectionMode       = DataGridViewSelectionMode.FullRowSelect;
            dataGridView1.RowHeadersVisible   = false;
            dataGridView1.RowTemplate.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
            dataGridView1.MultiSelect           = false;
            dataGridView1.ReadOnly              = true;
            dataGridView1.Columns[0].Width      = 250;
            dataGridView1.Columns[0].HeaderText = "Заглавие";
            dataGridView1.Columns[1].Width      = 145;
            dataGridView1.Columns[1].HeaderText = "Автор";
            dataGridView1.Columns[2].Visible    = false;
            dataGridView1.Columns[3].Visible    = false;
            //dataGridView1.Rows.RemoveAt(dataGridView1.Rows.Count-1);
            dataGridView1.AllowUserToAddRows = false;
        }
Esempio n. 7
0
        private static void ProcessNotify(DBWork work, DBRevisionWork revision_work)
        {
            log.DebugFormat("Running notifiers for lane_id: {1}, revision_id: {2}, host_id: {3}, State: {0}", work.State, revision_work.lane_id, revision_work.revision_id, revision_work.host_id);

            try {
                lock (lock_obj) {
                    List <NotificationBase> notifiers;

                    // We broadcast the notification to the API endpoint
                    WebNotification.BroadcastBuildNotification(work, revision_work);

                    if (!notifications_per_lane.TryGetValue(revision_work.lane_id, out notifiers))
                    {
                        return;
                    }

                    foreach (var notification in notifiers)
                    {
                        notification.Notify(work, revision_work);
                    }
                }
            } catch (Exception ex) {
                log.ErrorFormat("Exception while processing notification: {0}", ex);
            }
        }
Esempio n. 8
0
 public DBState GetWorkStateSafe(DBWork work)
 {
     return(ExecuteSafe("get work state", delegate()
     {
         return GetWorkState(WebServiceLogin, work);
     }));
 }
Esempio n. 9
0
		public static void Abort (DB db, int id)
		{
			DBWork work = DBWork_Extensions.Create (db, id);
			work.State = DBState.Aborted;
			work.Save (db);
			work.UpdateRevisionWorkState (db);
		}
Esempio n. 10
0
 public override void Notify(DBWork work, DBRevisionWork revision_work)
 {
     if (!(work.State == DBState.Failed || work.State == DBState.Issues || work.State == DBState.Timeout))
     {
         return;
     }
     base.Notify(work, revision_work);
 }
Esempio n. 11
0
 public Form25(DBWork DBW, Form1 _f1)
 {
     InitializeComponent();
     this.dbw = DBW;
     //this.ps = ps_;
     construct();
     this.f1 = _f1;
 }
Esempio n. 12
0
		public static void Clear (DB db, int id)
		{
			DBWork work = DBWork_Extensions.Create (db, id);
			work.State = DBState.NotDone;
			work.summary = string.Empty;
			work.Save (db);
			work.UpdateRevisionWorkState (db);
		}
Esempio n. 13
0
		public static void RemoveFile (this DBWork me, DB db, DBFile file)
		{
			using (IDbCommand cmd = db.CreateCommand ()) {
				cmd.CommandText = "DELETE FROM WorkFile WHERE work_id = @work_id AND file_id = @file_id;";
				DB.CreateParameter (cmd, "work_id", me.id);
				DB.CreateParameter (cmd, "file_id", file.id);
				cmd.ExecuteNonQuery ();
			}
		}
Esempio n. 14
0
		public static void Resume (DB db, int id)
		{
			DBWork work = DBWork_Extensions.Create (db, id);
			if (work.State == DBState.Paused) {
				work.State = DBState.NotDone;
				work.Save (db);
				work.UpdateRevisionWorkState (db);
			}
		}
Esempio n. 15
0
 public Form2(Form1 f1)
 {
     F1 = f1;
     InitializeComponent();
     db            = new DBWork(F1);
     textBox2.Text = "";
     textBox3.Text = "";
     //this.Left = (Screen.PrimaryScreen.Bounds.Width - this.Width) / 2;
     //this.Top = (Screen.PrimaryScreen.Bounds.Height - this.Height) / 2;
     this.StartPosition = FormStartPosition.CenterScreen;
 }
Esempio n. 16
0
        public static int NumberMove(int pointRN_new, int pointRN_old, List <Route> listRoute, List <Point> data, int way)
        {
            //Номер больше старого, но меньше или равен последнему - все номера начиная с нового сдвигаются на 1 вперед.
            //номер больше старого, и больше последнего - номер приравнивается последнему
            //Номер меньше старого - все номера больше или равный новому сдвигаются на 1

            //Происходит проверка на пробелы - выстраивается ряд точек на маршруте, если у какой то точки кроме последней нету точки перед ней, то все точки больше последней порядочной сдвигаются назад на 1


            //находим маршрут
            var w = 0;

            try
            {
                while (listRoute[w].RouteNumber != way)
                {
                    w++;
                }
            }
            catch (Exception)
            {
                return(0);
            }

            var route = listRoute[w];


            //если новый номер больше последнего то номер сохраняется как последний +1
            var firstNumber = FirstNumber(listRoute, data, way);

            if (pointRN_new > firstNumber)
            {
                pointRN_new = firstNumber;
                return(pointRN_new);
            }
            //осуществляем сдвиг, освобождая место под новый номер
            else
            {
                foreach (var point in data)
                {
                    if (point.ID_Route == route.ID_Route)
                    {
                        if (point.PointType >= pointRN_new)
                        {
                            //прибавляем точке номер и обновляем в бд
                            point.PointType++;
                            DBWork db = new DBWork();
                            db.UpdatePoint(point.ID_Point, point);
                        }
                    }
                }
                return(pointRN_new);
            }
        }
Esempio n. 17
0
		public static void AddFile (this DBWork me, DB db, DBFile file, string filename, bool hidden)
		{
			using (IDbCommand cmd = db.CreateCommand ()) {
				cmd.CommandText = "INSERT INTO WorkFile (work_id, file_id, hidden, filename) VALUES (@work_id, @file_id, @hidden, @filename);";
				DB.CreateParameter (cmd, "work_id", me.id);
				DB.CreateParameter (cmd, "file_id", file.id);
				DB.CreateParameter (cmd, "hidden", hidden);
				DB.CreateParameter (cmd, "filename", filename);
				cmd.ExecuteNonQuery ();
			}
		}
Esempio n. 18
0
 public Form2(Form1 f1)
 {
     F1 = f1;
     InitializeComponent();
     db = new DBWork(F1);
     //textBox2.Text = "";
     //textBox3.Text = "";
     //this.Left = (Screen.PrimaryScreen.Bounds.Width - this.Width) / 2;
     //this.Top = (Screen.PrimaryScreen.Bounds.Height - this.Height) / 2;
     this.StartPosition = FormStartPosition.CenterScreen;
     //this.InputLanguageChanged += new InputLanguageChangedEventHandler(Form2_InputLanguageChanged);
 }
Esempio n. 19
0
        public void UploadFileSafe(DBWork work, string filename, bool hidden)
        {
            string gz              = null;
            string file_to_upload  = null;
            string compressed_mime = null;

            try {             // try to upload
                // try to compress the file
                try {
                    gz = FileUtilities.GZCompress(filename);
                    if (gz != null)
                    {
                        file_to_upload  = gz;
                        compressed_mime = MimeTypes.GZ;
                    }
                    else
                    {
                        file_to_upload  = filename;
                        compressed_mime = null;
                    }
                } catch (Exception ex) {
                    file_to_upload  = filename;
                    compressed_mime = null;
                    Logger.Log("Could not compress the file {0}: {1}, uploading uncompressed.", filename, ex.Message);
                }

                long length = new FileInfo(file_to_upload).Length;
                if (length > 1024 * 1024 * 200)
                {
                    Logger.Log("Not uploading {0} ({2}): filesize is > 200MB (it is: {1} MB)", file_to_upload, length / (1024.0 * 1024.0), filename);
                    return;
                }

                // try to upload the file
                ExecuteSafe(string.Format("upload the file {0}", filename), delegate()
                {
                    this.UploadCompressedFile(WebServiceLogin, work, Path.GetFileName(filename), File.ReadAllBytes(file_to_upload), hidden, compressed_mime);
                });
            } catch (Exception ex) {
                Logger.Log("Could not upload {0}: {1}", filename, ex.Message);
            } finally {
                // clean up
                try {
                    // delete any files we may have created
                    if (gz != null)
                    {
                        File.Delete(gz);
                    }
                } catch {
                    // ignore any exceptions
                }
            }
        }
Esempio n. 20
0
        public static void Notify(DBWork work, DBRevisionWork revision_work)
        {
            log.DebugFormat("Notify (lane_id: {1} revision_id: {2} host_id: {3} State: {0})", work.State, revision_work.lane_id, revision_work.revision_id, revision_work.host_id);
            if (notifications == null)
            {
                return;
            }

            queued_notifications.Add(new QueuedNotification {
                IsInfo = false, work = work, revision_work = revision_work
            });
        }
Esempio n. 21
0
        private void button1_Click(object sender, EventArgs e)
        {
            if (dgO.SelectedRows.Count == 0)
            {
                MessageBox.Show("Выберите строку в таблице заказов!");
                return;
            }
            DBWork dbw     = new DBWork();
            string idOrder = dgO.SelectedRows[0].Cells["ID"].Value.ToString();

            dbw.MoveToHistoryOrders(idOrder);
            Orders_Load(sender, e);
        }
Esempio n. 22
0
        public static int NumberInsert(int pointRN_new, List <Route> listRoute, List <Point> data, int way)
        {
            //Вставка новой точки в маршрут. Варианты:
            //Новая точка встает в центр - сдивг точек начиная с номера новой точки
            //Новая точка встает дальше края - вначале для выявления этого получаем последний свободный номер, если он меньше номера новой точки то новой точке присвается последний номер
            //Новая точка встает на место крайней - см первый вариант

            //находим маршрут
            var w = 0;

            try
            {
                while (listRoute[w].RouteNumber != way)
                {
                    w++;
                }
            }
            catch (Exception)
            {
                return(0);
            }

            var route = listRoute[w];

            //если новый номер больше последнего то номер сохраняется как последний +1
            var firstNumber = FirstNumber(listRoute, data, way);

            if (pointRN_new >= firstNumber)
            {
                pointRN_new = firstNumber;
                return(pointRN_new);
            }

            //для каждой найденной точки на маршруте, большей, чем новый номер или равной ему, увеличивается номер на 1
            foreach (var point in data)
            {
                if (point.ID_Route == route.ID_Route)
                {
                    if (point.PointType >= pointRN_new)
                    {
                        //прибавляем точке номер и обновляем в бд
                        point.PointType++;
                        DBWork db = new DBWork();
                        db.UpdatePoint(point.ID_Point, point);
                    }
                }
            }

            return(pointRN_new);
        }
Esempio n. 23
0
        public static void Notify(DBWork work, DBRevisionWork revision_work)
        {
            Logger.Log("Notifications.Notify (lane_id: {1} revision_id: {2} host_id: {3} State: {0})", work.State, revision_work.lane_id, revision_work.revision_id, revision_work.host_id);
            if (notifications == null)
            {
                return;
            }

            if (!(work.State == DBState.Failed || work.State == DBState.Issues || work.State == DBState.Timeout))
            {
                return;
            }

            ThreadPool.QueueUserWorkItem((v) => ProcessNotify(work, revision_work));
        }
Esempio n. 24
0
        private void button1_Click(object sender, EventArgs e)
        {
            //MessageBox.Show();
            if (comboBox1.SelectedIndex == 0)
            {
                MessageBox.Show("Выберите тип абонемента или нажмите \"Отмена\"", "Внимание!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            DBWork db = new DBWork();

            db.SetReaderAbonement(this.idr, comboBox1.SelectedValue.ToString());
            MessageBox.Show("Тип абонемента успешно изменён!", "Информация", MessageBoxButtons.OK, MessageBoxIcon.Information);
            abon = comboBox1.Text;
            Form1.FireAbon(this, EventArgs.Empty);
            Close();
        }
Esempio n. 25
0
    private void Initialize()
    {
        if (m_bInitialized == false)
        {
            m_bInitialized = true;
            DontDestroyOnLoad(gameObject);
            m_dbItem          = new DBItem(Define.DB_TABLE_ASYNC_ITEM);
            m_dbItemMaster    = new DBItemMaster(Define.DB_TABLE_ASYNC_ITEM_MASTER);
            m_dbWork          = new DBWork(Define.DB_TABLE_ASYNC_WORK);
            m_dbMonster       = new DBMonster(Define.DB_TABLE_ASYNC_MONSTER);
            m_dbMonsterMaster = new DBMonsterMaster(Define.DB_TABLE_ASYNC_MONSTER_MASTER);
            m_dbKvs           = new DBKvs(Define.DB_TABLE_ASYNC_KVS);

            m_fInterval = 0.0f;
        }
    }
Esempio n. 26
0
        public virtual void Notify(DBWork work, DBRevisionWork revision_work)
        {
            List <DBPerson> people = new List <DBPerson> ();
            DBRevision      revision;
            DBLane          lane;
            DBHost          host;
            string          message;
            bool            nonfatal;

            log.DebugFormat("NotificationBase.Notify (lane_id: {1} revision_id: {2} host_id: {3} State: {0})", work.State, revision_work.lane_id, revision_work.revision_id, revision_work.host_id);

            nonfatal = false;

            if (!Evaluate(work, revision_work, out nonfatal))
            {
                log.DebugFormat("NotificationBase.Notify (lane_id: {1} revision_id: {2} host_id: {3} State: {0}) = evaluation returned false", work.State, revision_work.lane_id, revision_work.revision_id, revision_work.host_id);
                return;
            }

            if (nonfatal)
            {
                message = "Test failure";
            }
            else
            {
                message = "{red}{bold}Build failure{default}";
            }

            using (DB db = new DB()) {
                revision = DBRevision_Extensions.Create(db, revision_work.revision_id);
                lane     = DBLane_Extensions.Create(db, revision_work.lane_id);
                host     = DBHost_Extensions.Create(db, revision_work.host_id);
            }

            message = string.Format("{0} in revision {1} on {2}/{3}: {4}/ViewLane.aspx?lane_id={5}&host_id={6}&revision_id={7}",
                                    message,
                                    (revision.revision.Length > 8 ? revision.revision.Substring(0, 8) : revision.revision),
                                    lane.lane, host.host, Configuration.GetWebSiteUrl(), lane.id, host.id, revision.id);

            MonkeyWrench.Scheduler.Scheduler.FindPeopleForCommit(lane, revision, people);
            people = FindPeople(people);

            Notify(work, revision_work, people, message);
        }
Esempio n. 27
0
        /**
         * Notification callback for work updates.
         */
        public override void Notify(DBWork work, DBRevisionWork revision_work)
        {
            // Get info
            RevisionWorkInfo info;

            using (var db = new DB())
                info = getWorkInfo(db, revision_work.id, work.id);

            // Create object to send
            var statusObj = createPayload(revision_work.lane_id, revision_work.host_id, revision_work.revision_id,
                                          String.Format("Lane: {0}, Host: {1}, Status: {2}, Step: {3}, StepStatus: {4}",
                                                        info.laneName,
                                                        info.hostName,
                                                        revision_work.State,
                                                        info.command,
                                                        work.State
                                                        ),
                                          STATE_TO_GITHUB [revision_work.State]
                                          );

            sendNotification(info.repoURL, info.hash, statusObj);
        }
Esempio n. 28
0
        public DBWork GetNextStep(string lane)
        {
            DBWork result = null;

            using (IDbCommand cmd = CreateCommand()) {
                cmd.CommandText = "SELECT * FROM steps WHERE lane = @lane AND (state = 0 OR state = 1) ORDER BY revision DESC, sequence LIMIT 1";
                DB.CreateParameter(cmd, "lane", lane);
                using (IDataReader reader = cmd.ExecuteReader()) {
                    while (reader.Read())
                    {
                        if (result != null)
                        {
                            throw new Exception("Got more than one step");
                        }
                        result = new DBWork();
                        result.Load(reader);
                    }
                }
            }

            return(result);
        }
Esempio n. 29
0
        public Form33(string inv_, DBWork db)
        {
            InitializeComponent();
            DataSet DS = db.CheckForTwo(inv_);

            if (DS.Tables["t"].Rows.Count > 1)
            {
                SpecifyExampler(DS);
            }
            if (DS.Tables["t"].Rows.Count == 0)
            {
                CanShow = false;
                return;
            }
            if (DS.Tables["t"].Rows.Count == 1)
            {
                this.selectedid = DS.Tables["t"].Rows[0][4].ToString();
                this.bar        = DS.Tables["t"].Rows[0]["bar"].ToString();
            }
            inv = inv_;

            this.db = db;
            Construct();
        }
Esempio n. 30
0
        protected override void Notify(DBWork work, DBRevisionWork revision_work, List <DBPerson> people, string message)
        {
            if (!this.emails.Any())
            {
                log.DebugFormat("Notify no emails");
                return;
            }

            if (this.emails.Any(x => !x.EndsWith("@hipchat.xamarin.com", StringComparison.OrdinalIgnoreCase)))
            {
                log.Warn("EmailNotification.Notify skipping non-HipChat emails because we don't know how to send email!");
                return;
            }

            var actionableEmails = this.emails.Where(x => x.EndsWith("@hipchat.xamarin.com")).ToList();

            if (!actionableEmails.Any())
            {
                log.Debug("Notify no actionable emails!");
                return;
            }

            log.DebugFormat("Notify (lane_id: {1} revision_id: {2} host_id: {3} State: {0}) enabled: {4}, {5} people", work.State, revision_work.lane_id, revision_work.revision_id, revision_work.host_id, true, people.Count);

            bool nonfatal = false;

            if (!Evaluate(work, revision_work, out nonfatal))
            {
                log.DebugFormat("Notify (lane_id: {1} revision_id: {2} host_id: {3} State: {0}) = evaluation returned false", work.State, revision_work.lane_id, revision_work.revision_id, revision_work.host_id);
                return;
            }

            if (nonfatal)
            {
                message = "Test failure";
            }
            else
            {
                message = "Build failure";
            }

            DBRevision revision;
            DBLane     lane;
            DBHost     host;

            using (DB db = new DB()) {
                revision = DBRevision_Extensions.Create(db, revision_work.revision_id);
                lane     = DBLane_Extensions.Create(db, revision_work.lane_id);
                host     = DBHost_Extensions.Create(db, revision_work.host_id);
            }

            message = string.Format("{0} in revision {1} on {2}/{3} ({4}/ViewLane.aspx?lane_id={5}&host_id={6}&revision_id={7})",
                                    message,
                                    (revision.revision.Length > 8 ? revision.revision.Substring(0, 8) : revision.revision),
                                    lane.lane, host.host, Configuration.GetWebSiteUrl(), lane.id, host.id, revision.id);

            foreach (var person in people)
            {
                if (string.IsNullOrEmpty(person.irc_nicknames))
                {
                    using (var db = new DB()) {
                        var computed_nicks = new List <string> ();
                        var email_lists    = new List <IEnumerable <string> > ();
                        email_lists.Add(person.GetEmails(db));
                        if (person.Emails != null)
                        {
                            email_lists.Add(person.Emails);
                        }

                        foreach (var emails in email_lists)
                        {
                            foreach (var email in emails)
                            {
                                var at = email.IndexOf('@');
                                if (at > 0)
                                {
                                    computed_nicks.Add(email.Substring(0, at));
                                }
                            }
                        }
                        if (computed_nicks.Count == 0 && !string.IsNullOrEmpty(person.fullname))
                        {
                            computed_nicks.Add(person.fullname);
                        }
                        person.irc_nicknames = string.Join(",", computed_nicks.ToArray());
                    }
                }

                if (string.IsNullOrEmpty(person.irc_nicknames))
                {
                    log.DebugFormat("could not find somebody to notify for revision with id {0} on lane {1}", revision_work.revision_id, revision_work.lane_id);
                    continue;
                }
            }

            var          apiToken = identity.password;
            var          rooms    = actionableEmails.Select(email => email.Split('@') [0]).ToList();
            const string finalApi = "https://hipchat.xamarin.com/v1/rooms/message";

            var webClient = new WebClient();

            foreach (var r in rooms)
            {
                string prefix;
                string room = r;
                if (room.StartsWith("*"))
                {
                    room   = room.Substring(1);
                    prefix = "";
                }
                else
                {
                    prefix = "@";
                }

                var prefixNames  = string.Join(", ", people.SelectMany(x => x.irc_nicknames.Split(',')).Distinct().Select(x => string.Format("{1}{0}", x, prefix)));
                var finalMessage = prefixNames + ": " + message;

                if (cache [room + "|" + finalMessage] != null)
                {
                    continue;
                }
                cache.Add(room + "|" + finalMessage, string.Empty, new DateTimeOffset(DateTime.UtcNow.AddHours(1), TimeSpan.Zero));

                var postData = new NameValueCollection();
                postData.Add("auth_token", apiToken);
                postData.Add("room_id", room);
                postData.Add("from", "Wrench");
                postData.Add("message", finalMessage);
                postData.Add("notify", nonfatal ? "0" : "1");
                // TODO: Maybe send HTML eventually, though HTML doesn't allow @-mentions. :(
                postData.Add("message_format", "text");
                postData.Add("color", nonfatal ? "yellow" : "red");
                postData.Add("format", "json");
                var res       = webClient.UploadValues(finalApi, postData);
                var resString = Encoding.UTF8.GetString(res);

                log.DebugFormat("response from server: {0}", resString);
            }
        }