Exemple #1
0
        public StravaConnector()
        {
            const String         token = "5a034173fa52b384a43aac8ae83b4293230ef9bc";
            StaticAuthentication auth  = new StaticAuthentication(token);

            client = new StravaClient(auth);
        }
 public void Initialise(bool existing_data, JOB_Common_Parameters common_data)
 {
     Common_data         = new JOB_Common_Parameters();
     Common_data         = common_data;
     S_auth              = new StaticAuthentication(common_data.strava_token);
     client              = new StravaClient(S_auth);
     Activity_details    = new Activities_data();
     Activity_statistics = new JOB_Activities_Stats();
     Utilities           = new JOB_Utilities();
     if (!existing_data)
     {
         Logger.Info("No existing user data present - Creating Athlete Data", "Strava V2.0/JOB_Strava_Client/Initialise");
         Athlete_data = new JOB_Athlete_data(client, common_data.app_path);
         Logger.Info("No existing user data present - Athlete Data created", "Strava V2.0/JOB_Strava_Client/Initialise");
         Logger.Info("No existing user data present - Creating Gear Data", "Strava V2.0/JOB_Strava_Client/Initialise");
         Gear = new JOB_Gear(client, common_data);
         Logger.Info("No existing user data present - Gear Data created", "Strava V2.0/JOB_Strava_Client/Initialise");
     }
     if (existing_data)
     {
         Logger.Info("Existing user data present", "Strava V2.0/JOB_Strava_Client/Initialise");
         Athlete_data = new JOB_Athlete_data(common_data);
         Gear         = new JOB_Gear(client, common_data);
         Activity_statistics.Read_Activities_stats(common_data.activities_stats_filename_fullpath);
         stats_data           = new DataTable();
         stats_data           = Activity_statistics.Calculate_annual_stats();
         annual_stats_by_week = new DataTable();
         annual_stats_by_week = Activity_statistics.Calculate_annual_stats_by_week();
         Logger.Info("Existing user data present - Athlete Data Read and processed", "Strava V2.0/JOB_Strava_Client/Initialise");
     }
 }
        private void TimerTick(object sender, ElapsedEventArgs e)
        {
            StaticAuthentication authenticator = new StaticAuthentication(_token);
            StravaClient         stravaClient  = new StravaClient(authenticator);
            UploadStatus         uploadStatus  = stravaClient.Uploads.CheckUploadStatus(_uploadId);
            string status = uploadStatus.Status;

            switch (status)
            {
            default:
                if (status == "Your activity is ready.")
                {
                    if (this.UploadChecked != null)
                    {
                        this.UploadChecked(this, new UploadStatusCheckedEventArgs(CurrentUploadStatus.Ready));
                    }
                    if (this.ActivityReady != null)
                    {
                        this.ActivityReady(this, EventArgs.Empty);
                    }
                    Finish();
                }
                break;

            case "Your activity is still being processed.":
                if (this.UploadChecked != null)
                {
                    this.UploadChecked(this, new UploadStatusCheckedEventArgs(CurrentUploadStatus.Processing));
                }
                if (this.ActivityProcessing != null)
                {
                    this.ActivityProcessing(this, EventArgs.Empty);
                }
                break;

            case "The created activity has been deleted.":
                if (this.UploadChecked != null)
                {
                    this.UploadChecked(this, new UploadStatusCheckedEventArgs(CurrentUploadStatus.Deleted));
                }
                Finish();
                break;

            case "There was an error processing your activity.":
                if (this.UploadChecked != null)
                {
                    this.UploadChecked(this, new UploadStatusCheckedEventArgs(CurrentUploadStatus.Error));
                }
                ErrorMessage = uploadStatus.Error;
                if (this.Error != null)
                {
                    this.Error(this, EventArgs.Empty);
                }
                Finish();
                break;
            }
        }
        public void GetAccessToken_RetrievesTokenAsConstructed()
        {
            string expectedToken = "1234ABCD";

            var auth = new StaticAuthentication(expectedToken);

            string actualToken = auth.GetAccessToken();

            Assert.AreEqual(expectedToken, actualToken);
        }
Exemple #5
0
        private async void finish_StravaConnection(string token)
        {
            if (strava_Token.Length != 0)
            {
                auth   = new StaticAuthentication(token);
                client = new StravaClient(auth);
                Athlete athlete = await client.Athletes.GetAthleteAsync();

                statusText.Text = "Hello " + athlete.FirstName;
            }
        }
Exemple #6
0
 static void Main(string[] args)
 {
     var staticAuthentication = new StaticAuthentication("f112cb279e1ab839bae4918febb5b7a96f199e40");
     var web = new WebAuthentication {
         AccessToken = "f112cb279e1ab839bae4918febb5b7a96f199e40", AuthCode = ""
     };
     var client             = new StravaClient(staticAuthentication);
     var segment            = client.Segments.GetSegment("10393462");
     var segmentLeaderboard = client.Segments.GetFullSegmentLeaderboard("10393462");
     var athlete            = client.Athletes.GetAthlete();
 }
Exemple #7
0
        public Profile ImportProfile([FromUri] string activityId, [FromUri] Guid chartId)
        {
            _log.Debug("Creating profile from strava activity {activityId} med chart {chartId}", activityId, chartId);

            StaticAuthentication auth   = new StaticAuthentication(GetClaimedToken());
            StravaClient         client = new StravaClient(auth);

            StreamType streamTypes = StreamType.LatLng | StreamType.Distance | StreamType.Altitude | StreamType.Time;

            var activity = client.Activities.GetActivity(activityId, true);
            var streams  = client.Streams.GetActivityStream(activityId, streamTypes);

            var id    = Guid.NewGuid();
            var track = CreateTrack(activity, streams);


            var application = ApplicationManager.BuildApplication();

            application.ExecuteCommand(new CreateProfile(id, UserId, chartId, activity.Name, track));

            return(application.Views.Profiles.GetById(id));
        }
Exemple #8
0
 public StravaMediator(string apiToken)
 {
     auth   = new StaticAuthentication(apiToken);
     client = new StravaClient(auth);
 }
Exemple #9
0
        private StravaClient CreateClient()
        {
            StaticAuthentication auth = new StaticAuthentication(GetClaimedToken());

            return(new StravaClient(auth));
        }
Exemple #10
0
        public async static void Test()
        {
            Console.WriteLine("Framework: {0}", Framework.Version);

            // Please use your own, valid token!
            const String token = "";

            // Use either the static authentication method or use the WebAuthentication method.
            StaticAuthentication auth = new StaticAuthentication(token);

            //WebAuthentication auth = new WebAuthentication();
            //auth.AuthCodeReceived += delegate(object sender, AuthCodeReceivedEventArgs args) { Debug.WriteLine("Auth Code: " + args.AuthCode); };
            //auth.AccessTokenReceived += delegate(object sender, TokenReceivedEventArgs args) { Debug.WriteLine("Access Token: " + args.Token); };
            //auth.GetTokenAsync("<Client id>", "<Client Secret>", Scope.Full);

            // You can either use the StravaClient or 'single' clients like the ActivityClient.
            // The StravaClient offers predefined clients.
            StravaClient client = new StravaClient(auth);

            AthleteSummary a = await client.Athletes.GetAthleteAsync();

            Console.WriteLine("{0} {1}", a.FirstName, a.LastName);

            #region Activities

            //var activities = client.Activities.GetActivities(new DateTime(2014, 1, 1), DateTime.Now);
            //var activitiesAsync = await client.Activities.GetActivitiesAsync(new DateTime(2014, 1, 1), DateTime.Now);

            //foreach (var item in activities)
            //{
            //    Console.WriteLine(DateConverter.ConvertIsoTimeToDateTime(item.StartDateLocal));
            //}

            //Console.WriteLine("Sync: " + activities.Count);
            //Console.WriteLine("Async: " + activitiesAsync.Count);

            #endregion

            #region Athlete

            //Athlete current = await client.Athletes.GetAthleteAsync();
            //Console.WriteLine(current);

            //List<AthleteSummary> friends = await client.Athletes.GetFriendsAsync();
            //Console.WriteLine(friends.Count);

            //List<AthleteSummary> bothFollowing = await client.Athletes.GetBothFollowingAsync("528819");
            //Console.WriteLine(bothFollowing.Count);

            //List<SegmentEffort> records = await client.Segments.GetRecordsAsync("528819");

            //foreach (SegmentEffort effort in records)
            //{
            //    Console.WriteLine(effort.Name);
            //}

            //List<SegmentSummary> starred = await client.Segments.GetStarredSegmentsAsync();
            //Console.WriteLine(starred.Count);

            #region Update Athlete Weight

            //Athlete a = client.GetAthlete();
            //Console.WriteLine(a.FirstName + " " + a.LastName);

            //Athlete updated = client.UpdateAthlete(AthleteParameter.Weight, "60.0");
            //Console.WriteLine(updated.Email);

            #endregion

            #endregion

            #region Map Decoder

            //Activity mapActivity = await client.Activities.GetActivityAsync("109557593", false);
            //List<Coordinate> coords = PolylineDecoder.Decode(mapActivity.Map.Polyline);

            //foreach (var coordinate in coords)
            //{
            //    Console.WriteLine(coordinate);
            //}

            #endregion

            #region Leaderboard

            // Get the leaderboard of a segment.
            //Leaderboard leaderboard = client.Segments.GetFullSegmentLeaderboard("1300798");

            //foreach (LeaderboardEntry entry in leaderboard.Entries)
            //{
            //    Console.WriteLine(entry.ToString());
            //}

            #endregion

            #region Comments

            //List<Comment> comments = await client.Activities.GetCommentsAsync("112861810");

            //foreach (var comment in comments)
            //{
            //    Console.WriteLine(comment.Text);
            //    Console.WriteLine();
            //}

            #endregion

            #region Kudos

            //List<Athlete> kudoAthletes = await client.Activities.GetKudosAsync("112818941");

            //foreach (var kudos in kudoAthletes)
            //{
            //    Console.WriteLine(kudos.FirstName);
            //}

            #endregion

            #region Club

            //Athlete clubAthlete = await client.Athletes.GetAthleteAsync();

            //foreach (Club club in clubAthlete.Clubs)
            //{
            //    Console.WriteLine(club.Id);
            //}

            //Club c = await client.Clubs.GetClubAsync("949");
            //Console.WriteLine("Club: {0}", c.Name);

            //Image image = await ImageLoader.LoadImage(new Uri(c.Profile));
            //Form form = new Form();
            //form.Controls.Add(new PictureBox() { Dock = DockStyle.Fill, Image = image, SizeMode = PictureBoxSizeMode.CenterImage });
            //form.ShowDialog();

            //// Gets all the clubs of the currently authenticated user.
            //Console.WriteLine("Clubs:");
            //List<ClubSummary> clubs = await client.Clubs.GetClubsAsync();

            //foreach (var club in clubs)
            //{
            //    Console.WriteLine(club.Name);
            //}

            //// Only returns a result, if the athlete is a member in the club.
            //List<AthleteSummary> athletes = await client.Clubs.GetClubMembersAsync("949");
            //foreach (AthleteSummary athlete in athletes)
            //{
            //    Console.WriteLine(athlete.FirstName + " " + athlete.LastName);
            //}

            #endregion

            #region ActivityZones

            //List<ActivityZone> zones = client.Activities.GetActivityZones("114701243");

            //foreach (var item in zones.First().Buckets)
            //{
            //    Console.WriteLine(item.Maximum + " " + item.Minimum + " " + item.Time);
            //}

            #endregion

            #region Club Activities

            //List<ActivitySummary> items = client.Clubs.GetLatestClubActivities("949", 1, 5);

            //foreach (var activity in items)
            //{
            //    Console.WriteLine(activity.Name);
            //}

            //Console.WriteLine();

            //items = client.Clubs.GetLatestClubActivities("949", 2, 5);

            //foreach (var activity in items)
            //{
            //    Console.WriteLine(activity.Name);
            //}

            #endregion

            #region Latest activities of your friends

            //List<ActivitySummary> activities = await client.Activities.GetFriendsActivitiesAsync(10);

            //foreach (var item in activities)
            //{
            //    Console.WriteLine(item.Name);
            //}

            #endregion

            #region ActivityReceived Event-Test

            //client.Activities.ActivityReceived += delegate(object sender, ActivityReceivedEventArgs args) { Console.WriteLine(args.Activity.Name); };
            //await client.Activities.GetAllActivitiesAsync();

            #endregion

            #region Gear

            //Athlete athleteGear = client.Athletes.GetAthlete();

            //foreach (var bike in athleteGear.Bikes)
            //{
            //    Bike gear = await client.Gear.GetGearAsync(bike.Id);
            //    Console.WriteLine(gear.Name);
            //}

            //foreach (Shoes shoes in athleteGear.Shoes)
            //{
            //    Bike gear = await client.Gear.GetGearAsync(shoes.Id);
            //    Console.WriteLine(gear.Name);
            //}

            #endregion

            #region Streams

            //List<ActivityStream> streams = client.Streams.GetActivityStream("117700501", StreamType.LatLng | StreamType.Heartrate);
            //foreach (var stream in streams)
            //{
            //    Console.WriteLine(stream.StreamType);
            //    Console.WriteLine(stream.OriginalSize);
            //    Console.WriteLine(stream.Data.Count);
            //}


            //List<SegmentStream> segmentStreams = client.Streams.GetSegmentStream("6295188", SegmentStreamType.LatLng | SegmentStreamType.Distance, StreamResolution.All);
            //foreach (var stream in segmentStreams)
            //{
            //    Console.WriteLine(stream.StreamType);
            //    Console.WriteLine(stream.OriginalSize);
            //}

            //List<ActivitySummary> ac = client.Activities.GetActivitiesAfter(new DateTime(2014, 1, 1));
            //Console.WriteLine(ac.Count);

            #endregion

            #region Update Activity

            //Activity a = await client.Activities.UpdateActivityTypeAsync("<activity id>", ActivityType.Ride);
            //Console.WriteLine(a.Type);

            //Activity a = await client.Activities.UpdateActivityAsync("<activity id>", ActivityParameter.Name, "Kurze Testfahrt nach Schaltzug- und Kettenwechsel");
            //Console.WriteLine(a.Name);

            #endregion

            #region Weekly Progress

            //WeeklyProgress p = client.Activities.GetWeeklyProgress();

            //Console.WriteLine(p.TotalTime);
            //Console.WriteLine(p.RideDistance / 1000F);
            //Console.WriteLine(p.ActivityCount);

            #endregion

            #region Summary

            //var activities = client.Activities.GetSummary(new DateTime(2014, 1, 1), DateTime.Now);
            //var activities = client.Activities.GetSummaryLastYear();
            //var activities = client.Activities.GetSummaryThisYear();

            //Console.WriteLine("Activities: " + activities.ActivityCount);
            //Console.WriteLine("Rides: " + activities.Rides.Count);
            //Console.WriteLine("Ride Distance: " + activities.RideDistance / 1000D);

            #endregion

            #region Time Filter

            //Leaderboard l = await client.Segments.GetSegmentLeaderboardAsync("6861720", TimeFilter.ThisYear);
            //foreach (var s in l.Entries)
            //{
            //    Console.WriteLine(s.AthleteName);
            //}

            #endregion

            #region Segment-Explorer

            //ExplorerResult result = await client.Segments.ExploreSegmentsAsync(
            //    new Coordinate(37.821362, -122.505373),
            //    new Coordinate(37.842038, -122.465977),
            //    0,
            //    5);

            //foreach (ExplorerSegment s in result.Results)
            //{
            //    Console.WriteLine(s.Name);
            //}

            #endregion

            #region Segment Efforts

            //List<SegmentEffort> efforts = await client.Efforts.GetSegmentEffortsByTimeAsync("6386278", new DateTime(2014, 1, 1), new DateTime(2014, 4, 10));
            //List<SegmentEffort> efforts = await client.Efforts.GetSegmentEffortsByAthleteAsync("6386278", "1985994");
            //List<SegmentEffort> efforts = await client.Efforts.GetSegmentEffortsAsync("6386278", "1985994", new DateTime(2014, 4, 8), new DateTime(2014, 4, 10));
            //List<SegmentEffort> efforts = await client.Efforts.GetSegmentEffortsAsync("6386278");

            //foreach (SegmentEffort effort in efforts)
            //{
            //    Console.WriteLine(effort.Athlete.Id);
            //    Console.WriteLine(" " + effort.MovingTime / 60 + "m" + effort.MovingTime % 60 + "s");
            //}


            #endregion

            #region MapLoader

            //Activity a = await client.Activities.GetActivityAsync("129042840", false);
            //Debug.WriteLine(a.Map.SummaryPolyline);

            //System.Drawing.Image image = await GoogleImageLoader.LoadActivityPreviewAsync(a.Map.SummaryPolyline, new Dimension(150, 150), MapType.Terrain);
            //Form form = new Form();
            //form.Size = new Size(300, 300);

            //PictureBox p = new PictureBox();
            //p.Dock = DockStyle.Fill;
            //p.Image = image;
            //form.Controls.Add(p);

            //form.ShowDialog();

            #endregion

            #region Photos

            ////List<Photo> photos = await client.Activities.GetPhotosAsync("133317643");
            ////Debug.WriteLine("Photos: " + photos.Count);

            //List<Photo> photos = await client.Activities.GetLatestPhotosAsync(new DateTime(2014, 1, 1));
            //Debug.WriteLine("Photos: " + photos.Count);

            #endregion

            #region Laps

            //List<ActivityLap> laps = await client.Activities.GetActivityLapsAsync("135450490");

            //foreach (var lap in laps)
            //{
            //    Console.WriteLine((lap.Distance / 1000F).ToString("F"));
            //}

            #endregion
        }
 public StravaController()
 {
     auth   = new StaticAuthentication(AuthController.bearer);
     client = new StravaClient(auth);
 }
Exemple #12
0
        public string InitSession()
        {
            HttpStatusCode httpStatus;

            // No idea why from time to time the login fails.  It does
            // not appear that it is a failed login, but instead
            // strava is ignoring the post and is just re-rendering the
            // login page.  - must have something to do with the authenticity token or something.
            var loggedIn = false;

            for (var tryCount = 0; tryCount < 3; tryCount++)
            {
                this._cookieHolder = new CookieContainer();
                var loginPage = this.HttpGet("https://www.strava.com/login", out httpStatus);

                if (httpStatus != HttpStatusCode.OK)
                {
                    return("Unable to contact the Strava server.");
                }

                // Attempt to parse the table.
                var loader = new HtmlAgilityPack.HtmlDocument();
                loader.LoadHtml(loginPage);

                AttributeFinder finder = (doc, name) =>
                {
                    var element = (from n in doc.DocumentNode.Descendants("input") where n.GetAttributeValue("name", string.Empty) == name select n).FirstOrDefault();

                    if (element == null)
                    {
                        return(string.Empty);
                    }

                    var attb = element.Attributes.FirstOrDefault(f => f.Name == "value");

                    if (attb == null)
                    {
                        return(string.Empty);
                    }

                    return(attb.Value);
                };

                var authTok = finder(loader, "authenticity_token");
                var utf8    = finder(loader, "utf8");

                var loginResultPage = this.HttpPost(
                    "https://www.strava.com/session",
                    string.Format(
                        "email={0}&password={1}&authenticity_token={2}&utf8=%E2%9C%93",
                        HttpUtility.HtmlEncode(this._userName),
                        HttpUtility.HtmlEncode(this._password),
                        authTok),
                    out httpStatus);

                if (httpStatus != HttpStatusCode.OK)
                {
                    return("Unable to contact the Strava server.");
                }

                loader = new HtmlAgilityPack.HtmlDocument();
                loader.LoadHtml(loginResultPage);

                var htmlObj = loader.DocumentNode.Descendants("html").FirstOrDefault();

                if (htmlObj == null)
                {
                    return("Unexpected result returned from Strava Server");
                }

                if (htmlObj.GetAttributeValue("class", string.Empty).Split(' ').Any(a => a.ToLower() == "logged-in"))
                {
                    loggedIn = true;
                    break;
                }

                // Not logged in.
                // Need to see if an 'alert-message' exists.
                htmlObj = (from n in loader.DocumentNode.Descendants("div") where n.GetAttributeValue("class", string.Empty) == "alert-message" select n).FirstOrDefault();

                if (htmlObj != null &&
                    htmlObj.InnerHtml.ToLower().Contains("did not match"))
                {
                    // If this exists, the error is wrong pwd.
                    break;
                }

                if (htmlObj != null &&
                    htmlObj.InnerHtml.ToLower().Contains("expired"))
                {
                    // Session expired... loop around again.
                    // Is this a .net thing?  I'm creating a new cookie container...whatever, I
                    // guess this hack seems to work by looping and just trying again.
                }
            }

            if (!loggedIn)
            {
                return("The login details provider do not appear to be valid.");
            }

            // We're now logged in.

            // Next, we need to be sure we have a valid API token.
            this._auth = new StaticAuthentication(this._apiKey);
            var athlete = new AthleteClient(this._auth);

            try
            {
                var details = athlete.GetAthlete();

                if (details == null ||
                    details.Email == null ||
                    details.Email.ToLower() != this._userName.ToLower())
                {
                    return("The API key is not associated to the same Strava account as the user name provided.");
                }
            }
            catch
            {
                return("The API key provided does not appear to be valid");
            }


            return(string.Empty);
        }
Exemple #13
0
        static void Main(string[] args)
        {
            #region settings

            if (!ReadClientSettings())
            {
                //prompt and save to file
                ClientId      = ShowInputBox("Provide your Strava Client ID", "Configuration");
                ClientSecret  = ShowInputBox("Provide your Strava Client Secret", "Configuration");
                FolderWithTcx = ShowInputBox("Provide path to folder with TCX files", "Configuration");

                if (string.IsNullOrEmpty(ClientId) || string.IsNullOrEmpty(ClientSecret))
                {
                    Environment.Exit(0);
                }
                SetSetting(GetPropertyName(() => ClientId), ClientId);
                SetSetting(GetPropertyName(() => ClientSecret), ClientSecret);
                SetSetting(GetPropertyName(() => FolderWithTcx), FolderWithTcx);
            }
            Console.WriteLine("Configuration values - OK");
            #endregion

            #region authentication

            System.Diagnostics.Process.Start(
                $"https://www.strava.com/oauth/mobile/authorize?client_id={ClientId}&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&approval_prompt=auto&scope=activity%3Awrite%2Cread&state=test");

            if (string.IsNullOrEmpty(AuthCode))
            {
                AuthCode = ShowInputBox("Provide your Strava Auth Code", "Configuration");
            }

            #endregion

            string[] files = Directory.GetFiles(FolderWithTcx, "*.tcx");
            Console.WriteLine($"Found {files.Count()} TCX files to process.");

            HttpClient httpClient = new HttpClient();

            var values = new Dictionary <string, string>
            {
                { "client_id", ClientId },
                { "client_secret", ClientSecret },
                { "code", AuthCode },
                { "grant_type", "authorization_code" }
            };

            try
            {
                var     content        = new FormUrlEncodedContent(values);
                var     response       = httpClient.PostAsync("https://www.strava.com/api/v3/oauth/token", content).Result;
                var     responseString = response.Content.ReadAsStringAsync().Result;
                dynamic objects        = JsonConvert.DeserializeObject(responseString);
                string  token          = objects["access_token"];
                if (!string.IsNullOrEmpty(token))
                {
                    Console.WriteLine("Authentication - OK");
                }
                else
                {
                    Console.WriteLine("Authentication - FAILURE");
                }

                StaticAuthentication auth   = new StaticAuthentication(token);
                StravaClient         client = new StravaClient(auth);

                Console.WriteLine("If you see nothing below for a longer period - verify your Strava API usage limits.");
                int shortTermUsage = Limits.Usage.ShortTerm;
                int shortTermLimit = Limits.Limit.ShortTerm;
                foreach (var item in files)
                {
                    UploadStatus status = client.Uploads.UploadActivityAsync(item, DataFormat.Tcx).Result;
                    Thread.Sleep(2000);
                    UploadStatusCheck check = new UploadStatusCheck(token, status.Id.ToString());

                    check.UploadChecked += delegate(object o, UploadStatusCheckedEventArgs args2)
                    {
                        shortTermLimit = Limits.Limit.ShortTerm;
                        shortTermUsage = Limits.Usage.ShortTerm;
                        Console.WriteLine($"{args2.Status} {item} || Limit {shortTermUsage} {shortTermLimit}");

                        if (args2.Status == CurrentUploadStatus.Ready)
                        {
                            File.Delete(item);
                        }
                    };

                    check.Start();
                    if (shortTermLimit <= shortTermUsage + 10)
                    {
                        Thread.Sleep(GetTimeToSleep());
                        shortTermLimit = Limits.Limit.ShortTerm;
                        shortTermUsage = Limits.Usage.ShortTerm;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                Console.Read();
            }
        }