Mercurial Hosting > nabble
view src/nabble/modules/ad/Ad.java @ 0:7ecd1a4ef557
add content
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 21 Mar 2019 19:15:52 -0600 |
parents | |
children |
line wrap: on
line source
package nabble.modules.ad; import fschmidt.db.DbDatabase; import fschmidt.db.DbExpression; import fschmidt.db.DbNull; import fschmidt.db.DbRecord; import fschmidt.db.NoKey; import nabble.model.Db; import nabble.model.ExtensionFactory; import nabble.model.ModelHome; import nabble.model.Site; import nabble.model.ViewCount; import nabble.naml.compiler.Template; import nabble.naml.compiler.TemplatePrintWriter; import nabble.naml.namespaces.BasicNamespace; import nabble.view.web.template.NabbleNamespace; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collections; import java.util.Date; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; public final class Ad { private static final Logger logger = LoggerFactory.getLogger(Ad.class); private static final String AD_MODULE_TASK = "ad_free"; private static final ExtensionFactory<Site,Ad> FACTORY = new ExtensionFactory<Site,Ad>() { private final Set<Long> adFreeSites = Collections.newSetFromMap(new ConcurrentHashMap<Long,Boolean>()); public String getName() { return AdModule.INSTANCE.getName(); } public Class<Ad> extensionClass() { return Ad.class; } public Ad construct(Site site) { return null; } public Ad construct(Site site,ResultSet rs) throws SQLException { boolean isSafe = rs.getBoolean("is_safe"); int credits = rs.getInt("ad_free"); if( credits > 0 && adFreeSites.add(site.getId()) ) site.addTask(AD_MODULE_TASK); boolean isCreditsForUsersOnly = rs.getBoolean("ad_credits_for_users"); return new Ad(site,isSafe,credits,isCreditsForUsersOnly); } public Serializable getExportData(Site site) { throw new UnsupportedOperationException(); } public void saveExportData(Site site,Serializable s) { throw new UnsupportedOperationException(); } }; static { ModelHome.addSiteExtensionFactory(FACTORY); ViewCount.addCalculateActivityListener(new Runnable(){public void run(){ try { for( Site site : ModelHome.getSitesForTask(AD_MODULE_TASK) ) { Ad ad = Ad.of(site); int views; { Connection con = Db.dbGlobal().getConnection(); String field = ad.isCreditsForUsersOnly ? "user_views" : "views"; PreparedStatement stmt = con.prepareStatement( "select " + field + " from site_global where site_id = ?" ); stmt.setLong(1,site.getId()); ResultSet rs = stmt.executeQuery(); rs.next(); views = rs.getInt(field); rs.close(); stmt.close(); con.close(); if( views > 0 && !ad.wasCreatedRecently() ) { ad.decCredits(views); } else { site.addTask(AD_MODULE_TASK); } } if( ad.getCredits() > 0 ) { Connection con = site.getDb().getConnection(); PreparedStatement stmt = con.prepareStatement( "update site set monthly_views = monthly_views*29/30 + ?" ); stmt.setInt(1,views); stmt.executeUpdate(); stmt.close(); con.close(); } } } catch(SQLException e) { logger.error("",e); throw new RuntimeException(e); } }}); } static void init() {} public static Ad of(Site site) { return site.getExtension(FACTORY); } private final Site site; private boolean isSafe; private int credits = 0; private boolean isCreditsForUsersOnly; Ad(Site site,boolean isSafe,int credits,boolean isCreditsForUsersOnly) { this.site = site; this.isSafe = isSafe; this.credits = credits; this.isCreditsForUsersOnly = isCreditsForUsersOnly; } public boolean isSafe() { return isSafe; } public void setSafe(boolean isSafe) { DbRecord<NoKey,?> record = site.getDbRecord(); this.isSafe = isSafe; record.fields().put( "is_safe", isSafe ); // if( !isSafe ) { // record.fields().put( "when_created", DbExpression.NOW ); // record.fields().put( "ad_credits_for_users", false ); // } if (!site.getDb().isInTransaction()) { record.update(); } } public int getCredits() { return credits; } public void setCredits(int credits) { if( credits < 0 ) credits = 0; DbRecord<NoKey,?> record = site.getDbRecord(); this.credits = credits; record.fields().put( "ad_free", DbNull.fix(credits) ); DbDatabase db = site.getDb(); if( !db.isInTransaction() ) record.update(); if( credits > 0 ) site.addTask(AD_MODULE_TASK); } public void incCredits(int n) { setCredits(this.credits + n); } private void decCredits(int n) { setCredits(this.credits - n); // notify user? // I'm supposing that everyday we will deduct n credits, so he has one more day to buy new ones // I test if he has more than 0 credits to avoid send emails to everyone that doesn't have or buy credits if( this.credits < n && this.credits > 0) { // condition here Template template = site.getTemplate( "ad_notice", BasicNamespace.class, NabbleNamespace.class ); template.run( TemplatePrintWriter.NULL, Collections.<String,Object>emptyMap(), new BasicNamespace(template), new NabbleNamespace(site) ); } } public boolean isPaid() { return false; } public boolean isCreditsForUsersOnly() { return isCreditsForUsersOnly; } private static long ONE_DAY = 24 * 60 * 60 * 1000L; // 1 day private static long LIMIT_DAYS = 6 * 30 * ONE_DAY; // 6 months boolean wasCreatedRecently() { long whenCreated = site.getWhenCreated().getTime(); long now = new Date().getTime(); return now < whenCreated + LIMIT_DAYS; } long lastDayWithoutAds() { return site.getWhenCreated().getTime() + LIMIT_DAYS; } }