comparison src/nabble/model/SiteGlobal.java @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children c4ed473452d4
comparison
equal deleted inserted replaced
-1:000000000000 0:7ecd1a4ef557
1 package nabble.model;
2
3 import fschmidt.db.DbDatabase;
4 import fschmidt.db.DbNull;
5 import fschmidt.db.DbObject;
6 import fschmidt.db.DbObjectFactory;
7 import fschmidt.db.DbRecord;
8 import fschmidt.db.DbTable;
9 import fschmidt.db.Listener;
10 import fschmidt.db.LongKey;
11 import fschmidt.util.java.DateUtils;
12 import fschmidt.util.java.ObjectUtils;
13 import nabble.view.lib.Jtp;
14 import nabble.view.lib.SiteDeleteMail;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17
18 import java.sql.Connection;
19 import java.sql.PreparedStatement;
20 import java.sql.ResultSet;
21 import java.sql.SQLException;
22 import java.sql.Statement;
23 import java.util.ArrayList;
24 import java.util.Date;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.WeakHashMap;
28
29
30 final class SiteGlobal implements DbObject<LongKey,SiteGlobal> {
31 private static final Logger logger = LoggerFactory.getLogger(SiteGlobal.class);
32
33 final SiteKey siteKey;
34 private final DbRecord<LongKey,SiteGlobal> record;
35 private String customDomain;
36 private Date deleteDate;
37 private int activity;
38 private boolean isEmbarrassing = false;
39 private String remoteAddr = null; // IP of the user who created the site
40 private String baseUrl;
41
42 SiteGlobal() {
43 record = table.newRecord(this);
44 record.insert();
45 this.siteKey = SiteKey.getInstance(getId());
46 }
47
48 SiteGlobal(long siteId) {
49 record = table.newRecord(this);
50 record.fields().put("site_id", siteId );
51 record.insert();
52 this.siteKey = SiteKey.getInstance(getId());
53 }
54
55 private SiteGlobal(LongKey key,ResultSet rs)
56 throws SQLException
57 {
58 record = table.newRecord(this,key);
59 this.siteKey = SiteKey.getInstance(getId());
60 customDomain = rs.getString("custom_domain");
61 if( customDomain != null )
62 customDomain = customDomain.intern();
63 deleteDate = rs.getDate("delete_date");
64 activity = rs.getInt("activity");
65 isEmbarrassing = rs.getBoolean("is_embarrassing");
66 remoteAddr = rs.getString("remote_addr");
67 }
68
69 public DbRecord<LongKey,SiteGlobal> getDbRecord() {
70 return record;
71 }
72
73 public long getId() {
74 return record.getPrimaryKey().value();
75 }
76
77 private DbTable<LongKey,SiteGlobal> table() {
78 return record.getDbTable();
79 }
80
81 private DbDatabase db() {
82 return table().getDbDatabase();
83 }
84
85 SiteImpl site() {
86 return siteKey.site();
87 }
88
89 static DbTable<LongKey,SiteGlobal> table = Db.dbGlobal().newTable(
90 "site_global",
91 Db.dbGlobal().newIdentityLongKeySetter("site_id"),
92 new DbObjectFactory<LongKey, SiteGlobal>() {
93 public SiteGlobal makeDbObject(LongKey key,ResultSet rs,String tableName)
94 throws SQLException
95 {
96 return new SiteGlobal(key,rs);
97 }
98 }
99 );
100 static {
101 table.getPostUpdateListeners().add(new Listener<SiteGlobal>() {
102 public void event(SiteGlobal siteGlobal) {
103 SiteImpl.postUpdateListeners.event(siteGlobal.site());
104 }
105 } );
106 /*
107 // for debugging
108 table.getPreDeleteListeners().add(new Listener<SiteGlobal>() {
109 public void event(SiteGlobal siteGlobal) {
110 logger.error("deleting "+siteGlobal,new Exception());
111 }
112 } );
113 */
114 }
115
116 static SiteGlobal getSiteGlobal(long siteId) {
117 return table.findByPrimaryKey(new LongKey(siteId));
118 }
119
120 static SiteGlobal getSiteGlobal(ResultSet rs)
121 throws SQLException
122 {
123 return table.getDbObject(rs);
124 }
125
126 public void setCustomDomain(String customDomain) {
127 if( customDomain != null )
128 customDomain = customDomain.toLowerCase();
129 this.customDomain = customDomain;
130 record.fields().put("custom_domain", DbNull.fix(customDomain) );
131 if( !db().isInTransaction() )
132 record.update();
133 // calcBaseUrl();
134 }
135
136 public String getCustomDomain() {
137 return customDomain;
138 }
139
140 public String getBaseUrl() {
141 if( baseUrl == null ) {
142 baseUrl = "http://" +
143 (customDomain != null ? customDomain : Jtp.getDefaultBaseUrl(siteKey.site()));
144 }
145 return baseUrl;
146 }
147 /*
148 void calcBaseUrl() {
149 baseUrl = "http://" +
150 (customDomain != null ? customDomain : Jtp.getDefaultBaseUrl(siteKey.site()));
151 }
152 */
153
154
155 private static final Map<String,Long> domainMap = new WeakHashMap<String,Long>();
156
157 static Long getSiteIdFromDomain(String customDomain) {
158 Long siteId;
159 synchronized(domainMap) {
160 siteId = domainMap.get(customDomain);
161 if( siteId == null ) {
162 try {
163 Connection con = Db.dbGlobal().getConnection();
164 try {
165 PreparedStatement stmt = con.prepareStatement(
166 "select site_id from site_global where custom_domain = ?"
167 );
168 stmt.setString(1,customDomain);
169 ResultSet rs = stmt.executeQuery();
170 try {
171 if( !rs.next() )
172 return null;
173 siteId = rs.getLong("site_id");
174 } finally {
175 rs.close();
176 stmt.close();
177 }
178 } finally {
179 con.close();
180 }
181 } catch(SQLException e) {
182 throw new RuntimeException(e);
183 }
184 domainMap.put( customDomain.intern(), siteId );
185 }
186 }
187 return siteId;
188 }
189
190
191
192
193 public int getActivity() {
194 return activity;
195 }
196
197 void setActivity(int activity) {
198 this.activity = activity;
199 record.fields().put( "activity", activity );
200 if( !db().isInTransaction() )
201 record.update();
202 }
203
204
205 public Date getDeleteDate() {
206 return deleteDate;
207 }
208
209 private void setDeleteDate(Date deleteDate) {
210 if( deleteDate==null )
211 throw new NullPointerException();
212 this.deleteDate = deleteDate;
213 record.fields().put("delete_date",deleteDate);
214 record.update();
215 }
216
217 public void clearDeleteDate() {
218 record.fields().put("delete_date",DbNull.TIMESTAMP);
219 record.fields().put("activity",ViewCount.initialActivity);
220 record.update();
221 }
222
223 private static final boolean deleteInactiveSites = Init.hasDaemons && Init.get("deleteInactiveSites",false);
224 private static final int daysToDeletion = Init.get("daysToDeletion",30);
225
226 private static void deleteInactiveSites() {
227 logger.error("Starting deleteInactiveSites");
228 List<SiteGlobal> sitesToDelete = new ArrayList<SiteGlobal>();
229 try {
230 Date deletionDate = DateUtils.addDays(new Date(),daysToDeletion);
231 Connection con = Db.dbGlobal().getConnection();
232 try {
233 {
234 Statement stmt = con.createStatement();
235 ResultSet rs = stmt.executeQuery(
236 "select * from site_global"
237 +" where delete_date is null and activity=0"
238 );
239 int count = 0;
240 while( rs.next() ) {
241 SiteGlobal siteGlobal = SiteGlobal.getSiteGlobal(rs);
242 try {
243 SiteImpl site = siteGlobal.site();
244 siteGlobal.setDeleteDate(deletionDate);
245 count++;
246 for( UserImpl user : site.getPosters() ) {
247 if( !user.isRegistered() )
248 continue;
249 // Send an email if site has more than one node
250 if (site.getRootNode().getDescendantCount() > 1) {
251 SiteDeleteMail.send(user,site,daysToDeletion);
252 logger.info("Site deletion email sent to " + user.getEmail() + " for " + site);
253 } else
254 logger.info("Site scheduled for deletion: " + site);
255 }
256 } catch(UpdatingException e) {
257 logger.error("Couldn't schedule for deletion: " + e);
258 }
259 if( Executors.isShuttingDown() )
260 return;
261 }
262 rs.close();
263 stmt.close();
264 logger.error("Sites scheduled for deletion = " + count);
265 }
266 {
267 Statement stmt = con.createStatement();
268 ResultSet rs = stmt.executeQuery(
269 "select * from site_global"
270 +" where delete_date < now()"
271 );
272 while( rs.next() ) {
273 SiteGlobal siteGlobal = SiteGlobal.getSiteGlobal(rs);
274 sitesToDelete.add(siteGlobal);
275 }
276 rs.close();
277 stmt.close();
278 }
279 } finally {
280 con.close();
281 }
282 } catch(SQLException e) {
283 throw new RuntimeException(e);
284 }
285 for( SiteGlobal siteGlobal : sitesToDelete ) {
286 try {
287 Site site = siteGlobal.site();
288 logger.error("Deleting inactive site ID=" + site.getId() + " (" + site.getRootNode().getSubject() + " / " + site.getRootNode().getDescendantCount() + " nodes)");
289 site.delete();
290 } catch(UpdatingException e) {
291 logger.error("Couldn't delete inactive site: " + e);
292 } catch(RuntimeException e) {
293 logger.error("couldn't delete inactive site "+siteGlobal,e);
294 }
295 }
296 logger.error("Finished deleteInactiveSites");
297 }
298
299 static {
300 if( deleteInactiveSites ) {
301 Executors.runDaily(new Runnable(){public void run(){
302 deleteInactiveSites();
303 }});
304 }
305 }
306
307
308 public boolean isEmbarrassing() {
309 return isEmbarrassing;
310 }
311
312 public void setEmbarrassing(boolean isEmbarrassing) {
313 this.isEmbarrassing = isEmbarrassing;
314 record.fields().put( "is_embarrassing", DbNull.fix(isEmbarrassing) );
315 if( !db().isInTransaction() )
316 record.update();
317 }
318
319 public String toString() {
320 return "siteGlobal-"+getId();
321 }
322
323 @Override public boolean equals(Object obj) {
324 return this==obj || obj instanceof SiteGlobal && record.isInDb() && ((SiteGlobal)obj).getId()==getId();
325 }
326
327 @Override public int hashCode() {
328 return (int)getId();
329 }
330
331
332 boolean setRemoteAddr(String remoteAddr) {
333 this.remoteAddr = remoteAddr;
334 record.fields().put( "remote_addr", DbNull.fix(remoteAddr) );
335 record.update();
336 return true;
337 }
338
339 }