class CategorySubject(Ordered): name = models.CharField(max_length=255, verbose_name=_('name')) sub_title = models.CharField(max_length=255, null=True, blank=True, verbose_name=_('sub title')) clicks_count = models.IntegerField(default=0, verbose_name=_('clicks')) description = models.TextField(max_length=4096, verbose_name=_('description')) pub_date = models.DateTimeField(verbose_name=_('publish date')) icon_url = models.URLField(verify_exists=False, max_length=255, null=True, blank=True, verbose_name=_('icon URL'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 68x68')) icon_path = models.ImageField(storage=LocalFileSystemStorage(), upload_to='static/images/', verbose_name=_('icon path'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 68x68')) large_icon_url = models.URLField(verify_exists=False, max_length=255, null=True, blank=True, verbose_name=_('large icon URL'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 480x200')) large_icon_path = models.ImageField(storage=LocalFileSystemStorage(), upload_to='static/zimages/', max_length=255, verbose_name=_('large icon path'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 480x200'), null=True, blank=True) subject_tml = models.IntegerField(choices=SUBJECT_TML.to_choices(), verbose_name=_('subject template'), \ help_text=_('Please select client subject display template'), default=SUBJECT_TML.NOT_SET, blank=True) objects = CustomManager() def __unicode__(self): return self.name def save(self): if self.icon_path: self.icon_path.name = smart_str(self.icon_path.name) super(CategorySubject, self).save() SubjectItem.objects.filter(subject__id=self.pk).update(sync_status=0) class Meta: app_label = 'app' verbose_name = _('Category Subject') verbose_name_plural = _('Category Subjects')
class LocalEntry(Ordered): name = models.CharField(max_length=255, verbose_name=_('title')) icon_path = models.ImageField(storage=LocalFileSystemStorage(), upload_to='static/images/', verbose_name=_('icon path'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 120x60')) action = models.CharField(max_length=64, verbose_name=_('action'), choices=LOCAL_ENTRY_ACTION.to_choices()) value = models.CharField(max_length=256, verbose_name=_('value')) parameter = models.CharField(max_length=64, verbose_name=_('parameter'), choices=LOCAL_ENTRY_PARAMETER.to_choices()) condition = models.CharField(max_length=128, verbose_name=_('condition'), null=True, blank=True) objects = DefaultManager() def save(self): if self.icon_path: self.icon_path.name = smart_str(self.icon_path.name) super(LocalEntry, self).save() def __unicode__(self): return self.name class Meta: app_label = 'promotion' verbose_name = _('LocalEntry') verbose_name_plural = _('LocalEntries')
class KuWanItem(Ordered): title = models.CharField(max_length=255, verbose_name=_('title')) description = models.TextField(max_length=4096, verbose_name=_('description')) price = models.DecimalField(default=DECIMAL_0, max_digits=25, decimal_places=5, verbose_name=_('price')) icon_url = models.URLField(verify_exists=False, max_length=255, null=True, blank=True, verbose_name=_('icon URL'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 135x231')) icon_path = models.ImageField(storage=LocalFileSystemStorage(), upload_to='static/images/', null=True, blank=True, verbose_name=_('icon path'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 135x231')) list_type = models.IntegerField(choices=KUWAN_LIST_TYPES.to_choices(), verbose_name=_('list type'), \ help_text=_('need to be the same with huawei kuwan type')) t_id = models.IntegerField(verbose_name=_('tianyi kuwan id'), help_text=_('need to be the same with huaWei platform kuwan item id')) # ALTER TABLE `app_kuwanitem` ADD COLUMN `list_type` int(11) NOT NULL, ADD COLUMN `t_id` int(11) NOT NULL; # ALTER TABLE estore.app_kuwanitem MODIFY COLUMN title VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; # ALTER TABLE estore.app_kuwanitem MODIFY COLUMN description longtext CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; # ALTER TABLE estore.app_kuwanitem MODIFY COLUMN icon_url VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL; objects = CustomManager() def __unicode__(self): return self.title def save(self): if self.icon_path: self.icon_path.name = smart_str(self.icon_path.name) super(KuWanItem, self).save() class Meta: app_label = 'app' verbose_name = _('TianYi KuWan') verbose_name_plural = _('TianYi KuWan')
class PreviewIcon(Ordered): appversion = models.ForeignKey(AppVersion, related_name="preview_icon_urls", verbose_name=_('application version')) url = BtnURLField(verify_exists=False, max_length=255, null=True, blank=True, verbose_name=_('icon URL'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 320x480')) path = models.ImageField(storage=LocalFileSystemStorage(), upload_to='static/images/', verbose_name=_('icon path'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 320x480')) title = models.CharField(max_length=255, null=True, blank=True, verbose_name=_('icon title')) def save(self): self.path.name = smart_str(self.path.name) # for PreviewIcon , pass and published by default self.review_status = REVIEW_STATUS.APPROVED self.published = True # the name of path maybe changed by system when save # so need to save before changing the value of title super(PreviewIcon, self).save() self.title = self.path.name.split('/')[-1] or self.url.split('/')[-1] super(PreviewIcon, self).save() version = self.appversion.app.versions.all().order_by('-version_code')[0] self.appversion.app.has_icon = True if version.preview_icon_urls.count() > 0 else False self.appversion.app.save() def __unicode__(self): return self.url class Meta: app_label = 'app' verbose_name = _('Preview Icon') verbose_name_plural = _('Preview Icons')
class Message(EntityModel): title = models.CharField(max_length=50, verbose_name=_('title')) content = models.TextField(max_length=1023, verbose_name=_('content')) link_url = models.URLField(max_length=255, null=True, blank=True, verbose_name=_('link URL')) icon_url = models.URLField(verify_exists=False, max_length=255, null=True, blank=True, verbose_name=_('icon URL'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 64x64')) icon_path = models.ImageField(storage=LocalFileSystemStorage(), upload_to='static/images/', null=True, blank=True, verbose_name=_('icon path'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 64x64')) client_id = models.CharField(max_length=60, null=True, blank=True, verbose_name=_('client id')) category = models.CharField(max_length=30, null=True, blank=True, verbose_name=_('category')) invalid_before = models.DateTimeField(verbose_name=_('invalid before')) invalid_after = models.DateTimeField(verbose_name=_('invalid after')) short_message = models.CharField(max_length=200, null=True, blank=True, verbose_name=_('short message')) locales = models.CharField(max_length=200, null=True, blank=True, verbose_name=_('locales')) action = models.CharField(choices=PUSH_MESSAGE_ACTIONS.to_choices(), max_length=50, verbose_name=_('action')) value = models.CharField(max_length=255, verbose_name=_('value')) status = models.IntegerField(default=1, choices=MESSAGE_STATUS.to_choices(), verbose_name=_('status')) targets = models.CharField(max_length=409600, verbose_name=_('target'), null=True, blank=True) display_area = models.IntegerField(choices=PUSH_MESSAGE_DISPLAY_AREAS.to_choices(), verbose_name=_('display area')) extra_infos = models.CharField(max_length=1024, verbose_name=_('extra info'), null=True, blank=True) # ALTER TABLE `push_message` ADD COLUMN `extra_infos` varchar(1024) NULL; objects = DefaultManager() def __unicode__(self): return self.title def value_readable(self): if self.action in (PUSH_MESSAGE_ACTIONS.APP_DETAILES_PAGE, PUSH_MESSAGE_ACTIONS.SHORT_CUT_DETAIL_PAGE, \ PUSH_MESSAGE_ACTIONS.SHORT_CUT_DOWNLOAD_APP, PUSH_MESSAGE_ACTIONS.DOWNLOAD_APP, \ PUSH_MESSAGE_ACTIONS.DOWNLOADB, PUSH_MESSAGE_ACTIONS.LAUNCHB): try: app = Application.objects.get(pk=long(self.value)) return _('App-%(app_id)s-%(app_name)s') % {'app_id': app.id, 'app_name': app.name} except: return _('App with id %(app_id)s does not exists') % {'app_id': self.value} elif self.action == PUSH_MESSAGE_ACTIONS.SUBJECT_INFO: try: subject = CategorySubject.objects.get(pk=long(self.value)) return _('Subject-%(subject_id)s-%(subject_name)s') % {'subject_id': subject.id, 'subject_name': subject.name} except: return _('Subject with id %(subject_id)s does not exists') % {'subject_id': self.value} else: return self.value value_readable.short_description = _('value readable') def display_content(self): if len(self.content) > 30: return '%s...' % self.content[:30] return self.content display_content.short_description = _('content') class Meta: app_label = 'push' verbose_name = _('Message') verbose_name_plural = _('Messages')
class Activity(RichItem): title = models.CharField(max_length=255, verbose_name=_('title')) start_date = models.DateTimeField(verbose_name=_('start date')) end_date = models.DateTimeField(verbose_name=_('end date')) description = models.TextField(max_length=1023, verbose_name=_('description')) pub_date = models.DateTimeField(verbose_name=_('publish date')) icon_url = models.URLField(verify_exists=False, max_length=255, null=True, blank=True, verbose_name=_('icon URL'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 120x144')) icon_path = models.ImageField(storage=LocalFileSystemStorage(), upload_to='static/images/', verbose_name=_('icon path'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 120x144')) large_icon_url = models.URLField(verify_exists=False, max_length=255, null=True, blank=True, verbose_name=_('large icon URL'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 480x200')) large_icon_path = models.ImageField(storage=LocalFileSystemStorage(), upload_to='static/zimages/', max_length=255, verbose_name=_('large icon path'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 480x200'), null=True, blank=True) status = models.IntegerField(default=0, choices=ACTIVITY_STATUS.to_choices(), verbose_name=_('status')) tag = models.IntegerField(choices=ACTIVITY_TAGS.to_choices(), verbose_name=_('tag')) group = models.ForeignKey(Group, verbose_name=_('user group'), null=True, blank=True, editable=False) objects = DefaultManager() def save(self): if self.icon_path: self.icon_path.name = smart_str(self.icon_path.name) super(Activity, self).save() def __unicode__(self): return self.title class Meta: app_label = 'promotion' verbose_name = _('Activity') verbose_name_plural = _('Activities')
class SubjectItem(Ordered): subject = models.ForeignKey(CategorySubject, related_name='items', verbose_name=_('subject')) title = models.CharField(max_length=255, verbose_name=_('title')) description = models.TextField(max_length=4096, verbose_name=_('description')) icon_url = models.URLField(verify_exists=False, max_length=255, null=True, blank=True, verbose_name=_('icon URL'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 480x210')) icon_path = models.ImageField(storage=LocalFileSystemStorage(), upload_to='static/images/', null=True, blank=True, verbose_name=_('icon path'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 480x210')) objects = CustomManager() def __unicode__(self): return self.title class Meta: app_label = 'app' verbose_name = _('Subject Item') verbose_name_plural = _('Subject Items')
class AppListItem(RichItem, ExternalApp, StatsBaseModel): app = models.ForeignKey(Application, null=True, blank=True, limit_choices_to={'review_status__exact': 1, 'published': 1}, verbose_name=_('application')) app_list = models.ForeignKey(AppList, verbose_name=_('app list')) group = models.ForeignKey(Group, verbose_name=_('user group'),null=True, blank=True, editable=False) title = models.CharField(max_length=255, null=True, blank=True, verbose_name=_('title')) description = models.TextField(max_length=4096, null=True, blank=True, verbose_name=_('description')) icon_url = models.URLField(verify_exists=False, max_length=255, null=True, blank=True, verbose_name=_('icon URL'), \ help_text=_('Please upload JPEG, PNG, GIF files')) icon_path = models.ImageField(storage=LocalFileSystemStorage(), upload_to='static/images/', null=True, blank=True, verbose_name=_('icon path'), \ help_text=_('Please upload JPEG, PNG, GIF files')) extra_infos = models.CharField(max_length=1024, verbose_name=_('extra info'), null=True, blank=True) # ALTER TABLE `app_applistitem` ADD COLUMN `extra_infos` varchar(1024) NULL; objects = CustomManager() def save(self): if self.icon_path: self.icon_path.name = smart_str(self.icon_path.name) super(AppListItem, self).save() def attr_readable(self): if self.type and self.attr: if self.type == RICHITEM_TYPE.APP_DETAILES_PAGE: try: app = Application.objects.get(id=long(self.attr)) return _('App-%(app_id)s-%(app_name)s') % {'app_id': app.id, 'app_name': app.name} except: return _('App with id %(app_id)s does not exists') % {'app_id': self.attr} elif self.type == RICHITEM_TYPE.SUBJECT_INFO: try: subject = CategorySubject.objects.get(id=long(self.attr)) return _('Subject-%(subject_id)s-%(subject_name)s') % {'subject_id': subject.id, 'subject_name': subject.name} except: return _('Subject with id %(subject_id)s does not exists') % {'subject_id': self.attr} return self.attr attr_readable.short_description = _('attr readable') class Meta: app_label = 'app' verbose_name = _('AppListItem') verbose_name_plural = _('AppListItem')
class Category(Ordered): name = models.CharField(max_length=255, verbose_name=_('category name')) description = models.TextField(max_length=4096, verbose_name=_('description')) icon_url = models.URLField(verify_exists=False, max_length=255, null=True, blank=True, verbose_name=_('icon URL'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 64x64')) icon_path = models.ImageField(storage=LocalFileSystemStorage(), upload_to='static/images/', verbose_name=_('icon path'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 64x64')) level = models.IntegerField(choices=CATEGORY_LEVELS.to_choices(), verbose_name=_('level')) # parent_category null means top level parent_category = models.ForeignKey('self', related_name='children', limit_choices_to={'level__exact': CATEGORY_LEVELS.CATEGORY}, \ null=True, blank=True, default=None, verbose_name=_('parent category')) objects = CustomManager() def app_counts(self): if self.pk: if self.parent_category is None: return self.total_apps.filter(hided=False).count() else: return self.apps.filter(hided=False).count() return 0 app_counts.short_description = _('application count') def click_count(self): if self.pk: result = self.stats.values('clicks').annotate(clicks_count=models.Sum('clicks')) if result: return result[0]['clicks_count'] return 0 click_count.short_description = _('clicks') click_count.admin_order_field = 'clicks_count' def __unicode__(self): return self.name class Meta: app_label = 'app' verbose_name = _('Category') verbose_name_plural = _('Categories') unique_together = ("name", "level")
class LoginPicture(RichItem): name = models.CharField(max_length=255, verbose_name=_('picture name')) url = models.URLField(verify_exists=False, max_length=255, null=True, blank=True, verbose_name=_('picture URL'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 320x480')) path = models.ImageField(storage=LocalFileSystemStorage(), upload_to='static/images/', verbose_name=_('picture path'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 320x480')) start_date = models.DateTimeField(verbose_name=_('start date')) end_date = models.DateTimeField(verbose_name=_('end date')) is_default = models.BooleanField(verbose_name=_('is default')) search_keyword = models.CharField(max_length=128, blank=True, null=True, verbose_name=_('search keyword')) home_banner = models.CharField(max_length=256, blank=True, null=True, verbose_name=_('Home Banner')) group = models.ForeignKey(Group, verbose_name=_('user group'), null=True, blank=True, editable=False) objects = DefaultManager() def save(self): if self.path: self.path.name = smart_str(self.path.name) super(LoginPicture, self).save() def __unicode__(self): return self.name class Meta: app_label = 'promotion' verbose_name = _('Login Picture') verbose_name_plural = _('Login Pictures')
class AppVersion(EntityModel, StatsBaseModel): t_status = models.IntegerField(default=0, choices=TIANYI_STATUS.to_choices(), verbose_name=_("tianyi status")) app = models.ForeignKey("Application", related_name='versions', verbose_name=_('application')) version = models.CharField(max_length=255, null=True, blank=True, verbose_name=_('version')) version_code = models.IntegerField(verbose_name=_('version code'), null=True, blank=True) source = models.IntegerField(choices=APP_SOURCES.to_choices(), verbose_name=_('source')) developer = models.CharField(max_length=255, blank=True, null=True, verbose_name=_('developer')) description = models.TextField(max_length=4096, verbose_name=_('description')) price = models.DecimalField(default=DECIMAL_0, max_digits=25, decimal_places=5, verbose_name=_('price')) pub_date = models.DateTimeField(verbose_name=_('publish date')) icon_url = BtnURLField(verify_exists=False, max_length=255, null=True, blank=True, verbose_name=_('icon URL'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 72x72')) icon_path = models.ImageField(storage=LocalFileSystemStorage(), upload_to='static/images/', null=True, blank=True, verbose_name=_('icon path'), \ help_text=_('Please upload JPEG, PNG, GIF files, size: 72x72')) download_url = models.URLField(verify_exists=False, max_length=255, null=True, blank=True, verbose_name=_('download URL')) download_path = models.FileField(storage=LocalFileSystemStorage(), upload_to='static/apks/', verbose_name=_('download path')) size = models.BigIntegerField(default=0, null=True, blank=True, verbose_name=_('size')) package_hash = models.CharField(max_length=255, verbose_name=_('package hash'), null=True, blank=True) min_sdk_version = models.IntegerField(null=True, blank=True, verbose_name=_('min sdk version')) reviewed_desc_preview = models.BooleanField(default=False, verbose_name=_("reviewed desc preview")) #alter table appversion add column external_download_url varchar(2048) default null external_download_url = models.CharField(max_length=2048, verbose_name=_('external app download url'), null=True, blank=True) labels = models.CharField(max_length=512, verbose_name=_('labels'), null=True, blank=True) update_note = models.TextField(max_length=4096, null=True, blank=True, verbose_name=_('update_note')) tencent_safe = models.SmallIntegerField(blank=True, null=True, verbose_name=_('tencent safe')) objects = CustomManager() def save(self, save_apk_info=None): old_obj = AppVersion.objects.get(pk__exact=self.id) if self.pk else None self.download_path.name = smart_str(self.download_path.name) super(AppVersion, self).save() if save_apk_info is None: if not old_obj or old_obj.download_path != self.download_path: self._set_apk_info() elif save_apk_info: self._set_apk_info() if self.app.versions_count != self.app.versions.count(): self.app.versions_count = self.app.versions.count() if not self.app.current_version: self.app.current_version = self if self.app.current_version and self.id == self.app.current_version.id \ and self.app.sync_status == SYNC_STATUS.SYNCED: self.app.sync_status = 0 if not old_obj or old_obj.reviewed_desc_preview != self.reviewed_desc_preview: reviewed_versions = AppVersion.objects.filter(app=self.app, reviewed_desc_preview=1).order_by('-version_code') if reviewed_versions.count() == 0: self.app.reviewed_desc_preview_status = 0 elif reviewed_versions[0] == self.app.current_version: self.app.reviewed_desc_preview_status = 2 else: self.app.reviewed_desc_preview_status = 1 self.app.save() def _set_apk_info(self): apk_info = extract_apk_info(self, with_apk_sign=True) self.size = apk_info.get('size', 0) self.version = apk_info.get('version_name', None) self.version_code = apk_info.get('version_code', None) self.package_hash = apk_info.get('package_hash', None) self.min_sdk_version = apk_info.get('min_sdk_version', None) icon = apk_info.get('icon', None) if icon: self.icon_path.save(icon[0], icon[1]) if not self.app.package_name: self.app.package_name = apk_info.get('package_name', None) self.app.package_sig = apk_info.get('package_sign', None) self.save(save_apk_info=False) def app_version(self): if self.pk: return '%s - v%s' % (self.app.name, self.version) return self.version app_version.short_description = _('application version') def source_name(self): source_dict = APP_SOURCES.to_dict() if self.source in source_dict: return source_dict[self.source] else: return _('Unknown') source_name.short_description = _('source') source_name.admin_order_field = 'source' def rate(self): if self.pk and self.stats.count() > 0: return self.stats.all()[0].rate return 0 rate.short_description = _('rating') def icon_urls(self): preview_icon_urls = [icon.url or parse_url(icon.path.url) for icon in self.preview_icon_urls.all() if not icon.hided] return ','.join(preview_icon_urls) def __unicode__(self): return '%s - %s' % (self.version, self.get_source_display()) class Meta: app_label = 'app' verbose_name = _('Application Version') verbose_name_plural = _('Application Versions')
class CategoryFoucsImage(RichItem): category = models.ForeignKey(Category, limit_choices_to={'level__exact': CATEGORY_LEVELS.CATEGORY}, null=True, blank=True, verbose_name=_('category')) recommend_type = models.IntegerField(choices=RECOMMEND_TYPES.to_choices(), null=True, blank=True, verbose_name=_('recommend type')) pub_date = models.DateTimeField(verbose_name=_('publish date')) icon_url = models.URLField( verify_exists=False, max_length=255, null=True, blank=True, verbose_name=_('icon URL'), help_text=_('Please upload JPEG, PNG, GIF files, size: 480x210') ) icon_path = models.ImageField( storage=LocalFileSystemStorage(), upload_to='static/images/', verbose_name=_('icon path'), help_text=_('Please upload JPEG, PNG, GIF files, size: 480x210') ) area = models.IntegerField(choices=BANNER_IMAGE_AREAS.to_choices(), verbose_name=_('area')) group = models.ForeignKey(Group, verbose_name=_('user group'), null=True, blank=True, editable=False) cooperate_list_id = models.CharField( max_length=256, verbose_name=_('cooperate_list_id'), blank=True, null=True, help_text=_('Examples: tianyireading, lovemusic, lovegame, loveanimation, tianyishixun, liuliangbao') ) cooperate_list_name = models.CharField( max_length=256, verbose_name=_('cooperate_list_name'), blank=True, null=True, help_text=_(u'Examples: 天翼阅读, 爱音乐, 爱游戏, 爱动漫, 天翼视讯, 流量宝专区') ) objects = CustomManager() def __unicode__(self): return BANNER_IMAGE_AREAS.to_dict()[self.area]._proxy____unicode_cast() def save(self): if self.icon_path: self.icon_path.name = smart_str(self.icon_path.name) super(CategoryFoucsImage, self).save() def attr_readable(self): if self.type and self.attr: if self.type == RICHITEM_TYPE.APP_DETAILES_PAGE: try: app = Application.objects.get(id=long(self.attr)) return _('App-%(app_id)s-%(app_name)s') % {'app_id': app.id, 'app_name': app.name} except: return _('App with id %(app_id)s does not exists') % {'app_id': self.attr} elif self.type == RICHITEM_TYPE.SUBJECT_INFO: try: subject = CategorySubject.objects.get(id=long(self.attr)) return _('Subject-%(subject_id)s-%(subject_name)s') % {'subject_id': subject.id, 'subject_name': subject.name} except: return _('Subject with id %(subject_id)s does not exists') % {'subject_id': self.attr} return self.attr attr_readable.short_description = _('attr readable') def click_count(self): if self.pk: result = self.stats.values('clicks').annotate(clicks_count=models.Sum('clicks')) if result: return result[0]['clicks_count'] return 0 click_count.short_description = _('clicks') click_count.admin_order_field = 'clicks_count' class Meta: app_label = 'app' verbose_name = _('Category Foucs Image') verbose_name_plural = _('Category Foucs Images')
class UpdateApp(EntityModel): package_name = models.CharField(max_length=255, verbose_name=_('package name')) version_name = models.CharField(max_length=255, verbose_name=_('version name')) source = models.CharField(max_length=255, verbose_name=_('source')) version_code = models.IntegerField(verbose_name=_('version code')) os = models.CharField(max_length=255, verbose_name=_('os'), null=True, blank=True) os_version = models.CharField(max_length=255, verbose_name=_('os version'), null=True, blank=True) resolution = models.CharField(max_length=255, verbose_name=_('resolution'), null=True, blank=True) cpu = models.CharField(max_length=255, verbose_name=_('cpu'), null=True, blank=True) model = models.CharField(max_length=255, verbose_name=_('model'), null=True, blank=True) rom = models.CharField(max_length=255, verbose_name=_('rom'), null=True, blank=True) package_hash = models.CharField(max_length=255, verbose_name=_('package hash'), null=True) # ALTER TABLE `update_updateapp` ADD COLUMN `package_hash` varchar(255) DEFAULT NULL; device = models.CharField(max_length=512, verbose_name=_('device'), null=True, blank=True) download_url = models.URLField(verify_exists=False, max_length=255, null=True, blank=True, verbose_name=_('download URL')) download_path = models.FileField(storage=LocalFileSystemStorage(), null=True, blank=True, upload_to='static/apks/', verbose_name=_('download path')) is_force = models.BooleanField(default=False, verbose_name=_('is force')) is_auto = models.BooleanField(default=False, verbose_name=_('is auto')) is_patch = models.BooleanField(default=False, verbose_name=_('is patch')) channel_promote = models.BooleanField(default=False, verbose_name=_('channel promote')) title = models.CharField(max_length=255, verbose_name=_('title')) content_title = models.CharField(max_length=255, verbose_name=_('content title')) package_size = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('package size')) change_log = models.TextField(verbose_name=_('change log')) objects = DefaultManager() def __unicode__(self): return self.package_name def save(self): if self.download_path and not self.package_size: self.package_size = self.download_path.size super(UpdateApp, self).save() def get_buttons(self): update_buttons = [] for btn in self.buttons.all().filter(hided=False): update_buttons.append({ 'action': btn.action, 'btn': btn.btn, 'order': btn.order, }) return update_buttons class Meta: app_label = 'update' verbose_name = _('Update Application') verbose_name_plural = _('Update Applications')