예제 #1
0
        private SyncResult <T> GetTableData <T>(Guid districtId) where T : SyncModel
        {
            var mcs = "Data Source=yqdubo97gg.database.windows.net;Initial Catalog=ChalkableMaster;UID=chalkableadmin;Pwd=Hellowebapps1!";

            District d;

            using (var uow = new UnitOfWork(mcs, false))
            {
                var da = new DistrictDataAccess(uow);
                d = da.GetById(districtId);
            }
            var  cs = $"Data Source={d.ServerUrl};Initial Catalog={d.Id};UID=chalkableadmin;Pwd=Hellowebapps1!";
            long?version;

            using (var uow = new UnitOfWork(cs, true))
            {
                var name = typeof(T).Name;
                version = (new SyncVersionDataAccess(uow)).GetAll().First(x => x.TableName == name).Version;
            }

            Debug.WriteLine($"version {version}");
            var cl    = ConnectorLocator.Create(d.SisUserName, d.SisPassword, d.SisUrl);
            var items = (cl.SyncConnector.GetDiff(typeof(T), version) as SyncResult <T>);

            return(items);
        }
예제 #2
0
        public void GetSyncTablesProps()
        {
            var connector = ConnectorLocator.Create("Chalkable", "8nA4qU4yG", "http://sandbox.sti-k12.com/chalkable/api/");
            var client    = new WebClientGZip
            {
                Headers =
                {
                    [HttpRequestHeader.Authorization] = "Session " + connector.Token,
                    ["ApplicationKey"]  = $"chalkable {Settings.StiApplicationKey}",
                    ["Accept-Encoding"] = "gzip, deflate"
                },
                Encoding = Encoding.UTF8
            };

            client.Headers.Add("Content-Type", "application/json");
            try
            {
                var url = connector.BaseUrl + $"sync/tables/Homeroom/";

                client.QueryString = new NameValueCollection();
                var data = client.DownloadData(url);

                using (var ms = new MemoryStream(data))
                {
                    StreamReader reader;
                    GZipStream   unzipped = null;
                    if (client.ResponseHeaders[HttpResponseHeader.ContentType].ToLower() == "application/octet-stream")
                    {
                        unzipped = new GZipStream(ms, CompressionMode.Decompress);
                        reader   = new StreamReader(unzipped);
                    }
                    else
                    {
                        reader = new StreamReader(ms);
                    }

                    Debug.WriteLine(reader.ReadToEnd());

                    unzipped?.Dispose();
                }
            }
            catch (WebException ex)
            {
                if (ex.Response is HttpWebResponse &&
                    (ex.Response as HttpWebResponse).StatusCode == HttpStatusCode.NotFound)
                {
                    return;
                }

                string msg    = ex.Message;
                var    stream = ex.Response?.GetResponseStream();
                if (stream != null)
                {
                    var reader = new StreamReader(stream);
                    msg = reader.ReadToEnd();
                }
                throw new Exception(msg);
            }
        }
예제 #3
0
        public void TestMealTypeSync()
        {
            var connector = ConnectorLocator.Create("Chalkable", "8nA4qU4yG", "http://sandbox.sti-k12.com/chalkable/api/");

            var mealType = (connector.SyncConnector.GetDiff(typeof(StiConnector.SyncModel.MealType), null) as SyncResult <StiConnector.SyncModel.MealType>).All;

            Debug.WriteLine(JsonConvert.SerializeObject(mealType));
        }
예제 #4
0
        public void Resync(string tableName)
        {
            Log.LogInfo("start resync");
            connectorLocator     = ConnectorLocator.Create(ConnectionInfo.SisUserName, ConnectionInfo.SisPassword, ConnectionInfo.SisUrl);
            ServiceLocatorMaster = new ServiceLocatorMaster(sysadminCntx);
            ServiceLocatorSchool = ServiceLocatorMaster.SchoolServiceLocator(districtId, null);
            Log.LogInfo("download data to resync");
            context = new SyncContext(connectorLocator.ApiVersion);

            var tablesToResync = new List <string>
            {
                tableName,
                nameof(Gender),    // We need this tables for mappers
                nameof(SpEdStatus) // inside StudentAdapter/Selector
            };

            var toSync  = context.TablesToSync;
            var results = new List <SyncResultBase <SyncModel> >();

            foreach (var table in toSync)
            {
                var type = context.Types[table.Key];
                SyncResultBase <SyncModel> res;
                var resType = (typeof(SyncResult <>)).MakeGenericType(type);
                if (tablesToResync.Contains(table.Key))
                {
                    Log.LogInfo("Start downloading " + table.Key);
                    res = (SyncResultBase <SyncModel>)connectorLocator.SyncConnector.GetDiff(type, null);
                    Log.LogInfo("Table downloaded: " + table.Key + " " + res.RowCount);
                }
                else
                {
                    res = (SyncResultBase <SyncModel>)Activator.CreateInstance(resType, new object[0]);
                }


                if (table.Key == tableName) //resync table
                {
                    object o = resType.GetProperty("Rows").GetValue(res);
                    resType.GetProperty("Updated").SetValue(res, o);
                    resType.GetProperty("Inserted").SetValue(res, null);
                    resType.GetProperty("Deleted").SetValue(res, null);
                    resType.GetProperty("Rows").SetValue(res, null);
                }

                results.Add(res);
            }
            foreach (var syncResultBase in results)
            {
                context.SetResult(syncResultBase);
            }
            if (!ServiceLocatorSchool.Context.DistrictId.HasValue)
            {
                throw new Exception("District id should be defined for import");
            }
            DoRegularSync(false);
        }
예제 #5
0
        public void ResyncAfterRestore()
        {
            Log.LogInfo("start resync after sti DB restore");
            ServiceLocatorMaster = new ServiceLocatorMaster(sysadminCntx);
            ServiceLocatorSchool = ServiceLocatorMaster.SchoolServiceLocator(districtId, null);
            if (!ServiceLocatorSchool.Context.DistrictId.HasValue)
            {
                throw new Exception("District id should be defined for import");
            }

            var d = ServiceLocatorMaster.DistrictService.GetByIdOrNull(ServiceLocatorSchool.Context.DistrictId.Value);

            connectorLocator = ConnectorLocator.Create(ConnectionInfo.SisUserName, ConnectionInfo.SisPassword, ConnectionInfo.SisUrl);
            Log.LogInfo("remove district last sync label");
            d.LastSync = null;
            ServiceLocatorMaster.DistrictService.Update(d);
            Log.LogInfo("performing before restore preparation");
            ServiceLocatorMaster.DbMaintenanceService.BeforeSisRestore(d.Id);
            ServiceLocatorSchool.DbMaintenanceService.BeforeSisRestore();
            Log.LogInfo("download data to restore");
            DownloadSyncData();
            Log.LogInfo("remove user records");
            var all      = ServiceLocatorMaster.UserService.GetAll(districtId);
            var allIds   = new HashSet <int>(all.Select(x => x.SisUserId.Value));
            var newUsers = new List <StiConnector.SyncModel.User>();
            var rows     = context.GetSyncResult <StiConnector.SyncModel.User>().Rows;

            foreach (var r in rows)
            {
                if (!allIds.Contains(r.UserID))
                {
                    newUsers.Add(r);
                }
            }
            context.GetSyncResult <StiConnector.SyncModel.User>().Inserted = null;
            context.GetSyncResult <StiConnector.SyncModel.User>().Rows     = newUsers.ToArray();
            context.GetSyncResult <StiConnector.SyncModel.User>().Updated  = null;
            context.GetSyncResult <StiConnector.SyncModel.User>().Deleted  = null;
            Log.LogInfo("do initial sync");
            DoInitialSync();
            d = ServiceLocatorMaster.DistrictService.GetByIdOrNull(ServiceLocatorSchool.Context.DistrictId.Value);
            Log.LogInfo("performing after restore preparation");
            var logs = ServiceLocatorMaster.DbMaintenanceService.AfterSisRestore(d.Id);

            ServiceLocatorSchool.DbMaintenanceService.AfterSisRestore();
            foreach (var restoreLogItem in logs)
            {
                Log.LogWarning(restoreLogItem.Msg);
            }
            Log.LogInfo("updating district last sync");
            UpdateDistrictLastSync(d, true);
            CreateUserLoginInfos();
            Log.LogInfo("resync after sti DB restore is completed");
        }
예제 #6
0
        public ActionResult Register(DistrictRegisterViewData data)
        {
            string name     = data.DistrictGuid.ToString();
            string timeZone = data.DistrictTimeZone ?? "UTC";
            var    sl       = ServiceLocatorFactory.CreateMasterSysAdmin();
            var    context  = sl.UserService.Login(data.UserName, data.Password);

            if (context != null)
            {
                var district = sl.DistrictService.GetByIdOrNull(data.DistrictGuid);
                if (district == null && string.IsNullOrEmpty(data.SisPassword))
                {
                    throw new Exception("SIS password can not be null for a new district");
                }
                var pwd = data.SisPassword;
                if (string.IsNullOrEmpty(pwd))
                {
                    pwd = district.SisPassword;
                }
                var locator = ConnectorLocator.Create(data.SisUserName, pwd, data.ApiUrl);
                if (!locator.LinkConnector.Link(data.LinkKey))
                {
                    throw new Exception("The link keys do not match.");
                }
                if (district == null)
                {
                    sl.DistrictService.Create(data.DistrictGuid, name, data.ApiUrl, data.RedirectUrl, data.SisUserName, data.SisPassword, timeZone, data.DistrictState, data.IsReportCardsEnabled);
                }
                else
                {
                    if (String.Compare(district.SisUrl, data.ApiUrl, StringComparison.OrdinalIgnoreCase) != 0)
                    {
                        throw new Exception("API url can't be changed for existing district");
                    }

                    if (String.IsNullOrEmpty(district.Name))
                    {
                        district.Name = name;
                    }
                    if (!string.IsNullOrEmpty(data.SisPassword))
                    {
                        district.SisPassword = data.SisPassword;
                    }
                    district.SisUrl         = data.ApiUrl;
                    district.SisUserName    = data.SisUserName;
                    district.TimeZone       = timeZone;
                    district.SisRedirectUrl = data.RedirectUrl;
                    district.StateCode      = data.DistrictState;
                    sl.DistrictService.Update(district);
                }
                return(Json(true));
            }
            return(new HttpUnauthorizedResult());
        }
예제 #7
0
 void ForEachDistrict(IEnumerable <Guid> districtIds, Action <District, ConnectorLocator> action)
 {
     foreach (var districtId in districtIds)
     {
         var      mcs = "Data Source=yqdubo97gg.database.windows.net;Initial Catalog=ChalkableMaster;UID=chalkableadmin;Pwd=Hellowebapps1!";
         District d;
         using (var uow = new UnitOfWork(mcs, false))
         {
             var da = new DistrictDataAccess(uow);
             d = da.GetById(districtId);
         }
         var cl = ConnectorLocator.Create(d.SisUserName, d.SisPassword, d.SisUrl);
         action(d, cl);
         Debug.WriteLine($"district {d.Id} processing is done");
     }
 }
예제 #8
0
        private SyncResult <T> GetTableData <T>(Guid districtId, long?version) where T : SyncModel
        {
            var mcs = "Data Source=yqdubo97gg.database.windows.net;Initial Catalog=ChalkableMaster;UID=chalkableadmin;Pwd=Hellowebapps1!";

            District d;

            using (var uow = new UnitOfWork(mcs, false))
            {
                var da = new DistrictDataAccess(uow);
                d = da.GetById(districtId);
            }
            var cl    = ConnectorLocator.Create(d.SisUserName, d.SisPassword, d.SisUrl);
            var items = (cl.SyncConnector.GetDiff(typeof(T), version) as SyncResult <T>);

            return(items);
        }
예제 #9
0
        public void Import()
        {
            Log.LogInfo("start import");
            ServiceLocatorMaster = new ServiceLocatorMaster(sysadminCntx);
            ServiceLocatorSchool = ServiceLocatorMaster.SchoolServiceLocator(districtId, null);
            if (!ServiceLocatorSchool.Context.DistrictId.HasValue)
            {
                throw new Exception("District id should be defined for import");
            }

            var d = ServiceLocatorMaster.DistrictService.GetByIdOrNull(ServiceLocatorSchool.Context.DistrictId.Value);

            try
            {
                connectorLocator = ConnectorLocator.Create(ConnectionInfo.SisUserName, ConnectionInfo.SisPassword, ConnectionInfo.SisUrl);
                Log.LogInfo("download data to sync");
                DownloadSyncData();
                if (d.LastSync.HasValue)
                {
                    DoRegularSync(true);
                }
                else
                {
                    DoInitialSync();
                }
                Log.LogInfo("updating district last sync");
                d = ServiceLocatorMaster.DistrictService.GetByIdOrNull(ServiceLocatorSchool.Context.DistrictId.Value);
                UpdateDistrictLastSync(d, true);
            }
            catch (Exception)
            {
                UpdateDistrictLastSync(d, false);
                throw;
            }

            Log.LogInfo("process pictures");
            ProcessPictures();
            Log.LogInfo("setting link status");
            var importedSchoolIds = context.GetSyncResult <School>().All.Select(x => x.SchoolID);

            foreach (var importedSchoolId in importedSchoolIds)
            {
                connectorLocator.LinkConnector.CompleteSync(importedSchoolId);
            }
            CreateUserLoginInfos();
            Log.LogInfo("import is completed");
        }
예제 #10
0
 private void SaveSisToken(User user, UnitOfWork uow, ref ConnectorLocator iNowConnector)
 {
     if (user.SisUserName != null)
     {
         if (iNowConnector == null)
         {
             if (user.OriginalPassword == null)
             {
                 throw new ChalkableException(ChlkResources.ERR_SIS_CONNECTION_REQUERED_NOT_ENCRYPED_PASSWORD);
             }
             iNowConnector = ConnectorLocator.Create(user.SisUserName, user.OriginalPassword, user.District.SisUrl);
         }
         if (!string.IsNullOrEmpty(iNowConnector.Token))
         {
             UpdateUserLoginInfo(user, iNowConnector.Token, iNowConnector.TokenExpires, null, uow);
         }
     }
 }
예제 #11
0
        public void StudentPanoramaApiTest()
        {
            var studentId     = 3315;
            var connector     = ConnectorLocator.Create("MAGOLDEN-3856695863", "qqqq1111", "http://sandbox.sti-k12.com/chalkable/api/");
            var componentsIds = new List <int>
            {
                1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 6, 7, 7, 7, 7, 7, 7, 8, 10, 11, 12, 13, 14, 15
            };
            var scoreTypeIds = new List <int>
            {
                1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 11, 1, 2, 3, 4, 5, 6, 8, 12, 12, 12, 12, 12, 12
            };
            var acadSessionIds = new List <int> {
                179
            };

            var studentPanorama = connector.PanoramaConnector.GetStudentPanorama(studentId, acadSessionIds, componentsIds, scoreTypeIds);

            if (studentPanorama.StandardizedTests != null)
            {
                Debug.WriteLine("Standardized Tests:");
                Debug.WriteLine(JsonConvert.SerializeObject(studentPanorama.StandardizedTests));
            }

            if (studentPanorama.Infractions != null)
            {
                Debug.WriteLine("Infractions:");
                Debug.WriteLine(JsonConvert.SerializeObject(studentPanorama.Infractions));
            }

            if (studentPanorama.DailyAbsences != null)
            {
                Debug.WriteLine("DailyAbsences:");
                Debug.WriteLine(JsonConvert.SerializeObject(studentPanorama.DailyAbsences));
            }

            if (studentPanorama.PeriodAbsences != null)
            {
                Debug.WriteLine("PeriodAbsences:");
                Debug.WriteLine(JsonConvert.SerializeObject(studentPanorama.PeriodAbsences));
            }
        }
예제 #12
0
        public bool Handle(BackgroundTask task, BackgroundTaskService.BackgroundTaskLog log)
        {
            var sl               = ServiceLocatorFactory.CreateMasterSysAdmin();
            var data             = task.GetData <PictureImportTaskData>();
            var district         = sl.DistrictService.GetByIdOrNull(data.DistrictId);
            var connectorLocator = ConnectorLocator.Create(district.SisUserName, district.SisPassword, district.SisUrl);

            foreach (var person in data.PersonIds)
            {
                var content = connectorLocator.UsersConnector.GetPhoto(person);
                if (content != null)
                {
                    sl.PersonPictureService.UploadPicture(data.DistrictId, person, content);
                }
                else
                {
                    sl.PersonPictureService.DeletePicture(data.DistrictId, person);
                }
            }
            return(true);
        }
예제 #13
0
        public void FixRoomDelete(Guid districtid)
        {
            District d;
            var      mcs = "Data Source=yqdubo97gg.database.windows.net;Initial Catalog=ChalkableMaster;UID=chalkableadmin;Pwd=Hellowebapps1!";

            using (var uow = new UnitOfWork(mcs, false))
            {
                var da = new DistrictDataAccess(uow);
                d = da.GetById(districtid);
            }

            var cs = String.Format("Data Source={0};Initial Catalog={1};UID=chalkableadmin;Pwd=Hellowebapps1!", d.ServerUrl, d.Id);
            IList <SyncVersion> versions;

            using (var uow = new UnitOfWork(cs, true))
            {
                versions = (new SyncVersionDataAccess(uow)).GetAll();
                uow.Commit();
            }

            var cl           = ConnectorLocator.Create("Chalkable", d.SisPassword, d.SisUrl);
            var deletedRooms = (cl.SyncConnector.GetDiff(typeof(Room), versions.First(x => x.TableName == "Room").Version) as SyncResult <Room>).Deleted;

            using (var uow = new UnitOfWork(cs, true))
            {
                var da      = new ClassDataAccess(uow);
                var all     = da.GetAll();
                var classes = all.Where(x => deletedRooms.Any(y => x.RoomRef == y.RoomID)).ToList();
                foreach (var @class in classes)
                {
                    @class.RoomRef = null;
                }
                da.Update(classes.ToList());
                uow.Commit();
            }
        }
예제 #14
0
        public void FixMissingUsersSync(Guid districtid)
        {
            var mcs = "Data Source=yqdubo97gg.database.windows.net;Initial Catalog=ChalkableMaster;UID=chalkableadmin;Pwd=Hellowebapps1!";

            District d;
            IList <Data.Master.Model.User> existingUsers;

            using (var uow = new UnitOfWork(mcs, false))
            {
                var da = new DistrictDataAccess(uow);
                d = da.GetById(districtid);
                var conds = new SimpleQueryCondition("DistrictRef", districtid, ConditionRelation.Equal);
                existingUsers = (new UserDataAccess(uow)).GetAll(conds);
            }
            var cs = String.Format("Data Source={0};Initial Catalog={1};UID=chalkableadmin;Pwd=Hellowebapps1!", d.ServerUrl, d.Id);
            IList <SyncVersion> versions;

            using (var uow = new UnitOfWork(cs, true))
            {
                versions = (new SyncVersionDataAccess(uow)).GetAll();
                uow.Commit();
            }

            var cl           = ConnectorLocator.Create(d.SisUserName, d.SisPassword, d.SisUrl);
            var addedUsers   = (cl.SyncConnector.GetDiff(typeof(User), versions.First(x => x.TableName == "User").Version) as SyncResult <User>).Inserted;
            var allInowUsers = (cl.SyncConnector.GetDiff(typeof(User), null) as SyncResult <User>).All;
            var allUsers     = (cl.SyncConnector.GetDiff(typeof(User), null) as SyncResult <User>).All;
            //var addedUserSchools = (cl.SyncConnector.GetDiff(typeof(UserSchool), versions.First(x => x.TableName == "UserSchool").Version) as SyncResult<UserSchool>).Inserted;

            IList <Data.Master.Model.User> users = new List <Data.Master.Model.User>();
            var ids             = allInowUsers.Select(x => x.UserID).Distinct();
            var existingUserSet = new HashSet <int>(existingUsers.Select(x => x.SisUserId.Value).ToList());

            foreach (var addedUserSchool in ids)
            {
                if (!existingUserSet.Contains(addedUserSchool))
                {
                    if (addedUsers.All(x => x.UserID != addedUserSchool))
                    {
                        var sisu = allUsers.First(x => x.UserID == addedUserSchool);
                        Data.Master.Model.User u = new Data.Master.Model.User
                        {
                            Id          = Guid.NewGuid(),
                            DistrictRef = districtid,
                            FullName    = sisu.FullName,
                            Login       = $"user{sisu.UserID}_{districtid}@chalkable.com",
                            Password    = "******",
                            SisUserName = sisu.UserName,
                            SisUserId   = sisu.UserID
                        };
                        users.Add(u);
                    }
                }
            }


            using (var uow = new UnitOfWork(mcs, true))
            {
                (new UserDataAccess(uow)).Insert(users);
                uow.Commit();
            }
        }
예제 #15
0
        public void SectionPanoramaApiTest()
        {
            var connector     = ConnectorLocator.Create("MAGOLDEN-3856695863", "qqqq1111", "http://sandbox.sti-k12.com/chalkable/api/");
            var componentsIds = new List <int>
            {
                1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 6, 7, 7, 7, 7, 7, 7, 8, 10, 11, 12, 13, 14, 15
            };

            var scoreTypeIds = new List <int>
            {
                1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 11, 1, 2, 3, 4, 5, 6, 8, 12, 12, 12, 12, 12, 12
            };

            Debug.WriteLine($"{componentsIds.Count} - {scoreTypeIds.Count}");

            SectionPanorama callResult = new SectionPanorama();
            List <int>      classIds   = new List <int>
            {
                13770, 13771, 13772, 13806, 13861, 13862, 13950, 14011, 14436, 15165
            };

            bool found  = false;
            int  @class = 0;

            foreach (var classId in classIds)
            {
                callResult = connector.PanoramaConnector.GetSectionPanorama(classId, new List <int> {
                    179
                }, componentsIds, scoreTypeIds);
                if (callResult.StandardizedTests != null)
                {
                    found  = true;
                    @class = classId;
                    break;
                }
            }
            if (!found)
            {
                Debug.WriteLine("StandardizedTests not found in any class");
                return;
            }

            Debug.WriteLine($"ClassId : {@class}");
            Debug.WriteLine("Absences [StudentId - NumberOfAbsences - NumberOfDaysEnrolled]:");
            foreach (var studentAbsence in callResult.Absences)
            {
                Debug.WriteLine($"{studentAbsence.StudentId} - {studentAbsence.NumberOfAbsences} - {studentAbsence.NumberOfDaysEnrolled}");
            }

            Debug.WriteLine("Grades [StudentId - AvarageGrade]:");
            foreach (var grade in callResult.Grades)
            {
                Debug.WriteLine($"{grade.StudentId} - {grade.AverageGrade}");
            }

            Debug.WriteLine("Infractions [StudentId - NumberOfInfractions]:");
            foreach (var inf in callResult.Infractions)
            {
                Debug.WriteLine($"{inf.StudentId} - {inf.NumberOfInfractions}");
            }

            Debug.WriteLine("StandardizedTests [StudentId - Date - Score - StandardizedTestComponentId - StandardizedTestScoreTypeId]:");
            if (callResult.StandardizedTests != null)
            {
                foreach (var stTests in callResult.StandardizedTests)
                {
                    Debug.WriteLine($"{stTests.StudentId} - {stTests.Date} - {stTests.Score} - {stTests.StandardizedTestComponentId} - {stTests.StandardizedTestId} - {stTests.StandardizedTestScoreTypeId}");
                }
            }
        }