1 package Newslash::Web::Controller::API::Story;
2 use Mojo::Base 'Mojolicious::Controller';
3 use Mojo::Util qw(dumper);
4 use Mojo::JSON qw(decode_json encode_json);
6 use DateTime::Format::ISO8601;
7 use DateTime::Format::MySQL;
10 sub _submission_to_story {
11 my ($c, $submission) = @_;
13 for my $k (qw{title tags}) {
14 $story->{$k} = $submission->{$k};
17 $story->{intro_text} = $c->tt2renderer->render("system/submission/submission_formatter", $submission);
18 $story->{submitter} = $submission->{uid};
22 sub _journal_to_story {
23 my ($c, $journal) = @_;
25 for my $k (qw{title tags}) {
26 $story->{$k} = $journal->{$k};
28 $story->{intro_text} = $c->tt2renderer->render('system/subsmission/journal2submission',
29 { text => $journal->{full_text},
30 author => $journal->{author},
32 if (!$story->{intro_text}) {
33 $story->{intro_text} = $journal->{full_text};
35 $story->{submitter} = $journal->{uid};
41 my $sid = $c->param('sid');
42 my $stoid = $c->param('stoid');
43 my $subid = $c->param('subid') || $c->param('submission_id');
44 my $journal_id = $c->param('journal_id');
45 my $stories = $c->model('stories');
47 my $user = $c->stash('user');
50 $story = $stories->select(story_id => $stoid,
51 hide_future => !$user->{is_admin},
52 public_only => !$user->{is_admin},
56 $story = $stories->select(sid => $sid,
57 hide_future => !$user->{is_admin},
58 public_only => !$user->{is_admin},
62 my $item = $c->model('submissions')->select(subid => $subid);
64 $story = $c->_submission_to_story($item);
68 my $item = $c->model('journals')->select(id => $journal_id);
70 $story = $c->_journal_to_story($item);
74 $c->render(json => { error => 1, message => "invalid_request" });
80 $c->render(json => { error => 1, message => "not_found" });
84 my $related = $stories->get_related_items(stoid => $story->{stoid});
85 $story->{related} = $related;
86 $c->render(json => { item => $story });
93 my $user = $c->stash('user');
94 my $stories = $c->model('stories');
95 my $users = $c->model('users');
96 my $topics = $c->model('topics');
97 my $submissions = $c->model('submissions');
99 my $data = $c->req->json;
100 my $item = $data->{item};
103 if (!$user->{is_admin} && !$user->{editor}) {
104 $c->render(json => { err => 1, message => "no_permission" });
109 # client send data like this:
110 # {"item":{"title":"ほげ","introtext":"ほんぶん","bodytext":"","createtime":"2017-06-30T21:50:04","author":"hylom","dept":"テスト","commentstatus":"enabled","submissioncopy":0,"url":"","email":"","tags_string":"news","related_urls":"http://sdtest.osdn.co.jp:3000/story/16/01/28/0610215/"},"action":"preview"}
112 $params->{title} = $c->format_htmltext($item->{title}, "title");
113 $message = "no_title" if !$params->{title};
116 my $dt = DateTime::Format::ISO8601->parse_datetime($item->{createtime} || $item->{create_time});
118 $message = "invalid_createtime";
121 # convert localtime to GMT
122 if ($user && $user->{config}->{ui}->{offset_sec}) {
123 my $offset_sec = $user->{config}->{ui}->{offset_sec} || 0;
125 $dt->subtract(seconds => $offset_sec);
128 $params->{time} = DateTime::Format::MySQL->format_datetime($dt);
131 # check: is author valid ?
132 my $author = $users->select(nickname => $item->{author});
133 if (!defined $author || !$author->{is_admin}) {
134 $message = "invalid_author";
136 $params->{uid} = $author->{uid};
138 # check: dept exists ?
139 $params->{dept} = $item->{dept};
140 if (!$params->{dept}) {
141 $message = "department_not_given";
144 # check: introtext exists ?
145 my $intro_text = $item->{intro_text} || $item->{introtext} || "";
146 $params->{introtext} = $c->format_htmltext($intro_text, "story");
147 $params->{intro_text} = $params->{introtext};
148 if (!$params->{introtext}) {
149 $message = "introtext_not_given";
152 # bodytext (omittable)
153 my $body_text = $item->{body_text} || $item->{bodytext} || "";
154 $params->{bodytext} = $c->format_htmltext($body_text, "story");
157 my $related_string = $item->{add_related} || $item->{related_urls} || "";
158 my @relateds = split(/\s+/, $related_string);
159 my $related_sids = [];
160 for my $related (@relateds) {
161 if ($related =~ m|^.*(\d\d/\d\d/\d\d/\d+)/?|) {
162 push @$related_sids, $1;
165 $params->{add_related} = $related_sids;
168 # tags_strings is like: "mainpage japan business transport"
169 my @tags = split(/\s+/, $item->{tags_string} || "");
170 $params->{add_tags} = \@tags;
173 my $primary_topic = $topics->get_primary_topic_from_tags(\@tags);
174 if ($primary_topic) {
175 $params->{topics_chosen} = { $primary_topic->{tid} => 10 };
178 $params->{topics_chosen} = { 49 => 10, }; # tid => weight
181 # TODO: media related
186 if ($item->{source_id}) {
187 if ($item->{source_type} eq "submission") {
188 $params->{submission_id} = $item->{source_id};
190 elsif ($item->{source_type} eq "journal") {
191 $params->{journal_id} = $item->{source_id};
195 $params->{commentstatus} = $item->{commentstatus} || $item->{comment_status} || "enabled";
196 if (!$item->{display}) {
197 $params->{neverdisplay} = 1;
200 $params->{action} = $data->{action} || 'preview';
202 if (length($message) > 0) {
203 $c->render(json => { err => 1, message => $message });
208 if ($data->{action} eq 'preview') {
209 $c->render(json => {item => $params});
214 if ($params->{action} ne 'post') {
215 $c->render(json => { err => 1, message => "invalid_action" });
222 if ($item->{stoid} || $item->{id}) {
224 $params->{stoid} = $item->{stoid} || $item->{id};
225 ($sid, $stoid) = $stories->update(user => $user, %$params);
229 ($sid, $stoid) = $stories->create(user => $user, %$params);
230 #$stoid = $stories->create2(user => $user,
231 # config => $c->config->{Story},
232 # params => $params);
237 if ($stories->last_errorno && $stories->last_errorno == 1062) { #ER_DUP_ENTRY
238 $c->render(json => { error => 1, message => "duplicated_entry" });
242 $c->render(json => { error => 1, message => $stories->last_error });
247 # post succeeded, return result
248 $c->render(json => {type => "story", id => $stoid, sid => $sid, url_id => $sid});
249 $c->event_que->emit("story", "post", $user->{uid}, $stoid);
250 $c->stats->add_event_counter("story_create");