def __init__(self, parent=None): QDialog.__init__(self, parent) self.parent = parent self.setMinimumWidth(600) self.count = QLineEdit() self.price = QLineEdit() layoutGrid = QGridLayout() layoutGrid.setColumnStretch(1, 1) layoutGrid.setColumnMinimumWidth(1, 250) layoutGrid.addWidget(QLabel(_("Count")), 0, 0) layoutGrid.addWidget(self.count, 0, 1) layoutGrid.addWidget(QLabel(_("Price")), 1, 0) layoutGrid.addWidget(self.price, 1, 1) buttonApplyDialog = QPushButton(_("Apply")) buttonCancelDialog = QPushButton(_("Cancel")) self.connect(buttonApplyDialog, SIGNAL("clicked()"), self.applyDialog) self.connect(buttonCancelDialog, SIGNAL("clicked()"), self, SLOT("reject()")) buttonLayout = QHBoxLayout() buttonLayout.addStretch(1) buttonLayout.addWidget(buttonApplyDialog) buttonLayout.addWidget(buttonCancelDialog) layout = QVBoxLayout() layout.addLayout(layoutGrid) layout.addLayout(buttonLayout) self.setLayout(layout) self.setWindowTitle(_("Add resource"))
def assignRFID(self): def callback(rfid): self.rfid_id = rfid params = { 'http': self.http, 'static': self.static, 'mode': 'client', 'callback': callback, } dialog = WaitingRFID(self, params) dialog.setModal(True) dlgStatus = dialog.exec_() if QDialog.Accepted == dlgStatus: # check the rfid code params = {'rfid_code': self.rfid_id, 'mode': 'client'} if not self.http.request('/manager/get_client_info/', params): QMessageBox.critical(self, _('Client info'), _('Unable to fetch: %s') % self.http.error_msg) return default_response = None response = self.http.parse(default_response) if response and 'info' in response and response['info'] is not None: QMessageBox.warning(self, _('Warning'), _('This RFID is used already!')) else: self.buttonRFID.setText(self.rfid_id) self.buttonRFID.setDisabled(True)
def __init__(self, parent=None): QDialog.__init__(self, parent) self.parent = parent self.tabWidget = QTabWidget() self.tabWidget.addTab(TabGeneral(self), _('General')) self.tabWidget.addTab(TabNetwork(self), _('Network')) self.tabIndex = ['general', 'network'] applyButton = QPushButton(_('Apply')) cancelButton = QPushButton(_('Cancel')) self.connect(applyButton, SIGNAL('clicked()'), self.applyDialog) self.connect(cancelButton, SIGNAL('clicked()'), self, SLOT('reject()')) buttonLayout = QHBoxLayout() buttonLayout.addStretch(1) buttonLayout.addWidget(applyButton) buttonLayout.addWidget(cancelButton) mainLayout = QVBoxLayout() mainLayout.addWidget(self.tabWidget) mainLayout.addLayout(buttonLayout) self.setLayout(mainLayout) self.setWindowTitle(_('Settings')) # load settings self.settings = QSettings() self.loadSettings()
def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.mimes = {'team': 'application/x-team-item', 'event': 'application/x-calendar-event', } self.rooms = [] self.tree = [] self.rfid_id = None self.http = Http(self) self.work_hours = (8, 24) self.schedule_quant = timedelta(minutes=30) self.menus = [] self.create_menus() self.setup_views() settings = QSettings() settings.beginGroup('network') host = settings.value('addressHttpServer', QVariant('WrongHost')) settings.endGroup() if 'WrongHost' == host.toString(): self.setupApp() self.baseTitle = _('Manager\'s interface') self.logoutTitle() self.statusBar().showMessage(_('Ready'), 2000) self.resize(640, 480)
def reset(self): request = self.request registry = request.registry data, errors = self.extract() login = data.get('login') if login: principal = authService.get_principal_bylogin(login) if principal is not None and \ passwordTool.can_change_password(principal): passcode = passwordTool.generate_passcode(principal) template = ResetPasswordTemplate(principal, request) template.passcode = passcode template.send() self.request.registry.notify( ResetPasswordInitiatedEvent(principal)) self.message(_('Password reseting process has been initiated. ' 'Check your email for futher instructions.')) raise HTTPFound(location=request.application_url) self.message(_(u"System can't restore password for this user."))
def __init__(self, parent=None): QDialog.__init__(self, parent) self.parent = parent self.setMinimumWidth(400) self.calendar = QCalendarWidget() self.calendar.setFirstDayOfWeek(Qt.Monday) self.calendar.setGridVisible(True) self.calendar.setMinimumDate(QDate.currentDate()) self.calendar.showToday() buttonApplyDialog = QPushButton(_('Apply')) buttonCancelDialog = QPushButton(_('Cancel')) self.connect(buttonApplyDialog, SIGNAL('clicked()'), self.applyDialog) self.connect(buttonCancelDialog, SIGNAL('clicked()'), self, SLOT('reject()')) buttonLayout = QHBoxLayout() buttonLayout.addStretch(1) buttonLayout.addWidget(buttonApplyDialog) buttonLayout.addWidget(buttonCancelDialog) layout = QVBoxLayout() layout.addWidget(self.calendar) layout.addLayout(buttonLayout) self.setLayout(layout) self.setWindowTitle(_('Choose a week to fill'))
def get_static(self): """ Gets static information from server. First, all present rooms are L{retrieved<Http.request>}. They are returned as a dict in the following format:: {'rows': [{'color': 'FFAAAA', 'text': 'red', 'id': 1}, {'color': 'AAFFAA', 'text': 'green', 'id': 2}, ...]} Then, other static info is retrieved??? """ # get rooms if not self.http.request('/manager/get_rooms/', {}): QMessageBox.critical(self, _('Room info'), _('Unable to fetch: %s') % self.http.error_msg) return default_response = {'rows': []} response = self.http.parse(default_response) self.rooms = tuple( [ (a['title'], a['color'], a['id']) for a in response['rows'] ] ) self.schedule.update_static( {'rooms': self.rooms} ) # static info if not self.http.request('/manager/static/', {}): QMessageBox.critical(self, _('Static info'), _('Unable to fetch: %s') % self.http.error_msg) return response = self.http.parse() self.static = response print 'Static is', self.static.keys()
def context_menu(self, position): """ Create context menu.""" menu = QMenu() index = self.tableHistory.indexAt(position) model = index.model() # payment action_payment_add = menu.addAction(_('Payment')) need_to_add = self.payment_diff(index) if need_to_add < 0.01: action_payment_add.setDisabled(True) # cancel action_cancel = menu.addAction(_('Cancel')) idx_cancel = model.index(index.row(), self.COLUMN_CANCEL_INDEX) card_cancel = model.data(idx_cancel, Qt.DisplayRole) if type(card_cancel) is unicode: action_cancel.setDisabled(True) # show context menu action = menu.exec_(self.tableHistory.mapToGlobal(position)) # choose action if action == action_payment_add: self.payment_add(index, need_to_add) elif action == action_cancel: QMessageBox.warning(self, _('Warning'), _('Not yet implemented!')) else: print 'unknown'
def __init__(self, parent, params=dict()): self.mode = params.get('mode', 'client') self.apply_title = params.get('apply_title', _('Show')) if self.mode == 'client': self.title = _('Search client') else: self.title = _('Search renter') UiDlgTemplate.__init__(self, parent, params)
def _convertor(listitem): if type(listitem) is not dict: raise ValueError(_('It expexts a dictionary but took %s') % type(key_field)) if key_field not in listitem: raise KeyError(_('Key "%s" does not exists. Check dictionary.') % key_field) result.update( {listitem[key_field]: listitem} ) return True
def applyDialog(self): userinfo, ok = self.checkFields() if ok: rents_info = self.rentInfoModel.get_model_as_formset() self.saveSettings(userinfo, rents_info) self.accept() else: QMessageBox.warning(self, _('Warning'), _('Please fill required fields.'))
def applyDialog(self): try: count = int(self.count.text()) price = float(self.price.text()) except: QMessageBox.warning(self, _("Warning"), _("Improper values.")) return self.callback(count, price) self.accept()
def _search(listitem): if type(listitem) is not dict: raise ValueError(_('It expexts a dictionary but took %s') % type(key_field)) if key_field not in listitem: raise KeyError(_('Key "%s" does not exists. Check dictionary.') % key_field) if type(value) in (list, tuple): return listitem[key_field] in value else: return listitem[key_field] == value
def applyDialog(self): """ Apply settings. """ userinfo, ok = self.checkFields() if ok: if self.saveSettings(userinfo): self.accept() else: QMessageBox.warning(self, _('Warning'), _('Please fill all fields.'))
def exchangeRooms(self): exchanged = self.model().exchangeRoom(self.current_data, self.selected_data) if exchanged: data = self.current_data self.current_data = self.selected_data self.selected_data = data self.parent.statusBar().showMessage(_('Complete.')) else: self.parent.statusBar().showMessage(_('Unable to exchange.'))
def login(self): ''' Shows log in dialog, where manager is asked to provide login/password pair. If 'Ok' button is clicked, authentication L{request<Http.request>} is made to the server, which is then L{parsed<Http.parse>}. On success: - information about schedule is retrieved from the server and and L{QtSchedule} widget is L{updated<update_interface>}. - controls are L{activated<interface_disable>}. - window title is L{updated<loggedTitle>} - schedule information is being L{refreshed<refresh_data>} from now on. In case of failure to authenticate a message is displayed. ''' def callback(credentials): self.credentials = credentials self.dialog = DlgLogin(self) self.dialog.setCallback(callback) self.dialog.setModal(True) dlgStatus = self.dialog.exec_() if QDialog.Accepted == dlgStatus: if not self.http.request('/manager/login/', self.credentials): QMessageBox.critical(self, _('Login'), _('Unable to login: %s') % self.http.error_msg) return default_response = None response = self.http.parse(default_response) if response and 'user_info' in response: self.loggedTitle(response['user_info']) # update application's interface self.get_static() self.get_dynamic() self.update_interface() self.schedule.model().showCurrWeek() # run refresh timer self.refreshTimer = QTimer(self) from settings import SCHEDULE_REFRESH_TIMEOUT self.refreshTimer.setInterval(SCHEDULE_REFRESH_TIMEOUT) self.connect(self.refreshTimer, SIGNAL('timeout()'), self.refresh_data) self.refreshTimer.start() self.interface_disable(False) else: QMessageBox.warning(self, _('Login failed'), _('It seems you\'ve entered wrong login/password.'))
def client_search_rfid(self): ''' Search client in the database by RFID (Radio Frequency IDentificator). After RFID was successfully read from card, server is L{requested<Http.request>} client info. If user is found in database, L{dialog<ClientInfo>} with information about client is displayed. Otherwise, messageboxes with warnings are displayed. ''' if not self.http or not self.http.is_session_open(): return # login first def callback(rfid): self.rfid_id = rfid params = { 'http': self.http, 'static': self.static, 'mode': 'client', 'callback': callback, } dialog = WaitingRFID(self, params) dialog.setModal(True) dlgStatus = dialog.exec_() if QDialog.Accepted == dlgStatus and self.rfid_id is not None: params = {'rfid_code': self.rfid_id, 'mode': 'client'} if not self.http.request('/manager/get_client_info/', params): QMessageBox.critical(self, _('Client info'), _('Unable to fetch: %s') % self.http.error_msg) return default_response = None response = self.http.parse(default_response) if not response or response['info'] is None: QMessageBox.warning(self, _('Warning'), _('This RFID belongs to nobody.')) else: user_info = response['info'] params = { 'http': self.http, 'static': self.static, } self.dialog = ClientInfo(self, params) self.dialog.setModal(True) self.dialog.initData(user_info) self.dialog.exec_() self.rfid_id = None
def searchFor(self): name = self.editSearch.text().toUtf8() params = {'name': name, 'mode': self.mode} if not self.http.request('/manager/get_users_info_by_name/', params): QMessageBox.critical(self, _('Searching'), _('Unable to search: %s') % self.http.error_msg) return default_response = None response = self.http.parse(default_response) if response and 'users' in response: user_list = response['users'] self.showList(user_list) self.buttonApply.setDisabled(False)
def send_success_mail(self, raw_password): ''' send success emails ''' # prepare context context = { 'node': self, 'password': raw_password, 'site': SITE } # send email to owners email_owners(self, _('Node confirmed successfully on %(site)s') % {'site':SITE['name']}, 'email_notifications/success.txt', context) # notify admins that want to receive notifications notify_admins(self, _('New node details on %(site)s') % {'site':SITE['name']}, 'email_notifications/new-node-admin.txt', context, skip=True)
def __init__(self, parent=None): QTableView.__init__(self, parent) self.verticalHeader().setResizeMode(QHeaderView.Fixed) self.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents) self.actionRentCancel = QAction(_('Cancel rent'), self) self.actionRentCancel.setStatusTip(_('Cancel current rent.')) self.connect(self.actionRentCancel, SIGNAL('triggered()'), self.rentCancel) self.delegate = RentListDelegate() self.setItemDelegate(self.delegate)
def checkFields(self): userinfo = { 'last_name': self.editLastName.text().toUtf8(), 'first_name': self.editFirstName.text().toUtf8(), 'email': self.editEmail.text().toUtf8(), 'phone_mobile': self.editPhoneMobile.text().toUtf8(), 'phone_work': self.editPhoneWork.text().toUtf8(), 'phone_home': self.editPhoneHome.text().toUtf8(), } errorHighlight = [] phones = 0 for title, widget in [(_('Last name'), self.editLastName), (_('First name'), self.editFirstName), (_('E-mail'), self.editEmail)]: if 0 == len(widget.text().toUtf8()): errorHighlight.append(title) for title, widget in [(_('Mobile phone'), self.editPhoneMobile), (_('Work phone'), self.editPhoneWork), (_('Home phone'), self.editPhoneHome)]: if 0 < len(widget.text().toUtf8()): phones += 1 if phones == 0: errorHighlight.append(_('Phones')) if len(errorHighlight) > 0: QMessageBox.critical( self.parent, _('Dialog error'), 'Fields %s must be filled.' % ', '.join(errorHighlight)) return (userinfo, False) return (userinfo, True)
class UserProfile(models.Model): """ Extending django's user model so we can have an additional field where we can specify if admins should receive notifications or not https://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users """ user = models.OneToOneField(User) receive_notifications = models.BooleanField( _('Email notifications'), help_text= _('Activate/deactivate email notifications about the management of the map server (added nodes, deleted nodes, abuses, ecc).' ))
def saveSettings(self, userinfo): default_response = None # save client's information params = { 'user_id': self.client_id, } params.update(userinfo) if not self.http.request('/manager/set_client_info/', params): QMessageBox.critical(self, _('Save info'), _('Unable to save: %s') % self.http.error_msg) return response = self.http.parse(default_response) if not response: error_msg = self.http.error_msg message = _('Unable to save client\'s info!\nReason:\n%s') % error_msg QMessageBox.warning(self, _('Saving'), message) return False # save client's card model = self.tableHistory.model() params = model.get_model_as_formset(response['saved_id']) if not self.http.request('/manager/set_client_card/', params): QMessageBox.critical(self, _('Save cards'), _('Unable to save: %s') % self.http.error_msg) return response = self.http.parse(default_response) if not response: error_msg = self.http.error_msg message = _('Unable to save client\'s card!\nReason:\n%s') % error_msg QMessageBox.warning(self, _('Saving'), message) return False return True
def initData(self, obj, index): """ Use this method to initialize the dialog. """ self.schedule_object = obj self.schedule_index = index # get the event's information if not self.http.request('/manager/get_event_info/', {'id': self.schedule_object.id}): QMessageBox.critical(self, _('Event info'), _('Unable to fetch: %s') % self.http.error_msg) return default_response = None response = self.http.parse(default_response) self.schedule = response['info'] event = self.schedule['event'] status = self.schedule.get('status', 0) # 0 means wainting room = self.schedule['room'] self.editStyle.setText(event['dance_styles']) self.editPriceCategory.setText( event['price_category']['title'] ) if self.schedule_object.isTeam(): # get coaches list from schedule, not from team, because of exchange coaches_list = self.schedule.get('coaches', None) if coaches_list: title = ', '.join([i['name'] for i in coaches_list]) else: title = _('Unknown') self.editCoaches.setText(title) begin = __(self.schedule['begin_datetime']) end = __(self.schedule['end_datetime']) self.editBegin.setDateTime(QDateTime(begin)) self.editEnd.setDateTime(QDateTime(end)) current_id = int(room['id']) self.current_room_index = current_id - 1 for title, color, room_id in self.parent.rooms: self.comboRoom.addItem(title, QVariant(room_id)) if id == current_id + 100: current = self.comboRoom.count() - 1 self.comboRoom.setCurrentIndex(self.current_room_index) # disable controls for events in the past is_past = begin < datetime.now() self.buttonRemove.setDisabled(is_past) self.buttonVisitRFID.setDisabled(is_past) self.buttonVisitManual.setDisabled(is_past) self.buttonChange.setDisabled(is_past) self._init_fix(status)
def load_data(self): ''' Requests information about current timetable from the server. Only performes request, if schedule is currently showing weekly, not daily, timetable. If request is successful, list of events is obtained from server, which are then added to the model one by one using L{insert} method. Of failure, status bar of the main window gets updated with the error message. @important: Reimplement non-object-oriented handlement of status bar messages. ''' if 'day' == self.mode: return False # THIS IS UGLY!!! NEED TO REIMPLEMENT self.parent.parent.statusBar().showMessage(_('Request information for the calendar.')) monday, sunday = self.weekRange http = self.params.get('http', None) if http and http.is_session_open(): params = { 'monday': monday, 'filter': [] } http.request('/manager/get_week/', params) # FIXME: wrong place for HTTP Request! self.parent.parent.statusBar().showMessage(_('Parsing the response...')) response = http.parse(None) # result processing if response and 'events' in response: self.parent.parent.statusBar().showMessage(_('Filling the calendar...')) self.storage_init() # place the event in the model for event_info in response['events']: qApp.processEvents() # keep GUI active room_id = int( event_info['room']['id'] ) event_obj = Event(monday, event_info) self.insert( room_id , event_obj ) # draw events self.emit(SIGNAL('layoutChanged()')) self.parent.parent.statusBar().showMessage(_('Done'), 2000) # debugging #self.storage.dump() return True else: self.parent.parent.statusBar().showMessage(_('No reply')) return False
def initData(self, event_id): self.event_id = event_id if not self.http.request('/manager/get_visitors/', {'event_id': event_id}): QMessageBox.critical(self, _('Visitors'), _('Unable to fetch: %s') % self.http.error_msg) return default_response = None response = self.http.parse(default_response) visitor_list = response['visitor_list'] for last_name, first_name, rfid_code, reg_datetime in visitor_list: lastRow = self.tableVisitors.rowCount() self.tableVisitors.insertRow(lastRow) self.tableVisitors.setItem(lastRow, 0, QTableWidgetItem(last_name)) self.tableVisitors.setItem(lastRow, 1, QTableWidgetItem(first_name)) self.tableVisitors.setItem(lastRow, 2, QTableWidgetItem(rfid_code)) self.tableVisitors.setItem(lastRow, 3, QTableWidgetItem(reg_datetime))
class Device(models.Model): name = models.CharField(_('name'), max_length=50, unique=True) # TODO: add translation cname = models.SlugField( _('CNAME'), help_text= _('Name used for DNS resolution. Example: grid1 becomes grid1.nodename.domain.org. If left empty device name is used as default.' ), max_length=30, blank=True, null=True) description = models.CharField(_('description'), max_length=255, blank=True, null=True) type = models.CharField(_('type'), max_length=50, blank=True, null=True) node = models.ForeignKey(Node, verbose_name=_('node')) routing_protocol = models.CharField(_('routing protocol'), max_length=20, choices=ROUTING_PROTOCOLS, default=DEFAULT_ROUTING_PROTOCOL) routing_protocol_version = models.CharField(_('routing protocol version'), max_length=10, blank=True, null=True) added = models.DateTimeField(_('added on'), auto_now_add=True) updated = models.DateTimeField(_('updated on'), auto_now=True) def save(self): """ defaults CNAME to slugify(name) this is needed for the frontend. Backend is taken care by forms.py """ if not self.cname or self.cname == '': self.cname = slugify(self.name) super(Device, self).save() def __unicode__(self): return self.name class Meta: unique_together = (('node', 'cname'), ) verbose_name = _('Device') verbose_name_plural = _('Devices') @permalink def get_absolute_url(self): return ('nodeshot_select', None, {'slug': self.node.slug})
def parse(self, default={}): # public ''' Analyze response from server. - If succeeds, returns parsed JSON data as a dict; - On success in http status and error in JSON puts error message in .error_msg - On failure of http request recognizes requirement to authenticate (error 302), internal server error (error 500), in which case content of response is dumped into file ./dump.html - Unrecognized errors in http request are written to .error_msg In every case of failure 'default' value of http response is returned. @type default: dict @param default: Value to return in case of failure. @rtype: dict @return: Dictionary representing json data in response. ''' if not self.response: # request failed return None if self.response.status == 200: # http status data = self.response.read() # Decode JSON data from response # 2.5 and 2.6 versions compatibility included if hasattr(json, 'read'): response = json.read(data) # 2.5 else: response = json.loads(data) # 2.6 # if JSON response code is not equal to 200, something weird # happened # else, return decoded response if 'code' in response and response['code'] != 200: self.error_msg = '[%(code)s] %(desc)s' % response return default return response elif self.response.status == 302: # authentication self.error_msg = _('Authenticate yourself.') return default elif self.response.status == 500: # error self.error_msg = _('Error 500. Check dump!') open('./dump.html', 'w').write(self.response.read()) else: self.error_msg = '[%s] %s' % (self.response.status, self.response.reason) return default
def client_search_name(self): ''' Search client in the database by name. First it launches client search L{dialog<Searching>}, which tries to fetch unique user_id from the server based on information provided. If that succeeds, user_id-based search then Works analogously to L{RFID-based<client_search_rfid>} search. ''' if not self.http or not self.http.is_session_open(): return # login first def callback(user_id): self.user_id = user_id params = { 'http': self.http, 'static': self.static, 'mode': 'client', 'apply_title': _('Show'), } self.dialog = Searching(self, params) self.dialog.setModal(True) self.dialog.setCallback(callback) dlgStatus = self.dialog.exec_() if QDialog.Accepted == dlgStatus: if not self.http.request('/manager/get_client_info/', {'user_id': self.user_id, 'mode': 'client'}): QMessageBox.critical(self, _('Client info'), _('Unable to fetch: %s') % self.http.error_msg) return default_response = None response = self.http.parse(default_response) if not response or response['info'] is None: QMessageBox.warning(self, _('Warning'), _('This RFID belongs to nobody.')) else: params = { 'http': self.http, 'static': self.static, } self.dialog = ClientInfo(self, params) self.dialog.setModal(True) self.dialog.initData(response['info']) self.dialog.exec_()
def send_success_mail(self, raw_password): ''' send success emails ''' # prepare context context = {'node': self, 'password': raw_password, 'site': SITE} # send email to owners email_owners( self, _('Node confirmed successfully on %(site)s') % {'site': SITE['name']}, 'email_notifications/success.txt', context) # notify admins that want to receive notifications notify_admins(self, _('New node details on %(site)s') % {'site': SITE['name']}, 'email_notifications/new-node-admin.txt', context, skip=True)
def reset_password(self, petitioner): """ Resets the password of a node and send an email to the owners with the new password. petitioner: string containing the email address of who's requesting the password reset returns the raw password """ import random bit1 = ''.join( random.choice('abcdefghilmnopqrstuvz') for i in xrange(5)) bit2 = ''.join(random.choice('0123456789') for i in xrange(2)) raw_password = bit1 + bit2 self.password = raw_password self.set_password() self.save() # prepare context context = { 'petitioner': petitioner, 'node': self, 'password': raw_password, 'site': SITE } # send mail email_owners(self, _('New password for node %(name)s') % {'name': self.name}, 'email_notifications/password_recovery.txt', context) return raw_password
def handleLogin(self): request = self.request data, errors = self.extract() if errors: self.message(errors, 'form-error') return info = ptah.authService.authenticate(data) if info.status: request.registry.notify( ptah.events.LoggedInEvent(info.principal)) headers = security.remember(request, info.principal.uri) raise HTTPFound( headers = headers, location = '%s/login-success.html'%request.application_url) if info.principal is not None: request.registry.notify( ptah.events.LoginFailedEvent(info.principal, info.message)) if info.arguments.get('suspended'): raise HTTPFound( location='%s/login-suspended.html'%request.application_url) if info.message: self.message(info.message, 'warning') return self.message(_('You enter wrong login or password.'), 'error')
def initData(self, data=dict()): self.client_id = data.get('id', '0') meta = [('last_name', self.editLastName), ('first_name', self.editFirstName), ('email', self.editEmail), ('phone', self.editPhone), ] for key, obj in meta: text = data.get(key, '') obj.setText(text) obj.setToolTip(text) discount = data.get('discount', None) if discount: index = self.comboDiscount.findData(QVariant( int(discount.get('id', 0)) )) self.comboDiscount.setCurrentIndex( index ) def str2date(value): return datetime.strptime(value, '%Y-%m-%d').date() birth_date = data.get('birth_date', None) # it could be none while testing self.dateBirth.setDate(birth_date and str2date(birth_date) or \ QDate.currentDate()) rfid = data.get('rfid_code', None) if rfid: self.buttonRFID.setText(rfid) self.buttonRFID.setToolTip(_('RFID code of this client.')) self.buttonRFID.setDisabled(True) # fill the card list card_list = data.get('team_list', []) self.tableHistory.model().initData(card_list)
def parse_address(local_address, str): check.check_is_af_inet_address(local_address) #=@R19 try: match = re.match(r"\s*(.+)\s*:\s*([0-9]+)\s*$", str) if match: ret = (socket.gethostbyname(match.group(1)), string.atoi(match.group(2))) else: match = re.match(r"\s*([0-9]+)\s*$", str) if match: ret = (local_address[0], string.atoi(match.group(1))) else: ret = (socket.gethostbyname(string.strip(str)), settings.default_ports[0]) check.check_is_af_inet_address(ret) #=@E9 # Proof: socket.gethostbyname returns a string, atoi returns an int, # settings.default_ports is a non-empty list of integers. # local_address is itself an af_inet_address (@R19), so its first # element is a string suitable for an af_inet_address. local_address # is deeply immutable from @E11. return ret except: raise error.Error(_("Could not find peer.\n"+\ "Please give a valid IP address or machine name,\n"+\ "optionally followed by a colon and a port number"))
class Contact(models.Model): node = models.ForeignKey(Node) from_name = models.CharField(_('name'), max_length=50) from_email = models.EmailField(_('email'), max_length=50) message = models.CharField(_('message'), max_length=2000) ip = models.GenericIPAddressField(verbose_name=_('ip address')) user_agent = models.CharField(max_length=200, blank=True) http_referer = models.CharField(max_length=200, blank=True) accept_language = models.CharField(max_length=60, blank=True) date = models.DateTimeField(auto_now_add=True) def __unicode__(self): return _(u'Message from %(from)s to %(to)s') % ({ 'from': self.from_name, 'to': self.node.name }) class Meta: verbose_name = _('Contact Log') verbose_name_plural = _('Contact Logs')
def send_activation_mail(self): """ Sends activation link to node owners """ # prepare context for email template context = { 'node': self, 'expiration_days': ACTIVATION_DAYS, 'site': SITE, } # send mail to owners email_owners( self, _('Node confirmation required on %(site)s') % {'site': SITE['name']}, 'email_notifications/confirmation.txt', context)
class TvStoreUnit(models.Model): id = models.UUIDField(verbose_name=_('UUID'), default=uuid.uuid4, primary_key=True, unique=True, null=False, blank=False, editable=False) name = models.CharField(verbose_name=_('name'), max_length=200) ftp_url = models.CharField(verbose_name=_('ftp_url'), max_length=200, default=DEFAULT_UNIT_FTP_URL) serial_nr = models.CharField(verbose_name=_('serial_nr'), max_length=200, unique=True, null=False, blank=False, db_index=True, default=DEFAULT_UNIT_SERIAL_NR) creation_date = models.DateTimeField(default=timezone.now) expire_date = models.DateTimeField(null=True, blank=True) group = models.ForeignKey(Group, verbose_name=_('group'), null=True, on_delete=models.SET_NULL) user = models.ForeignKey(User, verbose_name=_('user'), null=True, on_delete=models.SET_NULL) js_attributes = models.TextField(_(u'js_attributes'), null=False, blank=True) def user_name(self): if self.user: return self.user.username
def clean(self): """ Require at least one of ipv4 or ipv6 to be set """ if not (self.ipv4_address or self.ipv6_address or self.mac_address): raise ValidationError( _('At least one of the following field is necessary: IPv4, IPv6 or Mac address.' )) # double check needed - don't know why if self.mac_address == '': self.mac_address = None if self.ipv4_address == '': self.ipv4_address = None if self.ipv6_address == '': self.ipv6_address = None
class Statistic(models.Model): active_nodes = models.IntegerField(_('active nodes')) potential_nodes = models.IntegerField(_('potential nodes')) hotspots = models.IntegerField(_('hotspots')) links = models.IntegerField(_('active links')) km = models.FloatField(_('Km')) date = models.DateTimeField(_('Added on'), auto_now_add=True) def __unicode__(self): return u'%s' % (self.date) class Meta: verbose_name = _('Statistic') verbose_name_plural = _('Statistics')
class Link(models.Model): from_interface = models.ForeignKey(Interface, related_name='from_interface') to_interface = models.ForeignKey(Interface, related_name='to_interface') etx = models.FloatField(default=0) dbm = models.IntegerField(default=0) sync_tx = models.IntegerField(default=0) sync_rx = models.IntegerField(default=0) hide = models.BooleanField(_('Hide from map'), default=False) def get_quality(self, type='etx'): """ used to determine color of links""" if type == 'etx': if 0 < self.etx < 1.5: quality = 1 elif self.etx < 3: quality = 2 else: quality = 3 elif type == 'dbm': if -83 < self.dbm < 0: quality = 1 elif self.dbm > -88: quality = 2 else: quality = 3 return quality def get_etx(self): """ return etx as a string to avoid dot to comma conversion (it happens only with certain LANGUAGE_CODEs like IT)""" return str(self.etx) def __unicode__(self): return u'%s » %s' % (self.from_interface.device, self.to_interface.device) class Meta: verbose_name = _('Link') verbose_name_plural = _('Links')
#!/usr/bin/python # -*- coding: utf-8 -*- from django.db import models from settings import _ from django.core.exceptions import ObjectDoesNotExist from easy_thumbnails.files import get_thumbnailer # Create your models here. PART_OF_SPEECH_CHOICES = [ ('NOUN', _('Noun')), ('VERB', _('Verb')), ('ADJECTIVE', _('Adjective')), ('ADVERB', _('Adverb')), ] class Icon(models.Model): icon = models.FileField(upload_to='icons', blank=False) color_mode = models.IntegerField(blank=True, null=True, choices=[(0, "B&W"), (1, "Color")]) def icon_thumbnail(self): source = self.icon thumbnail_options = dict(size=(64, 64), crop=False, bw=False)
class TvStoreContact(models.Model): STATUS = ( (0, _(u"in progress")), (1, _(u"completed")), (2, _(u"aborted")), (3, _(u"saved")), ) TYPES = ( (0, _(u"PING" )), (1, _(u"CREATE")), (2, _(u"UPDATE")), (3, _(u"ALERT" )), ) id = models.UUIDField(verbose_name=_('UUID'), default=uuid.uuid4, primary_key=True, unique=True, null=False, blank=False, editable=False) type = models.PositiveIntegerField(choices=TYPES, default=0, null=False, db_index=True) status = models.PositiveIntegerField(choices=STATUS, default=0, null=False, db_index=True) creation_date = models.DateTimeField(default=timezone.now) unit = models.ForeignKey(TvStoreUnit, verbose_name=_('unit'), null=True, on_delete=models.SET_NULL) user = models.ForeignKey(User, verbose_name=_('user'), null=True, on_delete=models.SET_NULL) unit_serial_nr = models.CharField(verbose_name=_('unit_serial_nr'), max_length=200, unique=False, null=False, blank=False, default=DEFAULT_UNIT_SERIAL_NR) js_attributes = models.TextField(_(u'js_attributes'), null=False, blank=True) def unit_name(self): return self.unit.name
class Meta: verbose_name = _('Node') verbose_name_plural = _('Nodes')
class Meta: unique_together = (('node', 'cname'), ) verbose_name = _('Device') verbose_name_plural = _('Devices')
class Meta: verbose_name = _('Hna') verbose_name_plural = _('Hna')
class Node(models.Model): name = models.CharField(_('name'), max_length=50, unique=True) slug = models.SlugField(max_length=50, db_index=True, unique=True) owner = models.CharField(_('owner'), max_length=50, blank=True, null=True) description = models.CharField(_('description'), max_length=200, blank=True, null=True) postal_code = models.CharField(_('postal code'), max_length=10, blank=True) email = models.EmailField() email2 = models.EmailField(blank=True, null=True) email3 = models.EmailField(blank=True, null=True) password = models.CharField( max_length=255, help_text= _('Use "[algo]$[salt]$[hexdigest]" or use the <a href="password/">change password form</a>.' )) lat = models.FloatField(_('latitude')) lng = models.FloatField(_('longitude')) alt = models.FloatField(_('altitude'), blank=True, null=True) status = models.CharField(_('status'), max_length=3, choices=NODE_STATUS, default='p') activation_key = models.CharField( _('activation key'), max_length=40, blank=True, null=True, help_text= _('Key needed for activation of the node. It\'s deleted once the node is activated.' )) notes = models.TextField(_('notes'), blank=True, null=True) added = models.DateTimeField(_('added on'), auto_now_add=True) updated = models.DateTimeField(_('updated on'), auto_now=True) def get_lat(self): """ returns latitude as string (avoid django converting the dot . into a comma , in certain language sets) """ return str(self.lat) def get_lng(self): """ returns longitude as string (avoid django converting the dot . into a comma , in certain language sets) """ return str(self.lng) def set_password(self): """ Encrypts node.password with salt and sha1. The password property must have been set previously (node.password = '******') """ self.password = make_password('sha1', self.password) return self.password def check_password(self, raw_password): """ Returns a boolean of whether the raw_password was correct. Handles encryption formats behind the scenes. """ return check_password(raw_password, self.password) def reset_password(self, petitioner): """ Resets the password of a node and send an email to the owners with the new password. petitioner: string containing the email address of who's requesting the password reset returns the raw password """ import random bit1 = ''.join( random.choice('abcdefghilmnopqrstuvz') for i in xrange(5)) bit2 = ''.join(random.choice('0123456789') for i in xrange(2)) raw_password = bit1 + bit2 self.password = raw_password self.set_password() self.save() # prepare context context = { 'petitioner': petitioner, 'node': self, 'password': raw_password, 'site': SITE } # send mail email_owners(self, _('New password for node %(name)s') % {'name': self.name}, 'email_notifications/password_recovery.txt', context) return raw_password def set_activation_key(self): ''' Set the activation key, generate it from a combinatin of the ''Node''s name and a random salt ''' salt = sha_constructor(str(random.random())).hexdigest()[:5] self.activation_key = sha_constructor(salt + self.slug).hexdigest() return self.activation_key def send_activation_mail(self): """ Sends activation link to node owners """ # prepare context for email template context = { 'node': self, 'expiration_days': ACTIVATION_DAYS, 'site': SITE, } # send mail to owners email_owners( self, _('Node confirmation required on %(site)s') % {'site': SITE['name']}, 'email_notifications/confirmation.txt', context) def send_success_mail(self, raw_password): ''' send success emails ''' # prepare context context = {'node': self, 'password': raw_password, 'site': SITE} # send email to owners email_owners( self, _('Node confirmed successfully on %(site)s') % {'site': SITE['name']}, 'email_notifications/success.txt', context) # notify admins that want to receive notifications notify_admins(self, _('New node details on %(site)s') % {'site': SITE['name']}, 'email_notifications/new-node-admin.txt', context, skip=True) def confirm(self): ''' * change status from ''unconfirmed'' to ''potential'' * clear the ''activation_key'' field * encrypt password * send email with details of the node to owners ''' self.status = 'p' self.activation_key = '' raw_password = self.password self.set_password() self.save() self.send_success_mail(raw_password) def save(self): ''' Override the save method in order to generate the activation key for new nodes. ''' # generate slug if needed if self.slug == '': self.slug = slugify(self.name) # if saving a new object if self.pk is None and not IS_SCRIPT: self.set_activation_key() super(Node, self).save() # confirmation email is sent afterwards so we can send the ID self.send_activation_mail() else: super(Node, self).save() def __unicode__(self): return u'%s' % (self.name) class Meta: verbose_name = _('Node') verbose_name_plural = _('Nodes') @permalink def get_absolute_url(self): return ('nodeshot_select', None, {'slug': self.slug})
class Interface(models.Model): ipv4_address = models.IPAddressField(verbose_name=_('ipv4 address'), blank=True, null=True, unique=True, default=None) ipv6_address = models.GenericIPAddressField(protocol='IPv6', verbose_name=_('ipv6 address'), blank=True, null=True, unique=True, default=None) mac_address = models.CharField(max_length=17, blank=True, null=True, unique=True, default=None) type = models.CharField(max_length=10, choices=INTERFACE_TYPE) # TODO: add translation cname = models.SlugField( _('cname'), help_text= _('Name used for DNS resolution. Example: eth0 becomes eth0.devicecname.nodename.domain.org. If left empty the interface type is used as default.' ), max_length=30, blank=True, null=True) device = models.ForeignKey(Device) draw_link = models.BooleanField( _('Draw links'), help_text=_( 'Draw links from/to this interface (not valid for VPN interfaces)' ), default=True, blank=True) wireless_mode = models.CharField(max_length=5, choices=WIRELESS_MODE, blank=True, null=True) wireless_channel = models.CharField(max_length=4, choices=WIRELESS_CHANNEL, blank=True, null=True) wireless_polarity = models.CharField(max_length=1, choices=WIRELESS_POLARITY, blank=True, null=True) essid = models.CharField(max_length=50, null=True, blank=True, default=None) bssid = models.CharField(max_length=50, null=True, blank=True, default=None) status = models.CharField(_('status'), max_length=1, choices=INTERFACE_STATUS, default='u') added = models.DateTimeField(auto_now_add=True, ) updated = models.DateTimeField(auto_now=True) def __unicode__(self): if self.ipv4_address: value = self.ipv4_address elif self.ipv6_address: value = self.ipv6_address elif self.mac_address: value = 'MAC: %s' % self.mac_address else: value = self.device.name return value def clean(self): """ Require at least one of ipv4 or ipv6 to be set """ if not (self.ipv4_address or self.ipv6_address or self.mac_address): raise ValidationError( _('At least one of the following field is necessary: IPv4, IPv6 or Mac address.' )) # double check needed - don't know why if self.mac_address == '': self.mac_address = None if self.ipv4_address == '': self.ipv4_address = None if self.ipv6_address == '': self.ipv6_address = None def save(self): """ defaults CNAME to interface type (eth, wifi, ecc.) this is needed for the frontend. Backend is taken care by forms.py """ # if cname hasn't been filled if not self.cname or self.cname == '': # try to default to interface type try: self.cname = self.type super(Interface, self).save() # if there's another interface with same type we'll get an exception that we are catching now except: # add a number to the cname i = 2 # loop until we find a number which won't cause the error. Example: eth2, eth3, eth4 while True: self.cname = '%s%s' % (self.type, i) try: # try to save super(Interface, self).save() break except: # if still getting error increment and retry i = i + 1 else: super(Interface, self).save() @permalink def get_absolute_url(self): return ('nodeshot_select', None, {'slug': self.device.node.slug}) class Meta: unique_together = (('device', 'cname'), ) verbose_name = _('Interface') verbose_name_plural = _('Interfaces')
class Meta: verbose_name = _('Contact Log') verbose_name_plural = _('Contact Logs')
def __unicode__(self): return _(u'Message from %(from)s to %(to)s') % ({ 'from': self.from_name, 'to': self.node.name })
class Meta: verbose_name = _('Statistic') verbose_name_plural = _('Statistics')
class Meta: verbose_name = _('Link') verbose_name_plural = _('Links')
try: from django.contrib.auth.utils import make_password, check_password # django <= 1.3 except ImportError: from nodeshot.utils import make_password, check_password from settings import ROUTING_PROTOCOLS, DEFAULT_ROUTING_PROTOCOL, ACTIVATION_DAYS, DEFAULT_FROM_EMAIL, SITE, _ # IS_SCRIPT is defined in management scripts to avoid sending notifications try: IS_SCRIPT except: IS_SCRIPT = False NODE_STATUS = ( ('p', _('potential')), ('a', _('active')), ('h', _('hotspot')), ('ah', _('active & hotspot')), ('u', _('unconfirmed')), # nodes that have not been confirmed via email yet #('i', _('inactive')), ) INTERFACE_TYPE = (('wifi', _('wifi')), ('eth', _('ethernet')), ('vpn', _('vpn')), ('batman', _('batman')), ('bridge', _('bridge')), ('vwifi', _('virtual-wifi')), ('veth', _('virtual-ethernet'))) INTERFACE_STATUS = (('r', _('reachable')), ('u', _('unreachable')))
class Meta: unique_together = (('device', 'cname'), ) verbose_name = _('Interface') verbose_name_plural = _('Interfaces')