Documentation using Sphinx

I am going to release source code documentation using Sphinx.Sphinx is a tool that makes easy writing documentation. Using a directive, you can alsoextract documentation from the source code. You will find this documentation under the Documents section in here: https://forja.rediris.es/projects/cusl5-learnie/

In this case, I have already uploaded some bits of source code documentation. You can read it in here:
https://forja.rediris.es/docman/view.php/908/1414/source%20code%20documentation.zip

Information about Sphinx can be found in its website: http://sphinx.pocoo.org/

Posted in overview, vlearnie | Tagged , , , , | Leave a comment

Control who can watch your publications

We have been developing an application to give you control over who can watch your content, and we have got this result:

You can create a list of friends. Every friend can be assigned to one friend list, and you can give readable access to these. The readable privilege will be granted by creating a composition of list, which means, you can select two or more friend lists and give them the same privileges. This gives you the opportunity to make a composition of these friend lists,. Therefore, you do not need to grant the access individually, just select more than one friend list to give them readable privileges over your publications.

We want to be able to apply this readable permission to the views in Django (the framework in which the application is being developed) in a non-intrusive way. We think the best way to do this, without rewriting the applications, is through the use of decorators. A decorator is a function that takes another function. This means that the function do something and call the other function. If a view in Django is usually written as follows:

 
def view(request): 
    something 

Now, the view will be something like this:


@permission(args) 
def view(request): 
    something

where @permission is a function that checks that the current user has privileges or permissions to read whatever he intends to watch. If he has such permissions, then show the view normally, otherwise fails.

Below, you can find a brief resume of the functionality:

You can create different friend lists, and build a composition list, which is a list with one or more friend lists. These friend lists defines certain permissions, and the general model makes the association of that permission in relation with the specified application.

Posted in overview, vlearnie | Tagged , , , , , | Leave a comment

Video demonstration of vLearnie in action

This entry will show a video with actions that can be done in vLearnie. It’s still under development and not stable yet, but it’s getting better, ^-^.

vLearnie small demo from Kiko Fernandez on Vimeo.

Posted in overview, vlearnie | Tagged , , , , , , , | 1 Comment

Description of vLearnie in detail

I have uploaded a new document in Spanish where I explain what is the main purpose of this project and what we have planned to do. A brief resume:

  • Building a web app integrated within the Moodle domain.
  • Creation of an API of web services, so that everyone can create new applications. The authentication protocol will be OAuth.
  • Development of a mobile app that makes use of the services created above.

Here is the link to the document: Desarrollo de un sistema de aprendizaje personal [ vlearnie.pdf ]

Posted in overview, vlearnie | Tagged , , , | Leave a comment

First experience with Inkscape

This weekend I have been dealing with the open source tool Inkscape, which since now on, I am a declared fan. It’s easy to work with, has many tutorials on its website and you can even find more on the internet. Best of all, it’s completely free. These are the icons that I have created for my project, I know they are nothing to write home about, but still, I am proud of what I did in not so much time.

I’ll try to upload a video showing the UI of the project, but right now, is still quite tough. Anyhow, I’ll give it a tweak adding some javascript and css.

Posted in overview, vlearnie | Tagged , , , , , , , | Leave a comment

Progress so far

We have been doing a lot of things since the last time I wrote in the blog. So far, the tool has the following built-in features:

  • Allow to create personal spaces
  • In every personal space, you can write a blog, insert post in categories, assign tags, et cetera.
  • Create a community, that do belong to anybody and can be extented by everyone
  • Every time you write a post, you have the option to publish your post in the community. Therefore, everyone can follow these topics and you can publish the entry without using any other app than your own blog. If your post has the status Hidden, then they won’t be published in the community.
  • We have an alpha version of the session from Moodle to vLearnie and vice versa. So far, we haven’t experienced any troubles.
  • We have built a new UI for the logging users. Right now, the appearance is similar to the public UI, but offering options to add / edit content. Nonetheless, they have different templates, so there’s no problem in changing the “logging” UI.
  • There is an alpha version for the portfolio app
  • Currently, developing a  simple file manager.
Posted in overview, vlearnie | Tagged , , , , , , | Leave a comment

SQLAlchemy for legacy databases

The question is ‘How to deal with legacy databases?’, and the answer with SQLAlchemy is simple, just create a model that represents the table and connect this with the session. That’s all. I am going to show you with an example what I have done for querying the Moodle User Table (I must warn you that the Moodle table mdl_user has a lot of fields, so don’t freak out after looking at the code).


from sqlalchemy import MetaData, Column
from sqlalchemy.dialects.mysql import TINYINT, VARCHAR, BIGINT, TEXT
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from msf.settings import DATABASES

USER_INFORMATION_TABLE = 'mdl_user'
USER = DATABASES.get('moodle').get('USER')
PASSWORD = DATABASES.get('moodle').get('PASSWORD')
HOST = DATABASES.get('moodle').get('HOST')
DBNAME = DATABASES.get('moodle').get('NAME')
PORT = DATABASES.get('moodle').get('PORT')

Base = declarative_base()
class MoodleMDLUser(Base):
    __tablename__ = USER_INFORMATION_TABLE

    id = Column(BIGINT, primary_key=True)
    auth = Column(VARCHAR(20), nullable=False, default='manual')
    confirmed = Column(TINYINT(1), nullable=False, default=0)
    policyagreed = Column(TINYINT(1), nullable=False, default=0)
    deleted = Column(TINYINT(1), nullable=False, default=0)
    mnethostid = Column(BIGINT(10), nullable=False, default=0)
    username = Column(VARCHAR(100), nullable=False)
    password = Column(VARCHAR(32), nullable=False)
    idnumber = Column(VARCHAR(255), nullable=False)
    firstname = Column(VARCHAR(100), nullable=False)
    lastname = Column(VARCHAR(100), nullable=False)
    email = Column(VARCHAR(100), nullable=False)
    emailstop = Column(TINYINT(1), nullable=False, default=0)
    icq = Column(VARCHAR(15), nullable=False)
    skype = Column(VARCHAR(50), nullable=False)
    yahoo = Column(VARCHAR(50), nullable=False)
    aim = Column(VARCHAR(50), nullable=False)
    msn = Column(VARCHAR(50), nullable=False)
    phone1 = Column(VARCHAR(20), nullable=False)
    phone2 = Column(VARCHAR(20), nullable=False)
    institution = Column(VARCHAR(40), nullable=False)
    department = Column(VARCHAR(30), nullable=False)
    address = Column(VARCHAR(70), nullable=False)
    city = Column(VARCHAR(20), nullable=False)
    country = Column(VARCHAR(2), nullable=False)
    lang = Column(VARCHAR(30), nullable=False, default='en_utf8')
    theme = Column(VARCHAR(50), nullable=False)
    timezone = Column(VARCHAR(100), nullable=False, default=99)
    firstaccess = Column(BIGINT(10), nullable=False, default=0)
    lastaccess = Column(BIGINT(10), nullable=False, default=0)
    lastlogin = Column(BIGINT(10), nullable=False, default=0)
    currentlogin = Column(BIGINT(10), nullable=False, default=0)
    lastip = Column(VARCHAR(15), nullable=False)
    secret = Column(VARCHAR(15), nullable=False)
    picture = Column(TINYINT(1), nullable=False, default=0)
    url = Column(VARCHAR(255), nullable=False)
    description = Column(TEXT)
    mailformat = Column(TINYINT(1), nullable=False, default=1)
    maildigest = Column(TINYINT(1), nullable=False, default=0)
    maildisplay = Column(TINYINT(2), nullable=False, default=2)
    htmleditor = Column(TINYINT(1), nullable=False, default=1)
    ajax = Column(TINYINT(1), nullable=False, default=1)
    autosubscribe = Column(TINYINT(1), nullable=False, default=1)
    trackforums = Column(TINYINT(1), nullable=False, default=0)
    timemodified = Column(BIGINT(10), nullable=False, default=0)
    trustbitmask = Column(BIGINT(10), nullable=False, default=0)
    imagealt = Column(VARCHAR(255))
    screenreader = Column(TINYINT(1), nullable=False, default=0)

    def __init__(self, id, auth, confirmed, policyagreed, deleted, mnethostid, username,
                 password, idnumber, firstname, lastname, email, emailstop, icq, skype, yahoo,
                 aim, msn, phone1, phone2, institution, department, address, city, country,
                 lang, theme, timezone, firstaccess, lastaccess, lastlogin, currentlogin,
                 lastip, secret, picture, url, description, mainformat, maildigest, maildisplay,
                 htmleditor, ajax, autosubscribe, trackforums, timemodified, trustbitmask,
                 imagealt, screenreader):
        self.id = id
        self.auth = auth
        self.confirmed = confirmed
        self.policyagreed = policyagreed
        self.deleted = deleted
        self.mnethostid = mnethostid
        self.username = username
        self.password = password
        self.idnumber = idnumber
        self.firstname = firstname
        self.lastname = lastname
        self.email = email
        self.emailstop = emailstop
        self.icq = icq
        self.skype = skype
        self.yahoo = yahoo
        self.aim = aim
        self.msn = msn
        self.phone1 = phone1
        self.phone2 = phone2
        self.institution = institution
        self.department = department
        self.address = address
        self.city = city
        self.country = country
        self.lang = lang
        self.theme = theme
        self.timezone = timezone
        self.firstaccess = firstaccess
        self.lastaccess = lastaccess
        self.lastlogin = lastlogin
        self.currentlogin = currentlogin
        self.lastip = lastip
        self.secret = secret
        self.picture = picture
        self.url = url
        self.description = description
        self.mainformat = mainformat
        self.maildigest = maildigest
        self.maildisplay = maildisplay
        self.htmleditor = htmleditor
        self.ajax = ajax
        self.autosubscribe = autosubscribe
        self.trackforums = trackforums
        self.timemodified = timemodified
        self.trustbitmask = trustbitmask
        self.imagealt = imagealt
        self.screenreader = screenreader

Base is the class from which our class is going to inherit from. After declaring the Base class, we start the creation of our object. The __tablename__ attribute must be the table that we want to connect and access as if it were an object. In our case, this will be ‘mdl_user’. All the other attributes are the definition of the table. Keep in mind that even if we do not create this table, we need it in order to make updates or add new values. Basically, I took the table and wrote the definition of the DDL language in a way that SQLAlchemy can understand. Later, the __init__ method initializes the attributes (kind of a java constructor).

After this definition, we can start from the beginning, that is calling the method that references to the database:


    engine = create_engine("mysql+mysqldb://%s:%s@%s:%s/%s" % (USER, PASSWORD, HOST, PORT, DBNAME))

where USER, PASSWORD, HOST, PORT and DBNAME are the corresponded user, password, host, port and database name. The next step is to create the Session object which will hold the session with the database, and create an instance for it:


        Session = sessionmaker(bind=engine)
        session = Session()

The “bind” argument in sessionmaker tie the engine to the session. After that, we can query for the User:


        username = 'kikofernandez'
        querydb = session.query(MoodleMDLUser).filter_by(username=username)

The query response is a list of objects. In this case, since the username is unique, it will get a list with only one object. Now, I can make a call to the attributes of the MoodleMDLUser class and treat it as if it were an object. In the python interpreter, this will work:


    >>> querydb[0].username
    'kikofernandez'
    >>> querydb[0].lastname
    'fernandez'

We can also add an new object to the database (behind the scenes INSERT INTO DBNAME VALUES (XXX, YYY, ZZZ)), and is fairly easy:


    querydb.add(MoodleMDLUser(attributes))
    querydb.commit()

The commit function will write to the database the information of the object declared.

I think this has been a long explanation and I’ve tried to keep it as simple as possible, so enjoy and try the same with a simpler example. You can also consult the tutorial for SQLAlchemy and the following are links that I consider useful:

Posted in overview | Tagged , , , , , , | Leave a comment