Example #1
0
        private void ProcessDownloaderGen(ContentGenRecipes oRecipes, string sContentUniqueId, string sContentHashCode)
        {
            string sNewGUID       = Guid.NewGuid().ToString().ToUpper();
            string sWorkingFolder = ContentWorkingPath + "\\" + sContentUniqueId;

            // Initialization
            DownloaderGenTask oDG = new DownloaderGenTask(
                sWorkingFolder,
                sNewGUID,
                sWorkingFolder + "\\" + sContentHashCode + TorrentExtension,
                "", // No Banner Replacement Support
                oRecipes.IconFile == "" ? "" : IconResPath + "\\" + oRecipes.IconFile,
                oRecipes.PromotionEventID,
                sContentHashCode + DownloaderExtension,
                oRecipes.DownloaderDisplayName,
                oRecipes.DownloaderHomeUrl,
                oRecipes.DisclaimerFile == "" ? "" : DisclaimerResPath + "\\" + oRecipes.DisclaimerFile,
                oRecipes.OnlineFaqUrl,
                oRecipes.GAProfileId,
                oRecipes.PromotionEventServerUrl,
                oRecipes.UPXCompression);

            // Generate the downloader accordingly
            oDG.Generate();
        }
Example #2
0
        internal static string ReadContentRecipesJson(string sContentUniqueId, string sContentHashCode)
        {
            lock (sigLock)
            {
                string sContentRecipesJsonFile =
                    ContentWorkingPath + "\\" +
                    sContentUniqueId + "\\" +
                    sContentHashCode + ContentRecipesFileExtension;

                if (File.Exists(sContentRecipesJsonFile))
                {
                    return(File.ReadAllText(sContentRecipesJsonFile));
                }
                else
                {
                    return(ContentGenRecipes.GetJson(
                               new ContentGenRecipes()
                    {
                        AutoDeploy = true,
                        UPXCompression = true
                    }
                               ));
                }
            }
        }
Example #3
0
        private static ContentGenRecipes GetContentRecipes(string sContentUniqueId, string sContentHashCode)
        {
            string sRecipesJson = ContentGenJob.ReadContentRecipesJson(sContentUniqueId, sContentHashCode);

            if (sRecipesJson != null)
            {
                return(ContentGenRecipes.FromJson(sRecipesJson));
            }
            return(null);
        }
Example #4
0
 public void GenerateContentReq(string sContentUniqueId, string sContentGenRecipesJson)
 {
     lock (quartzScheduler)
     {
         // Create a ContentGenJob per Content if none has existed
         if (null == quartzScheduler.GetJobDetail(
                 sContentUniqueId,
                 ContentGenConstants.ContentGenGroupName))
         {
             // Create a durable ContentGenJob and add to the scheduler
             JobDetail oJob = new JobDetail(
                 sContentUniqueId,
                 ContentGenConstants.ContentGenGroupName,
                 typeof(ContentGenJob), false, true, false);
             oJob.JobDataMap[ContentGenJobDataMapConstants.OverallCompletion] = "0%";
             quartzScheduler.AddJob(oJob, true);
         }
         // Create and initialize the trigger for the specific job request
         string sTriggerName = sContentUniqueId + " (" +
                               quartzScheduler.GetTriggersOfJob(
             sContentUniqueId,
             ContentGenConstants.ContentGenGroupName).Count + ")";
         Trigger oTrigger = new SimpleTrigger(
             sTriggerName,
             ContentGenConstants.ContentGenGroupName,
             // Compute a time that is on the next round minute
             TriggerUtils.GetNextGivenSecondDate(DateTime.UtcNow, 5));
         // ####################################################################
         oTrigger.MisfireInstruction = MisfireInstruction.SimpleTrigger.FireNow;
         // ####################################################################
         oTrigger.JobName  = sContentUniqueId;
         oTrigger.JobGroup = ContentGenConstants.ContentGenGroupName;
         ContentGenRecipes oJson = ContentGenRecipes.FromJson(sContentGenRecipesJson);
         oTrigger.JobDataMap[GeneralJobDataMapConstants.ContentUniqueId]       = sContentUniqueId;
         oTrigger.JobDataMap[ContentGenJobDataMapConstants.ContentRecipesJson] = ContentGenRecipes.GetJson(oJson);
         quartzScheduler.ScheduleJob(oTrigger);
     }
 }
Example #5
0
        public void Execute(JobExecutionContext context)
        {
            string            sContentHashCode = "";
            ContentGenRecipes oContentRecipes;
            JobDataMap        oJobDataMap         = context.JobDetail.JobDataMap;
            string            sContentUniqueId    = (string)context.MergedJobDataMap[GeneralJobDataMapConstants.ContentUniqueId];
            string            sContentRecipesJson = (string)context.MergedJobDataMap[ContentGenJobDataMapConstants.ContentRecipesJson];

            #region Content (Metafiles / Torrents) Generating (support for interruption)
            try
            {
                //=============================================================================
                log.InfoFormat(AppResource.StartJobExecution, typeof(ContentGenJob).Name);
                //=============================================================================

                // Validate the settings & the input data map parameters
                Check.IsNullOrEmpty(sContentUniqueId, GeneralJobDataMapConstants.ContentUniqueId);
                Check.IsNullOrEmpty(sContentRecipesJson, ContentGenJobDataMapConstants.ContentRecipesJson);
                // Check the existence of the content versioning file
                CheckAndCreateContentVersionFile(sContentUniqueId);
                // Deserialize Content Recipes from the input Json
                oContentRecipes = ContentGenRecipes.FromJson(sContentRecipesJson);
                if (oContentRecipes.ContentHashCode == null ||
                    oContentRecipes.ContentHashCode == "")
                {
                    // Do the torrent generating process
                    oJobDataMap[ContentGenJobDataMapConstants.OverallCompletion] = "0%";
                    ProcessTorrentGen(
                        sContentUniqueId,
                        oContentRecipes,
                        (o, ev) =>
                    {
                        // Update the overall completion rate of the job
                        oJobDataMap[ContentGenJobDataMapConstants.OverallCompletion] =
                            ev.OverallCompletion.ToString("#0.##\\%");
                    },
                        out sContentHashCode);
                }
                else
                {
                    // Skip the torrent generating process
                    oJobDataMap[ContentGenJobDataMapConstants.OverallCompletion] = "100%";
                    sContentHashCode = oContentRecipes.ContentHashCode;
                }
                // Update the content hash code to the job data map
                oJobDataMap[GeneralJobDataMapConstants.ContentHashCode] = sContentHashCode;

                //=============================================================================
                log.InfoFormat(AppResource.TaskExecutionDone, AppResource.MetafileGenTaskName);
                //=============================================================================
            }
            catch (Exception oEx)
            {
                Rollback(sContentUniqueId, sContentHashCode);

                //===================================================================================================
                log.ErrorFormat(AppResource.JobExecutionFailed, oEx, typeof(ContentGenJob).Name, oEx.Message);
                //===================================================================================================
                return;
            }
            #endregion

            #region Downloader Generating
            // The most brutal way to make sure of the job be executed synchronouly
            try
            {
                // Validate the settings & the input data map parameters
                Check.IsNullOrEmpty(sContentHashCode, GeneralJobDataMapConstants.ContentHashCode);
                lock (sigResUpdateLock) // To protect the global memory used in the ResourceLib
                {
                    // Generate the downloader accordingly
                    ProcessDownloaderGen(oContentRecipes, sContentUniqueId, sContentHashCode);
                }
                // Save the Content Recipes Json when downloader generating successfully
                Uri uri = new Uri(oContentRecipes.ContentSourceUrl);
                oContentRecipes.ContentFileName = Path.GetFileName(uri.LocalPath); // Get the file name
                oContentRecipes.ContentHashCode = sContentHashCode;
                oContentRecipes.CreateDateTime  = DateTime.Now;
                SaveContentRecipesJson(
                    sContentUniqueId, sContentHashCode,
                    ContentGenRecipes.GetJson(oContentRecipes));
                // Update the history file when downloader generating successfully
                AppendHistoryFile(ContentRecipesPropHistory.DownloaderDisplayName, sContentUniqueId, oContentRecipes.DownloaderDisplayName);
                AppendHistoryFile(ContentRecipesPropHistory.DownloaderHomeUrl, sContentUniqueId, oContentRecipes.DownloaderHomeUrl);
                AppendHistoryFile(ContentRecipesPropHistory.GAProfileId, sContentUniqueId, oContentRecipes.GAProfileId);
                AppendHistoryFile(ContentRecipesPropHistory.OnlineFaqUrl, sContentUniqueId, oContentRecipes.OnlineFaqUrl);
                AppendHistoryFile(ContentRecipesPropHistory.PromoEventId, sContentUniqueId, oContentRecipes.PromotionEventID);
                AppendHistoryFile(ContentRecipesPropHistory.PromoEventServerUrl, sContentUniqueId, oContentRecipes.PromotionEventServerUrl);

                //=============================================================================
                log.InfoFormat(AppResource.TaskExecutionDone, AppResource.DownloaderGenTaskName);
                //=============================================================================
            }
            catch (Exception oEx)
            {
                Rollback(sContentUniqueId, sContentHashCode);

                //===================================================================================================
                log.ErrorFormat(AppResource.JobExecutionFailed, oEx, typeof(ContentGenJob).Name, oEx.Message);
                //===================================================================================================
                return;
            }
            #endregion

            #region Content Deployment if specified
            // Do the content deployment if specified
            if (oContentRecipes.AutoDeploy)
            {
                try
                {
                    // Validate the settings & the input data map parameters
                    Check.IsNullOrEmpty(sContentHashCode, GeneralJobDataMapConstants.ContentHashCode);
                    // The most brutal way to make sure of the job be executed synchronouly
                    lock (sigResUpdateLock)
                    {
                        // Do the content deployment task
                        ContentDeployJob.ProcessContentDeploy(sContentUniqueId, sContentHashCode);
                    }

                    //=============================================================================
                    log.InfoFormat(AppResource.TaskExecutionDone, AppResource.MetafileDeployTaskName);
                    //=============================================================================
                }
                catch (Exception oEx)
                {
                    // Do nothing here so users can re-deploy again without re-generating all the files
                    // And keep on the next task for the aforementioned reason.

                    //===================================================================================================
                    log.ErrorFormat(AppResource.JobExecutionFailed, oEx, typeof(ContentGenJob).Name, oEx.Message);
                    //===================================================================================================
                }
            }
            #endregion

            #region Update Content Version File
            try
            {
                // Update the content versioning file in the very end of the job
                // to maintain the consistence as possible
                AppendContentVersionFile(sContentUniqueId, sContentHashCode);

                //=============================================================================
                log.InfoFormat(AppResource.EndJobExecution, typeof(ContentGenJob).Name);
                //=============================================================================
            }
            catch (Exception oEx)
            {
                // Clear up all the generated files & the deployed files since it should be a sever error!
                if (oContentRecipes.AutoDeploy)
                {
                    ContentDeployJob.Rollback(sContentHashCode);
                }
                Rollback(sContentUniqueId, sContentHashCode);

                //===================================================================================================
                log.ErrorFormat(AppResource.JobExecutionFailed, oEx, typeof(ContentGenJob).Name, oEx.Message);
                //===================================================================================================
                return;
            }
            #endregion
        }
Example #6
0
        private void ProcessTorrentGen(string sContentUniqueId, ContentGenRecipes oRecipes, EventHandler <TorrentCreatorEventArgs> callbackHashed, out string sContentHashCode)
        {
            long   lPieceLengthKB              = AppConfig.ContentGenJob.PieceLengthKB;
            string sCreatedBy                  = AppConfig.ContentGenJob.CreatedBy;
            string sTrackerAnnounceUrl         = AppConfig.ContentGenJob.TrackerAnnounceUrl;
            string sInternalTrackerAnnounceUrl = AppConfig.ContentGenJob.InternalTrackerAnnounceUrl;

            // Initialization
            _InterruptFlag   = false;
            sContentHashCode = "";

            // Initialize the torrent creation task
            MetafileGenTask oMG = new MetafileGenTask();

            oMG.Hashed += callbackHashed;

            // Set the torrent info
            oMG.PieceLength = lPieceLengthKB * 1024; // Torrent info: PieceLength
            oMG.StoreMD5    = false;                 // Don't store MD5SUM in the torrent file
            oMG.Private     = true;                  // Always be private torrent
            oMG.CreatedBy   = sCreatedBy;            // Torrent info: CreatedBy
            if (oRecipes.HttpSeedsUrl != null && oRecipes.HttpSeedsUrl.Length > 0)
            {
                List <string> listUrls = oRecipes.HttpSeedsUrlList;
                listUrls.ForEach(sUrl => { oMG.GetrightHttpSeeds.Add(sUrl); }); // URL seed
            }
            List <string> oAnn = new List <string>();

            oAnn.Add(sTrackerAnnounceUrl);
            oMG.Announces.Add(oAnn); // Torrent Info: Tracker Server
            // Assign the custom fields to the "info" section of the torrent
            oMG.AddCustomSecure("ga account name", new BEncodedString(oRecipes.GAProfileId));
            oMG.AddCustomSecure("ga host name", new BEncodedString("http://www.gamania.com"));
            oMG.AddCustomSecure("custom display name", new BEncodedString(oRecipes.DownloaderDisplayName));

            // Begin the async torrent creation process
            IAsyncResult asyncResult = oMG.BeginCreate(
                oRecipes.ContentSourceUrl, // Content Source URL
                null,                      // No callback needed
                oRecipes.ContentSourceUrl  // Async state
                );

            // Wait for the completion or the aborting
            if (!asyncResult.IsCompleted)
            {
                while (!asyncResult.AsyncWaitHandle.WaitOne(1000))
                {
                    if (_InterruptFlag)
                    {
                        oMG.AbortCreation();                 // Try to abort the task
                    }
                }
            }
            // End of the async torre creation
            BEncodedDictionary oTorrentBenDict = oMG.EndCreate(asyncResult);

            // Get the content hash code from the torrent file
            sContentHashCode = Torrent.Load(oTorrentBenDict).InfoHash.ToHex();
            lock (sigLock)
            {
                // ========= Save 3 types of torrent files for 3 different usages ==============
                // 1. Save the torrent file which contains the public tracker announce URL
                File.WriteAllBytes(
                    ContentWorkingPath + "\\" +
                    sContentUniqueId + "\\" +
                    sContentHashCode + TorrentExtension,
                    oTorrentBenDict.Encode());

                // 2. Save the VIP torrent file contains the public tracker announce URL
                if (oRecipes.VipHttpSeedsUrl != null && oRecipes.VipHttpSeedsUrl.Length > 0)
                {
                    // Add more Url Seed Urls
                    List <string> listUrls = oRecipes.VipHttpSeedsUrlList;
                    listUrls.ForEach(sUrl => { oMG.GetrightHttpSeeds.Add(sUrl); }); // Add more URL seed
                    // Convert to Ben-Encoded List
                    BEncodedList listUrlSeeds = new BEncodedList();
                    listUrlSeeds.AddRange(oMG.GetrightHttpSeeds.ConvertAll <BEncodedValue>(s => { return((BEncodedString)s); }));
                    oTorrentBenDict[TorrentInfoUrlListKey] = listUrlSeeds;
                }
                // Save the VIP Torrent file
                File.WriteAllBytes(
                    ContentWorkingPath + "\\" +
                    sContentUniqueId + "\\" +
                    sContentHashCode + TorrentVipExtension,
                    oTorrentBenDict.Encode());
                // 3. Save the FQDN torrent file which contains the internal tracker announce URL
                // First, add the content source URL to the torrent to accelerate the download speed
                if (-1 == oRecipes.HttpSeedsUrlList.FindIndex(x => { return(x.Equals(oRecipes.ContentSourceUrl)); }) &&
                    -1 == oRecipes.VipHttpSeedsUrlList.FindIndex(x => { return(x.Equals(oRecipes.ContentSourceUrl)); }))
                {
                    // Add the content source URL to the TorrentInfoUrlListKey
                    // together with the VIP URL seeds just added previously
                    oMG.GetrightHttpSeeds.Add(oRecipes.ContentSourceUrl);
                    // Convert to Ben-Encoded List
                    BEncodedList listUrlSeeds = new BEncodedList();
                    listUrlSeeds.AddRange(oMG.GetrightHttpSeeds.ConvertAll <BEncodedValue>(s => { return((BEncodedString)s); }));
                    oTorrentBenDict[TorrentInfoUrlListKey] = listUrlSeeds;
                }
                // Second, replace the tracker announce URL with the internal tracker announce URL
                oTorrentBenDict[TorrentInfoAnnounceKey] = new BEncodedString(sInternalTrackerAnnounceUrl);
                // Save the FQDN Torrent file
                File.WriteAllBytes(
                    ContentWorkingPath + "\\" +
                    sContentUniqueId + "\\" +
                    sContentHashCode + TorrentFqdnExtension,
                    oTorrentBenDict.Encode());
            }
        }
Example #7
0
        private static string ProcessContentMonitor(List <string> listVersion, JobExecutionContext context)
        {
            JobDataMap oJobDataMap = context.JobDetail.JobDataMap;

            string[]      listSeedWebIP  = AppConfig.ContentDeployJob.OfficalSeedWebIPList;
            ContentDetail oContentDetail = new ContentDetail();

            // Construct the hierarchy per the Version list & registered Seed Web IP list first
            oContentDetail.Name        = context.JobDetail.Name;
            oContentDetail.DateCreated = GetContentCreateDate(context.JobDetail.Name);
            foreach (string sVer in listVersion)
            {
                VersionDetail     oVerDetail      = new VersionDetail();
                ContentGenRecipes oContentRecipes = GetContentRecipes(oContentDetail.Name, sVer);

                if (oContentRecipes != null)
                {
                    oVerDetail.Name        = oContentRecipes.ContentFileName;
                    oVerDetail.DateCreated = oContentRecipes.CreateDateTime;
                }
                else
                {
                    oVerDetail.Name        = "";
                    oVerDetail.DateCreated = DateTime.MaxValue;
                }
                oVerDetail.Hash            = sVer;
                oVerDetail.DeployToTracker = QueryTrackerTorrentDeploymentStatus(sVer);
                oContentDetail.Versions.Add(oVerDetail);
                foreach (string sIP in listSeedWebIP)
                {
                    TorrentSeedDetail oDetail = new TorrentSeedDetail();

                    // Create the TorrentSeedDetail first with the unknown status
                    // And replace the unkown status with the real status parsed from JSON later
                    oDetail.IP            = sIP;
                    oDetail.Hash          = oVerDetail.Hash.ToUpper();
                    oDetail.Name          = "";
                    oDetail.TotalSize     = 0;
                    oDetail.PartDone      = 0f;
                    oDetail.StatusCode    = TorrentStatus.Unknown;
                    oDetail.DatePublished = DateTime.MaxValue;
                    oDetail.Error         = AppResource.SeedWebConnectionFailed;
                    oVerDetail.TorrentSeeds.Add(oDetail);
                }
            }
            // Enumerate all the registered seed web IP for walking through all the seed monitors
            foreach (string sIP in listSeedWebIP)
            {
                JobDetail oSeedJob = context.Scheduler.GetJobDetail(
                    sIP, SeedMonitorConstants.SeedMonitorGroupName);
                // Check to see if the seed monitor job exists
                if (oSeedJob != null)
                {
                    string sTorrentDetails = (string)oSeedJob.JobDataMap[SeedMonitorJobDataMapConstants.TorrentDetails];
                    // Check to see if the seed monitor has torrent detail JSON ready
                    if (sTorrentDetails != null)
                    {
                        List <TorrentDetail> listTorrentDetail = JsonConvert.DeserializeObject <List <TorrentDetail> >(sTorrentDetails);
                        List <string>        listTorrentInSeed = new List <string>();
                        // Enumerate all the TorrentDetail to update to the pre-created TorrentSeedDetail
                        foreach (TorrentDetail oTorrentDetail in listTorrentDetail)
                        {
                            TorrentSeedDetail oDetail = new TorrentSeedDetail();
                            oDetail.IP            = sIP;
                            oDetail.Hash          = oTorrentDetail.UniqueID.ToUpper();
                            oDetail.Name          = oTorrentDetail.Name;
                            oDetail.TotalSize     = oTorrentDetail.TotalSize;
                            oDetail.PartDone      = oTorrentDetail.PartDone;
                            oDetail.StatusCode    = oTorrentDetail.StatusCode;
                            oDetail.DatePublished = oTorrentDetail.DateAdded;
                            oDetail.Error         = oTorrentDetail.Error;
                            // Use the TorrentSeedDetail object to update the corresponding list
                            // in the VersionDetails list so the JSON just needs to be parsed just once
                            UpdateTorrentSeedDetail(oContentDetail, oDetail);
                            // Add the torrent hash for later use of checking the exclusion of the torrents
                            listTorrentInSeed.Add(oDetail.Hash);
                        }
                        // Update TorrentSeedDetail not found in the seed's torrent list to "content not deployed" error
                        foreach (VersionDetail oVersion in oContentDetail.Versions.FindAll
                                     (x => { return(!listTorrentInSeed.Contains(x.Hash)); }))
                        {
                            TorrentSeedDetail oTorrentSeed = oVersion.TorrentSeeds.Find(x => { return(x.IP == sIP); });
                            if (oTorrentSeed != null)
                            {
                                oTorrentSeed.Error = AppResource.ContentNotDeployToSeed;
                            }
                        }
                    }
                }
            }
            // Serialize the content detail to JSON and return
            return(JsonConvert.SerializeObject(oContentDetail));
        }