GeovaneSchmitz / sigaa-api

Unofficial high performance API for SIGAA (Sistema Integrado de Gestão de Atividades Acadêmicas) using web scraping.
MIT License
40 stars 11 forks source link

Error: SIGAA_UNKNOWN_USER_TYPE #4

Closed dduartee closed 3 years ago

dduartee commented 3 years ago

Olá, estou recebendo o seguinte erro:

Error: SIGAA_UNKNOWN_USER_TYPE at SigaaLogin._parseLogin (C:\Users\Duarte\Desktop\SIGAA-node-interface-master\libs\common\sigaa-login.js:140:17) at SigaaLogin.login (C:\Users\Duarte\Desktop\SIGAA-node-interface-master\libs\common\sigaa-login.js:106:25) at processTicksAndRejections (node:internal/process/task_queues:93:5) at async Sigaa.login (C:\Users\Duarte\Desktop\SIGAA-node-interface-master\index.js:65:7)

Creio que seja por causa de quando é feito o login, é redirecionado para uma página de seleção de vínculos, algum jeito de resolver isso? teremos que mudar o codigo?

GeovaneSchmitz commented 3 years ago

Olá, Desculpa pela demora, provavelmente, este erro acontece por causa de diferenças entre o a versão do SIGAA do IFSC e o seu SIGAA. Você poderia me dizer qual é tipo de usuário que você está tentando logar? É um professor ou aluno? Atualmente eu só tenho versão de aluno, pois só tenho acesso a minha conta, se você deseja utilizar contas de alunos o código talvez precise de poucas alterações para adaptar ao seu SIGAA, porém, se for para professor terá que ser implementado :(

GeovaneSchmitz commented 3 years ago

Olá, eu mudei o codigo para tentar adaptar, porém não tenho certeza se funcionou, pois eu não tenho a tela de seleção de vínculos, você poderia testar?

dduartee commented 3 years ago

Olá, Desculpa pela demora, provavelmente, este erro acontece por causa de diferenças entre o a versão do SIGAA do IFSC e o seu SIGAA. Você poderia me dizer qual é tipo de usuário que você está tentando logar? É um professor ou aluno? Atualmente eu só tenho versão de aluno, pois só tenho acesso a minha conta, se você deseja utilizar contas de alunos o código talvez precise de poucas alterações para adaptar ao seu SIGAA, porém, se for para professor terá que ser implementado :(

Olá, a URL do seu SIGAA é o mesmo do meu. Estou logando como aluno.

Olá, eu mudei o codigo para tentar adaptar, porém não tenho certeza se funcionou, pois eu não tenho a tela de seleção de vínculos, você poderia testar?

Acabei de testar aqui e funcionou, mas como é final de ano e um outro curso que eu estava fazendo ele acabou, então não tenho mais a tela de vínculos, perdão pelo falso aviso, eu até tinha salvo a pagina da seleção de vínculos mas acabei não encontrando e tentei modificar o código, é bem confuso, pois o identificador do formulário, como o por exemplo o form-login referente a página de login, que é o mesmo nome da seleção de vínculos.

Enfim, vou procurar novamente para ver se eu encontro a página de seleção de vínculos para ajudar na implementação. Caso eu encontre irei enviar por aqui.

Boa sorte no projeto, gostei bastante.

GeovaneSchmitz commented 3 years ago

Obrigado! Se você quiser o trecho de código que verifica o tipo de usuário, é este

https://github.com/GeovaneSchmitz/sigaa-api/blob/871ba447b0402597158ec608eba2bb6354582ff4/src/accounts/sigaa-account-student.ts#L16-L27

Após o login, ele executa essa função, ela retorna verdairo ou falso, indicando se usuário é um aluno. O que eu fiz foi verificar se o usuário foi redirecionado para a alguma url com '/telasPosSelecaoVinculos.jsf' e dentro da pagina tiver /sigaa/verPortalDiscente.do então é um aluno. Isso é um chute porque nem não sei com a pagina é.

Pior que agora eu vi que a linha 20 está errada

// O certo é
     if (page.body.includes('/sigaa/verPortalDiscente.do')) return true; 
// E não
     if (page.url.href.includes('/sigaa/verPortalDiscente.do')) return true; 
dduartee commented 3 years ago

Olá, consegui achar uma maneira de acessar a pagina de vínculos, irei anexar aqui as duas paginas, SIGAA MOBILE, e o clássico (PC).

Vinculos.zip

Não sou muito avançado em nodejs, e não entendo nada sobre cheerio. Espero que essas paginas te ajude. Estarei disponível caso precise.

GeovaneSchmitz commented 3 years ago

Olá, obrigado pela disponibilidade e pelo anexo!

Eu vi o seu anexo e fiquei com uma dúvida, após você escolher o seu vínculo no PC, quando você clica em “Ver turmas anteriores” o link que ele te redireciona é https://sigaa.ifsc.edu.br/sigaa/portais/discente/turmas.jsf ou tem algo como “?vinculo=1” na url? Se não tiver, você poderia fazer um teste, se não for muito incomodo? Entra com uma nova sessão ao SIGAA e pula direto para este link sem escolher o vínculo e me diz o que aparece, eu queria ter essa informação para saber se tenho que implementar um sistema de trocar de vínculo ou apenas usar a URL do botão.

Screenshot

Também não sou avançado, por isso eu mudo o código todo de tempos em tempos, em razão de aprender algo novo e perceber que a solução que tive não foi a melhor. Como o meu código está bagunçado, talvez você goste de um pouquinho de explicações, e também porque parece que você gosta de programar. No caso, atualmente eu uso Cheerio, no começo era o jsdom, mas tive problemas e migrei para o Cheerio. Ele, o cheerio, tem a mesma sintaxe do JQuery, serve para encontrar os elementos HTML. Já as solicitações ao sigaa são feita através de uma interface chamada HTTP (/src/session/sigaa-http.ts), ela gerencia toda a sessão, organiza as solicitações, tanto para evitar erros como “Você utilizou o botão voltar...”, “Sua sessão foi expirada...”, como também para evitar requests repetitivos. No código tem vários this.http.get ou this.http.post que servem para fazer uma solicitação ao sigaa, o que ele retorna é uma instância do SigaaPage (/src/session/sigaa-page.ts) que é resposta do sigaa,

 // Por exemplo
  const page = await this.http.get(‘/sigaa/portais/discente/discente.jsf’); // Faz o request
  console.log(page.statusCode) // É o status code da página que geralmente é 200
  console.log(page.body) // É o conteúdo inteiro da página 
  page.$ // É a instância do Cheerio

  // Se você quiser pegar o conteúdo HTML do primeiro elemento form você pode usar
  console.log(page.$(“form”).first().html())  

  // E se por acaso você quiser pegar algum atributo de um elemento
  page.$("form").attr('action') // Vai retornar o action do primeiro elemento form

  // Você pode acessar elementos dentro de elementos
  const formEl = page.$("form")
  const input = page.$(formEl).find(“input”) // pega o input dentro do formEl
dduartee commented 3 years ago

Eu vi o seu anexo e fiquei com uma dúvida, após você escolher o seu vínculo no PC, quando você clica em “Ver turmas anteriores” o link que ele te redireciona é https://sigaa.ifsc.edu.br/sigaa/portais/discente/turmas.jsf ou tem algo como “?vinculo=1” na url?

Quando eu entro no "Ver turmas anteriores" eu entro sem nenhuma query, normal "/turmas.jsf".

Se não tiver, você poderia fazer um teste, se não for muito incomodo? Entra com uma nova sessão ao SIGAA e pula direto para este link sem escolher o vínculo e me diz o que aparece, eu queria ter essa informação para saber se tenho que implementar um sistema de trocar de vínculo ou apenas usar a URL do botão.

Então, como o meu outro curso não esta mais ativo, quando eu logo pelo SIGAA automaticamente ele entra no meu curso ativo sem pedir o vinculo então não consigo fazer o teste.

Mas caso você queira alternar entre os vínculos, utilizei um proxy para pegar os requests na parte de escolher o vinculo, https://sigaa.ifsc.edu.br/sigaa/escolhaVinculo.do?dispatch=escolher&vinculo=1 recebendo os dois parâmetros GET com parâmetro vinculo sendo a ordem do vinculo escolhido, e o dispatch a ação do request, em uma busca rápida encontrei 2 tipos de dispatch, dispatch=escolher para escolher o vinculo, dispatch=listar para listar os vinculos redirecionando para o sigaa/vinculos.jsf. Essa talvez seja uma das formas de trocar de vínculos.

dduartee commented 3 years ago

Duas novas coisas que encontrei enquanto estava usando o proxy, uma não agrega a muita coisa mas sei lá... o SIGAA tem duas URLs https://sig.ifsc.edu.br e https://sigaa.ifsc.edu.br.

A outra coisa é um pouco mais relevante...

Eu vi o seu anexo e fiquei com uma dúvida, após você escolher o seu vínculo no PC, quando você clica em “Ver turmas anteriores” o link que ele te redireciona é https://sigaa.ifsc.edu.br/sigaa/portais/discente/turmas.jsf ou tem algo como “?vinculo=1” na url?

Essa seleção de vínculos, o servidor guarda pela sessão do cookie, ou seja, se abrir duas abas com dois vínculos diferentes e acessar o "Ver turmas anteriores", será redirecionado para o ultimo vinculo selecionado. Então na minha visão, a melhor alternativa para alterar de vinculo é, por exemplo, quer ver todas as matérias de todos os vínculos, teria que enviar o request com a query do https://sigaa.ifsc.edu.br/sigaa/escolhaVinculo.do?dispatch=escolher&vinculo=1.

dduartee commented 3 years ago

Também não sou avançado, por isso eu mudo o código todo de tempos em tempos, em razão de aprender algo novo e perceber que a solução que tive não foi a melhor. Como o meu código está bagunçado, talvez você goste de um pouquinho de explicações, e também porque parece que você gosta de programar. No caso, atualmente eu uso Cheerio, no começo era o jsdom, mas tive problemas e migrei para o Cheerio. Ele, o cheerio, tem a mesma sintaxe do JQuery, serve para encontrar os elementos HTML. Já as solicitações ao sigaa são feita através de uma interface chamada HTTP (/src/session/sigaa-http.ts), ela gerencia toda a sessão, organiza as solicitações, tanto para evitar erros como “Você utilizou o botão voltar...”, “Sua sessão foi expirada...”, como também para evitar requests repetitivos. No código tem vários this.http.get ou this.http.post que servem para fazer uma solicitação ao sigaa, o que ele retorna é uma instância do SigaaPage (/src/session/sigaa-page.ts) que é resposta do sigaa,

Vou dar uma estudada, talvez eu consiga ajudar no projeto.

GeovaneSchmitz commented 3 years ago

Duas novas coisas que encontrei enquanto estava usando o proxy, uma não agrega a muita coisa mas sei lá... o SIGAA tem duas URLs https://sig.ifsc.edu.br e https://sigaa.ifsc.edu.br.

Pior que tem, além dessa tem https://sipac.ifsc.edu.br/sigaa/ e https://sigadmin.ifsc.edu.br/sigaa/ a api permite definir a url base porque talvez funcione em outra instituição ou o link do ifsc pode mudar algum dia.

Essa seleção de vínculos, o servidor guarda pela sessão do cookie, ou seja, se abrir duas abas com dois vínculos diferentes e acessar o "Ver turmas anteriores", será redirecionado para o ultimo vinculo selecionado. Então na minha visão, a melhor alternativa para alterar de vinculo é, por exemplo, quer ver todas as matérias de todos os vínculos, teria que enviar o request com a query do https://sigaa.ifsc.edu.br/sigaa/escolhaVinculo.do?dispatch=escolher&vinculo=1.

Obrigado pela essa idéia, quando nós usamos o sigaa.login(), ele retorna um conta, nela tem a lista de vínculos do usuário, cada vínculo terá o nome do curso e o tipo student/teacher. Cada vinculo terá o seu próprio getCourses() que retornará somente as suas turmas. Para fazer isso, eu vou salvar na class SigaaSession o vínculo atual e se o vínculo acessado não for o mesmo do atual ele troca. O que você acha? Estou pensando nisso tanto para permitir saber qual vínculo a turma pertence tal como permitir carregar só o vinculo que o usuário quer.

PS: Se tudo der certo até sábado eu consigo implementar.

GeovaneSchmitz commented 3 years ago

Vou dar uma estudada, talvez eu consiga ajudar no projeto.

Se você não entender algo pode abrir um issue, prometo responder mais rápido do que este :D Atualmente eu tô tentando fazer um app para android com Kotlin usando essa api, se você quiser se aventurar em outros projetos com ela tem o bot do telegram.

dduartee commented 3 years ago

Obrigado pela essa idéia, quando nós usamos o sigaa.login(), ele retorna um conta, nela tem a lista de vínculos do usuário, cada vínculo terá o nome do curso e o tipo student/teacher. Cada vinculo terá o seu próprio getCourses() que retornará somente as suas turmas. Para fazer isso, eu vou salvar na class SigaaSession o vínculo atual e se o vínculo acessado não for o mesmo do atual ele troca. O que você acha? Estou pensando nisso tanto para permitir saber qual vínculo a turma pertence tal como permitir carregar só o vinculo que o usuário quer.

PS: Se tudo der certo até sábado eu consigo implementar.

Acho uma boa ideia. Boa sorte na implementação, se precisar que eu teste, talvez eu consiga testar.

Só para ver se eu entendi, quando fazer login, todos os usuários serão redirecionados para a escolha de vinculos? "https://sigaa.ifsc.edu.br/sigaa/vinculos.jsf", porque assim, qualquer usuário consegue acessar os vínculos e fazer o request do "?dispatch=escolher&vinculo=1", e então daria para procurar se o usuário tiver mais de um vinculo pelo "*https://sigaa.ifsc.edu.br/sigaa/escolhaVinculo.do?dispatch=listar" e escolher o vinculo. É essa a ideia?

GeovaneSchmitz commented 3 years ago

A ideia, é somente lista

Só para ver se eu entendi, quando fazer login, todos os usuários serão redirecionados para a escolha de vinculos?

Nem todos, somente os que têm mais de um vinculo, por exemplo se eu acessar https://sigaa.ifsc.edu.br/sigaa/escolhaVinculo.do?dispatch=listar aparece isso: Screenshot_2021-01-06 SIGAA - Sistema Integrado de Gestão de Atividades Acadêmicas Porém se eu acessar https://sigaa.ifsc.edu.br/sigaa/escolhaVinculo.do?dispatch=listar eu consigo ver a lista de vinculos. O que quero fazer é seguir com a resposta do sigaa, se ele responder com a tela de vínculos eu sei que o usuário tem mais de um (ele responde com o portal do aluno direto se tiver somente um).

Na API, quando for feita a autenticação, ela retornará a lista de vínculos, se tiver somente um ela não vai ficar trocando entre vínculos usando ?dispatch=escolher&vinculo=1 Também vou implementar um mecanismo de troca automática, por exemplo se usuário viu as turmas primeiro vínculo, depois viu as do segundo, se por acaso ele requisitar algo no primeiro ele trocará o vínculo, sem que seja necessário chamar alguma função para trocar o vínculo.

dduartee commented 3 years ago

O que quero fazer é seguir com a resposta do sigaa, se ele responder com a tela de vínculos eu sei que o usuário tem mais de um (ele responde com o portal do aluno direto se tiver somente um). Na API, quando for feita a autenticação, ela retornará a lista de vínculos, se tiver somente um ela não vai ficar trocando entre vínculos usando ?dispatch=escolher&vinculo=1 Também vou implementar um mecanismo de troca automática, por exemplo se usuário viu as turmas primeiro vínculo, depois viu as do segundo, se por acaso ele requisitar algo no primeiro ele trocará o vínculo, sem que seja necessário chamar alguma função para trocar o vínculo.

Ah é esqueci de testar o dispatch=listar em uma conta sem vínculos, testei somente o https://sigaa.ifsc.edu.br/sigaa/vinculos.jsf. Entendi agora...

GeovaneSchmitz commented 3 years ago

Eu tentei corrigir, para testar eu criei um mini script para forçar a troca de vínculo, você poderia ver se funcionou?

const Sigaa = require("sigaa-api").Sigaa;

const sigaa = new Sigaa({
  url: "https://sigaa.ifsc.edu.br",
});

// coloque seu usuário
const username = "";
const password = "";

// Serve só para exibir as notas no console
const printGrades = (gradesGroups) => {
  for (const gradesGroup of gradesGroups) {
    console.log("->" + gradesGroup.name);
    switch (gradesGroup.type) {
      case "only-average":
        console.log(gradesGroup.value);
        break;

      case "weighted-average":
        for (const grade of gradesGroup.grades) {
          console.log("-" + grade.name);
          console.log("peso: " + grade.weight);
          console.log(grade.value);
        }

        console.log("média:" + gradesGroup.value);

        break;

      case "sum-of-grades":
        for (const grade of gradesGroup.grades) {
          console.log("-" + grade.name);
          console.log("Valor máximo: " + grade.maxValue);
          console.log(grade.value);
        }

        console.log("soma:" + gradesGroup.value);
        break;
    }
    console.log(""); // Para espaçar as linhas
  }
};

const main = async () => {
  const account = await sigaa.login(username, password); // login

  const bonds = await account.getBonds();
  const courses = [];
  for (const bond of bonds) {
    if (bond.type === "student") {
      console.log("Matrícula do vínculo: " + bond.registration);
      console.log("Curso do vínculo: " + bond.program);
      courses.push(await bond.getCourses());
    } else {
      console.log("vínculo de professor");
    }
  }

  const firstCourse = courses[0][0]; //Pega a primeira turma do primeiro vinculo
  printGrades(await firstCourse.getGrades());

  const secondCourse = courses[1][0]; //Pega a primeira turma do segundo vinculo
  printGrades(await secondCourse.getGrades());

  const thirdCourse = courses[0][1]; //Pega a segunda turma do primeiro vinculo
  printGrades(await thirdCourse.getGrades());

  // Encerra a sessão
  await account.logoff();
};

main().catch((err) => {
  if (err) console.log(err);
});
dduartee commented 3 years ago

Olá, então, eu testei o seu código, com o modulo atualizado, e ele não pegou o meu outro curso, pegou somente um. Ele printou tudo certinho a nota do primeiro curso, mas logo após o fim da primeira matéria do primeiro vinculo, ele retornou o seguinte erro:

TypeError: Cannot read property '0' of undefined
    at main (C:\Users\Duarte\Desktop\sigaa\index.js:63:34)
    at processTicksAndRejections (node:internal/process/task_queues:93:5)

A linha 63 e 64:

const secondCourse = courses[1][0]; //Pega a primeira turma do segundo vinculo
  printGrades(await secondCourse.getGrades());

Sobre pegar a nota da segunda matéria do primeiro vinculo, funcionou. Dei um console.log no courses, teoricamente ele retornaria todas as matérias de todos os vinculos, mas retornou todas as materias de um vinculo, da seguinte maneira.

[
  [
    SigaaCourseStudent {
      forumsIdIndex: 0,
      instances: [Object],
      http: [SigaaHTTP],
      parser: SigaaParser {},
      id: '154792',
      title: 'ARTES I',
      code: 'ART027601',
      numberOfStudents: 0,
      period: '2020.1',
      schedule: '3M3',
      form: [Object] 
    }
  ]
]

Por curiosidade, dei console.log no "bonds".

const bonds = await account.getBonds();
console.log(bonds);

E ele retornou isso.

[
  SigaaStudentBond {
    type: 'student',
    http: SigaaHTTP { session: [SigaaHTTPSession] },
    parser: SigaaParser {},
    program: 'TÉCNICO EM MECÂNICA [276]/XXE',
    registration: '202011004225'
  }
]

Me surgiu uma duvida sobre o sigaa de mobile, a troca de vínculos está sendo feita por onde, pelo mobile ou pelo clássico? Pois no mobile na página de vínculos (https://sigaa.ifsc.edu.br/sigaa/mobile/touch/vinculos.jsf) ele só mostra o vinculo ativo, e não mostra o outro vinculo inativo, se a troca for realizada pelo mobile, não consigo testar até ter mais de um vinculo ativo. image

O que quero fazer é seguir com a resposta do sigaa, se ele responder com a tela de vínculos eu sei que o usuário tem mais de um (ele responde com o portal do aluno direto se tiver somente um).

Lembrei também, que quando eu faço login o meu sigaa, ele não aparece a tela de vínculos no primeiro momento, só acessando o link https://sigaa.ifsc.edu.br/sigaa/vinculos.jsf. Talvez seja por esse motivo dele não estar encontrando o outro vinculo.

O certo seria ter uma conta com pelo menos 2 vínculos ativos. Se você conseguir encontrar alguém com 2 vínculos ativos, podemos ter uma facilidade para entender se isso é um erro do usuário (minha conta do sigaa) ou erro do código.

Estive olhando o Sigaa de uma amiga minha e percebi uma diferença entre o usuário que já teve ou tem outro vinculo é no nome. No meu Sigaa, ao lado do meu nome tem um botão para alterar o vinculo. image

Já no Sigaa da minha amiga que não teve nenhum outro vinculo, esse botão não existe. image

Esse é outro jeito de ver se o usuário tem ou teve possível vínculos.

Nem todos, somente os que têm mais de um vinculo, por exemplo se eu acessar https://sigaa.ifsc.edu.br/sigaa/escolhaVinculo.do?dispatch=listar aparece isso: Screenshot_2021-01-06 SIGAA - Sistema Integrado de Gestão de Atividades Acadêmicas

Além também deste outro jeito.

GeovaneSchmitz commented 3 years ago

Me surgiu uma duvida sobre o sigaa de mobile, a troca de vínculos está sendo feita por onde, pelo mobile ou pelo clássico? Pois no mobile na página de vínculos (https://sigaa.ifsc.edu.br/sigaa/mobile/touch/vinculos.jsf) ele só mostra o vinculo ativo, e não mostra o outro vinculo inativo, se a troca for realizada pelo mobile, não consigo testar até ter mais de um vinculo ativo. image

Não, se ele receber a tela de seleção de vínculo no mobile ele carrega a página de vínculo do desktop, então era para os inativos funcionarem, mas agora acredito que só aparece essa tela direto se tiver pelo menos 2 vínculos, no caso suponho que tem um botão para trocar de vínculo no mobile.

O certo seria ter uma conta com pelo menos 2 vínculos ativos. Se você conseguir encontrar alguém com 2 vínculos ativos, podemos ter uma facilidade para entender se isso é um erro do usuário (minha conta do sigaa) ou erro do código.

Também queria! Mas pelo lado bom, agora nós desenvolvemos com suporte a vínculos inativos :)

Estive olhando o Sigaa de uma amiga minha e percebi uma diferença entre o usuário que já teve ou tem outro vinculo é no nome. No meu Sigaa, ao lado do meu nome tem um botão para alterar o vinculo. image

Já no Sigaa da minha amiga que não teve nenhum outro vinculo, esse botão não existe. image

Esse é outro jeito de ver se o usuário tem ou teve possível vínculos.

Você poderia mandar um trecho HTML dessa parta da página que tem o nome do usuário e o botão? Pois queria fazer teste para se tiver este botão ele carrega a página de vínculos. No caso, só preciso de um trecho como este tanto para versão mobile quanto para versão de pc:

    <div id="info-usuario">
        <p class="periodo-atual">Semestre atual: <strong>2020.2</strong></p>
        <p class="usuario"><span title="GEOVANE MARTINS SCHMITZ">GEOVANE MARTINS SCHMITZ</span>
            </p>
        <p class="unidade">
            CAMPUS FLORIANOPOLIS - FLN (11.00.62)</p>
    </div>
dduartee commented 3 years ago

no caso suponho que tem um botão para trocar de vínculo no mobile.

Negativo, pelo menos com 1 vinculo ativo não encontrei nada, provavelmente quando tiver 2 vínculos ativos ele deve aparecer algum botão...

Você poderia mandar um trecho HTML dessa parta da página que tem o nome do usuário e o botão? Pois queria fazer teste para se tiver este botão ele carrega a página de vínculos. No caso, só preciso de um trecho como este tanto para versão mobile quanto para versão de pc:

Aqui está. Consegui só a versão de pc, a versão de mobile não encontrei nada, nenhum botao

<div id="info-usuario">
    <p class="periodo-atual">Semestre atual: <strong>2020.1</strong></p>
    <p class="usuario"><span title="GABRIEL KLEEMANN DUARTE">GABRIEL KLEEMANN DUARTE</span>
    <i>
       <small>
        <a href="/sigaa/escolhaVinculo.do?dispatch=listar">Alterar vínculo</a>
       </small>
    </i>
    </p>
    <p class="unidade">
        CAMPUS XANXERÊ - XXE (11.01.48)</p>
</div>
GeovaneSchmitz commented 3 years ago

no caso suponho que tem um botão para trocar de vínculo no mobile.

Negativo, pelo menos com 1 vinculo ativo não encontrei nada, provavelmente quando tiver 2 vínculos ativos ele deve aparecer algum botão...

Não entendi, como que você consegue ver essa página, ela aparece direto?

image

dduartee commented 3 years ago

Não entendi, como que você consegue ver essa página, ela aparece direto?

Não, é pelo link https://sigaa.ifsc.edu.br/sigaa/mobile/touch/vinculos.jsf

dduartee commented 3 years ago

Não entendi, como que você consegue ver essa página, ela aparece direto?

Não, é pelo link https://sigaa.ifsc.edu.br/sigaa/mobile/touch/vinculos.jsf

Esse link eu não encontrei em nenhum botão, antigamente no começo dessa issue eu tinha entrado pelo mobile e lembro que tinha essa url quando eu fiz login.

GeovaneSchmitz commented 3 years ago

Eu fiz um novo commit tentando corrigir o problema de vínculos inativos. Você poderia testar?

const Sigaa = require("sigaa-api").Sigaa;

const sigaa = new Sigaa({
  url: "https://sigaa.ifsc.edu.br",
});

// coloque seu usuário
const username = "";
const password = "";

// Serve só para exibir as notas no console
const printGrades = (gradesGroups) => {
  for (const gradesGroup of gradesGroups) {
    console.log("->" + gradesGroup.name);
    switch (gradesGroup.type) {
      case "only-average":
        console.log(gradesGroup.value);
        break;

      case "weighted-average":
        for (const grade of gradesGroup.grades) {
          console.log("-" + grade.name);
          console.log("peso: " + grade.weight);
          console.log(grade.value);
        }

        console.log("média:" + gradesGroup.value);

        break;

      case "sum-of-grades":
        for (const grade of gradesGroup.grades) {
          console.log("-" + grade.name);
          console.log("Valor máximo: " + grade.maxValue);
          console.log(grade.value);
        }

        console.log("soma:" + gradesGroup.value);
        break;
    }
    console.log(""); // Para espaçar as linhas
  }
};

const main = async () => {
  const account = await sigaa.login(username, password); // login

  const activeBonds = await account.getActiveBonds();
  for (const bond of activeBonds) {
    console.log(">Vínculos ativos");
    if (bond.type === "student") {
      console.log("Matrícula do vínculo: " + bond.registration);
      console.log("Curso do vínculo: " + bond.program);
    } else {
      console.log("vínculo de professor");
    }
  }

  const inactiveBonds = await account.getInactiveBonds();

  for (const bond of inactiveBonds) {
    console.log(">Vínculos inativos");
    if (bond.type === "student") {
      console.log("Matrícula do vínculo: " + bond.registration);
      console.log("Curso do vínculo: " + bond.program);
    } else {
      console.log("vínculo de professor");
    }
  }

  const firstCourse = (await activeBonds[0].getCourses())[0]; //Pega a primeira turma do primeiro vinculo ativo
  printGrades(await firstCourse.getGrades());

  const secondCourse = (await inactiveBonds[0].getCourses())[0]; //Pega a primeira turma do primeiro vinculo inativo
  printGrades(await secondCourse.getGrades());

  const thirdCourse = (await activeBonds[0].getCourses())[1]; //Pega a segunda turma do primeiro vinculo ativo
  printGrades(await thirdCourse.getGrades());

  // Encerra a sessão
  await account.logoff();
};

main().catch((err) => {
  if (err) console.log(err);
});
dduartee commented 3 years ago

Executei o código, ele identificou o vinculo ativo, me deu as notas, mas retornou um erro na linha 75.

const secondCourse = (await inactiveBonds[0].getCourses())[0];
TypeError: Cannot read property 'getCourses' of undefined
    at main (C:\Users\Duarte\Desktop\sigaa\index.js:75:48)
    at processTicksAndRejections (node:internal/process/task_queues:93:5)

dei console.log no inactiveBonds da linha:

const inactiveBonds = await account.getInactiveBonds();
console.log(inactiveBonds);

Ele simplesmente retornou

>Vínculos ativos
Matrícula do vínculo: 202011004225
Curso do vínculo: TÉCNICO EM MECÂNICA [276]/XXE - Técnico - Integrado - Xanxerê - I
[]

dei console.log no account

const account = await sigaa.login(username, password);
console.log(account);

retornou:

SigaaAccount {
  errorInvalidCredentials: 'SIGAA: Invalid credentials.',
  errorInsufficientPasswordComplexity: 'SIGAA: Insufficent password complexity.',
  activeBonds: [
    SigaaStudentBond {
      type: 'student',
      http: [SigaaHTTP],
      parser: SigaaParser {},
      program: 'TÉCNICO EM MECÂNICA [276]/XXE - Técnico - Integrado - Xanxerê - I',
      registration: '202011004225',
      bondSwitchUrl: null
    }
  ],
  inactiveBonds: [],
  http: SigaaHTTP {
    session: SigaaHTTPSession {
      postRequestsStack: [SigaaPromiseStack],
      noCookieRequestsStack: [SigaaPromiseStack],
      requestStack: [SigaaPromiseStack],
      requestPromises: [],
      url: 'https://sigaa.ifsc.edu.br',
      token: [SigaaTokens],
      pageCache: [SigaaPageCache]
    }
  },
  parser: SigaaParser {},
  session: SigaaSession { loginStatus: 1 },
  bondFactory: SigaaBondFactory {
    httpFactory: SigaaHTTPFactory {
      session: [SigaaHTTPSession],
      bondController: [SigaaBondController]
    },
    parser: SigaaParser {}
  },
  pagehomeParsePromise: Promise { undefined }
}

ele ainda não encontrou os vínculos inativos...

GeovaneSchmitz commented 3 years ago

Ele não encontrou o botão de alterar vínculos, pois eu fiz seletor errado mas fiz um commit https://github.com/GeovaneSchmitz/sigaa-api/commit/5e1f06ba8f78db90ac81a14e3b6134a1f73306a7 para corrigir, pode testar novamente?

dduartee commented 3 years ago

Opa, finalmente, ele conseguiu identificar o outro curso mas teve alguns casos.

Executei o código, no primeiro momento mostrou os vínculos ativos e inativos, mas eles estavam duplicados...

>Vínculos ativos
Matrícula do vínculo: 202011004225
Curso do vínculo: TÉCNICO EM MECÂNICA [276]/XXE - Técnico - Integrado - Xanxerê
>Vínculos ativos
Matrícula do vínculo: 202011004225
Curso do vínculo: TÉCNICO EM MECÂNICA [276]/XXE - Técnico - Integrado - Xanxerê
>Vínculos inativos
Matrícula do vínculo: 202022700199
Curso do vínculo: PROGRAMADOR DE SISTEMAS/TUB - Tubarão - EAD
>Vínculos inativos
Matrícula do vínculo: 202022700199
Curso do vínculo: PROGRAMADOR DE SISTEMAS/TUB - Tubarão - EAD

isso não só no console, e sim com o debug consegui ver que estava duplicado dentro das variáveis... image

image

Em relação as notas, ele só retornou as notas do primeiro vinculo. A primeira matéria do meu primeiro vinculo, é ARTES, retornou correto. A primeira matéria do meu segundo vinculo, ele retornou ARTES, as mesmas notas do primeiro vinculo. A segunda matéria do meu primeiro vinculo, é BIOLOGIA, retornou correto.

São esses os casos que encontrei, os vínculos duplicados, e as notas do segundo vinculo.

dduartee commented 3 years ago

A primeira matéria do meu primeiro vinculo, é ARTES, retornou correto. A primeira matéria do meu segundo vinculo, ele retornou ARTES, as mesmas notas do primeiro vinculo. A segunda matéria do meu primeiro vinculo, é BIOLOGIA, retornou correto.

Para deixar mais claro

image

As notas do segundo vinculo são iguais as notas do primeiro.

dduartee commented 3 years ago

Para deixar mais claro

image

Desculpe na linha 77 o inactiveBonds está na posição 1, no seu código está na posição 0, mas não altera no erro.

image

GeovaneSchmitz commented 3 years ago

Eu acho que agora vai! Desculpe o excesso de tentativas, mas realmente é difícil para mim fazer um código sem poder testar. O problema que eu corrigi agora é o mecanismo de cache, o mecanismo de responder com a mesma página se a solicitação for igual, contudo ele não estava verificando qual é o vínculo atual, desta forma quanto ele acessa a página de lista de turma, como, a princípio, a solicitação era para mesmo endereço, a resposta que ele retornava era a mesma do vínculo anterior e, por conseguinte, as turmas que ele retornavam eram iguais independe do vínculo.

dduartee commented 3 years ago

Desculpe o excesso de tentativas, mas realmente é difícil para mim fazer um código sem poder testar.

Relaxa cara, parabéns para você que conseguiu desenvolver a parte de vínculos inativos sem ter como testar, para mim isso é incrível!

O problema que eu corrigi agora é o mecanismo de cache, o mecanismo de responder com a mesma página se a solicitação for igual, contudo ele não estava verificando qual é o vínculo atual, desta forma quanto ele acessa a página de lista de turma, como, a princípio, a solicitação era para mesmo endereço, a resposta que ele retornava era a mesma do vínculo anterior e, por conseguinte, as turmas que ele retornavam eram iguais independe do vínculo.

Boa, vou testar aqui e já retorno.

dduartee commented 3 years ago

Voltando, ele printou as notas das primeiras matérias de cada vinculo, menos a ultima, as notas da segunda matéria do primeiro vinculo.

Ele retornou o seguinte erro:

Error: SIGAA: Course sub menu button not found.
    at SigaaCourseStudent.getCourseSubMenu (C:\Users\Duarte\Desktop\sigaa11\node_modules\sigaa-api\src\courses\sigaa-course-student.ts:1039:13)
    at processTicksAndRejections (node:internal/process/task_queues:93:5)
    at SigaaCourseStudent.getGrades (C:\Users\Duarte\Desktop\sigaa11\node_modules\sigaa-api\src\courses\sigaa-course-student.ts:1591:18)
    at main (C:\Users\Duarte\Desktop\sigaa11\index.js:80:27)

vou debugar ele para ver se ajuda.

dduartee commented 3 years ago

No meio do debug, encontrei outro caso...

Quando ele vai pegar a nota da segunda matéria do primeiro vinculo ele pega a segunda matéria do segundo vinculo... image

e logo depois retorna o erro:

Error: SIGAA: Course sub menu button not found.
    at SigaaCourseStudent.getCourseSubMenu (C:\Users\Duarte\Desktop\sigaa11\node_modules\sigaa-api\src\courses\sigaa-course-student.ts:1039:13)
    at processTicksAndRejections (node:internal/process/task_queues:93:5)
    at SigaaCourseStudent.getGrades (C:\Users\Duarte\Desktop\sigaa11\node_modules\sigaa-api\src\courses\sigaa-course-student.ts:1591:18)
    at main (C:\Users\Duarte\Desktop\sigaa11\index.js:80:27)
GeovaneSchmitz commented 3 years ago

Olá, Eu fiz um novo commit, você poderia testar? Ainda acho que é o cache de página. Agora ele limpa o cache toda vez que muda de vínculo antes ele tinha um cache para cada vínculo

GeovaneSchmitz commented 3 years ago

    at SigaaCourseStudent.getCourseSubMenu (C:\Users\Duarte\Desktop\sigaa11\node_modules\sigaa-api\src\courses\sigaa-course-student.ts:1039:13)
    at processTicksAndRejections (node:internal/process/task_queues:93:5)
    at SigaaCourseStudent.getGrades (C:\Users\Duarte\Desktop\sigaa11\node_modules\sigaa-api\src\courses\sigaa-course-student.ts:1591:18)
    at main (C:\Users\Duarte\Desktop\sigaa11\index.js:80:27)

Que estranho, este erro acontence quando a página da turma não é carregada corretamente. Acredito que não pode ser utilizada uma página antiga se o vínculo trocou.

dduartee commented 3 years ago

Que estranho, este erro acontence quando a página da turma não é carregada corretamente.

Falando nisso, algumas vezes quando eu entro no sigaa, aparece um erro interno, isso também atrapalha.

Eu fiz um novo commit, você poderia testar? Ainda acho que é o cache de página. Agora ele limpa o cache toda vez que muda de vínculo antes ele tinha um cache para cada vínculo

Vou testar.

dduartee commented 3 years ago

Sem sucesso, continuou retornando o erro...

Error: SIGAA: Course sub menu button not found.
    at SigaaCourseStudent.getCourseSubMenu (C:\Users\Duarte\Desktop\sigaa13\node_modules\sigaa-api\src\courses\sigaa-course-student.ts:1039:13)
    at processTicksAndRejections (node:internal/process/task_queues:93:5)
    at SigaaCourseStudent.getGrades (C:\Users\Duarte\Desktop\sigaa13\node_modules\sigaa-api\src\courses\sigaa-course-student.ts:1591:18)
    at main (C:\Users\Duarte\Desktop\sigaa13\index.js:75:15)

Ele curiosamente funcionou 1 vez, mas logo depois parou de funcionar...

dduartee commented 3 years ago

image Esse buttonEl, ele é de onde?

dduartee commented 3 years ago

Sem sucesso, continuou retornando o erro...

Error: SIGAA: Course sub menu button not found.
    at SigaaCourseStudent.getCourseSubMenu (C:\Users\Duarte\Desktop\sigaa13\node_modules\sigaa-api\src\courses\sigaa-course-student.ts:1039:13)
    at processTicksAndRejections (node:internal/process/task_queues:93:5)
    at SigaaCourseStudent.getGrades (C:\Users\Duarte\Desktop\sigaa13\node_modules\sigaa-api\src\courses\sigaa-course-student.ts:1591:18)
    at main (C:\Users\Duarte\Desktop\sigaa13\index.js:75:15)

Ele curiosamente funcionou 1 vez, mas logo depois parou de funcionar...

esqueci de falar que agora ele nem passa para o terceiro, ele da o erro no segundo

GeovaneSchmitz commented 3 years ago

Sem sucesso, continuou retornando o erro...

Error: SIGAA: Course sub menu button not found.
    at SigaaCourseStudent.getCourseSubMenu (C:\Users\Duarte\Desktop\sigaa13\node_modules\sigaa-api\src\courses\sigaa-course-student.ts:1039:13)
    at processTicksAndRejections (node:internal/process/task_queues:93:5)
    at SigaaCourseStudent.getGrades (C:\Users\Duarte\Desktop\sigaa13\node_modules\sigaa-api\src\courses\sigaa-course-student.ts:1591:18)
    at main (C:\Users\Duarte\Desktop\sigaa13\index.js:75:15)

Sinceramente, eu não sei o que está acontencendo. Essa função carrega a página que o botão da barra lataral da página da turma redireciona, basicamente, já que você está vendo as suas notas, ele procura por um botão que esteja escrito "Ver Notas". https://github.com/GeovaneSchmitz/sigaa-api/blob/84a171dd537bc115ed9d8582808f643b47112ad3/src/courses/sigaa-course-student.ts#L1591 Este erro está dizendo que ele não consegui encontrar nenhum botão com este nome na pagina da turma, provavelmente, o request que ele fez para carregar a página da turma está errado e por isso o sigaa está retornando uma página que não tem este botão. Você pode ver o conteudo dessa página se inserir:

console.log(page.body)

Mas o importante mesmo é saber o que ele está enviando no request, por isso recomendo que use isso:

console.log(page.requestOptions)
console.log(page.requestBody)

Se você quiser publicar, deve omitir tudo que tiver JSESSIONID=, principalmente os campos dos cookies, só checa antes se ele tem o cookie.

dduartee commented 3 years ago

Essa função carrega a página que o botão da barra lataral da página da turma redireciona, basicamente, já que você está vendo as suas notas, ele procura por um botão que esteja escrito "Ver Notas".

Pode haver uma pagina de redirecionamento? tipo uma página de aguardo?

Estarei enviando os logs do Body, requestOptions, requestBody.

sigaa.zip

Se precisar de mais algum log das páginas pode chamar.

dduartee commented 3 years ago

Olha, acho que é problema de carregamento do Sigaa mesmo, pois com o debug, fui indo função por função fazendo a "pagina carregar" e eu consegui receber as notas... talvez se colocar alguma verificação entre o body do zip e a página das notas normal.

Vou anexar novamente o body que recebi com o delay do debug.

página de notas.zip

dduartee commented 3 years ago

Essa função carrega a página que o botão da barra lataral da página da turma redireciona, basicamente, já que você está vendo as suas notas, ele procura por um botão que esteja escrito "Ver Notas".

Pode haver uma pagina de redirecionamento? tipo uma página de aguardo?

Estarei enviando os logs do Body, requestOptions, requestBody.

sigaa.zip

Se precisar de mais algum log das páginas pode chamar.

Realmente conferi novamente, é uma página de aguardo do sigaa...

image

GeovaneSchmitz commented 3 years ago

Quando que aparece este aguardo?

GeovaneSchmitz commented 3 years ago

Eu descobri um bug nas notas, já vou lançar uma correção. Talvez, agora, corrija.

dduartee commented 3 years ago

Quando que aparece este aguardo?

Sei lá, quando acontece o erro do botão.

em sucesso, continuou retornando o erro...

Error: SIGAA: Course sub menu button not found.
    at SigaaCourseStudent.getCourseSubMenu (C:\Users\Duarte\Desktop\sigaa13\node_modules\sigaa-api\src\courses\sigaa-course-student.ts:1039:13)
    at processTicksAndRejections (node:internal/process/task_queues:93:5)
    at SigaaCourseStudent.getGrades (C:\Users\Duarte\Desktop\sigaa13\node_modules\sigaa-api\src\courses\sigaa-course-student.ts:1591:18)
    at main (C:\Users\Duarte\Desktop\sigaa13\index.js:75:15)

Ele recebe essa página

Realmente conferi novamente, é uma página de aguardo do sigaa...

image

Deve ser tipo, no banco de dados ter uma fila, para não sobrecarregar, não sei, mas acredito que podemos fazer uma verificação, não sei se na prática é facil, mas fazer tipo


if (page.body.includes('Aguarde, estamos processando as informações...')) 
{
//Aqui dai aguarda a página responder com as página das notas.
}
GeovaneSchmitz commented 3 years ago

Mas a página está completa, essas mensagens são porque o sigaa foi feito em 2006, nessa época os computadores que acessam eram muitoooo lentos e a engine do javascript era muito lenta. Como a página demora para renderizar, a solução que eles fizeram foi colocar uma mensagem para fazer a pessoa esperar e não ficar clicando no botão de atualizar a página. Isso tudo é suposição, porém encaixa bem no funcionamento do sigaa, uma vez que ele entrega tudo mastigadinho para o navegador.

dduartee commented 3 years ago

ok, então você diz que essa página vem antes de clicar o botão para acessar a matéria? ou depois de clicar no botão?

GeovaneSchmitz commented 3 years ago

É a página inteira, essa messagem só aparece se não carregar o css dela. (Eu acho)

dduartee commented 3 years ago

Entendo, pense comigo em relação a como eu encontrei essa página.

image

A bola vermelha no lado direito da linha é um breakpoint do debug, um momento antes do código começar a ler a linha, ele congela o código, eu consigo ver todas as variáveis que foram chamadas. Neste momento antes de executar o erro, a variável page.body contém está página.

Realmente conferi novamente, é uma página de aguardo do sigaa...

image

No meu ver, quando clica para acessar a matéria ele aparece essa tela para acessar o banco de dados, resgatar os dados, e até retornar ao usuário. Não estou dizendo que vc está errado, mas onde eu encontrei o body da página que causa o erro, entrega o problema do sigaa.

É a página inteira, essa messagem só aparece se não carregar o css dela.

Você tem alguma teoria?

GeovaneSchmitz commented 3 years ago

Eu fiz um commit, será que mudou os sintomas?

No meu ver, quando clica para acessar a matéria ele aparece essa tela para acessar o banco de dados, resgatar os dados, e até retornar ao usuário. Não estou dizendo que vc está errado, mas onde eu encontrei o body da página que causa o erro, entrega o problema do sigaa.

Se for quando tem troca de vínculos ele vai seguir os redirecionamentos, a linha 41 faz isso: https://github.com/GeovaneSchmitz/sigaa-api/blob/96506148a524f884e0c9999e162d33336b20eeac/src/session/sigaa-http-with-bond.ts#L38-L46 Se for quando você escolhe uma turma em https://sigaa.ifsc.edu.br/sigaa/portais/discente/turmas.jsf pelo menos no meu sigaa não tem redirecionamento, a página carrega direto

GeovaneSchmitz commented 3 years ago

Talvez, pode ser porque você tem mais de um vínculo, mas você pode mandar os headers dela? page.headers e o page.requestOptions