Package: django-bloxby
A django application for bridging bloxby and your django software supporting User creation, package creation and autologin
and also publishing sites from the bloxby application to your django application.QuickstartInstall Django Bloxby:pip install django-bloxbyAdd it to yourINSTALLED_APPS:App name you add to INSTALLED_APPS used to bebloxbyyou add toINSTALLED_APPSin versions0.0.19downwards, but
it has changed in version0.0.20since the ftp part has been integrated into the library.INSTALLED_APPS=(...'bloxby',# optional, if you are running the FTP server'bloxby.ftp'...)The following settings are available to you (insettings.py):BLOXBY_BUILDER={'url':'http://clouddigitalmarketing.com','custom_api_url':'http://159.65.79.47:3000',# optional, needed only if the node api is deployed'username':'hello@linkfusions.com','password':'accountpassword','package_prefix':'LF-',# optional, but you may want to provide this to ensure uniqueness'account_email_prefix':'LF',# optional, but you may want to provide this to ensure uniqueness'public_key':'Yourpublickeyasstatedinthebloxbyapplicationsettings','autologin_hash':'Yourautologinhash','default_package_id':1}url: This is the base url of the server that hosts the bloxby builder.custom_api_url: This is the base URL of the node server that interfaces the bloxby database to provide data not provided by the default bloxby builder API.username: Admin user emailpassword: Password of the admin user specifiedpackage_prefix: This could be empty, but it is used to distinguish packages in case of your builder being accessed by more than one application.account_prefix: Same explanation goes here, in case you have some users shared across your applications.public_key: API key you generated and saved in the admin settings on your bloxby dashboard.autologin_hash: The auto login hash which you as well got from the dashboard.default_package_id: Default package to add for new users being created if none is provided at the point of calling the create function.Then run migrate command.python manage.py migrate.Usage (Accessing Default Bloxby APIs)Once the settings are configured you could run requests to access the default endpoints provided by bloxby here this way:fromdjbloxby.bloxby.functionsimportBloxbyb=Bloxby()# Retrieve User with id of 4b.Users.retrieve(4)# Delete User with id of 4b.Users.delete(4)# Update user with id of 4b.Users.update(4,last_name='New')# Create new userb.Users.create(first_name='John',last_name='Felix',email='jfelix@localhost.com',password=generate_password(),type='User',package_id=5)# Working with Packagesb.Packages.create(name='New Free Package',sites_number=10,disk_space=100,export_site=True,ftp_publish=True,price=4.00,currency='USD')b.Packages.delete(3)# Delete packages with id of 3# .....# Could also do .update, .retrieve, .delete with this.More information on integrating with the default APIs ofUsersandPackagescan befound hereandhererespectively.TemplateYou could autologin user in html by getting the autologin URL for the current user, this process also creates a new account on the
the bloxby instance for the current logged in if they do not already have one.{% load bloxby %}<h1>Click<ahref="{% user_builder_dashboard %}">here</a>to login to your builder dashboard.Setup Extra API serverThis extra server helps to provide extra functionalities not provided by the default API service such as export and pulling of templates.
In the repo, there is a folder namednode_apithat contains Node.js server code that accesses the database of the Bloxby server directly.
To configure this, open the file atnode_api/index.jsand set the parameters of the database connection pool function like this:letpool=mysql.createPool({host:'database host',user:'root',password:'password',database:'bloxby'});Additionally, you need the credentials of an admin user from the builder site passed in thesignInfunction called at line 91 of theindex.jsfile.
To setup this node server on a fresh server(could as well run in the same server the bloxby instance runs in), you just need to clone this
repogit clone https://github.com/damey2011/django-bloxby.gitand then navigate into thenode_apifolder.Next, run./setup_node_api.sh. This installs all the dependencies needed to run the node_js application including npm and the Node V8 runtime itself.Then, install the project dependencies by runningnpm install. Once all these are done, you can start the server by running./start_node_api.sh. All together, after configuring theindex.jswith the correct database details. The lines of code below would setup and get the
node server running on port 3000.$gitclonehttps://github.com/damey2011/django-bloxby.git$cdnode_api$./setup_node_api.sh$npminstall$./start_node_api.sh$sudoufwallow3000The last line is to enable port 3000 which the server runs on accessible from outside the server.End points provided by the node server/<autologin_token>/templates: This endpoint would return the templates of the user whose autologin token is passed./<site_id>/export/: This returns a zip file of the exported site whose site_id is passed.Both endpoints take onlyGETrequests. You don’t need to consume these endpoints raw by the way, just for documentation purpose.
The next section provides information on how to consume these endpoints within the library in an abstract manner.Django User SupportYou are able to tie the bloxby instance users to a Django user through a model object provided in this
repo,bloxby.models.UserBridge.TheUserBridgeobject provides a couple of attributes and methods.createclassmethod: This can be used to create a bloxby account for a user. Takes in parameters:user: User object of the user you want to create the bloxby account for.package_id: Bloxby Builder Package ID of the package you want to assign to user being created. Falls back to thesettings.BLOXBY_BUILDER['default_package_id']if no parameter is provided in this position.Returns the newUserBridgeinstance.user=request.userUserBridge.create(user,4)dashboard_urlproperty: This returns the URL the current instance of UserBridge can use to auto login into the bloxby instancetry:login_url=request.user.userbridge.dashboard_url# OR login_url = UserBridge.objects.get(user=request.user).dashboard_urlexceptUserBridge.DoesNotExist:login_url=UserBridge.create(request.user).dashboard_url# Do whatever you want with the login url maybe pass it to HTMLuser_templatesmethod: This returns the templates the current user has. Assumed you have done the initial setup insettings.py, and most importantly added theBLOXBY_BUILDER['custom_api_url']setting.try:templates=request.user.userbridge.user_templates()exceptUserBridge.DoesNotExist:templates=UserBridge.create(request.user).user_templates()# You can also access the template data by doingfortemplateintemplates:print(template.sites_id)print(template.users_id)print(template.sites_name)print(template.sitethumb)print(template.sites_lastupdate_on)# To get your data in JSON in an API viewjson_templates=UserTemplateSerializer(templates,many=True).dataIf you want it in json, you can do a simple serializer in django rest framework like this:classUserTemplateSerializer(serializers.Serializer):sites_id=serializers.IntegerField()sites_name=serializers.CharField()sitethumb=serializers.CharField()edit_url=serializers.SerializerMethodField()sites_lastupdate_on=serializers.CharField()defget_edit_url(self,obj):returnf"{settings.BLOXBY_BUILDER['url']}/sites/{obj.sites_id}"defto_representation(self,instance):data=super(UserTemplateSerializer,self).to_representation(instance)try:last_updated=datetime.fromtimestamp(int(data.get('sites_lastupdate_on',0)))data['sites_lastupdate_on']=last_updated.strftime('%d%B %Y, %H:%m')exceptTypeError:data['sites_lastupdate_on']='Never'returndataNote that theto_representationmethod was overridden to format the datetime to our own taste, it is not
necessary to do so. If you are satisfied with the format of the defaultsites_lastupdate_on, you might want to
leave overriding to_representation out of your code.save_site_from_remotemethod: This method does not return anything, just downloads the site from the node server you setup earlier, takes parameters:site_id: This is the unique ID of the site which you want to download from the user’s builder account into your django application, how to render the site will be in the next section.target: This could be any string, something that differentiates objects using the sites. e.g. I could pass in ‘event’ as this parameter for me to know how to retrieve this particular template to render.obj_idoptional: Should you want to attach this site you are downloading to another model instance in your application, you can pass in their unique key (preferably primary key) here. Note that thetargetandobj_idneed to be unique together.Use in Django ApplicationAssuming that I intend to use a template for an event home page.In the view that lets us tie the event to a template:frombloxby.modelsimportTemplateclassAssignSiteToEvent(View):defpost(self,request,*args,**kwargs):# Assuming you hit this endpoint with a post request with data {"site_id": 100, "event_id": 4}site_id=self.request.data.get('site_id')event_id=self.request.data.get('event_id')ifevent_id:self.request.user.userbridge.save_site_from_remote(site_id=site_id,target='event',obj_id=tenant_id)else:Template.objects.filter(remote_id=site_id,target='home',owner=self.request.user).delete()returnHttpResponseRedirect('/success')To render it:frombloxby.modelsimportTemplateclassEventLandingPageView(View):defget(self,request,*args,**kwargs):page=request.GET.get('page')# The page parameter helps to handle the other page when the template attached has multiple pages,# and they are linked. e.g. http://site.com/<event_id>/?page=contact.htmlevent_id=kwargs.get('event_id')template=Template.objects.filter(target='event',obj_id=event_id)# retrieve the template that got saved from the 'save_site_from_remote' method called in the 'AssignSiteToEvent' part.iftemplate.exists():template=template.first()ifpage:try:page=template.page_set.filter(name__iexact=page.lower()).first()returnHttpResponse(page.render())exceptPage.DoesNotExist:raiseHttp404('Page does not exist.')index_page=template.index_pageifindex_page:returnHttpResponse(index_page.render())# Handle situation where no template is attached to the eventreturnHttpResponse('No template to render')Setup FTP Server (Alternative, not recommended)In Production EnvironmentThis part assumes you have python, pip and virtualenv installed globally on your server.Makesetup_ftp_server.shandstart_ftp_server.shexecutable if they are not already
executable.chmod u+x setup_ftp_server.shandchmod u+x start_ftp_server.sh.Run:./setup_ftp_server.shThis installs certain dependencies needed.** To start the servers **Run./start_ftp_server.shThis starts the FTP server on port 21 and the django server on port 8000. The servers work together, the django server started on port 8000
provides the admin dashboard to manage the external applications that want to receive files through FTP.So rather than running an FTP server on each and every one of those applications, we’d register them here
and also have this library running on them to allow authentication of users, receipt and processing of files.These processes are managed byPM2. So this allows you to use some of the
PM2 commands if you are familiar with them.For example, you just did a git pull and you want to restart, you could just do:pm2restartallThis restarts the django server and the ftp server.Why the Django Server inside of the libraryThe Django server provides admin interface to manage external applications.
You just need to add a model object namedApplicationthat takes in the auth URL and file receiving URL of the
external application (these are automatically also provided by this library), this where the FTP server performs
authentication for users that want to publish pages.e.g. I have an external application athttps://dev.linkfusions.com, and in this external application, I havedjango-bloxbyinstalled already with the URLs set. I can just add an Application model instance through the FTP server
instance admin, name it ‘dev-fusions’, provide the auth url as installed in my external application (How to do this in
the next section), provide the auth and receiving url and that’s all.How to add the URLs to your external applicationIn yoururls.py, you can add these:urlpatterns=[...path('bloxby/',include('djbloxby.bloxby.urls')),...]If I setup this way, my auth URL is going to behttp://<mydomain>/bloxby/ftp/auth/and my
receiving URL is going to behttp://<mydomain>/bloxby/ftp/receive/. (These are the URLs you
register in theApplicationmodel with the FTP server).How to access the pages published to your external applicationA couple of models are made available for thisTemplate,Page,TemplateAsset. TheTemplateis just a sugar-coated name for Website.
It encapsulates the assets and the HTML pages. ThePagerepresents the HTML files and they
have two major attributes (functions) which arerenderandprocess.Therenderfunction returns HTML string of a page.process, swaps all the URLs with
the django application compatible URLs depending on your default file storage, it’s only called once
for every page (at initial page request, the very first time the page is being accessed).It parses all the
CSS files also and makes sure their URLs are valid.Possible IssuesMake sure to set the correct address to theSitein admin.FTP Client is able to connect and authenticate but unable to list directory. Enable passive ports
on your server (where the FTP server runs). In this, passive ports run in the range 60000-65535.
You can enable this by running:sudoufwallowfromip_addresstoanyport60000:65535prototcpWhereip_addressis whatever (domain or IP address) you configure in theSitein admin.CreditsTools used in rendering this package:Cookiecuttercookiecutter-djangopackage