<commit_before>import json
import argparse
import os
import shutil
import sys
import zipfile

parser = argparse.ArgumentParser(description="The path of your src/")
parser.add_argument('path')

args = parser.parse_args()

# Build path
picto_folder = args.path + "/platform/ods/core/static/pictos/img/set-v3/pictos/"
reference_file = args.path + "/platform/ods/localepictos/reference.json"
rst_file = os.path.join(os.getcwd(),"icons_cheatsheet/icons_cheatsheet.rst")

# Debug
#print(picto_folder)
#print(reference_file)
#print(rst_file)
#print(os.path.isdir(picto_folder))
#print(os.path.isfile(reference_file))

# Build zip file with all the files in target folder (remove full path to unzip correctly)
myzip = zipfile.ZipFile(os.path.join(os.getcwd(),"ODS-icons.zip"), 'w')
src_files = os.listdir(picto_folder)
for i,file_name in enumerate(src_files):
    full_file_name = os.path.join(picto_folder, file_name)
    if (os.path.isfile(full_file_name)):
        sys.stdout.write("#")
        shutil.copy(full_file_name,os.path.join(os.getcwd(),"icons_cheatsheet/icons/"))
        myzip.write(full_file_name,os.path.basename(full_file_name))

myzip.close()

# Write Feedback
sys.stdout.write('-')
sys.stdout.write(str(len(src_files)))
sys.stdout.write(' icons copied\n')
sys.stdout.write('Zip created\n')

# Parse reference JSON
jsonfile = open(reference_file)
input_json = json.load(jsonfile)
jsonfile.close()
results = []
out_file = open(rst_file,"w")

# Write page title
out_file.write('Icons cheatsheet\n================\n\n')

out_file.write('These icons are distributed under the `Creative Commons Licence CC0 <https://creativecommons.org/publicdomain/zero/1.0/>`_ \n\n')
out_file.write('You can also :download:`download all the icons in zip </ODS-icons.zip>` (SVG, minified) 1.1Mb\n\n')
out_file.write('These icons can be selected as a marker or caption in maps or pasted directly in widget code\n\n')

for category in input_json.get('categories', []):
    col_num = 0
    res = {}

    out_file.write("{}\n".format(category.get('title')))

    # For each title write title
    out_file.write('-' * len(category.get('title')))
    out_file.write("\n\n")
    # Write category keywords
    #out_file.write("Keywords: {}\n\n".format(' '.join(category.get('keywords_cat', []))))

    # Add an icon-block class for CSS layout
    out_file.write("  .. container:: ods-icon-block\n\n")

    for icon in category.get('icons', []):

        # Add an icon-plus-captions class for CSS layout
        out_file.write("    .. container:: ods-icon-plus-caption tooltip\n\n")

        # Try to inline SVG but triggers too many errors - backup
        #out_file.write("      .. raw:: html\n\n")
        #out_file.write("         <object data=\"../_images/{}.svg\" type=\"image/svg+xml\"></object>\n\n".format(icon.get('filename')))

        # For each icon write the icon
        out_file.write("      .. image:: icons/{}.svg\n".format(icon.get('filename')))
        out_file.write("         :width: 30pt\n")
        out_file.write("         :height: 30pt\n")
        out_file.write("         :class: ods-icon\n")
        out_file.write("         :alt: {}\n\n".format(icon.get('name')))

        # Add an icon-caption class for CSS layout
        out_file.write("      .. container:: ods-icon-caption\n\n")

        # Add an two classes for CSS layout
        out_file.write("        .. container:: ods-icon-caption-name\n\n")
        out_file.write("           {}\n".format(icon.get('name')))
        out_file.write("        .. container:: ods-icon-caption-filename\n\n")
        out_file.write("           ods-{}\n\n".format(icon.get('filename')))

        # Tooltip to display keywords if someone asks - backup
        #out_file.write("      .. container:: tooltiptext\n\n")
        #out_file.write("        .. container:: ods-tooltip-filename\n\n")
        #out_file.write("            ods-{}\n\n".format(icon.get('filename')))
        #out_file.write("        .. container:: ods-tooltip-keywords\n\n")
        #out_file.write("            Keywords: {}\n\n".format(' '.join(icon.get('keywords', []))))

        out_file.write("\n")

# Write Feedback
sys.stdout.write('Page created\n')<commit_msg>Remove commented code<commit_after>import json
import argparse
import os
import shutil
import sys
import zipfile

parser = argparse.ArgumentParser(description="The path of your src/")
parser.add_argument('path')

args = parser.parse_args()

# Build path
picto_folder = args.path + "/platform/ods/core/static/pictos/img/set-v3/pictos/"
reference_file = args.path + "/platform/ods/localepictos/reference.json"
rst_file = os.path.join(os.getcwd(),"icons_cheatsheet/icons_cheatsheet.rst")

# Build zip file with all the files in target folder (remove full path to unzip correctly)
myzip = zipfile.ZipFile(os.path.join(os.getcwd(),"ODS-icons.zip"), 'w')
src_files = os.listdir(picto_folder)
for i,file_name in enumerate(src_files):
    full_file_name = os.path.join(picto_folder, file_name)
    if (os.path.isfile(full_file_name)):
        sys.stdout.write("#")
        shutil.copy(full_file_name,os.path.join(os.getcwd(),"icons_cheatsheet/icons/"))
        myzip.write(full_file_name,os.path.basename(full_file_name))

myzip.close()

# Write Feedback
sys.stdout.write('-')
sys.stdout.write(str(len(src_files)))
sys.stdout.write(' icons copied\n')
sys.stdout.write('Zip created\n')

# Parse reference JSON
jsonfile = open(reference_file)
input_json = json.load(jsonfile)
jsonfile.close()
results = []
out_file = open(rst_file,"w")

# Write page title
out_file.write('Icons cheatsheet\n================\n\n')

out_file.write('These icons are distributed under the `Creative Commons Licence CC0 <https://creativecommons.org/publicdomain/zero/1.0/>`_ \n\n')
out_file.write('You can also :download:`download all the icons in zip </ODS-icons.zip>` (SVG, minified) 1.1Mb\n\n')
out_file.write('These icons can be selected as a marker or caption in maps or pasted directly in widget code\n\n')

for category in input_json.get('categories', []):
    col_num = 0
    res = {}

    out_file.write("{}\n".format(category.get('title')))

    # For each title write title
    out_file.write('-' * len(category.get('title')))
    out_file.write("\n\n")

    # Add an icon-block class for CSS layout
    out_file.write("  .. container:: ods-icon-block\n\n")

    for icon in category.get('icons', []):

        # Add an icon-plus-captions class for CSS layout
        out_file.write("    .. container:: ods-icon-plus-caption tooltip\n\n")

        # For each icon write the icon
        out_file.write("      .. image:: icons/{}.svg\n".format(icon.get('filename')))
        out_file.write("         :width: 30pt\n")
        out_file.write("         :height: 30pt\n")
        out_file.write("         :class: ods-icon\n")
        out_file.write("         :alt: {}\n\n".format(icon.get('name')))

        # Add an icon-caption class for CSS layout
        out_file.write("      .. container:: ods-icon-caption\n\n")

        # Add an two classes for CSS layout
        out_file.write("        .. container:: ods-icon-caption-name\n\n")
        out_file.write("           {}\n".format(icon.get('name')))
        out_file.write("        .. container:: ods-icon-caption-filename\n\n")
        out_file.write("           ods-{}\n\n".format(icon.get('filename')))

        out_file.write("\n")

# Write Feedback
sys.stdout.write('Page created\n')<|endoftext|>


<commit_before>#########################################################################
#This module intergrates Open ERP with the magento core                 #
#Core settings are stored here                                          #
#########################################################################
#                                                                       #
# Copyright (C) 2009  Sharoon Thomas                                    #
#                                                                       #
#This program is free software: you can redistribute it and/or modify   #
#it under the terms of the GNU General Public License as published by   #
#the Free Software Foundation, either version 3 of the License, or      #
#(at your option) any later version.                                    #
#                                                                       #
#This program is distributed in the hope that it will be useful,        #
#but WITHOUT ANY WARRANTY; without even the implied warranty of         #
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          #
#GNU General Public License for more details.                           #
#                                                                       #
#You should have received a copy of the GNU General Public License      #
#along with this program.  If not, see <http://www.gnu.org/licenses/>.  #
#########################################################################

from osv import osv, fields
import magerp_osv
from base_external_referentials import external_osv

DEBUG = True
TIMEOUT = 2

class external_referential(magerp_osv.magerp_osv):
    #This class stores instances of magento to which the ERP will connect, the concept of multi website, multistore integration?
    _inherit = "external.referential"

    _columns = {
        'attribute_sets':fields.one2many('magerp.product_attribute_set', 'instance', 'Attribute Sets'),
        'default_pro_cat':fields.many2one('product.category','Default Product Category',required=True, help="Products imported from magento may have many categories.\nOpen ERP requires a specific category for a product to facilitate invoicing etc.")
    }

    def connect(self, cr, uid, ids, ctx={}):#TODO used?
        #ids has to be a list
        if ids:
            if len(ids) == 1:
                instance = self.browse(cr, uid, ids, ctx)[0]
                if instance:
                    core_imp_conn = self.external_connection(cr, uid, instance, DEBUG)
                    if core_imp_conn.connect():
                        return core_imp_conn
        return False

    def core_sync(self, cr, uid, ids, ctx={}):
        instances = self.browse(cr, uid, ids, ctx)
        filter = []
        for inst in instances:
            core_imp_conn = self.external_connection(cr, uid, inst, DEBUG)
            if core_imp_conn:
                #New import methods
                self.pool.get('external.shop.group').mage_import_base(cr, uid,core_imp_conn, inst.id)
                self.pool.get('magerp.storeviews').mage_import_base(cr,uid,core_imp_conn, inst.id)
                self.pool.get('sale.shop').mage_import_base(cr, uid, core_imp_conn, inst.id)
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))

    def sync_categs(self, cr, uid, ids, ctx):
        instances = self.browse(cr, uid, ids, ctx)
        for inst in instances:
            pro_cat_conn = self.external_connection(cr, uid, inst, DEBUG)
            if pro_cat_conn:
                confirmation = pro_cat_conn.call('catalog_category.currentStore', [0])   #Set browse to root store
                if confirmation:
                    categ_tree = pro_cat_conn.call('catalog_category.tree')             #Get the tree
                    self.pool.get('product.category').record_entire_tree(cr, uid, inst.id, pro_cat_conn, categ_tree, DEBUG)
                    exp_ids = self.pool.get('product.category').search(cr,uid,[('exportable','=',True)])
                    self.pool.get('product.category').ext_export(cr,uid,exp_ids,[inst.id],{},{'conn_obj':pro_cat_conn})
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))

    def sync_attribs(self, cr, uid, ids, ctx):
        instances = self.browse(cr, uid, ids, ctx)
        for inst in instances:
            attr_conn = self.external_connection(cr, uid, inst, DEBUG)
            if attr_conn:
                attrib_set_ids = self.pool.get('magerp.product_attribute_set').search(cr, uid, [('instance', '=', inst.id)])
                attrib_sets = self.pool.get('magerp.product_attribute_set').read(cr, uid, attrib_set_ids, ['magento_id'])
                #Get all attribute set ids to get all attributes in one go
                all_attr_set_ids = self.pool.get('magerp.product_attribute_set').get_all_mage_ids(cr, uid, [], inst.id)
                #Call magento for all attributes
                mage_inp = attr_conn.call('ol_catalog_product_attribute.list', all_attr_set_ids)             #Get the tree
                #self.pool.get('magerp.product_attributes').sync_import(cr, uid, mage_inp, inst.id, DEBUG) #Last argument is extra mage2oe filter as same attribute ids
                self.pool.get('magerp.product_attributes').ext_import(cr, uid, mage_inp, inst.id, defaults={'instance':inst.id}, context={})
                #Relate attribute sets & attributes
                mage_inp = {}
                #Pass in {attribute_set_id:{attributes},attribute_set_id2:{attributes}}
                #print "Attribute sets are:", attrib_sets
                for each in attrib_sets:
                    mage_inp[each['magento_id']] = attr_conn.call('ol_catalog_product_attribute.relations', [each['magento_id']])
                if mage_inp:
                    self.pool.get('magerp.product_attribute_set').relate(cr, uid, mage_inp, inst.id, DEBUG)
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))

    def sync_attrib_sets(self, cr, uid, ids, ctx):
        instances = self.browse(cr, uid, ids, ctx)
        for inst in instances:
            attr_conn = self.external_connection(cr, uid, inst, DEBUG)
            if attr_conn:
                filter = []
                #self.pool.get('magerp.product_attribute_set').mage_import(cr, uid, filter, attr_conn, inst.id, DEBUG)
                self.pool.get('magerp.product_attribute_set').mage_import_base(cr, uid, attr_conn, inst.id,{'instance':inst.id},{'ids_or_filter':filter})
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))

    def sync_attrib_groups(self, cr, uid, ids, ctx):
        instances = self.browse(cr, uid, ids, ctx)
        for inst in instances:
            attr_conn = self.external_connection(cr, uid, inst, DEBUG)
            attrset_ids = self.pool.get('magerp.product_attribute_set').get_all_mage_ids(cr, uid, [], inst.id)
            filter = [{'attribute_set_id':{'in':attrset_ids}}]
            if attr_conn:
                #self.pool.get('magerp.product_attribute_groups').mage_import(cr, uid, filter, attr_conn, inst.id, DEBUG)
                self.pool.get('magerp.product_attribute_groups').mage_import_base(cr, uid, attr_conn, inst.id, {'instance':inst.id}, {'ids_or_filter':filter})
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))

    def sync_customer_groups(self, cr, uid, ids, ctx):
        instances = self.browse(cr, uid, ids, ctx)
        for inst in instances:
            attr_conn = self.external_connection(cr, uid, inst, DEBUG)
            filter = []
            if attr_conn:
                self.pool.get('res.partner.category').mage_import(cr, uid, filter, attr_conn, inst.id, DEBUG)
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))

    def sync_customer_addresses(self, cr, uid, ids, ctx):
        instances = self.browse(cr, uid, ids, ctx)
        for inst in instances:
            attr_conn = self.external_connection(cr, uid, inst, DEBUG)
            filter = []
            if attr_conn:
                self.pool.get('res.partner').mage_import(cr, uid, filter, attr_conn, inst.id, DEBUG)
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))

    def sync_products(self, cr, uid, ids, ctx):
        instances = self.browse(cr, uid, ids, ctx)
        for inst in instances:
            attr_conn = self.external_connection(cr, uid, inst, DEBUG)
            filter = []
            if attr_conn:
                list_prods = attr_conn.call('catalog_product.list')
                #self.pool.get('product.product').mage_import(cr, uid, filter, attr_conn, inst.id, DEBUG)
                result = []
                for each in list_prods:
                    each_product_info = attr_conn.call('catalog_product.info', [each['product_id']])
                    result.append(each_product_info)
                self.pool.get('product.product').ext_import(cr, uid, result, inst.id, defaults={'instance':inst.id,'categ_id':inst.default_pro_cat.id}, context={})
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))
    def redefine_prod_view(self,cr,uid,ids,ctx):
        #This function will rebuild the view for product from instances, attribute groups etc
        #Get all objects needed
        inst_obj = self.pool.get('external.referential')
        attr_set_obj = self.pool.get('magerp.product_attribute_set')
        attr_group_obj = self.pool.get('magerp.product_attribute_group')
        attr_obj = self.pool.get('magerp.product_attributes')
        #Predefined items on top
        #Instance
        #Attribute Set
        #Get all instances
        inst_ids = inst_obj.search(cr,uid,[])#TODO:Search for active instances only
        instances = inst_obj.read(cr,uid,inst_ids,[])
        for each_instance in instances:
            #create a group & a notebook inside, group attr
            attr_set_ids = attr_set_obj.search(cr,uid,[('instance','=',each_instance['id'])])
            attr_sets = attr_set_obj.browse(cr,uid,attr_set_ids)
            for each_set in attr_sets:
                #Create a page with attrs corresponding to the set id
                attr_grp_ids = attr_group_obj.search(cr,uid,[('attribute_set','=',each_set['id'])]) #attribute_set is a function field, may slow down the whole thing
                attr_groups = attr_group_obj.read(cr,uid,attr_grp_ids,[])
                for each_group in attr_groups:
                    #Create a page for the attribute group
                    attribute_ids = each_set.attributes
                    attr

    def export_products(self, cr, uid, ids, ctx):
        instances = self.browse(cr, uid, ids, ctx)
        for inst in instances:
            attr_conn = self.external_connection(cr, uid, inst, DEBUG)
            if attr_conn:
                ids = self.pool.get('product.product').search(cr, uid, [])
                self.pool.get('product.product').mage_export(cr, uid, ids, attr_conn, inst.id, DEBUG)
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))

external_referential()

class external_shop_group(magerp_osv.magerp_osv):
    _inherit = "external.shop.group"
    #Return format of API:{'code': 'base', 'name': 'Main', 'website_id': '1', 'is_default': '1', 'sort_order': '0', 'default_group_id': '1'}

    def _get_group(self, cr, uid, ids, prop, unknow_none, context):
        res = self.group_get(cr, uid, ids, context={'field':'default_group_id'})
        return dict(res)

    _order = 'magento_id'

    _columns = {
        'code':fields.char('Code', size=100),
        'magento_id':fields.integer('Website ID'),
        'is_default':fields.boolean('Is Active?'),
        'sort_order':fields.integer('Sort Order'),
        'default_group_id':fields.integer('Default Store Group'), #Many 2 one?
        'default_group':fields.function(_get_group, type="many2one", relation="sale.shop", method=True, string="Default Store (Group)"),
        'instance':fields.many2one('external.referential', 'Instance', ondelete='cascade')
    }

external_shop_group()

class magerp_storeviews(magerp_osv.magerp_osv):
    _name = "magerp.storeviews"
    _description = "The magento store views information"

    def _get_website(self, cr, uid, ids, prop, unknow_none, context):
        res = self.website_get(cr, uid, ids, context={'field':'magento_id'})
        return dict(res)

    def _get_group(self, cr, uid, ids, prop, unknow_none, context):
        res = self.group_get(cr, uid, ids, context={'field':'group_id'})
        return dict(res)

    _order = 'magento_id'
    _LIST_METHOD = 'ol_storeviews.list'
    _MAGE_P_KEY = 'store_id'
    _columns = {
        'name':fields.char('Store View Name', size=100),
        'code':fields.char('Code', size=100),
        'magento_id':fields.integer('Store ID'),
        'website_id':fields.integer('Website'), # Many 2 one ?
        'website':fields.function(_get_website, type="many2one", relation="external.shop.group", method=True, string="Website"),
        'is_active':fields.boolean('Default ?'),
        'sort_order':fields.integer('Sort Order'),
        'group_id':fields.integer('Default Store Group'), #Many 2 one?
        'default_group':fields.function(_get_group, type="many2one", relation="sale.shop", method=True, string="Default Store (Group)"),
        #'instance':fields.many2one('external.referential', 'Instance', ondelete='cascade')
    }

    #Return format of API:{'code': 'default', 'store_id': '1', 'website_id': '1', 'is_active': '1', 'sort_order': '0', 'group_id': '1', 'name': 'Default Store View'}

magerp_storeviews()<commit_msg>[FIX]referential_id added for create method in mager.product_attributes<commit_after>#########################################################################
#This module intergrates Open ERP with the magento core                 #
#Core settings are stored here                                          #
#########################################################################
#                                                                       #
# Copyright (C) 2009  Sharoon Thomas                                    #
#                                                                       #
#This program is free software: you can redistribute it and/or modify   #
#it under the terms of the GNU General Public License as published by   #
#the Free Software Foundation, either version 3 of the License, or      #
#(at your option) any later version.                                    #
#                                                                       #
#This program is distributed in the hope that it will be useful,        #
#but WITHOUT ANY WARRANTY; without even the implied warranty of         #
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          #
#GNU General Public License for more details.                           #
#                                                                       #
#You should have received a copy of the GNU General Public License      #
#along with this program.  If not, see <http://www.gnu.org/licenses/>.  #
#########################################################################

from osv import osv, fields
import magerp_osv
from base_external_referentials import external_osv

DEBUG = True
TIMEOUT = 2

class external_referential(magerp_osv.magerp_osv):
    #This class stores instances of magento to which the ERP will connect, the concept of multi website, multistore integration?
    _inherit = "external.referential"

    _columns = {
        'attribute_sets':fields.one2many('magerp.product_attribute_set', 'instance', 'Attribute Sets'),
        'default_pro_cat':fields.many2one('product.category','Default Product Category',required=True, help="Products imported from magento may have many categories.\nOpen ERP requires a specific category for a product to facilitate invoicing etc.")
    }

    def connect(self, cr, uid, ids, ctx={}):#TODO used?
        #ids has to be a list
        if ids:
            if len(ids) == 1:
                instance = self.browse(cr, uid, ids, ctx)[0]
                if instance:
                    core_imp_conn = self.external_connection(cr, uid, instance, DEBUG)
                    if core_imp_conn.connect():
                        return core_imp_conn
        return False

    def core_sync(self, cr, uid, ids, ctx={}):
        instances = self.browse(cr, uid, ids, ctx)
        filter = []
        for inst in instances:
            core_imp_conn = self.external_connection(cr, uid, inst, DEBUG)
            if core_imp_conn:
                #New import methods
                self.pool.get('external.shop.group').mage_import_base(cr, uid,core_imp_conn, inst.id)
                self.pool.get('magerp.storeviews').mage_import_base(cr,uid,core_imp_conn, inst.id)
                self.pool.get('sale.shop').mage_import_base(cr, uid, core_imp_conn, inst.id)
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))

    def sync_categs(self, cr, uid, ids, ctx):
        instances = self.browse(cr, uid, ids, ctx)
        for inst in instances:
            pro_cat_conn = self.external_connection(cr, uid, inst, DEBUG)
            if pro_cat_conn:
                confirmation = pro_cat_conn.call('catalog_category.currentStore', [0])   #Set browse to root store
                if confirmation:
                    categ_tree = pro_cat_conn.call('catalog_category.tree')             #Get the tree
                    self.pool.get('product.category').record_entire_tree(cr, uid, inst.id, pro_cat_conn, categ_tree, DEBUG)
                    exp_ids = self.pool.get('product.category').search(cr,uid,[('exportable','=',True)])
                    self.pool.get('product.category').ext_export(cr,uid,exp_ids,[inst.id],{},{'conn_obj':pro_cat_conn})
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))

    def sync_attribs(self, cr, uid, ids, ctx):
        instances = self.browse(cr, uid, ids, ctx)
        for inst in instances:
            attr_conn = self.external_connection(cr, uid, inst, DEBUG)
            if attr_conn:
                attrib_set_ids = self.pool.get('magerp.product_attribute_set').search(cr, uid, [('instance', '=', inst.id)])
                attrib_sets = self.pool.get('magerp.product_attribute_set').read(cr, uid, attrib_set_ids, ['magento_id'])
                #Get all attribute set ids to get all attributes in one go
                all_attr_set_ids = self.pool.get('magerp.product_attribute_set').get_all_mage_ids(cr, uid, [], inst.id)
                #Call magento for all attributes
                mage_inp = attr_conn.call('ol_catalog_product_attribute.list', all_attr_set_ids)             #Get the tree
                #self.pool.get('magerp.product_attributes').sync_import(cr, uid, mage_inp, inst.id, DEBUG) #Last argument is extra mage2oe filter as same attribute ids
                self.pool.get('magerp.product_attributes').ext_import(cr, uid, mage_inp, inst.id, defaults={'instance':inst.id}, context={'referential_id':inst.id})
                #Relate attribute sets & attributes
                mage_inp = {}
                #Pass in {attribute_set_id:{attributes},attribute_set_id2:{attributes}}
                #print "Attribute sets are:", attrib_sets
                for each in attrib_sets:
                    mage_inp[each['magento_id']] = attr_conn.call('ol_catalog_product_attribute.relations', [each['magento_id']])
                if mage_inp:
                    self.pool.get('magerp.product_attribute_set').relate(cr, uid, mage_inp, inst.id, DEBUG)
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))

    def sync_attrib_sets(self, cr, uid, ids, ctx):
        instances = self.browse(cr, uid, ids, ctx)
        for inst in instances:
            attr_conn = self.external_connection(cr, uid, inst, DEBUG)
            if attr_conn:
                filter = []
                #self.pool.get('magerp.product_attribute_set').mage_import(cr, uid, filter, attr_conn, inst.id, DEBUG)
                self.pool.get('magerp.product_attribute_set').mage_import_base(cr, uid, attr_conn, inst.id,{'instance':inst.id},{'ids_or_filter':filter})
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))

    def sync_attrib_groups(self, cr, uid, ids, ctx):
        instances = self.browse(cr, uid, ids, ctx)
        for inst in instances:
            attr_conn = self.external_connection(cr, uid, inst, DEBUG)
            attrset_ids = self.pool.get('magerp.product_attribute_set').get_all_mage_ids(cr, uid, [], inst.id)
            filter = [{'attribute_set_id':{'in':attrset_ids}}]
            if attr_conn:
                #self.pool.get('magerp.product_attribute_groups').mage_import(cr, uid, filter, attr_conn, inst.id, DEBUG)
                self.pool.get('magerp.product_attribute_groups').mage_import_base(cr, uid, attr_conn, inst.id, {'instance':inst.id}, {'ids_or_filter':filter})
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))

    def sync_customer_groups(self, cr, uid, ids, ctx):
        instances = self.browse(cr, uid, ids, ctx)
        for inst in instances:
            attr_conn = self.external_connection(cr, uid, inst, DEBUG)
            filter = []
            if attr_conn:
                self.pool.get('res.partner.category').mage_import(cr, uid, filter, attr_conn, inst.id, DEBUG)
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))

    def sync_customer_addresses(self, cr, uid, ids, ctx):
        instances = self.browse(cr, uid, ids, ctx)
        for inst in instances:
            attr_conn = self.external_connection(cr, uid, inst, DEBUG)
            filter = []
            if attr_conn:
                self.pool.get('res.partner').mage_import(cr, uid, filter, attr_conn, inst.id, DEBUG)
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))

    def sync_products(self, cr, uid, ids, ctx):
        instances = self.browse(cr, uid, ids, ctx)
        for inst in instances:
            attr_conn = self.external_connection(cr, uid, inst, DEBUG)
            filter = []
            if attr_conn:
                list_prods = attr_conn.call('catalog_product.list')
                #self.pool.get('product.product').mage_import(cr, uid, filter, attr_conn, inst.id, DEBUG)
                result = []
                for each in list_prods:
                    each_product_info = attr_conn.call('catalog_product.info', [each['product_id']])
                    result.append(each_product_info)
                self.pool.get('product.product').ext_import(cr, uid, result, inst.id, defaults={'instance':inst.id,'categ_id':inst.default_pro_cat.id}, context={})
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))
    def redefine_prod_view(self,cr,uid,ids,ctx):
        #This function will rebuild the view for product from instances, attribute groups etc
        #Get all objects needed
        inst_obj = self.pool.get('external.referential')
        attr_set_obj = self.pool.get('magerp.product_attribute_set')
        attr_group_obj = self.pool.get('magerp.product_attribute_group')
        attr_obj = self.pool.get('magerp.product_attributes')
        #Predefined items on top
        #Instance
        #Attribute Set
        #Get all instances
        inst_ids = inst_obj.search(cr,uid,[])#TODO:Search for active instances only
        instances = inst_obj.read(cr,uid,inst_ids,[])
        for each_instance in instances:
            #create a group & a notebook inside, group attr
            attr_set_ids = attr_set_obj.search(cr,uid,[('instance','=',each_instance['id'])])
            attr_sets = attr_set_obj.browse(cr,uid,attr_set_ids)
            for each_set in attr_sets:
                #Create a page with attrs corresponding to the set id
                attr_grp_ids = attr_group_obj.search(cr,uid,[('attribute_set','=',each_set['id'])]) #attribute_set is a function field, may slow down the whole thing
                attr_groups = attr_group_obj.read(cr,uid,attr_grp_ids,[])
                for each_group in attr_groups:
                    #Create a page for the attribute group
                    attribute_ids = each_set.attributes
                    attr

    def export_products(self, cr, uid, ids, ctx):
        instances = self.browse(cr, uid, ids, ctx)
        for inst in instances:
            attr_conn = self.external_connection(cr, uid, inst, DEBUG)
            if attr_conn:
                ids = self.pool.get('product.product').search(cr, uid, [])
                self.pool.get('product.product').mage_export(cr, uid, ids, attr_conn, inst.id, DEBUG)
            else:
                osv.except_osv(_("Connection Error"), _("Could not connect to server\nCheck location, username & password."))

external_referential()

class external_shop_group(magerp_osv.magerp_osv):
    _inherit = "external.shop.group"
    #Return format of API:{'code': 'base', 'name': 'Main', 'website_id': '1', 'is_default': '1', 'sort_order': '0', 'default_group_id': '1'}

    def _get_group(self, cr, uid, ids, prop, unknow_none, context):
        res = self.group_get(cr, uid, ids, context={'field':'default_group_id'})
        return dict(res)

    _order = 'magento_id'

    _columns = {
        'code':fields.char('Code', size=100),
        'magento_id':fields.integer('Website ID'),
        'is_default':fields.boolean('Is Active?'),
        'sort_order':fields.integer('Sort Order'),
        'default_group_id':fields.integer('Default Store Group'), #Many 2 one?
        'default_group':fields.function(_get_group, type="many2one", relation="sale.shop", method=True, string="Default Store (Group)"),
        'instance':fields.many2one('external.referential', 'Instance', ondelete='cascade')
    }

external_shop_group()

class magerp_storeviews(magerp_osv.magerp_osv):
    _name = "magerp.storeviews"
    _description = "The magento store views information"

    def _get_website(self, cr, uid, ids, prop, unknow_none, context):
        res = self.website_get(cr, uid, ids, context={'field':'magento_id'})
        return dict(res)

    def _get_group(self, cr, uid, ids, prop, unknow_none, context):
        res = self.group_get(cr, uid, ids, context={'field':'group_id'})
        return dict(res)

    _order = 'magento_id'
    _LIST_METHOD = 'ol_storeviews.list'
    _MAGE_P_KEY = 'store_id'
    _columns = {
        'name':fields.char('Store View Name', size=100),
        'code':fields.char('Code', size=100),
        'magento_id':fields.integer('Store ID'),
        'website_id':fields.integer('Website'), # Many 2 one ?
        'website':fields.function(_get_website, type="many2one", relation="external.shop.group", method=True, string="Website"),
        'is_active':fields.boolean('Default ?'),
        'sort_order':fields.integer('Sort Order'),
        'group_id':fields.integer('Default Store Group'), #Many 2 one?
        'default_group':fields.function(_get_group, type="many2one", relation="sale.shop", method=True, string="Default Store (Group)"),
        #'instance':fields.many2one('external.referential', 'Instance', ondelete='cascade')
    }

    #Return format of API:{'code': 'default', 'store_id': '1', 'website_id': '1', 'is_active': '1', 'sort_order': '0', 'group_id': '1', 'name': 'Default Store View'}

magerp_storeviews()<|endoftext|>


<commit_before>from logbook import Logger
import json
import sqlite3

log = Logger(__name__)
_conn = None

def connect(db=None):
    global _conn
    db = db or ':memory:'
    log.info('Using database {}'.format(db))
    _conn = sqlite3.connect(db, detect_types=sqlite3.PARSE_DECLTYPES)
    _conn.row_factory = sqlite3.Row

def create_tables():
    log.debug('Creating tables')
    _conn.execute("""
        CREATE TABLE IF NOT EXISTS message (
            id INTEGER PRIMARY KEY ASC,
            sender TEXT,
            recipients TEXT,
            subject TEXT,
            source BLOB,
            size INTEGER,
            type TEXT,
            created_at TIMESTAMP
        )
    """)

    _conn.execute("""
        CREATE TABLE IF NOT EXISTS message_part (
            id INTEGER PRIMARY KEY ASC,
            message_id INTEGER NOT NULL,
            cid INTEGER,
            type TEXT,
            is_attachment INTEGER,
            filename TEXT,
            charset TEXT,
            body BLOB,
            size INTEGER,
            created_at TIMESTAMP
        )
    """)

def add_message(sender, recipients, body, message):
    sql = """
        INSERT INTO message
            (sender, recipients, subject, source, type, size, created_at)
        VALUES
            (?, ?, ?, ?, ?, ?, datetime('now'))
    """

    cur = _conn.cursor()
    cur.execute(sql, (sender,
                      json.dumps(recipients),
                      message['Subject'],
                      body,
                      message.get_content_type(),
                      len(body)))
    message_id = cur.lastrowid
    # Store parts (why do we do this for non-multipart at all?!)
    parts = [message] if not message.is_multipart() else message.get_payload()
    for cid, part in enumerate(parts):
        _add_message_part(message_id, cid, part)
    _conn.commit()
    cur.close()
    log.debug('Stored message {} (parts={})'.format(message_id, len(parts)))
    # TODO: Notify websocket clients
    return message_id

def _add_message_part(message_id, cid, part):
    sql = """
        INSERT INTO message_part
            (message_id, cid, type, is_attachment, filename, charset, body, size, created_at)
        VALUES
            (?, ?, ?, ?, ?, ?, ?, ?, datetime('now'))
    """

    body = str(part)
    _conn.execute(sql, (message_id,
                        cid,
                        part.get_content_type(),
                        part.get_filename() is not None,
                        part.get_filename(),
                        part.get_content_charset(),
                        body,
                        len(body)))

def get_message(message_id):
    row = _conn.execute('SELECT * FROM message WHERE id = ?', (message_id,)).fetchone()
    if not row:
        return None
    row = dict(row)
    row['recipients'] = json.loads(row['recipients'])
    return row

def get_message_attachments(message_id):
    sql = """
        SELECT
            cid, type, filename, size
        FROM
            message_part
        WHERE
            message_id = ? AND
            is_attachment = 1
        ORDER BY
            filename ASC
    """
    return _conn.execute(sql, (message_id,)).fetchall()

def _get_message_part_types(message_id, types):
    sql = """
        SELECT
            *
        FROM
            message_part
        WHERE
            message_id = ? AND
            type IN ({}) AND
            is_attachment = 0
        LIMIT
            1
    """.format(','.join('?' * len(types)))
    return _conn.execute(sql, (message_id,) + types).fetchone()

def get_message_part_html(message_id):
    return _get_message_part_types(message_id, ('text/html', 'application/xhtml+xml'))

def get_message_part_plain(message_id):
    return _get_message_part_types(message_id, ('text/plain',))

def get_message_part_cid(message_id, cid):
    return _conn.execute('SELECT * FROM message_part WHERE id = ? AND cid = ?', (message_id, cid)).fetchone()

def _message_has_types(message_id, types):
    sql = """
        SELECT
            1
        FROM
            message_part
        WHERE
            message_id = ? AND
            is_attachment = 0 AND
            type IN ({})
        LIMIT
            1
    """.format(','.join('?' * len(types)))
    res = _conn.execute(sql, (message_id,) + types).fetchone()
    return res is not None

def message_has_html(message_id):
    return _message_has_types(message_id, ('application/xhtml+xml', 'text/html'))

def message_has_plain(message_id):
    return _message_has_types(message_id, ('text/plain',))

def get_messages():
    rows = map(dict, _conn.execute('SELECT * FROM message').fetchall())
    for row in rows:
        row['recipients'] = json.loads(row['recipients'])
    return rows

def delete_message(message_id):
    _conn.execute('DELETE FROM message WHERE id = ?', (message_id,))
    _conn.execute('DELETE FROM message_part WHERE message_id = ?', (message_id,))
    _conn.commit()
    log.debug('Deleted message {}'.format(message_id))
    # TODO: Notify websocket clients

def delete_messages():
    _conn.execute('DELETE FROM message')
    _conn.execute('DELETE FROM message_part')
    _conn.commit()
    log.debug('Deleted all messages')<commit_msg>Fix storing of mail part bodies<commit_after>from logbook import Logger
import json
import sqlite3

log = Logger(__name__)
_conn = None

def connect(db=None):
    global _conn
    db = db or ':memory:'
    log.info('Using database {}'.format(db))
    _conn = sqlite3.connect(db, detect_types=sqlite3.PARSE_DECLTYPES)
    _conn.row_factory = sqlite3.Row

def create_tables():
    log.debug('Creating tables')
    _conn.execute("""
        CREATE TABLE IF NOT EXISTS message (
            id INTEGER PRIMARY KEY ASC,
            sender TEXT,
            recipients TEXT,
            subject TEXT,
            source BLOB,
            size INTEGER,
            type TEXT,
            created_at TIMESTAMP
        )
    """)

    _conn.execute("""
        CREATE TABLE IF NOT EXISTS message_part (
            id INTEGER PRIMARY KEY ASC,
            message_id INTEGER NOT NULL,
            cid INTEGER,
            type TEXT,
            is_attachment INTEGER,
            filename TEXT,
            charset TEXT,
            body BLOB,
            size INTEGER,
            created_at TIMESTAMP
        )
    """)

def add_message(sender, recipients, body, message):
    sql = """
        INSERT INTO message
            (sender, recipients, subject, source, type, size, created_at)
        VALUES
            (?, ?, ?, ?, ?, ?, datetime('now'))
    """

    cur = _conn.cursor()
    cur.execute(sql, (sender,
                      json.dumps(recipients),
                      message['Subject'],
                      body,
                      message.get_content_type(),
                      len(body)))
    message_id = cur.lastrowid
    # Store parts (why do we do this for non-multipart at all?!)
    parts = [message] if not message.is_multipart() else message.get_payload()
    for cid, part in enumerate(parts):
        _add_message_part(message_id, cid, part)
    _conn.commit()
    cur.close()
    log.debug('Stored message {} (parts={})'.format(message_id, len(parts)))
    # TODO: Notify websocket clients
    return message_id

def _add_message_part(message_id, cid, part):
    sql = """
        INSERT INTO message_part
            (message_id, cid, type, is_attachment, filename, charset, body, size, created_at)
        VALUES
            (?, ?, ?, ?, ?, ?, ?, ?, datetime('now'))
    """

    body = part.get_payload()
    _conn.execute(sql, (message_id,
                        cid,
                        part.get_content_type(),
                        part.get_filename() is not None,
                        part.get_filename(),
                        part.get_content_charset(),
                        body,
                        len(body)))

def get_message(message_id):
    row = _conn.execute('SELECT * FROM message WHERE id = ?', (message_id,)).fetchone()
    if not row:
        return None
    row = dict(row)
    row['recipients'] = json.loads(row['recipients'])
    return row

def get_message_attachments(message_id):
    sql = """
        SELECT
            cid, type, filename, size
        FROM
            message_part
        WHERE
            message_id = ? AND
            is_attachment = 1
        ORDER BY
            filename ASC
    """
    return _conn.execute(sql, (message_id,)).fetchall()

def _get_message_part_types(message_id, types):
    sql = """
        SELECT
            *
        FROM
            message_part
        WHERE
            message_id = ? AND
            type IN ({}) AND
            is_attachment = 0
        LIMIT
            1
    """.format(','.join('?' * len(types)))
    return _conn.execute(sql, (message_id,) + types).fetchone()

def get_message_part_html(message_id):
    return _get_message_part_types(message_id, ('text/html', 'application/xhtml+xml'))

def get_message_part_plain(message_id):
    return _get_message_part_types(message_id, ('text/plain',))

def get_message_part_cid(message_id, cid):
    return _conn.execute('SELECT * FROM message_part WHERE id = ? AND cid = ?', (message_id, cid)).fetchone()

def _message_has_types(message_id, types):
    sql = """
        SELECT
            1
        FROM
            message_part
        WHERE
            message_id = ? AND
            is_attachment = 0 AND
            type IN ({})
        LIMIT
            1
    """.format(','.join('?' * len(types)))
    res = _conn.execute(sql, (message_id,) + types).fetchone()
    return res is not None

def message_has_html(message_id):
    return _message_has_types(message_id, ('application/xhtml+xml', 'text/html'))

def message_has_plain(message_id):
    return _message_has_types(message_id, ('text/plain',))

def get_messages():
    rows = map(dict, _conn.execute('SELECT * FROM message').fetchall())
    for row in rows:
        row['recipients'] = json.loads(row['recipients'])
    return rows

def delete_message(message_id):
    _conn.execute('DELETE FROM message WHERE id = ?', (message_id,))
    _conn.execute('DELETE FROM message_part WHERE message_id = ?', (message_id,))
    _conn.commit()
    log.debug('Deleted message {}'.format(message_id))
    # TODO: Notify websocket clients

def delete_messages():
    _conn.execute('DELETE FROM message')
    _conn.execute('DELETE FROM message_part')
    _conn.commit()
    log.debug('Deleted all messages')<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from django.core.urlresolvers import reverse
from django.db import models
from redactor.fields import RedactorField
from django.utils.translation import ugettext_lazy as _
from mptt.models import MPTTModel, TreeForeignKey
from sorl.thumbnail import ImageField
from django.contrib.auth.models import User, UserManager, AbstractUser
from django.conf import settings

class AppUser(AbstractUser):

    phone = models.CharField(blank=True, max_length=10, verbose_name=_('Phone'))

    image = ImageField(upload_to='users', verbose_name=_('Image'), blank=True)

    objects = UserManager()

class Base(models.Model):

    active = models.BooleanField(default=True, verbose_name=_('Active'))

    author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('Author'))

    created_at = models.DateTimeField(auto_now_add=True)

    update_at = models.DateTimeField(auto_now=True)

    class Meta:

        abstract = True

class BaseTree(MPTTModel):

    parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True, verbose_name=_('Parent'))

    active = models.BooleanField(default=True, verbose_name=_('Active'))

    author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('Author'))

    created_at = models.DateTimeField(auto_now_add=True)

    update_at = models.DateTimeField(auto_now=True)

    def get_path(self):
        if hasattr(self, 'slug'):
            return '/'.join([item.slug for item in self.get_ancestors(include_self=True)])
        else:
            return None

    def has_childs(self):
        count = self.children.count()
        return count > 0

    class Meta:
        abstract = True

class BreadCrumbsMixin(object):
    def get_breadcrumbs(self, self_url=False):
        crumbs = [{'label': item.title, 'url': item.get_absolute_url()} for item in self.get_ancestors()]
        if self_url:
            crumbs += [{'label': self.title, 'url': self.get_absolute_url()}]
        else:
            crumbs += [{'label': self.title}]
        return crumbs

class Page(BreadCrumbsMixin, BaseTree):

    title = models.CharField(max_length=500, verbose_name=_('Title'))

    slug = models.SlugField(max_length=255, unique=True, verbose_name=_('Slug'))

    text = RedactorField(blank=True, verbose_name=_('Text'))

    sort = models.IntegerField(default=500, verbose_name=_('Sort'))

    metatitle = models.CharField(max_length=2000, blank=True, verbose_name=_('MetaTitle'))

    keywords = models.CharField(max_length=2000, blank=True, verbose_name=_('Keywords'))

    description = models.CharField(max_length=2000, blank=True, verbose_name=_('Description'))

    def get_absolute_url(self):
        return reverse('main:page_detail', kwargs={'path': self.get_path()})

    def __str__(self):
        return self.title

    class MPTTMeta:

        order_insertion_by = ['sort']

    class Meta:

        verbose_name = _('Page')

        verbose_name_plural = _('Pages')

class IncludeArea(Base):

    title = models.CharField(max_length=500, verbose_name=_('Title'))

    slug = models.SlugField(max_length=255, unique=True, verbose_name=_('Slug'))

    text = RedactorField(blank=True, verbose_name=_('Text'))

    def __str__(self):
        return self.title

    class Meta:

        verbose_name = _('IncludeArea')

        verbose_name_plural = _('IncludeAreas')

class Menu(BaseTree):

    TARGET_CHOICES = (
        ('_self', _('Self window')),
        ('_blank', _('Blank window')),
    )

    title = models.CharField(max_length=255, verbose_name=_('Title'))

    link = models.CharField(max_length=2000, blank=True, verbose_name=_('Link'))

    slug = models.SlugField(max_length=255, blank=True, verbose_name=_('Slug'))

    target = models.CharField(max_length=32, blank=True, verbose_name=_('Target'), choices=TARGET_CHOICES)

    cls = models.CharField(max_length=255, blank=True, verbose_name=_('Cls'))

    sort = models.IntegerField(default=500, verbose_name=_('Sort'))

    def __str__(self):
        return self.title

    class MPTTMeta:

        order_insertion_by = ['sort']

    class Meta:

        verbose_name = _('Menu')

        verbose_name_plural = _('Menu')

class PhotoAlbum(Base):

    title = models.CharField(max_length=500, verbose_name=_('Title'))

    slug = models.SlugField(max_length=255, unique=True, verbose_name=_('Slug'))

    text = RedactorField(blank=True, verbose_name=_('Text'))

    def __str__(self):
        return self.title

    class Meta:

        verbose_name = _('PhotoAlbum')

        verbose_name_plural = _('PhotoAlbums')

class Photo(Base):

    title = models.CharField(max_length=500, verbose_name=_('Title'))

    image = ImageField(upload_to='photos', verbose_name=_('Image'))

    album = models.ForeignKey(PhotoAlbum, verbose_name=_('PhotoAlbum'))

    sort = models.IntegerField(default=500, verbose_name=_('Sort'))

    def __str__(self):
        return self.title

    class Meta:

        verbose_name = _('Photo')

        verbose_name_plural = _('Photos')
<commit_msg>модель для комментариев к текстовым страницам<commit_after># -*- coding: utf-8 -*-
from django.core.urlresolvers import reverse
from django.db import models
from django.db.models import ForeignKey
from redactor.fields import RedactorField
from django.utils.translation import ugettext_lazy as _
from mptt.models import MPTTModel, TreeForeignKey
from sorl.thumbnail import ImageField
from django.contrib.auth.models import User, UserManager, AbstractUser
from django.conf import settings

class AppUser(AbstractUser):

    phone = models.CharField(blank=True, max_length=10, verbose_name=_('Phone'))

    image = ImageField(upload_to='users', verbose_name=_('Image'), blank=True)

    objects = UserManager()

class Base(models.Model):

    active = models.BooleanField(default=True, verbose_name=_('Active'))

    author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('Author'))

    created_at = models.DateTimeField(auto_now_add=True)

    update_at = models.DateTimeField(auto_now=True)

    class Meta:

        abstract = True

class BaseTree(MPTTModel):

    parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True, verbose_name=_('Parent'))

    active = models.BooleanField(default=True, verbose_name=_('Active'))

    author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('Author'))

    created_at = models.DateTimeField(auto_now_add=True)

    update_at = models.DateTimeField(auto_now=True)

    def get_path(self):
        if hasattr(self, 'slug'):
            return '/'.join([item.slug for item in self.get_ancestors(include_self=True)])
        else:
            return None

    def has_childs(self):
        count = self.children.count()
        return count > 0

    class Meta:
        abstract = True

class BaseComment(BaseTree):

    username = models.CharField(max_length=255)

    email = models.EmailField(max_length=255)

    text = models.TextField()

    class Meta:

        abstract = True

class BreadCrumbsMixin(object):
    def get_breadcrumbs(self, self_url=False):
        crumbs = [{'label': item.title, 'url': item.get_absolute_url()} for item in self.get_ancestors()]
        if self_url:
            crumbs += [{'label': self.title, 'url': self.get_absolute_url()}]
        else:
            crumbs += [{'label': self.title}]
        return crumbs

class Page(BreadCrumbsMixin, BaseTree):

    title = models.CharField(max_length=500, verbose_name=_('Title'))

    slug = models.SlugField(max_length=255, unique=True, verbose_name=_('Slug'))

    text = RedactorField(blank=True, verbose_name=_('Text'))

    sort = models.IntegerField(default=500, verbose_name=_('Sort'))

    metatitle = models.CharField(max_length=2000, blank=True, verbose_name=_('MetaTitle'))

    keywords = models.CharField(max_length=2000, blank=True, verbose_name=_('Keywords'))

    description = models.CharField(max_length=2000, blank=True, verbose_name=_('Description'))

    def get_absolute_url(self):
        return reverse('main:page_detail', kwargs={'path': self.get_path()})

    def __str__(self):
        return self.title

    class MPTTMeta:

        order_insertion_by = ['sort']

    class Meta:

        verbose_name = _('Page')

        verbose_name_plural = _('Pages')

class IncludeArea(Base):

    title = models.CharField(max_length=500, verbose_name=_('Title'))

    slug = models.SlugField(max_length=255, unique=True, verbose_name=_('Slug'))

    text = RedactorField(blank=True, verbose_name=_('Text'))

    def __str__(self):
        return self.title

    class Meta:

        verbose_name = _('IncludeArea')

        verbose_name_plural = _('IncludeAreas')

class Menu(BaseTree):

    TARGET_CHOICES = (
        ('_self', _('Self window')),
        ('_blank', _('Blank window')),
    )

    title = models.CharField(max_length=255, verbose_name=_('Title'))

    link = models.CharField(max_length=2000, blank=True, verbose_name=_('Link'))

    slug = models.SlugField(max_length=255, blank=True, verbose_name=_('Slug'))

    target = models.CharField(max_length=32, blank=True, verbose_name=_('Target'), choices=TARGET_CHOICES)

    cls = models.CharField(max_length=255, blank=True, verbose_name=_('Cls'))

    sort = models.IntegerField(default=500, verbose_name=_('Sort'))

    def __str__(self):
        return self.title

    class MPTTMeta:

        order_insertion_by = ['sort']

    class Meta:

        verbose_name = _('Menu')

        verbose_name_plural = _('Menu')

class PhotoAlbum(Base):

    title = models.CharField(max_length=500, verbose_name=_('Title'))

    slug = models.SlugField(max_length=255, unique=True, verbose_name=_('Slug'))

    text = RedactorField(blank=True, verbose_name=_('Text'))

    def __str__(self):
        return self.title

    class Meta:

        verbose_name = _('PhotoAlbum')

        verbose_name_plural = _('PhotoAlbums')

class Photo(Base):

    title = models.CharField(max_length=500, verbose_name=_('Title'))

    image = ImageField(upload_to='photos', verbose_name=_('Image'))

    album = models.ForeignKey(PhotoAlbum, verbose_name=_('PhotoAlbum'))

    sort = models.IntegerField(default=500, verbose_name=_('Sort'))

    def __str__(self):
        return self.title

    class Meta:

        verbose_name = _('Photo')

        verbose_name_plural = _('Photos')

class PageComment(BaseComment):

    obj = ForeignKey(Page)

    class MPTTMeta:

        order_insertion_by = ['id']

    class Meta:

        verbose_name = _('PageComment')

        verbose_name_plural = _('PageComment')
<|endoftext|>


<commit_before>from django.db import models
from django.db.models import signals
# from validatedfile.fields import ValidatedFileField
from django.contrib.auth.models import User
from django.utils.text import slugify

# Receive the pre_delete signal and delete the file associated with the model instance.
from django.db.models.signals import pre_delete
from django.dispatch.dispatcher import receiver

import sys
import yaml
import os
import time
from uuid import uuid1, uuid4

from taggit.managers import TaggableManager
from host.settings import MEDIA_ROOT

from validatedfile.fields import ValidatedFileField
validatedfile_rules = [(
    [ValidatedFileField],
    [],
    {
        "content_types": ["content_types", {"default": []}],
        "max_upload_size": ["max_upload_size", {"default": 0}],
        "mime_lookup_length": ["mime_lookup_length", {"default": 4096}],
    }
)]

from south.modelsinspector import add_introspection_rules
add_introspection_rules(validatedfile_rules, ["^validatedfile\.fields\.ValidatedFileField"])

def path_for_game_file():
    def path_generator(instance, filename):
        ext = filename.split('.')[-1]
        basename = filename.split('.')[0]
        # set path.
        if instance.game_group:
            library_dir = slugify(instance.game_group.name) if instance.game_group else "ungrouped"
            path = "uploads/{library_dir}/games/".format(library_dir=library_dir)
        else:
            path = "uploads/unclaimed/" # dump problematic files where we can see them.

        # since this is going into the group directory, along with Library files, make sure the filename is unique.
        filename = "{}_{}.{}".format(basename, int(time.time()), ext)

        # return the whole path to the file
        return os.path.join(path, filename)
    return path_generator

class Game(models.Model):
    name = models.CharField(max_length=255)
    description = models.TextField(blank=True, null=True)
    game_group = models.ForeignKey("GameGroup")
    game_spec = ValidatedFileField(
                        null = True,
                        blank = True,
                        upload_to = path_for_game_file(),
                        max_upload_size = 204800, # 200KB
                        content_types = ['application/x-yaml','text/yaml','text/plain','text/plain; charset=us-ascii', 'text/plain; charset=utf-8'])
    tags = TaggableManager(blank=True)

    def slug(self):
        return slugify(self.name)

    def __unicode__(self):
        return self.name

    def save(self, *args, **kwargs):
        # create Round objects as nec. set a 'parsed' flag to true when done.
        super(Game, self).save(*args, **kwargs)

        game_yaml_file_path = MEDIA_ROOT + str(self.game_spec)
        game_yaml_file = None
        try:
            game_yaml_file = open(game_yaml_file_path, 'r')
            game_yaml = yaml.load(game_yaml_file)

            # for a first stab at game YAML validation,
            # we try to create a Round object for each Round in the uploaded file.
            # if this fails, we pass back a validation error.
            rounds = game_yaml.get('rounds')
            for i, round in enumerate(rounds):
                rnd, created = Round.objects.get_or_create(game=self, nbr=(i+1), points=value)
                if created:
                    rnd.save()

            # if we've gotten this far, note it in the db.
            self.parsed = True
            super(Game, self).save(*args, **kwargs)

        except:
            e = sys.exc_info()[0]
            print( "Error: %s" % e )

        finally:
            if (game_yaml_file):
                game_yaml_file.close()

@receiver(pre_delete, sender=Game)
def game_delete(sender, instance, **kwargs):
    # Pass false so FileField doesn't save the model.
    instance.game_spec.delete(False)

class Round(models.Model):
    game = models.ForeignKey(Game)
    nbr = models.IntegerField()
    correct_answer = models.CharField(max_length=32)
    points = models.IntegerField()

class Struct:
    def __init__(self, **entries):
        self.__dict__.update(entries)

class GameReport(models.Model):
    payload = models.TextField(blank=True,null=True)
    student = models.ForeignKey(User, unique=False)
    game = models.ForeignKey(Game, unique=False)
    created_on = models.DateTimeField(auto_now_add=True)

    def _decode_payload(self):
        args = json.loads(self.payload)
        s = Struct(**args)
        return s
    decoded_payload = property(_decode_payload)

class GameGroup(models.Model):
    name = models.CharField(max_length=255)
    games = models.ManyToManyField(Game, blank=True, null=True)
    users = models.ManyToManyField(User, blank=True, null=True, through="Membership")
    library_files = models.ManyToManyField("LibraryFile", blank=True, null=True)

    def slug(self):
        return slugify(self.name)

    def __unicode__(self):
        return self.name

class Role(models.Model):
    name = models.CharField(max_length=64)

    def __unicode__(self):
        return self.name

class Membership(models.Model):
    user = models.ForeignKey(User)
    game_group = models.ForeignKey(GameGroup)
    role = models.ForeignKey(Role)

    def __unicode__(self):
        return "{}:{}".format(self.game_group.name, self.role.name)

def path_for_media_type():
    def path_generator(instance, filename):
        ext = filename.split('.')[-1]
        # set path.
        if instance.game_group:
            library_dir = slugify(instance.game_group.name) if instance.game_group else "ungrouped"
            path = "uploads/{library_dir}/custom_{media_type}/".format(library_dir=library_dir, media_type=instance.media_type)
        else:
            path = "uploads/unclaimed/" # dump problematic files where we can see them.

        # return the whole path to the file
        return os.path.join(path, filename)
    return path_generator

class LibraryFile(models.Model):
    MEDIA_CHOICES = (
        ('js', 'js'),
    )
    media_type = models.CharField(max_length=64, choices=MEDIA_CHOICES)
    description = models.TextField(blank=True, null=True)
    game_group = models.ForeignKey(GameGroup)
    file = models.FileField(
                        null = True,
                        blank = True,
                        upload_to = path_for_media_type())

    def __unicode__(self):
        return self.file.name

@receiver(pre_delete, sender=LibraryFile)
def library_file_delete(sender, instance, **kwargs):
    # Pass false so FileField doesn't save the model.
    instance.file.delete(False)
<commit_msg>have to provide {0} field numbers for str.format() for python 2.6 on lux.<commit_after>from django.db import models
from django.db.models import signals
# from validatedfile.fields import ValidatedFileField
from django.contrib.auth.models import User
from django.utils.text import slugify

# Receive the pre_delete signal and delete the file associated with the model instance.
from django.db.models.signals import pre_delete
from django.dispatch.dispatcher import receiver

import sys
import yaml
import os
import time
from uuid import uuid1, uuid4

from taggit.managers import TaggableManager
from host.settings import MEDIA_ROOT

from validatedfile.fields import ValidatedFileField
validatedfile_rules = [(
    [ValidatedFileField],
    [],
    {
        "content_types": ["content_types", {"default": []}],
        "max_upload_size": ["max_upload_size", {"default": 0}],
        "mime_lookup_length": ["mime_lookup_length", {"default": 4096}],
    }
)]

from south.modelsinspector import add_introspection_rules
add_introspection_rules(validatedfile_rules, ["^validatedfile\.fields\.ValidatedFileField"])

def path_for_game_file():
    def path_generator(instance, filename):
        ext = filename.split('.')[-1]
        basename = filename.split('.')[0]
        # set path.
        if instance.game_group:
            library_dir = slugify(instance.game_group.name) if instance.game_group else "ungrouped"
            path = "uploads/{library_dir}/games/".format(library_dir=library_dir)
        else:
            path = "uploads/unclaimed/" # dump problematic files where we can see them.

        # since this is going into the group directory, along with Library files, make sure the filename is unique.
        filename = "{0}_{1}.{2}".format(basename, int(time.time()), ext)

        # return the whole path to the file
        return os.path.join(path, filename)
    return path_generator

class Game(models.Model):
    name = models.CharField(max_length=255)
    description = models.TextField(blank=True, null=True)
    game_group = models.ForeignKey("GameGroup")
    game_spec = ValidatedFileField(
                        null = True,
                        blank = True,
                        upload_to = path_for_game_file(),
                        max_upload_size = 204800, # 200KB
                        content_types = ['application/x-yaml','text/yaml','text/plain','text/plain; charset=us-ascii', 'text/plain; charset=utf-8'])
    tags = TaggableManager(blank=True)

    def slug(self):
        return slugify(self.name)

    def __unicode__(self):
        return self.name

    def save(self, *args, **kwargs):
        # create Round objects as nec. set a 'parsed' flag to true when done.
        super(Game, self).save(*args, **kwargs)

        game_yaml_file_path = MEDIA_ROOT + str(self.game_spec)
        game_yaml_file = None
        try:
            game_yaml_file = open(game_yaml_file_path, 'r')
            game_yaml = yaml.load(game_yaml_file)

            # for a first stab at game YAML validation,
            # we try to create a Round object for each Round in the uploaded file.
            # if this fails, we pass back a validation error.
            rounds = game_yaml.get('rounds')
            for i, round in enumerate(rounds):
                rnd, created = Round.objects.get_or_create(game=self, nbr=(i+1), points=value)
                if created:
                    rnd.save()

            # if we've gotten this far, note it in the db.
            self.parsed = True
            super(Game, self).save(*args, **kwargs)

        except:
            e = sys.exc_info()[0]
            print( "Error: %s" % e )

        finally:
            if (game_yaml_file):
                game_yaml_file.close()

@receiver(pre_delete, sender=Game)
def game_delete(sender, instance, **kwargs):
    # Pass false so FileField doesn't save the model.
    instance.game_spec.delete(False)

class Round(models.Model):
    game = models.ForeignKey(Game)
    nbr = models.IntegerField()
    correct_answer = models.CharField(max_length=32)
    points = models.IntegerField()

class Struct:
    def __init__(self, **entries):
        self.__dict__.update(entries)

class GameReport(models.Model):
    payload = models.TextField(blank=True,null=True)
    student = models.ForeignKey(User, unique=False)
    game = models.ForeignKey(Game, unique=False)
    created_on = models.DateTimeField(auto_now_add=True)

    def _decode_payload(self):
        args = json.loads(self.payload)
        s = Struct(**args)
        return s
    decoded_payload = property(_decode_payload)

class GameGroup(models.Model):
    name = models.CharField(max_length=255)
    games = models.ManyToManyField(Game, blank=True, null=True)
    users = models.ManyToManyField(User, blank=True, null=True, through="Membership")
    library_files = models.ManyToManyField("LibraryFile", blank=True, null=True)

    def slug(self):
        return slugify(self.name)

    def __unicode__(self):
        return self.name

class Role(models.Model):
    name = models.CharField(max_length=64)

    def __unicode__(self):
        return self.name

class Membership(models.Model):
    user = models.ForeignKey(User)
    game_group = models.ForeignKey(GameGroup)
    role = models.ForeignKey(Role)

    def __unicode__(self):
        return "{}:{}".format(self.game_group.name, self.role.name)

def path_for_media_type():
    def path_generator(instance, filename):
        ext = filename.split('.')[-1]
        # set path.
        if instance.game_group:
            library_dir = slugify(instance.game_group.name) if instance.game_group else "ungrouped"
            path = "uploads/{library_dir}/custom_{media_type}/".format(library_dir=library_dir, media_type=instance.media_type)
        else:
            path = "uploads/unclaimed/" # dump problematic files where we can see them.

        # return the whole path to the file
        return os.path.join(path, filename)
    return path_generator

class LibraryFile(models.Model):
    MEDIA_CHOICES = (
        ('js', 'js'),
    )
    media_type = models.CharField(max_length=64, choices=MEDIA_CHOICES)
    description = models.TextField(blank=True, null=True)
    game_group = models.ForeignKey(GameGroup)
    file = models.FileField(
                        null = True,
                        blank = True,
                        upload_to = path_for_media_type())

    def __unicode__(self):
        return self.file.name

@receiver(pre_delete, sender=LibraryFile)
def library_file_delete(sender, instance, **kwargs):
    # Pass false so FileField doesn't save the model.
    instance.file.delete(False)
<|endoftext|>


<commit_before>import os

try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO

from django.conf import settings
from django.core.files.base import File
from django.core.files.storage import Storage
from django.core.files.uploadedfile import UploadedFile
from django.core.files.uploadhandler import FileUploadHandler, \
    StopFutureHandlers
from django.core.exceptions import ImproperlyConfigured
from django.http import HttpResponse
from django.utils.encoding import smart_str, force_unicode

from google.appengine.ext.blobstore import BlobInfo, BlobKey, delete, \
    create_upload_url, BLOB_KEY_HEADER

def prepare_upload(request, url, **kwargs):
    return create_upload_url(url), {}

def serve_file(request, file, save_as, content_type, **kwargs):
    if hasattr(file, 'file') and hasattr(file.file, 'blobstore_info'):
        blobkey = file.file.blobstore_info.key()
    elif hasattr(file, 'blobstore_info'):
        blobkey = file.blobstore_info.key()
    else:
        raise ValueError("The provided file can't be served via the "
                         "Google App Engine Blobstore.")
    response = HttpResponse(content_type=content_type)
    response[BLOB_KEY_HEADER] = str(blobkey)
    if save_as:
        response['Content-Disposition'] = smart_str(u'attachment; filename=%s' % save_as)
    if file.size is not None:
        response['Content-Length'] = file.size
    return response

class BlobstoreStorage(Storage):
    """Google App Engine Blobstore storage backend"""

    def _open(self, name, mode='rb'):
        return BlobstoreFile(name, mode, self)

    def _save(self, name, content):
        name = name.replace('\\', '/')
        if hasattr(content, 'file') and hasattr(content.file, 'blobstore_info'):
            data = content.file.blobstore_info
        elif hasattr(content, 'blobstore_info'):
            data = content.blobstore_info
        else:
            raise ValueError("The App Engine storage backend only supports "
                             "BlobstoreFile instances or File instances "
                             "whose file attribute is a BlobstoreFile.")

        if isinstance(data, (BlobInfo, BlobKey)):
            # We change the file name to the BlobKey's str() value
            if isinstance(data, BlobInfo):
                data = data.key()
            return '%s/%s' % (data, name.lstrip('/'))
        else:
            raise ValueError("The App Engine Blobstore only supports "
                             "BlobInfo values. Data can't be uploaded "
                             "directly. You have to use the file upload "
                             "handler.")

    def delete(self, name):
        delete(self._get_key(name))

    def exists(self, name):
        return self._get_blobinfo(name) is not None

    def size(self, name):
        return self._get_blobinfo(name).size

    def url(self, name):
        raise NotImplementedError()

    def get_valid_name(self, name):
        return force_unicode(name).strip().replace('\\', '/')

    def get_available_name(self, name):
        return name.replace('\\', '/')

    def _get_key(self, name):
        return BlobKey(name.split('/', 1)[0])

    def _get_blobinfo(self, name):
        return BlobInfo.get(self._get_key(name))

class BlobstoreFile(File):
    def __init__(self, name, mode, storage):
        self.name = name
        self._storage = storage
        self._mode = mode
        self.blobstore_info = storage._get_blobinfo(name)

    @property
    def size(self):
        return self.blobstore_info.size

    def read(self, *args, **kwargs):
        raise NotImplementedError()

    def write(self, content):
        raise NotImplementedError()

    def close(self):
        pass

class BlobstoreFileUploadHandler(FileUploadHandler):
    """
    File upload handler for the Google App Engine Blobstore
    """

    def new_file(self, *args, **kwargs):
        super(BlobstoreFileUploadHandler, self).new_file(*args, **kwargs)
        blobkey = self.content_type_extra.get('blob-key')
        self.active = blobkey is not None
        if self.active:
            self.blobkey = BlobKey(blobkey)
            raise StopFutureHandlers()

    def receive_data_chunk(self, raw_data, start):
        """
        Add the data to the StringIO file.
        """
        if not self.active:
            return raw_data

    def file_complete(self, file_size):
        """
        Return a file object if we're activated.
        """
        if not self.active:
            return

        return BlobstoreUploadedFile(
            blobinfo=BlobInfo(self.blobkey),
            charset=self.charset)

class BlobstoreUploadedFile(UploadedFile):
    """
    A file uploaded into memory (i.e. stream-to-memory).
    """
    def __init__(self, blobinfo, charset):
        super(BlobstoreUploadedFile, self).__init__(
            blobinfo, blobinfo.filename, blobinfo.content_type, blobinfo.size,
            charset)
        self.blobstore_info = blobinfo

    def open(self, mode=None):
        pass

    def close(self):
        pass

    def chunks(self, chunk_size=None):
        self.file.seek(0)
        yield self.read()

    def multiple_chunks(self, chunk_size=None):
        # Since it's in memory, we'll never have multiple chunks.
        return False
<commit_msg>added range support to Blobstore backend. thanks to Sylvain Fourmanoit for the patch!<commit_after>import os

try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO

from django.conf import settings
from django.core.files.base import File
from django.core.files.storage import Storage
from django.core.files.uploadedfile import UploadedFile
from django.core.files.uploadhandler import FileUploadHandler, \
    StopFutureHandlers
from django.core.exceptions import ImproperlyConfigured
from django.http import HttpResponse
from django.utils.encoding import smart_str, force_unicode

from google.appengine.ext.blobstore import BlobInfo, BlobKey, delete, \
    create_upload_url, BLOB_KEY_HEADER, BLOB_RANGE_HEADER

def prepare_upload(request, url, **kwargs):
    return create_upload_url(url), {}

def serve_file(request, file, save_as, content_type, **kwargs):
    if hasattr(file, 'file') and hasattr(file.file, 'blobstore_info'):
        blobkey = file.file.blobstore_info.key()
    elif hasattr(file, 'blobstore_info'):
        blobkey = file.blobstore_info.key()
    else:
        raise ValueError("The provided file can't be served via the "
                         "Google App Engine Blobstore.")
    response = HttpResponse(content_type=content_type)
    response[BLOB_KEY_HEADER] = str(blobkey)
    response['Accept-Ranges'] = 'bytes'
    http_range = request.META.get('HTTP_RANGE')
    if http_range is not None:
        response[BLOB_RANGE_HEADER] = http_range
    if save_as:
        response['Content-Disposition'] = smart_str(u'attachment; filename=%s' % save_as)
    if file.size is not None:
        response['Content-Length'] = file.size
    return response

class BlobstoreStorage(Storage):
    """Google App Engine Blobstore storage backend"""

    def _open(self, name, mode='rb'):
        return BlobstoreFile(name, mode, self)

    def _save(self, name, content):
        name = name.replace('\\', '/')
        if hasattr(content, 'file') and hasattr(content.file, 'blobstore_info'):
            data = content.file.blobstore_info
        elif hasattr(content, 'blobstore_info'):
            data = content.blobstore_info
        else:
            raise ValueError("The App Engine storage backend only supports "
                             "BlobstoreFile instances or File instances "
                             "whose file attribute is a BlobstoreFile.")

        if isinstance(data, (BlobInfo, BlobKey)):
            # We change the file name to the BlobKey's str() value
            if isinstance(data, BlobInfo):
                data = data.key()
            return '%s/%s' % (data, name.lstrip('/'))
        else:
            raise ValueError("The App Engine Blobstore only supports "
                             "BlobInfo values. Data can't be uploaded "
                             "directly. You have to use the file upload "
                             "handler.")

    def delete(self, name):
        delete(self._get_key(name))

    def exists(self, name):
        return self._get_blobinfo(name) is not None

    def size(self, name):
        return self._get_blobinfo(name).size

    def url(self, name):
        raise NotImplementedError()

    def get_valid_name(self, name):
        return force_unicode(name).strip().replace('\\', '/')

    def get_available_name(self, name):
        return name.replace('\\', '/')

    def _get_key(self, name):
        return BlobKey(name.split('/', 1)[0])

    def _get_blobinfo(self, name):
        return BlobInfo.get(self._get_key(name))

class BlobstoreFile(File):
    def __init__(self, name, mode, storage):
        self.name = name
        self._storage = storage
        self._mode = mode
        self.blobstore_info = storage._get_blobinfo(name)

    @property
    def size(self):
        return self.blobstore_info.size

    def read(self, *args, **kwargs):
        raise NotImplementedError()

    def write(self, content):
        raise NotImplementedError()

    def close(self):
        pass

class BlobstoreFileUploadHandler(FileUploadHandler):
    """
    File upload handler for the Google App Engine Blobstore
    """

    def new_file(self, *args, **kwargs):
        super(BlobstoreFileUploadHandler, self).new_file(*args, **kwargs)
        blobkey = self.content_type_extra.get('blob-key')
        self.active = blobkey is not None
        if self.active:
            self.blobkey = BlobKey(blobkey)
            raise StopFutureHandlers()

    def receive_data_chunk(self, raw_data, start):
        """
        Add the data to the StringIO file.
        """
        if not self.active:
            return raw_data

    def file_complete(self, file_size):
        """
        Return a file object if we're activated.
        """
        if not self.active:
            return

        return BlobstoreUploadedFile(
            blobinfo=BlobInfo(self.blobkey),
            charset=self.charset)

class BlobstoreUploadedFile(UploadedFile):
    """
    A file uploaded into memory (i.e. stream-to-memory).
    """
    def __init__(self, blobinfo, charset):
        super(BlobstoreUploadedFile, self).__init__(
            blobinfo, blobinfo.filename, blobinfo.content_type, blobinfo.size,
            charset)
        self.blobstore_info = blobinfo

    def open(self, mode=None):
        pass

    def close(self):
        pass

    def chunks(self, chunk_size=None):
        self.file.seek(0)
        yield self.read()

    def multiple_chunks(self, chunk_size=None):
        # Since it's in memory, we'll never have multiple chunks.
        return False
<|endoftext|>


<commit_before>import datetime
from django.db import models

class Paste(models.Model):
    ep_id = models.IntegerField(primary_key=True)
    ep_link = models.URLField(null=True)
    ep_json = models.TextField(null=True)
    ep_kind = models.CharField(max_length=100, null=True)
    ep_market_id = models.IntegerField(null=True)
    ep_market_name = models.CharField(max_length=100, null=True)
    ep_totals_buy = models.BigIntegerField(null=True)
    ep_totals_sell = models.BigIntegerField(null=True)
    ep_totals_volume = models.BigIntegerField(null=True)
    character = models.ManyToManyField('main.Character')
    created = models.DateTimeField(editable=False, null=True)

    def __unicode__(self):
        return 'Paste {}'.format(self.ep_id)

class Character(models.Model):
    name = models.CharField(max_length=100)

    def __unicode__(self):
        return self.name
<commit_msg>added blueloot & salvage total value fields. value fields use floats now.<commit_after>import datetime
from django.db import models

class Paste(models.Model):
    ep_id = models.IntegerField(primary_key=True)
    ep_link = models.URLField(null=True)
    ep_json = models.TextField(null=True)
    ep_kind = models.CharField(max_length=100, null=True)
    ep_market_id = models.IntegerField(null=True)
    ep_market_name = models.CharField(max_length=100, null=True)
    ep_totals_buy = models.FloatField(null=True)
    ep_totals_sell = models.FloatField(null=True)
    ep_totals_volume = models.BigIntegerField(null=True)
    character = models.ManyToManyField('main.Character')
    created = models.DateTimeField(editable=False, null=True)
    blue_loot_value = models.FloatField(null=True)
    salvage_value = models.FloatField(null=True)

    def __unicode__(self):
        return 'Paste {}'.format(self.ep_id)

class Character(models.Model):
    name = models.CharField(max_length=100)

    def __unicode__(self):
        return self.name
<|endoftext|>