Question

I have some code that works on one machine. I uploaded the code to github. When I downloaded the code to a different computer to run it, I get the following stack:

Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\bottle.py", line 744, in _handle
    return route.call(**args)
  File "C:\Python27\lib\site-packages\bottle.py", line 1479, in wrapper
    rv = callback(*a, **ka)
  File "C:/Users/jeff/Documents/GitHub/IPACS/test/src/server.py", line 82, in home_page
    return bottle.template('home.tpl')
  File "C:\Python27\lib\site-packages\bottle.py", line 2829, in template
    return TEMPLATES[tpl].render(kwargs)
  File "C:\Python27\lib\site-packages\bottle.py", line 2803, in render
    self.execute(stdout, kwargs)
  File "C:\Python27\lib\site-packages\bottle.py", line 2791, in execute
    eval(self.co, env)
  File "C:\Users\jeff\Documents\GitHub\IPACS\test\src\views\home.tpl", line 11, in <module>
    %include('main/header.tpl')
NameError: name '_base' is not defined
127.0.0.1 - - [03/Mar/2014 09:51:08] "GET / HTTP/1.1" 500 1867

The files in question:

1. bottle.py (not gonna post here)

2. home.tpl:

<!DOCTYPE html>

<!-- pass in a document-->
<html>
<head>
    <title>IPAC</title>
    <link rel="stylesheet" type="text/css" href="style.css">
    <script src="custom.js"></script>
</head>
<body>
%include('main/header.tpl')

<section>
<p>
    IPAC was designed as an open-source solution to "what servers/devices are on the network right now." It is designed
    to be a very simple, lightweight product to be one step up from spreadsheets as a CMDBs. This product is not meant
    to be a "one-stop shop" but a quick "whats on the network."
</p>
<p>
    Future iterations of this should have be able to have some ability to preform continuous monitoring, integrate with
    some common ticketing systems or larger change systems, and the intelligence to make suggestions to improve performance
    and capacity in a virtualized environment.
</p>
<p>

</p>
</section>

%include('main/footer.tpl')
</body>
</html>

3. server.py:

import copy
import mimetypes
import bottle

from bson import ObjectId
import gridfs
import pymongo
import sys
import lib.crud_ops


__author__ = 'Jeff Tindell'


 #
 #
 #
# Inventory Preformance And Capacity System

# The point of this program is to take json documents consisting of server or network devices basic configuration
# and display it on a basic web form.

# It will also hold and link documents regarding the systems (config files or whatever).

#
# Copyright (C) 2014  Richard Tindell II
#
# 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/>



#establish a connection to the db:
connection = pymongo.MongoClient("mongodb://localhost")
db = connection.ipac
# get collections of my network devices and servers in the inventory
collection = db.test
#get gridfs for the dbs
fs = gridfs.GridFS(db)





# Static Routes
@bottle.get('/<filename:re:.*\.js>')
def javascripts(filename):
    return bottle.static_file(filename, root='static/js')


@bottle.get('/<filename:re:.*\.css>')
def stylesheets(filename):
    return bottle.static_file(filename, root='static/css')


@bottle.get('/<filename:re:.*\.(jpg|png|gif|ico)>')
def images(filename):
    return bottle.static_file(filename, root='static/img')


@bottle.get('/<filename:re:.*\.(eot|ttf|woff|svg)>')
def fonts(filename):
    return bottle.static_file(filename, root='static/fonts')


###########################################
###    NAV BAR MAPPINGS
###########################################
#home page
@bottle.route('/')
def home_page():
    return bottle.template('home.tpl')


#view all inventory
@bottle.route('/viewAll')
def view_all():
    results = lib.crud_ops.find_all(collection)
    return bottle.template('devices/all_devices.tpl', {'results':results})

@bottle.route('/about')
def about_page():
    return bottle.template('about.tpl')



##########################################
###   CRUD ET AL.
##########################################

# Device view
@bottle.route('/showDevice')
def device_view():
    device_id = bottle.request.query.id
    result = lib.crud_ops.find_by_id(collection, device_id)
    files = lib.crud_ops.get_attached_files(db.fs.files, device_id)
    return bottle.template('devices/device_view.tpl', {'device':result, 'attached_files':files})

@bottle.route('/addDevice')
def add_device():
    return bottle.template('devices/add_device.tpl')



# trying out different html code:
@bottle.route('/test')
def test_page():
    return bottle.template('tryHTML/test.tpl')



@bottle.route('/upload', method='POST') #TODO: Change allowed extensions.
def do_upload():
    data = bottle.request.files.data
    did = bottle.request.query.id
    device_url = '/showDevice?id=' + str(did) +'#attached_files'
    raw = data.file.read()  # This is dangerous for big files
    file_name = data.filename
    try:
        newfile_id = fs.put(raw, filename=file_name, device_id = ObjectId(did))
    except:
        return "error inserting new file"

    return bottle.redirect(device_url)



@bottle.route('/download')
def download():
    file_id = ObjectId(bottle.request.query.id)
    if file_id:
        try:
            file_to_download = fs.get(file_id)
        except:
            return "document id not found for id:" + file_id, sys.exc_info()[0]
        file_extension = str(file_to_download.name)[(str(file_to_download.name).index('.')):]

        bottle.response.headers['Content-Type'] = (mimetypes.types_map[file_extension])
        bottle.response.headers['Content-Disposition'] = 'attachment; filename=' + file_to_download.name

        return  file_to_download

@bottle.route('/editFilename')
def edit_page():
    # in comes device id, device type, and file id, and filename
    device_id = bottle.request.query.did
    fid = bottle.request.query.fid
    old_filename = bottle.request.query.ofn
    filedict = {'_id': ObjectId(fid), 'ofn': old_filename}
    device={'_id': ObjectId(device_id)}

    return bottle.template('file_control/edit_existing_filename.tpl', {'device':device, 'file':filedict})

@bottle.route('/updateFilename', method='POST')
def update_filename():
    # /updateFilename?fid=FILE_ID&did=DEVICE_ID&type=TYPE
    fid= ObjectId(bottle.request.query.fid)
    did= ObjectId(bottle.request.query.did)

    form_dict = bottle.request.forms
    new_name = str(form_dict['new_filename']) + str(form_dict['ext'])
    device_url = '/showDevice?id=' + str(did) + '#attached_files'
    db.fs.files.update({'_id': fid}, {'$set': {'filename': new_name}})
    return bottle.redirect(device_url)





@bottle.route('/removeFile')
def delete_file():
    # /removeFile?fid=FILE_ID&did=DEVICE_ID&type=TYPE
    fid= ObjectId(bottle.request.query.fid)
    did = ObjectId(bottle.request.query.did)
    device_url = '/showDevice?id=' + str(did) + '#attached_files'
    fs.delete(fid)
    return bottle.redirect(device_url)

@bottle.route('/removeDevice')
def delete_device():
    # Need to delete any files related to this device, then delete the device
    did = ObjectId(bottle.request.query.did)
    dtype = bottle.request.query.type
    results = db.fs.files.find({'device_id': did})
    for file in results:
        fs.delete(file['_id']) # delete all files associated with this entry
    if dtype == 'net':
        col = db.net_devices
    elif dtype == 'server':
        col = db.servers
    else:
        return bottle.redirect('/')

    col.remove(did)


    return bottle.redirect('/')





bottle.debug(True)
bottle.run(host='localhost', port=8080)

4. header.tpl

<!--TODO:PUT HEAD TAG HERE-->

<div id="title">
    <h1>IPAC</h1>
    <a href="https://github.com/jdell64/IPACS"><img src="header/IPAC_logo.png"></a>
    <p>Inventory, Preformance, and Capacity</p>
</div>

<div id="nav_bar">
    <ul id="nav">
        <li><a href="/">Home</a></li>
        <li><a href="/viewAll">View All Inventory</a></li>
        <li><a href="/about">About</a></li>
    </ul>
    <div class="clear_both"></div>
</div>

I don't really know how I could have made my code not portable. How to I fix this?

(Full code of everything in this is here.)

Was it helpful?

Solution 2

I am a bit embarrassed, but the issue was on my first machine, I was using bottle 0.12, and on the new one, I had an older version of bottle. Upgrade from bottle 0.10 fixed the issue.

OTHER TIPS

In debian stable: I had the same issue, looks like in the debian stable by default in the repository is the old one.

Using:

apt-get install python-pip
pip install bottle

fixed the issue

Thanks

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top