Exemple #1
0
def install():
    Base.metadata.create_all(Session().bind)

    data = [
        ("Chicago", "United States", ("60601", "60602", "60603", "60604")),
        ("Montreal", "Canada", ("H2S 3K9", "H2B 1V4", "H7G 2T8")),
        ("Edmonton", "Canada", ("T5J 1R9", "T5J 1Z4", "T5H 1P6")),
        ("New York", "United States", ("10001", "10002", "10003", "10004", "10005", "10006")),
        ("San Francisco", "United States", ("94102", "94103", "94104", "94105", "94107", "94108")),
    ]

    countries = {}
    all_post_codes = []
    for city, country, postcodes in data:
        try:
            country = countries[country]
        except KeyError:
            countries[country] = country = Country(country)

        city = City(city, country)
        pc = [PostalCode(code, city) for code in postcodes]
        Session.add_all(pc)
        all_post_codes.extend(pc)

    for i in xrange(1, 51):
        person = Person(
            "person %.2d" % i,
            Address(street="street %.2d" % i, postal_code=all_post_codes[random.randint(0, len(all_post_codes) - 1)]),
        )
        Session.add(person)

    Session.commit()

    # start the demo fresh
    Session.remove()
Exemple #2
0
def load_word_info_from_feed(feed_url=None):
    '''Load word information (e.g. notes) from a set of entries supplied via an
    (atom) feed.

    @parm feed_url: if not provided using value from config
        "word_of_the_day.feed"
    '''
    if not feed_url:
        from pylons import config
        cfg_key = 'word_of_the_day.feed'
        feed_url = config.get(cfg_key, '')
    if not feed_url:
        msg = 'Need a feed_url - not specified in config (%s)' % cfg_key
        raise ValueError(msg)
    # do not make a global dependency
    import feedparser
    feed = feedparser.parse(feed_url)
    for idx, entry in enumerate(feed.entries):
        out = load_entry(entry)
        if idx == 0:
            word = out[0].object_id
            # update current wotd to latest entry (first one)
            setting = KeyValue.upsert(
                [u'config', u'word_of_the_day', u'current'], value=word)
            Session.commit()
Exemple #3
0
 def delete_all(self):
     for obj in [
             Posting, Transaction, Account, Slice, KeyValue,
             EnumerationValue, Key
     ]:
         Session.query(obj).delete()
     Session.commit()
     Session.remove()
Exemple #4
0
def load_entry(entry):
    '''Load a feedparser entry into KeyValue objects.
    
    @return: list of KeyValue objects created.
    '''
    name = entry.title.lower().strip()
    # may be of form "Word of the Day: Baker"
    if ':' in name:
        name = name.split(':')[1].strip()
    ns = u'word'
    objid = name
    notes = entry.content[0]['value']
    key=u'notes'
    # upsert ...
    # does not work ...
    # kv = KeyValue(ns=ns, object_id=objid, key=key, value=notes)
    kv = KeyValue.upsert([ns,objid,key], value=notes)
    Session.commit()
    return [kv]
Exemple #5
0
def load_entry(entry):
    '''Load a feedparser entry into KeyValue objects.
    
    @return: list of KeyValue objects created.
    '''
    name = entry.title.lower().strip()
    # may be of form "Word of the Day: Baker"
    if ':' in name:
        name = name.split(':')[1].strip()
    ns = u'word'
    objid = name
    notes = entry.content[0]['value']
    key = u'notes'
    # upsert ...
    # does not work ...
    # kv = KeyValue(ns=ns, object_id=objid, key=key, value=notes)
    kv = KeyValue.upsert([ns, objid, key], value=notes)
    Session.commit()
    return [kv]
def install():
    Base.metadata.create_all(Session().bind)

    data = [('Chicago', 'United States', ('60601', '60602', '60603', '60604')),
            ('Montreal', 'Canada', ('H2S 3K9', 'H2B 1V4', 'H7G 2T8')),
            ('Edmonton', 'Canada', ('T5J 1R9', 'T5J 1Z4', 'T5H 1P6')),
            ('New York', 'United States', ('10001', '10002', '10003', '10004',
                                           '10005', '10006')),
            ('San Francisco', 'United States', ('94102', '94103', '94104',
                                                '94105', '94107', '94108'))]

    countries = {}
    all_post_codes = []
    for city, country, postcodes in data:
        try:
            country = countries[country]
        except KeyError:
            countries[country] = country = Country(country)

        city = City(city, country)
        pc = [PostalCode(code, city) for code in postcodes]
        Session.add_all(pc)
        all_post_codes.extend(pc)

    for i in xrange(1, 51):
        person = Person(
            "person %.2d" % i,
            Address(street="street %.2d" % i,
                    postal_code=all_post_codes[random.randint(
                        0,
                        len(all_post_codes) - 1)]))
        Session.add(person)

    Session.commit()

    # start the demo fresh
    Session.remove()
Exemple #7
0
def load_word_info_from_feed(feed_url=None):
    '''Load word information (e.g. notes) from a set of entries supplied via an
    (atom) feed.

    @parm feed_url: if not provided using value from config
        "word_of_the_day.feed"
    '''
    if not feed_url:
        from pylons import config
        cfg_key = 'word_of_the_day.feed'
        feed_url = config.get(cfg_key, '')
    if not feed_url:
        msg = 'Need a feed_url - not specified in config (%s)' % cfg_key
        raise ValueError(msg)
    # do not make a global dependency
    import feedparser
    feed = feedparser.parse(feed_url)
    for idx, entry in enumerate(feed.entries):
        out = load_entry(entry)
        if idx == 0:
            word = out[0].object_id
            # update current wotd to latest entry (first one)
            setting = KeyValue.upsert([u'config',u'word_of_the_day',u'current'], value=word)
            Session.commit()
Exemple #8
0
    links = [a for a in rhscol.getiterator("a")]
    if len(links) != 3 or "Older" not in links[1].text or "Newer" not in links[2].text:
        print "Cant find older and newer links here, backing up"
        oldurl = page.url
        match = re.search("mbl_hs:(\d+),mbl_he:(\d+),mbl_rs:(\d+),mbl_re:(\d+)", oldurl)
        mbl_hs = int(match.group(1)) + 600
        mbl_he = int(match.group(2)) + 600
        mbl_rs = int(match.group(3)) + 600
        mbl_re = int(match.group(4)) + 600
        url = oldurl.replace(
            match.group(0),
            "mbl_hs:" + str(mbl_hs) + ",mbl_he:" + str(mbl_he) + ",mbl_rs:" + str(mbl_rs) + ",mbl_re:" + str(mbl_re),
        )
        lasturl = oldurl
        time.sleep(10)
        continue
    olderurl = u"http://www.google.com" + links[1].attrib["href"]
    newerurl = u"http://www.google.com" + links[2].attrib["href"]
    page = Page(url, html, numresults, olderurl, newerurl)
    Session.add(page)
    Session.commit()
    lasturl = url
    url = newerurl
    for rtdm in CSSSelector("span.rtdm")(doc):
        td, date = [text for text in rtdm.itertext()]
        day = datetime.strptime(date, "%b %d, %Y")
        if day > endtime:
            print "Quitting, " + str(day) + " > " + str(endtime)
            exit()
    time.sleep(10)
Exemple #9
0
class Inkcut(Application):
    """
    Inkcut application, creates inkcut.ui and controls job, material, 
    and device interaction.
    """
    
    def __init__(self):
        """Load initial application settings from database """
        Application.__init__(self)
        
        # setup the database session
        database = 'sqlite:///%s'%os.path.join(APP_DIR,config.get('Inkcut','database_dir'),config.get('Inkcut','database_name'))
        log.info("Database: %s"%database)
        engine = create_engine(database)
        Session.configure(bind=engine)
        self.session = Session()
        self.job = None
        self._flags = {'block_callbacks':True}
    
    # Builds the Inkcut user interface when Inkcut.run() is called
    def run(self, filename=None):
        builder = Gtk.Builder()
        builder.add_from_file(os.path.join(APP_DIR,'ui','inkcut.ui'))
        window = builder.get_object('inkcut')
            
        # Save any widgets needed later into groups
        self.add_widgets(builder,'job-dependent',['toolbutton3','toolbutton5','toolbutton6','box21','box9','box11','box3','box15','box25','box28','plot-order','box17','menu-file-print-preview','menu-file-print','menu-edit-undo','menu-edit-redo','gtk-zoom-fit','gtk-zoom-in','gtk-zoom-out','menu-file-save-as','menu-file-save'])
        self.add_widgets(builder,'inkcut',['inkcut','devices','statusbar','preview','scale-lock-box','scale-x-label','spinner'])
        self.add_widgets(builder,'graphic-properties',['graphic-width','graphic-height','graphic-scale-x','graphic-scale-y','graphic-scale-lock','graphic-rotation','graphic-rotate-to-save','graphic-weedline-enable','graphic-weedline-padding'])
        self.add_widgets(builder,'plot-properties',['plot-width','plot-height','plot-copies','plot-weedline-enable','plot-weedline-padding','plot-col-spacing','plot-row-spacing','plot-position-x','plot-position-y','plot-feed','plot-feed-distance'])
        self.add_widgets(builder,'material',['materials'])
        
        
        # Connect signals and invoke any UI setup
        builder.connect_signals(self)

        model = ['0 Degrees Clockwise','90 Degrees Clockwise','180 Degrees Clockwise','270 Degrees Clockwise']
        combobox = builder.get_object('graphic-rotation')
        self.set_model_from_list(combobox,model)
        combobox.set_active(0)

        model = ['One Copy at a Time','Best Tracking','Shortest Path']
        combobox = builder.get_object('plot-order')
        self.set_model_from_list(combobox,model)
        combobox.set_active(0)

        # Based on SQL Table: id, name, cost, width, length, margin_top, margin_right, margin_bottom, margin_left, velocity, force, color
        active = 0
        materials = Gtk.ListStore(int,str)
        for m in self.session.query(Material).all():
            materials.append([m.id,m.name])
            if m.id == int(config.get('Inkcut','default_device')):
                active = len(materials)
        combobox = self.get_widget('material','materials')
        combobox.set_model(materials)
        cell = Gtk.CellRendererText()
        combobox.pack_start(cell, True)
        combobox.add_attribute(cell, 'text', 1)  
        combobox.set_active(active)

        
        model = []
        device_active_index = 0
        for device in Device.get_printers():
            name = device.name
            if device.id == int(config.get('Inkcut','default_device')):
                name += " (default)"
                device_active_index = len(model)
            model.append(name)
            log.info(name) 
        combobox = builder.get_object('devices')
        self.set_model_from_list(combobox,model)
        combobox.set_active(device_active_index)
        
        
        
        # Init Accelerators
        accel_group = builder.get_object('accelgroup1')
        for action in builder.get_object('actiongroup1').list_actions():
            action.set_accel_group(accel_group)
            action.connect_accelerator()
        window.add_accel_group(accel_group)

        # Show the widgets
        self._update_sensitivity()
        window.show_all()
        self.flash("",indicator=False)
        
        # Fix!
        self._flags['block_callbacks']=False
        self.add_window(window,'inkcut')
        self.on_graphic_scale_lock_toggled(self.get_widget('graphic-properties','graphic-scale-lock'))
        # From command line arguments
        if filename is not None and os.path.isfile(filename):
            self.create_job(filename)
            
        Gtk.main()

    # ===================================== Plot Callbacks ===============================================
    @callback
    def on_plot_feed_distance_changed(self,radio,data=None):
        self.flash("Saving the plot feeding settings...",indicator=True)
        feed = self.get_widget('plot-properties','plot-feed').get_active()
        if feed:
            d = self.unit_to(self.get_widget('plot-properties','plot-feed-distance').get_value())
            pos = (0,d)
            if self.job.plot.get_rotation() == 90:
                pos = (d,0) 
            self.job.set_property('plot','finish_position',pos)
        else:
            self.job.set_property('plot','finish_position',(0,0))
        GObject.timeout_add(1000,self.flash,"")

    @callback
    def on_plot_copies_changed(self,adjustment,data=None):
        """Set's the plot's copies to the adjustment value. """
        n = int(adjustment.get_value())
        self.flash("Setting the number of copies to %s..."%n,indicator=True)
        GObject.idle_add(self.job.plot.set_copies,n)
        GObject.idle_add(self._update_preview)
        
    @callback
    def on_stack_reset_activated(self,button, data=None):
        """Sets the graphic-copies to 1"""
        self.get_widget('plot-properties','plot-copies').set_value(1)
        # Preview updated by on_plot_copies_changed

    @callback
    def on_stack_add_activated(self,button, data=None):
        """Adds a full stack of copies"""
        stack = self.job.plot.get_stack_size_x()
        copies = self.job.plot.get_copies()
        self.get_widget('plot-properties','plot-copies').set_value(stack*(copies/stack+1))
        # Preview updated by on_plot_copies_changed

    @callback
    def on_plot_spacing_x_changed(self,adjustment,data=None):
        x = self.unit_to(adjustment.get_value())
        if self.get_widget('plot-properties','plot-copies').get_value() > 1:
            msg = "Updating the column spacing..."
        else:
            msg = "Saving the plot column spacing..."
        self.flash(msg,indicator=True)
        GObject.idle_add(self.job.plot.set_spacing,x,None)
        GObject.idle_add(self._update_preview)

    @callback
    def on_plot_spacing_y_changed(self,adjustment,data=None):
        y = self.unit_to(adjustment.get_value())
        if self.get_widget('plot-properties','plot-copies').get_value() > 1:
            msg = "Updating the row spacing..."
        else:
            msg = "Saving the plot row spacing..."
        self.flash(msg,indicator=True)
        GObject.idle_add(self.job.plot.set_spacing,None,y)
        GObject.idle_add(self._update_preview)        

    @callback
    def on_plot_position_x_changed(self,widget,data=None):
        x = self.unit_to(widget.get_value())
        pos = self.job.plot.get_position()
        self.flash("Moving the plot to (%s,%s)"%(x,pos[1]),indicator=True)
        GObject.idle_add(self.job.plot.set_position,x,pos[1])
        GObject.idle_add(self._update_preview)

    @callback
    def on_plot_position_y_changed(self,widget,data=None):
        y = self.unit_to(widget.get_value())
        pos = self.job.plot.get_position()
        self.flash("Moving the plot to (%s,%s)"%(pos[0],y),indicator=True)
        GObject.idle_add(self.job.plot.set_position,pos[0],y)
        GObject.idle_add(self._update_preview)

    @callback
    def on_plot_center_x_toggled(self,checkbox,data=None):
        enabled = checkbox.get_active()
        if enabled:
            msg = "Centering the plot horizontally..."
        else:
            msg = "Moving the plot to the horizontal start..."
        self.flash(msg,indicator=True)
        GObject.idle_add(self.job.plot.set_align_center_x,enabled)
        GObject.idle_add(self._update_plot_ui)

    @callback
    def on_plot_center_y_toggled(self,checkbox,data=None):
        enabled = checkbox.get_active()
        if enabled:
            msg = "Centering the plot vertically..."
        else:
            msg = "Moving the plot to the vertical start..."
        self.flash(msg,indicator=True)
        GObject.idle_add(self.job.plot.set_align_center_y,enabled)
        GObject.idle_add(self._update_plot_ui)

    @callback
    def on_plot_weedline_toggled(self,checkbox,data=None):
        enabled = checkbox.get_active()
        if enabled:
            msg = "Adding a weedline to the plot..."
        else:
            msg = "Removing the plot weedline..."
        self.flash(msg,indicator=True)
        GObject.idle_add(self.job.plot.set_weedline,enabled)
        GObject.idle_add(self._update_preview)

    @callback
    def on_plot_weedline_padding_changed(self,adjustment,data=None):
        if self.get_widget('plot-properties','plot-weedline-enable').get_active():
            msg = "Updating the plot weedline padding..."
        else:
            msg = "Saving the plot weedline padding..."
        self.flash(msg,indicator=True)
        GObject.idle_add(self.job.plot.set_weedline_padding,self.unit_to(adjustment.get_value()))
        GObject.idle_add(self._update_preview)
    
    # ===================================== Graphic Callbacks ===============================================
    @callback
    def on_graphic_width_changed(self,adjustment,data=None):
        # Calculate new scale
        cur_w = self.job.plot.graphic.get_width()
        new_w = float(self.unit_to(adjustment.get_value()))
        sx,sy = self.job.plot.graphic.get_scale()
        sx = new_w/cur_w*sx
        # Updated in on_graphic_scale_x_changed callback
        self.get_widget('graphic-properties','graphic-scale-x').set_value(sx)
        
    @callback
    def on_graphic_height_changed(self,adjustment,data=None):
        # Calculate new scale
        cur = self.job.plot.graphic.get_height()
        new = float(self.unit_to(adjustment.get_value()))
        sx,sy = self.job.plot.graphic.get_scale()
        s = new/cur*sy
        # Updated in on_graphic_scale_x_changed callback
        self.get_widget('graphic-properties','graphic-scale-y').set_value(s)

    @callback
    def on_graphic_scale_y_changed(self,adjustment,data=None):
        sy = adjustment.get_value()
        if self.get_widget('graphic-properties','graphic-scale-lock').get_active():
            sx = sy
        else:
            sx = self.get_widget('graphic-properties','graphic-scale-x').get_value()
        GObject.idle_add(self.job.plot.graphic.set_scale,sx,sy)
        GObject.idle_add(self._update_ui)
        
    @callback
    def on_graphic_scale_x_changed(self,adjustment,data=None):
        sx = adjustment.get_value()
        if self.get_widget('graphic-properties','graphic-scale-lock').get_active():
            sy = sx
        else:
            sy = self.get_widget('graphic-properties','graphic-scale-y').get_value()
        GObject.idle_add(self.job.plot.graphic.set_scale,sx,sy)
        GObject.idle_add(self._update_ui)

    @callback
    def on_graphic_rotate_to_save_toggled(self,checkbox,data=None):
        self.flash("Checking and updating...",indicator=True)
        GObject.idle_add(self.job.plot.set_auto_rotate,checkbox.get_active())
        GObject.idle_add(self._update_preview)
        
    @callback
    def on_graphic_weedline_padding_changed(self,adjustment,data=None):
        if self.get_widget('graphic-properties','graphic-weedline-enable').get_active():
            msg = "Updating the graphic weedline padding..."
        else:
            msg = "Saving the graphic weedline padding..."
        self.flash(msg,indicator=True)
        GObject.idle_add(self.job.plot.graphic.set_weedline_padding,self.unit_to(adjustment.get_value()))
        GObject.idle_add(self._update_graphic_ui)
        
    @callback
    def on_graphic_weedline_toggled(self,checkbox,data=None):
        enabled = checkbox.get_active()
        if enabled:
            msg = "Adding a weedline to the graphic..."
        else:
            msg = "Removing the graphic weedline..."
        self.flash(msg,indicator=True)
        GObject.idle_add(self.job.plot.graphic.set_weedline,enabled)
        GObject.idle_add(self._update_preview)
        
    @callback
    def on_graphic_mirror_x_toggled(self,checkbox,data=None):
        enabled = checkbox.get_active()
        if enabled:
            msg = "Mirroring graphic about the y-axis..."
        else:
            msg = "Returning graphic to original mirror state..."
        self.flash(msg,indicator=True)
        GObject.idle_add(self.job.plot.graphic.set_mirror_x,enabled)
        GObject.idle_add(self._update_preview)

    @callback
    def on_graphic_mirror_y_toggled(self,checkbox,data=None):
        enabled = checkbox.get_active()
        if enabled:
            msg = "Mirroring graphic about the x-axis..."
        else:
            msg = "Returning graphic to original mirror state..."
        self.flash(msg,indicator=True)
        GObject.idle_add(self.job.plot.graphic.set_mirror_y,enabled)
        GObject.idle_add(self._update_preview)
        
    @callback
    def on_graphic_scale_lock_toggled(self,checkbox,data=None):
        if checkbox.get_active():
            self.get_widget('inkcut','scale-x-label').set_text("Scale:")
            self.get_widget('inkcut','scale-lock-box').hide()
            if self.job is not None:
                s = self.get_widget('graphic-properties','graphic-scale-x').get_value()
                self.get_widget('graphic-properties','graphic-scale-y').set_value(s)
        else:
            self.get_widget('inkcut','scale-x-label').set_text("Scale - X:")
            self.get_widget('inkcut','scale-lock-box').show()

    @callback
    def on_graphic_rotation_changed(self, combobox, data=None):
        degrees = combobox.get_active()*90
        self.flash("Setting graphic rotation to %s..."%degrees,indicator=True)
        GObject.idle_add(self.job.plot.graphic.set_rotation,degrees)
        GObject.idle_add(self._update_graphic_ui)
    
    
    # ===================================== File Menu Callbacks ===============================================
    @callback
    def on_job_review_activated(self,action,data=None):
        self.job.update_properties()
        builder = Gtk.Builder()
        builder.add_from_file(os.path.join(APP_DIR,'ui','plot.ui'))
        dialog = builder.get_object('dialog1')
        builder.connect_signals(self)
        dialog.show_all()
        dialog.run()
        dialog.destroy()

    @callback
    def on_job_submit_activated(self,action,data=None):
        self.job.update_properties()
        GObject.idle_add(self.run_export_plugin)

    def run_export_plugin(self):
        # Write the job to a file
        tmp = tempfile.NamedTemporaryFile(suffix=".svg",delete=False)
        tmp.file.write(self.job.plot.get_xml())
        svg = tmp.name
        tmp.close()

        # Get the current device
        name = self.get_combobox_active_text(self.get_widget('inkcut','devices'))
        #device = self.session.query(Device).filter(Device.name==name).first()
        device = Device.get_printer_by_name(name)
        log.info(device)
        # Init the export plugin
        # TODO: Gather plugins here.... let user select...
        plugins = [HPGL.Import(),HPGL.Export()]
        plugin_found = False
        for plugin in plugins:
            if plugin.mode.lower() == "export":
                if str(device.command_language.lower()) in plugin.filetypes:
                    plugin_found = True
                    break
        if plugin_found == False:
            msg = Gtk.MessageDialog(type=Gtk.MessageType.ERROR,
                buttons=Gtk.ButtonsType.OK,
                message_format="No plugins found for the command language:%s."%device.command_language)
            msg.format_secondary_text("Please make sure the plugins for this device are installed.\n If the problem persists, contact the developer.")
            msg.run()
            msg.destroy()
            raise Exception("Error, no plugin found for that command language...")

        # Initialize the plugin then run it
        # TODO: put everything needed here...
        plugin.export_init(plot=self.job.get_properties('plot'),
            device={
                'cutting_overlap':(10,False)
                })
        plugin.input = svg
        plugin.run()
        device.submit(plugin.output)

        # Cleanup
        os.remove(svg)
    
    def on_file_save_action_activated(self,widget,data=None):
        self.flash("Saving %s into the Job database..."%(self.job.name),indicator=True)
        self.job.update_properties()
        self.get_window('inkcut').set_title("%s - Inkcut"%self.job.name)
        self.session.commit()
        GObject.timeout_add(1000,self.flash,"")
        
    def create_job(self,filename,**kwargs):
        """Create a job and try to set the source. Returns bool success."""
        job = Job(**kwargs)
        # Get the default material
        job.material = self.get_material()
        try:
            job.set_source(filename)
            self.job = job
            self.session.add(self.job)
            msg = 'Loaded %s'%os.path.basename(job.name or 'File')
            self.get_window('inkcut').set_title("*%s - Inkcut"%job.name)
            self.flash(msg)
            self.on_plot_feed_distance_changed(self.get_widget('plot-properties','plot-feed'))
            self._update_ui()
            return False
        except Exception, err:
            # update the ui with job info
            log.debug(traceback.format_exc())
            msg = Gtk.MessageDialog(type=Gtk.MessageType.ERROR,
                buttons=Gtk.ButtonsType.OK,
                message_format="Issue loading file")
            msg.format_secondary_text(err)
            msg.run()
            msg.destroy()
            return False
        except:
Exemple #10
0
def syncdb():
    from meta import Base, engine, Session
    Base.metadata.drop_all(engine)
    Base.metadata.create_all(engine)
    #init data base
    #init perm
    perm_admin = Permission('can_view_admin')
    perm_admin_edit = Permission('can_edit_admin')
    perm_leader = Permission('can_decide')
    #init role
    role_admin = Role('admin')
    role_mem = Role('member')
    role_leader = Role('leader')
    #init type
    utypea = UserType('memberA', 95, 100)
    utypeb = UserType('memberB', 90, 150)
    utypec = UserType('memberC', 85, 200)
    #init user
    user = User('sheimi', 'zhang')
    nuser = User('shaymin', 'zhang')
    session = Session()
    session.add_all([role_admin, role_mem, role_leader, user, nuser])
    session.commit()
    #config relation
    role_admin.perms.append(perm_admin)
    role_leader.perms.append(perm_leader)
    role_leader.perms.append(perm_admin)
    role_admin.perms.append(perm_admin_edit)
    user.roles.append(role_admin)
    nuser.roles.append(role_leader)
    nuser.usertype = utypea
    session.commit()

    dt1 = DessertType('Cake')
    dt2 = DessertType('Ice Cream')
    dt3 = DessertType('Fruit')
    session.add_all([dt1, dt2, dt3])
    session.commit()

    d0 = Dessert('Goblet')
    d1 = Dessert('Lemon')
    d2 = Dessert('Buttermilk')
    d3 = Dessert('Chocolate')
    d4 = Dessert('Fruit')
    d5 = Dessert('Valentine')
    d6 = Dessert('Lemon Cake')
    d7 = Dessert('Exotic Fruits')
    d8 = Dessert('Fresh Fruit')
    d9 = Dessert('Chocolate Ice')

    d0.des, d0.type_id = 'This is Description ~~~~~~~', 2
    d1.des, d1.type_id = 'This is Description ~~~~~~~', 3
    d2.des, d2.type_id = 'This is Description ~~~~~~~', 1
    d3.des, d3.type_id = 'This is Description ~~~~~~~', 1
    d4.des, d4.type_id = 'This is Description ~~~~~~~', 3
    d5.des, d5.type_id = 'This is Description ~~~~~~~', 1
    d6.des, d6.type_id = 'This is Description ~~~~~~~', 1
    d7.des, d7.type_id = 'This is Description ~~~~~~~', 3
    d8.des, d8.type_id = 'This is Description ~~~~~~~', 3
    d9.des, d9.type_id = 'This is Description ~~~~~~~', 2

    d0.img = '13569b64-b9e3-4c3a-8a1d-5f794a723d8c'
    d1.img = '83289d63-b49b-4d70-b47a-08d43cdd940e'
    d2.img = 'adc15f11-3f8c-4e33-aba3-a199d2d47da9'
    d3.img = '3426bba5-03e2-4c46-bbd3-dfc7afdbe372'
    d4.img = '4ddc429e-c202-4fbe-8481-59738bc29a88'
    d5.img = '359e9e89-a6f9-44ca-bbef-46e49a490d5a'
    d6.img = '59465deb-26e8-493c-ba40-5c4b96362594'
    d7.img = '59e46ac2-0193-4f57-ae10-3c00a1bf2d3b'
    d8.img = 'c549125d-0f4f-417a-9813-7ea208573681'
    d9.img = '2c70a62e-a09c-4b55-906b-ba7f4bba04e8'

    session.add_all([d0, d1, d2, d3, d4, d5, d6, d7, d8, d9])
    session.commit()
    decision = Decision(content="test", title="title")
    decision.add()

    d = Dessert.get_all()
Exemple #11
0
 def create(cls, id):
     f = Foo(id=id)
     Session.add(f)
     Session.commit()
     return f
Exemple #12
0
class Inkcut(Application):
    """
    Inkcut application, creates inkcut.ui and controls job, material, 
    and device interaction.
    """
    def __init__(self):
        """Load initial application settings from database """
        Application.__init__(self)

        # setup the database session
        database = 'sqlite:///%s' % os.path.join(
            APP_DIR, config.get('Inkcut', 'database_dir'),
            config.get('Inkcut', 'database_name'))
        log.info("Database: %s" % database)
        engine = create_engine(database)
        Session.configure(bind=engine)
        self.session = Session()
        self.job = None
        self._flags = {'block_callbacks': True}

    # Builds the Inkcut user interface when Inkcut.run() is called
    def run(self, filename=None):
        builder = Gtk.Builder()
        builder.add_from_file(os.path.join(APP_DIR, 'ui', 'inkcut.ui'))
        window = builder.get_object('inkcut')

        # Save any widgets needed later into groups
        self.add_widgets(builder, 'job-dependent', [
            'toolbutton3', 'toolbutton5', 'toolbutton6', 'box21', 'box9',
            'box11', 'box3', 'box15', 'box25', 'box28', 'plot-order', 'box17',
            'menu-file-print-preview', 'menu-file-print', 'menu-edit-undo',
            'menu-edit-redo', 'gtk-zoom-fit', 'gtk-zoom-in', 'gtk-zoom-out',
            'menu-file-save-as', 'menu-file-save'
        ])
        self.add_widgets(builder, 'inkcut', [
            'inkcut', 'devices', 'statusbar', 'preview', 'scale-lock-box',
            'scale-x-label', 'spinner'
        ])
        self.add_widgets(builder, 'graphic-properties', [
            'graphic-width', 'graphic-height', 'graphic-scale-x',
            'graphic-scale-y', 'graphic-scale-lock', 'graphic-rotation',
            'graphic-rotate-to-save', 'graphic-weedline-enable',
            'graphic-weedline-padding'
        ])
        self.add_widgets(builder, 'plot-properties', [
            'plot-width', 'plot-height', 'plot-copies', 'plot-weedline-enable',
            'plot-weedline-padding', 'plot-col-spacing', 'plot-row-spacing',
            'plot-position-x', 'plot-position-y', 'plot-feed',
            'plot-feed-distance'
        ])
        self.add_widgets(builder, 'material', ['materials'])

        # Connect signals and invoke any UI setup
        builder.connect_signals(self)

        model = [
            '0 Degrees Clockwise', '90 Degrees Clockwise',
            '180 Degrees Clockwise', '270 Degrees Clockwise'
        ]
        combobox = builder.get_object('graphic-rotation')
        self.set_model_from_list(combobox, model)
        combobox.set_active(0)

        model = ['One Copy at a Time', 'Best Tracking', 'Shortest Path']
        combobox = builder.get_object('plot-order')
        self.set_model_from_list(combobox, model)
        combobox.set_active(0)

        # Based on SQL Table: id, name, cost, width, length, margin_top, margin_right, margin_bottom, margin_left, velocity, force, color
        active = 0
        materials = Gtk.ListStore(int, str)
        for m in self.session.query(Material).all():
            materials.append([m.id, m.name])
            if m.id == int(config.get('Inkcut', 'default_device')):
                active = len(materials)
        combobox = self.get_widget('material', 'materials')
        combobox.set_model(materials)
        cell = Gtk.CellRendererText()
        combobox.pack_start(cell, True)
        combobox.add_attribute(cell, 'text', 1)
        combobox.set_active(active)

        model = []
        device_active_index = 0
        for device in Device.get_printers():
            name = device.name
            if device.id == int(config.get('Inkcut', 'default_device')):
                name += " (default)"
                device_active_index = len(model)
            model.append(name)
            log.info(name)
        combobox = builder.get_object('devices')
        self.set_model_from_list(combobox, model)
        combobox.set_active(device_active_index)

        # Init Accelerators
        accel_group = builder.get_object('accelgroup1')
        for action in builder.get_object('actiongroup1').list_actions():
            action.set_accel_group(accel_group)
            action.connect_accelerator()
        window.add_accel_group(accel_group)

        # Show the widgets
        self._update_sensitivity()
        window.show_all()
        self.flash("", indicator=False)

        # Fix!
        self._flags['block_callbacks'] = False
        self.add_window(window, 'inkcut')
        self.on_graphic_scale_lock_toggled(
            self.get_widget('graphic-properties', 'graphic-scale-lock'))
        # From command line arguments
        if filename is not None and os.path.isfile(filename):
            self.create_job(filename)

        Gtk.main()

    # ===================================== Plot Callbacks ===============================================
    @callback
    def on_plot_feed_distance_changed(self, radio, data=None):
        self.flash("Saving the plot feeding settings...", indicator=True)
        feed = self.get_widget('plot-properties', 'plot-feed').get_active()
        if feed:
            d = self.unit_to(
                self.get_widget('plot-properties',
                                'plot-feed-distance').get_value())
            pos = (0, d)
            if self.job.plot.get_rotation() == 90:
                pos = (d, 0)
            self.job.set_property('plot', 'finish_position', pos)
        else:
            self.job.set_property('plot', 'finish_position', (0, 0))
        GObject.timeout_add(1000, self.flash, "")

    @callback
    def on_plot_copies_changed(self, adjustment, data=None):
        """Set's the plot's copies to the adjustment value. """
        n = int(adjustment.get_value())
        self.flash("Setting the number of copies to %s..." % n, indicator=True)
        GObject.idle_add(self.job.plot.set_copies, n)
        GObject.idle_add(self._update_preview)

    @callback
    def on_stack_reset_activated(self, button, data=None):
        """Sets the graphic-copies to 1"""
        self.get_widget('plot-properties', 'plot-copies').set_value(1)
        # Preview updated by on_plot_copies_changed

    @callback
    def on_stack_add_activated(self, button, data=None):
        """Adds a full stack of copies"""
        stack = self.job.plot.get_stack_size_x()
        copies = self.job.plot.get_copies()
        self.get_widget('plot-properties',
                        'plot-copies').set_value(stack * (copies / stack + 1))
        # Preview updated by on_plot_copies_changed

    @callback
    def on_plot_spacing_x_changed(self, adjustment, data=None):
        x = self.unit_to(adjustment.get_value())
        if self.get_widget('plot-properties', 'plot-copies').get_value() > 1:
            msg = "Updating the column spacing..."
        else:
            msg = "Saving the plot column spacing..."
        self.flash(msg, indicator=True)
        GObject.idle_add(self.job.plot.set_spacing, x, None)
        GObject.idle_add(self._update_preview)

    @callback
    def on_plot_spacing_y_changed(self, adjustment, data=None):
        y = self.unit_to(adjustment.get_value())
        if self.get_widget('plot-properties', 'plot-copies').get_value() > 1:
            msg = "Updating the row spacing..."
        else:
            msg = "Saving the plot row spacing..."
        self.flash(msg, indicator=True)
        GObject.idle_add(self.job.plot.set_spacing, None, y)
        GObject.idle_add(self._update_preview)

    @callback
    def on_plot_position_x_changed(self, widget, data=None):
        x = self.unit_to(widget.get_value())
        pos = self.job.plot.get_position()
        self.flash("Moving the plot to (%s,%s)" % (x, pos[1]), indicator=True)
        GObject.idle_add(self.job.plot.set_position, x, pos[1])
        GObject.idle_add(self._update_preview)

    @callback
    def on_plot_position_y_changed(self, widget, data=None):
        y = self.unit_to(widget.get_value())
        pos = self.job.plot.get_position()
        self.flash("Moving the plot to (%s,%s)" % (pos[0], y), indicator=True)
        GObject.idle_add(self.job.plot.set_position, pos[0], y)
        GObject.idle_add(self._update_preview)

    @callback
    def on_plot_center_x_toggled(self, checkbox, data=None):
        enabled = checkbox.get_active()
        if enabled:
            msg = "Centering the plot horizontally..."
        else:
            msg = "Moving the plot to the horizontal start..."
        self.flash(msg, indicator=True)
        GObject.idle_add(self.job.plot.set_align_center_x, enabled)
        GObject.idle_add(self._update_plot_ui)

    @callback
    def on_plot_center_y_toggled(self, checkbox, data=None):
        enabled = checkbox.get_active()
        if enabled:
            msg = "Centering the plot vertically..."
        else:
            msg = "Moving the plot to the vertical start..."
        self.flash(msg, indicator=True)
        GObject.idle_add(self.job.plot.set_align_center_y, enabled)
        GObject.idle_add(self._update_plot_ui)

    @callback
    def on_plot_weedline_toggled(self, checkbox, data=None):
        enabled = checkbox.get_active()
        if enabled:
            msg = "Adding a weedline to the plot..."
        else:
            msg = "Removing the plot weedline..."
        self.flash(msg, indicator=True)
        GObject.idle_add(self.job.plot.set_weedline, enabled)
        GObject.idle_add(self._update_preview)

    @callback
    def on_plot_weedline_padding_changed(self, adjustment, data=None):
        if self.get_widget('plot-properties',
                           'plot-weedline-enable').get_active():
            msg = "Updating the plot weedline padding..."
        else:
            msg = "Saving the plot weedline padding..."
        self.flash(msg, indicator=True)
        GObject.idle_add(self.job.plot.set_weedline_padding,
                         self.unit_to(adjustment.get_value()))
        GObject.idle_add(self._update_preview)

    # ===================================== Graphic Callbacks ===============================================
    @callback
    def on_graphic_width_changed(self, adjustment, data=None):
        # Calculate new scale
        cur_w = self.job.plot.graphic.get_width()
        new_w = float(self.unit_to(adjustment.get_value()))
        sx, sy = self.job.plot.graphic.get_scale()
        sx = new_w / cur_w * sx
        # Updated in on_graphic_scale_x_changed callback
        self.get_widget('graphic-properties', 'graphic-scale-x').set_value(sx)

    @callback
    def on_graphic_height_changed(self, adjustment, data=None):
        # Calculate new scale
        cur = self.job.plot.graphic.get_height()
        new = float(self.unit_to(adjustment.get_value()))
        sx, sy = self.job.plot.graphic.get_scale()
        s = new / cur * sy
        # Updated in on_graphic_scale_x_changed callback
        self.get_widget('graphic-properties', 'graphic-scale-y').set_value(s)

    @callback
    def on_graphic_scale_y_changed(self, adjustment, data=None):
        sy = adjustment.get_value()
        if self.get_widget('graphic-properties',
                           'graphic-scale-lock').get_active():
            sx = sy
        else:
            sx = self.get_widget('graphic-properties',
                                 'graphic-scale-x').get_value()
        GObject.idle_add(self.job.plot.graphic.set_scale, sx, sy)
        GObject.idle_add(self._update_ui)

    @callback
    def on_graphic_scale_x_changed(self, adjustment, data=None):
        sx = adjustment.get_value()
        if self.get_widget('graphic-properties',
                           'graphic-scale-lock').get_active():
            sy = sx
        else:
            sy = self.get_widget('graphic-properties',
                                 'graphic-scale-y').get_value()
        GObject.idle_add(self.job.plot.graphic.set_scale, sx, sy)
        GObject.idle_add(self._update_ui)

    @callback
    def on_graphic_rotate_to_save_toggled(self, checkbox, data=None):
        self.flash("Checking and updating...", indicator=True)
        GObject.idle_add(self.job.plot.set_auto_rotate, checkbox.get_active())
        GObject.idle_add(self._update_preview)

    @callback
    def on_graphic_weedline_padding_changed(self, adjustment, data=None):
        if self.get_widget('graphic-properties',
                           'graphic-weedline-enable').get_active():
            msg = "Updating the graphic weedline padding..."
        else:
            msg = "Saving the graphic weedline padding..."
        self.flash(msg, indicator=True)
        GObject.idle_add(self.job.plot.graphic.set_weedline_padding,
                         self.unit_to(adjustment.get_value()))
        GObject.idle_add(self._update_graphic_ui)

    @callback
    def on_graphic_weedline_toggled(self, checkbox, data=None):
        enabled = checkbox.get_active()
        if enabled:
            msg = "Adding a weedline to the graphic..."
        else:
            msg = "Removing the graphic weedline..."
        self.flash(msg, indicator=True)
        GObject.idle_add(self.job.plot.graphic.set_weedline, enabled)
        GObject.idle_add(self._update_preview)

    @callback
    def on_graphic_mirror_x_toggled(self, checkbox, data=None):
        enabled = checkbox.get_active()
        if enabled:
            msg = "Mirroring graphic about the y-axis..."
        else:
            msg = "Returning graphic to original mirror state..."
        self.flash(msg, indicator=True)
        GObject.idle_add(self.job.plot.graphic.set_mirror_x, enabled)
        GObject.idle_add(self._update_preview)

    @callback
    def on_graphic_mirror_y_toggled(self, checkbox, data=None):
        enabled = checkbox.get_active()
        if enabled:
            msg = "Mirroring graphic about the x-axis..."
        else:
            msg = "Returning graphic to original mirror state..."
        self.flash(msg, indicator=True)
        GObject.idle_add(self.job.plot.graphic.set_mirror_y, enabled)
        GObject.idle_add(self._update_preview)

    @callback
    def on_graphic_scale_lock_toggled(self, checkbox, data=None):
        if checkbox.get_active():
            self.get_widget('inkcut', 'scale-x-label').set_text("Scale:")
            self.get_widget('inkcut', 'scale-lock-box').hide()
            if self.job is not None:
                s = self.get_widget('graphic-properties',
                                    'graphic-scale-x').get_value()
                self.get_widget('graphic-properties',
                                'graphic-scale-y').set_value(s)
        else:
            self.get_widget('inkcut', 'scale-x-label').set_text("Scale - X:")
            self.get_widget('inkcut', 'scale-lock-box').show()

    @callback
    def on_graphic_rotation_changed(self, combobox, data=None):
        degrees = combobox.get_active() * 90
        self.flash("Setting graphic rotation to %s..." % degrees,
                   indicator=True)
        GObject.idle_add(self.job.plot.graphic.set_rotation, degrees)
        GObject.idle_add(self._update_graphic_ui)

    # ===================================== File Menu Callbacks ===============================================
    @callback
    def on_job_review_activated(self, action, data=None):
        self.job.update_properties()
        builder = Gtk.Builder()
        builder.add_from_file(os.path.join(APP_DIR, 'ui', 'plot.ui'))
        dialog = builder.get_object('dialog1')
        builder.connect_signals(self)
        dialog.show_all()
        dialog.run()
        dialog.destroy()

    @callback
    def on_job_submit_activated(self, action, data=None):
        self.job.update_properties()
        GObject.idle_add(self.run_export_plugin)

    def run_export_plugin(self):
        # Write the job to a file
        tmp = tempfile.NamedTemporaryFile(suffix=".svg", delete=False)
        tmp.file.write(self.job.plot.get_xml())
        svg = tmp.name
        tmp.close()

        # Get the current device
        name = self.get_combobox_active_text(
            self.get_widget('inkcut', 'devices'))
        #device = self.session.query(Device).filter(Device.name==name).first()
        device = Device.get_printer_by_name(name)
        log.info(device)
        # Init the export plugin
        # TODO: Gather plugins here.... let user select...
        plugins = [HPGL.Import(), HPGL.Export()]
        plugin_found = False
        for plugin in plugins:
            if plugin.mode.lower() == "export":
                if str(device.command_language.lower()) in plugin.filetypes:
                    plugin_found = True
                    break
        if plugin_found == False:
            msg = Gtk.MessageDialog(
                type=Gtk.MessageType.ERROR,
                buttons=Gtk.ButtonsType.OK,
                message_format="No plugins found for the command language:%s."
                % device.command_language)
            msg.format_secondary_text(
                "Please make sure the plugins for this device are installed.\n If the problem persists, contact the developer."
            )
            msg.run()
            msg.destroy()
            raise Exception(
                "Error, no plugin found for that command language...")

        # Initialize the plugin then run it
        # TODO: put everything needed here...
        plugin.export_init(plot=self.job.get_properties('plot'),
                           device={'cutting_overlap': (10, False)})
        plugin.input = svg
        plugin.run()
        device.submit(plugin.output)

        # Cleanup
        os.remove(svg)

    def on_file_save_action_activated(self, widget, data=None):
        self.flash("Saving %s into the Job database..." % (self.job.name),
                   indicator=True)
        self.job.update_properties()
        self.get_window('inkcut').set_title("%s - Inkcut" % self.job.name)
        self.session.commit()
        GObject.timeout_add(1000, self.flash, "")

    def create_job(self, filename, **kwargs):
        """Create a job and try to set the source. Returns bool success."""
        job = Job(**kwargs)
        # Get the default material
        job.material = self.get_material()
        try:
            job.set_source(filename)
            self.job = job
            self.session.add(self.job)
            msg = 'Loaded %s' % os.path.basename(job.name or 'File')
            self.get_window('inkcut').set_title("*%s - Inkcut" % job.name)
            self.flash(msg)
            self.on_plot_feed_distance_changed(
                self.get_widget('plot-properties', 'plot-feed'))
            self._update_ui()
            return False
        except Exception, err:
            # update the ui with job info
            log.debug(traceback.format_exc())
            msg = Gtk.MessageDialog(type=Gtk.MessageType.ERROR,
                                    buttons=Gtk.ButtonsType.OK,
                                    message_format="Issue loading file")
            msg.format_secondary_text(err)
            msg.run()
            msg.destroy()
            return False
        except:
Exemple #13
0
def syncdb():
    from meta import Base, engine, Session 
    Base.metadata.drop_all(engine)
    Base.metadata.create_all(engine)
    #init data base
    #init perm
    perm_admin = Permission('can_view_admin')
    perm_admin_edit = Permission('can_edit_admin')
    perm_leader = Permission('can_decide')
    #init role
    role_admin = Role('admin')
    role_mem = Role('member')
    role_leader = Role('leader')
    #init type
    utypea = UserType('memberA', 95, 100)
    utypeb = UserType('memberB', 90, 150)
    utypec = UserType('memberC', 85, 200)
    #init user
    user = User('sheimi', 'zhang')
    nuser = User('shaymin', 'zhang')
    session = Session()
    session.add_all([role_admin, role_mem, role_leader, user, nuser])
    session.commit()
    #config relation
    role_admin.perms.append(perm_admin)
    role_leader.perms.append(perm_leader)
    role_leader.perms.append(perm_admin)
    role_admin.perms.append(perm_admin_edit)
    user.roles.append(role_admin)
    nuser.roles.append(role_leader)
    nuser.usertype = utypea
    session.commit()
    
    dt1 = DessertType('Cake')
    dt2 = DessertType('Ice Cream')
    dt3 = DessertType('Fruit')
    session.add_all([dt1, dt2, dt3])
    session.commit()

    d0 = Dessert('Goblet')
    d1 = Dessert('Lemon')
    d2 = Dessert('Buttermilk')
    d3 = Dessert('Chocolate')
    d4 = Dessert('Fruit')
    d5 = Dessert('Valentine')
    d6 = Dessert('Lemon Cake')
    d7 = Dessert('Exotic Fruits')
    d8 = Dessert('Fresh Fruit')
    d9 = Dessert('Chocolate Ice')

    d0.des, d0.type_id = 'This is Description ~~~~~~~', 2
    d1.des, d1.type_id = 'This is Description ~~~~~~~', 3
    d2.des, d2.type_id = 'This is Description ~~~~~~~', 1
    d3.des, d3.type_id = 'This is Description ~~~~~~~', 1
    d4.des, d4.type_id = 'This is Description ~~~~~~~', 3
    d5.des, d5.type_id = 'This is Description ~~~~~~~', 1
    d6.des, d6.type_id = 'This is Description ~~~~~~~', 1
    d7.des, d7.type_id = 'This is Description ~~~~~~~', 3
    d8.des, d8.type_id = 'This is Description ~~~~~~~', 3
    d9.des, d9.type_id = 'This is Description ~~~~~~~', 2

    d0.img = '13569b64-b9e3-4c3a-8a1d-5f794a723d8c'
    d1.img = '83289d63-b49b-4d70-b47a-08d43cdd940e'
    d2.img = 'adc15f11-3f8c-4e33-aba3-a199d2d47da9'
    d3.img = '3426bba5-03e2-4c46-bbd3-dfc7afdbe372'
    d4.img = '4ddc429e-c202-4fbe-8481-59738bc29a88'
    d5.img = '359e9e89-a6f9-44ca-bbef-46e49a490d5a'
    d6.img = '59465deb-26e8-493c-ba40-5c4b96362594'
    d7.img = '59e46ac2-0193-4f57-ae10-3c00a1bf2d3b'
    d8.img = 'c549125d-0f4f-417a-9813-7ea208573681'
    d9.img = '2c70a62e-a09c-4b55-906b-ba7f4bba04e8'
    
    session.add_all([d0, d1, d2, d3, d4, d5, d6, d7, d8, d9])
    session.commit()
    decision = Decision(content="test", title="title")
    decision.add()

    d = Dessert.get_all()
Exemple #14
0
class Manager(object):
    """
    Feeds Manager.
    This is the main object to control Leolo. No other classes should be used
    instead.
    """

    def __init__(self):
        """
        Database loading.
        """
        self.sites = []  # list with all sites objects
        self.logger = Logger("Manager")
        self.session = Session()
        self.sites = self.session.query(Site).all()  # loading all sites

    def activate_site(self, opt):
        """
        Makes a site active.
        User can pass as 'opt' a site number or feed url.
        """
        self.deactivate_site(opt, False)

    def add_site(self, feedurl, mark_as_read=False):
        """
        Adds a new site.
        'feedurl' is the feed's url.
        If 'mark_as_read' is True, then old entries will be ignored in next
        update. Only new entries from now will be indexed.
        Returns feed's title if everything it's ok, otherwise, None.
        """
        # Check valid url
        if not url_re.search(feedurl):
            s = "Site: '%s' is not a valid url!" % (feedurl)
            self.logger.info(s)
            raise ValueError(s)

        # Check if site already exists in DB, and if it doesn't, a new Site
        # instance is created and saved.
        if not self.session.query(Site, Feed).filter(Site.id == Feed.siteid).filter(Feed.url == feedurl).first():
            fm = FeedManager()
            result = fm.check_feed(feedurl, True)
            if result:
                site = Site(feedurl, result[0], result[1])
                if mark_as_read:
                    FeedManager.mark_as_read(site.feed)
                self.session.save(site)
                self.session.commit()
                self.sites.append(site)
                return result[0]

    def deactivate_site(self, opt, deactivate=True):
        """
        Makes a site inactive.
        User can pass as 'opt' a site number or feed url.
        """
        # By option number
        if isinstance(opt, int):
            try:
                site = self.session.query(Site).filter(Site.id == opt).one()
                feed = self.session.query(Feed).filter(Feed.siteid == opt).one()
                i = 0
                while True:
                    if self.sites[i].feed.url == site.feed.url:
                        if deactivate:
                            self.sites[i].inactive = True
                        else:
                            self.sites[i].inactive = False
                        self.session.commit()
                        break
                    i += 1
            except IndexError:
                act_deact = None
                if deactivate:
                    act_deact = "deactivate"
                else:
                    act_deact = "activate"
                s = "Cannot find to %s site #%s." % (act_deact, str(opt))
                self.logger.error(s)
                return
        # By feed url
        elif isinstance(opt, str):
            i = 0
            while True:
                try:
                    site = self.sites[i]
                    if site.feed.url == opt:
                        if deactivate:
                            self.sites[i].inactive = True
                        else:
                            self.sites[i].inactive = False
                        self.session.commit()
                        break
                    i += 1
                except IndexError:
                    act_deact = None
                    if deactivate:
                        act_deact = "deactivate"
                    else:
                        act_deact = "activate"
                    s = "Cannot find '%s' to %s." % (str(opt), act_deact)
                    self.logger.error(s)
                    return
        # Error
        else:
            s = "Not a valid site! Use site's feed url or site number."
            self.logger.error(s)
            raise TypeError(s)

    def del_site(self, opt):
        """
        Removes site.
        User can pass as 'opt' a site number or feed url.
        """
        # Del by option number
        if isinstance(opt, int):
            try:
                site = self.session.query(Site).filter(Site.id == opt).one()
                feed = self.session.query(Feed).filter(Feed.siteid == opt).one()
                i = 0
                while True:
                    if self.sites[i].feed.url == site.feed.url:
                        del self.sites[i]
                        break
                    i += 1
                self.session.delete(site)
                self.session.commit()
            except IndexError:
                s = "Cannot find to remove site #" + str(opt) + "."
                self.logger.error(s)
                return
        # Del by feed url
        elif isinstance(opt, str):
            i = 0
            while True:
                try:
                    site = self.sites[i]
                    if site.feed.url == opt:
                        self.session.delete(site)
                        self.session.delete(site.feed)
                        del self.sites[i]
                        self.session.commit()
                        return
                    i += 1
                except IndexError:
                    s = "Cannot find to remove site's feed '" + opt + "'."
                    self.logger.error(s)
                    return
        # Error
        else:
            s = "Not a valid site! Use site's feed url or site number."
            self.logger.error(s)
            raise TypeError(s)

    def del_sites(self):
        """
        Deletes all sites.
        """
        sites = self.session.query(Site).all()
        for site in sites:
            self.session.delete(site)
        del self.sites[:]

    def display_sites(self):
        """
        Returns all sites as a string.
        """
        if len(self.sites) == 0:
            return "No sites yet."

        s = ""
        for (i, site) in enumerate(self.sites):
            if i > 0:
                s += "\n"
            s += "%s" % site
        return s

    def filter(self, q):
        """
        q is the query.
        """
        if not isinstance(q, str):
            s = "filter: invalid query argument. You must use a string."
            self.logger.error(s)
            raise TypeError(s)
        f = Filter(self.sites, q)
        f.apply()

    def get_site(self, opt):
        """
        Gets a site.
        """
        # TODO
        pass

    def get_sites(self):
        """
        Return all sites in a List.
        """
        return self.sites

    def update_sites(self, minutes=20, limit=None):
        """
        Updates all feeds from all sites.
        'minutes' is for checking sites which were last checked before that
        number of minutes. E.g: if you set it to 20, then the site will only
        be checked if last check was more than 20 minutes ago. Set 0 for
        checking always.
        'limit' reduces the number of updated sites. Leave blank to check all.
        """
        if not isinstance(minutes, int):
            s = "update_sites: not a valid 'minutes' argument, must be int."
            self.logger.error(s)
            raise TypeError(s)
        elif minutes < 0:
            s = "update_sites: 'minutes' must be less or equal than 0."
            self.logger.error(s)
            raise ValueError(s)
        if limit is None:
            pass
        elif not isinstance(limit, int):
            s = "update_sites: not a valid 'limit' argument, must be int."
            self.logger.error(s)
            raise TypeError(s)
        elif limit <= 0:
            s = "update_sites: 'limit' must be more than 0."
            self.logger.error(s)
            raise ValueError(s)

        l = []
        for site in self.sites:
            if not site.inactive:
                l.append(site.feed)

        fm = FeedManager(l)
        fm.update_feeds(minutes, limit)
        # Save changes to site and dependent objects
        self.session.commit()
        return self