Уведомления

Группа в Telegram: @pythonsu

Уведомления

  • Found 3494 posts.

Python для новичков » Создание объектов скрипта » Авг. 23, 2017 11:02:23

Есть задача запускать музыку на разных устройствах одновременно на raspberry pi. Так как единственная библиотека, подходящая по большему числу критериев - python-sounddevice, выбрал ее.
Но столкнулся с проблемой она написана не классом. Собственно написал отдельный скрипт запуска и обработки музыки, и запускаю этот скрипт с основной программы. Но тут возникла еще одна проблема - время загрузки разных треков разное и время на запуск скрипта не постоянно.
Можно ли каким-нибудь образом более точно и стабильно управлять этими процессами. (например загрузить все треки в память и давать указатели, неявное управление этими процессами)
Буду благодарен за пинок в нужную сторону.

Скрипт воспроизведения и записи треков:
 import argparse
import os
import sys
import sounddevice as sd
import soundfile as sf
class Music:
    __record_flag = False
    __playing_flag = False
    __current_time = 0
    __fs = 48000
    __duration = 5  # seconds
    sd.default.samplerate = __fs
    def __init__(self):
        self.parser = self.create_parser()
        self.myrecording = None
        self.file_name = self.parser.file
        sd.default.channels = tuple(map(int, self.parser.channels))
        sd.default.device = tuple(map(int, self.parser.device))
        self.mode = self.parser.mode
        self.__duration = int(self.parser.time)
        self.__loop = self.parser.loop.__contains__("True")
    @staticmethod
    def create_parser():
        parser = argparse.ArgumentParser()
        parser.add_argument('-c', '--channels', nargs='+')
        parser.add_argument('-d', '--device', nargs='+')
        parser.add_argument('-m', '--mode', default="play")
        parser.add_argument('-f', '--file', default="./resources/sounds/game.wav")
        parser.add_argument('-t', '--time', default="20")
        parser.add_argument('-p', '--pid', default="pid.txt")
        parser.add_argument('-l', '--loop', default="False")
        # print(parser.parse_args(sys.argv[1:]))
        return parser.parse_args(sys.argv[1:])
    def record(self):
        print("Start recording")
        myrecording = sd.rec(self.__duration * self.__fs)
        sd.wait()
        print("Recorded successful")
        # self.sd.play(myrecording)
        # self.sd.wait()
        sf.write(self.file_name, myrecording, self.__fs)
    def play_audio(self, arr):
        # print(self.__playing_flag)
        sd.play(arr, loop=self.__loop)
        sd.wait()
    def play_rec(self, arr):
        sd.playrec(arr)
        sd.wait()
    def stop_playing(self):
        # self.sd.play("./res/non.wav")
        sd.stop()
    def play_file(self):
        print("playing track")
        data, fs = sf.read(self.file_name)
        self.play_audio(data)
    def do_reverse(self):
        data, fs = sf.read(self.file_name)
        sf.write(self.file_name, data[::-1], fs)
    def show(self):
        print(sd.query_devices())
music = Music()
# music.show()
if music.mode == 'play':
    music.f = open(music.parser.pid, 'w')
    music.pid = str(os.getpid())
    # print(music.pid)
    music.f.write(music.pid)
    music.f.close()
    music.play_file()
elif music.mode == 'record':
    music.record()
elif music.mode == "reverse":
    music.do_reverse()
elif music.mode == "stop":
    music.stop_playing()
elif music.mode == 'play_rec':
    music.f = open(music.parser.pid, 'w')
    music.pid = str(os.getpid())
    # print(music.pid)
    music.f.write(music.pid)
    music.f.close()
    music.play_file()
# print("thats all")

Python для новичков » debug в IDE Spyder » Авг. 22, 2017 11:33:08

Не могу нормально дебажиться, потому что даже с точками останова весь скрипт пробегает целиком, разумеется, в режиме дебага, что я могу делать не так, какие настройки проверить?

Python для экспертов » Shell script Android » Авг. 21, 2017 11:18:27

У меня проблема. Я приобрёл root права(использовал Kingroot).
Затем я написал скрипт на питоне в начале скрипта написал:
#!/usr/bin/env python
А в Termux я вбил:
chmod ugo+rwx “мой фаил”
Но терминал в ответ пишет
Operation not permited
Что делать? Я использую QPython 3
Android 5.0.2 хотя эта инфа не нужна

Python для новичков » pip freeze возвращает -e git+https://github.com/..... Что это значит? » Авг. 18, 2017 18:17:01

Добрый день,
Изучаю микрофреймворк Flask по туториалам с официального сайта, после установки приложения как editable пакета по инструкциям по ссылке http://flask.pocoo.org/docs/0.12/tutorial/packaging/#tutorial-packaging , pip freeze возвращает такую строку, в которой почему-то ссылка на мой репозиторий
-e git+https://github.com/DayS1eeper/dataroot_week1.git@39d7738adf72b8c44182794bddf7#egg=flaskr&subdirectory=flaskr
Нигде не могу найти что это означает. Подскажите, пожалуйста, что это или хотя бы в какую сторону искать информацию по данному вопросу.

Python для новичков » Получение id в socketserver » Авг. 17, 2017 09:11:41

Есть такой вот код
 import socket
import socketserver
import threading
class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        data = self.request.recv(1024)
        data = data.decode('utf-8')
        cur = threading.current_thread()
        responce = cur.name + ' '+ self.client_address[0]+' ' +data
        responce = responce.encode('utf-8')
        self.request.sendall(responce)
class MyTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass
class Ser:
    def __init__(self):
        self.server = MyTCPServer(('localhost', 12345), MyTCPHandler)
        self.thread_server = threading.Thread(target=self.server.serve_forever)
        self.thread_server.daemon = True
        self.id = []
    def start(self):
        self.thread_server.start()
    def loop(self):
        while True:
            pass
s = Ser()
s.start()
s.loop()

Как мне поместить id в лист, если id можно получить только в обработчике, а get_request(), останавливает 1 поток. Можно ли реализовать это без костылей? .-.

Django » Помощь с портфолио » Авг. 15, 2017 15:29:00

Добрый день!
Я начиная с мая начал усиленно учиться Питону и Джанго, сейчас начал искать работу https://hh.ru/resume/d1235748ff03ebf0fd0039ed1f443869347335 ,создал не большой блог https://github.com/solliter/blog-with-accounts и по чуть-чуть увеличиваю его добавляя различные функции.
Подскажите пожалуйста, у кого есть опыт, что стоит исправить, добавить в блог и чего не хватает в резюме.
Вообще любые советы, в тему, нужны.

Центр помощи » Проблема с twx.botapi » Авг. 14, 2017 23:06:46

При попытке отправить сообщение происходит такая ошибка
Код
 class BOT(object):
    token = config.token
    admin = 'admin'
    def __init__(self):
        self.bot = twx.botapi.TelegramBot(self.token)
        self.bot.get_me()
        last_updates = self.bot.get_updates(offset=0).wait()
        try:
            self.last_update_id = list(last_updates)[-1].update_id
        except IndexError:
            self.last_update_id = None
        print('last update id: {0}'.format(self.last_update_id))
    def process_message(self, message,user):
        text = message.message.text
        chat = message.message.chat
        chat_id = message.message.chat.id
        chat_username = message.message.chat.username
        date = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.localtime(message.message.date))
       
        text = text.strip()
        user_file = ''
        user_file += str(user.id)
        to_logs = str(date) +':Got message: from chat: {1} username:{2}'.format(text,chat_id,chat_username) + """:'{0}'""".format(text)
        print(to_logs)
        with open('log\log.txt','a') as f_obj:
            f_obj.write(to_logs + '\n')
        
        bot_message = twx.botapi.send_message(chat_id,"Привет пользователь!")
        print(bot_message)
def run(self):
        print('Main loop started')
        while True:
            updates = self.bot.get_updates(offset=self.last_update_id).wait()
            try:
                for update in updates:
                    if int(update.update_id) > int(self.last_update_id):
                        self.last_update_id = update.update_id
                        self.process_message(update,twx.botapi.User)
                      
            except Exception as ex:
                print(traceback.format_exc())
if __name__ == '__main__':
    try:
        BOT().run()
    except KeyboardInterrupt:
        print('Exiting...')     
Ошибка:
File “C:\Program Files\Python36\lib\site-packages\twx\botapi\botapi.py”, line 1933, in send_message
return TelegramBotRPCRequest('sendMessage', params=params, on_result=Message.from_result, **kwargs)
TypeError: __init__() missing 1 required positional argument: ‘token’

Центр помощи » Управление PWM (GPIO) в RPi » Авг. 13, 2017 15:14:03

Привет всем!
Ребята, помогите написать простенькую програмку для управления генераторами частоты, которые есть в raspberry pi?
Видел примеры в интернете, программка с пару десятков строк. Думал сам осилю, начал читать книжки по пайтону, почти сутки читал, в голове полная каша, решил поискать помощи тут.
Что мне требуется - задать нужную частоту и выдавать её на один из пинов GPIO конектора. Менять частоту на ходу, например парой клавиш на клавиатуре (вверх или вниз) или автоматически, с заданным шагом и временем. Частоту буду смотреть осцилографом, но можно вывести и на экран, если не сложно, да хоть в консоль, gui не обязательно лепить.
У меня есть модель Rpi B+ (ver1) - там вроде уже 4 хардверных PWM генератора уже есть. Мне нужно будет только два из них.
Еще у меня есть внешний переменный резистор подключаемый по usb (например громкость регулировать) - можно наверное еще им управлять.
Буду очень признателен если поможете, мне это нужно для научных экспериментов : )

Python для новичков » asyncio | Запуск производителя и потребителя » Авг. 12, 2017 23:44:21

Есть код, который парсит страницы из списка и напарсенное сохраняет в базу sqlite3.
 async def main():
    authors = json.load(open(r'test/authors_list.txt'))[:100] # для теста
    async with aiohttp.ClientSession() as session:
        for x in authors:
            url = urljoin(config.SAMLIB_DOMAIN, x[0]); print(url)
            html = await crawler.fetch(session, url)
            if parser.SI_parse_index_counters(html):
                _upddate, _counters = parser.SI_parse_index_counters(html)
                _upddate = hooks.convert_date(_upddate)
            else:
                _upddate, _counters = '', [0, 0]
                # author_link, author_name, author_text, author_descr, last_update, works_count, works_size, last_check
            db.update_authors_counters([
                x[0],
                x[1],
                x[2],
                x[3],
                _upddate,
                _counters[1],
                _counters[0],
                datetime.datetime.now()
            ])

update_authors_counters:
 def update_authors_counters(args):
    '''author_link, author_name, author_text, author_descr, last_update, works_count, last_check'''
    print(*args)
    query = '''
    INSERT INTO samlib_testdb (
    author_link, author_name, author_text, author_descr, last_update, works_count, works_size, last_check
    )
    VALUES
    (
       ?, ?, ?, ?, ?, ?, ?, ?
    );
    '''
    dbcurr.execute(query, args)
    dbconn.commit()
Затем main запускается в loop.run_until_complete(main()). Прямо, как кирпич.
Все работает, но база мееедленная. Хочу переделать этот код в две корутины:
1) Производитель, который парсит данные из списка интернет страниц.
2) Потребитель, который распарсенное сохраняет в базу данных.

Я не понимаю, как запустить эти корутины одновременно. Если с помощью async.gather(coro1(), coro2()), то у потребителя могут закончится данные или он будет ждать вечно.
Этот вопрос выглядит так, будто он решается одной-двумя строчками, но я зашел в тупик.

P.S. Про sqlite3 - буду переписывать на postgre

Network » ICMP echo и socket_raw » Авг. 10, 2017 11:48:05

Привет всем! В образовательных для себя целях решил написать программу которая будет отправлять 1 icmp echo запрос и получать ответный. Хочу разобраться с raw_socet на примере это задачи.

Руководствовался следующими ресурсами:
https://github.com/corentone/python3-ping/blob/e821b38f532285238f24d12e170021ff26bb7165/ping.py
https://github.com/pferate/python_ping

Вот мой код:
 # -*- coding: utf-8 -*-
import os
import socket
import struct
import time
 def checksum (string_to_check): #Честно скопипастил из первого источника, но предварительно разобрался что к чему
    sum = 0
    countTo = (len(string_to_check)/2)*2
    count = 0
    while count<countTo:
        thisVal = string_to_check[count + 1]*256 + string_to_check[count]
        sum = sum + thisVal
        sum = sum & 0xFFFFFFFF
        count = count + 2
    if countTo<len(string_to_check):
        sum = sum + string_to_check[len(string_to_check) + 1]
        sum = sum & 0xFFFFFFFF
    sum = (sum >> 16) + (sum & 0xFFFF)
    sum = sum + (sum >> 16)
    answer = ~sum
    answer = answer & 0xFFFF
    answer = answer >> 8 | (answer << 8 & 0xFF00)
    return answer
 def BULD_ICMP_PACKET(icmp_identifier, icmp_sequence):
    icmp_checksum = 0
    icmp_header = struct.pack("!BBHHH", 8, 0, icmp_checksum, icmp_identifier, icmp_sequence)
    bytesInDouble = struct.calcsize("d")
    icmp_data = bytes((192 - bytesInDouble) * 'Q', 'utf-8')
    icmp_data = struct.pack("d", time.time() ) + icmp_data
    icmp_checksum = checksum(icmp_header + icmp_data)
    icmp_header = struct.pack("!BBHHH", 8, 0, socket.htons(icmp_checksum), icmp_identifier, icmp_sequence)
    packet = icmp_header + icmp_data
    return packet #, socket.htons(icmp_checksum)
 def SEND_ONE(icmp_identifier, icmp_sequence, dst_addr, use_socket):
    packet = BULD_ICMP_PACKET(icmp_identifier, icmp_sequence)
    destination_address = socket.gethostbyname(dst_addr)
    print(struct.unpack("!BBHHH",packet[0:8]))
    use_socket.sendto(packet, (destination_address, 1))
    recPacket, addr = use_socket.recvfrom(1024)
    recPacketHeader = recPacket[20:28]
    icmp_type_r, icmp_code_r, icmp_checksum_r, icmp_identifier_r, icmp_sequence_r = struct.unpack("!BBHHH", recPacketHeader)
    use_socket.close()
    return icmp_type_r, icmp_code_r, icmp_checksum_r, icmp_identifier_r, icmp_sequence_r, addr
 my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
 print(SEND_ONE(os.getpid() & 0xFFFF, 1,'8.8.8.8',my_socket))
Дело в том, что в ответ я получаю пакеты с icmp заголовком (3, 1, контрольная_сумма, 0, 0, ('ip-address', 0))

Не могу разобраться почему так происходит и то ли я вообще делаю.
Прошу помочь

Python для новичков » TUI, библиотека urwid » Авг. 6, 2017 12:15:18

Здравствуйте! У меня возникла проблема с библиотекой urwid. В частности, мне надо сделать меню с функцией множественного выбора, но прочитав официальную документацию я так и не смог даже кнопку одну вывести… Если кто сможет решить мою проблему, буду очень благодарен, ну или хотя бы скиньте ссылку на годный туториал, по гуглу ничего толкового так и не нашел. Спасибо

Python для новичков » разработка простого бота для телеграм на python » Авг. 5, 2017 14:21:55

всем привет это моя первая тема на форуме.
цель - создать бота для телеграм канала на py с функционалом приветствия новых пользователей


что имеется
sublime 3
Python 3.6.0
установленные библиотеки: pytelegrambotapi, telepot, configparser, requests, virtualenv


код:
 import telebot  
import configparser
config = configparser.ConfigParser()
config.read("config.ini")
bot = telebot.TeleBot(config["Telegram"]["access_token"])
@bot.message_handler(func=lambda m: True, content_types=['new_chat_member'])
def user_join(message):
        bot.send_message(message.chat.id, 'welcome message', parse_mode="HTML", disable_web_page_preview=True)
if __name__ == '__main__':
    while True:
        try:
            bot.polling(none_stop=True)
        except Exception as e:
            print(e)
            time.sleep(15)
предполагаю что через access_token и библиотеки pytelegrambotapi, telepot, configparser бот в режиме онлайн кушает код? но у меня так и не получилось настроить правильно. может быть найдется тот, кто сможет объяснить или подсказать ?в какую сторону смотреть..

Центр помощи » Помощь в скрипте. » Авг. 4, 2017 13:53:10

Доброго времени суток.
Есть скрипт на Python, selenium. Мои знания очень ограничены, есть необходимость проанализировать скрипт, и допилить. Естественно не за бесплатно, времени займёт думаю час - два, не больше.
Кто сможет помочь, буду благодарен - первый контакт - лс.

Python для новичков » python CLI task который будет запускаться по крону » Авг. 4, 2017 12:00:54

Добрый день, есть приложение которое написано на flask/ember/mongodb.
Поставили задачу:
- нужно создать CLI task (который будем запускать по крону). Он должен
- доставать все записи из базы
- запускать функционал для определения количества людей на фото (программа есть и код написан)
- записывать полученное количество в поле тимы

Как и чем такое лучше реализовать ?

Python для новичков » Публикация в группу VK сообщения с заданным интервалом времени » Авг. 3, 2017 20:12:05

Добрый вечер!
Осваиваю самостоятельно Python. Решил распарсить xml и найденные элементы (все тайтлы) публиковать в группу в vk с периодичностью, скажем, 5 минут.
Получить все тайтлы я получил. При запуске в pycharm'e происходит перебор всех тайтлов с интервалом. В группу в vk публикуется какой-то рандомный тайтл один раз и на этом все.
 import time
import vk
import xml.etree.ElementTree as ET
from urllib.request import Request, urlopen
headers = {"X-Access-Token": "xxxxxxxxxxxxxxx"}
request = Request("http://site.com", headers=headers)
response_body = urlopen(request).read()
tree = ET.fromstring(response_body)
paper = []
for offer in tree.findall('offer')[0:]:
    title = offer.get('title')
    paper.append({
        'title' : title
    })
for paper in papers:
    print(paper['title'])
    print()
    time.sleep(300)
# VK Posting
session = vk.AuthSession('xxxx', 'test@test.ru', 'password', scope='offline,wall,groups')
api = vk.API(session)
api.wall.post(owner_id='-1111', from_group='1', message=title)

Подскажите, пожалуйста, как переписать код, чтобы происходила публикация тайтлов по порядку с заданным интервалом времени.

Python для экспертов » multiprocessing.Pool и методы екземпляра класса » Авг. 3, 2017 19:24:59

Здравствуйте. Вот такая интересная задачка, над которой уже второй день сижу (Python 2.7.13):
есть класс, который имеет много методов для обработки какой-то коллекции данных, схематически вот:

 class DataProcessor(object):
    def process1(self, data):
         print "process 1 finished"
         return data
 
   def process2(self, data):
         print "process 2 finished"
         return data
   def process3(self, data):
         print "process 3 finished"
         return data
 
   def process4(self, data):
         print "process 4 finished"
         return data
 
   def make_all_processes(self, data):
        processes = [getattr(self, method) for method in dir(self) if method.startswith('process')]
        results = [process(data) for process in processes]
        return results

Вот эти процессы обработки данных хочу распаралелить, наибольший выигрыш получился через отдельные процессы, вот приблизительно таким образом:

 results = multiprocessing.Manager().dict()                             
processes = []                                                           
for lookup in lookup_methods:                                          
    process = multiprocessing.Process(target=self._lookup_process_wrapper, args=(lookup, input_data, results))
    process.start()                                                     
    processes.append(process)                                             
                                                                                 
for process in processes:                                                 
    process.join()

Естественно, если таких методов будет много, а у меня их сейчас 6, то куда разумней создать пул процессов, а не порождать новый процесс на каждый метод. И вот как раз с этим проблемы - в пул нельзя запихнуть метод экземпляра класса, так как они не могут быть сериализированы. Через multiprocessing.Queue или multiprocessing.Manager - то же самое.
Как же элегантно решить данную проблему?

п.с. есть ещё один вариант, поскольку всю сборку мне надо отобразить на веб-странице, возможно попробовать создать на каждый метод свой ajax-запрос, но не уверен, что это хорошее решение. Тем более, что такое паралельное выполнение может пригодиться где-то ещё.


Дополнение 1
Решил проблему таким образом:

  def lookup_process_wrapper(lookups_queue, data, results, config_dict):                             
    while True:                                                                 
         try:                                                                    
             lookup = lookups_queue.pop()                                        
         except:                                                                 
             break                                                               
         data_processor = DataProcessor(config_dict)                 
         lookup_method = getattr(data_processor, lookup)                              
         results[lookup] = lookup_method(data=data)

Эта функция объявлена на уровне модуля, она сериализируется и принимает в качестве аргументов только сериализируемые значения. Тогда её можно использовать в multiprocessing.Pool не изменяя сам класс DataProcessor. Правда, теперь для каждого метода будет инициализироваться сам класс. И вряд-ли можно сделать его синглтоном, ведь это всё пойдёт в отдельные процессы. Возможно, есть ещё какие-то варианты?

Python для новичков » вопрос по Python3 telnetlib и D-link » Авг. 2, 2017 20:52:32

Здравствуйте. Только начинаю изучать, возникла ошибка, которая вряд ли есть в мануалах.
Задача - коннектиться на свичи D-Link (тут DES-3028), собирать и обрабатывать инфу.
код следующий:

 	import telnetlib
	HOST = '10.90.90.90'
	PORT = 2
	command = 'show fdb port {} \n'.format(PORT))
	tn = telnetlib.Telnet(HOST)
	tn.read_until(b':') 
	tn.write('admin\n'.encode('ascii')) 
	tn.read_until(b':') 
	tn.write('password\n'.encode('ascii'))
	tn.read_until(b'#')
	tn.write(command.encode('ascii'))
	str_all = tn.read_until(b'#')
	tn.close()
	print (command)
	print (str_all)
Ну, понятно, в оригинале это функция, и я тут попереименовал вводные данные
Вывод такой:
show fdb port 2

b'8show fdb port 2 \n\r\n\rAvailable commands: \n\r.. ? cable_diag clear \n\rconfig create debug delete \n\rdir disable download enable \n\rlogin logout ping reboot \n\rreconfig reset save show \n\rsmtp telnet traceroute upload \n\r\n\rDES-3028:5#'
То есть моя команда начинается вместо show на 8show
Подскажите, откуда оно может браться и как это исправить?

Python для новичков » Вопрос по функции из библиоткеи socket » Авг. 1, 2017 22:02:55

Здравствуйте.
Пишу простенький чат с помощью библиотеки socket и потоки threading.
Ситуация такая: запускаю сервер, затем два клиента. Отправляю с одного клиента сообщение, на другом отображается, но, если отправить с того же клиента второе сообщение, то на другом клиенте оно не отобразиться, пока не написать какое-то сообщение в этом клиенте.
Все это решается функцией socket.setblocking(False).
Прописываю её в самом начале при бинде сокета и когда принимаю подключение.
Но я абсолютно не понимаю, почему все так происходит. Что делает эта функция? И почему она решает мою проблему?

Python для новичков » Интеграция с ФГИС Меркурий » Июль 28, 2017 08:01:20

Всем привет!
В общем есть у нас такая чудная система. С 01.01.18 все должны на нее перейти. Встал вопрос интеграции.
А там SOAP запросы. Я давай рыть библиотеку. Нашел suds, wsdl взял, логин пароль есть. Подключается все без проблем. Во всяком случае ошибок нет. А дальше какие-то сложности пошли.
Я вижу список методов. Вызываю передаю параметр - получаю 405ю ошибку

Ну и кода кусок
 connectclientreference = suds.Client('http://api.vetrf.ru/schema/platform/cerberus/services/EnterpriseService_v1.4_pilot.wsdl', username= 'usrname', password='pass')
connectclientreference.service.GetBusinessEntityList('ns2: Listoption count 100') - вот тут ошибка. 
Видимо неправильный параметр передаю...

PS Может кто-то пытался интегрироваться с данной системой? Буду рад подсказкам)

Python проекты » Система контроля версий для 3d моделирования » Июль 25, 2017 02:43:21

Добрый день, я разработчик игр работаю в среде Unreal Engine. У меня также есть небольшая команда вместе с которой мы работаем над 3d моделями для игровых проектов и маркетов игровых движков (UE4, Unity).

Уже работая над 3d моделями в команде, я обратил внимание, что у 3d специалистов все достаточно скудно для организации командной работы. Сейчас мы используем git + lfs для обмена данными по нашим проектам, но, в действительности, эта система позволяет лишь обмениваться актуальными версиями моделей и не более. При этом, нам бы очень хотелось в будущем использовать сервис, который сочетает в себе что-то от github и что-то от sketchfab.

Я предполагаю, что если задаться целью, то можно создать систему контроля версий которая бы позволяла в фоновом режиме сохранять состояние модели на каждом шаге моделирования и отправлять состояние на сервер, а сервер, в свою очередь, мог бы, имея эти данные, визуализировать их с помощью собственного клиентского сервиса на javascript/opengl.

Сервис будет позволять хранить версии моделей, отталкиваясь не только от состояния итогового исходного файла, но и от истории всех проводимых над ней операций и промежуточных состояний модели. Таким образом можно будет просмотреть весь процесс моделирования по шагам, создать альтернативные ветки моделирования, наблюдать за процессом моделирования онлайн в реальном времени.

Сервис можно будет использовать, как минимум для:
- создания уроков по моделированию, наглядно демонстрирующих каждый шаг.
- контролировать работу 3d специалиста, наблюдая за процессом моделирования модели онлайн.
- совместно работать над моделями, используя систему веток, близкую к гит
- хранить свои наработки по 3d моделированию в облаке.
- (позже) работать над одной моделью в разных редакторах

Для 3d моделирования мы используем blender. У этого редактора есть собственное api на python которое позволяет достаточно многое. Как минимум, оно позволяет получать данные по текущей операции с моделью и запоминать ее состояние (количество и положение вершин, граней, сторон). Сам Blender написал с открытым исходным кодом и, в случае если стандартного апи не хватит для каких-то особенных операций, есть возможность расширить возможности редактора используя с++.

Сам я долгое время работал с flash и javascript над игровыми проектами. Сейчас я также изучаю c++ и знакомлюсь со средой unreal engine. У меня есть небольшой опыт работы с python. Я работал одновременно и над клиентской и над серверной частью для коллекционной карточной игры похожей на Heartstone.

Я ищу партнера и наставника, уверенно знающего python/с++ и готового возглавить техническую часть разработки. Скажу честно, я боюсь браться за этот проект один, прежде всего потому что я на самом деле тяготею к продюсерской деятельности и программирование изучаю и использую скорее вынужденно. В этом проекте я хотел бы больше внимания уделять маркетингу, продажам, поиску необходимых ресурсов на каждом этапе разработки. Тем не менее, я готов на первых этапах участвовать в том числе и как программист, участвовать в разработке плагина в 3d редакторе, серверной и клиентской частях самого приложения. Главное, чтобы был кто-то кто мог спланировать разработку и сформулировать точные повседневные задачи. Работе готов уделять по 60 часов в неделю.

Пишите если вам также как и мне нравиться это направление. Обсудим все детали подробнее.