示例#1
0
        protected ComicRead GetReader(long comicId)
        {
            ComicRead read = null;

            try
            {
                this.EntityContext.TryAttach(this.ActiveUser);
                Data.Comic comic = this.EntityContext.TryGetComic(comicId, this.ActiveUser, this.Friends);
                if (comic == null || !comic.IsPublished)
                {
                    throw new Exception("Unable to find the requested comic.");
                }

                read = this.EntityContext.TryGetComicRead(comic, this.ActiveUser);

                if (read == null)
                {
                    read          = new ComicRead();
                    read.Comic    = comic;
                    read.Reader   = this.ActiveUser;
                    read.ReadTime = DateTime.Now;
                    this.EntityContext.AddToComicRead(read);
                }
            }
            finally
            {
                this.EntityContext.TryDetach(this.ActiveUser);
            }

            return(read);
        }
示例#2
0
        public EmptyResult ReaderComment(long id)
        {
            try
            {
                this.EntityContext.TryAttach(this.ActiveUser);
                Data.Comic comic = this.EntityContext.TryGetComic(id, this.ActiveUser);
                if (comic != null)
                {
                    comic.AuthorReference.Load();
                    UserEngage engage = this.GetUserEngage(comic.Author);

                    comic.Author.UserEngageReference.Load();

                    UserEngageHistory history = comic.Author.UserEngageHistory
                                                .OrderByDescending(h => h.EngageTime)
                                                .FirstOrDefault(h => h.Engagement == UserEngageHistory.EngagementType.Comment);

                    if (!engage.Unsubscribe && engage.Comment && (history == null || history.EngageTime <= DateTime.Now.AddDays(-1)))
                    {
                        ClientComic c = new ClientComic(comic);

                        // create & save history
                        history            = new UserEngageHistory();
                        history.Engagement = UserEngageHistory.EngagementType.Comment;
                        history.EngageTime = DateTime.Now;
                        history.User       = comic.Author;
                        this.EntityContext.AddToUserEngageHistory(history);
                        this.EntityContext.SaveChanges();

                        // Generate email message
                        EmailManager email = new EmailManager(this.Server);
                        Dictionary <string, string> data = new Dictionary <string, string>();
                        data.Add("id", history.EngageHistoryId.ToString());
                        data.Add("title", String.Format("New Comment - {0}", comic.Title));
                        data.Add("reader.name", this.ActiveUser.Nickname);
                        data.Add("comic.title", comic.Title);
                        data.Add("comic.readUrl", c.ReadUrl);

                        // Send email
                        email.SendEmail(comic.Author, "Comment.html", data);
                    }
                }
            }
            finally
            {
                this.EntityContext.TryDetach(this.ActiveUser);
            }

            return(new EmptyResult());
        }
示例#3
0
        public RedirectResult Random()
        {
            RedirectResult result;

            try
            {
                this.EntityContext.TryAttach(this.ActiveUser);

                Data.Comic comic = this.EntityContext.TryGetRandomComic(this.ActiveUser, this.Friends);
                if (comic == null || (comic.IsPrivate && !this.IsFriendOrSelf(comic.Author)))
                {
                    throw new Exception("Unable to find the requested comic.");
                }
                result = this.Redirect(ComicUrlHelper.GetReadUrl(comic));
            }
            finally
            {
                this.EntityContext.TryDetach(this.ActiveUser);
            }
            return(result);
        }
示例#4
0
        public JsonResult RenderProgress(string taskId)
        {
            CloudBlobContainer container = this.BlobClient.GetContainerReference(ComicConfigSectionGroup.Blob.TaskContainer);
            CloudBlobDirectory directory = container.GetDirectoryReference(ComicConfigSectionGroup.Blob.RenderTaskDirectory);
            CloudBlob          blob      = directory.GetBlobReference(taskId);

            XmlSerializer serializer = new XmlSerializer(typeof(RenderTask));

            using (MemoryStream stream = new MemoryStream())
            {
                blob.DownloadToStream(stream);
                stream.Seek(0, SeekOrigin.Begin);
                RenderTask task = (RenderTask)serializer.Deserialize(stream);

                if (task.OwnerUid != this.ActiveUser.Uid)
                {
                    throw new Exception("Unknown task");
                }

                ClientRenderTask clientTask = new ClientRenderTask(task);
                if (task.Status == TaskStatus.Complete && task.ComicId.HasValue)
                {
                    // Load completed comic from database
                    try
                    {
                        this.EntityContext.TryAttach(this.ActiveUser);
                        Data.Comic comic = this.EntityContext.TryGetUnpublishedComic(task.ComicId.Value, this.ActiveUser);
                        clientTask.Comic = new ClientComic(comic);
                    }
                    finally
                    {
                        this.EntityContext.TryDetach(this.ActiveUser);
                    }
                }

                return(this.Json(clientTask, JsonRequestBehavior.AllowGet));
            }

            throw new Exception("Unknown task");
        }
示例#5
0
        protected void Init(Data.Comic source, ComicStat.ComicStatPeriod statsPeriod)
        {
            this.ComicId     = source.ComicId;
            this.Uid         = source.Uid;
            this.TemplateId  = source.TemplateId;
            this.CreateTime  = source.CreateTime;
            this.UpdateTime  = source.UpdateTime;
            this.PublishTime = source.PublishTime;
            this.FeatureTime = source.FeatureTime;
            this.IsPublished = source.IsPublished;
            this.Title       = source.Title;
            this.Description = source.Description;
            this.ShareText   = source.ShareText;
            this.IsPrivate   = source.IsPrivate;

            this.ReadUrl       = ComicUrlHelper.GetReadUrl(source);
            this.ComicUrl      = ComicUrlHelper.GetRenderUrl(source, RenderMode.Comic);
            this.ThumbUrl      = ComicUrlHelper.GetRenderUrl(source, RenderMode.Thumb);
            this.FrameUrl      = ComicUrlHelper.GetRenderUrl(source, RenderMode.Frame);
            this.FrameThumbUrl = ComicUrlHelper.GetRenderUrl(source, RenderMode.FrameThumb);
            this.RemixUrl      = ComicUrlHelper.GetRemixUrl(source);

            this.Author   = new ClientUser(source.Author);
            this.Stats    = new ClientComicStat(source.PeriodStats(statsPeriod));
            this.Template = new ClientTemplate(source.Template);

            if (source.ComicTextBubbles.IsLoaded)
            {
                this.Bubbles = source.ComicTextBubbles.ToList().Select(b => new ClientComicTextBubble(b)).ToList();
            }
            if (source.ComicPhotos.IsLoaded)
            {
                this.Photos = source.ComicPhotos
                              .OrderBy(p => p.TemplateItem.Ordinal)
                              .ToList()
                              .Select(p => new ClientPhoto(p.Photo))
                              .ToList();
            }
        }
示例#6
0
        public ActionResult Delete(long?id)
        {
            try
            {
                this.EntityContext.TryAttach(this.ActiveUser);

                Data.Comic comic = this.EntityContext.TryGetAuthoredComic(id.Value, this.ActiveUser);
                if (comic == null)
                {
                    throw new Exception(String.Format("Unable to find the requested comic '{0}'", id.Value));
                }

                comic.IsDeleted = true;
                this.EntityContext.SaveChanges();
            }
            finally
            {
                this.EntityContext.TryDetach(this.ActiveUser);
            }

            return(this.View());
        }
示例#7
0
        private void ExecuteTask(object state)
        {
            CloudQueueMessage queueMessage = (CloudQueueMessage)state;

            this.Log.DebugFormat("Executing render task {0}", queueMessage.AsString);
            Data.Comic comic = null;
            RenderTask task  = null;

            string            connectionString = ConfigurationManager.ConnectionStrings["ComicModelContext"].ConnectionString;
            ComicModelContext entityContext    = new ComicModelContext(connectionString);

            try
            {
                // Read task details from storage
                CloudBlobContainer container = this.BlobClient.GetContainerReference(ComicConfigSectionGroup.Blob.TaskContainer);
                CloudBlobDirectory directory = container.GetDirectoryReference(ComicConfigSectionGroup.Blob.RenderTaskDirectory);
                CloudBlob          blob      = directory.GetBlobReference(queueMessage.AsString);

                XmlSerializer serializer = new XmlSerializer(typeof(RenderTask));

                using (MemoryStream stream = new MemoryStream())
                {
                    blob.DownloadToStream(stream);
                    stream.Seek(0, SeekOrigin.Begin);
                    task        = (RenderTask)serializer.Deserialize(stream);
                    task.Status = TaskStatus.Executing;
                    this.UpdateTask(task);
                }

                User user = entityContext.TryGetUser(task.OwnerUid);

                FacebookClient facebook = new FacebookClient(task.FacebookToken);

                // Get template
                Template            template      = entityContext.ListTemplates().First(t => t.TemplateId == task.TemplateId);
                List <TemplateItem> templateItems = template.TemplateItems.OrderBy(t => t.Ordinal).ToList();

                List <TextBubbleDirection> bubbles = entityContext.ListTextBubbles().SelectMany(b => b.TextBubbleDirections).ToList();

                TextBubble speechBubble = entityContext.ListTextBubbles().First(b => b.Title == "speech");
                TextBubble bubbleShout  = entityContext.ListTextBubbles().First(b => b.Title == "shout");
                TextBubble squareBubble = entityContext.ListTextBubbles().First(b => b.Title == "square");

                comic = new Data.Comic();
                entityContext.AddToComics(comic);

                comic.Author      = user;
                comic.Template    = template;
                comic.CreateTime  = DateTime.Now;
                comic.UpdateTime  = DateTime.Now;
                comic.PublishTime = null;
                comic.FeatureTime = null;
                comic.Title       = "";
                comic.Description = "";
                comic.ShareText   = "";
                comic.IsPublished = false;
                comic.IsPrivate   = false;
                comic.IsDeleted   = false;
                comic.Locale      = user.Locale ?? "en-US";
                comic.StorageKey  = Guid.NewGuid().ToString();

                if (task.RemixComicId.HasValue)
                {
                    comic.RemixedComic = entityContext.TryGetComic(task.RemixComicId.Value, user);
                }

                // Comic generator only used to size text
                ComicGenerator generator = new ComicGenerator(template.Width, template.Height);

                // Render effect parameters
                Dictionary <string, object> parameterValues = new Dictionary <string, object>();

                switch (task.Effect)
                {
                case ComicEffectType.ColorSketch:
                case ComicEffectType.PencilSketch:
                    parameterValues.Add("edging", 2);
                    parameterValues.Add("coloring", 35);
                    break;

                case ComicEffectType.Comic:
                default:
                    parameterValues.Add("coloring", 6);
                    break;
                }

                // Get photos for each frame
                for (int f = 0; f < task.Frames.Count && f < templateItems.Count; f++)
                {
                    Photo  photo    = null;
                    Bitmap image    = null;
                    string imageUrl = String.Empty;
                    ComicGenerator.ImageAlign imageAlignment = ComicGenerator.ImageAlign.Center;
                    Point tag          = Point.Empty;
                    bool  tagConfident = false;

                    if (task.PhotoSource == "Internal" && task.Frames[f].PhotoId.HasValue)
                    {
                        // Load image from database
                        photo           = entityContext.TryGetPhoto(task.Frames[f].PhotoId.Value);
                        photo.ImageData = this.GetStoredImage(photo.StorageKey);
                        image           = new Bitmap(new MemoryStream(photo.ImageData));
                    }
                    else
                    {
                        // Tagged facebook photos
                        if (task.PhotoSource == "Tagged")
                        {
                            try
                            {
                                // List photos of the user
                                Dictionary <string, object> args = new Dictionary <string, object>();
                                args.Add("limit", "50");

                                dynamic photoResult = facebook.Get(String.Format("/{0}/photos", task.Frames[f].Id), args);

                                if (photoResult.data.Count > 0)
                                {
                                    // Pick a random photo with 2 or fewer tags
                                    dynamic photoData = ((IList <dynamic>)photoResult.data)
                                                        .OrderBy(p => Guid.NewGuid())
                                                        .FirstOrDefault(p => p.tags.data.Count <= 2);

                                    if (photoData != null)
                                    {
                                        imageUrl = (string)photoData.source;

                                        // Look for user tag location
                                        int     id;
                                        dynamic tagData = ((IList <dynamic>)photoData.tags.data)
                                                          .FirstOrDefault(t => int.TryParse(t.id, out id) && id == task.Frames[f].Id);

                                        if (tagData != null)
                                        {
                                            tag          = new Point((int)Math.Round((double)tagData.x), (int)Math.Round((double)tagData.y));
                                            tagConfident = false;
                                        }
                                    }
                                }
                            }
                            catch (Exception x)
                            {
                                this.Log.Error("Unable to retrieve tagged photo from facebook.", x);
                            }
                        }

                        // Look for any photo of the user
                        else if (task.PhotoSource == "Any")
                        {
                            try
                            {
                                FaceRestAPI         faceApi   = this.CreateFaceApi(task.FacebookToken, user.Uid);
                                List <string>       ids       = new List <string>(new string[] { String.Format("{0}@facebook.com", task.Frames[f].Id) });
                                FaceRestAPI.FaceAPI anyResult = faceApi.facebook_get(ids, null, "1", null, "random");

                                if (anyResult.status == "success" && anyResult.photos.Count > 0)
                                {
                                    FaceRestAPI.Photo p = anyResult.photos[0];
                                    imageUrl     = p.url;
                                    tag          = new Point((int)Math.Round(p.tags.First().mouth_center.x), (int)Math.Round(p.tags.First().mouth_center.y));
                                    tagConfident = true;
                                }
                            }
                            catch (Exception x)
                            {
                                this.Log.Error("Unable to retrieve photo through face.com api.", x);
                            }
                        }

                        // Use profile photo as backup image
                        if (String.IsNullOrEmpty(imageUrl))
                        {
                            imageUrl = String.Format("https://graph.facebook.com/{0}/picture?access_token={1}&type=large", task.Frames[f].Id, facebook.AccessToken);
                        }

                        image = this.GetImage(imageUrl);


                        // Find faces when confidence in tag location is low
                        if (!tagConfident)
                        {
                            try
                            {
                                FaceRestAPI tagApi = this.CreateFaceApi(task.FacebookToken, user.Uid);
                                //List<string> tagIds = new List<string>(new string[] { String.Format("{0}@facebook.com", task.Frames[f].Id) });
                                List <string>       urls      = new List <string>(new string[] { imageUrl });
                                FaceRestAPI.FaceAPI tagResult = tagApi.faces_detect(urls, null, "Normal", null, null);

                                if (tagResult.status == "success" && tagResult.photos.Count > 0 && tagResult.photos[0].tags.Count > 0)
                                {
                                    FaceRestAPI.Tag t = tagResult.photos[0].tags.First();
                                    tag          = new Point((int)Math.Round(t.mouth_center.x), (int)Math.Round(t.mouth_center.y));
                                    tagConfident = true;
                                }
                            }
                            catch (Exception x)
                            {
                                this.Log.Error("Unable to detected faces.", x);
                            }
                        }

                        if (tag != Point.Empty && tag.Y <= image.Height / 3)
                        {
                            imageAlignment = ComicGenerator.ImageAlign.Top;
                        }
                    }

                    // Resize to fit frame
                    image = ComicGenerator.FitImage(new Size(templateItems[f].Width, templateItems[f].Height), image);

                    // Apply render effect
                    if (task.Effect != ComicEffectType.None)
                    {
                        RenderHelper    effectHelper = new RenderHelper(image.Size);
                        ImageRenderData renderResult = effectHelper.RenderEffect(image, task.Effect, parameterValues);
                        image = new Bitmap(renderResult.RenderStream);
                    }

                    // Read raw photo into memory
                    MemoryStream imageStream = new MemoryStream();
                    image.Save(imageStream, System.Drawing.Imaging.ImageFormat.Jpeg);
                    imageStream.Seek(0, SeekOrigin.Begin);


                    // Frame text bubbles
                    if (!String.IsNullOrWhiteSpace(task.Frames[f].Message))
                    {
                        ComicTextBubble comicBubble = new ComicTextBubble();
                        entityContext.AddToComicTextBubbles(comicBubble);
                        comicBubble.Comic = comic;
                        comicBubble.Text  = task.Frames[f].Message;

                        // Remove newlines
                        comicBubble.Text = comicBubble.Text.Replace('\n', ' ');

                        // Font size
                        int fontSize = 7;
                        if (comicBubble.Text.Length > 160)
                        {
                            fontSize = 6;
                        }
                        if (comicBubble.Text.Length > 200)
                        {
                            fontSize = 5;
                        }
                        comicBubble.Font = new Font(ComicGenerator.ComicFont, fontSize, FontStyle.Regular, GraphicsUnit.Point);

                        // Shouting / excited?
                        TextBubble bubble = speechBubble;
                        if (comicBubble.Text.Contains('!') || Regex.Matches(comicBubble.Text, "[A-Z]").Count > comicBubble.Text.Length / 4)
                        {
                            bubble = bubbleShout;
                        }

                        // Calculate tag x/y coords relative to the whole comic
                        if (tag != Point.Empty)
                        {
                            Size      templateSize = new Size(templateItems[f].Width, templateItems[f].Height);
                            Rectangle cropArea     = ComicGenerator.GetCropImageSize(image.Size, templateSize, imageAlignment);
                            tag.X = image.Size.Width * tag.X / 100 - cropArea.X + templateItems[f].X;
                            tag.Y = image.Size.Height * tag.Y / 100 - cropArea.Y + templateItems[f].Y;
                        }

                        // Position text bubble
                        this.PositionFrameBubble(comicBubble, image, generator, bubble, squareBubble, templateItems[f], tag, imageAlignment);

                        // Add photo as template item
                        photo            = new Photo();
                        photo.User       = user;
                        photo.CreateTime = DateTime.Now;
                        photo.ImageData  = imageStream.ToArray();
                        photo.StorageKey = Guid.NewGuid().ToString();
                        photo.Width      = image.Width;
                        photo.Height     = image.Height;
                        entityContext.AddToPhotos(photo);
                    }

                    // Tag users
                    //if (task.Frames[f].Id > 0)
                    //{
                    //    try
                    //    {

                    //        // Lookup existing user
                    //        User taggedUser = entityContext.TryGetUser(task.Frames[f].Id, true);
                    //        if (taggedUser == null)
                    //        {
                    //            // User doesn't exist in the db yet - grab from facebook
                    //            dynamic facebookUser = facebook.Get(String.Format("/{0}", task.Frames[f].Id));
                    //            taggedUser = new User();
                    //            taggedUser.Uid = long.Parse(facebookUser.id);
                    //            taggedUser.IsDeleted = false;
                    //            taggedUser.IsSubscribed = false;
                    //            taggedUser.Locale = facebookUser.locale;
                    //            taggedUser.Name = facebookUser.name;
                    //            taggedUser.Nickname = facebookUser.name;
                    //            taggedUser.FbLink = facebookUser.link;
                    //            entityContext.AddToUsers(taggedUser);
                    //        }

                    //        ComicTag comicTag = new ComicTag();
                    //        comicTag.User = taggedUser;
                    //        comicTag.Comic = comic;
                    //        if (tag != Point.Empty)
                    //        {
                    //            comicTag.X = tag.X;
                    //            comicTag.Y = tag.Y;
                    //        }
                    //    }
                    //    catch (Exception x)
                    //    {
                    //        this.Log.ErrorFormat("Failed to tag user {0} in comic. {1}", task.Frames[f].Id, x.ToString());
                    //    }
                    //}


                    ComicPhoto comicPhoto = new ComicPhoto();
                    comicPhoto.Comic        = comic;
                    comicPhoto.Photo        = photo;
                    comicPhoto.TemplateItem = templateItems[f];
                    comicPhoto.Alignment    = imageAlignment;
                    comic.ComicPhotos.Add(comicPhoto);

                    // Update task progress
                    task.CompletedOperations++;
                    this.UpdateTask(task);
                }

                for (int b = 0; task.Bubbles != null && b < task.Bubbles.Count; b++)
                {
                    ComicTextBubble comicBubble = new ComicTextBubble();
                    entityContext.AddToComicTextBubbles(comicBubble);
                    comicBubble.Comic = comic;
                    comicBubble.Text  = task.Bubbles[b].Text;
                    comicBubble.Font  = new Font(ComicGenerator.ComicFont, 7, FontStyle.Regular, GraphicsUnit.Point);
                    comicBubble.TextBubbleDirection = bubbles.First(d => d.TextBubbleDirectionId == task.Bubbles[b].TextBubbleDirectionId);
                    comicBubble.Position            = new Rectangle(new Point(task.Bubbles[b].X, task.Bubbles[b].Y), generator.MeasureText(comicBubble.Text, comicBubble.Font).ToSize());
                }

                // Fix for position to x,y coordinates
                foreach (ComicTextBubble b in comic.ComicTextBubbles)
                {
                    b.X = b.Position.X;
                    b.Y = b.Position.Y;
                }

                this.SaveComic(comic, entityContext);

                task.CompletedOperations = task.TotalOperations;
                task.Status  = TaskStatus.Complete;
                task.ComicId = comic.ComicId;
                this.UpdateTask(task);
                this.Log.DebugFormat("Completed render task {0}", task.TaskId);
            }
            catch (Exception x)
            {
                this.Log.Error("Unable to complete render task.", x);

                if (task != null)
                {
                    task.Status = TaskStatus.Failed;
                    this.UpdateTask(task);
                }

                if (comic != null)
                {
                    this.Log.DebugFormat("Text bubble info [{0}] [{1}]",
                                         String.Join(",", comic.ComicTextBubbles.Select(b => b.ComicTextBubbleId.ToString()).ToArray()),
                                         String.Join(",", comic.ComicTextBubbles.Select(b => b.TextBubbleDirectionId.ToString()).ToArray()));
                }
            }
        }
示例#8
0
 public ClientComic(Data.Comic source, ComicStat.ComicStatPeriod statsPeriod)
 {
     this.Init(source, statsPeriod);
 }
示例#9
0
 public ClientComic(Data.Comic source)
 {
     this.Init(source, ComicStat.ComicStatPeriod.AllTime);
 }
示例#10
0
        public JsonResult Publish(long comicId, string title, string description, bool isPrivate)
        {
            Data.Comic  comic = null;
            ClientComic c     = null;

            try
            {
                this.EntityContext.TryAttach(this.ActiveUser);

                comic = this.EntityContext.TryGetUnpublishedComic(comicId, this.ActiveUser);
                if (comic == null || comic.Uid != this.ActiveUser.Uid)
                {
                    throw new Exception("Could not find the requested comic.");
                }

                comic.Title       = title;
                comic.Description = description;
                comic.IsPrivate   = isPrivate;

                // Get bytecode from storage
                CloudBlobContainer container = this.BlobClient.GetContainerReference(ComicConfigSectionGroup.Blob.RenderContainer);
                CloudBlobDirectory directory = container.GetDirectoryReference(ComicConfigSectionGroup.Blob.ComicDirectory);
                CloudBlob          blob      = directory.GetBlobReference(comic.StorageKey);

                ClientComic clientComic = new ClientComic(comic);

                // Publish to facebook album for better visibility
                MemoryStream photoStream = new MemoryStream();
                try
                {
                    blob.DownloadToStream(photoStream);

                    FacebookMediaObject fbMedia = new FacebookMediaObject
                    {
                        ContentType = "image/jpeg",
                        FileName    = String.Format("{0}.jpg", comic.StorageKey)
                    };
                    fbMedia.SetValue(photoStream.ToArray());

                    Dictionary <string, object> photoParams = new Dictionary <string, object>();
                    photoParams.Add("message", String.Format("{0} - Remix this comic at {1}", comic.Description, clientComic.RemixUrl));
                    photoParams.Add("source", fbMedia);
                    this.Facebook.Post("/me/photos", photoParams);
                }
                catch (Exception x)
                {
                    this.Log.Error("Unable to publish comic to facebook album.", x);
                }
                finally
                {
                    photoStream.Dispose();
                }

                this.EntityContext.PublishComic(comic, this.ActiveUser);
                c = new ClientComic(comic);
                this.EntityContext.SaveChanges();


                // Email notifications
                UserEngage engage = this.GetUserEngage(this.ActiveUser);

                if (!engage.Unsubscribe && engage.ComicCreate)
                {
                    // create & save history
                    UserEngageHistory history = new UserEngageHistory();
                    history.Engagement = UserEngageHistory.EngagementType.ComicCreate;
                    history.EngageTime = DateTime.Now;
                    history.User       = this.ActiveUser;
                    this.EntityContext.AddToUserEngageHistory(history);
                    this.EntityContext.SaveChanges();

                    // Generate email message
                    EmailManager email = new EmailManager(this.Server);
                    Dictionary <string, string> data = new Dictionary <string, string>();
                    data.Add("id", history.EngageHistoryId.ToString());
                    data.Add("title", String.Format("New Comic - {0}", comic.Title));
                    data.Add("comic.title", c.Title);
                    data.Add("comic.readUrl", c.ReadUrl);

                    // Send email
                    email.SendEmail(this.ActiveUser, "ComicCreate.html", data);
                }

                // Check for notifications of a remixed comic
                if (comic.RemixedComic != null)
                {
                    engage = this.EntityContext.TryGetUserEngage(comic.RemixedComic.Author);
                    ClientComic remixed = new ClientComic(comic.RemixedComic);

                    if (!engage.Unsubscribe && engage.ComicRemix)
                    {
                        UserEngageHistory history = new UserEngageHistory();
                        history.Engagement = UserEngageHistory.EngagementType.ComicRemix;
                        history.EngageTime = DateTime.Now;
                        history.User       = comic.RemixedComic.Author;
                        this.EntityContext.AddToUserEngageHistory(history);
                        this.EntityContext.SaveChanges();

                        // Generate email message
                        EmailManager email = new EmailManager(this.Server);
                        Dictionary <string, string> data = new Dictionary <string, string>();
                        data.Add("id", history.EngageHistoryId.ToString());
                        data.Add("title", String.Format("Remixed Comic - {0}", comic.Title));
                        data.Add("comic.title", c.Title);
                        data.Add("comic.readUrl", c.ReadUrl);
                        data.Add("remix.title", remixed.Title);
                        data.Add("remix.readUrl", remixed.ReadUrl);

                        // Send email
                        email.SendEmail(comic.RemixedComic.Author, "ComicRemix.html", data);
                    }
                }
            }
            finally
            {
                this.EntityContext.TryDetach(this.ActiveUser);
            }

            return(this.Json(c, JsonRequestBehavior.DenyGet));
        }
示例#11
0
        public ActionResult Read(long comicId, string title)
        {
            ActionResult result;

            try
            {
                Data.Comic comic = null;

                //// Facebook shared comics
                //if (this.ActiveUser == null && this.HttpContext.Request.UrlReferrer != null && this.HttpContext.Request.UrlReferrer.Host.Contains("facebook.com"))
                //{
                //    comic = this.EntityContext.TryGetComic(comicId, null, true);
                //    if (comic != null)
                //    {
                //        this.LoginGuestUser(comic.Author);
                //    }
                //}
                //// Guest user logged in
                //else if (this.GuestUser != null)
                //{
                //    comic = this.EntityContext.TryGetComic(comicId, this.GuestUser);
                //}
                //else
                //{
                //    // All other entry points
                //    this.EntityContext.TryAttach(this.ActiveUser);
                //    comic = this.EntityContext.TryGetComic(comicId, this.ActiveUser, this.Friends);
                //}

                // Asume that if the user found the comic, they are allowed to read it (hard to track shares and whatnot)
                comic = this.EntityContext.TryGetComic(comicId);

                if (comic == null)
                {
                    result = this.View("ReadNotFound");
                }
                else
                {
                    // Track read
                    this.EntityContext.TryAttach(this.ActiveUser);
                    ComicRead read = this.EntityContext.TryGetComicRead(comic, this.ActiveUser);
                    try                     // Having an entity issue.. trying to track it down with this.
                    {
                        if (read == null)
                        {
                            read          = new ComicRead();
                            read.Comic    = comic;
                            read.Reader   = this.ActiveUser;
                            read.ReadTime = DateTime.Now;

                            if (this.ActiveUser != null)
                            {
                                this.EntityContext.AddToComicRead(read);
                                this.EntityContext.SaveChanges();
                            }
                        }
                    }
                    catch (Exception x)
                    {
                        this.Log.Error("Reader error", x);
                    }
                    finally
                    {
                        this.EntityContext.TryDetach(this.ActiveUser);
                    }

                    // Load tags
                    comic.ComicTags.Load();
                    List <ClientComicTag> tags = comic.ComicTags.Select(t => new ClientComicTag(t)).ToList();

                    result = (ActionResult)this.View(new ViewRead(new ClientComic(comic), new ClientComicRead(read), tags));
                }
            }
            finally
            {
                this.EntityContext.TryDetach(this.ActiveUser);
            }

            return(result);
        }
示例#12
0
        public ViewResult Create(long?id)
        {
            ClientComic comic = null;

            List <ClientTemplate> templates = this.EntityContext.ListTemplates()
                                              .ToList()
                                              .Select(t => new ClientTemplate(t))
                                              .ToList();

            foreach (ClientTemplate t in templates)
            {
                int    width  = Math.Min(t.Width, 734);
                double factor = Convert.ToDouble(width) / Convert.ToDouble(t.Width);
                t.Width  = width;
                t.Height = Convert.ToInt32(Convert.ToDouble(t.Height) * factor);
                foreach (ClientTemplateItem i in t.TemplateItems)
                {
                    i.Width  = Convert.ToInt32(Convert.ToDouble(i.Width) * factor);
                    i.Height = Convert.ToInt32(Convert.ToDouble(i.Height) * factor);
                    i.X      = Convert.ToInt32(Convert.ToDouble(i.X) * factor);
                    i.Y      = Convert.ToInt32(Convert.ToDouble(i.Y) * factor);
                }
            }

            if (id.HasValue)
            {
                // Facebook shared comics
                Data.Comic c = this.EntityContext.TryGetComic(id.Value, this.ActiveUser) ?? this.EntityContext.TryGetUnpublishedComic(id.Value, this.ActiveUser);

                if (c != null)
                {
                    c.ComicTextBubbles.Load();
                    c.ComicPhotos.Load();
                    comic = new ClientComic(c);

                    // inject newlines into text
                    int            maxWidth    = templates.SelectMany(t => t.TemplateItems).Select(t => t.Width).Min();
                    Font           measureFont = new Font(ComicGenerator.ComicFont, 7, FontStyle.Regular, GraphicsUnit.Point);
                    ComicGenerator generator   = new ComicGenerator(templates.Min(t => t.Width), templates.Min(t => t.Height));
                    foreach (ComicTextBubble bubble in c.ComicTextBubbles)
                    {
                        Size rawTextSize = generator.MeasureText(bubble.Text, maxWidth, measureFont).ToSize();
                        Size textSize    = this.CalculateTextSize(bubble.Text, rawTextSize, bubble.TextBubbleDirection.TextBubble);
                        textSize.Width  = Math.Min(textSize.Width, maxWidth); // Don't exceede template item area
                        textSize        = generator.MeasureText(bubble.Text, textSize.Width, measureFont).ToSize();
                        textSize.Width += 6;                                  // Measure error ?

                        int lines    = textSize.Height / measureFont.Height;
                        int cutWidth = (bubble.Text.Length / lines) - 4;
                        for (int l = 1; l < lines; l++)
                        {
                            int cut   = cutWidth * l;
                            int space = bubble.Text.IndexOf(' ', cut);
                            if (space > 0)
                            {
                                bubble.Text = bubble.Text.ReplaceAt(space, '\n');
                            }
                        }
                        comic.Bubbles.First(b => b.ComicTextBubbleId == bubble.ComicTextBubbleId).Text = bubble.Text;
                    }
                }
            }


            List <ClientTextBubbleDirection> bubbles = this.EntityContext.ListTextBubbles()
                                                       .SelectMany(b => b.TextBubbleDirections)
                                                       .ToList()
                                                       .Select(d => new ClientTextBubbleDirection(d))
                                                       .ToList();

            return(this.View(new ViewCreate(comic, templates, this.GetEffects(), bubbles)));
        }